From 67a55a1255c57e1d6677ac0589f3db8967f94870 Mon Sep 17 00:00:00 2001 From: William Date: Mon, 6 Jul 2026 15:21:04 +0200 Subject: [PATCH 01/16] feat: implemented firefox driver, tests are failing somehow this might be due to the chrome driver and request refactoring to support both firefox and chrome --- README.md | 2 +- .../SwiftWebDriver/WebDrivers/Driver.swift | 2 +- .../WebDrivers/ElementDragAndDropper.swift | 2 +- .../WebDrivers/Firefox/FirefoxDriver.swift | 702 +++++++++--------- docker-compose.yml | 48 +- package.json | 2 +- 6 files changed, 391 insertions(+), 367 deletions(-) diff --git a/README.md b/README.md index 1951ec5..abb2135 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ docker-compose run test // Run Tests in Docker # Testing on Host Machine ```bash -docker compose up selenium httpd -d +docker compose up selenium_chrome httpd -d ``` 2. Run tests via test runner / `swift test` diff --git a/Sources/SwiftWebDriver/WebDrivers/Driver.swift b/Sources/SwiftWebDriver/WebDrivers/Driver.swift index d3672a9..78ac98d 100644 --- a/Sources/SwiftWebDriver/WebDrivers/Driver.swift +++ b/Sources/SwiftWebDriver/WebDrivers/Driver.swift @@ -64,7 +64,7 @@ extension Driver { static func startDriverExternal( url: URL, - browserObject: ChromeOptions, + browserObject: some BrowserOptions, client: APIClient ) async throws -> String { let request = NewSessionRequest(baseURL: url, browserOptions: browserObject) diff --git a/Sources/SwiftWebDriver/WebDrivers/ElementDragAndDropper.swift b/Sources/SwiftWebDriver/WebDrivers/ElementDragAndDropper.swift index 07140cf..cfd53a1 100644 --- a/Sources/SwiftWebDriver/WebDrivers/ElementDragAndDropper.swift +++ b/Sources/SwiftWebDriver/WebDrivers/ElementDragAndDropper.swift @@ -93,7 +93,7 @@ internal struct ElementDragAndDropper { AnyEncodable(["element-6066-11e4-a52e-4f735466cecf": source.elementId]), AnyEncodable(["element-6066-11e4-a52e-4f735466cecf": target.elementId]) ] - try await driver.execute(script, args: arguments, type: .sync) + _ = try await driver.execute(script, args: arguments, type: .sync) } /// Determines whether the source element is HTML5-draggable. diff --git a/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxDriver.swift b/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxDriver.swift index dd253ff..db9dd6c 100644 --- a/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxDriver.swift +++ b/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxDriver.swift @@ -3,349 +3,359 @@ // All source code and related assets are the property of GetAutomaApp. // All rights reserved. -// -// import AsyncHTTPClient -// import Foundation -// import NIO -// import NIOHTTP1 -// - -// public class ChromeDriver: Driver { -// public typealias BrowserOption = ChromeOptions -// -// public var browserObject: ChromeOptions -// -// public var url: URL -// -// private let client = APIClient.shared -// -// public var sessionId: String? -// -// public required init(driverURL url: URL, browserObject: ChromeOptions) { -// self.url = url -// self.browserObject = browserObject -// } -// -// public convenience init( -// driverURLString urlString: String = "http://localhost:4444", -// browserObject: ChromeOptions -// ) throws { -// guard let url = URL(string: urlString) else { -// throw HTTPClientError.invalidURL -// } -// self.init(driverURL: url, browserObject: browserObject) -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// public func start() async throws -> String { -// // swiftlint:disable:next prefer_self_in_static_references -// let id = try await ChromeDriver.startDriverExternal(url: url, browserObject: browserObject, client: client) -// sessionId = id -// return id -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// public func stop() async throws -> String? { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// let request = DeleteSessionRequest(baseURL: url, sessionId: sessionId) -// return try await client.request(request).map(\.value).get() -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// public func status() async throws -> StatusResponse { -// let request = StatusRequest(baseURL: url) -// return try await client.request(request).get() -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// public func getNavigation() async throws -> GetNavigationResponse { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// let request = GetNavigationRequest(baseURL: url, sessionId: sessionId) -// return try await client.request(request).get() -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// public func postNavigation(requestURL: String) async throws -> PostNavigationResponse { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// let request = PostNavigationRequest(baseURL: url, sessionId: sessionId, requestURL: requestURL) -// return try await client.request(request).get() -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// public func postNavigationBack() async throws -> PostNavigationBackResponse { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// let request = PostNavigationBackRequest(baseURL: url, sessionId: sessionId) -// return try await client.request(request).get() -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// public func postNavigationForward() async throws -> PostNavigationForwardResponse { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// let request = PostNavigationForwardRequest(baseURL: url, sessionId: sessionId) -// return try await client.request(request).get() -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// public func postNavigationRefresh() async throws -> PostNavigationRefreshResponse { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// let request = PostNavigationRefreshRequest(baseURL: url, sessionId: sessionId) -// return try await client.request(request).get() -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// public func getNavigationTitle() async throws -> GetNavigationTitleResponse { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// let request = GetNavigationTitleRequest(baseURL: url, sessionId: sessionId) -// return try await client.request(request).get() -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// public func postElement(locatorSelector: LocatorSelector) async throws -> PostElementResponse { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// let request = PostElementRequest(baseURL: url, sessionId: sessionId, cssSelector: locatorSelector) -// return try await client.request(request).get() -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// public func postElements(locatorSelector: LocatorSelector) async throws -> PostElementsResponse { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// let request = PostElementsRequest(baseURL: url, sessionId: sessionId, cssSelector: locatorSelector) -// return try await client.request(request).get() -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// public func postElementByElementId( -// locatorSelector: LocatorSelector, -// elementId: String -// ) async throws -> PostElementByIdResponse { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// let request = PostElementByIdRequest( -// baseURL: url, -// sessionId: sessionId, -// elementId: elementId, -// cssSelector: locatorSelector -// ) -// return try await client.request(request).get() -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// public func postElementsByElementId( -// locatorSelector: LocatorSelector, -// elementId: String -// ) async throws -> PostElementsByIdResponse { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// let request = PostElementsByIdRequest( -// baseURL: url, -// sessionId: sessionId, -// elementId: elementId, -// cssSelector: locatorSelector -// ) -// return try await client.request(request).get() -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// public func getElementText(elementId: String) async throws -> GetElementTextResponse { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// let request = GetElementTextRequest(baseURL: url, sessionId: sessionId, elementId: elementId) -// return try await client.request(request).get() -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// public func getElementName(elementId: String) async throws -> GetElementNameResponse { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// let request = GetElementNameRequest(baseURL: url, sessionId: sessionId, elementId: elementId) -// return try await client.request(request).get() -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// public func findElement(_ locatorType: LocatorType) async throws -> Element { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// let request = PostElementRequest(baseURL: url, sessionId: sessionId, cssSelector: locatorType.create()) -// let response = try await client.request(request) -// return Element(baseURL: url, sessionId: sessionId, elementId: response.elementId) -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// public func findElements(_ locatorType: LocatorType) async throws -> Elements { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// let request = PostElementsRequest(baseURL: url, sessionId: sessionId, cssSelector: locatorType.create()) -// let response = try await client.request(request) -// return response.value.map { elementId in -// Element(baseURL: url, sessionId: sessionId, elementId: elementId) -// } -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// public func getScreenShot() async throws -> String { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// let request = GetScreenShotRequest(baseURL: url, sessionId: sessionId) -// let response = try await client.request(request) -// return response.value -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// @discardableResult -// public func waitUntil( -// _ locatorType: LocatorType, -// retryCount: Int = 3, -// durationSeconds: Int = 1 -// ) async throws -> Bool { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// let request = PostElementRequest(baseURL: url, sessionId: sessionId, cssSelector: locatorType.create()) -// -// do { -// try await client.request(request) -// return true -// } catch { -// guard -// retryCount > 0, -// error.isSeleniumError(ofType: .noSuchElement) -// else { -// return false -// } -// -// let retryCount = retryCount - 1 -// -// sleep(UInt32(durationSeconds)) -// -// return try await waitUntil(locatorType, retryCount: retryCount, durationSeconds: durationSeconds) -// } -// } -// -// private func executeJavascriptSync(_ script: String, args: [AnyEncodable]) async throws -> PostExecuteResponse { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// -// let request = PostExecuteRequest( -// baseURL: url, -// sessionId: sessionId, -// type: .sync, -// javascriptSnippet: .init(script: script, args: args) -// ) -// -// return try await client.request(request) -// } -// -// private func executeJavascriptAsync(_ script: String, args: [AnyEncodable]) async throws -> PostExecuteResponse { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// -// let request = PostExecuteRequest( -// baseURL: url, -// sessionId: sessionId, -// type: .async, -// javascriptSnippet: .init(script: script, args: args) -// ) -// -// return try await client.request(request) -// } -// -// @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) -// @discardableResult -// public func execute( -// _ script: String, -// args: [AnyEncodable], -// type: DevToolTypes.JavascriptExecutionTypes -// ) async throws -> PostExecuteResponse { -// try await type == .sync ? -// executeJavascriptSync(script, args: args) : -// executeJavascriptAsync( -// script, -// args: args -// ) -// } -// -// public func getActiveElement() async throws -> Element { -// guard let sessionId else { -// throw WebDriverError.sessionIdIsNil -// } -// -// let request = GetSessionActiveElementRequest(baseURL: url, sessionId: sessionId) -// -// let response = try await client.request(request) -// return Element(baseURL: url, sessionId: sessionId, elementId: response.elementId) -// } -// -// public func setAttribute(element: Element, attributeName: String, newValue: String) async throws { -// let script = "arguments[0].setAttribute(arguments[1], arguments[2]);" -// -// let args: [AnyEncodable] = [ -// AnyEncodable(["element-6066-11e4-a52e-4f735466cecf": element.elementId]), -// AnyEncodable(attributeName), -// AnyEncodable(newValue) -// ] -// try await execute(script, args: args, type: .sync) -// } -// -// public func getProperty(element: Element, propertyName: String) async throws -> PostExecuteResponse { -// let script = "return arguments[0][arguments[1]];" -// -// let args: [AnyEncodable] = [ -// AnyEncodable(["element-6066-11e4-a52e-4f735466cecf": element.elementId]), -// AnyEncodable(propertyName) -// ] -// return try await execute(script, args: args, type: .sync) -// } -// -// public func setProperty(element: Element, propertyName: String, newValue: String) async throws { -// let script = "arguments[0][arguments[1]] = arguments[2];" -// let args: [AnyEncodable] = [ -// AnyEncodable(["element-6066-11e4-a52e-4f735466cecf": element.elementId]), -// AnyEncodable(propertyName), -// AnyEncodable(newValue) -// ] -// -// try await execute(script, args: args, type: .sync) -// } -// -// public func dragAndDrop(from source: Element, to target: Element) async throws { -// try await ElementDragAndDropper(driver: self, from: source, to: target).dragAndDrop() -// } -// -// deinit { -// let url = url -// let sessionId = sessionId -// Task { -// guard let sessionId else { return } -// // swiftlint:disable:next prefer_self_in_static_references -// try await ChromeDriver.stopDriverExternal(url: url, sessionId: sessionId) -// } -// } -// -// } +import AsyncHTTPClient +import Foundation +import NIO +import NIOHTTP1 + +public class FirefoxDriver: Driver { + public typealias BrowserOption = FirefoxOptions + + public var browserObject: FirefoxOptions + + public var url: URL + + private let client = APIClient.shared + + public var sessionId: String? + + public required init(driverURL url: URL, browserObject: FirefoxOptions) { + self.url = url + self.browserObject = browserObject + } + + public convenience init( + driverURLString urlString: String = "http://localhost:4444", + browserObject: FirefoxOptions + ) throws { + guard let url = URL(string: urlString) else { + throw HTTPClientError.invalidURL + } + self.init(driverURL: url, browserObject: browserObject) + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func start() async throws -> String { + let id = try await FirefoxDriver.startDriverExternal( + url: url, + browserObject: browserObject, + client: client + ) + sessionId = id + return id + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func stop() async throws -> String? { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + let request = DeleteSessionRequest(baseURL: url, sessionId: sessionId) + return try await client.request(request).map(\.value).get() + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func status() async throws -> StatusResponse { + let request = StatusRequest(baseURL: url) + return try await client.request(request).get() + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func getNavigation() async throws -> GetNavigationResponse { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + let request = GetNavigationRequest(baseURL: url, sessionId: sessionId) + return try await client.request(request).get() + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func postNavigation(requestURL: String) async throws -> PostNavigationResponse { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + let request = PostNavigationRequest(baseURL: url, sessionId: sessionId, requestURL: requestURL) + return try await client.request(request).get() + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func postNavigationBack() async throws -> PostNavigationBackResponse { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + let request = PostNavigationBackRequest(baseURL: url, sessionId: sessionId) + return try await client.request(request).get() + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func postNavigationForward() async throws -> PostNavigationForwardResponse { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + let request = PostNavigationForwardRequest(baseURL: url, sessionId: sessionId) + return try await client.request(request).get() + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func postNavigationRefresh() async throws -> PostNavigationRefreshResponse { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + let request = PostNavigationRefreshRequest(baseURL: url, sessionId: sessionId) + return try await client.request(request).get() + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func getNavigationTitle() async throws -> GetNavigationTitleResponse { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + let request = GetNavigationTitleRequest(baseURL: url, sessionId: sessionId) + return try await client.request(request).get() + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func postElement(locatorSelector: LocatorSelector) async throws -> PostElementResponse { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + let request = PostElementRequest(baseURL: url, sessionId: sessionId, cssSelector: locatorSelector) + return try await client.request(request).get() + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func postElements(locatorSelector: LocatorSelector) async throws -> PostElementsResponse { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + let request = PostElementsRequest(baseURL: url, sessionId: sessionId, cssSelector: locatorSelector) + return try await client.request(request).get() + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func postElementByElementId( + locatorSelector: LocatorSelector, + elementId: String + ) async throws -> PostElementByIdResponse { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + let request = PostElementByIdRequest( + baseURL: url, + sessionId: sessionId, + elementId: elementId, + cssSelector: locatorSelector + ) + return try await client.request(request).get() + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func postElementsByElementId( + locatorSelector: LocatorSelector, + elementId: String + ) async throws -> PostElementsByIdResponse { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + let request = PostElementsByIdRequest( + baseURL: url, + sessionId: sessionId, + elementId: elementId, + cssSelector: locatorSelector + ) + return try await client.request(request).get() + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func getElementText(elementId: String) async throws -> GetElementTextResponse { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + let request = GetElementTextRequest(baseURL: url, sessionId: sessionId, elementId: elementId) + return try await client.request(request).get() + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func getElementName(elementId: String) async throws -> GetElementNameResponse { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + let request = GetElementNameRequest(baseURL: url, sessionId: sessionId, elementId: elementId) + return try await client.request(request).get() + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func findElement(_ locatorType: LocatorType) async throws -> Element { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + let request = PostElementRequest(baseURL: url, sessionId: sessionId, cssSelector: locatorType.create()) + let response = try await client.request(request) + return Element(baseURL: url, sessionId: sessionId, elementId: response.elementId) + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func findElements(_ locatorType: LocatorType) async throws -> Elements { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + let request = PostElementsRequest(baseURL: url, sessionId: sessionId, cssSelector: locatorType.create()) + let response = try await client.request(request) + return response.value.map { elementId in + Element(baseURL: url, sessionId: sessionId, elementId: elementId) + } + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func getScreenShot() async throws -> String { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + let request = GetScreenShotRequest(baseURL: url, sessionId: sessionId) + let response = try await client.request(request) + return response.value + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + @discardableResult + public func waitUntil( + _ locatorType: LocatorType, + retryCount: Int = 3, + durationSeconds: Int = 1 + ) async throws -> Bool { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + let request = PostElementRequest(baseURL: url, sessionId: sessionId, cssSelector: locatorType.create()) + + do { + try await client.request(request) + return true + } catch { + guard retryCount > 0, error.isSeleniumError(ofType: .noSuchElement) else { + return false + } + + sleep(UInt32(durationSeconds)) + + return try await waitUntil( + locatorType, + retryCount: retryCount - 1, + durationSeconds: durationSeconds + ) + } + } + + private func executeJavascriptSync(_ script: String, args: [AnyEncodable]) async throws -> PostExecuteResponse { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + + let request = PostExecuteRequest( + baseURL: url, + sessionId: sessionId, + type: .sync, + javascriptSnippet: .init(script: script, args: args) + ) + + return try await client.request(request) + } + + private func executeJavascriptAsync(_ script: String, args: [AnyEncodable]) async throws -> PostExecuteResponse { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + + let request = PostExecuteRequest( + baseURL: url, + sessionId: sessionId, + type: .async, + javascriptSnippet: .init(script: script, args: args) + ) + + return try await client.request(request) + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + @discardableResult + public func execute( + _ script: String, + args: [AnyEncodable], + type: DevToolTypes.JavascriptExecutionTypes + ) async throws -> PostExecuteResponse { + try await type == .sync + ? executeJavascriptSync(script, args: args) + : executeJavascriptAsync(script, args: args) + } + + public func getActiveElement() async throws -> Element { + guard let sessionId else { + throw WebDriverError.sessionIdIsNil + } + + let request = GetSessionActiveElementRequest(baseURL: url, sessionId: sessionId) + let response = try await client.request(request) + + return Element(baseURL: url, sessionId: sessionId, elementId: response.elementId) + } + + public func setAttribute(element: Element, attributeName: String, newValue: String) async throws { + let script = "arguments[0].setAttribute(arguments[1], arguments[2]);" + let args: [AnyEncodable] = [ + AnyEncodable(["element-6066-11e4-a52e-4f735466cecf": element.elementId]), + AnyEncodable(attributeName), + AnyEncodable(newValue) + ] + + try await execute(script, args: args, type: .sync) + } + + public func getProperty(element: Element, propertyName: String) async throws -> PostExecuteResponse { + let script = "return arguments[0][arguments[1]];" + let args: [AnyEncodable] = [ + AnyEncodable(["element-6066-11e4-a52e-4f735466cecf": element.elementId]), + AnyEncodable(propertyName) + ] + + return try await execute(script, args: args, type: .sync) + } + + public func setProperty(element: Element, propertyName: String, newValue: String) async throws { + let script = "arguments[0][arguments[1]] = arguments[2];" + let args: [AnyEncodable] = [ + AnyEncodable(["element-6066-11e4-a52e-4f735466cecf": element.elementId]), + AnyEncodable(propertyName), + AnyEncodable(newValue) + ] + + try await execute(script, args: args, type: .sync) + } + + public func dragAndDrop(from source: Element, to target: Element) async throws { + try await ElementDragAndDropper(driver: self, from: source, to: target).dragAndDrop() + } + + deinit { + let url = url + let sessionId = sessionId + + Task { + guard let sessionId else { return } + try await FirefoxDriver.stopDriverExternal(url: url, sessionId: sessionId) + } + } + + private static func stopDriverExternal(url: URL, sessionId: String) async throws { + let request = DeleteSessionRequest(baseURL: url, sessionId: sessionId) + _ = try await APIClient.shared.request(request).map(\.value).get() + } + + private static func startDriverExternal( + url: URL, + browserObject: FirefoxOptions, + client: APIClient + ) async throws -> String { + let request = NewSessionRequest(baseURL: url, browserOptions: browserObject) + return try await client.request(request).map(\.value.sessionId).get() + } +} diff --git a/docker-compose.yml b/docker-compose.yml index d013105..fbcd1d9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,20 +1,20 @@ services: httpd: - network_mode: host - build: - context: . - dockerfile: ./infra/HTTPDDockerfile - volumes: - - ./TestAssets:/usr/local/apache2/htdocs/ - ports: - - "80:80" - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost"] - interval: 30s - timeout: 10s - retries: 3 + network_mode: host + build: + context: . + dockerfile: ./infra/HTTPDDockerfile + volumes: + - ./TestAssets:/usr/local/apache2/htdocs/ + ports: + - "80:80" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost"] + interval: 30s + timeout: 10s + retries: 3 - selenium: + selenium_chrome: image: selenium/standalone-chrome:4.2.1-20220531 network_mode: host ports: @@ -28,8 +28,20 @@ services: timeout: 10s retries: 3 - swift_web_driver: - &SwiftWebDriver + selenium_firefox: + image: selenium/standalone-firefox:152.0-20260606 + ports: + - 4445:4444 + - 7901:7900 + environment: + - SE_NODE_MAX_SESSIONS=4 + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:4444/status"] + interval: 30s + timeout: 10s + retries: 3 + + swift_web_driver: &SwiftWebDriver build: context: . dockerfile: ./infra/Dockerfile @@ -41,7 +53,9 @@ services: SELENIUM_URL: http://localhost:4444 tty: true depends_on: - selenium: + selenium_chrome: + condition: service_healthy + selenium_firefox: condition: service_healthy httpd: condition: service_healthy diff --git a/package.json b/package.json index 8f94bc3..ce80464 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "install:swiftformat": "brew install swiftformat", "install:swiftlint": "brew install swiftlint", "compose:up": "npm run compose -- up -d", - "compose:up:integration-services": "npm run compose:up -- --wait selenium httpd", + "compose:up:integration-services": "npm run compose:up -- --wait selenium_chrome httpd", "compose:build": "npm run compose -- build", "compose:build:no-cache": "npm run compose -- build --no-cache", "compose:build-and-up": "npx npm-run-all --sequential compose:build compose:up", From a555313dcacccb3a55edb0a6618adfbf946b218d Mon Sep 17 00:00:00 2001 From: William Date: Tue, 7 Jul 2026 18:11:41 +0200 Subject: [PATCH 02/16] fix: fixed tests not working by fixing container networking configuration Currently busy with figuring out why firefox tests aren't passing. It has something to do with how the firefox options are encoded and sent, specifically the arguments and possibly the profile top-level parameter. --- .../Sources/SeleniumSwiftExample/main.swift | 6 +-- Package.swift | 1 - .../WebDrivers/Chrome/ChromeDriver.swift | 2 +- .../WebDrivers/Firefox/FirefoxDriver.swift | 2 +- .../WebDrivers/Firefox/FirefoxOptions.swift | 18 ++++++- .../ChromeDriverIntegrationTestsBase.swift | 9 ++-- .../FirefoxDriverIntegrationTestsBase.swift | 49 +++++++++++++++++++ .../Start/FirefoxDriverStartTests.swift | 22 +++++++++ docker-compose.yml | 7 ++- 9 files changed, 99 insertions(+), 17 deletions(-) create mode 100644 Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/FirefoxDriverIntegrationTestsBase.swift create mode 100644 Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/Start/FirefoxDriverStartTests.swift diff --git a/Example/Sources/SeleniumSwiftExample/main.swift b/Example/Sources/SeleniumSwiftExample/main.swift index 2b82d73..8080dd4 100644 --- a/Example/Sources/SeleniumSwiftExample/main.swift +++ b/Example/Sources/SeleniumSwiftExample/main.swift @@ -1,5 +1,5 @@ -// Main.swift -// Copyright (c) 2025 GetAutomaApp +// main.swift +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. @@ -15,7 +15,7 @@ internal enum Main { ) let chromeDriver = try ChromeDriver( - driverURLString: "http://localhost:4444", + driverURLString: "http://selenium_chrome:4444", browserObject: chromeOption ) diff --git a/Package.swift b/Package.swift index 69b6124..ae3fccd 100644 --- a/Package.swift +++ b/Package.swift @@ -2,7 +2,6 @@ import PackageDescription -/// A public let package = Package( name: "swift-webdriver", platforms: [ diff --git a/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeDriver.swift b/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeDriver.swift index 34dff4a..f934029 100644 --- a/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeDriver.swift +++ b/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeDriver.swift @@ -24,7 +24,7 @@ public class ChromeDriver: Driver { } public convenience init( - driverURLString urlString: String = "http://localhost:4444", + driverURLString urlString: String = "http://selenium_chrome:4444", browserObject: ChromeOptions ) throws { guard let url = URL(string: urlString) else { diff --git a/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxDriver.swift b/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxDriver.swift index db9dd6c..35d6063 100644 --- a/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxDriver.swift +++ b/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxDriver.swift @@ -25,7 +25,7 @@ public class FirefoxDriver: Driver { } public convenience init( - driverURLString urlString: String = "http://localhost:4444", + driverURLString urlString: String = "http://selenium_firefox:4444", browserObject: FirefoxOptions ) throws { guard let url = URL(string: urlString) else { diff --git a/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxOptions.swift b/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxOptions.swift index 22d0a12..ee3dd25 100644 --- a/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxOptions.swift +++ b/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxOptions.swift @@ -14,11 +14,27 @@ public struct FirefoxOptions: Codable { public let binary: String? - public let args: [String]? + public let args: [FirefoxArgument]? public let profile: String? public let prefs: [String: FirefoxPreferenceValue]? public let log: FirefoxLog? public let env: [String: String]? + + init( + binary: String? = nil, + args: [FirefoxArgument]? = nil, + profile: String? = nil, + prefs: [String: FirefoxPreferenceValue]? = nil, + log: FirefoxLog? = nil, + env: [String: String]? = nil + ) { + self.binary = binary + self.args = args + self.profile = profile + self.prefs = prefs + self.log = log + self.env = env + } } public enum FirefoxArgument: CustomStringConvertible, Codable { diff --git a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/ChromeDriverIntegrationTestsBase.swift b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/ChromeDriverIntegrationTestsBase.swift index f6346c1..b0c2458 100644 --- a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/ChromeDriverIntegrationTestsBase.swift +++ b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/ChromeDriverIntegrationTestsBase.swift @@ -1,10 +1,7 @@ // ChromeDriverIntegrationTestsBase.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation @testable import SwiftWebDriver @@ -17,7 +14,7 @@ internal protocol ChromeDriverIntegrationTestsBase { } internal class ChromeDriverTest: ChromeDriverIntegrationTestsBase { - public let baseUrl: String = "http://localhost" + public let baseUrl: String = "http://httpd" public var testPageURL: URL { // swiftlint:disable:next force_unwrapping .init(string: "\(baseUrl)/\(page)")! @@ -28,7 +25,7 @@ internal class ChromeDriverTest: ChromeDriverIntegrationTestsBase { public init() async throws { // swiftlint:disable:next force_unwrapping - let driverURL = URL(string: "http://localhost:4444")! + let driverURL = URL(string: "http://selenium_chrome:4444")! let chromeOptions = ChromeOptions(args: [ Args(.disableDevShmUsage), Args(.noSandbox), diff --git a/Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/FirefoxDriverIntegrationTestsBase.swift b/Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/FirefoxDriverIntegrationTestsBase.swift new file mode 100644 index 0000000..4dabc59 --- /dev/null +++ b/Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/FirefoxDriverIntegrationTestsBase.swift @@ -0,0 +1,49 @@ +// FirefoxDriverIntegrationTestsBase.swift +// Copyright (c) 2026 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +import Foundation +@testable import SwiftWebDriver + +internal protocol FirefoxDriverIntegrationTestsBase { + var driver: WebDriver { get set } + var testPageURL: URL { get } + var baseUrl: String { get } + var page: String { get set } +} + +internal class FirefoxDriverTest: FirefoxDriverIntegrationTestsBase { + public let baseUrl: String = "http://localhost" + public var testPageURL: URL { + // swiftlint:disable:next force_unwrapping + .init(string: "\(baseUrl)/\(page)")! + } + + public var page: String = "index.html" + public var driver: WebDriver + + public init() async throws { + // swiftlint:disable:next force_unwrapping + let driverURL = URL(string: "http://selenium_firefox:4444")! + + let firefoxOptions = FirefoxOptions( + args: [.headless], + log: FirefoxLog(level: .info), + ) + + // Initialize the WebDriver on the main actor + driver = WebDriver( + driver: FirefoxDriver( + driverURL: driverURL, + browserObject: firefoxOptions + ) + ) + + try await driver.start() + } + + deinit { + // Add deinit here + } +} diff --git a/Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/Start/FirefoxDriverStartTests.swift b/Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/Start/FirefoxDriverStartTests.swift new file mode 100644 index 0000000..14169ca --- /dev/null +++ b/Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/Start/FirefoxDriverStartTests.swift @@ -0,0 +1,22 @@ +// FirefoxDriverStartTests.swift +// Copyright (c) 2026 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +@testable import SwiftWebDriver +import Testing + +@Suite("Firefox Driver Start Tests", .serialized) +internal class FirefoxDriverStartTests: FirefoxDriverTest { + @Test("Start & Stop") + public func startAndStop() async throws { + let status = try await driver.status() + #expect(status.value.message != "") + let sessionId = try await driver.start() + #expect(sessionId != "") + } + + deinit { + // Add deinit logic here + } +} diff --git a/docker-compose.yml b/docker-compose.yml index fbcd1d9..8a2620d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,5 @@ services: httpd: - network_mode: host build: context: . dockerfile: ./infra/HTTPDDockerfile @@ -16,7 +15,6 @@ services: selenium_chrome: image: selenium/standalone-chrome:4.2.1-20220531 - network_mode: host ports: - 4444:4444 - 7900:7900 @@ -48,9 +46,10 @@ services: volumes: - .:/SwiftWebDriver working_dir: /SwiftWebDriver - network_mode: host environment: - SELENIUM_URL: http://localhost:4444 + CHROME_SELENIUM_URL: http://selenium_chrome:4444 + FIREFOX_SELENIUM_URL: http://selenium_firefox:4444 + TEST_SERVER_URL: http://httpd tty: true depends_on: selenium_chrome: From 9d37fa71dbaf45bf693d07e25c38d02a579f43f9 Mon Sep 17 00:00:00 2001 From: William Date: Wed, 8 Jul 2026 13:26:44 +0200 Subject: [PATCH 03/16] fix: fixed firefox tests not passing by fixing types and firefox argument options initiation issues Next todo: ideally do not re-write all chrome tests, run each test suite twice but one with chrome and one with firefox. --- .../Sources/SeleniumSwiftExample/main.swift | 2 +- README.md | 2 +- .../Request/Sessions/NewSessionRequest.swift | 53 +++----------- .../WebDrivers/Chrome/ChromeOptions.swift | 10 +-- .../WebDrivers/Firefox/FirefoxOptions.swift | 71 +++++++++---------- .../ChromeDriverIntegrationTestsBase.swift | 4 +- .../FirefoxDriverIntegrationTestsBase.swift | 3 +- 7 files changed, 52 insertions(+), 93 deletions(-) diff --git a/Example/Sources/SeleniumSwiftExample/main.swift b/Example/Sources/SeleniumSwiftExample/main.swift index 8080dd4..c31b0ec 100644 --- a/Example/Sources/SeleniumSwiftExample/main.swift +++ b/Example/Sources/SeleniumSwiftExample/main.swift @@ -10,7 +10,7 @@ internal enum Main { public static func main() async throws { let chromeOption = ChromeOptions( args: [ - Args(.headless), + ChromeArgs(.headless), ] ) diff --git a/README.md b/README.md index abb2135..be067ec 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ docker compose up selenium_chrome httpd -d ```Swift let chromeOption = ChromeOptions( args: [ - Args(.headless), + ChromeArgs(.headless), ] ) diff --git a/Sources/SwiftWebDriver/API/Request/Sessions/NewSessionRequest.swift b/Sources/SwiftWebDriver/API/Request/Sessions/NewSessionRequest.swift index d0f6341..a2e3a10 100644 --- a/Sources/SwiftWebDriver/API/Request/Sessions/NewSessionRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Sessions/NewSessionRequest.swift @@ -22,7 +22,7 @@ internal struct NewSessionRequest: RequestType { public var body: HTTPClient.Body? { let requestBody = RequestBody( capabilities: RequestBodyCapabilities( - alwaysMatch: RequestBodyCapabilities.AlwaysMatch( + alwaysMatch: AlwaysMatch( browserOptions: browserOptions ) ) @@ -48,8 +48,7 @@ internal extension NewSessionRequest { let alwaysMatch: AlwaysMatch } - struct AlwaysMatch: Decodable, Encodable { - let browserName: String + struct AlwaysMatch: Encodable, Decodable { let browserOptions: Options enum StaticCodingKeys: String, CodingKey { @@ -57,10 +56,9 @@ internal extension NewSessionRequest { } struct DynamicCodingKey: CodingKey { - var stringValue: String - var intValue: Int? { - nil - } + let stringValue: String + + let intValue: Int? = nil init(stringValue: String) { self.stringValue = stringValue @@ -73,11 +71,14 @@ internal extension NewSessionRequest { func encode(to encoder: Encoder) throws { var staticContainer = encoder.container(keyedBy: StaticCodingKeys.self) - try staticContainer.encode(browserName, forKey: .browserName) + + try staticContainer.encode(Options.browserName, forKey: .browserName) var dynamicContainer = encoder.container(keyedBy: DynamicCodingKey.self) + try dynamicContainer.encode( browserOptions, + forKey: DynamicCodingKey(stringValue: Options.codingKey) ) } @@ -97,42 +98,6 @@ internal extension NewSessionRequest { internal extension NewSessionRequest { struct RequestBodyCapabilities: Encodable, Decodable { let alwaysMatch: AlwaysMatch - - struct AlwaysMatch: Encodable, Decodable { - let browserOptions: Options - - enum StaticCodingKeys: String, CodingKey { - case browserName - } - - struct DynamicCodingKey: CodingKey { - let stringValue: String - - let intValue: Int? = nil - - init(stringValue: String) { - self.stringValue = stringValue - } - - init?(intValue _: Int) { - nil - } - } - - func encode(to encoder: Encoder) throws { - var staticContainer = encoder.container(keyedBy: StaticCodingKeys.self) - - try staticContainer.encode(Options.browserName, forKey: .browserName) - - var dynamicContainer = encoder.container(keyedBy: DynamicCodingKey.self) - - try dynamicContainer.encode( - browserOptions, - - forKey: DynamicCodingKey(stringValue: Options.codingKey) - ) - } - } } } diff --git a/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeOptions.swift b/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeOptions.swift index acd9f19..3db7c95 100644 --- a/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeOptions.swift +++ b/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeOptions.swift @@ -1,5 +1,5 @@ // ChromeOptions.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. @@ -7,22 +7,22 @@ import Foundation import NIOCore /// Typealias for a single ChromeOptions argument -public typealias Args = String +public typealias ChromeArgs = String /// ChromeOptions data structure, used to configure Chrome Driver instantiation public struct ChromeOptions: Codable { /// Chrome arguments - public let args: [Args]? + public let args: [ChromeArgs]? /// Initialize ChromeOptions /// - Parameter args: an array of arguments - public init(args: [Args]?) { + public init(args: [ChromeArgs]?) { self.args = args } } /// Restrict arguments to an enum of allowed arguments -public extension Args { +public extension ChromeArgs { /// Initialize chrome option argument init(_ args: Arguments) { self.init(describing: args) diff --git a/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxOptions.swift b/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxOptions.swift index ee3dd25..c7406d6 100644 --- a/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxOptions.swift +++ b/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxOptions.swift @@ -10,11 +10,10 @@ // // import Foundation // import NIOCore -// public struct FirefoxOptions: Codable { public let binary: String? - public let args: [FirefoxArgument]? + public let args: [FirefoxArgs]? public let profile: String? public let prefs: [String: FirefoxPreferenceValue]? public let log: FirefoxLog? @@ -22,7 +21,7 @@ public struct FirefoxOptions: Codable { init( binary: String? = nil, - args: [FirefoxArgument]? = nil, + args: [FirefoxArgs]? = nil, profile: String? = nil, prefs: [String: FirefoxPreferenceValue]? = nil, log: FirefoxLog? = nil, @@ -37,46 +36,42 @@ public struct FirefoxOptions: Codable { } } -public enum FirefoxArgument: CustomStringConvertible, Codable { - case headless - case profile(path: String) - case privateMode - case privateWindow - case newWindow(url: String) - case newTab(url: String) - case kiosk(url: String) - case devTools - case safeMode +public struct FirefoxArgs: RawRepresentable, Codable, CustomStringConvertible { + public let rawValue: String + + public init(rawValue: String) { + self.rawValue = rawValue + } + + public init(_ argument: Argument) { + rawValue = argument.description + } public var description: String { - switch self { - case .headless: - "-headless" - case let .profile(path): - "-profile \(path)" - case .privateMode: - "-private" - case .privateWindow: - "-private-window" - case let .newWindow(url): - "-new-window \(url)" - case let .newTab(url): - "-new-tab \(url)" - case let .kiosk(url): - "--kiosk \(url)" - case .devTools: - "-devtools" - case .safeMode: - "-safe-mode" - } + rawValue } -} -public typealias FirefoxArg = String + public enum Argument: CustomStringConvertible, Codable { + case headless + case privateMode + case privateWindow + case devTools + case safeMode -public extension FirefoxArg { - init(_ argument: FirefoxArgument) { - self.init(describing: argument) + public var description: String { + switch self { + case .headless: + "-headless" + case .privateMode: + "-private" + case .privateWindow: + "-private-window" + case .devTools: + "-devtools" + case .safeMode: + "-safe-mode" + } + } } } diff --git a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/ChromeDriverIntegrationTestsBase.swift b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/ChromeDriverIntegrationTestsBase.swift index b0c2458..f851b01 100644 --- a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/ChromeDriverIntegrationTestsBase.swift +++ b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/ChromeDriverIntegrationTestsBase.swift @@ -27,8 +27,8 @@ internal class ChromeDriverTest: ChromeDriverIntegrationTestsBase { // swiftlint:disable:next force_unwrapping let driverURL = URL(string: "http://selenium_chrome:4444")! let chromeOptions = ChromeOptions(args: [ - Args(.disableDevShmUsage), - Args(.noSandbox), + ChromeArgs(.disableDevShmUsage), + ChromeArgs(.noSandbox), ]) // Initialize the WebDriver on the main actor diff --git a/Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/FirefoxDriverIntegrationTestsBase.swift b/Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/FirefoxDriverIntegrationTestsBase.swift index 4dabc59..f9e6919 100644 --- a/Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/FirefoxDriverIntegrationTestsBase.swift +++ b/Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/FirefoxDriverIntegrationTestsBase.swift @@ -28,8 +28,7 @@ internal class FirefoxDriverTest: FirefoxDriverIntegrationTestsBase { let driverURL = URL(string: "http://selenium_firefox:4444")! let firefoxOptions = FirefoxOptions( - args: [.headless], - log: FirefoxLog(level: .info), + args: [FirefoxArgs(.headless as FirefoxArgs.Argument)], ) // Initialize the WebDriver on the main actor From 8079608085e7aa8849ad775cf8fb8011035bf480 Mon Sep 17 00:00:00 2001 From: William Date: Thu, 9 Jul 2026 11:50:33 +0200 Subject: [PATCH 04/16] refactor: refactored all tests to unified test suites, initiate for both drivers, all tests pass as expected --- .../SwiftWebDriver/WebDrivers/Driver.swift | 2 + .../ChromeDriverIntegrationTestsBase.swift | 48 ---- ...romeDriverJavascriptIntegrationTests.swift | 76 ----- ...omeDriverDragAndDropIntegrationTests.swift | 42 --- ...eDriverElementHandleIntegrationTests.swift | 145 ---------- ...omeDriverFindElementIntegrationTests.swift | 75 ----- ...meDriverFindElementsIntegrationTests.swift | 113 -------- ...meDriverSetAttributeIntegrationTests.swift | 27 -- ...omeDriverSpecialKeysIntegrationTests.swift | 26 -- ...romeDriverNavigationIntegrationTests.swift | 43 --- .../Start/ChromeDriverStartTests.swift | 25 -- .../DriverJavascriptIntegrationTests.swift | 123 +++++++++ .../DriverIntegrationTest.swift | 100 +++++++ .../DriverDragAndDropIntegrationTests.swift | 59 ++++ .../DriverElementHandleIntegrationTests.swift | 259 ++++++++++++++++++ .../DriverFindElementIntegrationTests.swift | 138 ++++++++++ .../DriverFindElementsIntegrationTests.swift | 170 ++++++++++++ .../DriverPropertyIntegrationTests.swift} | 66 ++++- .../DriverSetAttributeIntegrationTests.swift | 49 ++++ .../DriverSpecialKeysIntegrationTests.swift | 47 ++++ .../FirefoxDriverIntegrationTestsBase.swift | 48 ---- .../Start/FirefoxDriverStartTests.swift | 22 -- .../DriverNavigationIntegrationTests.swift | 71 +++++ .../Start/DriverStartTests.swift | 39 +++ 24 files changed, 1111 insertions(+), 702 deletions(-) delete mode 100644 Tests/SwiftWebDriverIntegrationTests/ChromeDriver/ChromeDriverIntegrationTestsBase.swift delete mode 100644 Tests/SwiftWebDriverIntegrationTests/ChromeDriver/DevTools/ChromeDriverJavascriptIntegrationTests.swift delete mode 100644 Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverDragAndDropIntegrationTests.swift delete mode 100644 Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverElementHandleIntegrationTests.swift delete mode 100644 Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverFindElementIntegrationTests.swift delete mode 100644 Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverFindElementsIntegrationTests.swift delete mode 100644 Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverSetAttributeIntegrationTests.swift delete mode 100644 Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverSpecialKeysIntegrationTests.swift delete mode 100644 Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Navigation/ChromeDriverNavigationIntegrationTests.swift delete mode 100644 Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Start/ChromeDriverStartTests.swift create mode 100644 Tests/SwiftWebDriverIntegrationTests/DevTools/DriverJavascriptIntegrationTests.swift create mode 100644 Tests/SwiftWebDriverIntegrationTests/DriverIntegrationTest.swift create mode 100644 Tests/SwiftWebDriverIntegrationTests/Element/DriverDragAndDropIntegrationTests.swift create mode 100644 Tests/SwiftWebDriverIntegrationTests/Element/DriverElementHandleIntegrationTests.swift create mode 100644 Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementIntegrationTests.swift create mode 100644 Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementsIntegrationTests.swift rename Tests/SwiftWebDriverIntegrationTests/{ChromeDriver/Element/ChromeDriverPropertyIntegrationTests.swift => Element/DriverPropertyIntegrationTests.swift} (51%) create mode 100644 Tests/SwiftWebDriverIntegrationTests/Element/DriverSetAttributeIntegrationTests.swift create mode 100644 Tests/SwiftWebDriverIntegrationTests/Element/DriverSpecialKeysIntegrationTests.swift delete mode 100644 Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/FirefoxDriverIntegrationTestsBase.swift delete mode 100644 Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/Start/FirefoxDriverStartTests.swift create mode 100644 Tests/SwiftWebDriverIntegrationTests/Navigation/DriverNavigationIntegrationTests.swift create mode 100644 Tests/SwiftWebDriverIntegrationTests/Start/DriverStartTests.swift diff --git a/Sources/SwiftWebDriver/WebDrivers/Driver.swift b/Sources/SwiftWebDriver/WebDrivers/Driver.swift index 78ac98d..f815063 100644 --- a/Sources/SwiftWebDriver/WebDrivers/Driver.swift +++ b/Sources/SwiftWebDriver/WebDrivers/Driver.swift @@ -54,6 +54,8 @@ public protocol Driver: FindElementProtocol { func setProperty(element: Element, propertyName: String, newValue: String) async throws func dragAndDrop(from source: Element, to target: Element) async throws + + init(driverURL url: URL, browserObject: BrowserOption) } extension Driver { diff --git a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/ChromeDriverIntegrationTestsBase.swift b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/ChromeDriverIntegrationTestsBase.swift deleted file mode 100644 index f851b01..0000000 --- a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/ChromeDriverIntegrationTestsBase.swift +++ /dev/null @@ -1,48 +0,0 @@ -// ChromeDriverIntegrationTestsBase.swift -// Copyright (c) 2026 GetAutomaApp -// All source code and related assets are the property of GetAutomaApp. -// All rights reserved. - -import Foundation -@testable import SwiftWebDriver - -internal protocol ChromeDriverIntegrationTestsBase { - var driver: WebDriver { get set } - var testPageURL: URL { get } - var baseUrl: String { get } - var page: String { get set } -} - -internal class ChromeDriverTest: ChromeDriverIntegrationTestsBase { - public let baseUrl: String = "http://httpd" - public var testPageURL: URL { - // swiftlint:disable:next force_unwrapping - .init(string: "\(baseUrl)/\(page)")! - } - - public var page: String = "index.html" - public var driver: WebDriver - - public init() async throws { - // swiftlint:disable:next force_unwrapping - let driverURL = URL(string: "http://selenium_chrome:4444")! - let chromeOptions = ChromeOptions(args: [ - ChromeArgs(.disableDevShmUsage), - ChromeArgs(.noSandbox), - ]) - - // Initialize the WebDriver on the main actor - driver = WebDriver( - driver: ChromeDriver( - driverURL: driverURL, - browserObject: chromeOptions - ) - ) - - try await driver.start() - } - - deinit { - // Add deinit here - } -} diff --git a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/DevTools/ChromeDriverJavascriptIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/DevTools/ChromeDriverJavascriptIntegrationTests.swift deleted file mode 100644 index a803826..0000000 --- a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/DevTools/ChromeDriverJavascriptIntegrationTests.swift +++ /dev/null @@ -1,76 +0,0 @@ -// ChromeDriverJavascriptIntegrationTests.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 Foundation -@testable import SwiftWebDriver -import Testing - -@Suite("Chrome Driver Javascript Sync", .serialized) -internal class ChromeDriverJavascriptIntegrationTests: ChromeDriverTest { - @Test("Test sync Javascript Execution", arguments: [ - ("return `${1 + 2}`", "3"), - ("return `${5 - 3}`", "2"), - ("return `${3 * 4}`", "12"), - ("return `${10 / 2}`", "5"), - ("return `Hello, ` + 'World!'", "Hello, World!"), - ("localStorage.setItem('user', 'John'); return localStorage.getItem('user')", "John"), - ("localStorage.setItem('token', 'abc123'); return localStorage.getItem('token')", "abc123"), - ("sessionStorage.setItem('session', 'active'); return sessionStorage.getItem('session')", "active"), - ("let arr = [1, 2, 3]; arr.push(4); return arr.join(',')", "1,2,3,4"), - ("let obj = { name: 'Alice', age: 25 }; obj.age = 26; return `${obj.age}`", "26"), - ("document.body.innerHTML = '

