From e462cb4b85b8b73fc57d6b46b21f81d11031da32 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sat, 30 Mar 2024 09:56:15 -0700 Subject: [PATCH 1/7] chore: add initial change --- lib/driver.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/driver.js b/lib/driver.js index 1dbfb603a..7e1491654 100644 --- a/lib/driver.js +++ b/lib/driver.js @@ -727,10 +727,11 @@ export class XCUITestDriver extends BaseDriver { // Let multiple WDA binaries with different derived data folders be built in parallel // Concurrent WDA builds from the same source will cause xcodebuild synchronization errors let synchronizationKey = XCUITestDriver.name; - if (this.opts.useXctestrunFile || !(await this.wda.isSourceFresh())) { + if (this.opts.useXctestrunFile || this.opts.usePrebuiltWDA || !(await this.wda.isSourceFresh())) { // First-time compilation is an expensive operation, which is done faster if executed // sequentially. Xcodebuild spreads the load caused by the clang compiler to all available CPU cores const derivedDataPath = await this.wda.retrieveDerivedDataPath(); + this.log.info(`[debug]: ${derivedDataPath}`); if (derivedDataPath) { synchronizationKey = path.normalize(derivedDataPath); } From 3a9f140018ea5c4c855102c7e7266742c97ebb4b Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sat, 30 Mar 2024 10:16:32 -0700 Subject: [PATCH 2/7] add another line --- lib/driver.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/driver.js b/lib/driver.js index 7e1491654..4fa40c819 100644 --- a/lib/driver.js +++ b/lib/driver.js @@ -554,6 +554,8 @@ export class XCUITestDriver extends BaseDriver { /** @type {import('appium-xcode').XcodeVersion} */ (this.xcodeVersion), { ...this.opts, + // here needs to set properly if the given appium:derivedDataPath already exists. Or perhaps try to get `this.wda.retrieveDerivedDataPath()` without that case as well. Then, maybe also the `this.wda.retrieveDerivedDataPath()` result can be `derivedDataPath` for the WDA. + prebuildWDA: this.opts.usePrebuiltWDA, device: this.device, realDevice: this.isRealDevice(), iosSdkVersion: this._iosSdkVersion, From 9a77bd81a4c0259fd6462a3912009b6d2ba4a49f Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sat, 30 Mar 2024 23:22:50 -0700 Subject: [PATCH 3/7] run prebuild every time --- lib/driver.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/driver.js b/lib/driver.js index 4fa40c819..6d5c60281 100644 --- a/lib/driver.js +++ b/lib/driver.js @@ -554,7 +554,10 @@ export class XCUITestDriver extends BaseDriver { /** @type {import('appium-xcode').XcodeVersion} */ (this.xcodeVersion), { ...this.opts, - // here needs to set properly if the given appium:derivedDataPath already exists. Or perhaps try to get `this.wda.retrieveDerivedDataPath()` without that case as well. Then, maybe also the `this.wda.retrieveDerivedDataPath()` result can be `derivedDataPath` for the WDA. + // Run prebuildWDA for the 'this.opts.usePrebuiltWDA' to use the prebuilt WDA project + // every time. + // The prebuildWDA could take full build time at the initial time, but it only could take + // a few seconds if the project has been built properly. prebuildWDA: this.opts.usePrebuiltWDA, device: this.device, realDevice: this.isRealDevice(), @@ -733,7 +736,6 @@ export class XCUITestDriver extends BaseDriver { // First-time compilation is an expensive operation, which is done faster if executed // sequentially. Xcodebuild spreads the load caused by the clang compiler to all available CPU cores const derivedDataPath = await this.wda.retrieveDerivedDataPath(); - this.log.info(`[debug]: ${derivedDataPath}`); if (derivedDataPath) { synchronizationKey = path.normalize(derivedDataPath); } From e6b48b8f292ae6d1c32fbd738050bbb277df723c Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sat, 30 Mar 2024 23:29:56 -0700 Subject: [PATCH 4/7] tweak comment --- lib/driver.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/driver.js b/lib/driver.js index 6d5c60281..a85b00426 100644 --- a/lib/driver.js +++ b/lib/driver.js @@ -554,10 +554,12 @@ export class XCUITestDriver extends BaseDriver { /** @type {import('appium-xcode').XcodeVersion} */ (this.xcodeVersion), { ...this.opts, - // Run prebuildWDA for the 'this.opts.usePrebuiltWDA' to use the prebuilt WDA project - // every time. + // Building the WDA project every time if 'appium:usePrebuiltWDA' was true. // The prebuildWDA could take full build time at the initial time, but it only could take - // a few seconds if the project has been built properly. + // a few seconds if the project has been built properly. It won't require `appium:derivedDataPath` + // has pre built WDA project by this flag. When `appium:derivedDataPath` is provided, + // the build will occur with it. If no `appium:derivedDataPath` is provided, + // the build will occur by xcodebuild's random path. prebuildWDA: this.opts.usePrebuiltWDA, device: this.device, realDevice: this.isRealDevice(), From 11f0650ab5185d67d5386a4e7acc1a542d27354f Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sat, 30 Mar 2024 23:54:35 -0700 Subject: [PATCH 5/7] tune a bit --- docs/guides/run-prebuilt-wda.md | 13 +++++++++---- docs/reference/capabilities.md | 2 +- lib/driver.js | 19 ++++++++++++------- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/docs/guides/run-prebuilt-wda.md b/docs/guides/run-prebuilt-wda.md index 24b4db6bd..ad207343a 100644 --- a/docs/guides/run-prebuilt-wda.md +++ b/docs/guides/run-prebuilt-wda.md @@ -55,7 +55,7 @@ xcodebuild test-without-building \ provided `.xctestrun` file. Once this is done, `http://localhost:8100` will be able to receive commands for the target device. -## Capabilities for Prebuilt WDA with `appium:useXctestrunFile` +## Capabilities for Prebuilt WDA with `appium:useXctestrunFile` or `appium:usePrebuiltWDA` The XCUITest driver provides two capabilities that allow skipping the `build-for-testing` command, and executing only the `test-without-building` command: __`appium:useXctestrunFile`__ and @@ -85,9 +85,14 @@ The capabilities can be used as follows: Not all combinations have been tested, but the target device can probably be anything. -The same thing can be achieved with the `appium:derivedDataPath` and `appium:usePrebuiltWDA` -capabilities, but this may fail if `xcodebuild` cannot find or handle the `.xctestrun` file -properly. The stability depends on Xcode. +The same thing can be achieved with the `appium:usePrebuiltWDA` capability. +`appium:derivedDataPath` will let the xcodebuild set the path as the `-derivedDataPath` argument. +If `appium:derivedDataPath` already has `Build` directory, Appium thinks the path already has prebuilt WDA project environment. +Then the `appium:usePrebuiltWDA` will just run xcodebuild with `test-without-building` command. + +The difference between `appium:useXctestrunFile` and `appium:usePrebuiltWDA` are +if let `xcodebuild` use specific `.xctestrun` file or use prebuilt entire WDA project. +Both stability depends on Xcode. ## Capabilities for Prebuilt WDA with `appium:prebuiltWDAPath` diff --git a/docs/reference/capabilities.md b/docs/reference/capabilities.md index d26dd5877..515a79801 100644 --- a/docs/reference/capabilities.md +++ b/docs/reference/capabilities.md @@ -60,7 +60,7 @@ about capabilities, refer to the [Appium documentation](https://appium.io/docs/e |`appium:wdaBaseUrl`| This value if specified, will be used as a prefix to build a custom `WebDriverAgent` url. It is different from `webDriverAgentUrl`, because if the latter is set then it expects `WebDriverAgent` to be already listening and skips the building phase. Defaults to `http://localhost` | `http://192.168.1.100`| |`appium:showXcodeLog`|Whether to display the output of the Xcode command used to run the tests. If this is `true`, there will be **lots** of extra logging at startup. Defaults to `false`|`true`| |`appium:iosInstallPause`|Time in milliseconds to pause between installing the application and starting `WebDriverAgent` on the device. Used particularly for larger applications. Defaults to `0`|`8000`| -|`appium:usePrebuiltWDA`|Skips the build phase of running the WDA app. Building is then the responsibility of the user. Only works for Xcode 8+. Defaults to `false`.|`true`| +|`appium:usePrebuiltWDA`|Run `build-for-testing` xcodebuild and start running the WDA app with `test-without-building`. If the WDA project already has prebuilt environment, the build itself takes only a few seconds. If `appium:derivedDataPath` is provided, the project destination will be the given path. If the given `appium:derivedDataPath` has `Build` directory, `build-for-testing` will be skipped. Defaults to `false`.|`true`| |`appium: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. |`/path/to/WebDriverAgentRunner-Runner.app`| |`appium:usePreinstalledWDA`| Whether to launch a preinstalled WebDriverAgentRunner application using a custom XCTest API client (via `com.apple.instruments` service) instead of running `xcodebuild` for real devices or simulators via simctl tool (since driver version 7.4.0). If `appium:prebuiltWDAPath` is provided, XCUITest driver will install WebDriverAgent-Runner app from the given path before launching the application. The preinstalled WebDriverAgent package must be built by Xcode 12+. The default target bundle identifier is `com.facebook.WebDriverAgentRunner.xctrunner`, although it could be customized by providing the `appium:updatedWDABundleId` capability value (the `.xctrunner` suffix is added automatically). Please read [Run Preinstalled WebDriverAgentRunner](../guides/run-preinstalled-wda.md) for more details. Defaults to `false`. |`true` or `false`| |`appium:updatedWDABundleIdSuffix`| Add suffix for the bundle id provided by the `appium:updatedWDABundleId` capability value in `appium:usePreinstalledWDA` capability usage since XCUITest driver v7.6.0. This is for an advanced usage that sets an arbitrary `CFBundleIdentifier` for prebuilt WebDriverAgent package to sign with the bundle identifier's certificate. For example, if you would need to sign a WebDriverAgent package with `io.appium.wda` bundle identifier's certificate, the WebDriverAgent's package must have the same bundle identifier as `CFBundleIdentifier`. Then, the WebDriverAgent package can be launched by `io.appium.wda`, which does not have `.xctrunner`. Then `"appium:updatedWDABundleIdSuffix": ""` (an empty string) helps. Please read [Run Preinstalled WebDriverAgentRunner](../guides/run-preinstalled-wda.md) for more details. Defaults to `.xctrunner`. | `""`, `".customsuffix"` | diff --git a/lib/driver.js b/lib/driver.js index a85b00426..f7d55fc95 100644 --- a/lib/driver.js +++ b/lib/driver.js @@ -550,17 +550,22 @@ export class XCUITestDriver extends BaseDriver { await this.runReset(); + // Building the WDA project every time if 'appium:usePrebuiltWDA' was true. + // The prebuildWDA could take full build time at the initial time, but it only could take + // a few seconds if the project has been built properly. It won't require `appium:derivedDataPath` + // has pre built WDA project by this flag. When `appium:derivedDataPath` is provided, + // the build will occur with it. If no `appium:derivedDataPath` is provided, + // the build will occur by xcodebuild's random path. + let shouldPrebuildWDA = this.opts.usePrebuiltWDA + if (shouldPrebuildWDA) { + // todo: check 'Build' directory existence with this.opts.derivedDataPath path + } + this.wda = new WebDriverAgent( /** @type {import('appium-xcode').XcodeVersion} */ (this.xcodeVersion), { ...this.opts, - // Building the WDA project every time if 'appium:usePrebuiltWDA' was true. - // The prebuildWDA could take full build time at the initial time, but it only could take - // a few seconds if the project has been built properly. It won't require `appium:derivedDataPath` - // has pre built WDA project by this flag. When `appium:derivedDataPath` is provided, - // the build will occur with it. If no `appium:derivedDataPath` is provided, - // the build will occur by xcodebuild's random path. - prebuildWDA: this.opts.usePrebuiltWDA, + prebuildWDA: shouldPrebuildWDA, device: this.device, realDevice: this.isRealDevice(), iosSdkVersion: this._iosSdkVersion, From 3c9b172cf3a4c17f5bcb7b0ce0ec4173d834084d Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sat, 30 Mar 2024 23:56:18 -0700 Subject: [PATCH 6/7] add ; --- lib/driver.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/driver.js b/lib/driver.js index f7d55fc95..aea9701de 100644 --- a/lib/driver.js +++ b/lib/driver.js @@ -556,7 +556,7 @@ export class XCUITestDriver extends BaseDriver { // has pre built WDA project by this flag. When `appium:derivedDataPath` is provided, // the build will occur with it. If no `appium:derivedDataPath` is provided, // the build will occur by xcodebuild's random path. - let shouldPrebuildWDA = this.opts.usePrebuiltWDA + let shouldPrebuildWDA = this.opts.usePrebuiltWDA; if (shouldPrebuildWDA) { // todo: check 'Build' directory existence with this.opts.derivedDataPath path } From 232e126b1a1f7f1fec4f7561e7f107b455776824 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sun, 31 Mar 2024 01:11:46 -0700 Subject: [PATCH 7/7] simply gives prebuildwda --- lib/driver.js | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/lib/driver.js b/lib/driver.js index aea9701de..3e0e6e951 100644 --- a/lib/driver.js +++ b/lib/driver.js @@ -550,22 +550,11 @@ export class XCUITestDriver extends BaseDriver { await this.runReset(); - // Building the WDA project every time if 'appium:usePrebuiltWDA' was true. - // The prebuildWDA could take full build time at the initial time, but it only could take - // a few seconds if the project has been built properly. It won't require `appium:derivedDataPath` - // has pre built WDA project by this flag. When `appium:derivedDataPath` is provided, - // the build will occur with it. If no `appium:derivedDataPath` is provided, - // the build will occur by xcodebuild's random path. - let shouldPrebuildWDA = this.opts.usePrebuiltWDA; - if (shouldPrebuildWDA) { - // todo: check 'Build' directory existence with this.opts.derivedDataPath path - } - this.wda = new WebDriverAgent( /** @type {import('appium-xcode').XcodeVersion} */ (this.xcodeVersion), { ...this.opts, - prebuildWDA: shouldPrebuildWDA, + prebuildWDA: this.opts.usePrebuiltWDA, device: this.device, realDevice: this.isRealDevice(), iosSdkVersion: this._iosSdkVersion,