Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
6b45bb5
fix: fixed some linting errors
vimscientist69 Aug 14, 2025
397e7a3
fix: fixed some linting errors
vimscientist69 Aug 15, 2025
5e9378d
fix: fixed some linting errors
vimscientist69 Aug 15, 2025
d365c2e
docs(Element): added documentation for all exposed public symbols
vimscientist69 Aug 15, 2025
3619bfc
docs(Element,ElementRect): added documentation
vimscientist69 Aug 15, 2025
7619996
docs(APIClient): added docs for public symbols
vimscientist69 Aug 15, 2025
e55488e
docs(ElementTypes): added documents for public symbols
vimscientist69 Aug 15, 2025
8471b98
docs(PostElementDoubleClickRequest): added documentation for public s…
vimscientist69 Aug 15, 2025
143f5e9
docs(DevToolTypes): added documentation for namespace
vimscientist69 Aug 15, 2025
8a68de1
docs(AnyEncodable): documentation added
vimscientist69 Aug 15, 2025
871606b
refactor(PostExecuteRequest): refactored to only one struct, added do…
vimscientist69 Aug 15, 2025
cb6213f
docs(ChromeDriverElementDragAndDropper): added documentation, fixed l…
vimscientist69 Aug 15, 2025
4687bb6
docs(Element): documented find element protocol
vimscientist69 Aug 15, 2025
b7b37fa
refactor(PostElementDragAndDropRequest): refactored body property get…
vimscientist69 Aug 15, 2025
186bf4c
docs(PostElementDragAndDropRequest): added documentation
vimscientist69 Aug 15, 2025
0c68071
docs(SeleniumError): added documentation
vimscientist69 Aug 15, 2025
c2cd766
docs(WebDriver): added documentation
vimscientist69 Aug 15, 2025
29f6bdb
docs(ActionsPayload): added documentation
vimscientist69 Aug 15, 2025
cccecc9
fix(ActionsPayload): fixed property names too short
vimscientist69 Aug 15, 2025
b4ca794
docs(GetElementRectRequest): added documentation, fixed no implicit a…
vimscientist69 Aug 15, 2025
9ea5e82
fix: fixed all linting errors
vimscientist69 Aug 15, 2025
43137db
feat(package.json): added test script to start up all required integr…
vimscientist69 Aug 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions Example/Sources/SeleniumSwiftExample/main.swift
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
// main.swift
// Main.swift

Check warning on line 1 in Example/Sources/SeleniumSwiftExample/main.swift

View workflow job for this annotation

GitHub Actions / swiftlint

File name should match a type or extension declared in the file (if any) (file_name)
// Copyright (c) 2025 GetAutomaApp
// All source code and related assets are the property of GetAutomaApp.
// All rights reserved.
//
// This package is freely distributable under the MIT license.
// This Package is a modified fork of https://github.com/ashi-psn/SwiftWebDriver.

import SwiftWebDriver