Hello, World!

'; return document.body.innerText", "Hello, World!"), - ]) - public func executeJavascript(input: (String, String)) async throws { - try await driver.navigateTo(url: testPageURL) - let output = try await driver.execute(input.0, args: []) - #expect(output.value?.stringValue == input.1) - - try await driver.stop() - } - - @Test("Test async Javascript Execution", arguments: [ - ( - """ - var callback = arguments[arguments.length - 1]; - setTimeout(function() { callback('Hello from async JavaScript'); }, 2000); - """, - "Hello from async JavaScript" - ), - ]) - public func executeAsyncJavascript(input: (String, String)) async throws { - try await driver.navigateTo(url: testPageURL) - let output = try await driver.execute( - input.0, - args: [], - type: .async - ) - #expect(output.value?.stringValue == input.1) - - try await driver.stop() - } - - @Test("Throws `javascript error` if JS fails") - public func throwSeleniumError() async throws { - do { - try await driver.navigateTo(url: testPageURL) - try await driver.execute("throw new Error('Test Error')", args: []) - try #require(Bool(false)) - } catch { - guard error.isSeleniumError(ofType: .javascriptError) else { - try #require(Bool(false)) - return - } - } - - try await driver.stop() - } - - deinit { - // Add deinit logic here - } -} diff --git a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverDragAndDropIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverDragAndDropIntegrationTests.swift deleted file mode 100644 index c457eb2..0000000 --- a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverDragAndDropIntegrationTests.swift +++ /dev/null @@ -1,42 +0,0 @@ -// ChromeDriverDragAndDropIntegrationTests.swift -// Copyright (c) 2025 GetAutomaApp -// All source code and related assets are the property of GetAutomaApp. -// All rights reserved. - -@testable import SwiftWebDriver -import Testing - -@Suite("Chrome Driver Drag and Drop Integration Tests", .serialized) -internal class ChromeDriverDragAndDropIntegrationTests: ChromeDriverTest { - /// Drag and drop draggable element to another element, testing the `dragAndDrop` method. - /// This test tests the JavaScript script executed in the DOM to drag the draggable element to the other element. - @Test("Drag Element To Another (JavaScript)") - public func dragAndDropDraggableElementToAnother() async throws { - page = "dragTarget.html" - try await dragAndDrop() - } - - /// Drag and drop draggable element to another element, testing the `dragAndDrop` method. - /// This test tests the Actions API request to drag the draggable element to the other element. - @Test("Drag Element To Another (WebDriver Actions API)") - public func dragAndDropElementToAnother() async throws { - page = "dragBox.html" - try await dragAndDrop() - } - - private func dragAndDrop() async throws { - try await driver.navigateTo(urlString: testPageURL.absoluteString) - - let sourceElement = try await driver.findElement(.css(.id("source"))) - let targetElement = try await driver.findElement(.css(.id("target"))) - - try await driver.dragAndDrop(from: sourceElement, to: targetElement) - - let targetElementText = try await driver.getProperty(element: targetElement, propertyName: "innerText").value? - .stringValue - - #expect(targetElementText == "DROPPED!") - } - - deinit {} -} diff --git a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverElementHandleIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverElementHandleIntegrationTests.swift deleted file mode 100644 index 6ac3977..0000000 --- a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverElementHandleIntegrationTests.swift +++ /dev/null @@ -1,145 +0,0 @@ -// ChromeDriverElementHandleIntegrationTests.swift -// Copyright (c) 2026 GetAutomaApp -// All source code and related assets are the property of GetAutomaApp. -// All rights reserved. - -@testable import SwiftWebDriver -import Testing - -@Suite("Chrome Driver Element Handles", .serialized) -internal class ChromeDriverElementHandleIntegrationTests: ChromeDriverTest { - @Test("Click Button") - public func clickButton() async throws { - page = "elementHandleTestPage.html" - - try await driver.navigateTo(urlString: testPageURL.absoluteString) - let button = try await driver.findElement(.css(.id("button"))) - try await button.click() - let test = try await button.text() - #expect(test == "clicked!") - } - - @Test("Double Click Button") - public func doubleClickButton() async throws { - page = "elementHandleTestPage.html" - - try await driver.navigateTo(urlString: testPageURL.absoluteString) - let button = try await driver.findElement(.css(.id("doubleclick"))) - try await button.doubleClick() - let test = try await button.text() - #expect(test == "ii") - } - - @Test("Drag Element To Another") - public func dragElementToAnother() async throws { - page = "dragBox.html" - try await driver.navigateTo(urlString: testPageURL.absoluteString) - - let source = try await driver.findElement(.css(.id("source"))) - let target = try await driver.findElement(.css(.id("target"))) - - try await source.dragAndDrop(to: target) - - let targetText = try await driver.getProperty(element: target, propertyName: "innerText").value?.stringValue - #expect(targetText == "DROPPED!", "Target text should be 'DROPPED!' after pointer drag") - } - - @Test("Get Element Attributes") - public func getAttribute() async throws { - page = "elementHandleTestPage.html" - try await driver.navigateTo(urlString: testPageURL.absoluteString) - - let inputElement = try await driver - .findElement(.css(.id("attribute"))) - let attribute = try await inputElement.attribute(name: "value") - #expect(attribute == "expect attribute") - } - - @Test("Get Element Rect") - public func getRect() async throws { - page = "elementHandleTestPage.html" - try await driver.navigateTo(urlString: testPageURL.absoluteString) - - let element = try await driver - .findElement(.css(.id("rect"))) - - let rect = try await element.rect() - - #expect(rect.height == 100) - #expect(rect.xPosition > 5) - #expect(rect.yPosition > 5) - #expect(rect.width == 100) - } - - @Test("Clear Element") - public func clearElement() async throws { - page = "elementHandleTestPage.html" - try await driver.navigateTo(urlString: testPageURL.absoluteString) - - let inputElement = try await driver - .findElement(.css(.id("clearInputValue"))) - - try await inputElement.clear() - - let text = try await inputElement.text() - #expect(text == "") - } - - @Test("Send Key") - public func sendKey() async throws { - page = "elementHandleTestPage.html" - try await driver.navigateTo(urlString: testPageURL.absoluteString) - let element = try await driver.findElement(.css(.id("sendValue"))) - try await element.send(value: "newValue") - let text = try await driver.execute("return document.querySelector('#sendValue').value").value?.stringValue - #expect(text == "newValue") - } - - @Test("Send Chord") - public func sendChord() async throws { - page = "elementHandleTestPage.html" - try await driver.navigateTo(urlString: testPageURL.absoluteString) - let element = try await driver.findElement(.css(.id("sendValue"))) - try await element.send(value: "newValue") - let text = try await driver.execute("return document.querySelector('#sendValue').value").value?.stringValue - #expect(text == "newValue") - - // Remove text from element - try await element.sendKeys(keys: .CONTROL, characters: "a") - try await element.sendKeys(keys: .BACKSPACE) - let newText = try await driver.execute("return document.querySelector('#sendValue').value").value?.stringValue - #expect(newText == "") - } - - @Test("Get Screenshot") - public func getScreenshot() async throws { - page = "elementHandleTestPage.html" - try await driver.navigateTo(urlString: testPageURL.absoluteString) - let element = try await driver.findElement(.css(.id("sendValue"))) - let elementScreenshot = try await element.screenshot() - let data = elementScreenshot.data(using: .utf8) - #expect(data != nil) - } - - @Test("Fail any operation if element becomes stale") - public func throwStaleError() async throws { - let sleepTotal = 3 - page = "elementHandleTestPage.html" - try await driver.navigateTo(urlString: testPageURL.absoluteString) - let element = try await driver.findElement(.css(.id("willDelete"))) - try await element.click() - - try await Task.sleep(for: .seconds(sleepTotal)) - - do { - try await element.click() - #expect(Bool(false)) - } catch { - #expect(Bool(true)) - } - } - - deinit { - // Add deinit logic here - } -} diff --git a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverFindElementIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverFindElementIntegrationTests.swift deleted file mode 100644 index 2e2f5c9..0000000 --- a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverFindElementIntegrationTests.swift +++ /dev/null @@ -1,75 +0,0 @@ -// ChromeDriverFindElementIntegrationTests.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. - -@testable import SwiftWebDriver -import Testing - -@Suite("Chrome Driver Find Element Tests", .serialized) -internal class ChromeDriverFindElementIntegrationTests: ChromeDriverTest { - @Test("Get Element By CSS Selector") - public func getElementCSSElement() async throws { - page = "index.html" - try await driver.navigateTo(url: testPageURL) - - let classText = try await driver.findElement(.css(.class("classElement"))).text() - #expect(classText == "classElement") - - let idElement = try await driver.findElement(.css(.id("idElement"))).text() - #expect(idElement == "idElement") - - let nameElement = try await driver.findElement(.css(.name("nameElement"))).text() - #expect(nameElement == "nameElement") - } - - @Test("Get Element By XPath") - public func getElementByXPath() async throws { - page = "index.html" - try await driver.navigateTo(url: testPageURL) - - let inParentSingleElement = try await driver.findElement(.xpath("//*[@id=\"inParentSingleElement\"]")).text() - #expect(inParentSingleElement == "inParentSingleElement") - } - - @Test("Get Element By Link Text") - public func getElementByLinkText() async throws { - page = "index.html" - try await driver.navigateTo(url: testPageURL) - - let text = try await driver - .findElement(.linkText("go to next page")) - .text() - #expect(text == "go to next page") - } - - @Test("Get Element By Partial Link") - public func getElementByPartialLink() async throws { - page = "index.html" - try await driver.navigateTo(url: testPageURL) - - let text = try await driver - .findElement(.partialLinkText("go")) - .text() - - #expect(text == "go to next page") - } - - @Test("Get Element By TagName") - public func getElementByTagName() async throws { - page = "index.html" - try await driver.navigateTo(url: testPageURL) - - let text = try await driver - .findElement(.tagName("h1")) - .text() - #expect(text == "this is h1") - } - - deinit { - // no-op - } -} diff --git a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverFindElementsIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverFindElementsIntegrationTests.swift deleted file mode 100644 index 37d5703..0000000 --- a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverFindElementsIntegrationTests.swift +++ /dev/null @@ -1,113 +0,0 @@ -// ChromeDriverFindElementsIntegrationTests.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. - -@testable import SwiftWebDriver -import Testing - -@Suite("Chrome Driver Find Elements Tests", .serialized) -internal class ChromeDriverFindElementsIntegrationTests: ChromeDriverTest { - @Test("Get Elements CSS Elements") - public func getElementsCSSElements() async throws { - page = "findElementsTestPage.html" - try await driver.navigateTo(urlString: testPageURL.absoluteString) - - let expectedElements1Count = 1 - let expectedElements2Count = 2 - - let elements = try await driver.findElements(.css(.class("classElement1"))) - #expect(elements.count == expectedElements1Count) - - let elements2 = try await driver.findElements(.css(.class("classElement2"))) - #expect(elements2.count == expectedElements2Count) - - let idElement1 = try await driver.findElements(.css(.id("idElement1"))) - #expect(idElement1.count == expectedElements1Count) - - let idElement2 = try await driver.findElements(.css(.id("idElement2"))) - #expect(idElement2.count == expectedElements2Count) - - let nameElement1 = try await driver.findElements(.css(.name("nameElement1"))) - #expect(nameElement1.count == expectedElements1Count) - - let nameElement2 = try await driver.findElements(.css(.name("nameElement2"))) - #expect(nameElement2.count == expectedElements2Count) - } - - @Test("Get Elements By XPath") - public func getElementsByXPath() async throws { - page = "findElementsTestPage.html" - try await driver.navigateTo(urlString: testPageURL.absoluteString) - - let xpathFirstLayerElementsCount = 9 - let xpathElements = try await driver - .findElements(.xpath("/html/body/div")) - - #expect(xpathElements.count == xpathFirstLayerElementsCount) - } - - @Test("Get Elements By Link Text") - public func getElementsByLinkText() async throws { - page = "findElementsTestPage.html" - try await driver.navigateTo(urlString: testPageURL.absoluteString) - - let linkElements1Count = 1 - let linkElements2Count = 2 - - let linkElement1 = try await driver - .findElements(.linkText("1linkElement")) - - #expect(linkElement1.count == linkElements1Count) - - let linkElement2 = try await driver - .findElements(.linkText("2linkElements")) - - #expect(linkElement2.count == linkElements2Count) - } - - @Test("Get Elements By Partial Link Text") - public func getElementsByPartialLink() async throws { - let partialLinkElements1Count = 1 - let partialLinkElements2Count = 2 - - page = "findElementsTestPage.html" - try await driver.navigateTo(urlString: testPageURL.absoluteString) - - let linkElement1 = try await driver - .findElements(.partialLinkText("1")) - - #expect(linkElement1.count == partialLinkElements1Count) - - let linkElement2 = try await driver - .findElements(.partialLinkText("2")) - - #expect(linkElement2.count == partialLinkElements2Count) - } - - @Test("Get Elements By Tag Name") - public func getElementByTagName() async throws { - let tagElements1Count = 1 - let tagElements2Count = 2 - - page = "findElementsTestPage.html" - try await driver.navigateTo(urlString: testPageURL.absoluteString) - - let tagElement1 = try await driver - .findElements(.tagName("p")) - - #expect(tagElement1.count == tagElements1Count) - - let tagElement2 = try await driver - .findElements(.tagName("b")) - - #expect(tagElement2.count == tagElements2Count) - } - - deinit { - // Add deinit logic here - } -} diff --git a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverSetAttributeIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverSetAttributeIntegrationTests.swift deleted file mode 100644 index ba63848..0000000 --- a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverSetAttributeIntegrationTests.swift +++ /dev/null @@ -1,27 +0,0 @@ -// ChromeDriverSetAttributeIntegrationTests.swift -// Copyright (c) 2025 GetAutomaApp -// All source code and related assets are the property of GetAutomaApp. -// All rights reserved. - -@testable import SwiftWebDriver -import Testing - -@Suite("Chrome Driver Set Attribute", .serialized) -internal class ChromeDriverSetAttributeIntegrationTests: ChromeDriverTest { - @Test("Set Attribute") - public func setAttribute() async throws { - page = "elementHandleTestPage.html" - try await driver.navigateTo(urlString: testPageURL.absoluteString) - - let element = try await driver.findElement(.css(.id("attribute"))) - let newIdentifier = "newidentifier" - try await driver.setAttribute(element: element, attributeName: "id", newValue: newIdentifier) - - let elementId = try await element.attribute(name: "id") - #expect(elementId == newIdentifier) - } - - deinit { - // Add deinit logic here - } -} diff --git a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverSpecialKeysIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverSpecialKeysIntegrationTests.swift deleted file mode 100644 index 17ae241..0000000 --- a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverSpecialKeysIntegrationTests.swift +++ /dev/null @@ -1,26 +0,0 @@ -// ChromeDriverSpecialKeysIntegrationTests.swift -// Copyright (c) 2026 GetAutomaApp -// All source code and related assets are the property of GetAutomaApp. -// All rights reserved. - -@testable import SwiftWebDriver -import Testing - -@Suite("Chrome Driver Special Keys", .serialized) -internal class ChromeDriverSpecialKeysIntegrationTests: ChromeDriverTest { - @Test("Tab Should Cycle Input Elements Focus") - public func tabCycleInputElementFocus() async throws { - page = "testSpecialKeys.html" - - try await driver.navigateTo(url: testPageURL) - let inputElement = try await driver.findElement(.css(.id("input1"))) - try await inputElement.send(value: .TAB) - try await Task.sleep(for: .seconds(1)) - let activeElement = try await driver.getActiveElement() - #expect(try await activeElement.attribute(name: "id") == "input2") - } - - deinit { - // Add deinit logic here - } -} diff --git a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Navigation/ChromeDriverNavigationIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Navigation/ChromeDriverNavigationIntegrationTests.swift deleted file mode 100644 index 8484b13..0000000 --- a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Navigation/ChromeDriverNavigationIntegrationTests.swift +++ /dev/null @@ -1,43 +0,0 @@ -// ChromeDriverNavigationIntegrationTests.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. - -@testable import SwiftWebDriver -import Testing - -@Suite("Chrome Driver Navigation Tests", .serialized) -internal class ChromeDriverNavigationIntegrationTests: ChromeDriverTest { - @Test("Get Navigation Title") - public func getNavigationTitle() async throws { - page = "awaitTestPage.html" - try await driver.navigateTo(urlString: testPageURL.absoluteString) - - let title = try await driver.navigationTitle() - #expect(title.value != nil) - #expect(title.value == "expect title") - } - - @Test("Wait Until Element Exists") - public func waitUntilElements() async throws { - page = "awaitTestPage.html" - try await driver.navigateTo(urlString: testPageURL.absoluteString) - - try await driver - .findElement(.css(.id("startButton"))) - .click() - - let retries = 5, sleepDuration = 1 - let result = try await driver - .waitUntil(.css(.id("asyncAddElement")), retryCount: retries, durationSeconds: sleepDuration) - - #expect(result) - } - - deinit { - // Add deinit logic here - } -} diff --git a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Start/ChromeDriverStartTests.swift b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Start/ChromeDriverStartTests.swift deleted file mode 100644 index fd60021..0000000 --- a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Start/ChromeDriverStartTests.swift +++ /dev/null @@ -1,25 +0,0 @@ -// ChromeDriverStartTests.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. - -@testable import SwiftWebDriver -import Testing - -@Suite("Chrome Driver Start Tests", .serialized) -internal class ChromeDriverStartTests: ChromeDriverTest { - @Test("Start & Stop") - public func startAndStop() async throws { - let status = try await driver.status() - #expect(status.value.message != "") - let sessionId = try await driver.start() - #expect(sessionId != "") - } - - deinit { - // Add deinit logic here - } -} diff --git a/Tests/SwiftWebDriverIntegrationTests/DevTools/DriverJavascriptIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/DevTools/DriverJavascriptIntegrationTests.swift new file mode 100644 index 0000000..6d8ecec --- /dev/null +++ b/Tests/SwiftWebDriverIntegrationTests/DevTools/DriverJavascriptIntegrationTests.swift @@ -0,0 +1,123 @@ +// DriverJavascriptIntegrationTests.swift +// Copyright (c) 2026 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +import Foundation +@testable import SwiftWebDriver +import Testing + +internal enum JavascriptIntegrationTestCases { + static let syncExecution: [(script: String, expected: String)] = [ + ("return `${1 + 2}`", "3"), + ("return `${5 - 3}`", "2"), + ("return `${3 * 4}`", "12"), + ("return `${10 / 2}`", "5"), + ("return `Hello, ` + 'World!'", "Hello, World!"), + ("localStorage.setItem('user', 'John'); return localStorage.getItem('user')", "John"), + ("localStorage.setItem('token', 'abc123'); return localStorage.getItem('token')", "abc123"), + ("sessionStorage.setItem('session', 'active'); return sessionStorage.getItem('session')", "active"), + ("let arr = [1, 2, 3]; arr.push(4); return arr.join(',')", "1,2,3,4"), + ("let obj = { name: 'Alice', age: 25 }; obj.age = 26; return `${obj.age}`", "26"), + ("document.body.innerHTML = '

