diff --git a/.github/workflows/gradle.yml b/.github/workflows/ci.yml similarity index 94% rename from .github/workflows/gradle.yml rename to .github/workflows/ci.yml index cd70a8203..591678f6d 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,7 @@ env: IOS_PLATFORM_VERSION: "17.5" FLUTTER_ANDROID_APP: "https://github.com/AppiumTestDistribution/appium-flutter-server/releases/latest/download/app-debug.apk" FLUTTER_IOS_APP: "https://github.com/AppiumTestDistribution/appium-flutter-server/releases/latest/download/ios.zip" + PREBUILT_WDA_PATH: ${{ github.workspace }}/wda/WebDriverAgentRunner-Runner.app jobs: build: @@ -135,12 +136,14 @@ jobs: with: model: "${{ env.IOS_DEVICE_NAME }}" os_version: "${{ env.IOS_PLATFORM_VERSION }}" + wait_for_boot: true + shutdown_after_job: false - name: Install XCUITest driver if: matrix.e2e-tests == 'ios' || matrix.e2e-tests == 'flutter-ios' run: appium driver install xcuitest - - name: Prebuild XCUITest driver + - name: Download prebuilt WDA if: matrix.e2e-tests == 'ios' || matrix.e2e-tests == 'flutter-ios' - run: appium driver run xcuitest build-wda --sdk=${{ env.IOS_PLATFORM_VERSION }} --name='${{ env.IOS_DEVICE_NAME }}' + run: appium driver run xcuitest download-wda-sim --platform=ios --outdir=$(dirname "$PREBUILT_WDA_PATH") - name: Run iOS E2E tests if: matrix.e2e-tests == 'ios' run: ./gradlew e2eIosTest -PisCI -Pselenium.version=$latest_snapshot diff --git a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java index a0dd5ccaa..1c502c4f4 100644 --- a/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java +++ b/src/e2eFlutterTest/java/io/appium/java_client/android/BaseFlutterTest.java @@ -35,6 +35,7 @@ class BaseFlutterTest { private static AppiumDriverLocalService service; protected static FlutterIntegrationTestDriver driver; protected static final By LOGIN_BUTTON = AppiumBy.flutterText("Login"); + private static String PREBUILT_WDA_PATH = System.getenv("PREBUILT_WDA_PATH"); /** * initialization. @@ -74,15 +75,19 @@ void startSession() throws MalformedURLException { String platformVersion = System.getenv("IOS_PLATFORM_VERSION") != null ? System.getenv("IOS_PLATFORM_VERSION") : "14.5"; - driver = new FlutterIOSDriver(service.getUrl(), flutterOptions - .setXCUITestOptions(new XCUITestOptions() - .setApp(System.getProperty("flutterApp")) - .setDeviceName(deviceName) - .setPlatformVersion(platformVersion) - .setWdaLaunchTimeout(Duration.ofMinutes(4)) - .setSimulatorStartupTimeout(Duration.ofMinutes(5)) - .eventTimings() - ) + XCUITestOptions xcuiTestOptions = new XCUITestOptions() + .setApp(System.getProperty("flutterApp")) + .setDeviceName(deviceName) + .setPlatformVersion(platformVersion) + .setWdaLaunchTimeout(Duration.ofMinutes(4)) + .setSimulatorStartupTimeout(Duration.ofMinutes(5)) + .eventTimings(); + if (PREBUILT_WDA_PATH != null) { + xcuiTestOptions.usePreinstalledWda().setPrebuiltWdaPath(PREBUILT_WDA_PATH); + } + driver = new FlutterIOSDriver( + service.getUrl(), + flutterOptions.setXCUITestOptions(xcuiTestOptions) ); } } diff --git a/src/e2eIosTest/java/io/appium/java_client/ios/AppIOSTest.java b/src/e2eIosTest/java/io/appium/java_client/ios/AppIOSTest.java index 595114978..8de7d60e7 100644 --- a/src/e2eIosTest/java/io/appium/java_client/ios/AppIOSTest.java +++ b/src/e2eIosTest/java/io/appium/java_client/ios/AppIOSTest.java @@ -23,6 +23,9 @@ public static void beforeClass() { .setApp(TEST_APP_ZIP) .enableBiDi() .setWdaLaunchTimeout(WDA_LAUNCH_TIMEOUT); + if (PREBUILT_WDA_PATH != null) { + options.usePreinstalledWda().setPrebuiltWdaPath(PREBUILT_WDA_PATH); + } try { driver = new IOSDriver(service.getUrl(), options); } catch (SessionNotCreatedException e) { diff --git a/src/e2eIosTest/java/io/appium/java_client/ios/BaseIOSTest.java b/src/e2eIosTest/java/io/appium/java_client/ios/BaseIOSTest.java index cc571b6fa..73772390f 100644 --- a/src/e2eIosTest/java/io/appium/java_client/ios/BaseIOSTest.java +++ b/src/e2eIosTest/java/io/appium/java_client/ios/BaseIOSTest.java @@ -36,6 +36,8 @@ public class BaseIOSTest { : "14.5"; public static final Duration WDA_LAUNCH_TIMEOUT = Duration.ofMinutes(4); public static final Duration SERVER_START_TIMEOUT = Duration.ofMinutes(3); + protected static String PREBUILT_WDA_PATH = System.getenv("PREBUILT_WDA_PATH"); + /** * Starts a local server. diff --git a/src/e2eIosTest/java/io/appium/java_client/ios/BaseIOSWebViewTest.java b/src/e2eIosTest/java/io/appium/java_client/ios/BaseIOSWebViewTest.java index 2ffe6c79c..2371a7b72 100644 --- a/src/e2eIosTest/java/io/appium/java_client/ios/BaseIOSWebViewTest.java +++ b/src/e2eIosTest/java/io/appium/java_client/ios/BaseIOSWebViewTest.java @@ -40,6 +40,9 @@ public static void beforeClass() { .setWdaLaunchTimeout(WDA_LAUNCH_TIMEOUT) .setCommandTimeouts(Duration.ofSeconds(240)) .setApp(VODQA_ZIP); + if (PREBUILT_WDA_PATH != null) { + options.usePreinstalledWda().setPrebuiltWdaPath(PREBUILT_WDA_PATH); + } Supplier createDriver = () -> new IOSDriver(service.getUrl(), options); try { driver = createDriver.get(); diff --git a/src/e2eIosTest/java/io/appium/java_client/ios/BaseSafariTest.java b/src/e2eIosTest/java/io/appium/java_client/ios/BaseSafariTest.java index 710f5dbf1..7468e89e9 100644 --- a/src/e2eIosTest/java/io/appium/java_client/ios/BaseSafariTest.java +++ b/src/e2eIosTest/java/io/appium/java_client/ios/BaseSafariTest.java @@ -34,6 +34,9 @@ public class BaseSafariTest extends BaseIOSTest { .setPlatformVersion(PLATFORM_VERSION) .setWebviewConnectTimeout(WEBVIEW_CONNECT_TIMEOUT) .setWdaLaunchTimeout(WDA_LAUNCH_TIMEOUT); + if (PREBUILT_WDA_PATH != null) { + options.usePreinstalledWda().setPrebuiltWdaPath(PREBUILT_WDA_PATH); + } driver = new IOSDriver(service.getUrl(), options); } } diff --git a/src/main/java/io/appium/java_client/ios/options/XCUITestOptions.java b/src/main/java/io/appium/java_client/ios/options/XCUITestOptions.java index 081099bc7..41d5047a2 100644 --- a/src/main/java/io/appium/java_client/ios/options/XCUITestOptions.java +++ b/src/main/java/io/appium/java_client/ios/options/XCUITestOptions.java @@ -55,6 +55,7 @@ import io.appium.java_client.ios.options.wda.SupportsKeychainOptions; import io.appium.java_client.ios.options.wda.SupportsMaxTypingFrequencyOption; import io.appium.java_client.ios.options.wda.SupportsMjpegServerPortOption; +import io.appium.java_client.ios.options.wda.SupportsPrebuiltWdaPathOption; import io.appium.java_client.ios.options.wda.SupportsProcessArgumentsOption; import io.appium.java_client.ios.options.wda.SupportsResultBundlePathOption; import io.appium.java_client.ios.options.wda.SupportsScreenshotQualityOption; @@ -66,6 +67,7 @@ import io.appium.java_client.ios.options.wda.SupportsUseNativeCachingStrategyOption; import io.appium.java_client.ios.options.wda.SupportsUseNewWdaOption; import io.appium.java_client.ios.options.wda.SupportsUsePrebuiltWdaOption; +import io.appium.java_client.ios.options.wda.SupportsUsePreinstalledWdaOption; import io.appium.java_client.ios.options.wda.SupportsUseSimpleBuildTestOption; import io.appium.java_client.ios.options.wda.SupportsUseXctestrunFileOption; import io.appium.java_client.ios.options.wda.SupportsWaitForIdleTimeoutOption; @@ -156,6 +158,8 @@ public class XCUITestOptions extends BaseOptions implements SupportsWdaBaseUrlOption, SupportsShowXcodeLogOption, SupportsUsePrebuiltWdaOption, + SupportsUsePreinstalledWdaOption, + SupportsPrebuiltWdaPathOption, SupportsShouldUseSingletonTestManagerOption, SupportsWaitForIdleTimeoutOption, SupportsUseXctestrunFileOption, diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsPrebuiltWdaPathOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsPrebuiltWdaPathOption.java new file mode 100644 index 000000000..7754f232c --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsPrebuiltWdaPathOption.java @@ -0,0 +1,50 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.appium.java_client.ios.options.wda; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +public interface SupportsPrebuiltWdaPathOption> extends + Capabilities, CanSetCapability { + String PREBUILT_WDA_PATH_OPTION = "prebuiltWDAPath"; + + /** + * The full path to the prebuilt WebDriverAgent-Runner application + * package to be installed if appium:usePreinstalledWDA capability + * is enabled. The package's bundle identifier could be customized via + * appium:updatedWDABundleId capability. + * + * @param path The full path to the bundle .app file on the server file system. + * @return self instance for chaining. + */ + default T setPrebuiltWdaPath(String path) { + return amend(PREBUILT_WDA_PATH_OPTION, path); + } + + /** + * Get prebuilt WebDriverAgent path. + * + * @return The full path to the bundle .app file on the server file system. + */ + default Optional getPrebuiltWdaPath() { + return Optional.ofNullable((String) getCapability(PREBUILT_WDA_PATH_OPTION)); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsUsePreinstalledWdaOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsUsePreinstalledWdaOption.java new file mode 100644 index 000000000..0ae2dbcfd --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsUsePreinstalledWdaOption.java @@ -0,0 +1,59 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.appium.java_client.ios.options.wda; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toSafeBoolean; + +public interface SupportsUsePreinstalledWdaOption> extends + Capabilities, CanSetCapability { + String USE_PREINSTALLED_WDA_OPTION = "usePreinstalledWDA"; + + /** + * Whether to launch a preinstalled WebDriverAgentRunner application using a custom XCTest API client. + * + * @return self instance for chaining. + */ + default T usePreinstalledWda() { + return amend(USE_PREINSTALLED_WDA_OPTION, true); + } + + /** + * Whether to launch a preinstalled WebDriverAgentRunner application using a custom XCTest API client. + * Defaults to false. + * + * @param value Either true or false. + * @return self instance for chaining. + */ + default T setUsePreinstalledWda(boolean value) { + return amend(USE_PREINSTALLED_WDA_OPTION, value); + } + + /** + * Get whether to launch a preinstalled WebDriverAgentRunner application using a custom XCTest API client. + * + * @return True or false. + */ + default Optional doesUsePreinstalledWda() { + return Optional.ofNullable(toSafeBoolean(getCapability(USE_PREINSTALLED_WDA_OPTION))); + } +}