internal enum Main {
/// Executable main procedure for this example package
public static func main() async throws {
let chromeOption = ChromeOptions(
args: [
Expand Down
47 changes: 37 additions & 10 deletions Sources/SwiftWebDriver/API/APIClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
// Copyright (c) 2025 GetAutomaApp
// All source code and related assets are the property of GetAutomaApp.
// All rights reserved.
//
// This package is freely distributable under the MIT license.
// This Package is a modified fork of https://github.com/ashi-psn/SwiftWebDriver.

import AsyncHTTPClient
import Foundation
Expand All @@ -25,14 +22,33 @@ internal enum APIError: Error {
internal struct APIClient {
private let httpClient = HTTPClient(eventLoopGroupProvider: .singleton)

/// The shared singleton instance of `APIClient`.
///
/// Use this when you need a shared HTTP client for sending requests to
/// the WebDriver server or other API endpoints without creating a new
/// instance each time.
public static let shared = Self()

/// Request send To API and Parse Codable Models
/// - Parameter request: RequestType
/// - Returns: EventLoopFuture<RequestType.Response>
/// Sends a request to the API and decodes the response into a `Codable` model.
///
/// This method executes the given `RequestType` using the underlying
/// `AsyncHTTPClient` and decodes the result into the associated `Response`
/// type declared by the request. If the server responds with a non-OK
/// status code, the response is checked for a `SeleniumError` and thrown
/// if present; otherwise, an `APIError.responseStatsFailed` is thrown.
///
/// - Parameter request: The request to send. Must conform to `RequestType`
/// and have a `Codable` response type.
/// - Returns: An `EventLoopFuture` that will succeed with the decoded
/// response object or fail with an error.
///
/// - Throws:
/// - `SeleniumError` if the server returns a known WebDriver error.
/// - `APIError.responseStatsFailed` if the status code indicates failure.
/// - `APIError.responseBodyIsNil` if no response body is returned.
/// - Any `DecodingError` if the response cannot be decoded.
public func request<R>(_ request: R) -> EventLoopFuture<R.Response> where R: RequestType {
httpClient.execute(request: request).flatMapResult { response -> Result<R.Response, Error> in

guard response.status == .ok else {
if
let buffer = response.body,
Expand All @@ -58,9 +74,20 @@ internal struct APIClient {
}
}

/// Request send To API and Perse Codable Models
/// - Parameter request: RequestType
/// - Returns: EventLoopFuture<RequestType.Response>
/// Sends a request to the API and decodes the response into a `Codable` model, using Swift concurrency.
///
/// This is the async/await variant of `request(_:)`, returning the decoded
/// response directly rather than wrapping it in an `EventLoopFuture`.
///
/// - Parameter request: The request to send. Must conform to `RequestType`
/// and have a `Codable` response type.
/// - Returns: The decoded response object.
///
/// - Throws:
/// - `SeleniumError` if the server returns a known WebDriver error.
/// - `APIError.responseStatsFailed` if the status code indicates failure.
/// - `APIError.responseBodyIsNil` if no response body is returned.
/// - Any `DecodingError` if the response cannot be decoded.
@discardableResult
public func request<R>(_ request: R) async throws -> R.Response where R: RequestType {
try await self.request(request).get()
Expand Down
122 changes: 95 additions & 27 deletions Sources/SwiftWebDriver/API/Request/ActionsPayload.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,118 @@
// All source code and related assets are the property of GetAutomaApp.
// All rights reserved.

struct WebDriverElementOrigin: Encodable {
let element: String
/// Represents a complete actions payload to be sent to the WebDriver Actions API.
///
/// Contains one or more input sources (pointer, touch, etc.) with their associated actions.
internal struct ActionsPayload: Encodable {
/// Array of input sources, each with their pointer actions.
public let actions: [PointerSource]
}

enum CodingKeys: String, CodingKey {
case element = "element-6066-11e4-a52e-4f735466cecf"
/// Represents a pointer input source (e.g., mouse) for the WebDriver Actions API.
internal struct PointerSource: Encodable {
/// Type of input source, usually `"pointer"`.
public let type: String

/// Identifier for the input source, e.g., `"mouse"`.
public let id: String

/// Parameters describing the input source.
public let parameters: Parameters

/// Sequence of pointer actions for this input source.
public let actions: [PointerAction]

/// Parameters describing the pointer input source.
internal struct Parameters: Encodable {
/// Pointer type, e.g., `"mouse"`, `"pen"`, `"touch"`.
public let pointerType: String
}
}

struct PointerAction: Encodable {
let type: String
let origin: WebDriverElementOrigin?
let x: Int?
let y: Int?
let button: Int?
let duration: Int?
/// Represents a single pointer action for use in the WebDriver Actions API.
///
/// Examples of actions include pointer move, pointer down/up, and pauses.
internal struct PointerAction: Encodable {
/// The type of the action, e.g., `"pointerMove"`, `"pointerDown"`, `"pointerUp"`, `"pause"`.
public let type: String

/// Optional origin element for the action.
public let origin: WebDriverElementOrigin?

/// Optional x-coordinate for the pointer action.
public let xCoordinate: Int?

/// Optional y-coordinate for the pointer action.
public let yCoordinate: Int?

/// Optional button for pointer actions (0 = left, 1 = middle, 2 = right).
public let button: Int?

/// Optional duration in milliseconds for pause actions.
public let duration: Int?

init(
/// Coding keys for encoding/decoding `PointerAction` to/from JSON.
///
/// Maps the Swift property names to the corresponding keys expected by the WebDriver Actions API.
public enum CodingKeys: String, CodingKey {
/// Action type (e.g., "pointerMove", "pointerDown", "pointerUp").
case type

/// Origin element for the pointer action.
case origin

/// X-coordinate of the pointer action.
case xCoordinate = "x"

/// Y-coordinate of the pointer action.
case yCoordinate = "y"

/// Mouse button involved in the action (0 = left, 1 = middle, 2 = right).
case button

/// Duration of the action in milliseconds.
case duration
}

/// Initializes a new `PointerAction`.
///
/// - Parameters:
/// - type: The type of pointer action.
/// - origin: The element origin for the action (optional).
/// - xCoordinate: X-coordinate (optional).
/// - yCoordinate: Y-coordinate (optional).
/// - button: Button index for mouse actions (optional).
/// - duration: Duration in milliseconds for pause actions (optional).
public init(
type: String,
origin: WebDriverElementOrigin? = nil,
x: Int? = nil,
y: Int? = nil,
xCoordinate: Int? = nil,
yCoordinate: Int? = nil,
button: Int? = nil,
duration: Int? = nil
) {
self.type = type
self.origin = origin
self.x = x
self.y = y
self.xCoordinate = xCoordinate
self.yCoordinate = yCoordinate
self.button = button
self.duration = duration
}
}

struct PointerSource: Encodable {
let type: String
let id: String
let parameters: Parameters
let actions: [PointerAction]
/// Represents a reference to a WebDriver element in the Actions API.
///
/// This is used as the origin for pointer or touch actions.
internal struct WebDriverElementOrigin: Encodable {
/// The element ID in WebDriver protocol format.
public let element: String

struct Parameters: Encodable {
let pointerType: String
/// Coding keys for encoding/decoding `WebDriverElementOrigin` to/from JSON.
///
/// Maps the Swift property `element` to the WebDriver protocol’s expected key.
public enum CodingKeys: String, CodingKey {
/// The WebDriver element identifier key used in actions payloads.
case element = "element-6066-11e4-a52e-4f735466cecf"
}
}

struct ActionsPayload: Encodable {
let actions: [PointerSource]
}
22 changes: 21 additions & 1 deletion Sources/SwiftWebDriver/API/Request/DevTools/AnyEncodable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,33 @@
// All source code and related assets are the property of GetAutomaApp.
// All rights reserved.

/// A type-erased wrapper for any `Encodable` value.
///
/// `AnyEncodable` allows you to store or pass around values of different `Encodable`
/// types without knowing their concrete type at compile time. This is useful when
/// building heterogeneous collections of `Encodable` objects or creating dynamic
/// JSON payloads.
public struct AnyEncodable: Encodable {
// MARK: - Private Properties

/// The internal closure used to encode the wrapped value.
private let encodeFunc: (Encoder) throws -> Void

init(_ value: some Encodable) {
// MARK: - Initializers

/// Creates a type-erased wrapper around the given `Encodable` value.
///
/// - Parameter value: Any value that conforms to `Encodable`.
public init(_ value: some Encodable) {
encodeFunc = value.encode
}

// MARK: - Encoding

/// Encodes the wrapped value using the given encoder.
///
/// - Parameter encoder: The encoder to write data to.
/// - Throws: Any encoding error thrown by the wrapped value.
public func encode(to encoder: Encoder) throws {
try encodeFunc(encoder)
}
Expand Down
22 changes: 18 additions & 4 deletions Sources/SwiftWebDriver/API/Request/DevTools/DevToolTypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,26 @@
// Copyright (c) 2025 GetAutomaApp
// All source code and related assets are the property of GetAutomaApp.
// All rights reserved.
//
// This package is freely distributable under the MIT license.
// This Package is a modified fork of https://github.com/ashi-psn/SwiftWebDriver.

/// A namespace containing types related to browser developer tool operations.
///
/// `DevToolTypes` groups together constants and enumerations that define
/// configuration or execution modes for actions performed via browser
/// developer tools.
public enum DevToolTypes {
/// Represents the available modes for executing JavaScript through
/// browser developer tools.
public enum JavascriptExecutionTypes {
case async, sync
/// Executes JavaScript **asynchronously**.
///
/// The execution returns a result only after an asynchronous operation
/// completes, allowing for `Promise` handling or delayed callbacks.
case async

/// Executes JavaScript **synchronously**.
///
/// The execution blocks until a result is immediately available,
/// without waiting for asynchronous operations.
case sync
}
}

This file was deleted.

Loading
Loading