From 2382781ae98647ce65c3cbb1a4c06b00c3dbce6f Mon Sep 17 00:00:00 2001 From: William Date: Thu, 14 Aug 2025 11:31:13 -0600 Subject: [PATCH 1/5] feat(PostElementDragToAnotherRequest): implemented drag method and request to webdriver api Code is untested. Code can compile. Refactored action types from double click request source file to its own source file --- .../API/Request/ActionsPayload.swift | 52 ++++++++++++++++ .../PostElementDoubleClickRequest.swift | 48 -------------- .../PostElementDragToAnotherRequest.swift | 62 +++++++++++++++++++ Sources/SwiftWebDriver/Element/Element.swift | 14 +++++ 4 files changed, 128 insertions(+), 48 deletions(-) create mode 100644 Sources/SwiftWebDriver/API/Request/ActionsPayload.swift create mode 100644 Sources/SwiftWebDriver/API/Request/Elements/PostElementDragToAnotherRequest.swift diff --git a/Sources/SwiftWebDriver/API/Request/ActionsPayload.swift b/Sources/SwiftWebDriver/API/Request/ActionsPayload.swift new file mode 100644 index 0000000..dd97786 --- /dev/null +++ b/Sources/SwiftWebDriver/API/Request/ActionsPayload.swift @@ -0,0 +1,52 @@ +// ActionsPayload.swift +// Copyright (c) 2025 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +struct WebDriverElementOrigin: Encodable { + let element: String + + enum CodingKeys: String, CodingKey { + case element = "element-6066-11e4-a52e-4f735466cecf" + } +} + +struct PointerAction: Encodable { + let type: String + let origin: WebDriverElementOrigin? + let x: Int? + let y: Int? + let button: Int? + let duration: Int? + + init( + type: String, + origin: WebDriverElementOrigin? = nil, + x: Int? = nil, + y: Int? = nil, + button: Int? = nil, + duration: Int? = nil + ) { + self.type = type + self.origin = origin + self.x = x + self.y = y + self.button = button + self.duration = duration + } +} + +struct PointerSource: Encodable { + let type: String + let id: String + let parameters: Parameters + let actions: [PointerAction] + + struct Parameters: Encodable { + let pointerType: String + } +} + +struct ActionsPayload: Encodable { + let actions: [PointerSource] +} diff --git a/Sources/SwiftWebDriver/API/Request/Elements/PostElementDoubleClickRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/PostElementDoubleClickRequest.swift index aba8832..c8f92f0 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/PostElementDoubleClickRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/PostElementDoubleClickRequest.swift @@ -58,51 +58,3 @@ internal struct PostElementDoubleClickRequest: RequestType { return .data(data) } } - -struct WebDriverElementOrigin: Encodable { - let element: String - - enum CodingKeys: String, CodingKey { - case element = "element-6066-11e4-a52e-4f735466cecf" - } -} - -struct PointerAction: Encodable { - let type: String - let origin: WebDriverElementOrigin? - let x: Int? - let y: Int? - let button: Int? - let duration: Int? - - init( - type: String, - origin: WebDriverElementOrigin? = nil, - x: Int? = nil, - y: Int? = nil, - button: Int? = nil, - duration: Int? = nil - ) { - self.type = type - self.origin = origin - self.x = x - self.y = y - self.button = button - self.duration = duration - } -} - -struct PointerSource: Encodable { - let type: String - let id: String - let parameters: Parameters - let actions: [PointerAction] - - struct Parameters: Encodable { - let pointerType: String - } -} - -struct ActionsPayload: Encodable { - let actions: [PointerSource] -} diff --git a/Sources/SwiftWebDriver/API/Request/Elements/PostElementDragToAnotherRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/PostElementDragToAnotherRequest.swift new file mode 100644 index 0000000..be13e7a --- /dev/null +++ b/Sources/SwiftWebDriver/API/Request/Elements/PostElementDragToAnotherRequest.swift @@ -0,0 +1,62 @@ +// PostElementDragToAnotherRequest.swift +// Copyright (c) 2025 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +import AnyCodable +import AsyncHTTPClient +import Foundation +import NIO +import NIOHTTP1 + +internal struct PostElementDragToAnotherRequest: RequestType { + typealias Response = PostElementClickResponse + + var baseURL: URL + + var sessionId: String + + var elementId: String + + var toElementId: String + + var path: String { + "session/\(sessionId)/actions" + } + + var method: HTTPMethod = .POST + + var headers: HTTPHeaders = [:] + + var body: HTTPClient.Body? { + let origin = WebDriverElementOrigin(element: elementId) + let dragToOrigin = WebDriverElementOrigin(element: toElementId) + + let pointerActions = [ + PointerAction(type: "pointerMove", origin: origin, x: 0, y: 0), + PointerAction(type: "pointerDown", button: 0), + PointerAction(type: "pause", duration: 100), + PointerAction(type: "pointerMove", origin: dragToOrigin, x: 0, y: 0), + PointerAction(type: "pointerUp", button: 0) + ] + + let pointerSource = PointerSource( + type: "pointer", + id: "mouse", + parameters: .init(pointerType: "mouse"), + actions: pointerActions + ) + + let payload = ActionsPayload(actions: [pointerSource]) + + let encoder = JSONEncoder() + encoder.outputFormatting = .prettyPrinted + let data = try? encoder.encode(payload) + + guard let data else { + return nil + } + + return .data(data) + } +} diff --git a/Sources/SwiftWebDriver/Element/Element.swift b/Sources/SwiftWebDriver/Element/Element.swift index 1a5b25e..7a48559 100644 --- a/Sources/SwiftWebDriver/Element/Element.swift +++ b/Sources/SwiftWebDriver/Element/Element.swift @@ -17,6 +17,7 @@ public protocol ElementCommandProtocol: FindElementProtocol { func name() async throws -> String func click() async throws -> String? func doubleClick() async throws -> String? + func drag(to: Element) async throws -> String? func clear() async throws -> String? func attribute(name: String) async throws -> String func send(value: String) async throws -> String? @@ -85,6 +86,19 @@ public struct Element: ElementCommandProtocol, Sendable { return response.value } + @discardableResult + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func drag(to: Element) async throws -> String? { + let request = PostElementDragToAnotherRequest( + baseURL: baseURL, + sessionId: sessionId, + elementId: elementId, + toElementId: to.elementId + ) + let response = try await APIClient.shared.request(request) + return response.value + } + @discardableResult @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) public func clear() async throws -> String? { From 14400ada59dfee6cc5f5f77f9138ed63a299c6ba Mon Sep 17 00:00:00 2001 From: William Date: Thu, 14 Aug 2025 14:03:53 -0600 Subject: [PATCH 2/5] feat(Element,ChromeDriver): implemented rect, drag and drop on both element and driver methods Integration test for `Element.dragAndDrop()` implemented and passed as expected. `dragAndDrop()` webdriver method is a dynamic method that can either use javascript when element is draggable to drag element and fire off javascript event listeners, or use `Element.dragAndDrop()` when element is not draggable to use webdriver actions API instead. --- .../Elements/GetElementRectRequest.swift | 22 +++++ ...ft => PostElementDragAndDropRequest.swift} | 17 +++- .../Elements/GetElementRectResponse.swift | 10 +++ Sources/SwiftWebDriver/Element/Element.swift | 22 ++++- .../SwiftWebDriver/Element/ElementRect.swift | 11 +++ Sources/SwiftWebDriver/WebDriver.swift | 5 ++ .../WebDrivers/Chrome/ChromeDriver.swift | 4 + .../ChromeDriverElementDragAndDropper.swift | 64 ++++++++++++++ .../SwiftWebDriver/WebDrivers/Driver.swift | 2 + TestAssets/dragBox.html | 83 +++++++++++++++++++ TestAssets/dragTarget.html | 60 ++++++++++++++ ...eDriverElementHandleIntegrationTests.swift | 14 ++++ 12 files changed, 307 insertions(+), 7 deletions(-) create mode 100644 Sources/SwiftWebDriver/API/Request/Elements/GetElementRectRequest.swift rename Sources/SwiftWebDriver/API/Request/Elements/{PostElementDragToAnotherRequest.swift => PostElementDragAndDropRequest.swift} (72%) create mode 100644 Sources/SwiftWebDriver/API/Response/Elements/GetElementRectResponse.swift create mode 100644 Sources/SwiftWebDriver/Element/ElementRect.swift create mode 100644 Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeDriverElementDragAndDropper.swift create mode 100644 TestAssets/dragBox.html create mode 100644 TestAssets/dragTarget.html diff --git a/Sources/SwiftWebDriver/API/Request/Elements/GetElementRectRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/GetElementRectRequest.swift new file mode 100644 index 0000000..53553cb --- /dev/null +++ b/Sources/SwiftWebDriver/API/Request/Elements/GetElementRectRequest.swift @@ -0,0 +1,22 @@ +// GetElementRectRequest.swift +// Copyright (c) 2025 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +import AsyncHTTPClient +import Foundation +import NIO +import NIOHTTP1 + +internal struct GetElementRectRequest: RequestType { + typealias Response = GetElementRectResponse + + var baseURL: URL + var sessionId: String + var elementId: String + + var path: String { "session/\(sessionId)/element/\(elementId)/rect" } + var method: HTTPMethod = .GET + var headers: HTTPHeaders = [:] + var body: HTTPClient.Body? { nil } +} diff --git a/Sources/SwiftWebDriver/API/Request/Elements/PostElementDragToAnotherRequest.swift b/Sources/SwiftWebDriver/API/Request/Elements/PostElementDragAndDropRequest.swift similarity index 72% rename from Sources/SwiftWebDriver/API/Request/Elements/PostElementDragToAnotherRequest.swift rename to Sources/SwiftWebDriver/API/Request/Elements/PostElementDragAndDropRequest.swift index be13e7a..2fb28fa 100644 --- a/Sources/SwiftWebDriver/API/Request/Elements/PostElementDragToAnotherRequest.swift +++ b/Sources/SwiftWebDriver/API/Request/Elements/PostElementDragAndDropRequest.swift @@ -1,4 +1,4 @@ -// PostElementDragToAnotherRequest.swift +// PostElementDragAndDropRequest.swift // Copyright (c) 2025 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. @@ -9,7 +9,7 @@ import Foundation import NIO import NIOHTTP1 -internal struct PostElementDragToAnotherRequest: RequestType { +internal struct PostElementDragAndDropRequest: RequestType { typealias Response = PostElementClickResponse var baseURL: URL @@ -20,6 +20,10 @@ internal struct PostElementDragToAnotherRequest: RequestType { var toElementId: String + var elementRect: ElementRect + + var targetElementRect: ElementRect + var path: String { "session/\(sessionId)/actions" } @@ -32,11 +36,18 @@ internal struct PostElementDragToAnotherRequest: RequestType { let origin = WebDriverElementOrigin(element: elementId) let dragToOrigin = WebDriverElementOrigin(element: toElementId) + // let sourceCenterX = Int(elementRect.width / 2) + // let sourceCenterY = Int(elementRect.height / 2) + // + let targetCenterX = Int(targetElementRect.width / 2) + let targetCenterY = Int(targetElementRect.height / 2) + let pointerActions = [ + // PointerAction(type: "pointerMove", origin: origin, x: sourceCenterX, y: sourceCenterY), PointerAction(type: "pointerMove", origin: origin, x: 0, y: 0), PointerAction(type: "pointerDown", button: 0), PointerAction(type: "pause", duration: 100), - PointerAction(type: "pointerMove", origin: dragToOrigin, x: 0, y: 0), + PointerAction(type: "pointerMove", origin: dragToOrigin, x: targetCenterX, y: targetCenterY), PointerAction(type: "pointerUp", button: 0) ] diff --git a/Sources/SwiftWebDriver/API/Response/Elements/GetElementRectResponse.swift b/Sources/SwiftWebDriver/API/Response/Elements/GetElementRectResponse.swift new file mode 100644 index 0000000..13e34e2 --- /dev/null +++ b/Sources/SwiftWebDriver/API/Response/Elements/GetElementRectResponse.swift @@ -0,0 +1,10 @@ +// GetElementRectResponse.swift +// Copyright (c) 2025 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +import Foundation + +public struct GetElementRectResponse: ResponseType { + public let value: ElementRect +} diff --git a/Sources/SwiftWebDriver/Element/Element.swift b/Sources/SwiftWebDriver/Element/Element.swift index 7a48559..a6fcb0c 100644 --- a/Sources/SwiftWebDriver/Element/Element.swift +++ b/Sources/SwiftWebDriver/Element/Element.swift @@ -17,11 +17,12 @@ public protocol ElementCommandProtocol: FindElementProtocol { func name() async throws -> String func click() async throws -> String? func doubleClick() async throws -> String? - func drag(to: Element) async throws -> String? + func dragAndDrop(to: Element) async throws -> String? func clear() async throws -> String? func attribute(name: String) async throws -> String func send(value: String) async throws -> String? func screenshot() async throws -> String + func rect() async throws -> ElementRect } public struct Element: ElementCommandProtocol, Sendable { @@ -88,12 +89,25 @@ public struct Element: ElementCommandProtocol, Sendable { @discardableResult @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) - public func drag(to: Element) async throws -> String? { - let request = PostElementDragToAnotherRequest( + public func dragAndDrop(to: Element) async throws -> String? { + let request = try await PostElementDragAndDropRequest( baseURL: baseURL, sessionId: sessionId, elementId: elementId, - toElementId: to.elementId + toElementId: to.elementId, + elementRect: rect(), + targetElementRect: to.rect() + ) + let response = try await APIClient.shared.request(request) + return response.value + } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func rect() async throws -> ElementRect { + let request = GetElementRectRequest( + baseURL: baseURL, + sessionId: sessionId, + elementId: elementId ) let response = try await APIClient.shared.request(request) return response.value diff --git a/Sources/SwiftWebDriver/Element/ElementRect.swift b/Sources/SwiftWebDriver/Element/ElementRect.swift new file mode 100644 index 0000000..f5fd9da --- /dev/null +++ b/Sources/SwiftWebDriver/Element/ElementRect.swift @@ -0,0 +1,11 @@ +// ElementRect.swift +// Copyright (c) 2025 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +public struct ElementRect: Codable, Sendable { + public let x: Double + public let y: Double + public let width: Double + public let height: Double +} diff --git a/Sources/SwiftWebDriver/WebDriver.swift b/Sources/SwiftWebDriver/WebDriver.swift index 6b223b6..ed40856 100644 --- a/Sources/SwiftWebDriver/WebDriver.swift +++ b/Sources/SwiftWebDriver/WebDriver.swift @@ -143,4 +143,9 @@ public class WebDriver { public func setProperty(element: Element, propertyName: String, newValue: String) async throws { try await driver.setProperty(element: element, propertyName: propertyName, newValue: newValue) } + + @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func dragAndDrop(from source: Element, to target: Element) async throws { + try await driver.dragAndDrop(from: source, to: target) + } } diff --git a/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeDriver.swift b/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeDriver.swift index c77c619..1573c8e 100644 --- a/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeDriver.swift +++ b/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeDriver.swift @@ -332,6 +332,10 @@ public class ChromeDriver: Driver { try await execute(script, args: args, type: .sync) } + public func dragAndDrop(from source: Element, to target: Element) async throws { + try await ChromeDriverElementDragAndDropper(driver: self, from: source, to: target).dragAndDrop() + } + deinit { let url = url let sessionId = sessionId diff --git a/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeDriverElementDragAndDropper.swift b/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeDriverElementDragAndDropper.swift new file mode 100644 index 0000000..2721772 --- /dev/null +++ b/Sources/SwiftWebDriver/WebDrivers/Chrome/ChromeDriverElementDragAndDropper.swift @@ -0,0 +1,64 @@ +// ChromeDriverElementDragAndDropper.swift +// Copyright (c) 2025 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +internal struct ChromeDriverElementDragAndDropper { + let source: Element + let target: Element + let driver: ChromeDriver + + public init(driver: ChromeDriver, from source: Element, to target: Element) { + self.driver = driver + self.source = source + self.target = target + } + + public func dragAndDrop() async throws { + if try await isHTML5Draggable() { + try await simulateHTML5DragAndDrop() + } else { + try await source.dragAndDrop(to: target) + } + } + + private func simulateHTML5DragAndDrop() async throws { + let script = """ + function simulateHTML5DragAndDrop(source, target) { + const dataTransfer = new DataTransfer(); + + const dragStartEvent = new DragEvent('dragstart', { + bubbles: true, + cancelable: true, + dataTransfer: dataTransfer + }); + source.dispatchEvent(dragStartEvent); + + const dragOverEvent = new DragEvent('dragover', { + bubbles: true, + cancelable: true, + dataTransfer: dataTransfer + }); + target.dispatchEvent(dragOverEvent); + + const dropEvent = new DragEvent('drop', { + bubbles: true, + cancelable: true, + dataTransfer: dataTransfer + }); + target.dispatchEvent(dropEvent); + } + simulateHTML5DragAndDrop(arguments[0], arguments[1]); + """ + let arguments: [AnyEncodable] = [ + 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) + } + + private func isHTML5Draggable() async throws -> Bool { + let draggableValue = try await source.attribute(name: "draggable") + return draggableValue.lowercased() == "true" + } +} diff --git a/Sources/SwiftWebDriver/WebDrivers/Driver.swift b/Sources/SwiftWebDriver/WebDrivers/Driver.swift index 57088b5..47414ce 100644 --- a/Sources/SwiftWebDriver/WebDrivers/Driver.swift +++ b/Sources/SwiftWebDriver/WebDrivers/Driver.swift @@ -52,4 +52,6 @@ public protocol Driver: FindElementProtocol { func getProperty(element: Element, propertyName: String) async throws -> PostExecuteResponse func setProperty(element: Element, propertyName: String, newValue: String) async throws + + func dragAndDrop(from source: Element, to target: Element) async throws } diff --git a/TestAssets/dragBox.html b/TestAssets/dragBox.html new file mode 100644 index 0000000..71bd8ba --- /dev/null +++ b/TestAssets/dragBox.html @@ -0,0 +1,83 @@ + + + + + + Pointer Drag Test + + + + +
SOURCE
+
TARGET
+ + + + + diff --git a/TestAssets/dragTarget.html b/TestAssets/dragTarget.html new file mode 100644 index 0000000..732c424 --- /dev/null +++ b/TestAssets/dragTarget.html @@ -0,0 +1,60 @@ + + + + + + Drag and Drop Test + + + + +
SOURCE
+
TARGET
+ + + + + diff --git a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverElementHandleIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverElementHandleIntegrationTests.swift index 4633017..271de4e 100644 --- a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverElementHandleIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverElementHandleIntegrationTests.swift @@ -30,6 +30,20 @@ internal class ChromeDriverElementHandleIntegrationTests: ChromeDriverTest { #expect(test == "ii") } + @Test("Drag Element To Another") + 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") func getAttribute() async throws { page = "elementHandleTestPage.html" From 69c734eaa253d09ec7b6822440db723c8e23f6fe Mon Sep 17 00:00:00 2001 From: William Date: Thu, 14 Aug 2025 14:07:33 -0600 Subject: [PATCH 3/5] chore: update submodules --- .dotfiles | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.dotfiles b/.dotfiles index 3de6f4f..ec9bc76 160000 --- a/.dotfiles +++ b/.dotfiles @@ -1 +1 @@ -Subproject commit 3de6f4f94f7c3e2c2a7b43f83bc1da3748678f7d +Subproject commit ec9bc762fe9f4a14eee111d5ae65f02dab540b0b From bbdfce76b90b06c97ea0cf5b6666f5df6c69f24c Mon Sep 17 00:00:00 2001 From: William Date: Thu, 14 Aug 2025 14:13:14 -0600 Subject: [PATCH 4/5] test(ChromeDriverElementHandleIntegrationTests): implemented rect integation test, passed as expected --- TestAssets/elementHandleTestPage.html | 7 +++++++ ...romeDriverElementHandleIntegrationTests.swift | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/TestAssets/elementHandleTestPage.html b/TestAssets/elementHandleTestPage.html index 981d2b9..8208f0e 100644 --- a/TestAssets/elementHandleTestPage.html +++ b/TestAssets/elementHandleTestPage.html @@ -28,10 +28,17 @@ element.remove() }, 2000) + +
diff --git a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverElementHandleIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverElementHandleIntegrationTests.swift index 271de4e..c5fb9d1 100644 --- a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverElementHandleIntegrationTests.swift +++ b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverElementHandleIntegrationTests.swift @@ -55,6 +55,22 @@ internal class ChromeDriverElementHandleIntegrationTests: ChromeDriverTest { #expect(attribute == "expect attribute") } + @Test("Get Element Rect") + 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.x > 5) + #expect(rect.y > 5) + #expect(rect.width == 100) + } + @Test("Clear Element") func clearElement() async throws { page = "elementHandleTestPage.html" From a520c9bd7009a3d7b302d0a010fcef689d429cf6 Mon Sep 17 00:00:00 2001 From: William Date: Thu, 14 Aug 2025 14:18:45 -0600 Subject: [PATCH 5/5] test(ChromeDriverDragAndDropIntegrationTests): implemented working integration test for drag and drop element to another element method --- ...omeDriverDragAndDropIntegrationTests.swift | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverDragAndDropIntegrationTests.swift diff --git a/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverDragAndDropIntegrationTests.swift b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverDragAndDropIntegrationTests.swift new file mode 100644 index 0000000..1ffe790 --- /dev/null +++ b/Tests/SwiftWebDriverIntegrationTests/ChromeDriver/Element/ChromeDriverDragAndDropIntegrationTests.swift @@ -0,0 +1,47 @@ +// 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 { + @Test("Drag Element To Another") + func dragAndDropElementToAnother() async throws { + page = "dragTarget.html" + 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!") + } + + @Test("Set Property") + func setProperty() 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) + guard + 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") + return + } + + #expect(newPropertyValue == elementInnerTextValue) + } + + deinit {} +}