Hello, World!

'; return document.body.innerText", "Hello, World!") + ] + + static let asyncExecution: [(script: String, expected: String)] = [ + ( + """ + var callback = arguments[arguments.length - 1]; + setTimeout(function() { callback('Hello from async JavaScript'); }, 2000); + """, + "Hello from async JavaScript" + ) + ] +} + +internal class DriverJavascriptIntegrationTestBase: + DriverIntegrationTest +{ + func runExecuteJavascriptTest(input: (script: String, expected: String)) async throws { + try await driver.navigateTo(url: testPageURL) + + let output = try await driver.execute(input.script, args: []) + + #expect(output.value?.stringValue == input.expected) + } + + func runExecuteAsyncJavascriptTest(input: (script: String, expected: String)) async throws { + try await driver.navigateTo(url: testPageURL) + + let output = try await driver.execute( + input.script, + args: [], + type: .async + ) + + #expect(output.value?.stringValue == input.expected) + } + + func runThrowSeleniumErrorTest() async throws { + do { + try await driver.navigateTo(url: testPageURL) + try await driver.execute("throw new Error('Test Error')", args: []) + try #require(Bool(false)) + } catch { + guard error.isSeleniumError(ofType: .javascriptError) else { + try #require(Bool(false)) + return + } + } + } +} + +@Suite("Chrome Driver Javascript Integration Tests", .serialized) +internal final class ChromeDriverJavascriptIntegrationTests: + DriverJavascriptIntegrationTestBase +{ + @Test( + "Test sync Javascript Execution", + arguments: JavascriptIntegrationTestCases.syncExecution + ) + func executeJavascript(input: (script: String, expected: String)) async throws { + try await runExecuteJavascriptTest(input: input) + } + + @Test( + "Test async Javascript Execution", + arguments: JavascriptIntegrationTestCases.asyncExecution + ) + func executeAsyncJavascript(input: (script: String, expected: String)) async throws { + try await runExecuteAsyncJavascriptTest(input: input) + } + + @Test("Throws `javascript error` if JS fails") + func throwSeleniumError() async throws { + try await runThrowSeleniumErrorTest() + } +} + +@Suite("Firefox Driver Javascript Integration Tests", .serialized) +internal final class FirefoxDriverJavascriptIntegrationTests: + DriverJavascriptIntegrationTestBase +{ + @Test( + "Test sync Javascript Execution", + arguments: JavascriptIntegrationTestCases.syncExecution + ) + func executeJavascript(input: (script: String, expected: String)) async throws { + try await runExecuteJavascriptTest(input: input) + } + + @Test( + "Test async Javascript Execution", + arguments: JavascriptIntegrationTestCases.asyncExecution + ) + func executeAsyncJavascript(input: (script: String, expected: String)) async throws { + try await runExecuteAsyncJavascriptTest(input: input) + } + + @Test("Throws `javascript error` if JS fails") + func throwSeleniumError() async throws { + try await runThrowSeleniumErrorTest() + } +} diff --git a/Tests/SwiftWebDriverIntegrationTests/DriverIntegrationTest.swift b/Tests/SwiftWebDriverIntegrationTests/DriverIntegrationTest.swift new file mode 100644 index 0000000..f6532df --- /dev/null +++ b/Tests/SwiftWebDriverIntegrationTests/DriverIntegrationTest.swift @@ -0,0 +1,100 @@ +// DriverIntegrationTest.swift +// Copyright (c) 2026 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +import Foundation +@testable import SwiftWebDriver + +internal protocol DriverTestConfiguration { + associatedtype ConcreteDriver: Driver + + static var suiteName: String { get } + static var seleniumURL: URL { get } + static var browserObject: ConcreteDriver.BrowserOption { get } +} + +internal enum ChromeTestConfiguration: DriverTestConfiguration { + static let suiteName = "Chrome" + + static let seleniumURL = URL(string: "http://selenium_chrome:4444")! + + nonisolated(unsafe) static let browserObject = ChromeOptions(args: [ + ChromeArgs(.disableDevShmUsage), + ChromeArgs(.noSandbox) + ]) + + typealias ConcreteDriver = ChromeDriver +} + +internal enum FirefoxTestConfiguration: DriverTestConfiguration { + static let suiteName = "Firefox" + + static let seleniumURL = URL(string: "http://selenium_firefox:4444")! + + nonisolated(unsafe) static let browserObject = FirefoxOptions( + args: [ + FirefoxArgs(FirefoxArgs.Argument.headless) + ], + log: FirefoxLog(level: .info) + ) + + typealias ConcreteDriver = FirefoxDriver +} + +internal class DriverIntegrationTest { + public let baseUrl = "http://httpd" + + public var testPageURL: URL { + URL(string: "\(baseUrl)/\(page)")! + } + + public var page = "index.html" + + public var driver: WebDriver + + public required init() async throws { + driver = WebDriver( + driver: Configuration.ConcreteDriver( + driverURL: Configuration.seleniumURL, + browserObject: Configuration.browserObject + ) + ) + + try await driver.start() + } +} + +// internal class ChromeDriverTest: ChromeDriverIntegrationTestsBase { +// public let baseUrl: String = "http://httpd" +// public var testPageURL: URL { +// // swiftlint:disable:next force_unwrapping +// .init(string: "\(baseUrl)/\(page)")! +// } +// +// public var page: String = "index.html" +// public var driver: WebDriver +// +// public init() async throws { +// // swiftlint:disable:next force_unwrapping +// let driverURL = URL(string: "http://selenium_chrome:4444")! +// let chromeOptions = ChromeOptions(args: [ +// ChromeArgs(.disableDevShmUsage), +// Args(.noSandbox), +// ]) +// +// // Initialize the WebDriver on the main actor +// driver = WebDriver( +// driver: ChromeDriver( +// driverURL: driverURL, +// browserObject: chromeOptions +// ) +// ) +// +// try await driver.start() +// } +// +// deinit { +// // Add deinit here +// } +// } diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverDragAndDropIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverDragAndDropIntegrationTests.swift new file mode 100644 index 0000000..98fb9a4 --- /dev/null +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverDragAndDropIntegrationTests.swift @@ -0,0 +1,59 @@ +// ChromeDriverDragAndDropIntegrationTests.swift +// Copyright (c) 2026 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +@testable import SwiftWebDriver +import Testing + +internal class DriverDragAndDropIntegrationTestBase: + DriverIntegrationTest +{ + func runDragAndDropTest(page: String) async throws { + self.page = page + + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let sourceElement = try await driver.findElement(.css(.id("source"))) + let targetElement = try await driver.findElement(.css(.id("target"))) + + try await driver.dragAndDrop(from: sourceElement, to: targetElement) + + let targetElementText = try await driver + .getProperty(element: targetElement, propertyName: "innerText") + .value? + .stringValue + + #expect(targetElementText == "DROPPED!") + } +} + +@Suite("Chrome Driver Drag and Drop Integration Tests", .serialized) +internal final class ChromeDriverDragAndDropIntegrationTests: + DriverDragAndDropIntegrationTestBase +{ + @Test("Drag Element To Another (JavaScript)") + func dragAndDropDraggableElementToAnother() async throws { + try await runDragAndDropTest(page: "dragTarget.html") + } + + @Test("Drag Element To Another (WebDriver Actions API)") + func dragAndDropElementToAnother() async throws { + try await runDragAndDropTest(page: "dragBox.html") + } +} + +@Suite("Firefox Driver Drag and Drop Integration Tests", .serialized) +internal final class FirefoxDriverDragAndDropIntegrationTests: + DriverDragAndDropIntegrationTestBase +{ + @Test("Drag Element To Another (JavaScript)") + func dragAndDropDraggableElementToAnother() async throws { + try await runDragAndDropTest(page: "dragTarget.html") + } + + @Test("Drag Element To Another (WebDriver Actions API)") + func dragAndDropElementToAnother() async throws { + try await runDragAndDropTest(page: "dragBox.html") + } +} diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverElementHandleIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverElementHandleIntegrationTests.swift new file mode 100644 index 0000000..ed9e46e --- /dev/null +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverElementHandleIntegrationTests.swift @@ -0,0 +1,259 @@ +// ChromeDriverElementHandleIntegrationTests.swift +// Copyright (c) 2026 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +@testable import SwiftWebDriver +import Testing + +internal class DriverElementHandleIntegrationTestBase: + DriverIntegrationTest +{ + func runClickButtonTest() async throws { + page = "elementHandleTestPage.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let button = try await driver.findElement(.css(.id("button"))) + try await button.click() + + #expect(try await button.text() == "clicked!") + } + + func runDoubleClickButtonTest() async throws { + page = "elementHandleTestPage.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let button = try await driver.findElement(.css(.id("doubleclick"))) + try await button.doubleClick() + + #expect(try await button.text() == "ii") + } + + func runDragElementToAnotherTest() async throws { + page = "dragBox.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let source = try await driver.findElement(.css(.id("source"))) + let target = try await driver.findElement(.css(.id("target"))) + + try await source.dragAndDrop(to: target) + + let targetText = try await driver + .getProperty(element: target, propertyName: "innerText") + .value? + .stringValue + + #expect(targetText == "DROPPED!", "Target text should be 'DROPPED!' after pointer drag") + } + + func runGetAttributeTest() async throws { + page = "elementHandleTestPage.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let inputElement = try await driver.findElement(.css(.id("attribute"))) + let attribute = try await inputElement.attribute(name: "value") + + #expect(attribute == "expect attribute") + } + + func runGetRectTest() async throws { + page = "elementHandleTestPage.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let element = try await driver.findElement(.css(.id("rect"))) + let rect = try await element.rect() + + #expect(rect.height == 100) + #expect(rect.xPosition > 5) + #expect(rect.yPosition > 5) + #expect(rect.width == 100) + } + + func runClearElementTest() async throws { + page = "elementHandleTestPage.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let inputElement = try await driver.findElement(.css(.id("clearInputValue"))) + try await inputElement.clear() + + #expect(try await inputElement.text() == "") + } + + func runSendKeyTest() async throws { + page = "elementHandleTestPage.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let element = try await driver.findElement(.css(.id("sendValue"))) + try await element.send(value: "newValue") + + let text = try await driver + .execute("return document.querySelector('#sendValue').value") + .value? + .stringValue + + #expect(text == "newValue") + } + + func runSendChordTest() async throws { + page = "elementHandleTestPage.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let element = try await driver.findElement(.css(.id("sendValue"))) + try await element.send(value: "newValue") + + let text = try await driver + .execute("return document.querySelector('#sendValue').value") + .value? + .stringValue + + #expect(text == "newValue") + + try await element.sendKeys(keys: .CONTROL, characters: "a") + try await element.sendKeys(keys: .BACKSPACE) + + let newText = try await driver + .execute("return document.querySelector('#sendValue').value") + .value? + .stringValue + + #expect(newText == "") + } + + func runGetScreenshotTest() async throws { + page = "elementHandleTestPage.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let element = try await driver.findElement(.css(.id("sendValue"))) + let elementScreenshot = try await element.screenshot() + let data = elementScreenshot.data(using: .utf8) + + #expect(data != nil) + } + + func runThrowStaleErrorTest() async throws { + page = "elementHandleTestPage.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let element = try await driver.findElement(.css(.id("willDelete"))) + try await element.click() + + try await Task.sleep(for: .seconds(3)) + + do { + try await element.click() + #expect(Bool(false)) + } catch { + #expect(Bool(true)) + } + } +} + +@Suite("Chrome Driver Element Handles", .serialized) +internal final class ChromeDriverElementHandleIntegrationTests: + DriverElementHandleIntegrationTestBase +{ + @Test("Click Button") + func clickButton() async throws { + try await runClickButtonTest() + } + + @Test("Double Click Button") + func doubleClickButton() async throws { + try await runDoubleClickButtonTest() + } + + @Test("Drag Element To Another") + func dragElementToAnother() async throws { + try await runDragElementToAnotherTest() + } + + @Test("Get Element Attributes") + func getAttribute() async throws { + try await runGetAttributeTest() + } + + @Test("Get Element Rect") + func getRect() async throws { + try await runGetRectTest() + } + + @Test("Clear Element") + func clearElement() async throws { + try await runClearElementTest() + } + + @Test("Send Key") + func sendKey() async throws { + try await runSendKeyTest() + } + + @Test("Send Chord") + func sendChord() async throws { + try await runSendChordTest() + } + + @Test("Get Screenshot") + func getScreenshot() async throws { + try await runGetScreenshotTest() + } + + @Test("Fail any operation if element becomes stale") + func throwStaleError() async throws { + try await runThrowStaleErrorTest() + } +} + +@Suite("Firefox Driver Element Handles", .serialized) +internal final class FirefoxDriverElementHandleIntegrationTests: + DriverElementHandleIntegrationTestBase +{ + @Test("Click Button") + func clickButton() async throws { + try await runClickButtonTest() + } + + @Test("Double Click Button") + func doubleClickButton() async throws { + try await runDoubleClickButtonTest() + } + + @Test("Drag Element To Another") + func dragElementToAnother() async throws { + try await runDragElementToAnotherTest() + } + + @Test("Get Element Attributes") + func getAttribute() async throws { + try await runGetAttributeTest() + } + + @Test("Get Element Rect") + func getRect() async throws { + try await runGetRectTest() + } + + @Test("Clear Element") + func clearElement() async throws { + try await runClearElementTest() + } + + @Test("Send Key") + func sendKey() async throws { + try await runSendKeyTest() + } + + @Test("Send Chord") + func sendChord() async throws { + try await runSendChordTest() + } + + @Test("Get Screenshot") + func getScreenshot() async throws { + try await runGetScreenshotTest() + } + + @Test("Fail any operation if element becomes stale") + func throwStaleError() async throws { + try await runThrowStaleErrorTest() + } +} diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementIntegrationTests.swift new file mode 100644 index 0000000..f0393ec --- /dev/null +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementIntegrationTests.swift @@ -0,0 +1,138 @@ +// DriverFindElementIntegrationTests.swift +// Copyright (c) 2026 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +@testable import SwiftWebDriver +import Testing + +internal class DriverFindElementIntegrationTestBase: + DriverIntegrationTest +{ + func runGetElementCSSElementTest() async throws { + page = "index.html" + try await driver.navigateTo(url: testPageURL) + + let classText = try await driver + .findElement(.css(.class("classElement"))) + .text() + + #expect(classText == "classElement") + + let idElement = try await driver + .findElement(.css(.id("idElement"))) + .text() + + #expect(idElement == "idElement") + + let nameElement = try await driver + .findElement(.css(.name("nameElement"))) + .text() + + #expect(nameElement == "nameElement") + } + + func runGetElementByXPathTest() async throws { + page = "index.html" + try await driver.navigateTo(url: testPageURL) + + let inParentSingleElement = try await driver + .findElement(.xpath("//*[@id=\"inParentSingleElement\"]")) + .text() + + #expect(inParentSingleElement == "inParentSingleElement") + } + + func runGetElementByLinkTextTest() async throws { + page = "index.html" + try await driver.navigateTo(url: testPageURL) + + let text = try await driver + .findElement(.linkText("go to next page")) + .text() + + #expect(text == "go to next page") + } + + func runGetElementByPartialLinkTest() async throws { + page = "index.html" + try await driver.navigateTo(url: testPageURL) + + let text = try await driver + .findElement(.partialLinkText("go")) + .text() + + #expect(text == "go to next page") + } + + func runGetElementByTagNameTest() async throws { + page = "index.html" + try await driver.navigateTo(url: testPageURL) + + let text = try await driver + .findElement(.tagName("h1")) + .text() + + #expect(text == "this is h1") + } +} + +@Suite("Chrome Driver Find Element Tests", .serialized) +internal final class ChromeDriverFindElementIntegrationTests: + DriverFindElementIntegrationTestBase +{ + @Test("Get Element By CSS Selector") + func getElementCSSElement() async throws { + try await runGetElementCSSElementTest() + } + + @Test("Get Element By XPath") + func getElementByXPath() async throws { + try await runGetElementByXPathTest() + } + + @Test("Get Element By Link Text") + func getElementByLinkText() async throws { + try await runGetElementByLinkTextTest() + } + + @Test("Get Element By Partial Link") + func getElementByPartialLink() async throws { + try await runGetElementByPartialLinkTest() + } + + @Test("Get Element By TagName") + func getElementByTagName() async throws { + try await runGetElementByTagNameTest() + } +} + +@Suite("Firefox Driver Find Element Tests", .serialized) +internal final class FirefoxDriverFindElementIntegrationTests: + DriverFindElementIntegrationTestBase +{ + @Test("Get Element By CSS Selector") + func getElementCSSElement() async throws { + try await runGetElementCSSElementTest() + } + + @Test("Get Element By XPath") + func getElementByXPath() async throws { + try await runGetElementByXPathTest() + } + + @Test("Get Element By Link Text") + func getElementByLinkText() async throws { + try await runGetElementByLinkTextTest() + } + + @Test("Get Element By Partial Link") + func getElementByPartialLink() async throws { + try await runGetElementByPartialLinkTest() + } + + @Test("Get Element By TagName") + func getElementByTagName() async throws { + try await runGetElementByTagNameTest() + } +} diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementsIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementsIntegrationTests.swift new file mode 100644 index 0000000..1c112a1 --- /dev/null +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementsIntegrationTests.swift @@ -0,0 +1,170 @@ +// DriverFindElementsIntegrationTests.swift +// Copyright (c) 2026 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +@testable import SwiftWebDriver +import Testing + +internal class DriverFindElementsIntegrationTestBase: + DriverIntegrationTest +{ + func runGetElementsCSSElementsTest() async throws { + page = "findElementsTestPage.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let expectedElements1Count = 1 + let expectedElements2Count = 2 + + let elements = try await driver.findElements(.css(.class("classElement1"))) + #expect(elements.count == expectedElements1Count) + + let elements2 = try await driver.findElements(.css(.class("classElement2"))) + #expect(elements2.count == expectedElements2Count) + + let idElement1 = try await driver.findElements(.css(.id("idElement1"))) + #expect(idElement1.count == expectedElements1Count) + + let idElement2 = try await driver.findElements(.css(.id("idElement2"))) + #expect(idElement2.count == expectedElements2Count) + + let nameElement1 = try await driver.findElements(.css(.name("nameElement1"))) + #expect(nameElement1.count == expectedElements1Count) + + let nameElement2 = try await driver.findElements(.css(.name("nameElement2"))) + #expect(nameElement2.count == expectedElements2Count) + } + + func runGetElementsByXPathTest() async throws { + page = "findElementsTestPage.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let xpathFirstLayerElementsCount = 9 + + let xpathElements = try await driver.findElements( + .xpath("/html/body/div") + ) + + #expect(xpathElements.count == xpathFirstLayerElementsCount) + } + + func runGetElementsByLinkTextTest() async throws { + page = "findElementsTestPage.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let linkElements1Count = 1 + let linkElements2Count = 2 + + let linkElement1 = try await driver.findElements( + .linkText("1linkElement") + ) + + #expect(linkElement1.count == linkElements1Count) + + let linkElement2 = try await driver.findElements( + .linkText("2linkElements") + ) + + #expect(linkElement2.count == linkElements2Count) + } + + func runGetElementsByPartialLinkTest() async throws { + page = "findElementsTestPage.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let partialLinkElements1Count = 1 + let partialLinkElements2Count = 2 + + let linkElement1 = try await driver.findElements( + .partialLinkText("1") + ) + + #expect(linkElement1.count == partialLinkElements1Count) + + let linkElement2 = try await driver.findElements( + .partialLinkText("2") + ) + + #expect(linkElement2.count == partialLinkElements2Count) + } + + func runGetElementsByTagNameTest() async throws { + page = "findElementsTestPage.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let tagElements1Count = 1 + let tagElements2Count = 2 + + let tagElement1 = try await driver.findElements( + .tagName("p") + ) + + #expect(tagElement1.count == tagElements1Count) + + let tagElement2 = try await driver.findElements( + .tagName("b") + ) + + #expect(tagElement2.count == tagElements2Count) + } +} + +@Suite("Chrome Driver Find Elements Tests", .serialized) +internal final class ChromeDriverFindElementsIntegrationTests: + DriverFindElementsIntegrationTestBase +{ + @Test("Get Elements CSS Elements") + func getElementsCSSElements() async throws { + try await runGetElementsCSSElementsTest() + } + + @Test("Get Elements By XPath") + func getElementsByXPath() async throws { + try await runGetElementsByXPathTest() + } + + @Test("Get Elements By Link Text") + func getElementsByLinkText() async throws { + try await runGetElementsByLinkTextTest() + } + + @Test("Get Elements By Partial Link Text") + func getElementsByPartialLink() async throws { + try await runGetElementsByPartialLinkTest() + } + + @Test("Get Elements By Tag Name") + func getElementByTagName() async throws { + try await runGetElementsByTagNameTest() + } +} + +@Suite("Firefox Driver Find Elements Tests", .serialized) +internal final class FirefoxDriverFindElementsIntegrationTests: + DriverFindElementsIntegrationTestBase +{ + @Test("Get Elements CSS Elements") + func getElementsCSSElements() async throws { + try await runGetElementsCSSElementsTest() + } + + @Test("Get Elements By XPath") + func getElementsByXPath() async throws { + try await runGetElementsByXPathTest() + } + + @Test("Get Elements By Link Text") + func getElementsByLinkText() async throws { + try await runGetElementsByLinkTextTest() + } + + @Test("Get Elements By Partial Link Text") + func getElementsByPartialLink() async throws { + try await runGetElementsByPartialLinkTest() + } + + @Test("Get Elements By Tag Name") + func getElementByTagName() async throws { + try await runGetElementsByTagNameTest() + } +} diff --git a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverPropertyIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverPropertyIntegrationTests.swift similarity index 51% rename from Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverPropertyIntegrationTests.swift rename to Tests/SwiftWebDriverIntegrationTests/Element/DriverPropertyIntegrationTests.swift index 2c594ba..4d47a86 100644 --- a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverPropertyIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverPropertyIntegrationTests.swift @@ -1,26 +1,33 @@ -// ChromeDriverPropertyIntegrationTests.swift -// Copyright (c) 2025 GetAutomaApp +// DriverPropertyIntegrationTests.swift +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. @testable import SwiftWebDriver import Testing -@Suite("Chrome Driver Property Integration Tests", .serialized) -internal class ChromeDriverPropertyIntegrationTests: ChromeDriverTest { +internal class DriverPropertyIntegrationTestBase: + DriverIntegrationTest +{ /// Test `getProperty()` method, a method to get a specific property value from an element. - @Test("Get Property") - public func getProperty() async throws { + func runGetPropertyTest() async throws { page = "elementHandleTestPage.html" try await driver.navigateTo(urlString: testPageURL.absoluteString) + let updatedElementValue = "NewElementValue" + try await driver.execute(""" let element = document.getElementById('attribute') element.value = '\(updatedElementValue)' """) + let element = try await driver.findElement(.css(.id("attribute"))) + guard - let elementValue = try await driver.getProperty(element: element, propertyName: "value").value?.stringValue + let elementValue = try await driver + .getProperty(element: element, propertyName: "value") + .value? + .stringValue else { #expect(Bool(false), "Could not convert element value to string value") return @@ -30,16 +37,23 @@ internal class ChromeDriverPropertyIntegrationTests: ChromeDriverTest { } /// Test `setProperty()` method, a method to set a specific property value from an element. - @Test("Set Property") - public func setProperty() async throws { + func runSetPropertyTest() async throws { page = "elementHandleTestPage.html" try await driver.navigateTo(urlString: testPageURL.absoluteString) + let element = try await driver.findElement(.css(.id("setproperty"))) let newPropertyValue = "element new inner text" - try await driver.setProperty(element: element, propertyName: "innerText", newValue: newPropertyValue) + try await driver.setProperty( + element: element, + propertyName: "innerText", + newValue: newPropertyValue + ) + guard - let elementInnerTextValue = try await driver.getProperty(element: element, propertyName: "innerText").value? + let elementInnerTextValue = try await driver + .getProperty(element: element, propertyName: "innerText") + .value? .stringValue else { #expect(Bool(false), "Could not convert element innerText value to string value") @@ -48,6 +62,34 @@ internal class ChromeDriverPropertyIntegrationTests: ChromeDriverTest { #expect(newPropertyValue == elementInnerTextValue) } +} + +@Suite("Chrome Driver Property Integration Tests", .serialized) +internal final class ChromeDriverPropertyIntegrationTests: + DriverPropertyIntegrationTestBase +{ + @Test("Get Property") + func getProperty() async throws { + try await runGetPropertyTest() + } + + @Test("Set Property") + func setProperty() async throws { + try await runSetPropertyTest() + } +} + +@Suite("Firefox Driver Property Integration Tests", .serialized) +internal final class FirefoxDriverPropertyIntegrationTests: + DriverPropertyIntegrationTestBase +{ + @Test("Get Property") + func getProperty() async throws { + try await runGetPropertyTest() + } - deinit {} + @Test("Set Property") + func setProperty() async throws { + try await runSetPropertyTest() + } } diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverSetAttributeIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverSetAttributeIntegrationTests.swift new file mode 100644 index 0000000..bd73615 --- /dev/null +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverSetAttributeIntegrationTests.swift @@ -0,0 +1,49 @@ +// DriverSetAttributeIntegrationTests.swift +// Copyright (c) 2026 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +@testable import SwiftWebDriver +import Testing + +internal class DriverSetAttributeIntegrationTestBase: + DriverIntegrationTest +{ + func runSetAttributeTest() async throws { + page = "elementHandleTestPage.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let element = try await driver.findElement(.css(.id("attribute"))) + let newIdentifier = "newidentifier" + + try await driver.setAttribute( + element: element, + attributeName: "id", + newValue: newIdentifier + ) + + let elementId = try await element.attribute(name: "id") + + #expect(elementId == newIdentifier) + } +} + +@Suite("Chrome Driver Set Attribute", .serialized) +internal final class ChromeDriverSetAttributeIntegrationTests: + DriverSetAttributeIntegrationTestBase +{ + @Test("Set Attribute") + func setAttribute() async throws { + try await runSetAttributeTest() + } +} + +@Suite("Firefox Driver Set Attribute", .serialized) +internal final class FirefoxDriverSetAttributeIntegrationTests: + DriverSetAttributeIntegrationTestBase +{ + @Test("Set Attribute") + func setAttribute() async throws { + try await runSetAttributeTest() + } +} diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverSpecialKeysIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverSpecialKeysIntegrationTests.swift new file mode 100644 index 0000000..fc6cf27 --- /dev/null +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverSpecialKeysIntegrationTests.swift @@ -0,0 +1,47 @@ +// DriverSpecialKeysIntegrationTests.swift +// Copyright (c) 2026 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +@testable import SwiftWebDriver +import Testing + +internal class DriverSpecialKeysIntegrationTestBase: + DriverIntegrationTest +{ + func runTabCycleInputElementFocusTest() async throws { + page = "testSpecialKeys.html" + + try await driver.navigateTo(url: testPageURL) + + let inputElement = try await driver.findElement(.css(.id("input1"))) + try await inputElement.send(value: .TAB) + + try await Task.sleep(for: .seconds(1)) + + let activeElement = try await driver.getActiveElement() + let activeElementId = try await activeElement.attribute(name: "id") + + #expect(activeElementId == "input2") + } +} + +@Suite("Chrome Driver Special Keys", .serialized) +internal final class ChromeDriverSpecialKeysIntegrationTests: + DriverSpecialKeysIntegrationTestBase +{ + @Test("Tab Should Cycle Input Elements Focus") + func tabCycleInputElementFocus() async throws { + try await runTabCycleInputElementFocusTest() + } +} + +@Suite("Firefox Driver Special Keys", .serialized) +internal final class FirefoxDriverSpecialKeysIntegrationTests: + DriverSpecialKeysIntegrationTestBase +{ + @Test("Tab Should Cycle Input Elements Focus") + func tabCycleInputElementFocus() async throws { + try await runTabCycleInputElementFocusTest() + } +} diff --git a/Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/FirefoxDriverIntegrationTestsBase.swift b/Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/FirefoxDriverIntegrationTestsBase.swift deleted file mode 100644 index f9e6919..0000000 --- a/Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/FirefoxDriverIntegrationTestsBase.swift +++ /dev/null @@ -1,48 +0,0 @@ -// FirefoxDriverIntegrationTestsBase.swift -// Copyright (c) 2026 GetAutomaApp -// All source code and related assets are the property of GetAutomaApp. -// All rights reserved. - -import Foundation -@testable import SwiftWebDriver - -internal protocol FirefoxDriverIntegrationTestsBase { - var driver: WebDriver { get set } - var testPageURL: URL { get } - var baseUrl: String { get } - var page: String { get set } -} - -internal class FirefoxDriverTest: FirefoxDriverIntegrationTestsBase { - public let baseUrl: String = "http://localhost" - public var testPageURL: URL { - // swiftlint:disable:next force_unwrapping - .init(string: "\(baseUrl)/\(page)")! - } - - public var page: String = "index.html" - public var driver: WebDriver - - public init() async throws { - // swiftlint:disable:next force_unwrapping - let driverURL = URL(string: "http://selenium_firefox:4444")! - - let firefoxOptions = FirefoxOptions( - args: [FirefoxArgs(.headless as FirefoxArgs.Argument)], - ) - - // Initialize the WebDriver on the main actor - driver = WebDriver( - driver: FirefoxDriver( - driverURL: driverURL, - browserObject: firefoxOptions - ) - ) - - try await driver.start() - } - - deinit { - // Add deinit here - } -} diff --git a/Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/Start/FirefoxDriverStartTests.swift b/Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/Start/FirefoxDriverStartTests.swift deleted file mode 100644 index 14169ca..0000000 --- a/Tests/SwiftWebDriverIntegrationTests/FirefoxDriver/Start/FirefoxDriverStartTests.swift +++ /dev/null @@ -1,22 +0,0 @@ -// FirefoxDriverStartTests.swift -// Copyright (c) 2026 GetAutomaApp -// All source code and related assets are the property of GetAutomaApp. -// All rights reserved. - -@testable import SwiftWebDriver -import Testing - -@Suite("Firefox Driver Start Tests", .serialized) -internal class FirefoxDriverStartTests: FirefoxDriverTest { - @Test("Start & Stop") - public func startAndStop() async throws { - let status = try await driver.status() - #expect(status.value.message != "") - let sessionId = try await driver.start() - #expect(sessionId != "") - } - - deinit { - // Add deinit logic here - } -} diff --git a/Tests/SwiftWebDriverIntegrationTests/Navigation/DriverNavigationIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Navigation/DriverNavigationIntegrationTests.swift new file mode 100644 index 0000000..7da37bf --- /dev/null +++ b/Tests/SwiftWebDriverIntegrationTests/Navigation/DriverNavigationIntegrationTests.swift @@ -0,0 +1,71 @@ +// DriverNavigationIntegrationTests.swift +// Copyright (c) 2026 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +@testable import SwiftWebDriver +import Testing + +internal class DriverNavigationIntegrationTestBase: + DriverIntegrationTest +{ + func runGetNavigationTitleTest() async throws { + page = "awaitTestPage.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let title = try await driver.navigationTitle() + + #expect(title.value != nil) + #expect(title.value == "expect title") + } + + func runWaitUntilElementsTest() async throws { + page = "awaitTestPage.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + try await driver + .findElement(.css(.id("startButton"))) + .click() + + let retries = 5 + let sleepDuration = 1 + + let result = try await driver.waitUntil( + .css(.id("asyncAddElement")), + retryCount: retries, + durationSeconds: sleepDuration + ) + + #expect(result) + } +} + +@Suite("Chrome Driver Navigation Tests", .serialized) +internal final class ChromeDriverNavigationIntegrationTests: + DriverNavigationIntegrationTestBase +{ + @Test("Get Navigation Title") + func getNavigationTitle() async throws { + try await runGetNavigationTitleTest() + } + + @Test("Wait Until Element Exists") + func waitUntilElements() async throws { + try await runWaitUntilElementsTest() + } +} + +@Suite("Firefox Driver Navigation Tests", .serialized) +internal final class FirefoxDriverNavigationIntegrationTests: + DriverNavigationIntegrationTestBase +{ + @Test("Get Navigation Title") + func getNavigationTitle() async throws { + try await runGetNavigationTitleTest() + } + + @Test("Wait Until Element Exists") + func waitUntilElements() async throws { + try await runWaitUntilElementsTest() + } +} diff --git a/Tests/SwiftWebDriverIntegrationTests/Start/DriverStartTests.swift b/Tests/SwiftWebDriverIntegrationTests/Start/DriverStartTests.swift new file mode 100644 index 0000000..b0d5ece --- /dev/null +++ b/Tests/SwiftWebDriverIntegrationTests/Start/DriverStartTests.swift @@ -0,0 +1,39 @@ +// DriverStartTests.swift +// Copyright (c) 2026 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +@testable import SwiftWebDriver +import Testing + +internal class DriverStartTestBase: + DriverIntegrationTest +{ + func runStartAndStopTest() async throws { + let status = try await driver.status() + #expect(status.value.message != "") + + let sessionId = try await driver.start() + #expect(sessionId != "") + } +} + +@Suite("Chrome Driver Start Tests", .serialized) +internal final class ChromeDriverStartTests: + DriverStartTestBase +{ + @Test("Start & Stop") + func startAndStop() async throws { + try await runStartAndStopTest() + } +} + +@Suite("Firefox Driver Start Tests", .serialized) +internal final class FirefoxDriverStartTests: + DriverStartTestBase +{ + @Test("Start & Stop") + func startAndStop() async throws { + try await runStartAndStopTest() + } +} From a301ef2f61bc5a2cbb085a6a5f8dafb73fceb210 Mon Sep 17 00:00:00 2001 From: William Date: Thu, 9 Jul 2026 12:18:03 +0200 Subject: [PATCH 05/16] fix: fixed some linting issues, hopefully fixed all-tests workflow by fixing docker-compose service names --- .github/workflows/run-all-tests.yml | 10 +++++----- .../SeleniumSwiftExampleTests.swift | 5 +---- Sources/SwiftWebDriver/API/APIClient.swift | 6 +++--- .../SwiftWebDriver/API/Request/ActionsPayload.swift | 2 +- .../API/Request/DevTools/AnyEncodable.swift | 2 +- .../API/Request/DevTools/DevToolTypes.swift | 2 +- .../API/Request/DevTools/PostExecuteRequest.swift | 2 +- .../Request/Elements/GetElementAttributeRequest.swift | 5 +---- .../Elements/GetElementNamePropertyRequest.swift | 5 +---- .../API/Request/Elements/GetElementNameRequest.swift | 5 +---- .../Elements/GetElementPropertyNameRequest.swift | 5 +---- .../API/Request/Elements/GetElementRectRequest.swift | 10 +++++++--- .../Request/Elements/GetElementScreenShotRequest.swift | 5 +---- .../Request/Elements/GetElementSelectedRequest.swift | 5 +---- .../API/Request/Elements/GetElementTextRequest.swift | 5 +---- .../API/Request/Elements/GetScreenShotRequest.swift | 5 +---- .../Elements/GetSessionActiveElementRequest.swift | 8 ++------ .../API/Request/Elements/PostElementByIdRequest.swift | 5 +---- .../API/Request/Elements/PostElementClearRequest.swift | 5 +---- .../API/Request/Elements/PostElementClickRequest.swift | 5 +---- .../Elements/PostElementDoubleClickRequest.swift | 2 +- .../Elements/PostElementDragAndDropRequest.swift | 2 +- .../API/Request/Elements/PostElementRequest.swift | 5 +---- .../Request/Elements/PostElementSendValueRequest.swift | 5 +---- .../API/Request/Elements/PostElementsByIdRequest.swift | 5 +---- .../API/Request/Elements/PostElementsRequest.swift | 5 +---- .../API/Request/Navigation/GetNavigationRequest.swift | 5 +---- .../Request/Navigation/GetNavigationTitleRequest.swift | 5 +---- .../Request/Navigation/PostNavigationBackRequest.swift | 9 +++------ .../Navigation/PostNavigationForwardRequest.swift | 5 +---- .../Navigation/PostNavigationRefreshRequest.swift | 5 +---- .../API/Request/Navigation/PostNavigationRequest.swift | 5 +---- Sources/SwiftWebDriver/API/Request/RequestType.swift | 2 +- .../API/Request/Sessions/DeleteSessionRequest.swift | 5 +---- .../API/Request/Sessions/StatusRequest.swift | 5 +---- .../API/Response/DevTools/PostExecuteResponse.swift | 5 +---- .../Elements/GetElementAttributeResponse.swift | 5 +---- .../Elements/GetElementNamePropertyResponse.swift | 5 +---- .../API/Response/Elements/GetElementNameResponse.swift | 5 +---- .../Elements/GetElementPropertyNameResponse.swift | 5 +---- .../API/Response/Elements/GetElementRectResponse.swift | 2 +- .../Elements/GetElementScreenShotResponse.swift | 5 +---- .../Response/Elements/GetElementSelectedResponse.swift | 5 +---- .../API/Response/Elements/GetElementTextResponse.swift | 5 +---- .../API/Response/Elements/GetScreenShotResponse.swift | 5 +---- .../Elements/GetSessionActiveElementResponse.swift | 5 +---- .../Response/Elements/PostElementByIdResponse.swift | 5 +---- .../Response/Elements/PostElementClearResponse.swift | 5 +---- .../Response/Elements/PostElementClickResponse.swift | 5 +---- .../API/Response/Elements/PostElementResponse.swift | 5 +---- .../Elements/PostElementSendValueResponse.swift | 5 +---- .../Response/Elements/PostElementsByIdResponse.swift | 5 +---- .../API/Response/Elements/PostElementsResponse.swift | 5 +---- .../Response/Navigation/GetNavigationResponse.swift | 5 +---- .../Navigation/GetNavigationTitleResponse.swift | 5 +---- .../Navigation/PostNavigationBackResponse.swift | 5 +---- .../Navigation/PostNavigationForwardResponse.swift | 7 ++----- .../Navigation/PostNavigationRefreshResponse.swift | 5 +---- .../Response/Navigation/PostNavigationResponse.swift | 7 ++----- Sources/SwiftWebDriver/API/Response/ResponseType.swift | 5 +---- .../API/Response/Sessions/DeleteSessionResponse.swift | 5 +---- .../API/Response/Sessions/NewSessionResponse.swift | 5 +---- .../API/Response/Sessions/StatusResponse.swift | 5 +---- Sources/SwiftWebDriver/Element/ElementRect.swift | 2 +- Sources/SwiftWebDriver/Element/Elements.swift | 4 ++-- .../SwiftWebDriver/Element/Selector/CSSSelector.swift | 5 +---- .../Element/Selector/LocatorSelector.swift | 5 +---- .../SwiftWebDriver/Element/Selector/LocatorType.swift | 5 +---- Sources/SwiftWebDriver/Error/SeleniumError.swift | 2 +- Sources/SwiftWebDriver/Error/WebDriverError.swift | 5 +---- Sources/SwiftWebDriver/WebDriver.swift | 2 +- .../WebDrivers/Firefox/FirefoxDriver.swift | 4 ++-- .../Element/DriverDragAndDropIntegrationTests.swift | 2 +- .../Element/DriverElementHandleIntegrationTests.swift | 2 +- .../Element/DriverSpecialKeysIntegrationTests.swift | 6 +++--- 75 files changed, 96 insertions(+), 261 deletions(-) diff --git a/.github/workflows/run-all-tests.yml b/.github/workflows/run-all-tests.yml index 1822eaf..24e1efe 100644 --- a/.github/workflows/run-all-tests.yml +++ b/.github/workflows/run-all-tests.yml @@ -3,7 +3,7 @@ name: Run All Tests on: pull_request: paths: - - '**.swift' + - "**.swift" jobs: all-tests: @@ -19,15 +19,15 @@ jobs: id: cache-build uses: actions/cache@v3 with: - key: tests-build-cache-${{ hashFiles('Package.resolved') }}-${{ github.ref_name }} - path: ./.build + key: tests-build-cache-${{ hashFiles('Package.resolved') }}-${{ github.ref_name }} + path: ./.build - name: Run All Tests uses: GetAutomaApp/opensource-actions/swifttesting@main with: compose: "true" - required_healthy_services_docker_compose: '["selenium", "httpd"]' - compose_services_to_startup: '["selenium", "httpd"]' + required_healthy_services_docker_compose: '["selenium_chrome", "selenium_firefox", "httpd"]' + compose_services_to_startup: '["selenium_chrome", "selenium_firefox", "httpd"]' env: PATH: "/usr/local/bin:/usr/bin:/bin" diff --git a/Example/Tests/SeleniumSwiftExampleTests/SeleniumSwiftExampleTests.swift b/Example/Tests/SeleniumSwiftExampleTests/SeleniumSwiftExampleTests.swift index 97835cb..6df5322 100644 --- a/Example/Tests/SeleniumSwiftExampleTests/SeleniumSwiftExampleTests.swift +++ b/Example/Tests/SeleniumSwiftExampleTests/SeleniumSwiftExampleTests.swift @@ -1,10 +1,7 @@ // SeleniumSwiftExampleTests.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 class Foundation.Bundle import XCTest diff --git a/Sources/SwiftWebDriver/API/APIClient.swift b/Sources/SwiftWebDriver/API/APIClient.swift index 3095cea..7439f79 100644 --- a/Sources/SwiftWebDriver/API/APIClient.swift +++ b/Sources/SwiftWebDriver/API/APIClient.swift @@ -1,5 +1,5 @@ // APIClient.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. @@ -47,7 +47,7 @@ internal struct APIClient { /// - `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(_ request: R) -> EventLoopFuture where R: RequestType { + public func request(_ request: R) -> EventLoopFuture { httpClient.execute(request: request).flatMapResult { response -> Result in guard response.status == .ok else { if @@ -89,7 +89,7 @@ internal struct APIClient { /// - `APIError.responseBodyIsNil` if no response body is returned. /// - Any `DecodingError` if the response cannot be decoded. @discardableResult - public func request(_ request: R) async throws -> R.Response where R: RequestType { + public func request(_ request: R) async throws -> R.Response { try await self.request(request).get() } } diff --git a/Sources/SwiftWebDriver/API/Request/ActionsPayload.swift b/Sources/SwiftWebDriver/API/Request/ActionsPayload.swift index 4a44171..47336cf 100644 --- a/Sources/SwiftWebDriver/API/Request/ActionsPayload.swift +++ b/Sources/SwiftWebDriver/API/Request/ActionsPayload.swift @@ -1,5 +1,5 @@ // ActionsPayload.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. diff --git a/Sources/SwiftWebDriver/API/Request/DevTools/AnyEncodable.swift b/Sources/SwiftWebDriver/API/Request/DevTools/AnyEncodable.swift index 076ec3e..06db586 100644 --- a/Sources/SwiftWebDriver/API/Request/DevTools/AnyEncodable.swift +++ b/Sources/SwiftWebDriver/API/Request/DevTools/AnyEncodable.swift @@ -1,5 +1,5 @@ // AnyEncodable.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. diff --git a/Sources/SwiftWebDriver/API/Request/DevTools/DevToolTypes.swift b/Sources/SwiftWebDriver/API/Request/DevTools/DevToolTypes.swift index 9a85032..d0600ed 100644 --- a/Sources/SwiftWebDriver/API/Request/DevTools/DevToolTypes.swift +++ b/Sources/SwiftWebDriver/API/Request/DevTools/DevToolTypes.swift @@ -1,5 +1,5 @@ // DevToolTypes.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. diff --git a/Sources/SwiftWebDriver/API/Request/DevTools/PostExecuteRequest.swift b/Sources/SwiftWebDriver/API/Request/DevTools/PostExecuteRequest.swift index 5ea476c..2d1a5d7 100644 --- a/Sources/SwiftWebDriver/API/Request/DevTools/PostExecuteRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/DevTools/PostExecuteRequest.swift @@ -1,5 +1,5 @@ // PostExecuteRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. diff --git a/Sources/SwiftWebDriver/API/Request/Elements/GetElementAttributeRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/GetElementAttributeRequest.swift index 994ce6f..f1006e6 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/GetElementAttributeRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/GetElementAttributeRequest.swift @@ -1,10 +1,7 @@ // GetElementAttributeRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Elements/GetElementNamePropertyRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/GetElementNamePropertyRequest.swift index 9d21ca2..368e2a4 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/GetElementNamePropertyRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/GetElementNamePropertyRequest.swift @@ -1,10 +1,7 @@ // GetElementNamePropertyRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Elements/GetElementNameRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/GetElementNameRequest.swift index 3c424e8..49b147d 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/GetElementNameRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/GetElementNameRequest.swift @@ -1,10 +1,7 @@ // GetElementNameRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Elements/GetElementPropertyNameRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/GetElementPropertyNameRequest.swift index c525806..4034b34 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/GetElementPropertyNameRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/GetElementPropertyNameRequest.swift @@ -1,10 +1,7 @@ // GetElementPropertyNameRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Elements/GetElementRectRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/GetElementRectRequest.swift index 9a4073b..615c93e 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/GetElementRectRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/GetElementRectRequest.swift @@ -1,5 +1,5 @@ // GetElementRectRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. @@ -25,7 +25,9 @@ internal struct GetElementRectRequest: RequestType { public var elementId: String /// Endpoint path for retrieving the element rectangle. - public var path: String { "session/\(sessionId)/element/\(elementId)/rect" } + public var path: String { + "session/\(sessionId)/element/\(elementId)/rect" + } /// HTTP method used for this request (`GET`). public var method: HTTPMethod = .GET @@ -34,5 +36,7 @@ internal struct GetElementRectRequest: RequestType { public var headers: HTTPHeaders = [:] /// HTTP request body (none required for this request). - public var body: HTTPClient.Body? { nil } + public var body: HTTPClient.Body? { + nil + } } diff --git a/Sources/SwiftWebDriver/API/Request/Elements/GetElementScreenShotRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/GetElementScreenShotRequest.swift index 07aa560..569774b 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/GetElementScreenShotRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/GetElementScreenShotRequest.swift @@ -1,10 +1,7 @@ // GetElementScreenShotRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Elements/GetElementSelectedRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/GetElementSelectedRequest.swift index 406896f..1c80b4e 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/GetElementSelectedRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/GetElementSelectedRequest.swift @@ -1,10 +1,7 @@ // GetElementSelectedRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Elements/GetElementTextRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/GetElementTextRequest.swift index a9783da..5fd32af 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/GetElementTextRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/GetElementTextRequest.swift @@ -1,10 +1,7 @@ // GetElementTextRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Elements/GetScreenShotRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/GetScreenShotRequest.swift index 63eed89..d99687e 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/GetScreenShotRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/GetScreenShotRequest.swift @@ -1,10 +1,7 @@ // GetScreenShotRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Elements/GetSessionActiveElementRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/GetSessionActiveElementRequest.swift index 971a0d1..4495c17 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/GetSessionActiveElementRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/GetSessionActiveElementRequest.swift @@ -1,14 +1,10 @@ // GetSessionActiveElementRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation import AsyncHTTPClient +import Foundation import NIO import NIOHTTP1 diff --git a/Sources/SwiftWebDriver/API/Request/Elements/PostElementByIdRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/PostElementByIdRequest.swift index acf9974..347065c 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/PostElementByIdRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/PostElementByIdRequest.swift @@ -1,10 +1,7 @@ // PostElementByIdRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Elements/PostElementClearRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/PostElementClearRequest.swift index 5510447..93db575 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/PostElementClearRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/PostElementClearRequest.swift @@ -1,10 +1,7 @@ // PostElementClearRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Elements/PostElementClickRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/PostElementClickRequest.swift index 926d6b8..353bb70 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/PostElementClickRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/PostElementClickRequest.swift @@ -1,10 +1,7 @@ // PostElementClickRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Elements/PostElementDoubleClickRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/PostElementDoubleClickRequest.swift index c789f18..cbce474 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/PostElementDoubleClickRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/PostElementDoubleClickRequest.swift @@ -1,5 +1,5 @@ // PostElementDoubleClickRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. diff --git a/Sources/SwiftWebDriver/API/Request/Elements/PostElementDragAndDropRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/PostElementDragAndDropRequest.swift index cb2ec9c..a5137dd 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/PostElementDragAndDropRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/PostElementDragAndDropRequest.swift @@ -1,5 +1,5 @@ // PostElementDragAndDropRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. diff --git a/Sources/SwiftWebDriver/API/Request/Elements/PostElementRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/PostElementRequest.swift index 60f0043..e8b0b88 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/PostElementRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/PostElementRequest.swift @@ -1,10 +1,7 @@ // PostElementRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Elements/PostElementSendValueRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/PostElementSendValueRequest.swift index 5027dbe..9cae6d4 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/PostElementSendValueRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/PostElementSendValueRequest.swift @@ -1,10 +1,7 @@ // PostElementSendValueRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Elements/PostElementsByIdRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/PostElementsByIdRequest.swift index 9214dd5..7419683 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/PostElementsByIdRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/PostElementsByIdRequest.swift @@ -1,10 +1,7 @@ // PostElementsByIdRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Elements/PostElementsRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/PostElementsRequest.swift index 2871b47..2f7f7d4 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/PostElementsRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/PostElementsRequest.swift @@ -1,10 +1,7 @@ // PostElementsRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Navigation/GetNavigationRequest.swift b/Sources/SwiftWebDriver/API/Request/Navigation/GetNavigationRequest.swift index 72daf36..7a41d5e 100644 --- a/Sources/SwiftWebDriver/API/Request/Navigation/GetNavigationRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Navigation/GetNavigationRequest.swift @@ -1,10 +1,7 @@ // GetNavigationRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Navigation/GetNavigationTitleRequest.swift b/Sources/SwiftWebDriver/API/Request/Navigation/GetNavigationTitleRequest.swift index c5ea272..a54da29 100644 --- a/Sources/SwiftWebDriver/API/Request/Navigation/GetNavigationTitleRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Navigation/GetNavigationTitleRequest.swift @@ -1,10 +1,7 @@ // GetNavigationTitleRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Navigation/PostNavigationBackRequest.swift b/Sources/SwiftWebDriver/API/Request/Navigation/PostNavigationBackRequest.swift index 50077fb..36bd62d 100644 --- a/Sources/SwiftWebDriver/API/Request/Navigation/PostNavigationBackRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Navigation/PostNavigationBackRequest.swift @@ -1,10 +1,9 @@ // PostNavigationBackRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 // PostNavigatioinBackRequest.swift // Copyright (c) 2025 GetAutomaApp @@ -14,8 +13,6 @@ // This package is freely distributable under the MIT license. // This Package is a modified fork of https://github.com/ashi-psn/SwiftWebDriver. import Foundation - -import AsyncHTTPClient import NIO import NIOHTTP1 diff --git a/Sources/SwiftWebDriver/API/Request/Navigation/PostNavigationForwardRequest.swift b/Sources/SwiftWebDriver/API/Request/Navigation/PostNavigationForwardRequest.swift index 6be662e..38465b6 100644 --- a/Sources/SwiftWebDriver/API/Request/Navigation/PostNavigationForwardRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Navigation/PostNavigationForwardRequest.swift @@ -1,10 +1,7 @@ // PostNavigationForwardRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Navigation/PostNavigationRefreshRequest.swift b/Sources/SwiftWebDriver/API/Request/Navigation/PostNavigationRefreshRequest.swift index 5bf64f5..0694fe7 100644 --- a/Sources/SwiftWebDriver/API/Request/Navigation/PostNavigationRefreshRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Navigation/PostNavigationRefreshRequest.swift @@ -1,10 +1,7 @@ // PostNavigationRefreshRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Navigation/PostNavigationRequest.swift b/Sources/SwiftWebDriver/API/Request/Navigation/PostNavigationRequest.swift index 3850519..c62b9b7 100644 --- a/Sources/SwiftWebDriver/API/Request/Navigation/PostNavigationRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Navigation/PostNavigationRequest.swift @@ -1,10 +1,7 @@ // PostNavigationRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/RequestType.swift b/Sources/SwiftWebDriver/API/Request/RequestType.swift index 126eaa1..59ece79 100644 --- a/Sources/SwiftWebDriver/API/Request/RequestType.swift +++ b/Sources/SwiftWebDriver/API/Request/RequestType.swift @@ -39,7 +39,7 @@ internal extension RequestType { internal extension HTTPClient { func execute(request: some RequestType, deadline: NIODeadline? = nil) -> EventLoopFuture { do { - let request = try HTTPClient.Request( + let request = try Self.Request( url: request.url, method: request.method, headers: request.headers, diff --git a/Sources/SwiftWebDriver/API/Request/Sessions/DeleteSessionRequest.swift b/Sources/SwiftWebDriver/API/Request/Sessions/DeleteSessionRequest.swift index ac2e498..a8051b6 100644 --- a/Sources/SwiftWebDriver/API/Request/Sessions/DeleteSessionRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Sessions/DeleteSessionRequest.swift @@ -1,10 +1,7 @@ // DeleteSessionRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Request/Sessions/StatusRequest.swift b/Sources/SwiftWebDriver/API/Request/Sessions/StatusRequest.swift index 8832a16..eb1dd83 100644 --- a/Sources/SwiftWebDriver/API/Request/Sessions/StatusRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Sessions/StatusRequest.swift @@ -1,10 +1,7 @@ // StatusRequest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 diff --git a/Sources/SwiftWebDriver/API/Response/DevTools/PostExecuteResponse.swift b/Sources/SwiftWebDriver/API/Response/DevTools/PostExecuteResponse.swift index 1602320..49c3398 100644 --- a/Sources/SwiftWebDriver/API/Response/DevTools/PostExecuteResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/DevTools/PostExecuteResponse.swift @@ -1,10 +1,7 @@ // PostExecuteResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 AnyCodable import Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Elements/GetElementAttributeResponse.swift b/Sources/SwiftWebDriver/API/Response/Elements/GetElementAttributeResponse.swift index 3dfbc0f..7f4b9bf 100644 --- a/Sources/SwiftWebDriver/API/Response/Elements/GetElementAttributeResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Elements/GetElementAttributeResponse.swift @@ -1,10 +1,7 @@ // GetElementAttributeResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Elements/GetElementNamePropertyResponse.swift b/Sources/SwiftWebDriver/API/Response/Elements/GetElementNamePropertyResponse.swift index 0a94099..9cd6c33 100644 --- a/Sources/SwiftWebDriver/API/Response/Elements/GetElementNamePropertyResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Elements/GetElementNamePropertyResponse.swift @@ -1,10 +1,7 @@ // GetElementNamePropertyResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Elements/GetElementNameResponse.swift b/Sources/SwiftWebDriver/API/Response/Elements/GetElementNameResponse.swift index df8a3b1..99f0bca 100644 --- a/Sources/SwiftWebDriver/API/Response/Elements/GetElementNameResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Elements/GetElementNameResponse.swift @@ -1,10 +1,7 @@ // GetElementNameResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Elements/GetElementPropertyNameResponse.swift b/Sources/SwiftWebDriver/API/Response/Elements/GetElementPropertyNameResponse.swift index d8154c9..f2fb31c 100644 --- a/Sources/SwiftWebDriver/API/Response/Elements/GetElementPropertyNameResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Elements/GetElementPropertyNameResponse.swift @@ -1,10 +1,7 @@ // GetElementPropertyNameResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Elements/GetElementRectResponse.swift b/Sources/SwiftWebDriver/API/Response/Elements/GetElementRectResponse.swift index 13e34e2..6c5ab88 100644 --- a/Sources/SwiftWebDriver/API/Response/Elements/GetElementRectResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Elements/GetElementRectResponse.swift @@ -1,5 +1,5 @@ // GetElementRectResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. diff --git a/Sources/SwiftWebDriver/API/Response/Elements/GetElementScreenShotResponse.swift b/Sources/SwiftWebDriver/API/Response/Elements/GetElementScreenShotResponse.swift index ee9ba62..3609259 100644 --- a/Sources/SwiftWebDriver/API/Response/Elements/GetElementScreenShotResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Elements/GetElementScreenShotResponse.swift @@ -1,10 +1,7 @@ // GetElementScreenShotResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Elements/GetElementSelectedResponse.swift b/Sources/SwiftWebDriver/API/Response/Elements/GetElementSelectedResponse.swift index 1f16431..5fdda4f 100644 --- a/Sources/SwiftWebDriver/API/Response/Elements/GetElementSelectedResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Elements/GetElementSelectedResponse.swift @@ -1,10 +1,7 @@ // GetElementSelectedResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Elements/GetElementTextResponse.swift b/Sources/SwiftWebDriver/API/Response/Elements/GetElementTextResponse.swift index d62ffdd..db84f59 100644 --- a/Sources/SwiftWebDriver/API/Response/Elements/GetElementTextResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Elements/GetElementTextResponse.swift @@ -1,10 +1,7 @@ // GetElementTextResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Elements/GetScreenShotResponse.swift b/Sources/SwiftWebDriver/API/Response/Elements/GetScreenShotResponse.swift index 006baf1..003b9f0 100644 --- a/Sources/SwiftWebDriver/API/Response/Elements/GetScreenShotResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Elements/GetScreenShotResponse.swift @@ -1,10 +1,7 @@ // GetScreenShotResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Elements/GetSessionActiveElementResponse.swift b/Sources/SwiftWebDriver/API/Response/Elements/GetSessionActiveElementResponse.swift index ad20682..dc621d3 100644 --- a/Sources/SwiftWebDriver/API/Response/Elements/GetSessionActiveElementResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Elements/GetSessionActiveElementResponse.swift @@ -1,10 +1,7 @@ // GetSessionActiveElementResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Elements/PostElementByIdResponse.swift b/Sources/SwiftWebDriver/API/Response/Elements/PostElementByIdResponse.swift index e02290f..3246d4e 100644 --- a/Sources/SwiftWebDriver/API/Response/Elements/PostElementByIdResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Elements/PostElementByIdResponse.swift @@ -1,10 +1,7 @@ // PostElementByIdResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Elements/PostElementClearResponse.swift b/Sources/SwiftWebDriver/API/Response/Elements/PostElementClearResponse.swift index 5b13ba6..c01456e 100644 --- a/Sources/SwiftWebDriver/API/Response/Elements/PostElementClearResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Elements/PostElementClearResponse.swift @@ -1,10 +1,7 @@ // PostElementClearResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Elements/PostElementClickResponse.swift b/Sources/SwiftWebDriver/API/Response/Elements/PostElementClickResponse.swift index 222ae24..3b6978f 100644 --- a/Sources/SwiftWebDriver/API/Response/Elements/PostElementClickResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Elements/PostElementClickResponse.swift @@ -1,10 +1,7 @@ // PostElementClickResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Elements/PostElementResponse.swift b/Sources/SwiftWebDriver/API/Response/Elements/PostElementResponse.swift index 8846e98..d9f0582 100644 --- a/Sources/SwiftWebDriver/API/Response/Elements/PostElementResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Elements/PostElementResponse.swift @@ -1,10 +1,7 @@ // PostElementResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Elements/PostElementSendValueResponse.swift b/Sources/SwiftWebDriver/API/Response/Elements/PostElementSendValueResponse.swift index 982bdaa..21d4cb8 100644 --- a/Sources/SwiftWebDriver/API/Response/Elements/PostElementSendValueResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Elements/PostElementSendValueResponse.swift @@ -1,10 +1,7 @@ // PostElementSendValueResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Elements/PostElementsByIdResponse.swift b/Sources/SwiftWebDriver/API/Response/Elements/PostElementsByIdResponse.swift index c48128d..c357dac 100644 --- a/Sources/SwiftWebDriver/API/Response/Elements/PostElementsByIdResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Elements/PostElementsByIdResponse.swift @@ -1,10 +1,7 @@ // PostElementsByIdResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Elements/PostElementsResponse.swift b/Sources/SwiftWebDriver/API/Response/Elements/PostElementsResponse.swift index fb78d51..0246d97 100644 --- a/Sources/SwiftWebDriver/API/Response/Elements/PostElementsResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Elements/PostElementsResponse.swift @@ -1,10 +1,7 @@ // PostElementsResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Navigation/GetNavigationResponse.swift b/Sources/SwiftWebDriver/API/Response/Navigation/GetNavigationResponse.swift index 0539d95..805b89e 100644 --- a/Sources/SwiftWebDriver/API/Response/Navigation/GetNavigationResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Navigation/GetNavigationResponse.swift @@ -1,10 +1,7 @@ // GetNavigationResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Navigation/GetNavigationTitleResponse.swift b/Sources/SwiftWebDriver/API/Response/Navigation/GetNavigationTitleResponse.swift index e086d9e..b6b2357 100644 --- a/Sources/SwiftWebDriver/API/Response/Navigation/GetNavigationTitleResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Navigation/GetNavigationTitleResponse.swift @@ -1,10 +1,7 @@ // GetNavigationTitleResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Navigation/PostNavigationBackResponse.swift b/Sources/SwiftWebDriver/API/Response/Navigation/PostNavigationBackResponse.swift index d6a1b88..81a5b76 100644 --- a/Sources/SwiftWebDriver/API/Response/Navigation/PostNavigationBackResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Navigation/PostNavigationBackResponse.swift @@ -1,10 +1,7 @@ // PostNavigationBackResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Navigation/PostNavigationForwardResponse.swift b/Sources/SwiftWebDriver/API/Response/Navigation/PostNavigationForwardResponse.swift index 2620bb8..0387cc8 100644 --- a/Sources/SwiftWebDriver/API/Response/Navigation/PostNavigationForwardResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Navigation/PostNavigationForwardResponse.swift @@ -1,10 +1,7 @@ -// PostNavigatoinForwardResponse.swift -// Copyright (c) 2025 GetAutomaApp +// PostNavigationForwardResponse.swift +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Navigation/PostNavigationRefreshResponse.swift b/Sources/SwiftWebDriver/API/Response/Navigation/PostNavigationRefreshResponse.swift index 72f9252..df2f85a 100644 --- a/Sources/SwiftWebDriver/API/Response/Navigation/PostNavigationRefreshResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Navigation/PostNavigationRefreshResponse.swift @@ -1,10 +1,7 @@ // PostNavigationRefreshResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Navigation/PostNavigationResponse.swift b/Sources/SwiftWebDriver/API/Response/Navigation/PostNavigationResponse.swift index 5136e99..2512fed 100644 --- a/Sources/SwiftWebDriver/API/Response/Navigation/PostNavigationResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Navigation/PostNavigationResponse.swift @@ -1,10 +1,7 @@ -// NavigationResponse.swift -// Copyright (c) 2025 GetAutomaApp +// PostNavigationResponse.swift +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/ResponseType.swift b/Sources/SwiftWebDriver/API/Response/ResponseType.swift index 89f3df4..e3a6de5 100644 --- a/Sources/SwiftWebDriver/API/Response/ResponseType.swift +++ b/Sources/SwiftWebDriver/API/Response/ResponseType.swift @@ -1,9 +1,6 @@ // ResponseType.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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. public protocol ResponseType: Sendable, Codable {} diff --git a/Sources/SwiftWebDriver/API/Response/Sessions/DeleteSessionResponse.swift b/Sources/SwiftWebDriver/API/Response/Sessions/DeleteSessionResponse.swift index 1be12ea..c138584 100644 --- a/Sources/SwiftWebDriver/API/Response/Sessions/DeleteSessionResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Sessions/DeleteSessionResponse.swift @@ -1,10 +1,7 @@ // DeleteSessionResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Sessions/NewSessionResponse.swift b/Sources/SwiftWebDriver/API/Response/Sessions/NewSessionResponse.swift index 67c1f74..e5018d1 100644 --- a/Sources/SwiftWebDriver/API/Response/Sessions/NewSessionResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Sessions/NewSessionResponse.swift @@ -1,10 +1,7 @@ // NewSessionResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/API/Response/Sessions/StatusResponse.swift b/Sources/SwiftWebDriver/API/Response/Sessions/StatusResponse.swift index c71350b..f8f5772 100644 --- a/Sources/SwiftWebDriver/API/Response/Sessions/StatusResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Sessions/StatusResponse.swift @@ -1,10 +1,7 @@ // StatusResponse.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/Element/ElementRect.swift b/Sources/SwiftWebDriver/Element/ElementRect.swift index 417caf3..76c8ba5 100644 --- a/Sources/SwiftWebDriver/Element/ElementRect.swift +++ b/Sources/SwiftWebDriver/Element/ElementRect.swift @@ -1,5 +1,5 @@ // ElementRect.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. diff --git a/Sources/SwiftWebDriver/Element/Elements.swift b/Sources/SwiftWebDriver/Element/Elements.swift index 117d521..cde929e 100644 --- a/Sources/SwiftWebDriver/Element/Elements.swift +++ b/Sources/SwiftWebDriver/Element/Elements.swift @@ -1,5 +1,5 @@ // Elements.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. @@ -111,7 +111,7 @@ public extension Elements { /// - Throws: An error if the WebDriver request fails. @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) func findElements(_ locatorType: LocatorType) async throws -> Elements { - var elements = [Elements]() + var elements = [Self]() try await withThrowingTaskGroup(of: Elements.self) { group in for element in self { group.addTask { diff --git a/Sources/SwiftWebDriver/Element/Selector/CSSSelector.swift b/Sources/SwiftWebDriver/Element/Selector/CSSSelector.swift index 91c9954..89347b0 100644 --- a/Sources/SwiftWebDriver/Element/Selector/CSSSelector.swift +++ b/Sources/SwiftWebDriver/Element/Selector/CSSSelector.swift @@ -1,10 +1,7 @@ // CSSSelector.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/Element/Selector/LocatorSelector.swift b/Sources/SwiftWebDriver/Element/Selector/LocatorSelector.swift index d96d021..2643b1c 100644 --- a/Sources/SwiftWebDriver/Element/Selector/LocatorSelector.swift +++ b/Sources/SwiftWebDriver/Element/Selector/LocatorSelector.swift @@ -1,10 +1,7 @@ // LocatorSelector.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/Element/Selector/LocatorType.swift b/Sources/SwiftWebDriver/Element/Selector/LocatorType.swift index f64a4ea..49069e0 100644 --- a/Sources/SwiftWebDriver/Element/Selector/LocatorType.swift +++ b/Sources/SwiftWebDriver/Element/Selector/LocatorType.swift @@ -1,10 +1,7 @@ // LocatorType.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/Error/SeleniumError.swift b/Sources/SwiftWebDriver/Error/SeleniumError.swift index 58f0343..5cc99a0 100644 --- a/Sources/SwiftWebDriver/Error/SeleniumError.swift +++ b/Sources/SwiftWebDriver/Error/SeleniumError.swift @@ -1,5 +1,5 @@ // SeleniumError.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. diff --git a/Sources/SwiftWebDriver/Error/WebDriverError.swift b/Sources/SwiftWebDriver/Error/WebDriverError.swift index 1676c3e..fa0c10b 100644 --- a/Sources/SwiftWebDriver/Error/WebDriverError.swift +++ b/Sources/SwiftWebDriver/Error/WebDriverError.swift @@ -1,10 +1,7 @@ // WebDriverError.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 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 Foundation diff --git a/Sources/SwiftWebDriver/WebDriver.swift b/Sources/SwiftWebDriver/WebDriver.swift index 087b275..cc50129 100644 --- a/Sources/SwiftWebDriver/WebDriver.swift +++ b/Sources/SwiftWebDriver/WebDriver.swift @@ -1,5 +1,5 @@ // WebDriver.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. diff --git a/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxDriver.swift b/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxDriver.swift index 35d6063..47796c6 100644 --- a/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxDriver.swift +++ b/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxDriver.swift @@ -36,7 +36,7 @@ public class FirefoxDriver: Driver { @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) public func start() async throws -> String { - let id = try await FirefoxDriver.startDriverExternal( + let id = try await Self.startDriverExternal( url: url, browserObject: browserObject, client: client @@ -341,7 +341,7 @@ public class FirefoxDriver: Driver { Task { guard let sessionId else { return } - try await FirefoxDriver.stopDriverExternal(url: url, sessionId: sessionId) + try await Self.stopDriverExternal(url: url, sessionId: sessionId) } } diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverDragAndDropIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverDragAndDropIntegrationTests.swift index 98fb9a4..a1aa3d2 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Element/DriverDragAndDropIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverDragAndDropIntegrationTests.swift @@ -1,4 +1,4 @@ -// ChromeDriverDragAndDropIntegrationTests.swift +// DriverDragAndDropIntegrationTests.swift // Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverElementHandleIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverElementHandleIntegrationTests.swift index ed9e46e..e03ecff 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Element/DriverElementHandleIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverElementHandleIntegrationTests.swift @@ -1,4 +1,4 @@ -// ChromeDriverElementHandleIntegrationTests.swift +// DriverElementHandleIntegrationTests.swift // Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverSpecialKeysIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverSpecialKeysIntegrationTests.swift index fc6cf27..4eb6598 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Element/DriverSpecialKeysIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverSpecialKeysIntegrationTests.swift @@ -9,7 +9,7 @@ import Testing internal class DriverSpecialKeysIntegrationTestBase: DriverIntegrationTest { - func runTabCycleInputElementFocusTest() async throws { + internal func runTabCycleInputElementFocusTest() async throws { page = "testSpecialKeys.html" try await driver.navigateTo(url: testPageURL) @@ -31,7 +31,7 @@ internal final class ChromeDriverSpecialKeysIntegrationTests: DriverSpecialKeysIntegrationTestBase { @Test("Tab Should Cycle Input Elements Focus") - func tabCycleInputElementFocus() async throws { + internal func tabCycleInputElementFocus() async throws { try await runTabCycleInputElementFocusTest() } } @@ -41,7 +41,7 @@ internal final class FirefoxDriverSpecialKeysIntegrationTests: DriverSpecialKeysIntegrationTestBase { @Test("Tab Should Cycle Input Elements Focus") - func tabCycleInputElementFocus() async throws { + internal func tabCycleInputElementFocus() async throws { try await runTabCycleInputElementFocusTest() } } From 9d2b76aa927a990bc2982c48e8e5d8d7967ea441 Mon Sep 17 00:00:00 2001 From: William Date: Thu, 9 Jul 2026 12:44:17 +0200 Subject: [PATCH 06/16] fix: firefox driver fixed --- .../WebDrivers/Firefox/FirefoxDriver.swift | 20 +++---- .../DriverJavascriptIntegrationTests.swift | 18 +++--- .../DriverDragAndDropIntegrationTests.swift | 10 ++-- .../DriverElementHandleIntegrationTests.swift | 60 +++++++++---------- .../DriverFindElementIntegrationTests.swift | 30 +++++----- .../DriverFindElementsIntegrationTests.swift | 30 +++++----- .../DriverPropertyIntegrationTests.swift | 12 ++-- .../DriverSetAttributeIntegrationTests.swift | 6 +- .../DriverNavigationIntegrationTests.swift | 12 ++-- .../Start/DriverStartTests.swift | 6 +- 10 files changed, 102 insertions(+), 102 deletions(-) diff --git a/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxDriver.swift b/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxDriver.swift index 47796c6..b8e9de7 100644 --- a/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxDriver.swift +++ b/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxDriver.swift @@ -335,16 +335,6 @@ public class FirefoxDriver: Driver { try await ElementDragAndDropper(driver: self, from: source, to: target).dragAndDrop() } - deinit { - let url = url - let sessionId = sessionId - - Task { - guard let sessionId else { return } - try await Self.stopDriverExternal(url: url, sessionId: sessionId) - } - } - private static func stopDriverExternal(url: URL, sessionId: String) async throws { let request = DeleteSessionRequest(baseURL: url, sessionId: sessionId) _ = try await APIClient.shared.request(request).map(\.value).get() @@ -358,4 +348,14 @@ public class FirefoxDriver: Driver { let request = NewSessionRequest(baseURL: url, browserOptions: browserObject) return try await client.request(request).map(\.value.sessionId).get() } + + deinit { + let url = url + let sessionId = sessionId + Task { + guard let sessionId else { return } + // swiftlint:disable:next prefer_self_in_static_references + try await FirefoxDriver.stopDriverExternal(url: url, sessionId: sessionId) + } + } } diff --git a/Tests/SwiftWebDriverIntegrationTests/DevTools/DriverJavascriptIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/DevTools/DriverJavascriptIntegrationTests.swift index 6d8ecec..15df0ac 100644 --- a/Tests/SwiftWebDriverIntegrationTests/DevTools/DriverJavascriptIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/DevTools/DriverJavascriptIntegrationTests.swift @@ -36,7 +36,7 @@ internal enum JavascriptIntegrationTestCases { internal class DriverJavascriptIntegrationTestBase: DriverIntegrationTest { - func runExecuteJavascriptTest(input: (script: String, expected: String)) async throws { + internal func runExecuteJavascriptTest(input: (script: String, expected: String)) async throws { try await driver.navigateTo(url: testPageURL) let output = try await driver.execute(input.script, args: []) @@ -44,7 +44,7 @@ internal class DriverJavascriptIntegrationTestBase: DriverIntegrationTest { - func runDragAndDropTest(page: String) async throws { + internal func runDragAndDropTest(page: String) async throws { self.page = page try await driver.navigateTo(urlString: testPageURL.absoluteString) @@ -33,12 +33,12 @@ internal final class ChromeDriverDragAndDropIntegrationTests: DriverDragAndDropIntegrationTestBase { @Test("Drag Element To Another (JavaScript)") - func dragAndDropDraggableElementToAnother() async throws { + internal func dragAndDropDraggableElementToAnother() async throws { try await runDragAndDropTest(page: "dragTarget.html") } @Test("Drag Element To Another (WebDriver Actions API)") - func dragAndDropElementToAnother() async throws { + internal func dragAndDropElementToAnother() async throws { try await runDragAndDropTest(page: "dragBox.html") } } @@ -48,12 +48,12 @@ internal final class FirefoxDriverDragAndDropIntegrationTests: DriverDragAndDropIntegrationTestBase { @Test("Drag Element To Another (JavaScript)") - func dragAndDropDraggableElementToAnother() async throws { + internal func dragAndDropDraggableElementToAnother() async throws { try await runDragAndDropTest(page: "dragTarget.html") } @Test("Drag Element To Another (WebDriver Actions API)") - func dragAndDropElementToAnother() async throws { + internal func dragAndDropElementToAnother() async throws { try await runDragAndDropTest(page: "dragBox.html") } } diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverElementHandleIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverElementHandleIntegrationTests.swift index e03ecff..1b5468b 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Element/DriverElementHandleIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverElementHandleIntegrationTests.swift @@ -9,7 +9,7 @@ import Testing internal class DriverElementHandleIntegrationTestBase: DriverIntegrationTest { - func runClickButtonTest() async throws { + internal func runClickButtonTest() async throws { page = "elementHandleTestPage.html" try await driver.navigateTo(urlString: testPageURL.absoluteString) @@ -19,7 +19,7 @@ internal class DriverElementHandleIntegrationTestBase { @Test("Click Button") - func clickButton() async throws { + internal func clickButton() async throws { try await runClickButtonTest() } @Test("Double Click Button") - func doubleClickButton() async throws { + internal func doubleClickButton() async throws { try await runDoubleClickButtonTest() } @Test("Drag Element To Another") - func dragElementToAnother() async throws { + internal func dragElementToAnother() async throws { try await runDragElementToAnotherTest() } @Test("Get Element Attributes") - func getAttribute() async throws { + internal func getAttribute() async throws { try await runGetAttributeTest() } @Test("Get Element Rect") - func getRect() async throws { + internal func getRect() async throws { try await runGetRectTest() } @Test("Clear Element") - func clearElement() async throws { + internal func clearElement() async throws { try await runClearElementTest() } @Test("Send Key") - func sendKey() async throws { + internal func sendKey() async throws { try await runSendKeyTest() } @Test("Send Chord") - func sendChord() async throws { + internal func sendChord() async throws { try await runSendChordTest() } @Test("Get Screenshot") - func getScreenshot() async throws { + internal func getScreenshot() async throws { try await runGetScreenshotTest() } @Test("Fail any operation if element becomes stale") - func throwStaleError() async throws { + internal func throwStaleError() async throws { try await runThrowStaleErrorTest() } } @@ -208,52 +208,52 @@ internal final class FirefoxDriverElementHandleIntegrationTests: DriverElementHandleIntegrationTestBase { @Test("Click Button") - func clickButton() async throws { + internal func clickButton() async throws { try await runClickButtonTest() } @Test("Double Click Button") - func doubleClickButton() async throws { + internal func doubleClickButton() async throws { try await runDoubleClickButtonTest() } @Test("Drag Element To Another") - func dragElementToAnother() async throws { + internal func dragElementToAnother() async throws { try await runDragElementToAnotherTest() } @Test("Get Element Attributes") - func getAttribute() async throws { + internal func getAttribute() async throws { try await runGetAttributeTest() } @Test("Get Element Rect") - func getRect() async throws { + internal func getRect() async throws { try await runGetRectTest() } @Test("Clear Element") - func clearElement() async throws { + internal func clearElement() async throws { try await runClearElementTest() } @Test("Send Key") - func sendKey() async throws { + internal func sendKey() async throws { try await runSendKeyTest() } @Test("Send Chord") - func sendChord() async throws { + internal func sendChord() async throws { try await runSendChordTest() } @Test("Get Screenshot") - func getScreenshot() async throws { + internal func getScreenshot() async throws { try await runGetScreenshotTest() } @Test("Fail any operation if element becomes stale") - func throwStaleError() async throws { + internal func throwStaleError() async throws { try await runThrowStaleErrorTest() } } diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementIntegrationTests.swift index f0393ec..03bd68b 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementIntegrationTests.swift @@ -9,7 +9,7 @@ import Testing internal class DriverFindElementIntegrationTestBase: DriverIntegrationTest { - func runGetElementCSSElementTest() async throws { + internal func runGetElementCSSElementTest() async throws { page = "index.html" try await driver.navigateTo(url: testPageURL) @@ -32,7 +32,7 @@ internal class DriverFindElementIntegrationTestBase { @Test("Get Element By CSS Selector") - func getElementCSSElement() async throws { + internal func getElementCSSElement() async throws { try await runGetElementCSSElementTest() } @Test("Get Element By XPath") - func getElementByXPath() async throws { + internal func getElementByXPath() async throws { try await runGetElementByXPathTest() } @Test("Get Element By Link Text") - func getElementByLinkText() async throws { + internal func getElementByLinkText() async throws { try await runGetElementByLinkTextTest() } @Test("Get Element By Partial Link") - func getElementByPartialLink() async throws { + internal func getElementByPartialLink() async throws { try await runGetElementByPartialLinkTest() } @Test("Get Element By TagName") - func getElementByTagName() async throws { + internal func getElementByTagName() async throws { try await runGetElementByTagNameTest() } } @@ -112,27 +112,27 @@ internal final class FirefoxDriverFindElementIntegrationTests: DriverFindElementIntegrationTestBase { @Test("Get Element By CSS Selector") - func getElementCSSElement() async throws { + internal func getElementCSSElement() async throws { try await runGetElementCSSElementTest() } @Test("Get Element By XPath") - func getElementByXPath() async throws { + internal func getElementByXPath() async throws { try await runGetElementByXPathTest() } @Test("Get Element By Link Text") - func getElementByLinkText() async throws { + internal func getElementByLinkText() async throws { try await runGetElementByLinkTextTest() } @Test("Get Element By Partial Link") - func getElementByPartialLink() async throws { + internal func getElementByPartialLink() async throws { try await runGetElementByPartialLinkTest() } @Test("Get Element By TagName") - func getElementByTagName() async throws { + internal func getElementByTagName() async throws { try await runGetElementByTagNameTest() } } diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementsIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementsIntegrationTests.swift index 1c112a1..04ee9b0 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementsIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementsIntegrationTests.swift @@ -9,7 +9,7 @@ import Testing internal class DriverFindElementsIntegrationTestBase: DriverIntegrationTest { - func runGetElementsCSSElementsTest() async throws { + internal func runGetElementsCSSElementsTest() async throws { page = "findElementsTestPage.html" try await driver.navigateTo(urlString: testPageURL.absoluteString) @@ -35,7 +35,7 @@ internal class DriverFindElementsIntegrationTestBase { @Test("Get Elements CSS Elements") - func getElementsCSSElements() async throws { + internal func getElementsCSSElements() async throws { try await runGetElementsCSSElementsTest() } @Test("Get Elements By XPath") - func getElementsByXPath() async throws { + internal func getElementsByXPath() async throws { try await runGetElementsByXPathTest() } @Test("Get Elements By Link Text") - func getElementsByLinkText() async throws { + internal func getElementsByLinkText() async throws { try await runGetElementsByLinkTextTest() } @Test("Get Elements By Partial Link Text") - func getElementsByPartialLink() async throws { + internal func getElementsByPartialLink() async throws { try await runGetElementsByPartialLinkTest() } @Test("Get Elements By Tag Name") - func getElementByTagName() async throws { + internal func getElementByTagName() async throws { try await runGetElementsByTagNameTest() } } @@ -144,27 +144,27 @@ internal final class FirefoxDriverFindElementsIntegrationTests: DriverFindElementsIntegrationTestBase { @Test("Get Elements CSS Elements") - func getElementsCSSElements() async throws { + internal func getElementsCSSElements() async throws { try await runGetElementsCSSElementsTest() } @Test("Get Elements By XPath") - func getElementsByXPath() async throws { + internal func getElementsByXPath() async throws { try await runGetElementsByXPathTest() } @Test("Get Elements By Link Text") - func getElementsByLinkText() async throws { + internal func getElementsByLinkText() async throws { try await runGetElementsByLinkTextTest() } @Test("Get Elements By Partial Link Text") - func getElementsByPartialLink() async throws { + internal func getElementsByPartialLink() async throws { try await runGetElementsByPartialLinkTest() } @Test("Get Elements By Tag Name") - func getElementByTagName() async throws { + internal func getElementByTagName() async throws { try await runGetElementsByTagNameTest() } } diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverPropertyIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverPropertyIntegrationTests.swift index 4d47a86..7fbb8a0 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Element/DriverPropertyIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverPropertyIntegrationTests.swift @@ -10,7 +10,7 @@ internal class DriverPropertyIntegrationTestBase { /// Test `getProperty()` method, a method to get a specific property value from an element. - func runGetPropertyTest() async throws { + internal func runGetPropertyTest() async throws { page = "elementHandleTestPage.html" try await driver.navigateTo(urlString: testPageURL.absoluteString) @@ -37,7 +37,7 @@ internal class DriverPropertyIntegrationTestBase { @Test("Get Property") - func getProperty() async throws { + internal func getProperty() async throws { try await runGetPropertyTest() } @Test("Set Property") - func setProperty() async throws { + internal func setProperty() async throws { try await runSetPropertyTest() } } @@ -84,12 +84,12 @@ internal final class FirefoxDriverPropertyIntegrationTests: DriverPropertyIntegrationTestBase { @Test("Get Property") - func getProperty() async throws { + internal func getProperty() async throws { try await runGetPropertyTest() } @Test("Set Property") - func setProperty() async throws { + internal func setProperty() async throws { try await runSetPropertyTest() } } diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverSetAttributeIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverSetAttributeIntegrationTests.swift index bd73615..c975014 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Element/DriverSetAttributeIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverSetAttributeIntegrationTests.swift @@ -9,7 +9,7 @@ import Testing internal class DriverSetAttributeIntegrationTestBase: DriverIntegrationTest { - func runSetAttributeTest() async throws { + internal func runSetAttributeTest() async throws { page = "elementHandleTestPage.html" try await driver.navigateTo(urlString: testPageURL.absoluteString) @@ -33,7 +33,7 @@ internal final class ChromeDriverSetAttributeIntegrationTests: DriverSetAttributeIntegrationTestBase { @Test("Set Attribute") - func setAttribute() async throws { + internal func setAttribute() async throws { try await runSetAttributeTest() } } @@ -43,7 +43,7 @@ internal final class FirefoxDriverSetAttributeIntegrationTests: DriverSetAttributeIntegrationTestBase { @Test("Set Attribute") - func setAttribute() async throws { + internal func setAttribute() async throws { try await runSetAttributeTest() } } diff --git a/Tests/SwiftWebDriverIntegrationTests/Navigation/DriverNavigationIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Navigation/DriverNavigationIntegrationTests.swift index 7da37bf..0358973 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Navigation/DriverNavigationIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Navigation/DriverNavigationIntegrationTests.swift @@ -9,7 +9,7 @@ import Testing internal class DriverNavigationIntegrationTestBase: DriverIntegrationTest { - func runGetNavigationTitleTest() async throws { + internal func runGetNavigationTitleTest() async throws { page = "awaitTestPage.html" try await driver.navigateTo(urlString: testPageURL.absoluteString) @@ -19,7 +19,7 @@ internal class DriverNavigationIntegrationTestBase { @Test("Get Navigation Title") - func getNavigationTitle() async throws { + internal func getNavigationTitle() async throws { try await runGetNavigationTitleTest() } @Test("Wait Until Element Exists") - func waitUntilElements() async throws { + internal func waitUntilElements() async throws { try await runWaitUntilElementsTest() } } @@ -60,12 +60,12 @@ internal final class FirefoxDriverNavigationIntegrationTests: DriverNavigationIntegrationTestBase { @Test("Get Navigation Title") - func getNavigationTitle() async throws { + internal func getNavigationTitle() async throws { try await runGetNavigationTitleTest() } @Test("Wait Until Element Exists") - func waitUntilElements() async throws { + internal func waitUntilElements() async throws { try await runWaitUntilElementsTest() } } diff --git a/Tests/SwiftWebDriverIntegrationTests/Start/DriverStartTests.swift b/Tests/SwiftWebDriverIntegrationTests/Start/DriverStartTests.swift index b0d5ece..11ddafa 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Start/DriverStartTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Start/DriverStartTests.swift @@ -9,7 +9,7 @@ import Testing internal class DriverStartTestBase: DriverIntegrationTest { - func runStartAndStopTest() async throws { + internal func runStartAndStopTest() async throws { let status = try await driver.status() #expect(status.value.message != "") @@ -23,7 +23,7 @@ internal final class ChromeDriverStartTests: DriverStartTestBase { @Test("Start & Stop") - func startAndStop() async throws { + internal func startAndStop() async throws { try await runStartAndStopTest() } } @@ -33,7 +33,7 @@ internal final class FirefoxDriverStartTests: DriverStartTestBase { @Test("Start & Stop") - func startAndStop() async throws { + internal func startAndStop() async throws { try await runStartAndStopTest() } } From 3234f15c4365c5b0b2d8c5f15cc7278dae6af332 Mon Sep 17 00:00:00 2001 From: William Date: Thu, 9 Jul 2026 13:10:53 +0200 Subject: [PATCH 07/16] refactor: standardize driver session methods, update FirefoxOptions visibility, and add deinit cleanup to integration tests --- .../API/Request/Elements/ElementsTypes.swift | 51 +++++++------------ .../DriverJavascriptIntegrationTests.swift | 6 +-- .../DriverDragAndDropIntegrationTests.swift | 6 +-- .../DriverElementHandleIntegrationTests.swift | 6 +-- .../DriverFindElementIntegrationTests.swift | 6 +-- .../DriverFindElementsIntegrationTests.swift | 6 +-- .../DriverPropertyIntegrationTests.swift | 6 +-- .../DriverSetAttributeIntegrationTests.swift | 6 +-- .../DriverSpecialKeysIntegrationTests.swift | 6 +-- .../DriverNavigationIntegrationTests.swift | 6 +-- .../Start/DriverStartTests.swift | 6 +-- 11 files changed, 49 insertions(+), 62 deletions(-) diff --git a/Sources/SwiftWebDriver/API/Request/Elements/ElementsTypes.swift b/Sources/SwiftWebDriver/API/Request/Elements/ElementsTypes.swift index 99db4fa..84fdecb 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/ElementsTypes.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/ElementsTypes.swift @@ -14,45 +14,32 @@ public enum ElementsTypes { /// such as `Enter`, `Return`, and `Tab`. They can be sent along with regular /// text input to simulate keyboard events in browser automation. public enum SendValueActionKeyTypes: String { - /// The **Enter** key (Unicode: `\u{E007}`). - /// - /// Typically used to submit forms or trigger button actions in web pages. - case ENTER1 = "\u{E007}" - - /// The **Return** key (Unicode: `\u{E006}`). - /// - /// Often treated similarly to `Enter`, but provided as a separate code - /// for systems that distinguish between them. - case RETURN1 = "\u{E006}" - - /// The **Tab** key (Unicode: `\u{E004}`). - /// - /// Used to move focus between interactive elements (e.g., form fields) in a web page. - case TAB = "\u{E004}" - - case NULL = "\u{E000}" - case CANCEL = "\u{E001}" - case HELP = "\u{E002}" + case ALT = "\u{E00A}" case BACKSPACE = "\u{E003}" + case CANCEL = "\u{E001}" case CLEAR = "\u{E005}" - case SHIFT = "\u{E008}" case CONTROL = "\u{E009}" - case ALT = "\u{E00A}" - case PAUSE = "\u{E00B}" - case ESCAPE = "\u{E00C}" - case SPACE = "\u{E00D}" - case PAGE_UP = "\u{E00E}" - case PAGE_DOWN = "\u{E00F}" + case DELETE = "\u{E017}" + case DOWN_ARROW = "\u{E015}" case END = "\u{E010}" + case ENTER1 = "\u{E007}" + case ESCAPE = "\u{E00C}" + case F1 = "\u{E031}" + case F2 = "\u{E032}" + case HELP = "\u{E002}" case HOME = "\u{E011}" + case INSERT = "\u{E016}" case LEFT_ARROW = "\u{E012}" - case UP_ARROW = "\u{E013}" + case NULL = "\u{E000}" + case PAGE_DOWN = "\u{E00F}" + case PAGE_UP = "\u{E00E}" + case PAUSE = "\u{E00B}" + case RETURN1 = "\u{E006}" case RIGHT_ARROW = "\u{E014}" - case DOWN_ARROW = "\u{E015}" - case INSERT = "\u{E016}" - case DELETE = "\u{E017}" - case F1 = "\u{E031}" - case F2 = "\u{E032}" + case SHIFT = "\u{E008}" + case SPACE = "\u{E00D}" + case TAB = "\u{E004}" + case UP_ARROW = "\u{E013}" /// The raw Unicode representation of the key. /// diff --git a/Tests/SwiftWebDriverIntegrationTests/DevTools/DriverJavascriptIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/DevTools/DriverJavascriptIntegrationTests.swift index 15df0ac..10d12f2 100644 --- a/Tests/SwiftWebDriverIntegrationTests/DevTools/DriverJavascriptIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/DevTools/DriverJavascriptIntegrationTests.swift @@ -33,7 +33,7 @@ internal enum JavascriptIntegrationTestCases { ] } -internal class DriverJavascriptIntegrationTestBase: +internal class DriverJavascriptIntegrationTest: DriverIntegrationTest { internal func runExecuteJavascriptTest(input: (script: String, expected: String)) async throws { @@ -72,7 +72,7 @@ internal class DriverJavascriptIntegrationTestBase + DriverJavascriptIntegrationTest { @Test( "Test sync Javascript Execution", @@ -98,7 +98,7 @@ internal final class ChromeDriverJavascriptIntegrationTests: @Suite("Firefox Driver Javascript Integration Tests", .serialized) internal final class FirefoxDriverJavascriptIntegrationTests: - DriverJavascriptIntegrationTestBase + DriverJavascriptIntegrationTest { @Test( "Test sync Javascript Execution", diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverDragAndDropIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverDragAndDropIntegrationTests.swift index bcd851a..90405ce 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Element/DriverDragAndDropIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverDragAndDropIntegrationTests.swift @@ -6,7 +6,7 @@ @testable import SwiftWebDriver import Testing -internal class DriverDragAndDropIntegrationTestBase: +internal class DriverDragAndDropIntegrationTest: DriverIntegrationTest { internal func runDragAndDropTest(page: String) async throws { @@ -30,7 +30,7 @@ internal class DriverDragAndDropIntegrationTestBase + DriverDragAndDropIntegrationTest { @Test("Drag Element To Another (JavaScript)") internal func dragAndDropDraggableElementToAnother() async throws { @@ -45,7 +45,7 @@ internal final class ChromeDriverDragAndDropIntegrationTests: @Suite("Firefox Driver Drag and Drop Integration Tests", .serialized) internal final class FirefoxDriverDragAndDropIntegrationTests: - DriverDragAndDropIntegrationTestBase + DriverDragAndDropIntegrationTest { @Test("Drag Element To Another (JavaScript)") internal func dragAndDropDraggableElementToAnother() async throws { diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverElementHandleIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverElementHandleIntegrationTests.swift index 1b5468b..2dde4aa 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Element/DriverElementHandleIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverElementHandleIntegrationTests.swift @@ -6,7 +6,7 @@ @testable import SwiftWebDriver import Testing -internal class DriverElementHandleIntegrationTestBase: +internal class DriverElementHandleIntegrationTest: DriverIntegrationTest { internal func runClickButtonTest() async throws { @@ -150,7 +150,7 @@ internal class DriverElementHandleIntegrationTestBase + DriverElementHandleIntegrationTest { @Test("Click Button") internal func clickButton() async throws { @@ -205,7 +205,7 @@ internal final class ChromeDriverElementHandleIntegrationTests: @Suite("Firefox Driver Element Handles", .serialized) internal final class FirefoxDriverElementHandleIntegrationTests: - DriverElementHandleIntegrationTestBase + DriverElementHandleIntegrationTest { @Test("Click Button") internal func clickButton() async throws { diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementIntegrationTests.swift index 03bd68b..65fc31e 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementIntegrationTests.swift @@ -6,7 +6,7 @@ @testable import SwiftWebDriver import Testing -internal class DriverFindElementIntegrationTestBase: +internal class DriverFindElementIntegrationTest: DriverIntegrationTest { internal func runGetElementCSSElementTest() async throws { @@ -79,7 +79,7 @@ internal class DriverFindElementIntegrationTestBase + DriverFindElementIntegrationTest { @Test("Get Element By CSS Selector") internal func getElementCSSElement() async throws { @@ -109,7 +109,7 @@ internal final class ChromeDriverFindElementIntegrationTests: @Suite("Firefox Driver Find Element Tests", .serialized) internal final class FirefoxDriverFindElementIntegrationTests: - DriverFindElementIntegrationTestBase + DriverFindElementIntegrationTest { @Test("Get Element By CSS Selector") internal func getElementCSSElement() async throws { diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementsIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementsIntegrationTests.swift index 04ee9b0..b240a49 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementsIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverFindElementsIntegrationTests.swift @@ -6,7 +6,7 @@ @testable import SwiftWebDriver import Testing -internal class DriverFindElementsIntegrationTestBase: +internal class DriverFindElementsIntegrationTest: DriverIntegrationTest { internal func runGetElementsCSSElementsTest() async throws { @@ -111,7 +111,7 @@ internal class DriverFindElementsIntegrationTestBase + DriverFindElementsIntegrationTest { @Test("Get Elements CSS Elements") internal func getElementsCSSElements() async throws { @@ -141,7 +141,7 @@ internal final class ChromeDriverFindElementsIntegrationTests: @Suite("Firefox Driver Find Elements Tests", .serialized) internal final class FirefoxDriverFindElementsIntegrationTests: - DriverFindElementsIntegrationTestBase + DriverFindElementsIntegrationTest { @Test("Get Elements CSS Elements") internal func getElementsCSSElements() async throws { diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverPropertyIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverPropertyIntegrationTests.swift index 7fbb8a0..9495abc 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Element/DriverPropertyIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverPropertyIntegrationTests.swift @@ -6,7 +6,7 @@ @testable import SwiftWebDriver import Testing -internal class DriverPropertyIntegrationTestBase: +internal class DriverPropertyIntegrationTest: DriverIntegrationTest { /// Test `getProperty()` method, a method to get a specific property value from an element. @@ -66,7 +66,7 @@ internal class DriverPropertyIntegrationTestBase + DriverPropertyIntegrationTest { @Test("Get Property") internal func getProperty() async throws { @@ -81,7 +81,7 @@ internal final class ChromeDriverPropertyIntegrationTests: @Suite("Firefox Driver Property Integration Tests", .serialized) internal final class FirefoxDriverPropertyIntegrationTests: - DriverPropertyIntegrationTestBase + DriverPropertyIntegrationTest { @Test("Get Property") internal func getProperty() async throws { diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverSetAttributeIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverSetAttributeIntegrationTests.swift index c975014..89dd973 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Element/DriverSetAttributeIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverSetAttributeIntegrationTests.swift @@ -6,7 +6,7 @@ @testable import SwiftWebDriver import Testing -internal class DriverSetAttributeIntegrationTestBase: +internal class DriverSetAttributeIntegrationTest: DriverIntegrationTest { internal func runSetAttributeTest() async throws { @@ -30,7 +30,7 @@ internal class DriverSetAttributeIntegrationTestBase + DriverSetAttributeIntegrationTest { @Test("Set Attribute") internal func setAttribute() async throws { @@ -40,7 +40,7 @@ internal final class ChromeDriverSetAttributeIntegrationTests: @Suite("Firefox Driver Set Attribute", .serialized) internal final class FirefoxDriverSetAttributeIntegrationTests: - DriverSetAttributeIntegrationTestBase + DriverSetAttributeIntegrationTest { @Test("Set Attribute") internal func setAttribute() async throws { diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverSpecialKeysIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverSpecialKeysIntegrationTests.swift index 4eb6598..3946ba1 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Element/DriverSpecialKeysIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverSpecialKeysIntegrationTests.swift @@ -6,7 +6,7 @@ @testable import SwiftWebDriver import Testing -internal class DriverSpecialKeysIntegrationTestBase: +internal class DriverSpecialKeysIntegrationTest: DriverIntegrationTest { internal func runTabCycleInputElementFocusTest() async throws { @@ -28,7 +28,7 @@ internal class DriverSpecialKeysIntegrationTestBase + DriverSpecialKeysIntegrationTest { @Test("Tab Should Cycle Input Elements Focus") internal func tabCycleInputElementFocus() async throws { @@ -38,7 +38,7 @@ internal final class ChromeDriverSpecialKeysIntegrationTests: @Suite("Firefox Driver Special Keys", .serialized) internal final class FirefoxDriverSpecialKeysIntegrationTests: - DriverSpecialKeysIntegrationTestBase + DriverSpecialKeysIntegrationTest { @Test("Tab Should Cycle Input Elements Focus") internal func tabCycleInputElementFocus() async throws { diff --git a/Tests/SwiftWebDriverIntegrationTests/Navigation/DriverNavigationIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Navigation/DriverNavigationIntegrationTests.swift index 0358973..f38288d 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Navigation/DriverNavigationIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Navigation/DriverNavigationIntegrationTests.swift @@ -6,7 +6,7 @@ @testable import SwiftWebDriver import Testing -internal class DriverNavigationIntegrationTestBase: +internal class DriverNavigationIntegrationTest: DriverIntegrationTest { internal func runGetNavigationTitleTest() async throws { @@ -42,7 +42,7 @@ internal class DriverNavigationIntegrationTestBase + DriverNavigationIntegrationTest { @Test("Get Navigation Title") internal func getNavigationTitle() async throws { @@ -57,7 +57,7 @@ internal final class ChromeDriverNavigationIntegrationTests: @Suite("Firefox Driver Navigation Tests", .serialized) internal final class FirefoxDriverNavigationIntegrationTests: - DriverNavigationIntegrationTestBase + DriverNavigationIntegrationTest { @Test("Get Navigation Title") internal func getNavigationTitle() async throws { diff --git a/Tests/SwiftWebDriverIntegrationTests/Start/DriverStartTests.swift b/Tests/SwiftWebDriverIntegrationTests/Start/DriverStartTests.swift index 11ddafa..f3ad97b 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Start/DriverStartTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Start/DriverStartTests.swift @@ -6,7 +6,7 @@ @testable import SwiftWebDriver import Testing -internal class DriverStartTestBase: +internal class DriverStartTest: DriverIntegrationTest { internal func runStartAndStopTest() async throws { @@ -20,7 +20,7 @@ internal class DriverStartTestBase: @Suite("Chrome Driver Start Tests", .serialized) internal final class ChromeDriverStartTests: - DriverStartTestBase + DriverStartTest { @Test("Start & Stop") internal func startAndStop() async throws { @@ -30,7 +30,7 @@ internal final class ChromeDriverStartTests: @Suite("Firefox Driver Start Tests", .serialized) internal final class FirefoxDriverStartTests: - DriverStartTestBase + DriverStartTest { @Test("Start & Stop") internal func startAndStop() async throws { From 116f680642e04b214c3aadcc507a470bbbb95ef0 Mon Sep 17 00:00:00 2001 From: William Date: Thu, 9 Jul 2026 13:11:00 +0200 Subject: [PATCH 08/16] refactor: update visibility of internal types and methods and add deinit cleanup to integration tests --- .../SeleniumSwiftExampleTests.swift | 2 + .../API/Request/Elements/ElementsTypes.swift | 16 ++--- .../Request/Sessions/NewSessionRequest.swift | 30 ++++----- .../SwiftWebDriver/WebDrivers/Driver.swift | 4 +- .../WebDrivers/Firefox/FirefoxOptions.swift | 4 +- .../DriverJavascriptIntegrationTests.swift | 12 +++- .../DriverIntegrationTest.swift | 67 ++++++------------- .../DriverDragAndDropIntegrationTests.swift | 8 +++ .../DriverElementHandleIntegrationTests.swift | 8 +++ .../DriverFindElementIntegrationTests.swift | 8 +++ .../DriverFindElementsIntegrationTests.swift | 8 +++ .../DriverPropertyIntegrationTests.swift | 8 +++ .../DriverSetAttributeIntegrationTests.swift | 8 +++ .../DriverSpecialKeysIntegrationTests.swift | 8 +++ .../DriverNavigationIntegrationTests.swift | 8 +++ .../Start/DriverStartTests.swift | 8 +++ 16 files changed, 130 insertions(+), 77 deletions(-) diff --git a/Example/Tests/SeleniumSwiftExampleTests/SeleniumSwiftExampleTests.swift b/Example/Tests/SeleniumSwiftExampleTests/SeleniumSwiftExampleTests.swift index 6df5322..4e678e2 100644 --- a/Example/Tests/SeleniumSwiftExampleTests/SeleniumSwiftExampleTests.swift +++ b/Example/Tests/SeleniumSwiftExampleTests/SeleniumSwiftExampleTests.swift @@ -6,6 +6,8 @@ import class Foundation.Bundle import XCTest +internal enum SeleniumSwiftExample {} + public final class SeleniumSwiftExampleTests: XCTestCase { public func testExample() throws { // This is an example of a functional test case. diff --git a/Sources/SwiftWebDriver/API/Request/Elements/ElementsTypes.swift b/Sources/SwiftWebDriver/API/Request/Elements/ElementsTypes.swift index 84fdecb..f388d1b 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/ElementsTypes.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/ElementsTypes.swift @@ -20,26 +20,26 @@ public enum ElementsTypes { case CLEAR = "\u{E005}" case CONTROL = "\u{E009}" case DELETE = "\u{E017}" - case DOWN_ARROW = "\u{E015}" + case DOWNARROW = "\u{E015}" case END = "\u{E010}" case ENTER1 = "\u{E007}" case ESCAPE = "\u{E00C}" - case F1 = "\u{E031}" - case F2 = "\u{E032}" + case FKEY1 = "\u{E031}" + case FKEY2 = "\u{E032}" case HELP = "\u{E002}" case HOME = "\u{E011}" case INSERT = "\u{E016}" - case LEFT_ARROW = "\u{E012}" + case LEFTARROW = "\u{E012}" case NULL = "\u{E000}" - case PAGE_DOWN = "\u{E00F}" - case PAGE_UP = "\u{E00E}" + case PAGEDOWN = "\u{E00F}" + case PAGEUP = "\u{E00E}" case PAUSE = "\u{E00B}" case RETURN1 = "\u{E006}" - case RIGHT_ARROW = "\u{E014}" + case RIGHTARROW = "\u{E014}" case SHIFT = "\u{E008}" case SPACE = "\u{E00D}" case TAB = "\u{E004}" - case UP_ARROW = "\u{E013}" + case UPARROW = "\u{E013}" /// The raw Unicode representation of the key. /// diff --git a/Sources/SwiftWebDriver/API/Request/Sessions/NewSessionRequest.swift b/Sources/SwiftWebDriver/API/Request/Sessions/NewSessionRequest.swift index a2e3a10..26cc68e 100644 --- a/Sources/SwiftWebDriver/API/Request/Sessions/NewSessionRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Sessions/NewSessionRequest.swift @@ -41,35 +41,35 @@ internal struct NewSessionRequest: RequestType { internal extension NewSessionRequest { struct RequestBody: Codable { - let capabilities: RequestBodyCapabilities + internal let capabilities: RequestBodyCapabilities } struct Capabilities: Codable { - let alwaysMatch: AlwaysMatch + internal let alwaysMatch: AlwaysMatch } struct AlwaysMatch: Encodable, Decodable { - let browserOptions: Options + internal let browserOptions: Options - enum StaticCodingKeys: String, CodingKey { + internal enum StaticCodingKeys: String, CodingKey { case browserName } - struct DynamicCodingKey: CodingKey { - let stringValue: String + internal struct DynamicCodingKey: CodingKey { + internal let stringValue: String - let intValue: Int? = nil + internal let intValue: Int? = nil - init(stringValue: String) { + internal init(stringValue: String) { self.stringValue = stringValue } - init?(intValue _: Int) { + internal init?(intValue _: Int) { nil } } - func encode(to encoder: Encoder) throws { + internal func encode(to encoder: Encoder) throws { var staticContainer = encoder.container(keyedBy: StaticCodingKeys.self) try staticContainer.encode(Options.browserName, forKey: .browserName) @@ -97,7 +97,7 @@ internal extension NewSessionRequest { internal extension NewSessionRequest { struct RequestBodyCapabilities: Encodable, Decodable { - let alwaysMatch: AlwaysMatch + internal let alwaysMatch: AlwaysMatch } } @@ -120,11 +120,11 @@ internal protocol BrowserOptions: Codable, Decodable { } extension ChromeOptions: BrowserOptions { - static let browserName = "chrome" - static let codingKey = "goog:chromeOptions" + internal static let browserName = "chrome" + internal static let codingKey = "goog:chromeOptions" } extension FirefoxOptions: BrowserOptions { - static let browserName = "firefox" - static let codingKey = "moz:firefoxOptions" + internal static let browserName = "firefox" + internal static let codingKey = "moz:firefoxOptions" } diff --git a/Sources/SwiftWebDriver/WebDrivers/Driver.swift b/Sources/SwiftWebDriver/WebDrivers/Driver.swift index f815063..8c82a62 100644 --- a/Sources/SwiftWebDriver/WebDrivers/Driver.swift +++ b/Sources/SwiftWebDriver/WebDrivers/Driver.swift @@ -59,12 +59,12 @@ public protocol Driver: FindElementProtocol { } extension Driver { - static func stopDriverExternal(url: URL, sessionId: String) async throws { + internal static func stopDriverExternal(url: URL, sessionId: String) async throws { let request = DeleteSessionRequest(baseURL: url, sessionId: sessionId) _ = try await APIClient.shared.request(request).map(\.value).get() } - static func startDriverExternal( + internal static func startDriverExternal( url: URL, browserObject: some BrowserOptions, client: APIClient diff --git a/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxOptions.swift b/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxOptions.swift index c7406d6..4b2a0aa 100644 --- a/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxOptions.swift +++ b/Sources/SwiftWebDriver/WebDrivers/Firefox/FirefoxOptions.swift @@ -19,7 +19,7 @@ public struct FirefoxOptions: Codable { public let log: FirefoxLog? public let env: [String: String]? - init( + public init( binary: String? = nil, args: [FirefoxArgs]? = nil, profile: String? = nil, @@ -76,9 +76,9 @@ public struct FirefoxArgs: RawRepresentable, Codable, CustomStringConvertible { } public enum FirefoxPreferenceValue: Codable { - case string(String) case bool(Bool) case int(Int) + case string(String) } public struct FirefoxLog: Codable { diff --git a/Tests/SwiftWebDriverIntegrationTests/DevTools/DriverJavascriptIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/DevTools/DriverJavascriptIntegrationTests.swift index 10d12f2..8b58899 100644 --- a/Tests/SwiftWebDriverIntegrationTests/DevTools/DriverJavascriptIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/DevTools/DriverJavascriptIntegrationTests.swift @@ -8,7 +8,7 @@ import Foundation import Testing internal enum JavascriptIntegrationTestCases { - static let syncExecution: [(script: String, expected: String)] = [ + internal static let syncExecution: [(script: String, expected: String)] = [ ("return `${1 + 2}`", "3"), ("return `${5 - 3}`", "2"), ("return `${3 * 4}`", "12"), @@ -22,7 +22,7 @@ internal enum JavascriptIntegrationTestCases { ("document.body.innerHTML = '

