diff --git a/Sources/SwiftWebDriver/API/Response/Sessions/StatusResponse.swift b/Sources/SwiftWebDriver/API/Response/Sessions/StatusResponse.swift index 60a3972..3ca4bd5 100644 --- a/Sources/SwiftWebDriver/API/Response/Sessions/StatusResponse.swift +++ b/Sources/SwiftWebDriver/API/Response/Sessions/StatusResponse.swift @@ -8,10 +8,10 @@ import Foundation public struct StatusResponse: Codable { - let value: Value + public let value: Value - struct Value: Codable { - let ready: Bool - let message: String + public struct Value: Codable { + public let ready: Bool + public let message: String } } diff --git a/Sources/SwiftWebDriver/Element/Element.swift b/Sources/SwiftWebDriver/Element/Element.swift index 5194bbc..7f67825 100644 --- a/Sources/SwiftWebDriver/Element/Element.swift +++ b/Sources/SwiftWebDriver/Element/Element.swift @@ -11,6 +11,7 @@ import NIO public protocol FindElementProtocol { func findElement(_ locatorType: LocatorType) async throws -> Element func findElements(_ locatorType: LocatorType) async throws -> Elements + func waitUntil(_ locatorType: LocatorType, retryCount: Int, durationSeconds: Int) async throws -> Bool } public protocol ElementCommandProtocol: FindElementProtocol { @@ -97,4 +98,29 @@ public struct Element: ElementCommandProtocol { let response = try await APIClient.shared.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 { + + do { + let _ = try await findElement(locatorType) + return true + } catch let error { + guard + retryCount > 0, + let error = error as? SeleniumError + else { return false } + + guard error.value.error == "no such element" else { + return false + } + + let retryCount = retryCount - 1 + + sleep(UInt32(durationSeconds)) + + return try await waitUntil(locatorType, retryCount: retryCount, durationSeconds: durationSeconds) + } + } } diff --git a/Sources/SwiftWebDriver/Element/Elements.swift b/Sources/SwiftWebDriver/Element/Elements.swift index a1a99df..6d1e062 100644 --- a/Sources/SwiftWebDriver/Element/Elements.swift +++ b/Sources/SwiftWebDriver/Element/Elements.swift @@ -92,4 +92,29 @@ extension Elements { return elements.flatMap{ $0 } } + + @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 { + + do { + let _ = try await findElement(locatorType) + return true + } catch let error { + guard + retryCount > 0, + let error = error as? SeleniumError + else { return false } + + guard error.value.error == "no such element" else { + return false + } + + let retryCount = retryCount - 1 + + sleep(UInt32(durationSeconds)) + + return try await waitUntil(locatorType, retryCount: retryCount, durationSeconds: durationSeconds) + } + } } diff --git a/Sources/SwiftWebDriver/WebDriver.swift b/Sources/SwiftWebDriver/WebDriver.swift index 4fed014..f1a37a9 100644 --- a/Sources/SwiftWebDriver/WebDriver.swift +++ b/Sources/SwiftWebDriver/WebDriver.swift @@ -113,6 +113,7 @@ public class WebDriver { } @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 { return try await driver.waitUntil(locatorType, retryCount: retryCount, durationSeconds: durationSeconds) } diff --git a/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeDriver.swift b/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeDriver.swift index b926b52..239427d 100644 --- a/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeDriver.swift +++ b/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeDriver.swift @@ -201,6 +201,7 @@ public class ChromeDriver: Driver { } @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 = sessionId else {