Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
// 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
6 changes: 3 additions & 3 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

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