diff --git a/Sources/Requests.swift b/Sources/Requests.swift index 0e5f3bd..fbfc0a8 100644 --- a/Sources/Requests.swift +++ b/Sources/Requests.swift @@ -235,6 +235,21 @@ public enum Requests { public typealias Response = ResponseWithValue } + public struct SessionTimeouts: Request { + public var session: String + public var type: String + public var ms: Double + + public var pathComponents: [String] { ["session", session, "timeouts"] } + public var method: HTTPMethod { .post } + public var body: Body { .init(type: type, ms: ms) } + + public struct Body: Codable { + public var type: String + public var ms: Double + } + } + public struct SessionTitle: Request { public var session: String diff --git a/Sources/Session.swift b/Sources/Session.swift index 45e012a..131497d 100644 --- a/Sources/Session.swift +++ b/Sources/Session.swift @@ -33,6 +33,13 @@ public class Session { } } + /// Sets a a timeout value on this session. + /// https://www.selenium.dev/documentation/legacy/json_wire_protocol/#sessionsessionidtimeouts + public func setTimeout(type: String, duration: TimeInterval) throws { + try webDriver.send( + Requests.SessionTimeouts(session: id, type: type, ms: duration * 1000)) + } + /// screenshot() /// Take a screenshot of the current page. /// - Returns: The screenshot data as a PNG file. diff --git a/Sources/TimeoutType.swift b/Sources/TimeoutType.swift new file mode 100644 index 0000000..a4146e3 --- /dev/null +++ b/Sources/TimeoutType.swift @@ -0,0 +1,5 @@ +public enum TimeoutType { + public static let script = "script" + public static let implicitWait = "implicit" + public static let pageLoad = "page load" +} \ No newline at end of file diff --git a/Tests/WebDriverTests/TimeoutTests.swift b/Tests/WebDriverTests/TimeoutTests.swift new file mode 100644 index 0000000..d159c12 --- /dev/null +++ b/Tests/WebDriverTests/TimeoutTests.swift @@ -0,0 +1,55 @@ +@testable import WebDriver +import XCTest + +class TimeoutTests: XCTestCase { + private static var _winAppDriver: Result! + public var winAppDriver: WinAppDriver! { try? Self._winAppDriver.get() } + + public override class func setUp() { + _winAppDriver = Result { try WinAppDriver() } + } + + public override class func tearDown() { + _winAppDriver = nil + } + + public override func setUpWithError() throws { + try XCTSkipIf(winAppDriver == nil) + } + + func startApp() throws -> Session { + // Use a simple app in which we can expect queries to execute quickly + let windowsDir = ProcessInfo.processInfo.environment["SystemRoot"]! + let capabilities = WinAppDriver.Capabilities(app: "\(windowsDir)\\System32\\winver.exe") + return try Session(webDriver: winAppDriver, desiredCapabilities: capabilities) + } + + static func time(_ callback: () throws -> Void) rethrows -> Double { + let before = DispatchTime.now() + try callback() + let after = DispatchTime.now() + return Double(after.uptimeNanoseconds - before.uptimeNanoseconds) / 1_000_000_000 + } + + public func testLibraryImplicitWait() throws { + let session = try startApp() + + // Test library timeout implementation + session.defaultRetryTimeout = 1 + XCTAssert(try Self.time({ _ = try session.findElement(byAccessibilityId: "IdThatDoesNotExist") }) > 0.5) + + session.defaultRetryTimeout = 0 + XCTAssert(try Self.time({ _ = try session.findElement(byAccessibilityId: "IdThatDoesNotExist") }) < 0.5) + } + + public func testWebDriverImplicitWait() throws { + let session = try startApp() + session.defaultRetryTimeout = 0 + + try session.setTimeout(type: TimeoutType.implicitWait, duration: 1) + XCTAssert(try Self.time({ _ = try session.findElement(byAccessibilityId: "IdThatDoesNotExist") }) > 0.5) + + try session.setTimeout(type: TimeoutType.implicitWait, duration: 0) + XCTAssert(try Self.time({ _ = try session.findElement(byAccessibilityId: "IdThatDoesNotExist") }) < 0.5) + } +}