Hello, World!

'; return document.body.innerText", "Hello, World!") ] - static let asyncExecution: [(script: String, expected: String)] = [ + internal static let asyncExecution: [(script: String, expected: String)] = [ ( """ var callback = arguments[arguments.length - 1]; @@ -33,6 +33,8 @@ internal enum JavascriptIntegrationTestCases { ] } +internal enum DriverJavascriptIntegration {} + internal class DriverJavascriptIntegrationTest: DriverIntegrationTest { @@ -68,6 +70,8 @@ internal class DriverJavascriptIntegrationTest { - public let baseUrl = "http://httpd" + internal let baseUrl = "http://httpd" - public var testPageURL: URL { - URL(string: "\(baseUrl)/\(page)")! + internal var testPageURL: URL { + guard let url = URL(string: "\(baseUrl)/\(page)") else { + fatalError("Invalid test page URL for page: \(page)") + } + return url } - public var page = "index.html" + internal var page = "index.html" - public var driver: WebDriver + internal var driver: WebDriver - public required init() async throws { + internal required init() async throws { driver = WebDriver( driver: Configuration.ConcreteDriver( driverURL: Configuration.seleniumURL, @@ -63,38 +66,6 @@ internal class DriverIntegrationTest { try await driver.start() } -} -// internal class ChromeDriverTest: ChromeDriverIntegrationTestsBase { -// public let baseUrl: String = "http://httpd" -// public var testPageURL: URL { -// // swiftlint:disable:next force_unwrapping -// .init(string: "\(baseUrl)/\(page)")! -// } -// -// public var page: String = "index.html" -// public var driver: WebDriver -// -// public init() async throws { -// // swiftlint:disable:next force_unwrapping -// let driverURL = URL(string: "http://selenium_chrome:4444")! -// let chromeOptions = ChromeOptions(args: [ -// ChromeArgs(.disableDevShmUsage), -// Args(.noSandbox), -// ]) -// -// // Initialize the WebDriver on the main actor -// driver = WebDriver( -// driver: ChromeDriver( -// driverURL: driverURL, -// browserObject: chromeOptions -// ) -// ) -// -// try await driver.start() -// } -// -// deinit { -// // Add deinit here -// } -// } + deinit {} +} diff --git a/Tests/SwiftWebDriverIntegrationTests/Element/DriverDragAndDropIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/Element/DriverDragAndDropIntegrationTests.swift index 90405ce..1941a7d 100644 --- a/Tests/SwiftWebDriverIntegrationTests/Element/DriverDragAndDropIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/Element/DriverDragAndDropIntegrationTests.swift @@ -6,6 +6,8 @@ @testable import SwiftWebDriver import Testing +internal enum DriverDragAndDropIntegration {} + internal class DriverDragAndDropIntegrationTest: DriverIntegrationTest { @@ -26,6 +28,8 @@ internal class DriverDragAndDropIntegrationTest: DriverIntegrationTest { @@ -146,6 +148,8 @@ internal class DriverElementHandleIntegrationTest: DriverIntegrationTest { @@ -75,6 +77,8 @@ internal class DriverFindElementIntegrationTest: DriverIntegrationTest { @@ -107,6 +109,8 @@ internal class DriverFindElementsIntegrationTest: DriverIntegrationTest { @@ -62,6 +64,8 @@ internal class DriverPropertyIntegrationTest: DriverIntegrationTest { @@ -26,6 +28,8 @@ internal class DriverSetAttributeIntegrationTest: DriverIntegrationTest { @@ -24,6 +26,8 @@ internal class DriverSpecialKeysIntegrationTest: DriverIntegrationTest { @@ -38,6 +40,8 @@ internal class DriverNavigationIntegrationTest: DriverIntegrationTest { @@ -16,6 +18,8 @@ internal class DriverStartTest: let sessionId = try await driver.start() #expect(sessionId != "") } + + deinit {} } @Suite("Chrome Driver Start Tests", .serialized) @@ -26,6 +30,8 @@ internal final class ChromeDriverStartTests: internal func startAndStop() async throws { try await runStartAndStopTest() } + + deinit {} } @Suite("Firefox Driver Start Tests", .serialized) @@ -36,4 +42,6 @@ internal final class FirefoxDriverStartTests: internal func startAndStop() async throws { try await runStartAndStopTest() } + + deinit {} } From 2828ae0d30a1842d54923310c673f92d333aea07 Mon Sep 17 00:00:00 2001 From: William Date: Thu, 9 Jul 2026 13:11:32 +0200 Subject: [PATCH 09/16] dotfiles changes --- .dotfiles | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.dotfiles b/.dotfiles index ec9bc76..b9e67aa 160000 --- a/.dotfiles +++ b/.dotfiles @@ -1 +1 @@ -Subproject commit ec9bc762fe9f4a14eee111d5ae65f02dab540b0b +Subproject commit b9e67aa29dd6f69a719295f30935bbee00544847 From fbc5b0981301dd28f92ec92bc90cb421a1d35f18 Mon Sep 17 00:00:00 2001 From: William Date: Thu, 9 Jul 2026 14:08:22 +0200 Subject: [PATCH 10/16] fix: skip tests arg added, added test as compose service hopefully fix tests test action not passing in gh actions --- .github/workflows/run-all-tests.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/run-all-tests.yml b/.github/workflows/run-all-tests.yml index 24e1efe..9fcd42c 100644 --- a/.github/workflows/run-all-tests.yml +++ b/.github/workflows/run-all-tests.yml @@ -27,7 +27,8 @@ jobs: with: compose: "true" required_healthy_services_docker_compose: '["selenium_chrome", "selenium_firefox", "httpd"]' - compose_services_to_startup: '["selenium_chrome", "selenium_firefox", "httpd"]' + compose_services_to_startup: '["selenium_chrome", "selenium_firefox", "httpd", "test"]' + skip-tests: "true" env: PATH: "/usr/local/bin:/usr/bin:/bin" From 9fd885cf805510f57ee81b40ed551275ac81ec8d Mon Sep 17 00:00:00 2001 From: William Date: Thu, 9 Jul 2026 14:32:12 +0200 Subject: [PATCH 11/16] fixup! fix: skip tests arg added, added test as compose service --- .github/workflows/run-all-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-all-tests.yml b/.github/workflows/run-all-tests.yml index 9fcd42c..ab7f9b3 100644 --- a/.github/workflows/run-all-tests.yml +++ b/.github/workflows/run-all-tests.yml @@ -27,8 +27,8 @@ jobs: with: compose: "true" required_healthy_services_docker_compose: '["selenium_chrome", "selenium_firefox", "httpd"]' - compose_services_to_startup: '["selenium_chrome", "selenium_firefox", "httpd", "test"]' - skip-tests: "true" + compose_services_to_startup: '["selenium_chrome", "selenium_firefox", "httpd"]' + tests-as-compose-service-name: "test" env: PATH: "/usr/local/bin:/usr/bin:/bin" From e454ce1f827143ba867c8ac45a5d1c1484b2fb9d Mon Sep 17 00:00:00 2001 From: William Date: Thu, 9 Jul 2026 19:03:32 +0200 Subject: [PATCH 12/16] feat: added se node max sessions env var --- .github/workflows/run-all-tests.yml | 8 +++++--- docker-compose.yml | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/run-all-tests.yml b/.github/workflows/run-all-tests.yml index ab7f9b3..7291604 100644 --- a/.github/workflows/run-all-tests.yml +++ b/.github/workflows/run-all-tests.yml @@ -8,6 +8,11 @@ on: jobs: all-tests: runs-on: ubuntu-latest + + env: + PATH: "/usr/local/bin:/usr/bin:/bin" + SELENIUM_MAX_SESSIONS: "1" + steps: - uses: actions/checkout@v4 @@ -29,6 +34,3 @@ jobs: required_healthy_services_docker_compose: '["selenium_chrome", "selenium_firefox", "httpd"]' compose_services_to_startup: '["selenium_chrome", "selenium_firefox", "httpd"]' tests-as-compose-service-name: "test" - - env: - PATH: "/usr/local/bin:/usr/bin:/bin" diff --git a/docker-compose.yml b/docker-compose.yml index 8a2620d..7bb888c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,7 +19,7 @@ services: - 4444:4444 - 7900:7900 environment: - - SE_NODE_MAX_SESSIONS=4 + SE_NODE_MAX_SESSIONS: "${SELENIUM_MAX_SESSIONS:-4}" healthcheck: test: ["CMD", "curl", "-f", "http://localhost:4444/status"] interval: 30s @@ -32,7 +32,7 @@ services: - 4445:4444 - 7901:7900 environment: - - SE_NODE_MAX_SESSIONS=4 + SE_NODE_MAX_SESSIONS: "${SELENIUM_MAX_SESSIONS:-4}" healthcheck: test: ["CMD", "curl", "-f", "http://localhost:4444/status"] interval: 30s From b70880df44838c9e02a22292c0b8667e457439da Mon Sep 17 00:00:00 2001 From: William Date: Thu, 9 Jul 2026 19:17:33 +0200 Subject: [PATCH 13/16] fixup! feat: added se node max sessions env var --- .github/workflows/run-all-tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/run-all-tests.yml b/.github/workflows/run-all-tests.yml index 7291604..239ee88 100644 --- a/.github/workflows/run-all-tests.yml +++ b/.github/workflows/run-all-tests.yml @@ -29,6 +29,8 @@ jobs: - name: Run All Tests uses: GetAutomaApp/opensource-actions/swifttesting@main + env: + SELENIUM_MAX_SESSIONS: "1" with: compose: "true" required_healthy_services_docker_compose: '["selenium_chrome", "selenium_firefox", "httpd"]' From 8f9080ea34cb4592ac30c13e5ef08e3e8bccec34 Mon Sep 17 00:00:00 2001 From: William Date: Fri, 10 Jul 2026 15:58:58 +0200 Subject: [PATCH 14/16] fixup! fixup! feat: added se node max sessions env var --- .github/workflows/run-all-tests.yml | 2 ++ docker-compose.yml | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/run-all-tests.yml b/.github/workflows/run-all-tests.yml index 239ee88..57d5e24 100644 --- a/.github/workflows/run-all-tests.yml +++ b/.github/workflows/run-all-tests.yml @@ -31,8 +31,10 @@ jobs: uses: GetAutomaApp/opensource-actions/swifttesting@main env: SELENIUM_MAX_SESSIONS: "1" + SWIFT_TEST_WORKERS: "1" with: compose: "true" required_healthy_services_docker_compose: '["selenium_chrome", "selenium_firefox", "httpd"]' compose_services_to_startup: '["selenium_chrome", "selenium_firefox", "httpd"]' tests-as-compose-service-name: "test" + diff --git a/docker-compose.yml b/docker-compose.yml index 7bb888c..7037481 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -65,7 +65,13 @@ services: test: <<: *SwiftWebDriver - command: /bin/bash -xcl "swift test -Xswiftc -warnings-as-errors $${SANITIZER_ARG-}" + command: > + /bin/bash -xcl + "swift test + --parallel + --num-workers $${SWIFT_TEST_WORKERS:-4} + -Xswiftc -warnings-as-errors + $${SANITIZER_ARG-}" shell: <<: *SwiftWebDriver From 39795a450ec3f840c8d7342974545dca01c34ec7 Mon Sep 17 00:00:00 2001 From: William Date: Fri, 10 Jul 2026 16:14:17 +0200 Subject: [PATCH 15/16] fixup! fixup! fixup! feat: added se node max sessions env var --- .github/workflows/run-all-tests.yml | 4 +--- docker-compose.yml | 4 +++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/run-all-tests.yml b/.github/workflows/run-all-tests.yml index 57d5e24..b26a874 100644 --- a/.github/workflows/run-all-tests.yml +++ b/.github/workflows/run-all-tests.yml @@ -12,6 +12,7 @@ jobs: env: PATH: "/usr/local/bin:/usr/bin:/bin" SELENIUM_MAX_SESSIONS: "1" + SWIFT_TEST_WORKERS: "1" steps: - uses: actions/checkout@v4 @@ -29,9 +30,6 @@ jobs: - name: Run All Tests uses: GetAutomaApp/opensource-actions/swifttesting@main - env: - SELENIUM_MAX_SESSIONS: "1" - SWIFT_TEST_WORKERS: "1" with: compose: "true" required_healthy_services_docker_compose: '["selenium_chrome", "selenium_firefox", "httpd"]' diff --git a/docker-compose.yml b/docker-compose.yml index 7037481..98c1a2d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -50,6 +50,8 @@ services: CHROME_SELENIUM_URL: http://selenium_chrome:4444 FIREFOX_SELENIUM_URL: http://selenium_firefox:4444 TEST_SERVER_URL: http://httpd + SANITIZER_ARG: "${SANITIZER_ARG:-}" + SWIFT_TEST_WORKERS: "${SWIFT_TEST_WORKERS:-4}" tty: true depends_on: selenium_chrome: @@ -71,7 +73,7 @@ services: --parallel --num-workers $${SWIFT_TEST_WORKERS:-4} -Xswiftc -warnings-as-errors - $${SANITIZER_ARG-}" + $${SANITIZER_ARG:-}" shell: <<: *SwiftWebDriver From a4f78360dec5087d2b6cd3ffe04bc86f779a41d0 Mon Sep 17 00:00:00 2001 From: William Date: Fri, 10 Jul 2026 16:34:03 +0200 Subject: [PATCH 16/16] fixup! fixup! fixup! fixup! feat: added se node max sessions env var --- .github/workflows/run-all-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-all-tests.yml b/.github/workflows/run-all-tests.yml index b26a874..d02f051 100644 --- a/.github/workflows/run-all-tests.yml +++ b/.github/workflows/run-all-tests.yml @@ -11,8 +11,8 @@ jobs: env: PATH: "/usr/local/bin:/usr/bin:/bin" - SELENIUM_MAX_SESSIONS: "1" - SWIFT_TEST_WORKERS: "1" + SELENIUM_MAX_SESSIONS: "2" + SWIFT_TEST_WORKERS: "2" steps: - uses: actions/checkout@v4