From 2349ee5b7034dd7a175dfee56fd1f9027ee39a15 Mon Sep 17 00:00:00 2001 From: William Date: Wed, 1 Jul 2026 20:24:36 +0200 Subject: [PATCH 1/2] feat(Helium): create press method, with integration tests, working as expected --- .swift-version | 1 + Package.resolved | 227 +++++++++++++----- Package.swift | 2 +- Sources/HeliumSwift/Helium.swift | 38 ++- Sources/HeliumSwift/HeliumElement.swift | 2 +- .../DriverIntegrationTest.swift | 17 +- .../PressMethodIntegrationTests.swift | 57 +++++ .../WriteMethodIntegrationTests.swift | 29 +-- 8 files changed, 283 insertions(+), 90 deletions(-) create mode 100644 .swift-version create mode 100644 Tests/HeliumSwiftTests/PressMethodIntegrationTests.swift diff --git a/.swift-version b/.swift-version new file mode 100644 index 0000000..91e4a9f --- /dev/null +++ b/.swift-version @@ -0,0 +1 @@ +6.3.2 diff --git a/Package.resolved b/Package.resolved index 0224674..e9cb03b 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,13 +1,13 @@ { - "originHash" : "300cedf1b20bbc960adb5d30e3004cc5c1829ce5c00aea92ee5682db32815adc", + "originHash" : "ac4a95d78ae4ea726da4f3c6dc9282058d6eb5dad9d74514d8224b6d1833a0cf", "pins" : [ { "identity" : "async-http-client", "kind" : "remoteSourceControl", "location" : "https://github.com/swift-server/async-http-client.git", "state" : { - "revision" : "7dc119c7edf3c23f52638faadb89182861dee853", - "version" : "1.28.0" + "revision" : "7744c2a035c68ec14726c709f031835e3e30bde1", + "version" : "1.34.0" } }, { @@ -15,8 +15,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/async-kit.git", "state" : { - "revision" : "6f3615ccf2ac3c2ae0c8087d527546e9544a43dd", - "version" : "1.21.0" + "revision" : "6bbb83cbf9d886623a967a965c8fb1b73e6566f9", + "version" : "1.22.0" } }, { @@ -25,7 +25,7 @@ "location" : "https://github.com/GetAutomaApp/AutomaUtilities", "state" : { "branch" : "main", - "revision" : "60e4a28b9f54ab9556e5cbbb176a5bcf41337161" + "revision" : "7d4f72d98487b15397b5dd7d7140b4c9e76bf8e9" } }, { @@ -33,8 +33,44 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/console-kit.git", "state" : { - "revision" : "742f624a998cba2a9e653d9b1e91ad3f3a5dff6b", - "version" : "4.15.2" + "revision" : "32ad16dfc7677b927b225595ed18f3debb32f577", + "version" : "4.16.0" + } + }, + { + "identity" : "flyingfox", + "kind" : "remoteSourceControl", + "location" : "https://github.com/swhitty/FlyingFox.git", + "state" : { + "revision" : "de38230104cf63ef4843cb569ba11c13f8165685", + "version" : "0.26.2" + } + }, + { + "identity" : "grpc-swift-2", + "kind" : "remoteSourceControl", + "location" : "https://github.com/grpc/grpc-swift-2.git", + "state" : { + "revision" : "28cdd63ef88583ddc67d7bb179eab46fab465ce9", + "version" : "2.4.2" + } + }, + { + "identity" : "grpc-swift-nio-transport", + "kind" : "remoteSourceControl", + "location" : "https://github.com/grpc/grpc-swift-nio-transport.git", + "state" : { + "revision" : "2ca31f06658ed288a2560e23ad649acbb3d6b3a3", + "version" : "2.9.0" + } + }, + { + "identity" : "grpc-swift-protobuf", + "kind" : "remoteSourceControl", + "location" : "https://github.com/grpc/grpc-swift-protobuf.git", + "state" : { + "revision" : "176c5a434fd76f6f479848d1a8f7d44967534168", + "version" : "2.4.1" } }, { @@ -46,13 +82,40 @@ "version" : "4.7.1" } }, + { + "identity" : "opentelemetry-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/getautomaapp/opentelemetry-swift.git", + "state" : { + "branch" : "main", + "revision" : "5e2bf0a6b298fb25ad54564055c9e32d13fece62" + } + }, + { + "identity" : "opentelemetry-swift-core", + "kind" : "remoteSourceControl", + "location" : "https://github.com/open-telemetry/opentelemetry-swift-core.git", + "state" : { + "revision" : "240c8d5e36c3c7b774ed961325369f0b1f2c965f", + "version" : "2.3.0" + } + }, + { + "identity" : "opentracing-objc", + "kind" : "remoteSourceControl", + "location" : "https://github.com/undefinedlabs/opentracing-objc", + "state" : { + "revision" : "18c1a35ca966236cee0c5a714a51a73ff33384c1", + "version" : "0.5.2" + } + }, { "identity" : "routing-kit", "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/routing-kit.git", "state" : { - "revision" : "93f7222c8e195cbad39fafb5a0e4cc85a8def7ea", - "version" : "4.9.2" + "revision" : "1a10ccea61e4248effd23b6e814999ce7bdf0ee0", + "version" : "4.9.3" } }, { @@ -78,8 +141,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-asn1.git", "state" : { - "revision" : "f70225981241859eb4aa1a18a75531d26637c8cc", - "version" : "1.4.0" + "revision" : "a9a5efd40eaf558a2bcd48d64b1d1646be686008", + "version" : "1.7.1" } }, { @@ -87,8 +150,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-async-algorithms.git", "state" : { - "revision" : "042e1c4d9d19748c9c228f8d4ebc97bb1e339b0b", - "version" : "1.0.4" + "revision" : "3da39bbc4e687d4192af7c9cf4eab805745a0b9c", + "version" : "1.1.5" } }, { @@ -96,8 +159,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-atomics.git", "state" : { - "revision" : "b601256eab081c0f92f059e12818ac1d4f178ff7", - "version" : "1.3.0" + "revision" : "0442cb5a3f98ab802acb777929fdb446bda11a34", + "version" : "1.3.1" } }, { @@ -105,8 +168,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-certificates.git", "state" : { - "revision" : "20c451f1ad8e344e61ddbb34ef196653d4b73ea6", - "version" : "1.13.0" + "revision" : "eaa10d47d19919979dd8df22ff4fd6349b1108d4", + "version" : "1.19.2" } }, { @@ -114,8 +177,17 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-collections.git", "state" : { - "revision" : "8c0c0a8b49e080e54e5e328cc552821ff07cd341", - "version" : "1.2.1" + "revision" : "a0cb0954ecb21e4e31b0070e6ed5674e8556685a", + "version" : "1.6.0" + } + }, + { + "identity" : "swift-configuration", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-configuration.git", + "state" : { + "revision" : "be76c4ad929eb6c4bcaf3351799f2adf9e6848a9", + "version" : "1.2.0" } }, { @@ -123,8 +195,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-crypto.git", "state" : { - "revision" : "d1c6b70f7c5f19fb0b8750cb8dcdf2ea6e2d8c34", - "version" : "3.15.0" + "revision" : "1b6b2e274e85105bfa155183145a1dcfd63331f1", + "version" : "4.5.0" } }, { @@ -132,8 +204,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-distributed-tracing.git", "state" : { - "revision" : "149fa4cc7d54c513288108142e7af9ceaf8def8f", - "version" : "1.2.2" + "revision" : "dc4030184203ffafbb2ec614352487235d747fe0", + "version" : "1.4.1" } }, { @@ -141,8 +213,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-http-structured-headers.git", "state" : { - "revision" : "1625f271afb04375bf48737a5572613248d0e7a0", - "version" : "1.4.0" + "revision" : "933538faa42c432d385f02e07df0ace7c5ecfc47", + "version" : "1.7.0" } }, { @@ -150,8 +222,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-http-types.git", "state" : { - "revision" : "a0a57e949a8903563aba4615869310c0ebf14c03", - "version" : "1.4.0" + "revision" : "db774a277f60063a32d854f2980299caf06da041", + "version" : "1.6.0" } }, { @@ -159,8 +231,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-log.git", "state" : { - "revision" : "ce592ae52f982c847a4efc0dd881cc9eb32d29f2", - "version" : "1.6.4" + "revision" : "a878e7f8f46cfc0e1125e565b5c08e7d5272dc9a", + "version" : "1.14.0" } }, { @@ -168,8 +240,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-metrics.git", "state" : { - "revision" : "4c83e1cdf4ba538ef6e43a9bbd0bcc33a0ca46e3", - "version" : "2.7.0" + "revision" : "087e8074afa97040c3b870c8664fe5482fb87cc4", + "version" : "2.11.0" } }, { @@ -177,8 +249,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-nio.git", "state" : { - "revision" : "1c30f0f2053b654e3d1302492124aa6d242cdba7", - "version" : "2.86.0" + "revision" : "cd3e1152083706d77b223fb29110e590efcc70c0", + "version" : "2.101.2" } }, { @@ -186,8 +258,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-nio-extras.git", "state" : { - "revision" : "a55c3dd3a81d035af8a20ce5718889c0dcab073d", - "version" : "1.29.0" + "revision" : "d2eeec0339074034f11a040a74aa2a341a2c4506", + "version" : "1.34.1" } }, { @@ -195,8 +267,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-nio-http2.git", "state" : { - "revision" : "5e9e99ec96c53bc2c18ddd10c1e25a3cd97c55e5", - "version" : "1.38.0" + "revision" : "61d1b44f6e4e118792be1cff88ee2bc0267c6f9a", + "version" : "1.44.0" } }, { @@ -204,8 +276,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-nio-ssl.git", "state" : { - "revision" : "737e550e607d82bf15bdfddf158ec61652ce836f", - "version" : "2.34.0" + "revision" : "407d82d5b6cc00e1c3fb83a81b1539b70c788c5e", + "version" : "2.37.1" } }, { @@ -213,8 +285,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-nio-transport-services.git", "state" : { - "revision" : "e645014baea2ec1c2db564410c51a656cf47c923", - "version" : "1.25.1" + "revision" : "67787bb645a5e67d2edcdfbe48a216cc549222d5", + "version" : "1.28.0" } }, { @@ -222,8 +294,35 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-numerics.git", "state" : { - "revision" : "bbadd4b853a33fd78c4ae977d17bb2af15eb3f2a", - "version" : "1.1.0" + "revision" : "0c0290ff6b24942dadb83a929ffaaa1481df04a2", + "version" : "1.1.1" + } + }, + { + "identity" : "swift-otel", + "kind" : "remoteSourceControl", + "location" : "https://github.com/swift-otel/swift-otel.git", + "state" : { + "revision" : "599309ecc03d27f3331bb096c5bdcb4839b3d187", + "version" : "1.4.0" + } + }, + { + "identity" : "swift-prometheus", + "kind" : "remoteSourceControl", + "location" : "https://github.com/swift-server/swift-prometheus.git", + "state" : { + "revision" : "3b94f0dc975d0ad36ae196484b6ab6342c14aa97", + "version" : "2.3.0" + } + }, + { + "identity" : "swift-protobuf", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-protobuf.git", + "state" : { + "revision" : "55d7a1cc5666b85c13464aea1c4b4a90feccb4c8", + "version" : "1.38.1" } }, { @@ -231,8 +330,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-service-context.git", "state" : { - "revision" : "1983448fefc717a2bc2ebde5490fe99873c5b8a6", - "version" : "1.2.1" + "revision" : "d0997351b0c7779017f88e7a93bc30a1878d7f29", + "version" : "1.3.0" } }, { @@ -240,8 +339,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/swift-server/swift-service-lifecycle.git", "state" : { - "revision" : "e7187309187695115033536e8fc9b2eb87fd956d", - "version" : "2.8.0" + "revision" : "9829955b385e5bb88128b73f1b8389e9b9c3191a", + "version" : "2.11.0" } }, { @@ -249,8 +348,17 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-system.git", "state" : { - "revision" : "890830fff1a577dc83134890c7984020c5f6b43b", - "version" : "1.6.2" + "revision" : "7502b711c92a17741fa625d722b0ccbd595d8ed1", + "version" : "1.7.2" + } + }, + { + "identity" : "swift-w3c-trace-context", + "kind" : "remoteSourceControl", + "location" : "https://github.com/swift-otel/swift-w3c-trace-context.git", + "state" : { + "revision" : "5da9b143ba6046734de3fa51dafea28290174e4e", + "version" : "1.0.0-beta.5" } }, { @@ -259,7 +367,16 @@ "location" : "https://github.com/GetAutomaApp/SwiftWebDriver.git", "state" : { "branch" : "master", - "revision" : "2b8041007c52f04c4a1753c67eb6abc13d11dc4f" + "revision" : "4a2ec41c64f3258bd08bcef869b4e172d9482392" + } + }, + { + "identity" : "thrift-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/undefinedlabs/Thrift-Swift", + "state" : { + "revision" : "18ff09e6b30e589ed38f90a1af23e193b8ecef8e", + "version" : "1.1.2" } }, { @@ -267,8 +384,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/vapor.git", "state" : { - "revision" : "636fbe688e001dc1f8d6f6026a52bcc396025d19", - "version" : "4.116.0" + "revision" : "cfd8f434843ac7850e2d97f46c1aa5ddb906cf1c", + "version" : "4.121.4" } }, { @@ -276,8 +393,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/vapor/websocket-kit.git", "state" : { - "revision" : "8666c92dbbb3c8eefc8008c9c8dcf50bfd302167", - "version" : "2.16.1" + "revision" : "90bbbdab3ede12c803cfbe91646f291c092517a3", + "version" : "2.16.2" } } ], diff --git a/Package.swift b/Package.swift index 915fa7a..0c35124 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 6.1 +// swift-tools-version: 6.3.2 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription diff --git a/Sources/HeliumSwift/Helium.swift b/Sources/HeliumSwift/Helium.swift index 7cf8e05..e189971 100644 --- a/Sources/HeliumSwift/Helium.swift +++ b/Sources/HeliumSwift/Helium.swift @@ -1,5 +1,5 @@ // Helium.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. @@ -17,7 +17,7 @@ public enum Helium { public static func startChrome(payload: ChromeStarterPayload? = nil) async throws -> WebDriver { - return try await ChromeStarter(payload: payload).startChrome() + try await ChromeStarter(payload: payload).startChrome() } /// Send text to a `AnyElement` @@ -26,7 +26,7 @@ public enum Helium { /// - element: `E`, find an element from the driver /// /// - Throws: An error if there is a problem sending keys to the element - public static func write(text: String, element: E) async throws { + public static func write(text: String, element: some AnyElement) async throws { try await ElementWriter(text: text, element: element.underlyingElement).write() } @@ -36,7 +36,7 @@ public enum Helium { /// - driver: `WebDriver`, the driver to send the keys to /// /// - Throws: An error if there is a problem sending keys to the currently active element - public static func write(text: String, driver: WebDriver) async throws { + public static func write(text: String, driver: WebDriver) async throws { try await write(text: text, element: driver.getActiveElement()) } @@ -46,7 +46,7 @@ public enum Helium { /// - urlString: `String`, The URL you want to navigate to you wan /// /// - Throws: `Helium.invalidURL` when URL format is invalid or an error when driver navigation failed - public static func goTo(driver: WebDriver, urlString: String) async throws { + public static func goTo(driver: WebDriver, urlString: String) async throws { let url = try URL.fromString(payload: .init(string: urlString, asHttp: true)) try await driver.navigateTo(url: url) } @@ -54,7 +54,7 @@ public enum Helium { /// Click on a `AnyElement` /// - Parameter element: `E`, the element to click on /// - Throws: An error if there is a problem clicking on the element - public static func click(element: E) async throws { + public static func click(element: some AnyElement) async throws { try await ElementClicker(element: element.underlyingElement).click() } @@ -62,7 +62,7 @@ public enum Helium { /// initializers /// - Parameter element: `E`, the element to click on /// - Throws: An error if there is a problem clicking on the element - public static func doubleClick(element: E) async throws { + public static func doubleClick(element: some AnyElement) async throws { try await element.underlyingElement.doubleClick() } @@ -73,11 +73,27 @@ public enum Helium { /// - targetElement: `E2`, the target element you want to drag the source element to /// /// - Throws: An error if there is a problem dragging the source element to the target element - public static func drag>( - driver: D, - element: E1, - to targetElement: E2 + public static func drag( + driver: some WebDriver, + element: some AnyElement, + to targetElement: some AnyElement ) async throws { try await driver.dragAndDrop(from: element.underlyingElement, to: targetElement.underlyingElement) } + + public static func press( + _ keys: [ElementsTypes.SendValueActionKeyTypes?], + _ characters: String = "", + _ driver: some WebDriver, + ) async throws -> String? { + try await driver.getActiveElement().sendKeys(keys: keys, characters: characters) + } + + public static func press( + _ keys: [ElementsTypes.SendValueActionKeyTypes?], + _ characters: String = "", + _ element: some AnyElement + ) async throws -> String? { + try await element.underlyingElement.sendKeys(keys: keys, characters: characters) + } } diff --git a/Sources/HeliumSwift/HeliumElement.swift b/Sources/HeliumSwift/HeliumElement.swift index 151d3bb..4c7ff2b 100644 --- a/Sources/HeliumSwift/HeliumElement.swift +++ b/Sources/HeliumSwift/HeliumElement.swift @@ -1,5 +1,5 @@ // HeliumElement.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/Tests/HeliumSwiftTests/DriverIntegrationTest.swift b/Tests/HeliumSwiftTests/DriverIntegrationTest.swift index 3b5ee56..7982bf3 100644 --- a/Tests/HeliumSwiftTests/DriverIntegrationTest.swift +++ b/Tests/HeliumSwiftTests/DriverIntegrationTest.swift @@ -1,10 +1,12 @@ // DriverIntegrationTest.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. import Foundation +@testable import HeliumSwift import SwiftWebDriver +import Testing internal protocol DriverIntegrationTestsBase { var driver: WebDriver { get set } @@ -42,5 +44,18 @@ internal class DriverIntegrationTest: DriverIntegrationTestsBase { try await driver.start() } + internal func getElementValue(_ element: Element) async throws -> String { + guard + let elementValue = try await driver.getProperty(element: element, propertyName: + "value").value?.stringValue + else { + let errorMessage = "Element value could not be converted to a string" + #expect(Bool(false), .init(rawValue: errorMessage)) + throw HeliumError.unknown(message: errorMessage) + } + + return elementValue + } + deinit {} } diff --git a/Tests/HeliumSwiftTests/PressMethodIntegrationTests.swift b/Tests/HeliumSwiftTests/PressMethodIntegrationTests.swift new file mode 100644 index 0000000..f187f44 --- /dev/null +++ b/Tests/HeliumSwiftTests/PressMethodIntegrationTests.swift @@ -0,0 +1,57 @@ +// PressMethodIntegrationTests.swift +// Copyright (c) 2026 GetAutomaApp +// All source code and related assets are the property of GetAutomaApp. +// All rights reserved. + +@testable import HeliumSwift +import Testing + +@Suite("Press Method Integration Tests", .serialized) +internal class PressMethodIntegrationTests: DriverIntegrationTest { + @Test + public func `Press Chord To Active Window`() async throws { + page = "0.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let elementId = "findElementByInnerText" + + // focus on the element so that this element becomes the active element + let element = try await driver.findElement(.css(.id(elementId))) + try await element.click() + + let textToSendToActiveWindow = "randomText" + try await Helium.write(text: textToSendToActiveWindow, driver: driver) + + let elementValue = try await getElementValue(element) + #expect(elementValue == textToSendToActiveWindow) + + _ = try await Helium.press([.CONTROL], "a", driver) + _ = try await Helium.press([.BACKSPACE], "", driver) + + let afterHittingControlBackspaceElementValue = try await getElementValue(element) + #expect(afterHittingControlBackspaceElementValue == "") + } + + @Test + public func `Press Chord To SwiftWebDriver Element`() async throws { + page = "0.html" + try await driver.navigateTo(urlString: testPageURL.absoluteString) + + let elementId = "findElementByInnerText" + let element = try await driver.findElement(.css(.id(elementId))) + + let textToSendToElement = "randomText" + try await Helium.write(text: textToSendToElement, element: element) + + let elementValue = try await getElementValue(element) + #expect(elementValue == textToSendToElement) + + _ = try await Helium.press([.CONTROL], "a", element) + _ = try await Helium.press([.BACKSPACE], "", element) + + let afterHittingControlBackspaceElementValue = try await getElementValue(element) + #expect(afterHittingControlBackspaceElementValue == "") + } + + deinit {} +} diff --git a/Tests/HeliumSwiftTests/WriteMethodIntegrationTests.swift b/Tests/HeliumSwiftTests/WriteMethodIntegrationTests.swift index cde6029..17c950d 100644 --- a/Tests/HeliumSwiftTests/WriteMethodIntegrationTests.swift +++ b/Tests/HeliumSwiftTests/WriteMethodIntegrationTests.swift @@ -1,16 +1,15 @@ // WriteMethodIntegrationTests.swift -// Copyright (c) 2025 GetAutomaApp +// Copyright (c) 2026 GetAutomaApp // All source code and related assets are the property of GetAutomaApp. // All rights reserved. -import Testing - @testable import HeliumSwift +import Testing @Suite("Write Method Integration Tests", .serialized) internal class WriteMethodIntegrationTests: DriverIntegrationTest { - @Test("Write To HeliumElement") - public func writeToHeliumElement() async throws { + @Test + public func `Write To HeliumElement`() async throws { page = "0.html" try await driver.navigateTo(urlString: testPageURL.absoluteString) @@ -33,8 +32,8 @@ internal class WriteMethodIntegrationTests: DriverIntegrationTest { #expect(elementValue == textToSendToElement) } - @Test("Write To Active Window") - public func writeToActiveWindow() async throws { + @Test + public func `Write To Active Window`() async throws { page = "0.html" try await driver.navigateTo(urlString: testPageURL.absoluteString) @@ -52,8 +51,8 @@ internal class WriteMethodIntegrationTests: DriverIntegrationTest { #expect(elementValue == textToSendToActiveWindow) } - @Test("Write To SwiftWebDriver Element") - public func writeToSwiftWebDriverElement() async throws { + @Test + public func `Write To SwiftWebDriver Element`() async throws { page = "0.html" try await driver.navigateTo(urlString: testPageURL.absoluteString) @@ -68,17 +67,5 @@ internal class WriteMethodIntegrationTests: DriverIntegrationTest { #expect(elementValue == textToSendToElement) } - private func getElementValue(_ element: Element) async throws -> String { - guard - let elementValue = try await driver.getProperty(element: element, propertyName: "value").value?.stringValue - else { - let errorMessage = "Element value could not be converted to a string" - #expect(Bool(false), .init(rawValue: errorMessage)) - throw HeliumError.unknown(message: errorMessage) - } - - return elementValue - } - deinit {} } From fa70da88713a60bdb2789a6780d29c77318f7a80 Mon Sep 17 00:00:00 2001 From: William Date: Wed, 1 Jul 2026 20:37:19 +0200 Subject: [PATCH 2/2] docs(Helium): fixed methods doc strings and added docs strings for new press methods --- Sources/HeliumSwift/Helium.swift | 40 +++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/Sources/HeliumSwift/Helium.swift b/Sources/HeliumSwift/Helium.swift index e189971..ba63ee5 100644 --- a/Sources/HeliumSwift/Helium.swift +++ b/Sources/HeliumSwift/Helium.swift @@ -22,8 +22,8 @@ public enum Helium { /// Send text to a `AnyElement` /// - Parameters: - /// - text: Text to send to element - /// - element: `E`, find an element from the driver + /// - text: `String`, text to send to element + /// - element: ``, find an element from the driver /// /// - Throws: An error if there is a problem sending keys to the element public static func write(text: String, element: some AnyElement) async throws { @@ -33,7 +33,7 @@ public enum Helium { /// Send text to the active element in the current window of the passed in driver /// - Parameters: /// - text: `String`, text to send to element - /// - driver: `WebDriver`, the driver to send the keys to + /// - driver: ``, the driver to send the keys to /// /// - Throws: An error if there is a problem sending keys to the currently active element public static func write(text: String, driver: WebDriver) async throws { @@ -42,17 +42,17 @@ public enum Helium { /// Opens the specified URL in the passed in web driver window /// - Parameters: - /// - driver: `WebDriver`, The driver you want the current window to navigate to the passed in URL + /// - driver: `WebDriver`, The driver you want the current window to navigate to the passed in URL /// - urlString: `String`, The URL you want to navigate to you wan /// /// - Throws: `Helium.invalidURL` when URL format is invalid or an error when driver navigation failed - public static func goTo(driver: WebDriver, urlString: String) async throws { + public static func goTo(driver: WebDriver, urlString: String) async throws { let url = try URL.fromString(payload: .init(string: urlString, asHttp: true)) try await driver.navigateTo(url: url) } /// Click on a `AnyElement` - /// - Parameter element: `E`, the element to click on + /// - Parameter element: `some AnyElement`, the element to click on /// - Throws: An error if there is a problem clicking on the element public static func click(element: some AnyElement) async throws { try await ElementClicker(element: element.underlyingElement).click() @@ -60,7 +60,7 @@ public enum Helium { /// Double click on a `AnyElement` /// initializers - /// - Parameter element: `E`, the element to click on + /// - Parameter element: `some AnyElement`, the element to click on /// - Throws: An error if there is a problem clicking on the element public static func doubleClick(element: some AnyElement) async throws { try await element.underlyingElement.doubleClick() @@ -68,19 +68,28 @@ public enum Helium { /// Drag and drop an element to another element /// - Parameters: - /// - driver: `D`, The driver you want to use to perform drag and drop implementation - /// - element: `E1`, the source element you want to drag - /// - targetElement: `E2`, the target element you want to drag the source element to + /// - driver: `WebDriver`, The driver you want to use to perform drag and drop implementation + /// - element: `some AnyElement`, the source element you want to drag + /// - targetElement: `some AnyElement`, the target element you want to drag the source element to /// /// - Throws: An error if there is a problem dragging the source element to the target element public static func drag( - driver: some WebDriver, + driver: WebDriver, element: some AnyElement, to targetElement: some AnyElement ) async throws { try await driver.dragAndDrop(from: element.underlyingElement, to: targetElement.underlyingElement) } + /// Press keys and characters in combination to the currently active element + /// - Parameters: + /// - keys: `[ElementTypes.SendValueActionKeyTypes?]`, the keys to chord to the active element, can be left as an + /// empty array + /// - characters: `String`, characters to send to the current active element, can be left as empty or a sequence + /// of elements provided + /// - driver: `WebDriver`, The driver to send or chord keys and characters to + /// + /// - Throws: An error if there is a problem sending or chording keys and characters to the currently active element public static func press( _ keys: [ElementsTypes.SendValueActionKeyTypes?], _ characters: String = "", @@ -89,6 +98,15 @@ public enum Helium { try await driver.getActiveElement().sendKeys(keys: keys, characters: characters) } + /// Press keys and characters in combination to a `AnyElement` + /// - Parameters: + /// - keys: `[ElementTypes.SendValueActionKeyTypes?]`, the keys to chord to the active element, can be left as an + /// empty array + /// - characters: `String`, characters to send to the current active element, can be left as empty or a sequence + /// of elements provided + /// - element: `some AnyElement`, find an element from the driver + /// + /// - Throws: An error if there is a problem sending or chording keys and characters to the currently active element public static func press( _ keys: [ElementsTypes.SendValueActionKeyTypes?], _ characters: String = "",