From e7e1aae9ba6c5ae120ad3d3e439c1c79f3a89eac Mon Sep 17 00:00:00 2001 From: Squidonomics Date: Sun, 3 Dec 2023 16:43:35 -0800 Subject: [PATCH 1/5] feat: Location method --- Docs/SupportedAPIs.md | 3 +- Sources/WebDriver/Requests.swift | 35 +++++++++++++++++++ Sources/WebDriver/Session.swift | 13 +++++++ .../UnitTests/APIToRequestMappingTests.swift | 13 +++++++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/Docs/SupportedAPIs.md b/Docs/SupportedAPIs.md index 1e6c987..7193db0 100644 --- a/Docs/SupportedAPIs.md +++ b/Docs/SupportedAPIs.md @@ -39,7 +39,8 @@ Contributions to expand support to unimplemented functionality are always welcom | POST | `/session/:sessionId/element/:id/value` | Supported | `Element.sendKeys()`| | POST | `/session/:sessionId/forward` | Supported | `Session.forward()` | | POST | `/session/:sessionId/keys` | Supported | `Session.sendKeys()`| -| GET | `/session/:sessionId/location` | Supported | Not implemented | +| POST | `/session/:sessionId/location` | Supported | `Session.setLocation`| +| GET | `/session/:sessionId/location` | Supported | `Session.getLocation`| | POST | `/session/:sessionId/moveto` | Supported | `Session.moveTo()` | | GET | `/session/:sessionId/orientation` | Supported | Not implemented | | POST | `/session/:sessionId/refresh` | Not supported| `Session.refresh()` | diff --git a/Sources/WebDriver/Requests.swift b/Sources/WebDriver/Requests.swift index 0351bc0..0936a34 100644 --- a/Sources/WebDriver/Requests.swift +++ b/Sources/WebDriver/Requests.swift @@ -524,6 +524,41 @@ public enum Requests { } } + // https://www.selenium.dev/documentation/legacy/json_wire_protocol/#sessionsessionidlocation + public enum SessionGeoLocation { + public struct Post: Request { + public var session: String + public var latitude: Int + public var longitude: Int + public var altitude: Int + + public var pathComponents: [String] {["session", session, "location"]} + public var method: HTTPMethod { .post } + public var body: Body {.init(latitude: latitude, longitude: longitude, altitude: altitude)} + + public struct Body: Codable { + public var latitude: Int + public var longitude: Int + public var altitude: Int + } + } + + public struct Get: Request { + public var session: String + + public var pathComponents: [String] {["session", session, "location"]} + public var method: HTTPMethod {.get} + + public typealias Response = ResponseWithValue + + public struct ResponseValue: Codable { + public var latitude: Int + public var longitude: Int + public var altitude: Int + } + } + } + // https://www.selenium.dev/documentation/legacy/json_wire_protocol/#status public struct Status: Request { public var pathComponents: [String] { ["status"] } diff --git a/Sources/WebDriver/Session.swift b/Sources/WebDriver/Session.swift index 22bd368..ea20e54 100644 --- a/Sources/WebDriver/Session.swift +++ b/Sources/WebDriver/Session.swift @@ -317,6 +317,19 @@ public class Session { try webDriver.send(Requests.SessionWindowSize.Post(session: id, windowHandle: handle, width: width, height: height)) } + /// - Parameters: + /// - latitude: Number coordinate of current geo location + /// - longitude: Number coordinate of current geo location + /// - altitude: Number coordinate of current geo location + public func setLocation(latitude: Int, longitude: Int, altitude: Int) throws { + try webDriver.send(Requests.SessionGeoLocation.Post(session: id, latitude: latitude, longitude: longitude, altitude: altitude)) + } + + public func getLocation() throws -> (latitude: Int, longitude: Int, altitude: Int) { + let response = try webDriver.send(Requests.SessionGeoLocation.Get(session: id)) + return (latitude: response.value.latitude, longitude: response.value.longitude, altitude: response.value.altitude) + } + /// Deletes the current session. public func delete() throws { guard shouldDelete else { return } diff --git a/Tests/UnitTests/APIToRequestMappingTests.swift b/Tests/UnitTests/APIToRequestMappingTests.swift index a674dd4..ad51f9b 100644 --- a/Tests/UnitTests/APIToRequestMappingTests.swift +++ b/Tests/UnitTests/APIToRequestMappingTests.swift @@ -199,4 +199,17 @@ class APIToRequestMappingTests: XCTestCase { } XCTAssert(try session.size(window: "myWindow") == (width: 500, height: 500)) } + + func testGeoLocation() throws { + let mockWebDriver: MockWebDriver = MockWebDriver() + let session = Session(webDriver: mockWebDriver, existingId: "mySession") + + mockWebDriver.expect(path: "session/mySession/location", method: .post) + try session.setLocation(latitude: 5, longitude: 20, altitude: 2003) + + mockWebDriver.expect(path: "session/mySession/window/myWindow/size", method: .get, type: Requests.SessionGeoLocation.Get.self) { + ResponseWithValue(.init(latitude: 5, longitude: 20, altitude: 2003)) + } + XCTAssert(try session.getLocation() == (latitude: 5, longitude: 20, altitude: 2003)) + } } From 3cbcb11cfdc1d51569a12ce5b2d5b58d63be9f8d Mon Sep 17 00:00:00 2001 From: Squidonomics Date: Sun, 3 Dec 2023 16:49:16 -0800 Subject: [PATCH 2/5] fix: Failing tests --- Tests/UnitTests/APIToRequestMappingTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/UnitTests/APIToRequestMappingTests.swift b/Tests/UnitTests/APIToRequestMappingTests.swift index ad51f9b..ed015cb 100644 --- a/Tests/UnitTests/APIToRequestMappingTests.swift +++ b/Tests/UnitTests/APIToRequestMappingTests.swift @@ -207,7 +207,7 @@ class APIToRequestMappingTests: XCTestCase { mockWebDriver.expect(path: "session/mySession/location", method: .post) try session.setLocation(latitude: 5, longitude: 20, altitude: 2003) - mockWebDriver.expect(path: "session/mySession/window/myWindow/size", method: .get, type: Requests.SessionGeoLocation.Get.self) { + mockWebDriver.expect(path: "session/mySession/location", method: .get, type: Requests.SessionGeoLocation.Get.self) { ResponseWithValue(.init(latitude: 5, longitude: 20, altitude: 2003)) } XCTAssert(try session.getLocation() == (latitude: 5, longitude: 20, altitude: 2003)) From 55a9e21090673edf8490c05b42b3bdf3e4ee413c Mon Sep 17 00:00:00 2001 From: Squidonomics Date: Fri, 23 Feb 2024 18:50:10 -0500 Subject: [PATCH 3/5] feat: Address pr comments --- Sources/WebDriver/Location.swift | 16 ++++++++++ Sources/WebDriver/Requests.swift | 29 ++++++------------- Sources/WebDriver/Session.swift | 15 ++++++---- .../UnitTests/APIToRequestMappingTests.swift | 10 ++++--- 4 files changed, 40 insertions(+), 30 deletions(-) create mode 100644 Sources/WebDriver/Location.swift diff --git a/Sources/WebDriver/Location.swift b/Sources/WebDriver/Location.swift new file mode 100644 index 0000000..6d42e57 --- /dev/null +++ b/Sources/WebDriver/Location.swift @@ -0,0 +1,16 @@ +public struct Location: Codable { + public var latitude: Double + public var longitude: Double + public var altitude: Float + + init(latitude: Double, longitude: Double, altitude: Float) { + self.latitude = latitude + self.longitude = longitude + self.altitude = altitude + } + +} + +extension Location: Equatable { + +} diff --git a/Sources/WebDriver/Requests.swift b/Sources/WebDriver/Requests.swift index f9f710b..dc3ff3e 100644 --- a/Sources/WebDriver/Requests.swift +++ b/Sources/WebDriver/Requests.swift @@ -542,38 +542,27 @@ public enum Requests { } // https://www.selenium.dev/documentation/legacy/json_wire_protocol/#sessionsessionidlocation - public enum SessionGeoLocation { + public enum SessionLocation { public struct Post: Request { public var session: String - public var latitude: Int - public var longitude: Int - public var altitude: Int + public var latitude: Double + public var longitude: Double + public var altitude: Float - public var pathComponents: [String] {["session", session, "location"]} + public var pathComponents: [String] { ["session", session, "location"] } public var method: HTTPMethod { .post } - public var body: Body {.init(latitude: latitude, longitude: longitude, altitude: altitude)} - - public struct Body: Codable { - public var latitude: Int - public var longitude: Int - public var altitude: Int - } + public var body: Location { .init(latitude: latitude, longitude: longitude, altitude: altitude) } } public struct Get: Request { public var session: String - public var pathComponents: [String] {["session", session, "location"]} + public var pathComponents: [String] { ["session", session, "location"] } public var method: HTTPMethod {.get} - public typealias Response = ResponseWithValue - - public struct ResponseValue: Codable { - public var latitude: Int - public var longitude: Int - public var altitude: Int - } + public typealias Response = ResponseWithValue } + } // https://www.selenium.dev/documentation/legacy/json_wire_protocol/#sessionsessionidsource public struct SessionSource: Request { diff --git a/Sources/WebDriver/Session.swift b/Sources/WebDriver/Session.swift index 4814f06..9ce870a 100644 --- a/Sources/WebDriver/Session.swift +++ b/Sources/WebDriver/Session.swift @@ -66,6 +66,13 @@ public class Session { } } } + + public var location: Location { + get throws { + let response = try webDriver.send(Requests.SessionLocation.Get(session: id)) + return Location(latitude: response.value.latitude, longitude: response.value.longitude, altitude: response.value.altitude) + } + } /// Sets a a timeout value on this session. public func setTimeout(type: String, duration: TimeInterval) throws { @@ -325,14 +332,10 @@ public class Session { /// - latitude: Number coordinate of current geo location /// - longitude: Number coordinate of current geo location /// - altitude: Number coordinate of current geo location - public func setLocation(latitude: Int, longitude: Int, altitude: Int) throws { - try webDriver.send(Requests.SessionGeoLocation.Post(session: id, latitude: latitude, longitude: longitude, altitude: altitude)) + public func setLocation(latitude: Double, longitude: Double, altitude: Float) throws { + try webDriver.send(Requests.SessionLocation.Post(session: id, latitude: latitude, longitude: longitude, altitude: altitude)) } - public func getLocation() throws -> (latitude: Int, longitude: Int, altitude: Int) { - let response = try webDriver.send(Requests.SessionGeoLocation.Get(session: id)) - return (latitude: response.value.latitude, longitude: response.value.longitude, altitude: response.value.altitude) - /// - Returns: The current page source. public func source() throws -> String { let response = try webDriver.send(Requests.SessionSource(session: id)) diff --git a/Tests/UnitTests/APIToRequestMappingTests.swift b/Tests/UnitTests/APIToRequestMappingTests.swift index 90b9498..0af18bb 100644 --- a/Tests/UnitTests/APIToRequestMappingTests.swift +++ b/Tests/UnitTests/APIToRequestMappingTests.swift @@ -214,17 +214,19 @@ class APIToRequestMappingTests: XCTestCase { XCTAssert(try session.size(window: "myWindow") == (width: 500, height: 500)) } - func testGeoLocation() throws { + func testLocation() throws { let mockWebDriver: MockWebDriver = MockWebDriver() let session = Session(webDriver: mockWebDriver, existingId: "mySession") + let location = Location(latitude: 5, longitude: 20, altitude: 2003) mockWebDriver.expect(path: "session/mySession/location", method: .post) try session.setLocation(latitude: 5, longitude: 20, altitude: 2003) - - mockWebDriver.expect(path: "session/mySession/location", method: .get, type: Requests.SessionGeoLocation.Get.self) { + + mockWebDriver.expect(path: "session/mySession/location", method: .get, type: Requests.SessionLocation.Get.self) { ResponseWithValue(.init(latitude: 5, longitude: 20, altitude: 2003)) } - XCTAssert(try session.getLocation() == (latitude: 5, longitude: 20, altitude: 2003)) + XCTAssert(try session.location == location) + } func testSessionSource() throws { let mockWebDriver: MockWebDriver = MockWebDriver() From 2bc9fff66654be32ff5308cfdce80037863c3e17 Mon Sep 17 00:00:00 2001 From: Squidonomics Date: Mon, 26 Feb 2024 18:48:44 -0500 Subject: [PATCH 4/5] fix: Add location type to response --- Docs/SupportedAPIs.md | 2 +- Sources/WebDriver/Location.swift | 10 +++------- Sources/WebDriver/Requests.swift | 3 ++- Sources/WebDriver/Session.swift | 11 ++++------- Tests/UnitTests/APIToRequestMappingTests.swift | 2 +- 5 files changed, 11 insertions(+), 17 deletions(-) diff --git a/Docs/SupportedAPIs.md b/Docs/SupportedAPIs.md index 2aa7ded..eb9fbf9 100644 --- a/Docs/SupportedAPIs.md +++ b/Docs/SupportedAPIs.md @@ -42,7 +42,7 @@ Contributions to expand support to unimplemented functionality are always welcom | POST | `/session/:sessionId/forward` | Supported | `Session.forward()` | | POST | `/session/:sessionId/keys` | Supported | `Session.sendKeys()`| | POST | `/session/:sessionId/location` | Supported | `Session.setLocation`| -| GET | `/session/:sessionId/location` | Supported | `Session.getLocation`| +| GET | `/session/:sessionId/location` | Supported | `Session.location`| | POST | `/session/:sessionId/moveto` | Supported | `Session.moveTo()` | | GET | `/session/:sessionId/orientation` | Supported | Not implemented | | POST | `/session/:sessionId/refresh` | Not supported| `Session.refresh()` | diff --git a/Sources/WebDriver/Location.swift b/Sources/WebDriver/Location.swift index 6d42e57..98cc21c 100644 --- a/Sources/WebDriver/Location.swift +++ b/Sources/WebDriver/Location.swift @@ -1,16 +1,12 @@ -public struct Location: Codable { +public struct Location: Codable, Equatable { public var latitude: Double public var longitude: Double - public var altitude: Float + public var altitude: Double - init(latitude: Double, longitude: Double, altitude: Float) { + public init(latitude: Double, longitude: Double, altitude: Double) { self.latitude = latitude self.longitude = longitude self.altitude = altitude } } - -extension Location: Equatable { - -} diff --git a/Sources/WebDriver/Requests.swift b/Sources/WebDriver/Requests.swift index dc3ff3e..c62e582 100644 --- a/Sources/WebDriver/Requests.swift +++ b/Sources/WebDriver/Requests.swift @@ -547,7 +547,8 @@ public enum Requests { public var session: String public var latitude: Double public var longitude: Double - public var altitude: Float + public var altitude: Double + public var location: Location public var pathComponents: [String] { ["session", session, "location"] } public var method: HTTPMethod { .post } diff --git a/Sources/WebDriver/Session.swift b/Sources/WebDriver/Session.swift index 9ce870a..8748984 100644 --- a/Sources/WebDriver/Session.swift +++ b/Sources/WebDriver/Session.swift @@ -70,7 +70,7 @@ public class Session { public var location: Location { get throws { let response = try webDriver.send(Requests.SessionLocation.Get(session: id)) - return Location(latitude: response.value.latitude, longitude: response.value.longitude, altitude: response.value.altitude) + return response.value } } @@ -328,12 +328,9 @@ public class Session { try webDriver.send(Requests.SessionWindowSize.Post(session: id, windowHandle: handle, width: width, height: height)) } - /// - Parameters: - /// - latitude: Number coordinate of current geo location - /// - longitude: Number coordinate of current geo location - /// - altitude: Number coordinate of current geo location - public func setLocation(latitude: Double, longitude: Double, altitude: Float) throws { - try webDriver.send(Requests.SessionLocation.Post(session: id, latitude: latitude, longitude: longitude, altitude: altitude)) + /// Set the current geolocation + public func setLocation(latitude: Double, longitude: Double, altitude: Double, location: Location) throws { + try webDriver.send(Requests.SessionLocation.Post(session: id, latitude: latitude, longitude: longitude, altitude: altitude, location: location)) } /// - Returns: The current page source. diff --git a/Tests/UnitTests/APIToRequestMappingTests.swift b/Tests/UnitTests/APIToRequestMappingTests.swift index 0af18bb..cb16d5f 100644 --- a/Tests/UnitTests/APIToRequestMappingTests.swift +++ b/Tests/UnitTests/APIToRequestMappingTests.swift @@ -220,7 +220,7 @@ class APIToRequestMappingTests: XCTestCase { let location = Location(latitude: 5, longitude: 20, altitude: 2003) mockWebDriver.expect(path: "session/mySession/location", method: .post) - try session.setLocation(latitude: 5, longitude: 20, altitude: 2003) + try session.setLocation(latitude: 5, longitude: 20, altitude: 2003, location: location) mockWebDriver.expect(path: "session/mySession/location", method: .get, type: Requests.SessionLocation.Get.self) { ResponseWithValue(.init(latitude: 5, longitude: 20, altitude: 2003)) From 42852536ba22865a5b7ed5b50b1788c26021f297 Mon Sep 17 00:00:00 2001 From: Squidonomics Date: Wed, 6 Mar 2024 16:08:21 -0500 Subject: [PATCH 5/5] fix: Rebase and remove old values to add overload --- Sources/WebDriver/Requests.swift | 5 +---- Sources/WebDriver/Session.swift | 12 ++++++------ Tests/UnitTests/APIToRequestMappingTests.swift | 7 ++----- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/Sources/WebDriver/Requests.swift b/Sources/WebDriver/Requests.swift index 94b332d..bc93a29 100644 --- a/Sources/WebDriver/Requests.swift +++ b/Sources/WebDriver/Requests.swift @@ -545,14 +545,11 @@ public enum Requests { public enum SessionLocation { public struct Post: Request { public var session: String - public var latitude: Double - public var longitude: Double - public var altitude: Double public var location: Location public var pathComponents: [String] { ["session", session, "location"] } public var method: HTTPMethod { .post } - public var body: Location { .init(latitude: latitude, longitude: longitude, altitude: altitude) } + public var body: Location { location } } public struct Get: Request { diff --git a/Sources/WebDriver/Session.swift b/Sources/WebDriver/Session.swift index e072856..688ffad 100644 --- a/Sources/WebDriver/Session.swift +++ b/Sources/WebDriver/Session.swift @@ -70,7 +70,9 @@ public class Session { public var location: Location { get throws { let response = try webDriver.send(Requests.SessionLocation.Get(session: id)) + return response.value } + } public var orientation: ScreenOrientation { get throws { @@ -344,14 +346,12 @@ public class Session { } /// Set the current geolocation - public func setLocation(latitude: Double, longitude: Double, altitude: Double, location: Location) throws { - try webDriver.send(Requests.SessionLocation.Post(session: id, latitude: latitude, longitude: longitude, altitude: altitude, location: location)) + public func setLocation(_ location: Location) throws { + try webDriver.send(Requests.SessionLocation.Post(session: id, location: location)) } - /// - Returns: The current page source. - public func source() throws -> String { - let response = try webDriver.send(Requests.SessionSource(session: id)) - return response.value.source + public func setLocation(latitude: Double, longitude: Double, altitude: Double) throws { + try setLocation(Location(latitude: latitude, longitude: longitude, altitude: altitude)) } /// - Returns: Array of window handles diff --git a/Tests/UnitTests/APIToRequestMappingTests.swift b/Tests/UnitTests/APIToRequestMappingTests.swift index 2a4a06f..3181aef 100644 --- a/Tests/UnitTests/APIToRequestMappingTests.swift +++ b/Tests/UnitTests/APIToRequestMappingTests.swift @@ -252,7 +252,7 @@ class APIToRequestMappingTests: XCTestCase { let location = Location(latitude: 5, longitude: 20, altitude: 2003) mockWebDriver.expect(path: "session/mySession/location", method: .post) - try session.setLocation(latitude: 5, longitude: 20, altitude: 2003, location: location) + try session.setLocation(location) mockWebDriver.expect(path: "session/mySession/location", method: .get, type: Requests.SessionLocation.Get.self) { ResponseWithValue(.init(latitude: 5, longitude: 20, altitude: 2003)) @@ -260,10 +260,6 @@ class APIToRequestMappingTests: XCTestCase { XCTAssert(try session.location == location) } - func testSessionSource() throws { - XCTAssert(try session.source == "currentSource") - } - func testMaximizeWindow() throws { let mockWebDriver: MockWebDriver = MockWebDriver() let session: Session = Session(webDriver: mockWebDriver, existingId: "mySession") @@ -298,5 +294,6 @@ class APIToRequestMappingTests: XCTestCase { mockWebDriver.expect(path: "session/mySession/source", method: .get, type: Requests.SessionSource.self) { ResponseWithValue("currentSource") } + XCTAssert(try session.source == "currentSource") } }