From cafad7e8ed0e9bccf8d41043d7643cb9b9f9cab2 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Mon, 22 Aug 2022 14:26:46 +0200 Subject: [PATCH 001/240] fix: Handle async pasteboard alert confirmation since iOS 16 (#600) --- WebDriverAgentLib/Utilities/FBPasteboard.m | 94 ++++++++++++++++++- .../IntegrationTests/FBPasteboardTests.m | 6 +- 2 files changed, 92 insertions(+), 8 deletions(-) diff --git a/WebDriverAgentLib/Utilities/FBPasteboard.m b/WebDriverAgentLib/Utilities/FBPasteboard.m index 149ad4f01..cdcd6ec3e 100644 --- a/WebDriverAgentLib/Utilities/FBPasteboard.m +++ b/WebDriverAgentLib/Utilities/FBPasteboard.m @@ -9,7 +9,16 @@ #import "FBPasteboard.h" +#import +#import "FBAlert.h" +#import "FBApplication.h" #import "FBErrorBuilder.h" +#import "FBMacros.h" +#import "XCUIApplication+FBAlert.h" + +#define ALERT_TIMEOUT_SEC 30 +// Must not be less than FB_MONTORING_INTERVAL in FBAlertsMonitor +#define ALERT_CHECK_INTERVAL_SEC 2 #if !TARGET_OS_TV @implementation FBPasteboard @@ -50,21 +59,100 @@ + (BOOL)setData:(NSData *)data forType:(NSString *)type error:(NSError **)error return YES; } ++ (nullable id)pasteboardContentForItem:(NSString *)item + instance:(UIPasteboard *)pbInstance + timeout:(NSTimeInterval)timeout + error:(NSError **)error +{ + SEL selector = NSSelectorFromString(item); + NSMethodSignature *methodSignature = [pbInstance methodSignatureForSelector:selector]; + if (nil == methodSignature) { + NSString *description = [NSString stringWithFormat:@"Cannot retrieve '%@' from a UIPasteboard instance", item]; + if (error) { + *error = [[FBErrorBuilder.builder withDescription:description] build]; + } + return nil; + } + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; + [invocation setSelector:selector]; + [invocation setTarget:pbInstance]; + if (SYSTEM_VERSION_LESS_THAN(@"16.0")) { + [invocation invoke]; + id __unsafe_unretained result; + [invocation getReturnValue:&result]; + return result; + } + + // https://github.com/appium/appium/issues/17392 + __block id pasteboardContent; + dispatch_queue_t backgroundQueue = dispatch_queue_create("GetPasteboard", NULL); + __block BOOL didFinishGetPasteboard = NO; + dispatch_async(backgroundQueue, ^{ + [invocation invoke]; + id __unsafe_unretained result; + [invocation getReturnValue:&result]; + pasteboardContent = result; + didFinishGetPasteboard = YES; + }); + uint64_t timeStarted = mach_absolute_time(); + while (!didFinishGetPasteboard) { + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:ALERT_CHECK_INTERVAL_SEC]]; + if (didFinishGetPasteboard) { + break; + } + + XCUIElement *alertElement = FBApplication.fb_systemApplication.fb_alertElement; + if (nil != alertElement) { + FBAlert *alert = [FBAlert alertWithElement:alertElement]; + [alert acceptWithError:nil]; + } + uint64_t timeElapsed = mach_absolute_time() - timeStarted; + if (timeElapsed / NSEC_PER_SEC > timeout) { + NSString *description = [NSString stringWithFormat:@"Cannot handle pasteboard alert within %@s timeout", @(timeout)]; + if (error) { + *error = [[FBErrorBuilder.builder withDescription:description] build]; + } + return nil; + } + } + return pasteboardContent; +} + + (NSData *)dataForType:(NSString *)type error:(NSError **)error { UIPasteboard *pb = UIPasteboard.generalPasteboard; if ([type.lowercaseString isEqualToString:@"plaintext"]) { if (pb.hasStrings) { - return [[pb.strings componentsJoinedByString:@"\n"] dataUsingEncoding:NSUTF8StringEncoding]; + id result = [self.class pasteboardContentForItem:@"strings" + instance:pb + timeout:ALERT_TIMEOUT_SEC + error:error + ]; + return nil == result + ? nil + : [[(NSArray *)result componentsJoinedByString:@"\n"] dataUsingEncoding:NSUTF8StringEncoding]; } } else if ([type.lowercaseString isEqualToString:@"image"]) { if (pb.hasImages) { - return UIImagePNGRepresentation((UIImage *)pb.image); + id result = [self.class pasteboardContentForItem:@"image" + instance:pb + timeout:ALERT_TIMEOUT_SEC + error:error + ]; + return nil == result ? nil : UIImagePNGRepresentation((UIImage *)result); } } else if ([type.lowercaseString isEqualToString:@"url"]) { if (pb.hasURLs) { + id result = [self.class pasteboardContentForItem:@"URLs" + instance:pb + timeout:ALERT_TIMEOUT_SEC + error:error + ]; + if (nil == result) { + return nil; + } NSMutableArray *urls = [NSMutableArray array]; - for (NSURL *url in pb.URLs) { + for (NSURL *url in (NSArray *)result) { if (nil != url.absoluteString) { [urls addObject:(id)url.absoluteString]; } diff --git a/WebDriverAgentTests/IntegrationTests/FBPasteboardTests.m b/WebDriverAgentTests/IntegrationTests/FBPasteboardTests.m index 81e1c50cc..4f407aa64 100644 --- a/WebDriverAgentTests/IntegrationTests/FBPasteboardTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBPasteboardTests.m @@ -71,11 +71,7 @@ - (void)testGetPasteboard FBWaitExact(1.0); NSData *result = [FBPasteboard dataForType:@"plaintext" error:&error]; XCTAssertNil(error); - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"16.0")) { - // Pasteboard permission appears in a simulator. Not in a real device. - } else { - XCTAssertEqualObjects(textField.value, [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding]); - } + XCTAssertEqualObjects(textField.value, [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding]); } - (void)testUrlCopyPaste From 7c19c33660b60734b129da8b7bd9099b606ef718 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 22 Aug 2022 12:30:04 +0000 Subject: [PATCH 002/240] chore(release): 4.8.2 [skip ci] ## [4.8.2](https://github.com/appium/WebDriverAgent/compare/v4.8.1...v4.8.2) (2022-08-22) ### Bug Fixes * Handle async pasteboard alert confirmation since iOS 16 ([#600](https://github.com/appium/WebDriverAgent/issues/600)) ([cafad7e](https://github.com/appium/WebDriverAgent/commit/cafad7e8ed0e9bccf8d41043d7643cb9b9f9cab2)) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0efc1500b..39a893f7b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.8.1", + "version": "4.8.2", "description": "Package bundling WebDriverAgent", "main": "build/index.js", "scripts": { From de828dfe18ad7740258c48c3233ba83773d237e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Aug 2022 15:11:13 +0200 Subject: [PATCH 003/240] chore(deps): bump teen_process from 1.16.0 to 2.0.0 (#598) Bumps [teen_process](https://github.com/appium/node-teen_process) from 1.16.0 to 2.0.0. - [Release notes](https://github.com/appium/node-teen_process/releases) - [Commits](https://github.com/appium/node-teen_process/compare/v1.16.0...v2.0.0) --- updated-dependencies: - dependency-name: teen_process dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 39a893f7b..c6f446665 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "lodash": "^4.17.11", "node-simctl": "^7.0.1", "source-map-support": "^0.x", - "teen_process": "^1.14.1" + "teen_process": "^2.0.0" }, "files": [ "index.js", From 88e80fe8194fc10a0ed42195c421fbfe4c4e4da7 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 22 Aug 2022 13:15:13 +0000 Subject: [PATCH 004/240] chore(release): 4.8.3 [skip ci] ## [4.8.3](https://github.com/appium/WebDriverAgent/compare/v4.8.2...v4.8.3) (2022-08-22) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c6f446665..e0e42463f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.8.2", + "version": "4.8.3", "description": "Package bundling WebDriverAgent", "main": "build/index.js", "scripts": { From 2aa82d16f6cc195375e40c61f5a60885a09d095a Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Fri, 26 Aug 2022 20:47:23 +0200 Subject: [PATCH 005/240] refactor: Decouple the module from @appium/gulp-plugins (#603) --- .azure-pipelines.yml | 34 ++++++------ .eslintignore | 1 + .eslintrc | 3 - .eslintrc.json | 11 ++++ .github/workflows/publish.js.yml | 10 ++-- .mocharc.js | 4 ++ babel.config.json | 25 +++++++++ ci-jobs/build.yml | 4 +- ci-jobs/templates/build.yml | 4 +- gulpfile.js | 19 ------- index.js | 11 +--- lib/check-dependencies.js | 6 +- lib/constants.js | 13 +---- lib/utils.js | 33 +++++++++-- lib/webdriveragent.js | 5 +- package.json | 61 ++++++++++++++------- test/functional/webdriveragent-e2e-specs.js | 10 ++-- test/unit/webdriveragent-specs.js | 3 +- 18 files changed, 151 insertions(+), 106 deletions(-) delete mode 100644 .eslintrc create mode 100644 .eslintrc.json create mode 100644 .mocharc.js create mode 100644 babel.config.json delete mode 100644 gulpfile.js diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index 0d99a23f2..8a3dddc32 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -1,21 +1,19 @@ -# https://github.com/actions/virtual-environments/tree/main/images/macos +# https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops&tabs=yaml variables: - MIN_VM_IMAGE: macOS-10.15 - MIN_XCODE_VERSION: 12.1 - # Xcode 10.0 did not have Apple TV - MIN_TV_XCODE_VERSION: 12.1 - MIN_TV_PLATFORM_VERSION: 14.0 + MIN_VM_IMAGE: macOS-11 + MIN_XCODE_VERSION: 12.4 + MIN_PLATFORM_VERSION: 14.4 + MIN_TV_PLATFORM_VERSION: 14.3 MIN_TV_DEVICE_NAME: Apple TV 4K - MIN_PLATFORM_VERSION: 14.1 MIN_IPHONE_DEVICE_NAME: iPhone 11 MIN_IPAD_DEVICE_NAME: iPad Pro (11-inch) (2nd generation) - MAX_VM_IMAGE: macOS-11 - MAX_XCODE_VERSION: 13.2 - MAX_PLATFORM_VERSION: 15.2 - MAX_PLATFORM_VERSION_TV: 15.2 - MAX_IPHONE_DEVICE_NAME: iPhone 11 Pro Max - MAX_TV_DEVICE_NAME: Apple TV 4K - MAX_IPAD_DEVICE_NAME: iPad Pro (11-inch) (2nd generation) + MAX_VM_IMAGE: macOS-12 + MAX_XCODE_VERSION: 13.4 + MAX_PLATFORM_VERSION: 15.5 + MAX_PLATFORM_VERSION_TV: 15.4 + MAX_IPHONE_DEVICE_NAME: iPhone 13 + MAX_TV_DEVICE_NAME: Apple TV 4K (2nd generation) + MAX_IPAD_DEVICE_NAME: iPad Pro (11-inch) (3rd generation) DEFAULT_NODE_VERSION: "16.x" @@ -135,7 +133,7 @@ stages: dest: tv tvModel: $(MIN_TV_DEVICE_NAME) tvVersion: $(MIN_TV_PLATFORM_VERSION) - xcodeVersion: $(MIN_TV_XCODE_VERSION) + xcodeVersion: $(MIN_XCODE_VERSION) vmImage: $(MIN_VM_IMAGE) # endregion @@ -212,7 +210,7 @@ stages: sdk: tv_sim tvModel: $(MIN_TV_DEVICE_NAME) tvVersion: $(MIN_TV_PLATFORM_VERSION) - xcodeVersion: $(MIN_TV_XCODE_VERSION) + xcodeVersion: $(MIN_XCODE_VERSION) vmImage: $(MIN_VM_IMAGE) - template: ./azure-templates/base_job.yml parameters: @@ -222,7 +220,7 @@ stages: sdk: tv_sim tvModel: $(MIN_TV_DEVICE_NAME) tvVersion: $(MIN_TV_PLATFORM_VERSION) - xcodeVersion: $(MIN_TV_XCODE_VERSION) + xcodeVersion: $(MIN_XCODE_VERSION) vmImage: $(MIN_VM_IMAGE) # endregion @@ -295,7 +293,7 @@ stages: sdk: tv_sim tvModel: $(MIN_TV_DEVICE_NAME) tvVersion: $(MIN_TV_PLATFORM_VERSION) - xcodeVersion: $(MIN_TV_XCODE_VERSION) + xcodeVersion: $(MIN_XCODE_VERSION) vmImage: $(MIN_VM_IMAGE) # endregion diff --git a/.eslintignore b/.eslintignore index 4671072fa..84930aead 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,3 @@ Resources coverage +build diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 47415a57c..000000000 --- a/.eslintrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "@appium/eslint-config-appium" -} diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 000000000..69a602c5c --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,11 @@ +{ + "extends": "@appium/eslint-config-appium", + "overrides": [ + { + "files": "test/**/*.js", + "rules": { + "func-names": "off" + } + } + ] +} diff --git a/.github/workflows/publish.js.yml b/.github/workflows/publish.js.yml index 89c0ab731..eb0464bea 100644 --- a/.github/workflows/publish.js.yml +++ b/.github/workflows/publish.js.yml @@ -13,16 +13,18 @@ jobs: runs-on: macos-latest steps: - uses: actions/checkout@v2 - - name: Use Node.js 16.x + - name: Use Node.js 18.x uses: actions/setup-node@v1 with: - node-version: 16.x + node-version: 18.x - run: | npm install -g appium@next npm install --no-package-lock name: Install dev dependencies - - run: npm test - name: Run NPM Test + - run: npm run build + name: Run build + - run: npm run test + name: Run test - run: npx semantic-release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.mocharc.js b/.mocharc.js new file mode 100644 index 000000000..66d4a976a --- /dev/null +++ b/.mocharc.js @@ -0,0 +1,4 @@ +module.exports = { + require: ['@babel/register'], + forbidOnly: Boolean(process.env.CI) +}; diff --git a/babel.config.json b/babel.config.json new file mode 100644 index 000000000..048e9cf60 --- /dev/null +++ b/babel.config.json @@ -0,0 +1,25 @@ +{ + "presets": [ + [ + "@babel/preset-env", + { + "targets": { + "node": "14" + }, + "shippedProposals": true + } + ] + ], + "plugins": [ + "source-map-support", + "@babel/plugin-transform-runtime" + ], + "comments": false, + "sourceMaps": "both", + "env": { + "test": { + "retainLines": true, + "comments": true + } + } +} diff --git a/ci-jobs/build.yml b/ci-jobs/build.yml index ac0532250..fc50e2085 100644 --- a/ci-jobs/build.yml +++ b/ci-jobs/build.yml @@ -9,6 +9,6 @@ jobs: addChangeLog: false - template: ./templates/build.yml parameters: - vmImage: 'macOS-10.15' - name: 'macOS_10_15' + vmImage: 'macOS-11' + name: 'macOS_11' excludeXcode: '10.3.0,10.3,11.3,11.4,12' diff --git a/ci-jobs/templates/build.yml b/ci-jobs/templates/build.yml index 4d0d0ef1b..e5e768de3 100644 --- a/ci-jobs/templates/build.yml +++ b/ci-jobs/templates/build.yml @@ -1,6 +1,6 @@ parameters: - vmImage: 'macOS-10.15' - name: macOS_10_15 + vmImage: 'macOS-11' + name: macOS_11 excludeXcode: $(excludeXcode) jobs: - job: ${{ parameters.name }} diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index 740ea352f..000000000 --- a/gulpfile.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict'; - -const gulp = require('gulp'); -const boilerplate = require('@appium/gulp-plugins').boilerplate.use(gulp); -const DEFAULTS = require('@appium/gulp-plugins').boilerplate.DEFAULTS; - - -boilerplate({ - build: 'appium-webdriveragent', - files: DEFAULTS.files.concat('index.js'), - projectRoot: __dirname, -}); - -gulp.task('install:dependencies', gulp.series('transpile', function installDependencies () { - // we cannot require `fetchDependencies` at the top level because it has not - // necessarily been transpiled at that point - const { checkForDependencies } = require('./build'); - return checkForDependencies(); -})); diff --git a/index.js b/index.js index 68fe37538..3513d683b 100644 --- a/index.js +++ b/index.js @@ -3,20 +3,13 @@ import * as proxies from './lib/no-session-proxy'; import * as driver from './lib/webdriveragent'; import * as constants from './lib/constants'; import * as utils from './lib/utils'; -import { asyncify } from 'asyncbox'; const { checkForDependencies, bundleWDASim } = dependencies; const { NoSessionProxy } = proxies; const { WebDriverAgent } = driver; -const { BOOTSTRAP_PATH, WDA_BASE_URL, WDA_RUNNER_BUNDLE_ID, PROJECT_FILE } = constants; -const { resetTestProcesses } = utils; - - -// When run as a command line utility, this should check for the dependencies -if (require.main === module) { - asyncify(checkForDependencies); -} +const { WDA_BASE_URL, WDA_RUNNER_BUNDLE_ID, PROJECT_FILE } = constants; +const { resetTestProcesses, BOOTSTRAP_PATH } = utils; export { WebDriverAgent, diff --git a/lib/check-dependencies.js b/lib/check-dependencies.js index d8232dc7d..b2be31d33 100644 --- a/lib/check-dependencies.js +++ b/lib/check-dependencies.js @@ -4,13 +4,14 @@ import { exec } from 'teen_process'; import path from 'path'; import XcodeBuild from './xcodebuild'; import { - WDA_PROJECT, WDA_SCHEME, SDK_SIMULATOR, WDA_RUNNER_APP + WDA_SCHEME, SDK_SIMULATOR, WDA_RUNNER_APP } from './constants'; +import { BOOTSTRAP_PATH } from './utils'; import log from './logger'; async function buildWDASim () { const args = [ - '-project', WDA_PROJECT, + '-project', path.join(BOOTSTRAP_PATH, 'WebDriverAgent.xcodeproj'), '-scheme', WDA_SCHEME, '-sdk', SDK_SIMULATOR, 'CODE_SIGN_IDENTITY=""', @@ -37,7 +38,6 @@ async function bundleWDASim (xcodebuild, opts = {}) { if (await fs.exists(wdaBundlePath)) { return wdaBundlePath; } - await checkForDependencies(opts); await buildWDASim(xcodebuild, opts); return wdaBundlePath; } diff --git a/lib/constants.js b/lib/constants.js index ad9c2535e..caea65cec 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -1,11 +1,5 @@ import path from 'path'; - -const BOOTSTRAP_PATH = __dirname.endsWith('build') - ? path.resolve(__dirname, '..', '..', '..') - : path.resolve(__dirname, '..', '..'); -const WDA_PROJECT = path.join(BOOTSTRAP_PATH, 'WebDriverAgent.xcodeproj'); -const WDA_SCRIPTS_ROOT = path.join(BOOTSTRAP_PATH, 'Scripts'); const WDA_RUNNER_BUNDLE_ID = 'com.facebook.WebDriverAgentRunner'; const WDA_RUNNER_APP = 'WebDriverAgentRunner-Runner.app'; const WDA_SCHEME = 'WebDriverAgentRunner'; @@ -21,10 +15,7 @@ const SDK_DEVICE = 'iphoneos'; const WDA_UPGRADE_TIMESTAMP_PATH = path.join('.appium', 'webdriveragent', 'upgrade.time'); export { - BOOTSTRAP_PATH, WDA_RUNNER_BUNDLE_ID, WDA_RUNNER_APP, PROJECT_FILE, - WDA_PROJECT, WDA_SCHEME, - PLATFORM_NAME_TVOS, PLATFORM_NAME_IOS, - SDK_SIMULATOR, SDK_DEVICE, - WDA_BASE_URL, WDA_SCRIPTS_ROOT, WDA_UPGRADE_TIMESTAMP_PATH + WDA_SCHEME, PLATFORM_NAME_TVOS, PLATFORM_NAME_IOS, + SDK_SIMULATOR, SDK_DEVICE, WDA_BASE_URL, WDA_UPGRADE_TIMESTAMP_PATH }; diff --git a/lib/utils.js b/lib/utils.js index 00d8d5502..cea05c420 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -5,13 +5,36 @@ import log from './logger'; import _ from 'lodash'; import { WDA_RUNNER_BUNDLE_ID, PLATFORM_NAME_TVOS } from './constants'; import B from 'bluebird'; +import _fs from 'fs'; import { waitForCondition } from 'asyncbox'; -const ROOT_DIR = path.basename(__dirname) === 'lib' - ? path.resolve(__dirname, process.env.NO_PRECOMPILE ? '..' : '../..') - : __dirname; const PROJECT_FILE = 'project.pbxproj'; +/** + * Calculates the path to the current module's root folder + * + * @returns {string} The full path to module root + * @throws {Error} If the current module root folder cannot be determined + */ +const getModuleRoot = _.memoize(function getModuleRoot () { + const pathParts = path.resolve(__dirname).split(path.sep); + for (let pathItemIdx = pathParts.length; pathItemIdx > 0; --pathItemIdx) { + const currentDir = path.join(...(pathParts.slice(0, pathItemIdx))); + const manifestPath = path.join(currentDir, 'package.json'); + try { + if (!_fs.existsSync(manifestPath)) { + continue; + } + if (JSON.parse(_fs.readFileSync(manifestPath, 'utf8')).name === 'appium-webdriveragent') { + return currentDir; + } + } catch (ign) {} + } + throw new Error('Cannot find the root folder of the appium-webdriveragent Node.js module'); +}); + +export const BOOTSTRAP_PATH = getModuleRoot(); + async function getPIDsUsingPattern (pattern) { const args = [ '-if', // case insensitive, full cmdline match @@ -297,7 +320,7 @@ function randomInt (low, high) { * package upgrade. */ async function getWDAUpgradeTimestamp () { - const packageManifest = path.resolve(ROOT_DIR, 'package.json'); + const packageManifest = path.resolve(getModuleRoot(), 'package.json'); if (!await fs.exists(packageManifest)) { return null; } @@ -371,5 +394,5 @@ export { updateProjectFile, resetProjectFile, setRealDeviceSecurity, getAdditionalRunContent, getXctestrunFileName, generateXcodeConfigFile, setXctestrunFile, getXctestrunFilePath, killProcess, randomInt, getWDAUpgradeTimestamp, resetTestProcesses, - getPIDsListeningOnPort, killAppUsingPattern, isTvOS, + getPIDsListeningOnPort, killAppUsingPattern, isTvOS }; diff --git a/lib/webdriveragent.js b/lib/webdriveragent.js index 61e65d8ea..5ccb0475f 100644 --- a/lib/webdriveragent.js +++ b/lib/webdriveragent.js @@ -7,15 +7,14 @@ import { fs, util, plist, mkdirp } from 'appium/support'; import defaultLogger from './logger'; import { NoSessionProxy } from './no-session-proxy'; import { - getWDAUpgradeTimestamp, resetTestProcesses, getPIDsListeningOnPort + getWDAUpgradeTimestamp, resetTestProcesses, getPIDsListeningOnPort, BOOTSTRAP_PATH } from './utils'; import XcodeBuild from './xcodebuild'; import AsyncLock from 'async-lock'; import { exec } from 'teen_process'; import { bundleWDASim } from './check-dependencies'; import { - BOOTSTRAP_PATH, WDA_RUNNER_BUNDLE_ID, WDA_RUNNER_APP, - WDA_BASE_URL, WDA_UPGRADE_TIMESTAMP_PATH, + WDA_RUNNER_BUNDLE_ID, WDA_RUNNER_APP, WDA_BASE_URL, WDA_UPGRADE_TIMESTAMP_PATH, } from './constants'; const WDA_LAUNCH_TIMEOUT = 60 * 1000; diff --git a/package.json b/package.json index e0e42463f..dbe1f07db 100644 --- a/package.json +++ b/package.json @@ -2,28 +2,38 @@ "name": "appium-webdriveragent", "version": "4.8.3", "description": "Package bundling WebDriverAgent", - "main": "build/index.js", + "main": "./build/index.js", "scripts": { - "test": "gulp once", - "e2e-test": "npm run build && _FORCE_LOGS=1 npx mocha -t 0 -R spec build/test/functional --exit", - "clean": "rm -rf node_modules && rm -f package-lock.json && npm install", - "install:dependencies": "gulp install:dependencies", - "build": "gulp transpile", - "prepare": "gulp prepublish", - "prepublishOnly": "npm run bundle", - "lint": "gulp lint", - "lint:fix": "gulp eslint --fix", + "build": "rm -rf build && babel --out-dir=build/lib lib && babel --out-dir=build index.js", + "dev": "npm run build -- --watch", + "lint": "eslint .", + "lint:fix": "npm run lint -- --fix", "precommit-msg": "echo 'Pre-commit checks...' && exit 0", - "precommit-test": "gulp lint", + "precommit-lint": "lint-staged", + "prepare": "npm run build", + "test": "mocha --exit --timeout 1m \"./test/unit/**/*-specs.js\"", + "e2e-test": "mocha --exit --timeout 10m \"./test/functional/**/*-specs.js\"", + "prepublishOnly": "npm run bundle", "bundle": "node ./Scripts/build-webdriveragent.js", - "fetch-prebuilt-wda": "node ./Scripts/fetch-prebuilt-wda" + "fetch-prebuilt-wda": "node ./Scripts/fetch-prebuilt-wda.js" + }, + "engines": { + "node": ">=14", + "npm": ">=8" + }, + "lint-staged": { + "*.js": [ + "eslint --fix" + ] }, - "bin": { - "appium-wda-bootstrap": "./build/index.js" + "prettier": { + "bracketSpacing": false, + "printWidth": 100, + "singleQuote": true }, "pre-commit": [ "precommit-msg", - "precommit-test" + "precommit-lint" ], "repository": { "type": "git", @@ -36,26 +46,37 @@ "Selenium", "WebDriverAgent" ], - "author": "appium", + "author": "Appium Contributors", "license": "Apache-2.0", "bugs": { "url": "https://github.com/appium/WebDriverAgent/issues" }, "homepage": "https://github.com/appium/WebDriverAgent#readme", "devDependencies": { - "@appium/gulp-plugins": "^7.0.0", "@appium/eslint-config-appium": "^6.0.0", "@appium/test-support": "^1.0.0", + "@babel/cli": "^7.18.10", + "@babel/core": "^7.18.10", + "@babel/eslint-parser": "^7.18.9", + "@babel/plugin-transform-runtime": "^7.18.10", + "@babel/preset-env": "^7.18.10", + "@babel/register": "^7.18.9", "@semantic-release/git": "^10.0.1", - "appium-xcode": "^4.0.0", + "babel-plugin-source-map-support": "^2.2.0", + "appium-xcode": "^4.0.1", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", + "eslint": "^7.32.0", "eslint-config-prettier": "^8.5.0", "glob": "^8.0.1", - "gulp": "^4.0.2", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-mocha": "^9.0.0", + "eslint-plugin-promise": "^6.0.0", + "lint-staged": "^13.0.3", "ios-uicatalog": "^3.5.0", "mocha": "^10.0.0", "pre-commit": "^1.2.2", + "prettier": "^2.7.1", "semantic-release": "^19.0.2", "sinon": "^14.0.0" }, @@ -82,8 +103,6 @@ "Scripts/build.sh", "Scripts/fetch-prebuilt-wda.js", "Scripts/build-webdriveragent.js", - "Cartfile", - "Cartfile.resolved", "Configurations", "PrivateHeaders", "WebDriverAgent.xcodeproj", diff --git a/test/functional/webdriveragent-e2e-specs.js b/test/functional/webdriveragent-e2e-specs.js index ae63a799d..e715fb6d4 100644 --- a/test/functional/webdriveragent-e2e-specs.js +++ b/test/functional/webdriveragent-e2e-specs.js @@ -10,10 +10,11 @@ import { retryInterval } from 'asyncbox'; import { WebDriverAgent } from '../../lib/webdriveragent'; import axios from 'axios'; +const MOCHA_TIMEOUT_MS = 60 * 1000 * 4; const SIM_DEVICE_NAME = 'webDriverAgentTest'; +const SIM_STARTUP_TIMEOUT_MS = MOCHA_TIMEOUT_MS; -const MOCHA_TIMEOUT = 60 * 1000 * 4; chai.should(); chai.use(chaiAsPromised); @@ -29,13 +30,12 @@ function getStartOpts (device) { realDevice: false, showXcodeLog: true, wdaLaunchTimeout: 60 * 3 * 1000, - simulatorStartupTimeout: 60 * 4 * 1000, }; } describe('WebDriverAgent', function () { - this.timeout(MOCHA_TIMEOUT); + this.timeout(MOCHA_TIMEOUT_MS); let xcodeVersion; before(async function () { @@ -61,7 +61,7 @@ describe('WebDriverAgent', function () { }); after(async function () { - this.timeout(MOCHA_TIMEOUT); + this.timeout(MOCHA_TIMEOUT_MS); await shutdownSimulator(device); @@ -72,7 +72,7 @@ describe('WebDriverAgent', function () { this.timeout(6 * 60 * 1000); beforeEach(async function () { await killAllSimulators(); - await device.run(); + await device.run({startupTimeout: SIM_STARTUP_TIMEOUT_MS}); }); afterEach(async function () { try { diff --git a/test/unit/webdriveragent-specs.js b/test/unit/webdriveragent-specs.js index bfdeab9f9..6eac94c5b 100644 --- a/test/unit/webdriveragent-specs.js +++ b/test/unit/webdriveragent-specs.js @@ -1,4 +1,5 @@ -import { WebDriverAgent, BOOTSTRAP_PATH } from '../..'; +import { BOOTSTRAP_PATH } from '../../lib/utils'; +import { WebDriverAgent } from '../../lib/webdriveragent'; import * as utils from '../../lib/utils'; import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; From 9aee5fa9f48abfab22096d286c02ebd6fa723cb9 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Sun, 28 Aug 2022 08:15:45 +0200 Subject: [PATCH 006/240] fix: Tune finding of the module root (#605) --- lib/utils.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/utils.js b/lib/utils.js index cea05c420..a28539914 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -17,18 +17,18 @@ const PROJECT_FILE = 'project.pbxproj'; * @throws {Error} If the current module root folder cannot be determined */ const getModuleRoot = _.memoize(function getModuleRoot () { - const pathParts = path.resolve(__dirname).split(path.sep); - for (let pathItemIdx = pathParts.length; pathItemIdx > 0; --pathItemIdx) { - const currentDir = path.join(...(pathParts.slice(0, pathItemIdx))); + let currentDir = path.dirname(path.resolve(__filename)); + let isAtFsRoot = false; + while (!isAtFsRoot) { const manifestPath = path.join(currentDir, 'package.json'); try { - if (!_fs.existsSync(manifestPath)) { - continue; - } - if (JSON.parse(_fs.readFileSync(manifestPath, 'utf8')).name === 'appium-webdriveragent') { + if (_fs.existsSync(manifestPath) && + JSON.parse(_fs.readFileSync(manifestPath, 'utf8')).name === 'appium-webdriveragent') { return currentDir; } } catch (ign) {} + currentDir = path.dirname(currentDir); + isAtFsRoot = currentDir.length <= path.dirname(currentDir).length; } throw new Error('Cannot find the root folder of the appium-webdriveragent Node.js module'); }); From 32cc28752ce7d90fffc6b4cd0c6fca9f99ade335 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 28 Aug 2022 06:20:06 +0000 Subject: [PATCH 007/240] chore(release): 4.8.4 [skip ci] ## [4.8.4](https://github.com/appium/WebDriverAgent/compare/v4.8.3...v4.8.4) (2022-08-28) ### Bug Fixes * Tune finding of the module root ([#605](https://github.com/appium/WebDriverAgent/issues/605)) ([9aee5fa](https://github.com/appium/WebDriverAgent/commit/9aee5fa9f48abfab22096d286c02ebd6fa723cb9)) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dbe1f07db..c2ba57e24 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.8.3", + "version": "4.8.4", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From cb4897d77d07d834f36cd7917fb6a4e414cc36df Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Sun, 28 Aug 2022 09:10:10 +0200 Subject: [PATCH 008/240] ci: Add linting --- .azure-pipelines.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index 8a3dddc32..203c0517a 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -48,6 +48,7 @@ stages: - script: | npm install -g appium@next npm install + npm run lint - script: npm run test # region Build From 898f6388de26d59a344a537c186f4e61f39e04d1 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Wed, 7 Sep 2022 21:31:02 +0200 Subject: [PATCH 009/240] ci: Run node.js functional and unit tests using Github Actions (#607) --- .azure-pipelines.yml | 20 ---- .github/workflows/functional-test.yml | 29 +++++ .github/workflows/pr-title.yml | 13 +++ .github/workflows/unit-test.yml | 40 +++++++ package.json | 1 - test/functional/desired.js | 150 +------------------------- 6 files changed, 86 insertions(+), 167 deletions(-) create mode 100644 .github/workflows/functional-test.yml create mode 100644 .github/workflows/pr-title.yml create mode 100644 .github/workflows/unit-test.yml diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index 203c0517a..03ad02e58 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -42,15 +42,6 @@ parameters: stages: - stage: Unit_Tests_And_Linters jobs: - - job: Node_Unit_Tests - steps: - - template: azure-templates/node_setup_steps.yml - - script: | - npm install -g appium@next - npm install - npm run lint - - script: npm run test - # region Build - template: ./azure-templates/base_job.yml parameters: @@ -301,17 +292,6 @@ stages: - stage: Integration_Tests jobs: - - job: Node_Integration_Tests - variables: - XCODE_VERSION: $(MAX_XCODE_VERSION) - DEVICE_NAME: $(MAX_IPHONE_DEVICE_NAME) - PLATFORM_VERSION: $(MAX_PLATFORM_VERSION) - steps: - - template: azure-templates/node_setup_steps.yml - - script: npm install - - template: azure-templates/bootstrap_steps.yml - - script: npm run e2e-test - # region Integration Tests Max Xcode - ${{ each job in parameters.integrationJobs }}: - template: ./azure-templates/base_job.yml diff --git a/.github/workflows/functional-test.yml b/.github/workflows/functional-test.yml new file mode 100644 index 000000000..8c95517e9 --- /dev/null +++ b/.github/workflows/functional-test.yml @@ -0,0 +1,29 @@ +name: Functional Tests + +on: [pull_request] + + +jobs: + test: + env: + CI: true + _FORCE_LOGS: 1 + XCODE_VERSION: 13.4 + DEVICE_NAME: iPhone 11 + PLATFORM_VERSION: 15.5 + # https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md + runs-on: macos-12 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: "${{ env.XCODE_VERSION }}" + - run: | + npm install + mkdir -p ./Resources/WebDriverAgent.bundle + name: Install dev dependencies + - run: npm run e2e-test + name: Run functional tests diff --git a/.github/workflows/pr-title.yml b/.github/workflows/pr-title.yml new file mode 100644 index 000000000..93840452e --- /dev/null +++ b/.github/workflows/pr-title.yml @@ -0,0 +1,13 @@ +name: Conventional Commits +on: + pull_request: + + +jobs: + lint: + name: https://www.conventionalcommits.org + runs-on: ubuntu-latest + steps: + - uses: beemojs/conventional-pr-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml new file mode 100644 index 000000000..818f00824 --- /dev/null +++ b/.github/workflows/unit-test.yml @@ -0,0 +1,40 @@ +name: Unit Tests + +on: [pull_request, push] + + +jobs: + prepare_matrix: + runs-on: ubuntu-latest + outputs: + versions: ${{ steps.generate-matrix.outputs.versions }} + steps: + - name: Generate Node.js versions matrix + id: generate-matrix + run: | + current_lts=$(curl -s https://nodejs.org/en/ | grep -E -o 'Download [0-9.]+ LTS' | grep -E -o '([0-9]+)' | head -n 1) + previous_lts=$(( current_lts - 2 )) + next_lts=$(( current_lts + 2 )) + VERSIONS="[$previous_lts, $current_lts, $next_lts]" + echo ::set-output name=versions::${VERSIONS} + + test: + needs: + - prepare_matrix + strategy: + matrix: + node-version: ${{ fromJSON(needs.prepare_matrix.outputs.versions) }} + runs-on: macos-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - run: npm i -g npm + name: Update NPM + - run: npm install --no-package-lock + name: Install dev dependencies + - run: npm run lint + name: Run linter + - run: npm run test + name: Run unit tests diff --git a/package.json b/package.json index c2ba57e24..3b5f36435 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,6 @@ "eslint-plugin-mocha": "^9.0.0", "eslint-plugin-promise": "^6.0.0", "lint-staged": "^13.0.3", - "ios-uicatalog": "^3.5.0", "mocha": "^10.0.0", "pre-commit": "^1.2.2", "prettier": "^2.7.1", diff --git a/test/functional/desired.js b/test/functional/desired.js index 98304f1ff..06527a18b 100644 --- a/test/functional/desired.js +++ b/test/functional/desired.js @@ -1,147 +1,5 @@ -import _ from 'lodash'; -import path from 'path'; -import glob from 'glob'; -import fs from 'fs'; -import { system, util } from 'appium/support'; +import { util } from 'appium/support'; - -// translate integer environment variable to a boolean 0=false, !0=true -function checkFeatureInEnv (envArg) { - let feature = parseInt(process.env[envArg], 10); - if (isNaN(feature)) { - feature = process.env[envArg]; - } - return !!feature; -} - -const PLATFORM_VERSION = process.env.PLATFORM_VERSION ? process.env.PLATFORM_VERSION : '11.3'; -const LAUNCH_WITH_IDB = process.env.LAUNCH_WITH_IDB; - -// If it's real device cloud, don't set a device name. Use dynamic device allocation. -const DEVICE_NAME = process.env.DEVICE_NAME - ? process.env.DEVICE_NAME - : process.env.SAUCE_RDC - ? undefined - : util.compareVersions(PLATFORM_VERSION, '>=', '13.0') ? 'iPhone 8' : 'iPhone 6'; - -const SHOW_XCODE_LOG = checkFeatureInEnv('SHOW_XCODE_LOG'); -const REAL_DEVICE = checkFeatureInEnv('REAL_DEVICE'); -let XCCONFIG_FILE = process.env.XCCONFIG_FILE; -if (REAL_DEVICE && !XCCONFIG_FILE) { - // no xcconfig file specified, so try to find in the root directory of the package - // this happens once, at the start of a test run, so using sync method is ok - let cwd = path.resolve(__dirname, '..', '..', '..'); - let files = glob.sync('*.xcconfig', { cwd }); - if (files.length) { - XCCONFIG_FILE = path.resolve(cwd, _.first(files)); - } -} - -// Had to make these two optional dependencies so the tests -// can still run in linux -let uiCatalogPath; -if (system.isMac() && !process.env.CLOUD) { - // iOS 13+ need a slightly different app to be able to get the correct automation - uiCatalogPath = parseInt(PLATFORM_VERSION, 10) >= 13 - ? require('ios-uicatalog').uiKitCatalog.absolute - : require('ios-uicatalog').uiCatalog.absolute; -} - -const apps = {}; - -const CLOUD = process.env.CLOUD; - -if (REAL_DEVICE) { - if (CLOUD) { - apps.testAppId = 1; - } else { - apps.uiCatalogApp = uiCatalogPath.iphoneos; - } -} else { - if (CLOUD) { - apps.uiCatalogApp = 'http://appium.github.io/appium/assets/UICatalog9.4.app.zip'; - apps.touchIdApp = null; // TODO: Upload this to appium.io - } else { - apps.uiCatalogApp = uiCatalogPath.iphonesimulator; - apps.touchIdApp = path.resolve('.', 'test', 'assets', 'TouchIDExample.app'); - } -} - -const REAL_DEVICE_CAPS = REAL_DEVICE ? { - udid: 'auto', - xcodeConfigFile: XCCONFIG_FILE, - webkitResponseTimeout: 30000, - testobject_app_id: apps.testAppId, - testobject_api_key: process.env.SAUCE_RDC_ACCESS_KEY, - testobject_remote_appium_url: process.env.APPIUM_STAGING_URL, // TODO: Once RDC starts supporting this again, re-insert this -} : {}; - -let GENERIC_CAPS = { - platformName: 'iOS', - platformVersion: PLATFORM_VERSION, - deviceName: DEVICE_NAME, - automationName: 'XCUITest', - launchWithIDB: !!LAUNCH_WITH_IDB, - noReset: true, - maxTypingFrequency: 30, - clearSystemFiles: true, - showXcodeLog: SHOW_XCODE_LOG, - wdaLaunchTimeout: (60 * 1000 * 4), - wdaConnectionTimeout: (60 * 1000 * 8), - useNewWDA: true, - simulatorStartupTimeout: 240000, -}; - -if (process.env.CLOUD) { - GENERIC_CAPS.platformVersion = process.env.CLOUD_PLATFORM_VERSION; - GENERIC_CAPS.build = process.env.SAUCE_BUILD; - GENERIC_CAPS.showIOSLog = false; - GENERIC_CAPS[process.env.APPIUM_BUNDLE_CAP || 'appium-version'] = {'appium-url': 'sauce-storage:appium.zip'}; - // TODO: If it's SAUCE_RDC add the appium staging URL - - // `name` will be set during session initialization -} - -// on Travis, when load is high, the app often fails to build, -// and tests fail, so use static one in assets if necessary, -// but prefer to have one build locally -// only do this for sim, since real device one needs to be built with dev creds -if (!REAL_DEVICE && !process.env.CLOUD) { - // this happens a single time, at load-time for the test suite, - // so sync method is not overly problematic - if (!fs.existsSync(apps.uiCatalogApp)) { - apps.uiCatalogApp = path.resolve('.', 'test', 'assets', - `${parseInt(PLATFORM_VERSION, 10) >= 13 ? 'UIKitCatalog' : 'UICatalog'}-iphonesimulator.app`); - } - if (!fs.existsSync(apps.iosTestApp)) { - apps.iosTestApp = path.resolve('.', 'test', 'assets', 'TestApp-iphonesimulator.app'); - } -} - -const UICATALOG_CAPS = _.defaults({ - app: apps.uiCatalogApp, -}, GENERIC_CAPS, REAL_DEVICE_CAPS); - -const UICATALOG_SIM_CAPS = _.defaults({ - app: apps.uiCatalogApp, -}, GENERIC_CAPS); -delete UICATALOG_SIM_CAPS.noReset; // do not want to have no reset on the tests that use this - -const W3C_CAPS = { - capabilities: { - alwaysMatch: UICATALOG_CAPS, - firstMatch: [{}], - } -}; - -let TVOS_CAPS = _.defaults({ - platformName: 'tvOS', - bundleId: 'com.apple.TVSettings', - deviceName: 'Apple TV' -}, GENERIC_CAPS); - -export { - UICATALOG_CAPS, UICATALOG_SIM_CAPS, - PLATFORM_VERSION, DEVICE_NAME, W3C_CAPS, - TVOS_CAPS -}; +export const PLATFORM_VERSION = process.env.PLATFORM_VERSION ? process.env.PLATFORM_VERSION : '11.3'; +export const DEVICE_NAME = process.env.DEVICE_NAME + || (util.compareVersions(PLATFORM_VERSION, '>=', '13.0') ? 'iPhone X' : 'iPhone 6'); From 3dd5d59c1318c99921bea140ffb671b3456f6a7b Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Wed, 7 Sep 2022 21:55:45 +0200 Subject: [PATCH 010/240] ci: Update config preset for conventional commits --- .github/workflows/pr-title.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/pr-title.yml b/.github/workflows/pr-title.yml index 93840452e..9a192aec5 100644 --- a/.github/workflows/pr-title.yml +++ b/.github/workflows/pr-title.yml @@ -9,5 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: beemojs/conventional-pr-action@v2 + with: + config-preset: angular env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 5b20d27f56f264e2ee9c043b944930e97896416c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Sep 2022 18:04:16 +0200 Subject: [PATCH 011/240] chore(deps-dev): bump @appium/test-support from 1.5.0 to 2.0.0 (#608) Bumps [@appium/test-support](https://github.com/appium/appium/tree/HEAD/packages/test-support) from 1.5.0 to 2.0.0. - [Release notes](https://github.com/appium/appium/releases) - [Changelog](https://github.com/appium/appium/blob/master/packages/test-support/CHANGELOG.md) - [Commits](https://github.com/appium/appium/commits/@appium/test-support@2.0.0/packages/test-support) --- updated-dependencies: - dependency-name: "@appium/test-support" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3b5f36435..d16783e98 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "homepage": "https://github.com/appium/WebDriverAgent#readme", "devDependencies": { "@appium/eslint-config-appium": "^6.0.0", - "@appium/test-support": "^1.0.0", + "@appium/test-support": "^2.0.0", "@babel/cli": "^7.18.10", "@babel/core": "^7.18.10", "@babel/eslint-parser": "^7.18.9", From 5372974b4677097b4d169cc5d026cee835279dd0 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 8 Sep 2022 16:06:09 +0000 Subject: [PATCH 012/240] chore(release): 4.8.5 [skip ci] ## [4.8.5](https://github.com/appium/WebDriverAgent/compare/v4.8.4...v4.8.5) (2022-09-08) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d16783e98..ef2fc962a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.8.4", + "version": "4.8.5", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From f1d37ae5b3e6641112f2396a253f25458a4e66ae Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Tue, 27 Sep 2022 22:24:03 -0700 Subject: [PATCH 013/240] fix: update the target device family (#610) --- WebDriverAgent.xcodeproj/project.pbxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WebDriverAgent.xcodeproj/project.pbxproj b/WebDriverAgent.xcodeproj/project.pbxproj index 10c68c2c7..ea7ae19e0 100644 --- a/WebDriverAgent.xcodeproj/project.pbxproj +++ b/WebDriverAgent.xcodeproj/project.pbxproj @@ -3625,6 +3625,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 3; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; WARNING_CFLAGS = ( @@ -3686,6 +3687,7 @@ PROVISIONING_PROFILE_SPECIFIER = ""; SDKROOT = appletvos; SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 3; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; WARNING_CFLAGS = ( From ccf2a795e5cec3521cb07fffc36d4b05de7a081d Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 28 Sep 2022 05:29:15 +0000 Subject: [PATCH 014/240] chore(release): 4.8.6 [skip ci] ## [4.8.6](https://github.com/appium/WebDriverAgent/compare/v4.8.5...v4.8.6) (2022-09-28) ### Bug Fixes * update the target device family ([#610](https://github.com/appium/WebDriverAgent/issues/610)) ([f1d37ae](https://github.com/appium/WebDriverAgent/commit/f1d37ae5b3e6641112f2396a253f25458a4e66ae)) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ef2fc962a..6a5dd35c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.8.5", + "version": "4.8.6", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 8984bd054b8ed037176362dd60537bf138e25896 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Wed, 28 Sep 2022 10:41:09 +0200 Subject: [PATCH 015/240] feat: Add shortcut for press-and-hold gesture with velocity (#611) --- PrivateHeaders/XCTest/XCUICoordinate.h | 6 +++ PrivateHeaders/XCTest/XCUIElement.h | 6 +++ .../Commands/FBElementCommands.m | 39 +++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/PrivateHeaders/XCTest/XCUICoordinate.h b/PrivateHeaders/XCTest/XCUICoordinate.h index 173118951..a7f7122e2 100644 --- a/PrivateHeaders/XCTest/XCUICoordinate.h +++ b/PrivateHeaders/XCTest/XCUICoordinate.h @@ -34,5 +34,11 @@ - (void)pressWithPressure:(double)arg1 duration:(double)arg2; - (void)forcePress; +// Since Xcode 12 +- (void)pressForDuration:(double)duration + thenDragToCoordinate:(XCUICoordinate *)otherCoordinate + withVelocity:(CGFloat)velocity + thenHoldForDuration:(double)holdDuration; + @end #endif diff --git a/PrivateHeaders/XCTest/XCUIElement.h b/PrivateHeaders/XCTest/XCUIElement.h index 7280b2ccf..d5dc18802 100644 --- a/PrivateHeaders/XCTest/XCUIElement.h +++ b/PrivateHeaders/XCTest/XCUIElement.h @@ -65,4 +65,10 @@ - (void)swipeDownWithVelocity:(double)arg1; - (void)swipeUpWithVelocity:(double)arg1; +// Since Xcode 12 +- (void)pressForDuration:(double)duration + thenDragToElement:(XCUIElement *)otherElement + withVelocity:(CGFloat)velocity + thenHoldForDuration:(double)holdDuration; + @end diff --git a/WebDriverAgentLib/Commands/FBElementCommands.m b/WebDriverAgentLib/Commands/FBElementCommands.m index 59ce7f7f6..9d4f3b209 100644 --- a/WebDriverAgentLib/Commands/FBElementCommands.m +++ b/WebDriverAgentLib/Commands/FBElementCommands.m @@ -85,8 +85,10 @@ + (NSArray *)routes [[FBRoute POST:@"/wda/element/:uuid/scroll"] respondWithTarget:self action:@selector(handleScroll:)], [[FBRoute POST:@"/wda/element/:uuid/scrollTo"] respondWithTarget:self action:@selector(handleScrollTo:)], [[FBRoute POST:@"/wda/element/:uuid/dragfromtoforduration"] respondWithTarget:self action:@selector(handleDrag:)], + [[FBRoute POST:@"/wda/element/:uuid/pressAndDragWithVelocity"] respondWithTarget:self action:@selector(handlePressAndDragWithVelocity:)], [[FBRoute POST:@"/wda/element/:uuid/forceTouch"] respondWithTarget:self action:@selector(handleForceTouch:)], [[FBRoute POST:@"/wda/dragfromtoforduration"] respondWithTarget:self action:@selector(handleDragCoordinate:)], + [[FBRoute POST:@"/wda/pressAndDragWithVelocity"] respondWithTarget:self action:@selector(handlePressAndDragCoordinateWithVelocity:)], [[FBRoute POST:@"/wda/tap/:uuid"] respondWithTarget:self action:@selector(handleTap:)], [[FBRoute POST:@"/wda/touchAndHold"] respondWithTarget:self action:@selector(handleTouchAndHoldCoordinate:)], [[FBRoute POST:@"/wda/doubleTap"] respondWithTarget:self action:@selector(handleDoubleTapCoordinate:)], @@ -338,6 +340,43 @@ + (NSArray *)routes return FBResponseWithOK(); } ++ (id)handlePressAndDragWithVelocity:(FBRouteRequest *)request +{ + FBElementCache *elementCache = request.session.elementCache; + XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]]; + if (![element respondsToSelector:@selector(pressForDuration:thenDragToElement:withVelocity:thenHoldForDuration:)]) { + return FBResponseWithStatus([FBCommandStatus unsupportedOperationErrorWithMessage:@"This method is only supported in Xcode 12 and above" + traceback:nil]); + } + [element pressForDuration:[request.arguments[@"pressDuration"] doubleValue] + thenDragToElement:[elementCache elementForUUID:(NSString *)request.arguments[@"toElement"]] + withVelocity:[request.arguments[@"velocity"] doubleValue] + thenHoldForDuration:[request.arguments[@"holdDuration"] doubleValue]]; + return FBResponseWithOK(); +} + ++ (id)handlePressAndDragCoordinateWithVelocity:(FBRouteRequest *)request +{ + FBSession *session = request.session; + CGPoint startPoint = CGPointMake((CGFloat)[request.arguments[@"fromX"] doubleValue], + (CGFloat)[request.arguments[@"fromY"] doubleValue]); + CGPoint endPoint = CGPointMake((CGFloat)[request.arguments[@"toX"] doubleValue], + (CGFloat)[request.arguments[@"toY"] doubleValue]); + XCUICoordinate *endCoordinate = [self.class gestureCoordinateWithCoordinate:endPoint + application:session.activeApplication]; + XCUICoordinate *startCoordinate = [self.class gestureCoordinateWithCoordinate:startPoint + application:session.activeApplication]; + if (![startCoordinate respondsToSelector:@selector(pressForDuration:thenDragToCoordinate:withVelocity:thenHoldForDuration:)]) { + return FBResponseWithStatus([FBCommandStatus unsupportedOperationErrorWithMessage:@"This method is only supported in Xcode 12 and above" + traceback:nil]); + } + [startCoordinate pressForDuration:[request.arguments[@"pressDuration"] doubleValue] + thenDragToCoordinate:endCoordinate + withVelocity:[request.arguments[@"velocity"] doubleValue] + thenHoldForDuration:[request.arguments[@"holdDuration"] doubleValue]]; + return FBResponseWithOK(); +} + + (id)handleScroll:(FBRouteRequest *)request { FBElementCache *elementCache = request.session.elementCache; From d24ab06f8b042a9ef0ed88f5c586c1ad3cb81891 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 28 Sep 2022 08:43:07 +0000 Subject: [PATCH 016/240] chore(release): 4.9.0 [skip ci] # [4.9.0](https://github.com/appium/WebDriverAgent/compare/v4.8.6...v4.9.0) (2022-09-28) ### Features * Add shortcut for press-and-hold gesture with velocity ([#611](https://github.com/appium/WebDriverAgent/issues/611)) ([8984bd0](https://github.com/appium/WebDriverAgent/commit/8984bd054b8ed037176362dd60537bf138e25896)) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6a5dd35c7..9905ae423 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.8.6", + "version": "4.9.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 6eaa9a6beed53b32659b0a9aad2c16afa7ec2d28 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Tue, 4 Oct 2022 18:41:23 +0200 Subject: [PATCH 017/240] test: Verify line break representation in the resulting xml (#612) --- .../UnitTests/Doubles/XCElementSnapshotDouble.h | 1 + .../UnitTests/Doubles/XCElementSnapshotDouble.m | 6 +----- WebDriverAgentTests/UnitTests/FBXPathTests.m | 3 ++- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.h b/WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.h index 394760791..716ba7cbb 100644 --- a/WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.h +++ b/WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.h @@ -11,4 +11,5 @@ @interface XCElementSnapshotDouble : NSObject @property (readwrite, nullable) id value; +@property (readwrite, nullable, copy) NSString *label; @end diff --git a/WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.m b/WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.m index cd25e3917..455e32227 100644 --- a/WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.m +++ b/WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.m @@ -18,6 +18,7 @@ - (id)init { self = [super init]; self->_value = @"magicValue"; + self->_label = @"testLabel"; return self; } @@ -36,11 +37,6 @@ - (NSString *)title return @"testTitle"; } -- (NSString *)label -{ - return @"testLabel"; -} - - (XCUIElementType)elementType { return XCUIElementTypeOther; diff --git a/WebDriverAgentTests/UnitTests/FBXPathTests.m b/WebDriverAgentTests/UnitTests/FBXPathTests.m index a78fe72a7..a04dab23e 100644 --- a/WebDriverAgentTests/UnitTests/FBXPathTests.m +++ b/WebDriverAgentTests/UnitTests/FBXPathTests.m @@ -83,12 +83,13 @@ - (void)testXPathPresentationBasedOnQueryMatchingAllAttributes { XCElementSnapshotDouble *snapshot = [XCElementSnapshotDouble new]; snapshot.value = @"йоло<>&\""; + snapshot.label = @"a\nb"; id element = (id)[FBXCElementSnapshotWrapper ensureWrapped:(id)snapshot]; NSString *resultXml = [self xmlStringWithElement:element xpathQuery:[NSString stringWithFormat:@"//%@[@*]", element.wdType] excludingAttributes:@[@"visible"]]; NSString *expectedXml = [NSString stringWithFormat:@"\n<%@ type=\"%@\" value=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" private_indexPath=\"top\"/>\n", - element.wdType, element.wdType, @"йоло<>&"", element.wdName, element.wdLabel, element.wdEnabled ? @"true" : @"false", element.wdVisible ? @"true" : @"false", element.wdAccessible ? @"true" : @"false", element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex]; + element.wdType, element.wdType, @"йоло<>&"", element.wdName, @"a b", element.wdEnabled ? @"true" : @"false", element.wdVisible ? @"true" : @"false", element.wdAccessible ? @"true" : @"false", element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex]; XCTAssertTrue([resultXml isEqualToString:expectedXml]); } From b7493f290f1d4acba01ddabb7ec5d6a8821274df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Oct 2022 14:30:12 +0200 Subject: [PATCH 018/240] chore(deps): bump axios from 0.27.2 to 1.0.0 (#613) Bumps [axios](https://github.com/axios/axios) from 0.27.2 to 1.0.0. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v0.27.2...v1.0.0) --- updated-dependencies: - dependency-name: axios dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9905ae423..1fb43196f 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "appium-ios-simulator": "^4.0.0", "async-lock": "^1.0.0", "asyncbox": "^2.5.3", - "axios": "^0.x", + "axios": "^1.x", "bluebird": "^3.5.5", "lodash": "^4.17.11", "node-simctl": "^7.0.1", From 54b002353f7b6af00d37a52ccae66caa530bc707 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 5 Oct 2022 12:34:12 +0000 Subject: [PATCH 019/240] chore(release): 4.9.1 [skip ci] ## [4.9.1](https://github.com/appium/WebDriverAgent/compare/v4.9.0...v4.9.1) (2022-10-05) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1fb43196f..da5fa6f34 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.9.0", + "version": "4.9.1", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 7db608e05e08a4a86b8c4bd59992503a46cfc229 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Mon, 10 Oct 2022 10:26:38 -0700 Subject: [PATCH 020/240] ci: build ios/tvos for generic devices with no code sign (#614) * ci: build ios/tvos for generic devices with no code sign * ci: add uploading artifacts for testing --- .github/workflows/wda-package.yml | 60 +++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 .github/workflows/wda-package.yml diff --git a/.github/workflows/wda-package.yml b/.github/workflows/wda-package.yml new file mode 100644 index 000000000..997acae1a --- /dev/null +++ b/.github/workflows/wda-package.yml @@ -0,0 +1,60 @@ +name: Building WebDriverAgent + +on: + workflow_dispatch: + pull_request: # for testing, will remove this after merging this PR once + +jobs: + build: + name: Build WDA for real iOS and tvOS devices + runs-on: macos-11 + + env: + XCODE_VERSION: 13.2.1 + ZIP_PKG_NAME_IOS: "WebDriverAgentRunner-Runner.zip" + PKG_PATH_IOS: "appium_wda_ios" + ZIP_PKG_NAME_TVOS: "WebDriverAgentRunner_tvOS-Runner.zip" + PKG_PATH_TVOS: "appium_wda_tvos" + + steps: + - name: Checkout + uses: actions/checkout@v3 + - uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: "${{ env.XCODE_VERSION }}" + - name: Build iOS + run: | + xcodebuild clean build-for-testing \ + -project WebDriverAgent.xcodeproj \ + -derivedDataPath $PKG_PATH_IOS \ + -scheme WebDriverAgentRunner \ + -destination generic/platform=iOS \ + CODE_SIGNING_ALLOWED=NO + - name: Creating a zip of WebDriverAgentRunner-Runner.app for iOS + run: | + pushd appium_wda_ios/Build/Products/Debug-iphoneos + zip -r $ZIP_PKG_NAME_IOS WebDriverAgentRunner-Runner.app + popd + mv $PKG_PATH_IOS/Build/Products/Debug-iphoneos/$ZIP_PKG_NAME_IOS ./ + - name: Build tvOS + run: | + xcodebuild clean build-for-testing \ + -project WebDriverAgent.xcodeproj \ + -derivedDataPath $PKG_PATH_TVOS \ + -scheme WebDriverAgentRunner_tvOS \ + -destination generic/platform=tvOS \ + CODE_SIGNING_ALLOWED=NO + - name: Creating a zip of WebDriverAgentRunner-Runner.app for tvOS + run: | + pushd appium_wda_tvos/Build/Products/Debug-appletvos + zip -r $ZIP_PKG_NAME_TVOS WebDriverAgentRunner_tvOS-Runner.app + popd + mv $PKG_PATH_TVOS/Build/Products/Debug-appletvos/$ZIP_PKG_NAME_TVOS ./ + - name: Upload the built generic app package for iOS + uses: actions/upload-artifact@v3.1.0 + with: + path: "${{ env.ZIP_PKG_NAME_IOS }}" + - name: Upload the built generic app package for tvOS + uses: actions/upload-artifact@v3.1.0 + with: + path: "${{ env.ZIP_PKG_NAME_TVOS }}" From b612de0c7ac8dd7bb9cb8850d547cf342a323072 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Mon, 10 Oct 2022 10:28:18 -0700 Subject: [PATCH 021/240] ci: run only by manual for WDA creation for now (#617) --- .github/workflows/wda-package.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/wda-package.yml b/.github/workflows/wda-package.yml index 997acae1a..767d8e17a 100644 --- a/.github/workflows/wda-package.yml +++ b/.github/workflows/wda-package.yml @@ -2,7 +2,6 @@ name: Building WebDriverAgent on: workflow_dispatch: - pull_request: # for testing, will remove this after merging this PR once jobs: build: From 9225d18986bee06d9799ab3d7cc0cf2d34af1888 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Mon, 10 Oct 2022 19:41:56 +0200 Subject: [PATCH 022/240] fix: Use stable picker instance while selecting values (#616) --- .../Categories/XCUIElement+FBPickerWheel.m | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBPickerWheel.m b/WebDriverAgentLib/Categories/XCUIElement+FBPickerWheel.m index 7740dbc6b..adce016ff 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBPickerWheel.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBPickerWheel.m @@ -16,6 +16,7 @@ #import "XCUICoordinate.h" #import "XCUICoordinate+FBFix.h" #import "XCUIElement+FBCaching.h" +#import "XCUIElement+FBResolve.h" #if !TARGET_OS_TV @implementation XCUIElement (FBPickerWheel) @@ -40,6 +41,13 @@ - (BOOL)fb_scrollWithOffset:(CGFloat)relativeHeightOffset error:(NSError **)erro } } ]; + // If picker value is reflected in its accessiblity id + // then fetching of the next snapshot may fail with StaleElementReferenceError + // because we bound elements by their accessbility ids by default. + // Fetching stable instance of an element allows it to be bounded to the + // unique element identifier (UID), so it could be found next time even if its + // id is different from the initial one. See https://github.com/appium/appium/issues/17569 + XCUIElement *stableInstance = self.fb_stableInstance; if (![self.application fb_performAppiumTouchActions:gesture elementCache:nil error:error]) { return NO; } @@ -47,7 +55,7 @@ - (BOOL)fb_scrollWithOffset:(CGFloat)relativeHeightOffset error:(NSError **)erro timeout:VALUE_CHANGE_TIMEOUT] timeoutErrorMessage:[NSString stringWithFormat:@"Picker wheel value has not been changed after %@ seconds timeout", @(VALUE_CHANGE_TIMEOUT)]] spinUntilTrue:^BOOL{ - return ![self.fb_takeSnapshot.value isEqualToString:previousValue]; + return ![stableInstance.value isEqualToString:previousValue]; } error:error]; } From c7b992366454cdc099842fde0c1b9c1c85d88719 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 10 Oct 2022 17:43:42 +0000 Subject: [PATCH 023/240] chore(release): 4.9.2 [skip ci] ## [4.9.2](https://github.com/appium/WebDriverAgent/compare/v4.9.1...v4.9.2) (2022-10-10) ### Bug Fixes * Use stable picker instance while selecting values ([#616](https://github.com/appium/WebDriverAgent/issues/616)) ([9225d18](https://github.com/appium/WebDriverAgent/commit/9225d18986bee06d9799ab3d7cc0cf2d34af1888)) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index da5fa6f34..f8510fdbc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.9.1", + "version": "4.9.2", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From ab9b59ea8c10dd95782a7a03648f8159ed9feed7 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Mon, 10 Oct 2022 22:35:04 -0700 Subject: [PATCH 024/240] ci: add building WDA packages tasks in the release task (#615) * Update publish.js.yml * Update publish.js.yml * Update publish.js.yml --- .github/workflows/publish.js.yml | 55 +++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.js.yml b/.github/workflows/publish.js.yml index eb0464bea..a1dd9c93e 100644 --- a/.github/workflows/publish.js.yml +++ b/.github/workflows/publish.js.yml @@ -10,13 +10,28 @@ on: jobs: build: - runs-on: macos-latest + # To specify Xcode version + runs-on: macos-11 + + env: + XCODE_VERSION: 13.2.1 + ZIP_PKG_NAME_IOS: "WebDriverAgentRunner-Runner.zip" + PKG_PATH_IOS: "appium_wda_ios" + ZIP_PKG_NAME_TVOS: "WebDriverAgentRunner_tvOS-Runner.zip" + PKG_PATH_TVOS: "appium_wda_tvos" + steps: + # setup - uses: actions/checkout@v2 - name: Use Node.js 18.x uses: actions/setup-node@v1 with: node-version: 18.x + - uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: "${{ env.XCODE_VERSION }}" + + # nodejs - run: | npm install -g appium@next npm install --no-package-lock @@ -25,8 +40,46 @@ jobs: name: Run build - run: npm run test name: Run test + + # building WDA packages + - name: Build iOS + run: | + xcodebuild clean build-for-testing \ + -project WebDriverAgent.xcodeproj \ + -derivedDataPath $PKG_PATH_IOS \ + -scheme WebDriverAgentRunner \ + -destination generic/platform=iOS \ + CODE_SIGNING_ALLOWED=NO + - name: Creating a zip of WebDriverAgentRunner-Runner.app for iOS + run: | + pushd appium_wda_ios/Build/Products/Debug-iphoneos + zip -r $ZIP_PKG_NAME_IOS WebDriverAgentRunner-Runner.app + popd + mv $PKG_PATH_IOS/Build/Products/Debug-iphoneos/$ZIP_PKG_NAME_IOS ./ + - name: Build tvOS + run: | + xcodebuild clean build-for-testing \ + -project WebDriverAgent.xcodeproj \ + -derivedDataPath $PKG_PATH_TVOS \ + -scheme WebDriverAgentRunner_tvOS \ + -destination generic/platform=tvOS \ + CODE_SIGNING_ALLOWED=NO + - name: Creating a zip of WebDriverAgentRunner-Runner.app for tvOS + run: | + pushd appium_wda_tvos/Build/Products/Debug-appletvos + zip -r $ZIP_PKG_NAME_TVOS WebDriverAgentRunner_tvOS-Runner.app + popd + mv $PKG_PATH_TVOS/Build/Products/Debug-appletvos/$ZIP_PKG_NAME_TVOS ./ + + # release tasks - run: npx semantic-release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} name: Release + - name: Upload Release assets + uses: softprops/action-gh-release@v1 + with: + files: | + "${{ env.ZIP_PKG_NAME_IOS }}" + "${{ env.ZIP_PKG_NAME_TVOS }}" From dfe4e94ad4de6c71a3a87dde84c72e4e4c771c9e Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Mon, 10 Oct 2022 22:36:08 -0700 Subject: [PATCH 025/240] chore: dummy commit to test a release task (#618) --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 0b9e0e488..3b6fb3bfe 100644 --- a/README.md +++ b/README.md @@ -51,4 +51,3 @@ projects has been integrated directly in the WebDriverAgent source tree. You can find the source files and their licenses in the `WebDriverAgentLib/Vendor` directory. Have fun! - From 6b12c272b954284645ee206272ec0d373bc63783 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 11 Oct 2022 05:44:55 +0000 Subject: [PATCH 026/240] chore(release): 4.9.3 [skip ci] ## [4.9.3](https://github.com/appium/WebDriverAgent/compare/v4.9.2...v4.9.3) (2022-10-11) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f8510fdbc..d9b48c183 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.9.2", + "version": "4.9.3", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From f579bd94f9ee2a665a54a376c198cc057e241344 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Mon, 10 Oct 2022 22:59:42 -0700 Subject: [PATCH 027/240] chore: update the release config (#619) --- .github/workflows/publish.js.yml | 7 +------ .releaserc | 6 +++++- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish.js.yml b/.github/workflows/publish.js.yml index a1dd9c93e..3585772e5 100644 --- a/.github/workflows/publish.js.yml +++ b/.github/workflows/publish.js.yml @@ -77,9 +77,4 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} name: Release - - name: Upload Release assets - uses: softprops/action-gh-release@v1 - with: - files: | - "${{ env.ZIP_PKG_NAME_IOS }}" - "${{ env.ZIP_PKG_NAME_TVOS }}" + diff --git a/.releaserc b/.releaserc index 997c559d8..275bf7e24 100644 --- a/.releaserc +++ b/.releaserc @@ -13,6 +13,10 @@ "assets": ["docs", "package.json"], "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" }], - "@semantic-release/github", + ["@semantic-release/github", { + "assets": [ + "WebDriverAgentRunner-Runner.zip", + "WebDriverAgentRunner_tvOS-Runner.zip" + ]}], ] } From 1feddd0a17d3741f15af294e3f24622a12d6e42e Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 11 Oct 2022 06:08:59 +0000 Subject: [PATCH 028/240] chore(release): 4.9.4 [skip ci] ## [4.9.4](https://github.com/appium/WebDriverAgent/compare/v4.9.3...v4.9.4) (2022-10-11) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d9b48c183..5ea0b7941 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.9.3", + "version": "4.9.4", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From b93f4a2b51516f37ac6cd3586204d5a7c1f7f2c8 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sun, 23 Oct 2022 10:17:32 -0700 Subject: [PATCH 029/240] ci: remove unused job (#626) --- ci-jobs/build.yml | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 ci-jobs/build.yml diff --git a/ci-jobs/build.yml b/ci-jobs/build.yml deleted file mode 100644 index fc50e2085..000000000 --- a/ci-jobs/build.yml +++ /dev/null @@ -1,14 +0,0 @@ -jobs: - - job: create_github_release - steps: - - task: GithubRelease@0 - inputs: - action: create - githubConnection: appiumbot - repositoryName: appium/WebDriverAgent - addChangeLog: false - - template: ./templates/build.yml - parameters: - vmImage: 'macOS-11' - name: 'macOS_11' - excludeXcode: '10.3.0,10.3,11.3,11.4,12' From 13f497e2ce3851a940015c462c746b3fbbd27cef Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sun, 23 Oct 2022 10:18:12 -0700 Subject: [PATCH 030/240] feat: return the device window size without session (#625) --- WebDriverAgentLib/Commands/FBElementCommands.m | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/WebDriverAgentLib/Commands/FBElementCommands.m b/WebDriverAgentLib/Commands/FBElementCommands.m index 9d4f3b209..7ef157073 100644 --- a/WebDriverAgentLib/Commands/FBElementCommands.m +++ b/WebDriverAgentLib/Commands/FBElementCommands.m @@ -55,6 +55,7 @@ + (NSArray *)routes return @[ [[FBRoute GET:@"/window/size"] respondWithTarget:self action:@selector(handleGetWindowSize:)], + [[FBRoute GET:@"/window/size"].withoutSession respondWithTarget:self action:@selector(handleGetWindowSize:)], [[FBRoute GET:@"/element/:uuid/enabled"] respondWithTarget:self action:@selector(handleGetEnabled:)], [[FBRoute GET:@"/element/:uuid/rect"] respondWithTarget:self action:@selector(handleGetRect:)], [[FBRoute GET:@"/element/:uuid/attribute/:name"] respondWithTarget:self action:@selector(handleGetAttribute:)], @@ -571,11 +572,13 @@ + (NSArray *)routes + (id)handleGetWindowSize:(FBRouteRequest *)request { + XCUIApplication *app = request.session.activeApplication ?: FBApplication.fb_activeApplication; + #if TARGET_OS_TV - CGSize screenSize = request.session.activeApplication.frame.size; + CGSize screenSize = app.frame.size; #else - CGRect frame = request.session.activeApplication.wdFrame; - CGSize screenSize = FBAdjustDimensionsForApplication(frame.size, request.session.activeApplication.interfaceOrientation); + CGRect frame = app.wdFrame; + CGSize screenSize = FBAdjustDimensionsForApplication(frame.size, app.interfaceOrientation); #endif return FBResponseWithObject(@{ @"width": @(screenSize.width), From 051fe6c633c9a7a510ff9006d95f14ab5352bdf7 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 23 Oct 2022 17:36:06 +0000 Subject: [PATCH 031/240] chore(release): 4.10.0 [skip ci] # [4.10.0](https://github.com/appium/WebDriverAgent/compare/v4.9.4...v4.10.0) (2022-10-23) ### Features * return the device window size without session ([#625](https://github.com/appium/WebDriverAgent/issues/625)) ([13f497e](https://github.com/appium/WebDriverAgent/commit/13f497e2ce3851a940015c462c746b3fbbd27cef)) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5ea0b7941..5dc8d1183 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.9.4", + "version": "4.10.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 5d1d76b568075b59ccd41da17a86d172f2c85dbe Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Tue, 25 Oct 2022 17:47:32 +0200 Subject: [PATCH 032/240] fix: Enforce usage of base64 RFC4648 encoder (#627) --- WebDriverAgentLib/Commands/FBCustomCommands.m | 2 +- WebDriverAgentLib/Commands/FBElementCommands.m | 2 +- WebDriverAgentLib/Commands/FBScreenshotCommands.m | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WebDriverAgentLib/Commands/FBCustomCommands.m b/WebDriverAgentLib/Commands/FBCustomCommands.m index 0ea527dae..2f4f8a6cb 100644 --- a/WebDriverAgentLib/Commands/FBCustomCommands.m +++ b/WebDriverAgentLib/Commands/FBCustomCommands.m @@ -226,7 +226,7 @@ + (NSDictionary *)processArguments:(XCUIApplication *)app if (nil == result) { return FBResponseWithUnknownError(error); } - return FBResponseWithObject([result base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]); + return FBResponseWithObject([result base64EncodedStringWithOptions:0]); } + (id)handleGetBatteryInfo:(FBRouteRequest *)request diff --git a/WebDriverAgentLib/Commands/FBElementCommands.m b/WebDriverAgentLib/Commands/FBElementCommands.m index 7ef157073..bb175e59e 100644 --- a/WebDriverAgentLib/Commands/FBElementCommands.m +++ b/WebDriverAgentLib/Commands/FBElementCommands.m @@ -596,7 +596,7 @@ + (NSArray *)routes return FBResponseWithStatus([FBCommandStatus unableToCaptureScreenErrorWithMessage:error.description traceback:nil]); } - NSString *screenshot = [screenshotData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; + NSString *screenshot = [screenshotData base64EncodedStringWithOptions:0]; return FBResponseWithObject(screenshot); } diff --git a/WebDriverAgentLib/Commands/FBScreenshotCommands.m b/WebDriverAgentLib/Commands/FBScreenshotCommands.m index 71dcf6ec1..0b6e42427 100644 --- a/WebDriverAgentLib/Commands/FBScreenshotCommands.m +++ b/WebDriverAgentLib/Commands/FBScreenshotCommands.m @@ -34,7 +34,7 @@ + (NSArray *)routes if (nil == screenshotData) { return FBResponseWithStatus([FBCommandStatus unableToCaptureScreenErrorWithMessage:error.description traceback:nil]); } - NSString *screenshot = [screenshotData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; + NSString *screenshot = [screenshotData base64EncodedStringWithOptions:0]; return FBResponseWithObject(screenshot); } From 404847ae8b2c8d55bdc2bf1ced43bc4e2a7dbf40 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 25 Oct 2022 15:56:30 +0000 Subject: [PATCH 033/240] chore(release): 4.10.1 [skip ci] ## [4.10.1](https://github.com/appium/WebDriverAgent/compare/v4.10.0...v4.10.1) (2022-10-25) ### Bug Fixes * Enforce usage of base64 RFC4648 encoder ([#627](https://github.com/appium/WebDriverAgent/issues/627)) ([5d1d76b](https://github.com/appium/WebDriverAgent/commit/5d1d76b568075b59ccd41da17a86d172f2c85dbe)) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5dc8d1183..91b1ae34e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.0", + "version": "4.10.1", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 674fbe9b45d841d2bcf0749d797a88ea9ce00a04 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Wed, 26 Oct 2022 19:44:58 +0200 Subject: [PATCH 034/240] ci: Update node versions retrieval algorithm --- .github/workflows/unit-test.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 818f00824..da5e37c93 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -12,10 +12,13 @@ jobs: - name: Generate Node.js versions matrix id: generate-matrix run: | - current_lts=$(curl -s https://nodejs.org/en/ | grep -E -o 'Download [0-9.]+ LTS' | grep -E -o '([0-9]+)' | head -n 1) - previous_lts=$(( current_lts - 2 )) - next_lts=$(( current_lts + 2 )) - VERSIONS="[$previous_lts, $current_lts, $next_lts]" + sudo apt-get install -y lynx + lynx -dump https://endoflife.date/nodejs | grep -E -o '[0-9]+ \(LTS\)' | grep -E -o '([0-9]+)' > eol.list + cat eol.list + lts1=$(cat eol.list | head -1) + lts2=$(cat eol.list | head -2 | tail -1) + lts3=$(cat eol.list | head -3 | tail -1) + VERSIONS="[$lts1, $lts2, $lts3]" echo ::set-output name=versions::${VERSIONS} test: From 915f5486e8d8477342d2aeb39aeadd5379a3aa7c Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sun, 6 Nov 2022 01:05:59 -0700 Subject: [PATCH 035/240] chore: add changelog with @semantic-release/changelog (#628) * chore: add changelog with @semantic-release/changelog * Update package.json --- .releaserc | 8 +++++--- CHANGELOG.md | 0 package.json | 4 +++- 3 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 CHANGELOG.md diff --git a/.releaserc b/.releaserc index 275bf7e24..e6cf22bff 100644 --- a/.releaserc +++ b/.releaserc @@ -4,13 +4,15 @@ "preset": "angular", "releaseRules": [ {"type": "chore", "release": "patch"} - ] }], - "@semantic-release/npm", "@semantic-release/release-notes-generator", + ["@semantic-release/changelog", { + "changelogFile": "CHANGELOG.md" + }], + "@semantic-release/npm", ["@semantic-release/git", { - "assets": ["docs", "package.json"], + "assets": ["docs", "package.json", "CHANGELOG.md"], "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" }], ["@semantic-release/github", { diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..e69de29bb diff --git a/package.json b/package.json index 91b1ae34e..b7d178d5f 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "@babel/plugin-transform-runtime": "^7.18.10", "@babel/preset-env": "^7.18.10", "@babel/register": "^7.18.9", + "@semantic-release/changelog": "^6.0.1", "@semantic-release/git": "^10.0.1", "babel-plugin-source-map-support": "^2.2.0", "appium-xcode": "^4.0.1", @@ -109,6 +110,7 @@ "WebDriverAgentRunner", "WebDriverAgentTests", "XCTWebDriverAgentLib", - "WebDriverAgentRunner-Runner.app.zip" + "WebDriverAgentRunner-Runner.app.zip", + "CHANGELOG.md" ] } From b71f8b5703e1c7f37640e7d7ea2aaa6610e413c2 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 6 Nov 2022 09:43:36 +0000 Subject: [PATCH 036/240] chore(release): 4.10.2 [skip ci] ## [4.10.2](https://github.com/appium/WebDriverAgent/compare/v4.10.1...v4.10.2) (2022-11-06) --- CHANGELOG.md | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e69de29bb..0c981e888 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -0,0 +1 @@ +## [4.10.2](https://github.com/appium/WebDriverAgent/compare/v4.10.1...v4.10.2) (2022-11-06) diff --git a/package.json b/package.json index b7d178d5f..b4a254b6e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.1", + "version": "4.10.2", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From b08183d4712c13789a48a692d9847accedc241e4 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Tue, 8 Nov 2022 05:33:49 +0100 Subject: [PATCH 037/240] refactor: Reset session-specific settings on its startup (#629) --- .../Commands/FBSessionCommands.m | 11 ++-- WebDriverAgentLib/Utilities/FBCapabilities.h | 2 +- WebDriverAgentLib/Utilities/FBCapabilities.m | 2 +- WebDriverAgentLib/Utilities/FBConfiguration.h | 5 ++ WebDriverAgentLib/Utilities/FBConfiguration.m | 64 +++++++++++++------ 5 files changed, 57 insertions(+), 27 deletions(-) diff --git a/WebDriverAgentLib/Commands/FBSessionCommands.m b/WebDriverAgentLib/Commands/FBSessionCommands.m index 243cf2327..3100ba710 100644 --- a/WebDriverAgentLib/Commands/FBSessionCommands.m +++ b/WebDriverAgentLib/Commands/FBSessionCommands.m @@ -88,6 +88,8 @@ + (NSArray *)routes if (nil == (capabilities = FBParseCapabilities((NSDictionary *)request.arguments[@"capabilities"], &error))) { return FBResponseWithStatus([FBCommandStatus sessionNotCreatedError:error.description traceback:nil]); } + + [FBConfiguration resetSessionSettings]; [FBConfiguration setShouldUseTestManagerForVisibilityDetection:[capabilities[FB_CAP_USE_TEST_MANAGER_FOR_VISIBLITY_DETECTION] boolValue]]; if (capabilities[FB_SETTING_USE_COMPACT_RESPONSES]) { [FBConfiguration setShouldUseCompactResponses:[capabilities[FB_SETTING_USE_COMPACT_RESPONSES] boolValue]]; @@ -96,8 +98,8 @@ + (NSArray *)routes if (elementResponseAttributes) { [FBConfiguration setElementResponseAttributes:elementResponseAttributes]; } - if (capabilities[FB_CAP_MAX_TYPING_FREQUNCY]) { - [FBConfiguration setMaxTypingFrequency:[capabilities[FB_CAP_MAX_TYPING_FREQUNCY] unsignedIntegerValue]]; + if (capabilities[FB_CAP_MAX_TYPING_FREQUENCY]) { + [FBConfiguration setMaxTypingFrequency:[capabilities[FB_CAP_MAX_TYPING_FREQUENCY] unsignedIntegerValue]]; } if (capabilities[FB_CAP_USE_SINGLETON_TEST_MANAGER]) { [FBConfiguration setShouldUseSingletonTestManager:[capabilities[FB_CAP_USE_SINGLETON_TEST_MANAGER] boolValue]]; @@ -380,10 +382,9 @@ + (NSArray *)routes NSError *error; if (![FBConfiguration setScreenshotOrientation:(NSString *)[settings objectForKey:FB_SETTING_SCREENSHOT_ORIENTATION] error:&error]) { - return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:error.description traceback:nil]); + return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:error.description + traceback:nil]); } - - } #endif diff --git a/WebDriverAgentLib/Utilities/FBCapabilities.h b/WebDriverAgentLib/Utilities/FBCapabilities.h index 76b9f1203..116c408df 100644 --- a/WebDriverAgentLib/Utilities/FBCapabilities.h +++ b/WebDriverAgentLib/Utilities/FBCapabilities.h @@ -10,7 +10,7 @@ #import extern NSString* const FB_CAP_USE_TEST_MANAGER_FOR_VISIBLITY_DETECTION; -extern NSString* const FB_CAP_MAX_TYPING_FREQUNCY; +extern NSString* const FB_CAP_MAX_TYPING_FREQUENCY; extern NSString* const FB_CAP_USE_SINGLETON_TEST_MANAGER; extern NSString* const FB_CAP_DISABLE_AUTOMATIC_SCREENSHOTS; extern NSString* const FB_CAP_SHOULD_TERMINATE_APP; diff --git a/WebDriverAgentLib/Utilities/FBCapabilities.m b/WebDriverAgentLib/Utilities/FBCapabilities.m index 0cef52273..cafd0f168 100644 --- a/WebDriverAgentLib/Utilities/FBCapabilities.m +++ b/WebDriverAgentLib/Utilities/FBCapabilities.m @@ -10,7 +10,7 @@ #import "FBCapabilities.h" NSString* const FB_CAP_USE_TEST_MANAGER_FOR_VISIBLITY_DETECTION = @"shouldUseTestManagerForVisibilityDetection"; -NSString* const FB_CAP_MAX_TYPING_FREQUNCY = @"maxTypingFrequency"; +NSString* const FB_CAP_MAX_TYPING_FREQUENCY = @"maxTypingFrequency"; NSString* const FB_CAP_USE_SINGLETON_TEST_MANAGER = @"shouldUseSingletonTestManager"; NSString* const FB_CAP_DISABLE_AUTOMATIC_SCREENSHOTS = @"disableAutomaticScreenshots"; NSString* const FB_CAP_SHOULD_TERMINATE_APP = @"shouldTerminateApp"; diff --git a/WebDriverAgentLib/Utilities/FBConfiguration.h b/WebDriverAgentLib/Utilities/FBConfiguration.h index 8490ea7de..72c01d9c2 100644 --- a/WebDriverAgentLib/Utilities/FBConfiguration.h +++ b/WebDriverAgentLib/Utilities/FBConfiguration.h @@ -301,6 +301,11 @@ typedef NS_ENUM(NSInteger, FBConfigurationKeyboardPreference) { #endif +/** + Resets all session-specific settings to their default values + */ ++ (void)resetSessionSettings; + @end NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Utilities/FBConfiguration.m b/WebDriverAgentLib/Utilities/FBConfiguration.m index 4e374a3d0..d34d7d53d 100644 --- a/WebDriverAgentLib/Utilities/FBConfiguration.m +++ b/WebDriverAgentLib/Utilities/FBConfiguration.m @@ -30,30 +30,30 @@ static BOOL FBShouldUseTestManagerForVisibilityDetection = NO; static BOOL FBShouldUseSingletonTestManager = YES; -static BOOL FBShouldUseCompactResponses = YES; -static BOOL FBShouldTerminateApp = YES; -static NSString *FBElementResponseAttributes = @"type,label"; -static NSUInteger FBMaxTypingFrequency = 60; +NSString *const FBSnapshotMaxDepthKey = @"maxDepth"; + +static NSUInteger FBMjpegScalingFactor = 100; static NSUInteger FBMjpegServerScreenshotQuality = 25; static NSUInteger FBMjpegServerFramerate = 10; -static NSUInteger FBScreenshotQuality = 1; -static NSUInteger FBMjpegScalingFactor = 100; -static NSTimeInterval FBCustomSnapshotTimeout = 15.; -static BOOL FBShouldUseFirstMatch = NO; -static BOOL FBShouldBoundElementsByIndex = NO; -// This is diabled by default because enabling it prevents the accessbility snapshot to be taken -// (it always errors with kxIllegalArgument error) -static BOOL FBIncludeNonModalElements = NO; -static NSString *FBAcceptAlertButtonSelector = @""; -static NSString *FBDismissAlertButtonSelector = @""; -NSString *const FBSnapshotMaxDepthKey = @"maxDepth"; -static NSMutableDictionary *FBSnapshotRequestParameters; -static NSTimeInterval FBWaitForIdleTimeout = 10.; -static NSTimeInterval FBAnimationCoolOffTimeout = 2.; +// Session-specific settings +static BOOL FBShouldTerminateApp; +static NSUInteger FBMaxTypingFrequency; +static NSUInteger FBScreenshotQuality; +static NSTimeInterval FBCustomSnapshotTimeout; +static BOOL FBShouldUseFirstMatch; +static BOOL FBShouldBoundElementsByIndex; +static BOOL FBIncludeNonModalElements; +static NSString *FBAcceptAlertButtonSelector; +static NSString *FBDismissAlertButtonSelector; +static NSTimeInterval FBWaitForIdleTimeout; +static NSTimeInterval FBAnimationCoolOffTimeout; +static BOOL FBShouldUseCompactResponses; +static NSString *FBElementResponseAttributes; #if !TARGET_OS_TV -static UIInterfaceOrientation FBScreenshotOrientation = UIInterfaceOrientationUnknown; +static UIInterfaceOrientation FBScreenshotOrientation; #endif +static NSMutableDictionary *FBSnapshotRequestParameters; @implementation FBConfiguration @@ -62,9 +62,9 @@ + (void)initialize FBSnapshotRequestParameters = [NSMutableDictionary dictionaryWithDictionary:@{ @"maxArrayCount": @INT_MAX, @"maxChildren": @INT_MAX, - FBSnapshotMaxDepthKey: @50, // 50 should be enough for the majority of the cases. The performance is acceptable for values up to 100. @"traverseFromParentsToChildren": @1 }]; + [FBConfiguration resetSessionSettings]; } #pragma mark Public @@ -450,6 +450,30 @@ + (NSString *)humanReadableScreenshotOrientation } #endif ++ (void)resetSessionSettings +{ + FBShouldTerminateApp = YES; + FBShouldUseCompactResponses = YES; + FBElementResponseAttributes = @"type,label"; + FBMaxTypingFrequency = 60; + FBScreenshotQuality = 1; + FBCustomSnapshotTimeout = 15.; + FBShouldUseFirstMatch = NO; + FBShouldBoundElementsByIndex = NO; + // This is diabled by default because enabling it prevents the accessbility snapshot to be taken + // (it always errors with kxIllegalArgument error) + FBIncludeNonModalElements = NO; + FBAcceptAlertButtonSelector = @""; + FBDismissAlertButtonSelector = @""; + FBWaitForIdleTimeout = 10.; + FBAnimationCoolOffTimeout = 2.; + // 50 should be enough for the majority of the cases. The performance is acceptable for values up to 100. + FBSnapshotRequestParameters[FBSnapshotMaxDepthKey] = @50; +#if !TARGET_OS_TV + FBScreenshotOrientation = UIInterfaceOrientationUnknown; +#endif +} + #pragma mark Private + (FBConfigurationKeyboardPreference)keyboardsPreference:(nonnull NSString *)key From c17f16b815795823502f676cf2e186960ed02fed Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Tue, 22 Nov 2022 10:55:57 +0100 Subject: [PATCH 038/240] chore: Cache results of reflection calls to protocols (#630) --- .../XCUIElement+FBWebDriverAttributes.m | 16 +++++++++------- WebDriverAgentLib/Routing/FBElementUtils.h | 8 ++++++++ WebDriverAgentLib/Routing/FBElementUtils.m | 17 ++++++++++++++++- .../Routing/FBXCElementSnapshotWrapper.m | 14 ++++++++++---- 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m b/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m index 024563dcc..71a17b636 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m @@ -9,8 +9,6 @@ #import "XCUIElement+FBWebDriverAttributes.h" -#import - #import "FBElementTypeTransformer.h" #import "FBLogger.h" #import "FBMacros.h" @@ -58,11 +56,15 @@ - (id)fb_valueForWDAttributeName:(NSString *)name - (id)forwardingTargetForSelector:(SEL)aSelector { - struct objc_method_description descr = protocol_getMethodDescription(@protocol(FBElement), aSelector, YES, YES); - SEL webDriverAttributesSelector = descr.name; - return nil == webDriverAttributesSelector - ? nil - : [FBXCElementSnapshotWrapper ensureWrapped:[self fb_snapshotForAttributeName:NSStringFromSelector(webDriverAttributesSelector)]]; + static dispatch_once_t onceToken; + static NSSet *fbElementAttributeNames; + dispatch_once(&onceToken, ^{ + fbElementAttributeNames = [FBElementUtils selectorNamesWithProtocol:@protocol(FBElement)]; + }); + NSString* attributeName = NSStringFromSelector(aSelector); + return [fbElementAttributeNames containsObject:attributeName] + ? [FBXCElementSnapshotWrapper ensureWrapped:[self fb_snapshotForAttributeName:attributeName]] + : nil; } @end diff --git a/WebDriverAgentLib/Routing/FBElementUtils.h b/WebDriverAgentLib/Routing/FBElementUtils.h index 84de384ae..0c7209829 100644 --- a/WebDriverAgentLib/Routing/FBElementUtils.h +++ b/WebDriverAgentLib/Routing/FBElementUtils.h @@ -64,6 +64,14 @@ extern NSString *const FBUnknownAttributeException; */ + (unsigned long long)idWithAccessibilityElement:(id)element; +/** + Retrieves the list of required insatnce methods of the given protocol + + @param protocol target protocol reference + @return set of selector names + */ ++ (NSSet *)selectorNamesWithProtocol:(Protocol *)protocol; + @end NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Routing/FBElementUtils.m b/WebDriverAgentLib/Routing/FBElementUtils.m index d97ee1688..5a98b85fc 100644 --- a/WebDriverAgentLib/Routing/FBElementUtils.m +++ b/WebDriverAgentLib/Routing/FBElementUtils.m @@ -20,11 +20,26 @@ @implementation FBElementUtils ++ (NSSet *)selectorNamesWithProtocol:(Protocol *)protocol +{ + unsigned int count; + struct objc_method_description *methods = protocol_copyMethodDescriptionList(protocol, YES, YES, &count); + NSMutableSet *result = [NSMutableSet set]; + for (unsigned int i = 0; i < count; i++) { + SEL sel = methods[i].name; + if (nil != sel) { + [result addObject:NSStringFromSelector(sel)]; + } + } + free(methods); + return result.copy; +} + + (NSString *)wdAttributeNameForAttributeName:(NSString *)name { NSAssert(name.length > 0, @"Attribute name cannot be empty", nil); NSDictionary *attributeNamesMapping = [self.class wdAttributeNamesMapping]; - NSString *result = [attributeNamesMapping valueForKey:name]; + NSString *result = attributeNamesMapping[name]; if (nil == result) { NSString *description = [NSString stringWithFormat:@"The attribute '%@' is unknown. Valid attribute names are: %@", name, [attributeNamesMapping.allKeys sortedArrayUsingSelector:@selector(compare:)]]; @throw [NSException exceptionWithName:FBUnknownAttributeException reason:description userInfo:@{}]; diff --git a/WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.m b/WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.m index cbc6e46b8..d78c7d378 100644 --- a/WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.m +++ b/WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.m @@ -9,7 +9,7 @@ #import "FBXCElementSnapshotWrapper.h" -#import +#import "FBElementUtils.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-protocol-property-synthesis" @@ -35,9 +35,15 @@ + (instancetype)ensureWrapped:(id)snapshot - (id)forwardingTargetForSelector:(SEL)aSelector { - struct objc_method_description descr = protocol_getMethodDescription(@protocol(FBXCElementSnapshot), aSelector, YES, YES); - SEL selector = descr.name; - return nil == selector ? nil : self.snapshot; + static dispatch_once_t onceToken; + static NSSet *allNames; + dispatch_once(&onceToken, ^{ + NSMutableSet *names = [NSMutableSet set]; + [names unionSet:[FBElementUtils selectorNamesWithProtocol:@protocol(FBXCElementSnapshot)]]; + [names unionSet:[FBElementUtils selectorNamesWithProtocol:@protocol(XCUIElementAttributes)]]; + allNames = [names copy]; + }); + return [allNames containsObject:NSStringFromSelector(aSelector)] ? self.snapshot : nil; } @end From a5d0bb4264ee860a49217d39991771d947b3fc62 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 22 Nov 2022 10:07:27 +0000 Subject: [PATCH 039/240] chore(release): 4.10.3 [skip ci] ## [4.10.3](https://github.com/appium/WebDriverAgent/compare/v4.10.2...v4.10.3) (2022-11-22) --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c981e888..bf2f9e8d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1 +1,3 @@ +## [4.10.3](https://github.com/appium/WebDriverAgent/compare/v4.10.2...v4.10.3) (2022-11-22) + ## [4.10.2](https://github.com/appium/WebDriverAgent/compare/v4.10.1...v4.10.2) (2022-11-06) diff --git a/package.json b/package.json index b4a254b6e..48463791a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.2", + "version": "4.10.3", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 167a482110d37fa64d269985a9c92b78967c9a26 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Tue, 22 Nov 2022 19:20:16 +0100 Subject: [PATCH 040/240] refactor: Remove peer dependency to appium (#631) --- .github/workflows/publish.js.yml | 14 ++++---------- Scripts/build-webdriveragent.js | 2 +- Scripts/fetch-prebuilt-wda.js | 2 +- ci-jobs/scripts/build-webdriveragents.js | 2 +- ci-jobs/templates/build.yml | 11 +++++------ lib/check-dependencies.js | 2 +- lib/logger.js | 2 +- lib/no-session-proxy.js | 2 +- lib/utils.js | 2 +- lib/webdriveragent.js | 4 ++-- lib/xcodebuild.js | 2 +- package.json | 5 ++--- test/functional/desired.js | 2 +- test/unit/utils-specs.js | 2 +- 14 files changed, 23 insertions(+), 31 deletions(-) diff --git a/.github/workflows/publish.js.yml b/.github/workflows/publish.js.yml index 3585772e5..571e8632f 100644 --- a/.github/workflows/publish.js.yml +++ b/.github/workflows/publish.js.yml @@ -10,7 +10,6 @@ on: jobs: build: - # To specify Xcode version runs-on: macos-11 env: @@ -21,20 +20,15 @@ jobs: PKG_PATH_TVOS: "appium_wda_tvos" steps: - # setup - uses: actions/checkout@v2 - - name: Use Node.js 18.x - uses: actions/setup-node@v1 + - name: Use Node.js + uses: actions/setup-node@v3 with: - node-version: 18.x + node-version: lts/* - uses: maxim-lobanov/setup-xcode@v1 with: xcode-version: "${{ env.XCODE_VERSION }}" - - # nodejs - - run: | - npm install -g appium@next - npm install --no-package-lock + - run: npm install --no-package-lock name: Install dev dependencies - run: npm run build name: Run build diff --git a/Scripts/build-webdriveragent.js b/Scripts/build-webdriveragent.js index d93fccd26..2099c134c 100644 --- a/Scripts/build-webdriveragent.js +++ b/Scripts/build-webdriveragent.js @@ -1,7 +1,7 @@ const path = require('path'); const os = require('os'); const { asyncify } = require('asyncbox'); -const { logger, fs, mkdirp, zip } = require('appium/support'); +const { logger, fs, mkdirp, zip } = require('@appium/support'); const { exec } = require('teen_process'); const xcode = require('appium-xcode'); diff --git a/Scripts/fetch-prebuilt-wda.js b/Scripts/fetch-prebuilt-wda.js index a7ad5101f..8bedd9a3d 100644 --- a/Scripts/fetch-prebuilt-wda.js +++ b/Scripts/fetch-prebuilt-wda.js @@ -1,7 +1,7 @@ const path = require('path'); const axios = require('axios'); const { asyncify } = require('asyncbox'); -const { logger, fs, mkdirp, net } = require('appium/support'); +const { logger, fs, mkdirp, net } = require('@appium/support'); const _ = require('lodash'); const B = require('bluebird'); diff --git a/ci-jobs/scripts/build-webdriveragents.js b/ci-jobs/scripts/build-webdriveragents.js index f7485e25d..be7a70496 100644 --- a/ci-jobs/scripts/build-webdriveragents.js +++ b/ci-jobs/scripts/build-webdriveragents.js @@ -1,6 +1,6 @@ const buildWebDriverAgent = require('./build-webdriveragent'); const { asyncify } = require('asyncbox'); -const { fs, logger } = require('appium/support'); +const { fs, logger } = require('@appium/support'); const { exec } = require('teen_process'); const path = require('path'); diff --git a/ci-jobs/templates/build.yml b/ci-jobs/templates/build.yml index e5e768de3..d32d34a8f 100644 --- a/ci-jobs/templates/build.yml +++ b/ci-jobs/templates/build.yml @@ -14,12 +14,11 @@ jobs: displayName: Print Tag Name - script: ls /Applications/ displayName: List Installed Applications - - task: NodeTool@0 - inputs: - versionSpec: '16.x' - - script: | - npm install -g appium@next - npm install + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: lts/* + - script: npm install displayName: Install Node Modules - script: mkdir -p Resources/WebDriverAgent.bundle displayName: Make Resources Folder diff --git a/lib/check-dependencies.js b/lib/check-dependencies.js index b2be31d33..39b824373 100644 --- a/lib/check-dependencies.js +++ b/lib/check-dependencies.js @@ -1,4 +1,4 @@ -import { fs } from 'appium/support'; +import { fs } from '@appium/support'; import _ from 'lodash'; import { exec } from 'teen_process'; import path from 'path'; diff --git a/lib/logger.js b/lib/logger.js index 3f822d8ee..4727be0ff 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -1,4 +1,4 @@ -import { logger } from 'appium/support'; +import { logger } from '@appium/support'; const log = logger.getLogger('WebDriverAgent'); diff --git a/lib/no-session-proxy.js b/lib/no-session-proxy.js index f73c6eeb9..f0760c701 100644 --- a/lib/no-session-proxy.js +++ b/lib/no-session-proxy.js @@ -1,4 +1,4 @@ -import { JWProxy } from 'appium/driver'; +import { JWProxy } from '@appium/base-driver'; class NoSessionProxy extends JWProxy { diff --git a/lib/utils.js b/lib/utils.js index a28539914..71cac28ba 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,4 +1,4 @@ -import { fs, tempDir, plist } from 'appium/support'; +import { fs, tempDir, plist } from '@appium/support'; import { exec } from 'teen_process'; import path from 'path'; import log from './logger'; diff --git a/lib/webdriveragent.js b/lib/webdriveragent.js index 5ccb0475f..93898047b 100644 --- a/lib/webdriveragent.js +++ b/lib/webdriveragent.js @@ -2,8 +2,8 @@ import _ from 'lodash'; import path from 'path'; import url from 'url'; import B from 'bluebird'; -import { JWProxy } from 'appium/driver'; -import { fs, util, plist, mkdirp } from 'appium/support'; +import { JWProxy } from '@appium/base-driver'; +import { fs, util, plist, mkdirp } from '@appium/support'; import defaultLogger from './logger'; import { NoSessionProxy } from './no-session-proxy'; import { diff --git a/lib/xcodebuild.js b/lib/xcodebuild.js index 2bd35239b..aca528aab 100644 --- a/lib/xcodebuild.js +++ b/lib/xcodebuild.js @@ -1,6 +1,6 @@ import { retryInterval } from 'asyncbox'; import { SubProcess, exec } from 'teen_process'; -import { fs, logger, timing } from 'appium/support'; +import { fs, logger, timing } from '@appium/support'; import defaultLogger from './logger'; import B from 'bluebird'; import { diff --git a/package.json b/package.json index 48463791a..66e6d4f68 100644 --- a/package.json +++ b/package.json @@ -80,10 +80,9 @@ "semantic-release": "^19.0.2", "sinon": "^14.0.0" }, - "peerDependencies": { - "appium": "^2.0.0-beta.40" - }, "dependencies": { + "@appium/base-driver": "^8.7.3", + "@appium/support": "^2.61.0", "@babel/runtime": "^7.0.0", "appium-ios-simulator": "^4.0.0", "async-lock": "^1.0.0", diff --git a/test/functional/desired.js b/test/functional/desired.js index 06527a18b..52a3d1932 100644 --- a/test/functional/desired.js +++ b/test/functional/desired.js @@ -1,4 +1,4 @@ -import { util } from 'appium/support'; +import { util } from '@appium/support'; export const PLATFORM_VERSION = process.env.PLATFORM_VERSION ? process.env.PLATFORM_VERSION : '11.3'; export const DEVICE_NAME = process.env.DEVICE_NAME diff --git a/test/unit/utils-specs.js b/test/unit/utils-specs.js index 7ce35763c..1d61b4854 100644 --- a/test/unit/utils-specs.js +++ b/test/unit/utils-specs.js @@ -3,7 +3,7 @@ import { PLATFORM_NAME_IOS, PLATFORM_NAME_TVOS } from '../../lib/constants'; import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; import { withMocks } from '@appium/test-support'; -import { fs } from 'appium/support'; +import { fs } from '@appium/support'; import path from 'path'; import { fail } from 'assert'; From ba736955a6820700bf0f6b302501bea9fb9d5807 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Tue, 22 Nov 2022 19:21:06 +0100 Subject: [PATCH 041/240] chore: Prefer direct attribute accessors over forwardingTargetForSelector usage (#632) --- WebDriverAgentLib/Routing/FBElementUtils.h | 2 +- .../Routing/FBXCElementSnapshotWrapper.m | 69 +++++++++++++++++-- 2 files changed, 64 insertions(+), 7 deletions(-) diff --git a/WebDriverAgentLib/Routing/FBElementUtils.h b/WebDriverAgentLib/Routing/FBElementUtils.h index 0c7209829..a0b6da839 100644 --- a/WebDriverAgentLib/Routing/FBElementUtils.h +++ b/WebDriverAgentLib/Routing/FBElementUtils.h @@ -65,7 +65,7 @@ extern NSString *const FBUnknownAttributeException; + (unsigned long long)idWithAccessibilityElement:(id)element; /** - Retrieves the list of required insatnce methods of the given protocol + Retrieves the list of required instance methods of the given protocol @param protocol target protocol reference @return set of selector names diff --git a/WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.m b/WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.m index d78c7d378..6e48e0721 100644 --- a/WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.m +++ b/WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.m @@ -33,17 +33,74 @@ + (instancetype)ensureWrapped:(id)snapshot : [[FBXCElementSnapshotWrapper alloc] initWithSnapshot:snapshot]; } +// Attributes are queried most often, +// so we prefer them to have direct accessors defined here +// rather than to use message forwarding via forwardingTargetForSelector, +// which is slow + +- (NSString *)identifier +{ + return self.snapshot.identifier; +} + +- (CGRect)frame +{ + return self.snapshot.frame; +} + +- (id)value +{ + return self.snapshot.value; +} + +- (NSString *)title +{ + return self.snapshot.title; +} + +- (NSString *)label +{ + return self.snapshot.label; +} + +- (XCUIElementType)elementType +{ + return self.snapshot.elementType; +} + +- (BOOL)isEnabled +{ + return self.snapshot.enabled; +} + +- (XCUIUserInterfaceSizeClass)horizontalSizeClass +{ + return self.snapshot.horizontalSizeClass; +} + +- (XCUIUserInterfaceSizeClass)verticalSizeClass +{ + return self.snapshot.verticalSizeClass; +} + +- (NSString *)placeholderValue +{ + return self.snapshot.placeholderValue; +} + +- (BOOL)isSelected +{ + return self.snapshot.selected; +} + - (id)forwardingTargetForSelector:(SEL)aSelector { static dispatch_once_t onceToken; - static NSSet *allNames; + static NSSet *names; dispatch_once(&onceToken, ^{ - NSMutableSet *names = [NSMutableSet set]; - [names unionSet:[FBElementUtils selectorNamesWithProtocol:@protocol(FBXCElementSnapshot)]]; - [names unionSet:[FBElementUtils selectorNamesWithProtocol:@protocol(XCUIElementAttributes)]]; - allNames = [names copy]; + names = [FBElementUtils selectorNamesWithProtocol:@protocol(FBXCElementSnapshot)]; }); - return [allNames containsObject:NSStringFromSelector(aSelector)] ? self.snapshot : nil; + return [names containsObject:NSStringFromSelector(aSelector)] ? self.snapshot : nil; } @end From 23bfc863f58dc5b805b987fa0b3c5a4de5b0ab84 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 22 Nov 2022 18:28:09 +0000 Subject: [PATCH 042/240] chore(release): 4.10.4 [skip ci] ## [4.10.4](https://github.com/appium/WebDriverAgent/compare/v4.10.3...v4.10.4) (2022-11-22) --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf2f9e8d5..271e955f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [4.10.4](https://github.com/appium/WebDriverAgent/compare/v4.10.3...v4.10.4) (2022-11-22) + ## [4.10.3](https://github.com/appium/WebDriverAgent/compare/v4.10.2...v4.10.3) (2022-11-22) ## [4.10.2](https://github.com/appium/WebDriverAgent/compare/v4.10.1...v4.10.2) (2022-11-06) diff --git a/package.json b/package.json index 66e6d4f68..0a5f7ca35 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.3", + "version": "4.10.4", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From fb5ef895dfa3315eab87f9b51baae5888a3600db Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Tue, 22 Nov 2022 22:13:27 +0100 Subject: [PATCH 043/240] chore: Add accessor for hasFocus attribute (#633) --- WebDriverAgentLib/Routing/FBElementUtils.m | 2 +- WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.m | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/WebDriverAgentLib/Routing/FBElementUtils.m b/WebDriverAgentLib/Routing/FBElementUtils.m index 5a98b85fc..8aec9d8a8 100644 --- a/WebDriverAgentLib/Routing/FBElementUtils.m +++ b/WebDriverAgentLib/Routing/FBElementUtils.m @@ -122,7 +122,7 @@ + (NSString *)wdAttributeNameForAttributeName:(NSString *)name } attributeNamesMapping = resultCache.copy; }); - return attributeNamesMapping.copy; + return attributeNamesMapping; } + (NSString *)uidWithAccessibilityElement:(id)element diff --git a/WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.m b/WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.m index 6e48e0721..1beb87bb2 100644 --- a/WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.m +++ b/WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.m @@ -93,6 +93,13 @@ - (BOOL)isSelected return self.snapshot.selected; } +#if !TARGET_OS_OSX +- (BOOL)hasFocus +{ + return self.snapshot.hasFocus; +} +#endif + - (id)forwardingTargetForSelector:(SEL)aSelector { static dispatch_once_t onceToken; From b46737c0dac1731af5006e88c4e9df933b59f9e2 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 22 Nov 2022 21:22:29 +0000 Subject: [PATCH 044/240] chore(release): 4.10.5 [skip ci] ## [4.10.5](https://github.com/appium/WebDriverAgent/compare/v4.10.4...v4.10.5) (2022-11-22) --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 271e955f3..15eabd634 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [4.10.5](https://github.com/appium/WebDriverAgent/compare/v4.10.4...v4.10.5) (2022-11-22) + ## [4.10.4](https://github.com/appium/WebDriverAgent/compare/v4.10.3...v4.10.4) (2022-11-22) ## [4.10.3](https://github.com/appium/WebDriverAgent/compare/v4.10.2...v4.10.3) (2022-11-22) diff --git a/package.json b/package.json index 0a5f7ca35..e74eb7e2c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.4", + "version": "4.10.5", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 6d6599bf48385d379b80039c817256a8b4bdf7e4 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Wed, 23 Nov 2022 11:57:27 +0100 Subject: [PATCH 045/240] chore: Simplify attributes lookup (#634) --- .../Categories/XCUIElement+FBFind.m | 43 +++---------------- .../Categories/XCUIElement+FBResolve.m | 2 +- .../Categories/XCUIElement+FBUID.h | 8 ++++ .../Categories/XCUIElement+FBUID.m | 7 ++- .../Categories/XCUIElement+FBUtilities.m | 9 ++-- .../XCUIElement+FBWebDriverAttributes.h | 8 ++++ .../XCUIElement+FBWebDriverAttributes.m | 13 ++++-- .../Utilities/NSPredicate+FBFormat.m | 4 ++ 8 files changed, 49 insertions(+), 45 deletions(-) diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBFind.m b/WebDriverAgentLib/Categories/XCUIElement+FBFind.m index f2f55f2dc..4d46f4c8f 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBFind.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBFind.m @@ -16,6 +16,7 @@ #import "FBXCElementSnapshotWrapper+Helpers.h" #import "FBXCodeCompatibility.h" #import "XCUIElement+FBCaching.h" +#import "XCUIElement+FBUID.h" #import "XCUIElement+FBUtilities.h" #import "XCUIElement+FBWebDriverAttributes.h" #import "XCUIElementQuery.h" @@ -48,7 +49,8 @@ @implementation XCUIElement (FBFind) XCUIElementType type = [FBElementTypeTransformer elementTypeWithTypeName:className]; XCUIElementQuery *query = [self.fb_query descendantsMatchingType:type]; NSMutableArray *result = [NSMutableArray array]; - [result addObjectsFromArray:[self.class fb_extractMatchingElementsFromQuery:query shouldReturnAfterFirstMatch:shouldReturnAfterFirstMatch]]; + [result addObjectsFromArray:[self.class fb_extractMatchingElementsFromQuery:query + shouldReturnAfterFirstMatch:shouldReturnAfterFirstMatch]]; id cachedSnapshot = [self fb_cachedSnapshotWithQuery:query]; if (type == XCUIElementTypeAny || cachedSnapshot.elementType == type) { if (shouldReturnAfterFirstMatch || result.count == 0) { @@ -66,40 +68,10 @@ @implementation XCUIElement (FBFind) value:(NSString *)value partialSearch:(BOOL)partialSearch { - NSMutableArray *elements = [NSMutableArray array]; - [self descendantsWithProperty:property value:value partial:partialSearch results:elements]; - return elements; + NSPredicate *searchPredicate = [NSPredicate predicateWithFormat:(partialSearch ? @"%K CONTAINS %@" : @"%K == %@"), property, value]; + return [self fb_descendantsMatchingPredicate:searchPredicate shouldReturnAfterFirstMatch:NO]; } -- (void)descendantsWithProperty:(NSString *)property value:(NSString *)value - partial:(BOOL)partialSearch - results:(NSMutableArray *)results -{ - if (partialSearch) { - NSString *text = [self fb_valueForWDAttributeName:property]; - BOOL isString = [text isKindOfClass:[NSString class]]; - if (isString && [text rangeOfString:value].location != NSNotFound) { - [results addObject:self]; - } - } else { - if ([[self fb_valueForWDAttributeName:property] isEqual:value]) { - [results addObject:self]; - } - } - - property = [FBElementUtils wdAttributeNameForAttributeName:property]; - NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id snapshot, - NSDictionary * _Nullable bindings) { - FBXCElementSnapshotWrapper *wrappedSnapshot = [FBXCElementSnapshotWrapper ensureWrapped:snapshot]; - NSString *propertyValue = [NSString stringWithFormat:@"%@", [wrappedSnapshot fb_valueForWDAttributeName:property]]; - return partialSearch ? [value containsString:propertyValue] : [value isEqualToString:propertyValue]; - }]; - XCUIElementQuery *query = [[self.fb_query descendantsMatchingType:XCUIElementTypeAny] matchingPredicate:predicate]; - NSArray *childElements = query.fb_allMatches; - [results addObjectsFromArray:childElements]; -} - - #pragma mark - Search by Predicate String - (NSArray *)fb_descendantsMatchingPredicate:(NSPredicate *)predicate @@ -138,7 +110,7 @@ - (void)descendantsWithProperty:(NSString *)property value:(NSString *)value matchingSnapshots = @[snapshot]; } return [self fb_filterDescendantsWithSnapshots:matchingSnapshots - selfUID:[FBXCElementSnapshotWrapper ensureWrapped:self.lastSnapshot].wdUID + selfUID:[FBXCElementSnapshotWrapper wdUIDWithSnapshot:self.lastSnapshot] onlyChildren:NO]; } @@ -150,8 +122,7 @@ - (void)descendantsWithProperty:(NSString *)property value:(NSString *)value { NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id snapshot, NSDictionary * _Nullable bindings) { - FBXCElementSnapshotWrapper *wrappedSnapshot = [FBXCElementSnapshotWrapper ensureWrapped:snapshot]; - return [wrappedSnapshot.wdName isEqualToString:accessibilityId]; + return [[FBXCElementSnapshotWrapper wdNameWithSnapshot:snapshot] isEqualToString:accessibilityId]; }]; return [self fb_descendantsMatchingPredicate:predicate shouldReturnAfterFirstMatch:shouldReturnAfterFirstMatch]; diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m b/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m index a0fb0af9a..ff6b3f003 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m @@ -47,7 +47,7 @@ - (XCUIElement *)fb_stableInstance return self; } NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id snapshot, NSDictionary *bindings) { - return [[FBXCElementSnapshotWrapper ensureWrapped:snapshot].fb_uid isEqualToString:uid]; + return [[FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot] isEqualToString:uid]; }]; return (XCUIElement *)[query matchingPredicate:predicate].fb_firstMatch; } diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBUID.h b/WebDriverAgentLib/Categories/XCUIElement+FBUID.h index 3ca0bae2b..8b1a2da64 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBUID.h +++ b/WebDriverAgentLib/Categories/XCUIElement+FBUID.h @@ -30,6 +30,14 @@ NS_ASSUME_NONNULL_BEGIN /*! Represents unique internal element identifier, which is the same for an element and its snapshot */ @property (nonatomic, readonly) unsigned long long fb_accessibiltyId; +/** + Fetches wdUID attribute value for the given snapshot instance + + @param snapshot snapshot instance + @return UID attribute value + */ ++ (nullable NSString *)wdUIDWithSnapshot:(id)snapshot; + @end NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBUID.m b/WebDriverAgentLib/Categories/XCUIElement+FBUID.m index cb8ef1396..1af09a4ec 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBUID.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBUID.m @@ -38,9 +38,14 @@ - (unsigned long long)fb_accessibiltyId return [FBElementUtils idWithAccessibilityElement:self.accessibilityElement]; } ++ (nullable NSString *)wdUIDWithSnapshot:(id)snapshot +{ + return [FBElementUtils uidWithAccessibilityElement:[snapshot accessibilityElement]]; +} + - (NSString *)fb_uid { - return [FBElementUtils uidWithAccessibilityElement:[self accessibilityElement]]; + return [self.class wdUIDWithSnapshot:self.snapshot]; } @end diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m b/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m index 17837b019..9d20c1f2b 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m @@ -134,13 +134,16 @@ @implementation XCUIElement (FBUtilities) } NSMutableArray *sortedIds = [NSMutableArray new]; for (id snapshot in snapshots) { - [sortedIds addObject:(NSString *)[FBXCElementSnapshotWrapper ensureWrapped:snapshot].fb_uid]; + NSString *uid = [FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot]; + if (nil != uid) { + [sortedIds addObject:uid]; + } } NSMutableArray *matchedElements = [NSMutableArray array]; NSString *uid = selfUID; if (nil == uid) { uid = self.fb_isResolvedFromCache.boolValue - ? [FBXCElementSnapshotWrapper ensureWrapped:self.lastSnapshot].fb_uid + ? [FBXCElementSnapshotWrapper wdUIDWithSnapshot:self.lastSnapshot] : self.fb_uid; } if ([sortedIds containsObject:uid]) { @@ -158,7 +161,7 @@ @implementation XCUIElement (FBUtilities) ? [self.fb_query childrenMatchingType:type] : [self.fb_query descendantsMatchingType:type]; NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id snapshot, NSDictionary *bindings) { - return [sortedIds containsObject:(NSString *)[FBXCElementSnapshotWrapper ensureWrapped:snapshot].fb_uid]; + return [sortedIds containsObject:[FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot] ?: @""]; }]; query = [query matchingPredicate:predicate]; if (1 == snapshots.count) { diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.h b/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.h index 903eeb432..fdeedaf91 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.h +++ b/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.h @@ -20,6 +20,14 @@ NS_ASSUME_NONNULL_BEGIN @interface FBXCElementSnapshotWrapper (WebDriverAttributes) +/** + Fetches wdName attribute value for the given snapshot instance + + @param snapshot snapshot instance + @return wdName attribute value or nil + */ ++ (nullable NSString *)wdNameWithSnapshot:(id)snapshot; + @end NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m b/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m index 71a17b636..cc2b46daf 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m @@ -100,18 +100,23 @@ - (NSString *)wdValue value = [NSString stringWithFormat:@"%@", value]; } return value; - } +} -- (NSString *)wdName ++ (NSString *)wdNameWithSnapshot:(id)snapshot { - NSString *identifier = self.identifier; + NSString *identifier = snapshot.identifier; if (nil != identifier && identifier.length != 0) { return identifier; } - NSString *label = self.label; + NSString *label = snapshot.label; return FBTransferEmptyStringToNil(label); } +- (NSString *)wdName +{ + return [self.class wdNameWithSnapshot:self.snapshot]; +} + - (NSString *)wdLabel { NSString *label = self.label; diff --git a/WebDriverAgentLib/Utilities/NSPredicate+FBFormat.m b/WebDriverAgentLib/Utilities/NSPredicate+FBFormat.m index 96c4d71b1..8a033e707 100644 --- a/WebDriverAgentLib/Utilities/NSPredicate+FBFormat.m +++ b/WebDriverAgentLib/Utilities/NSPredicate+FBFormat.m @@ -52,6 +52,10 @@ + (instancetype)fb_formatSearchPredicate:(NSPredicate *)input + (instancetype)fb_snapshotBlockPredicateWithPredicate:(NSPredicate *)input { + if ([NSStringFromClass(input.class) isEqualToString:@"NSBlockPredicate"]) { + return input; + } + NSPredicate *wdPredicate = [self.class fb_formatSearchPredicate:input]; return [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary * _Nullable bindings) { From a39b4f3645dc92e80fb95afa5715b1f5d79682a6 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 23 Nov 2022 11:04:04 +0000 Subject: [PATCH 046/240] chore(release): 4.10.6 [skip ci] ## [4.10.6](https://github.com/appium/WebDriverAgent/compare/v4.10.5...v4.10.6) (2022-11-23) --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15eabd634..8873e5db6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [4.10.6](https://github.com/appium/WebDriverAgent/compare/v4.10.5...v4.10.6) (2022-11-23) + ## [4.10.5](https://github.com/appium/WebDriverAgent/compare/v4.10.4...v4.10.5) (2022-11-22) ## [4.10.4](https://github.com/appium/WebDriverAgent/compare/v4.10.3...v4.10.4) (2022-11-22) diff --git a/package.json b/package.json index e74eb7e2c..ab5de9ffd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.5", + "version": "4.10.6", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 9c8d375189cae18ef03ad4e5ccd214aaa4a4eb06 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 24 Nov 2022 19:07:40 +0100 Subject: [PATCH 047/240] chore: Simplify various method calls (#636) --- .../Categories/XCUIElement+FBCaching.m | 2 +- .../Categories/XCUIElement+FBIsVisible.m | 20 +++++++++---------- .../Categories/XCUIElement+FBResolve.m | 5 +++-- .../Commands/FBFindElementCommands.m | 3 ++- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBCaching.m b/WebDriverAgentLib/Categories/XCUIElement+FBCaching.m index 9d1d2dc0d..faa42ea86 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBCaching.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBCaching.m @@ -48,7 +48,7 @@ - (NSString *)fb_cacheId uid = self.fb_uid; } else { id snapshot = self.fb_cachedSnapshot ?: self.fb_takeSnapshot; - uid = [FBXCElementSnapshotWrapper ensureWrapped:snapshot].wdUID; + uid = [FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot]; } objc_setAssociatedObject(self, &XCUIELEMENT_CACHE_ID_KEY, uid, OBJC_ASSOCIATION_RETAIN_NONATOMIC); diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBIsVisible.m b/WebDriverAgentLib/Categories/XCUIElement+FBIsVisible.m index 1ec2e9ac9..c667a48c8 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBIsVisible.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBIsVisible.m @@ -34,9 +34,9 @@ - (BOOL)fb_isVisible @implementation FBXCElementSnapshotWrapper (FBIsVisible) -- (NSString *)fb_uniqId ++ (NSString *)fb_uniqIdWithSnapshot:(id)snapshot { - return self.fb_uid ?: [NSString stringWithFormat:@"%p", (void *)self]; + return [FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot] ?: [NSString stringWithFormat:@"%p", (void *)snapshot]; } - (nullable NSNumber *)fb_cachedVisibilityValue @@ -46,14 +46,14 @@ - (nullable NSNumber *)fb_cachedVisibilityValue return nil; } - NSDictionary *result = [cache objectForKey:@(self.generation)]; + NSDictionary *result = cache[@(self.generation)]; if (nil == result) { // There is no need to keep the cached data for the previous generations [cache removeAllObjects]; - [cache setObject:[NSMutableDictionary dictionary] forKey:@(self.generation)]; + cache[@(self.generation)] = [NSMutableDictionary dictionary]; return nil; } - return [result objectForKey:self.fb_uniqId]; + return result[[self.class fb_uniqIdWithSnapshot:self.snapshot]]; } - (BOOL)fb_cacheVisibilityWithValue:(BOOL)isVisible @@ -63,19 +63,19 @@ - (BOOL)fb_cacheVisibilityWithValue:(BOOL)isVisible if (nil == cache) { return isVisible; } - NSMutableDictionary *destination = [cache objectForKey:@(self.generation)]; + NSMutableDictionary *destination = cache[@(self.generation)]; if (nil == destination) { return isVisible; } NSNumber *visibleObj = [NSNumber numberWithBool:isVisible]; - [destination setObject:visibleObj forKey:self.fb_uniqId]; + destination[[self.class fb_uniqIdWithSnapshot:self.snapshot]] = visibleObj; if (isVisible && nil != ancestors) { // if an element is visible then all its ancestors must be visible as well for (id ancestor in ancestors) { - NSString *ancestorId = [FBXCElementSnapshotWrapper ensureWrapped:ancestor].fb_uniqId; - if (nil == [destination objectForKey:ancestorId]) { - [destination setObject:visibleObj forKey:ancestorId]; + NSString *ancestorId = [self.class fb_uniqIdWithSnapshot:ancestor]; + if (nil == destination[ancestorId]) { + destination[ancestorId] = visibleObj; } } } diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m b/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m index ff6b3f003..f9ad806f2 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m @@ -41,8 +41,9 @@ - (XCUIElement *)fb_stableInstance XCUIElementQuery *query = [self isKindOfClass:XCUIApplication.class] ? self.application.fb_query : [self.application.fb_query descendantsMatchingType:XCUIElementTypeAny]; - FBXCElementSnapshotWrapper *cachedSnapshot = [FBXCElementSnapshotWrapper ensureWrapped:self.fb_cachedSnapshot]; - NSString *uid = nil == cachedSnapshot ? self.fb_uid : cachedSnapshot.fb_uid; + NSString *uid = nil == self.fb_cachedSnapshot + ? self.fb_uid + : [FBXCElementSnapshotWrapper wdUIDWithSnapshot:(id)self.fb_cachedSnapshot]; if (nil == uid) { return self; } diff --git a/WebDriverAgentLib/Commands/FBFindElementCommands.m b/WebDriverAgentLib/Commands/FBFindElementCommands.m index debc389be..037dbae15 100644 --- a/WebDriverAgentLib/Commands/FBFindElementCommands.m +++ b/WebDriverAgentLib/Commands/FBFindElementCommands.m @@ -22,6 +22,7 @@ #import "XCUIElement+FBClassChain.h" #import "XCUIElement+FBFind.h" #import "XCUIElement+FBIsVisible.h" +#import "XCUIElement+FBUID.h" #import "XCUIElement+FBUtilities.h" #import "XCUIElement+FBWebDriverAttributes.h" @@ -88,7 +89,7 @@ + (NSArray *)routes && [FBXCElementSnapshotWrapper ensureWrapped:snapshot].wdVisible; }]; NSArray *cells = [element fb_filterDescendantsWithSnapshots:visibleCellSnapshots - selfUID:[FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot].wdUID + selfUID:[FBXCElementSnapshotWrapper wdUIDWithSnapshot:element.lastSnapshot] onlyChildren:NO]; return FBResponseWithCachedElements(cells, request.session.elementCache, FBConfiguration.shouldUseCompactResponses); } From 642d0b722faac5ffff084b6077e795bb3fefe417 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 24 Nov 2022 18:19:08 +0000 Subject: [PATCH 048/240] chore(release): 4.10.7 [skip ci] ## [4.10.7](https://github.com/appium/WebDriverAgent/compare/v4.10.6...v4.10.7) (2022-11-24) --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8873e5db6..a672b088a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [4.10.7](https://github.com/appium/WebDriverAgent/compare/v4.10.6...v4.10.7) (2022-11-24) + ## [4.10.6](https://github.com/appium/WebDriverAgent/compare/v4.10.5...v4.10.6) (2022-11-23) ## [4.10.5](https://github.com/appium/WebDriverAgent/compare/v4.10.4...v4.10.5) (2022-11-22) diff --git a/package.json b/package.json index ab5de9ffd..d27e8522f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.6", + "version": "4.10.7", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From d72eb0f1ed70a8b7b748b68681dbbd83825f862d Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 24 Nov 2022 20:31:15 +0100 Subject: [PATCH 049/240] chore: Replace usage of mach_absolute_time with clock_gettime_nsec_np (#635) --- WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m | 3 +-- WebDriverAgentLib/Utilities/FBMjpegServer.m | 8 +++----- WebDriverAgentLib/Utilities/FBPasteboard.m | 4 ++-- .../IntegrationTests/XCUIApplicationHelperTests.m | 4 ++-- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m b/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m index 6c9dde467..5756a630b 100644 --- a/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +++ b/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m @@ -31,7 +31,6 @@ #import "XCTestPrivateSymbols.h" #import "XCTRunnerDaemonSession.h" -const static NSTimeInterval FBMinimumAppSwitchWait = 3.0; static NSString* const FBUnknownBundleId = @"unknown"; @@ -92,7 +91,7 @@ - (BOOL)fb_deactivateWithDuration:(NSTimeInterval)duration error:(NSError **)err if(![[XCUIDevice sharedDevice] fb_goToHomescreenWithError:error]) { return NO; } - [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:MAX(duration, FBMinimumAppSwitchWait)]]; + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:MAX(duration, .0)]]; [self fb_activate]; return YES; } diff --git a/WebDriverAgentLib/Utilities/FBMjpegServer.m b/WebDriverAgentLib/Utilities/FBMjpegServer.m index f3baf58e6..beacecc97 100644 --- a/WebDriverAgentLib/Utilities/FBMjpegServer.m +++ b/WebDriverAgentLib/Utilities/FBMjpegServer.m @@ -31,7 +31,6 @@ @interface FBMjpegServer() @property (nonatomic, readonly) dispatch_queue_t backgroundQueue; @property (nonatomic, readonly) NSMutableArray *listeningClients; -@property (nonatomic, readonly) mach_timebase_info_data_t timebaseInfo; @property (nonatomic, readonly) FBImageIOScaler *imageScaler; @property (nonatomic, readonly) long long mainScreenID; @@ -46,7 +45,6 @@ - (instancetype)init _listeningClients = [NSMutableArray array]; dispatch_queue_attr_t queueAttributes = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_UTILITY, 0); _backgroundQueue = dispatch_queue_create(QUEUE_NAME, queueAttributes); - mach_timebase_info(&_timebaseInfo); dispatch_async(_backgroundQueue, ^{ [self streamScreenshot]; }); @@ -58,8 +56,8 @@ - (instancetype)init - (void)scheduleNextScreenshotWithInterval:(uint64_t)timerInterval timeStarted:(uint64_t)timeStarted { - uint64_t timeElapsed = mach_absolute_time() - timeStarted; - int64_t nextTickDelta = timerInterval - timeElapsed * self.timebaseInfo.numer / self.timebaseInfo.denom; + uint64_t timeElapsed = clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW) - timeStarted; + int64_t nextTickDelta = timerInterval - timeElapsed; if (nextTickDelta > 0) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, nextTickDelta), self.backgroundQueue, ^{ [self streamScreenshot]; @@ -81,7 +79,7 @@ - (void)streamScreenshot NSUInteger framerate = FBConfiguration.mjpegServerFramerate; uint64_t timerInterval = (uint64_t)(1.0 / ((0 == framerate || framerate > MAX_FPS) ? MAX_FPS : framerate) * NSEC_PER_SEC); - uint64_t timeStarted = mach_absolute_time(); + uint64_t timeStarted = clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW); @synchronized (self.listeningClients) { if (0 == self.listeningClients.count) { [self scheduleNextScreenshotWithInterval:timerInterval timeStarted:timeStarted]; diff --git a/WebDriverAgentLib/Utilities/FBPasteboard.m b/WebDriverAgentLib/Utilities/FBPasteboard.m index cdcd6ec3e..6340efff3 100644 --- a/WebDriverAgentLib/Utilities/FBPasteboard.m +++ b/WebDriverAgentLib/Utilities/FBPasteboard.m @@ -94,7 +94,7 @@ + (nullable id)pasteboardContentForItem:(NSString *)item pasteboardContent = result; didFinishGetPasteboard = YES; }); - uint64_t timeStarted = mach_absolute_time(); + uint64_t timeStarted = clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW); while (!didFinishGetPasteboard) { [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:ALERT_CHECK_INTERVAL_SEC]]; if (didFinishGetPasteboard) { @@ -106,7 +106,7 @@ + (nullable id)pasteboardContentForItem:(NSString *)item FBAlert *alert = [FBAlert alertWithElement:alertElement]; [alert acceptWithError:nil]; } - uint64_t timeElapsed = mach_absolute_time() - timeStarted; + uint64_t timeElapsed = clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW) - timeStarted; if (timeElapsed / NSEC_PER_SEC > timeout) { NSString *description = [NSString stringWithFormat:@"Cannot handle pasteboard alert within %@s timeout", @(timeout)]; if (error) { diff --git a/WebDriverAgentTests/IntegrationTests/XCUIApplicationHelperTests.m b/WebDriverAgentTests/IntegrationTests/XCUIApplicationHelperTests.m index 3f47d4ae9..8a7d47ae7 100644 --- a/WebDriverAgentTests/IntegrationTests/XCUIApplicationHelperTests.m +++ b/WebDriverAgentTests/IntegrationTests/XCUIApplicationHelperTests.m @@ -46,10 +46,10 @@ - (void)testApplicationTree - (void)testDeactivateApplication { NSError *error; - uint64_t timeStarted = mach_absolute_time(); + uint64_t timeStarted = clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW); NSTimeInterval backgroundDuration = 5.0; XCTAssertTrue([self.testedApplication fb_deactivateWithDuration:backgroundDuration error:&error]); - NSTimeInterval timeElapsed = (mach_absolute_time() - timeStarted) / NSEC_PER_SEC; + NSTimeInterval timeElapsed = (clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW) - timeStarted) / NSEC_PER_SEC; XCTAssertNil(error); XCTAssertEqualWithAccuracy(timeElapsed, backgroundDuration, 3.0); XCTAssertTrue(self.testedApplication.buttons[@"Alerts"].exists); From 76ec460033e9c9dafc2925e5377f9228ff591e70 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 24 Nov 2022 19:37:23 +0000 Subject: [PATCH 050/240] chore(release): 4.10.8 [skip ci] ## [4.10.8](https://github.com/appium/WebDriverAgent/compare/v4.10.7...v4.10.8) (2022-11-24) --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a672b088a..ef4dfd62c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [4.10.8](https://github.com/appium/WebDriverAgent/compare/v4.10.7...v4.10.8) (2022-11-24) + ## [4.10.7](https://github.com/appium/WebDriverAgent/compare/v4.10.6...v4.10.7) (2022-11-24) ## [4.10.6](https://github.com/appium/WebDriverAgent/compare/v4.10.5...v4.10.6) (2022-11-23) diff --git a/package.json b/package.json index d27e8522f..675e6b462 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.7", + "version": "4.10.8", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 20847f03165edf49c8dfe4f57f61b5560e068fa8 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Fri, 25 Nov 2022 08:31:05 +0100 Subject: [PATCH 051/240] chore: Tune element responses creation (#637) --- .../Categories/XCUIElement+FBResolve.m | 2 +- WebDriverAgentLib/Routing/FBElementCache.m | 4 +- WebDriverAgentLib/Routing/FBResponsePayload.m | 68 ++++++++++--------- .../Utilities/FBAppiumActionsSynthesizer.m | 5 +- .../Utilities/FBProtocolHelpers.h | 7 +- .../Utilities/FBProtocolHelpers.m | 10 +-- 6 files changed, 50 insertions(+), 46 deletions(-) diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m b/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m index f9ad806f2..d5198b0d3 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m @@ -50,7 +50,7 @@ - (XCUIElement *)fb_stableInstance NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id snapshot, NSDictionary *bindings) { return [[FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot] isEqualToString:uid]; }]; - return (XCUIElement *)[query matchingPredicate:predicate].fb_firstMatch; + return [query matchingPredicate:predicate].fb_firstMatch ?: self; } @end diff --git a/WebDriverAgentLib/Routing/FBElementCache.m b/WebDriverAgentLib/Routing/FBElementCache.m index 1c91a8fb6..1f069bec6 100644 --- a/WebDriverAgentLib/Routing/FBElementCache.m +++ b/WebDriverAgentLib/Routing/FBElementCache.m @@ -38,7 +38,7 @@ - (instancetype)init return nil; } _elementCache = [[LRUCache alloc] initWithCapacity:ELEMENT_CACHE_SIZE]; - _elementsNeedReset = YES; + _elementsNeedReset = NO; return self; } @@ -50,8 +50,8 @@ - (NSString *)storeElement:(XCUIElement *)element } @synchronized (self.elementCache) { [self.elementCache setObject:element forKey:uuid]; + self.elementsNeedReset = YES; } - self.elementsNeedReset = YES; return uuid; } diff --git a/WebDriverAgentLib/Routing/FBResponsePayload.m b/WebDriverAgentLib/Routing/FBResponsePayload.m index becf962aa..1fa81024a 100644 --- a/WebDriverAgentLib/Routing/FBResponsePayload.m +++ b/WebDriverAgentLib/Routing/FBResponsePayload.m @@ -18,6 +18,7 @@ #import "FBProtocolHelpers.h" #import "XCUIElementQuery.h" #import "XCUIElement+FBResolve.h" +#import "XCUIElement+FBUID.h" #import "XCUIElement+FBUtilities.h" #import "XCUIElement+FBWebDriverAttributes.h" @@ -39,7 +40,7 @@ ? YES : FBSession.activeSession.useNativeCachingStrategy; [elementCache storeElement:(useNativeCachingStrategy ? element : element.fb_stableInstance)]; - return FBResponseWithStatus([FBCommandStatus okWithValue: FBDictionaryResponseWithElement(element, compact)]); + return FBResponseWithStatus([FBCommandStatus okWithValue:FBDictionaryResponseWithElement(element, compact)]); } id FBResponseWithCachedElements(NSArray *elements, FBElementCache *elementCache, BOOL compact) @@ -65,7 +66,8 @@ va_list argList; va_start(argList, format); NSString *errorMessage = [[NSString alloc] initWithFormat:format arguments:argList]; - id payload = FBResponseWithStatus([FBCommandStatus unknownErrorWithMessage:errorMessage traceback:nil]); + id payload = FBResponseWithStatus([FBCommandStatus unknownErrorWithMessage:errorMessage + traceback:nil]); va_end(argList); return payload; } @@ -77,13 +79,12 @@ if (nil == status.error) { response[@"value"] = status.value ?: NSNull.null; } else { - NSMutableDictionary* value = [NSMutableDictionary dictionary]; - value[@"error"] = status.error; - value[@"message"] = status.message ?: @""; - value[@"traceback"] = status.traceback ?: @""; - response[@"value"] = value.copy; + response[@"value"] = @{ + @"error": (id)status.error, + @"message": status.message ?: @"", + @"traceback": status.traceback ?: @"" + }; } - return [[FBResponseJSONPayload alloc] initWithDictionary:response.copy httpStatusCode:status.statusCode]; } @@ -97,31 +98,34 @@ if (nil == snapshot) { snapshot = element.lastSnapshot ?: element.fb_takeSnapshot; } + NSDictionary *compactResult = FBToElementDict((NSString *)[FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot]); + if (compact) { + return compactResult; + } + + NSMutableDictionary *result = compactResult.mutableCopy; FBXCElementSnapshotWrapper *wrappedSnapshot = [FBXCElementSnapshotWrapper ensureWrapped:snapshot]; - NSMutableDictionary *dictionary = FBInsertElement(@{}, (NSString *)wrappedSnapshot.wdUID).mutableCopy; - if (!compact) { - NSArray *fields = [FBConfiguration.elementResponseAttributes componentsSeparatedByString:@","]; - for (NSString *field in fields) { - // 'name' here is the w3c-approved identifier for what we mean by 'type' - if ([field isEqualToString:@"name"] || [field isEqualToString:@"type"]) { - dictionary[field] = wrappedSnapshot.wdType; - } else if ([field isEqualToString:@"text"]) { - dictionary[field] = FBFirstNonEmptyValue(wrappedSnapshot.wdValue, wrappedSnapshot.wdLabel) ?: [NSNull null]; - } else if ([field isEqualToString:@"rect"]) { - dictionary[field] = wrappedSnapshot.wdRect; - } else if ([field isEqualToString:@"enabled"]) { - dictionary[field] = @(wrappedSnapshot.wdEnabled); - } else if ([field isEqualToString:@"displayed"]) { - dictionary[field] = @(wrappedSnapshot.wdVisible); - } else if ([field isEqualToString:@"selected"]) { - dictionary[field] = @(wrappedSnapshot.wdSelected); - } else if ([field isEqualToString:@"label"]) { - dictionary[field] = wrappedSnapshot.wdLabel ?: [NSNull null]; - } else if ([field hasPrefix:arbitraryAttrPrefix]) { - NSString *attributeName = [field substringFromIndex:[arbitraryAttrPrefix length]]; - dictionary[field] = [wrappedSnapshot fb_valueForWDAttributeName:attributeName] ?: [NSNull null]; - } + NSArray *fields = [FBConfiguration.elementResponseAttributes componentsSeparatedByString:@","]; + for (NSString *field in fields) { + // 'name' here is the w3c-approved identifier for what we mean by 'type' + if ([field isEqualToString:@"name"] || [field isEqualToString:@"type"]) { + result[field] = wrappedSnapshot.wdType; + } else if ([field isEqualToString:@"text"]) { + result[field] = FBFirstNonEmptyValue(wrappedSnapshot.wdValue, wrappedSnapshot.wdLabel) ?: [NSNull null]; + } else if ([field isEqualToString:@"rect"]) { + result[field] = wrappedSnapshot.wdRect; + } else if ([field isEqualToString:@"enabled"]) { + result[field] = @(wrappedSnapshot.wdEnabled); + } else if ([field isEqualToString:@"displayed"]) { + result[field] = @(wrappedSnapshot.wdVisible); + } else if ([field isEqualToString:@"selected"]) { + result[field] = @(wrappedSnapshot.wdSelected); + } else if ([field isEqualToString:@"label"]) { + result[field] = wrappedSnapshot.wdLabel ?: [NSNull null]; + } else if ([field hasPrefix:arbitraryAttrPrefix]) { + NSString *attributeName = [field substringFromIndex:[arbitraryAttrPrefix length]]; + result[field] = [wrappedSnapshot fb_valueForWDAttributeName:attributeName] ?: [NSNull null]; } } - return dictionary.copy; + return result.copy; } diff --git a/WebDriverAgentLib/Utilities/FBAppiumActionsSynthesizer.m b/WebDriverAgentLib/Utilities/FBAppiumActionsSynthesizer.m index 0dfe8fa51..7aec01b08 100644 --- a/WebDriverAgentLib/Utilities/FBAppiumActionsSynthesizer.m +++ b/WebDriverAgentLib/Utilities/FBAppiumActionsSynthesizer.m @@ -448,9 +448,10 @@ @implementation FBAppiumActionsSynthesizer [result addObject:touchItem]; continue; } + NSMutableDictionary *elementDict = FBCleanupElements(options).mutableCopy; + [elementDict addEntriesFromDictionary:FBToElementDict(element)]; NSMutableDictionary *processedItem = touchItem.mutableCopy; - [processedItem setObject:FBInsertElement(FBCleanupElements(options), element) - forKey:FB_OPTIONS_KEY]; + processedItem[FB_OPTIONS_KEY] = elementDict.copy; [result addObject:processedItem.copy]; } return [[result reverseObjectEnumerator] allObjects]; diff --git a/WebDriverAgentLib/Utilities/FBProtocolHelpers.h b/WebDriverAgentLib/Utilities/FBProtocolHelpers.h index 5db7bb756..eff0a518b 100644 --- a/WebDriverAgentLib/Utilities/FBProtocolHelpers.h +++ b/WebDriverAgentLib/Utilities/FBProtocolHelpers.h @@ -12,13 +12,12 @@ NS_ASSUME_NONNULL_BEGIN /** - Inserts element uuid into the response dictionary + Prepares an element dictionary, which could be then used in hybrid W3C/JWP responses - @param dst The target dictionary. It is NOT mutated @param element Either element identifier or element object itself - @returns The changed dictionary + @returns The resulting dictionary */ -NSDictionary *FBInsertElement(NSDictionary *dst, id element); +NSDictionary *FBToElementDict(id element); /** Extracts element uuid from dictionary diff --git a/WebDriverAgentLib/Utilities/FBProtocolHelpers.m b/WebDriverAgentLib/Utilities/FBProtocolHelpers.m index 287cae575..3cd037586 100644 --- a/WebDriverAgentLib/Utilities/FBProtocolHelpers.m +++ b/WebDriverAgentLib/Utilities/FBProtocolHelpers.m @@ -20,12 +20,12 @@ static NSString *const FIRST_MATCH_KEY = @"firstMatch"; -NSDictionary *FBInsertElement(NSDictionary *dst, id element) +NSDictionary *FBToElementDict(id element) { - NSMutableDictionary *result = dst.mutableCopy; - result[W3C_ELEMENT_KEY] = element; - result[JSONWP_ELEMENT_KEY] = element; - return result.copy; + return @{ + W3C_ELEMENT_KEY: element, + JSONWP_ELEMENT_KEY: element + }; } id FBExtractElement(NSDictionary *src) From 3ec5a06ab1e350f643d4b42cb00fe465922f8289 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 25 Nov 2022 07:39:49 +0000 Subject: [PATCH 052/240] chore(release): 4.10.9 [skip ci] ## [4.10.9](https://github.com/appium/WebDriverAgent/compare/v4.10.8...v4.10.9) (2022-11-25) --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef4dfd62c..abba0c5ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [4.10.9](https://github.com/appium/WebDriverAgent/compare/v4.10.8...v4.10.9) (2022-11-25) + ## [4.10.8](https://github.com/appium/WebDriverAgent/compare/v4.10.7...v4.10.8) (2022-11-24) ## [4.10.7](https://github.com/appium/WebDriverAgent/compare/v4.10.6...v4.10.7) (2022-11-24) diff --git a/package.json b/package.json index 675e6b462..43dc8d70c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.8", + "version": "4.10.9", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 5394fe8cc2eda3d1668685bd00f9f7383e122627 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Fri, 25 Nov 2022 20:36:58 +0100 Subject: [PATCH 053/240] fix: Only check existence if firstMatch is applied (#638) --- .../Categories/XCUIApplication+FBAlert.m | 6 +- .../Categories/XCUIApplication+FBHelpers.m | 2 +- .../Categories/XCUIElement+FBResolve.m | 2 +- .../Categories/XCUIElement+FBUtilities.m | 41 ++---- .../Commands/FBElementCommands.m | 14 ++- WebDriverAgentLib/FBAlert.m | 2 +- WebDriverAgentLib/Utilities/FBScreen.m | 2 +- .../Utilities/FBXCodeCompatibility.m | 9 +- .../FBAppiumTouchActionsIntegrationTests.m | 2 +- .../FBElementAttributeTests.m | 2 +- .../FBElementVisibilityTests.m | 8 +- .../IntegrationTests/FBPasteboardTests.m | 2 +- .../FBPickerWheelSelectTests.m | 2 +- .../FBW3CTouchActionsIntegrationTests.m | 2 +- .../FBXPathIntegrationTests.m | 2 +- .../IntegrationTests/XCUIElementFBFindTests.m | 117 ++++++++++++------ .../XCUIElementHelperIntegrationTests.m | 4 +- 17 files changed, 123 insertions(+), 96 deletions(-) diff --git a/WebDriverAgentLib/Categories/XCUIApplication+FBAlert.m b/WebDriverAgentLib/Categories/XCUIApplication+FBAlert.m index 9130bb3b3..eb23ed6a7 100644 --- a/WebDriverAgentLib/Categories/XCUIApplication+FBAlert.m +++ b/WebDriverAgentLib/Categories/XCUIApplication+FBAlert.m @@ -45,7 +45,7 @@ - (nullable XCUIElement *)fb_alertElementFromSafariWithScrollView:(XCUIElement * descendantsMatchingType:XCUIElementTypeOther] matchingPredicate:dstViewMatchPredicate] containingPredicate:dstViewContainPredicate1] - containingPredicate:dstViewContainPredicate2].fb_firstMatch; + containingPredicate:dstViewContainPredicate2].allElementsBoundByIndex.firstObject; } else { NSPredicate *webViewPredicate = [NSPredicate predicateWithFormat:@"elementType == %lu", XCUIElementTypeWebView]; // Find the first XCUIElementTypeOther which is the descendant of the scroll view @@ -54,7 +54,7 @@ - (nullable XCUIElement *)fb_alertElementFromSafariWithScrollView:(XCUIElement * descendantsMatchingType:XCUIElementTypeOther] matchingPredicate:dstViewMatchPredicate] containingPredicate:dstViewContainPredicate1] - containingPredicate:dstViewContainPredicate2].fb_firstMatch; + containingPredicate:dstViewContainPredicate2].allElementsBoundByIndex.firstObject; } if (nil == candidate) { return nil; @@ -80,7 +80,7 @@ - (XCUIElement *)fb_alertElement NSPredicate *alertCollectorPredicate = [NSPredicate predicateWithFormat:@"elementType IN {%lu,%lu,%lu}", XCUIElementTypeAlert, XCUIElementTypeSheet, XCUIElementTypeScrollView]; XCUIElement *alert = [[self descendantsMatchingType:XCUIElementTypeAny] - matchingPredicate:alertCollectorPredicate].fb_firstMatch; + matchingPredicate:alertCollectorPredicate].allElementsBoundByIndex.firstObject; if (nil == alert) { return nil; } diff --git a/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m b/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m index 5756a630b..022df5b9d 100644 --- a/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +++ b/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m @@ -192,7 +192,7 @@ - (NSString *)fb_xmlRepresentationWithOptions:(FBXMLGenerationOptions *)options - (NSString *)fb_descriptionRepresentation { NSMutableArray *childrenDescriptions = [NSMutableArray array]; - for (XCUIElement *child in [self.fb_query childrenMatchingType:XCUIElementTypeAny].allElementsBoundByAccessibilityElement) { + for (XCUIElement *child in [self.fb_query childrenMatchingType:XCUIElementTypeAny].allElementsBoundByIndex) { [childrenDescriptions addObject:child.debugDescription]; } // debugDescription property of XCUIApplication instance shows descendants addresses in memory diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m b/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m index d5198b0d3..16b5eb190 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m @@ -50,7 +50,7 @@ - (XCUIElement *)fb_stableInstance NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id snapshot, NSDictionary *bindings) { return [[FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot] isEqualToString:uid]; }]; - return [query matchingPredicate:predicate].fb_firstMatch ?: self; + return [query matchingPredicate:predicate].allElementsBoundByIndex.firstObject ?: self; } @end diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m b/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m index 9d20c1f2b..bd8c8135c 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m @@ -132,11 +132,11 @@ @implementation XCUIElement (FBUtilities) if (0 == snapshots.count) { return @[]; } - NSMutableArray *sortedIds = [NSMutableArray new]; + NSMutableArray *matchedIds = [NSMutableArray new]; for (id snapshot in snapshots) { NSString *uid = [FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot]; if (nil != uid) { - [sortedIds addObject:uid]; + [matchedIds addObject:uid]; } } NSMutableArray *matchedElements = [NSMutableArray array]; @@ -146,11 +146,13 @@ @implementation XCUIElement (FBUtilities) ? [FBXCElementSnapshotWrapper wdUIDWithSnapshot:self.lastSnapshot] : self.fb_uid; } - if ([sortedIds containsObject:uid]) { + if (nil != uid && [matchedIds containsObject:uid]) { + XCUIElement *stableSelf = self.fb_stableInstance; + stableSelf.fb_isResolvedNatively = @NO; if (1 == snapshots.count) { - return @[self]; + return @[stableSelf]; } - [matchedElements addObject:self]; + [matchedElements addObject:stableSelf]; } XCUIElementType type = XCUIElementTypeAny; NSArray *uniqueTypes = [snapshots valueForKeyPath:[NSString stringWithFormat:@"@distinctUnionOfObjects.%@", FBStringify(XCUIElement, elementType)]]; @@ -161,34 +163,13 @@ @implementation XCUIElement (FBUtilities) ? [self.fb_query childrenMatchingType:type] : [self.fb_query descendantsMatchingType:type]; NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id snapshot, NSDictionary *bindings) { - return [sortedIds containsObject:[FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot] ?: @""]; + return [matchedIds containsObject:[FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot] ?: @""]; }]; - query = [query matchingPredicate:predicate]; - if (1 == snapshots.count) { - XCUIElement *result = query.fb_firstMatch; - result.fb_isResolvedNatively = @NO; - return result ? @[result] : @[]; - } - // Rely here on the fact, that XPath always returns query results in the same - // order they appear in the document, which means we don't need to resort the resulting - // array. Although, if it turns out this is still not the case then we could always - // uncomment the sorting procedure below: - // query = [query sorted:(id)^NSComparisonResult(XCElementSnapshot *a, XCElementSnapshot *b) { - // NSUInteger first = [sortedIds indexOfObject:a.wdUID]; - // NSUInteger second = [sortedIds indexOfObject:b.wdUID]; - // if (first < second) { - // return NSOrderedAscending; - // } - // if (first > second) { - // return NSOrderedDescending; - // } - // return NSOrderedSame; - // }]; - NSArray *result = query.fb_allMatches; - for (XCUIElement *el in result) { + [matchedElements addObjectsFromArray:[query matchingPredicate:predicate].allElementsBoundByIndex]; + for (XCUIElement *el in matchedElements) { el.fb_isResolvedNatively = @NO; } - return result; + return matchedElements.copy; } - (void)fb_waitUntilStable diff --git a/WebDriverAgentLib/Commands/FBElementCommands.m b/WebDriverAgentLib/Commands/FBElementCommands.m index bb175e59e..d5feca45e 100644 --- a/WebDriverAgentLib/Commands/FBElementCommands.m +++ b/WebDriverAgentLib/Commands/FBElementCommands.m @@ -386,9 +386,11 @@ + (NSArray *)routes // what ios-driver did and sadly, we must copy them. NSString *const name = request.arguments[@"name"]; if (name) { - XCUIElement *childElement = [[[[element.fb_query descendantsMatchingType:XCUIElementTypeAny] matchingIdentifier:name] allElementsBoundByAccessibilityElement] lastObject]; + XCUIElement *childElement = [[[[element.fb_query descendantsMatchingType:XCUIElementTypeAny] + matchingIdentifier:name] allElementsBoundByIndex] lastObject]; if (!childElement) { - return FBResponseWithStatus([FBCommandStatus noSuchElementErrorWithMessage:[NSString stringWithFormat:@"'%@' identifier didn't match any elements", name] traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]); + return FBResponseWithStatus([FBCommandStatus noSuchElementErrorWithMessage:[NSString stringWithFormat:@"'%@' identifier didn't match any elements", name] + traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]); } return [self.class handleScrollElementToVisible:childElement withRequest:request]; } @@ -413,9 +415,11 @@ + (NSArray *)routes if (predicateString) { NSPredicate *formattedPredicate = [NSPredicate fb_snapshotBlockPredicateWithPredicate:[NSPredicate predicateWithFormat:predicateString]]; - XCUIElement *childElement = [[[[element.fb_query descendantsMatchingType:XCUIElementTypeAny] matchingPredicate:formattedPredicate] allElementsBoundByAccessibilityElement] lastObject]; + XCUIElement *childElement = [[[[element.fb_query descendantsMatchingType:XCUIElementTypeAny] + matchingPredicate:formattedPredicate] allElementsBoundByIndex] lastObject]; if (!childElement) { - return FBResponseWithStatus([FBCommandStatus noSuchElementErrorWithMessage:[NSString stringWithFormat:@"'%@' predicate didn't match any elements", predicateString] traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]); + return FBResponseWithStatus([FBCommandStatus noSuchElementErrorWithMessage:[NSString stringWithFormat:@"'%@' predicate didn't match any elements", predicateString] + traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]); } return [self.class handleScrollElementToVisible:childElement withRequest:request]; } @@ -675,7 +679,7 @@ + (XCUICoordinate *)gestureCoordinateWithCoordinate:(CGPoint)coordinate */ XCUIElement *element = application; if (isSDKVersionGreaterThanOrEqualTo(@"11.0")) { - XCUIElement *window = application.windows.fb_firstMatch; + XCUIElement *window = application.windows.allElementsBoundByIndex.firstObject; if (window) { element = window; id snapshot = element.fb_cachedSnapshot ?: element.fb_takeSnapshot; diff --git a/WebDriverAgentLib/FBAlert.m b/WebDriverAgentLib/FBAlert.m index cc46918b5..705ab3ccc 100644 --- a/WebDriverAgentLib/FBAlert.m +++ b/WebDriverAgentLib/FBAlert.m @@ -245,7 +245,7 @@ - (BOOL)clickAlertButton:(NSString *)label error:(NSError **)error NSPredicate *predicate = [NSPredicate predicateWithFormat:@"label == %@", label]; XCUIElement *requestedButton = [[self.alertElement descendantsMatchingType:XCUIElementTypeButton] - matchingPredicate:predicate].fb_firstMatch; + matchingPredicate:predicate].allElementsBoundByIndex.firstObject; if (!requestedButton) { return [[[FBErrorBuilder builder] withDescriptionFormat:@"Failed to find button with label '%@' for alert: %@", label, self.alertElement] diff --git a/WebDriverAgentLib/Utilities/FBScreen.m b/WebDriverAgentLib/Utilities/FBScreen.m index 1ca356b83..81e7b930c 100644 --- a/WebDriverAgentLib/Utilities/FBScreen.m +++ b/WebDriverAgentLib/Utilities/FBScreen.m @@ -31,7 +31,7 @@ + (CGSize)statusBarSizeForApplication:(XCUIApplication *)application expectVisibleBar = NO; } - XCUIElement *mainStatusBar = app.statusBars.fb_firstMatch; + XCUIElement *mainStatusBar = app.statusBars.allElementsBoundByIndex.firstObject; if (!mainStatusBar || (expectVisibleBar && !mainStatusBar.fb_isVisible)) { return CGSizeZero; } diff --git a/WebDriverAgentLib/Utilities/FBXCodeCompatibility.m b/WebDriverAgentLib/Utilities/FBXCodeCompatibility.m index 999802aab..911c5ec85 100644 --- a/WebDriverAgentLib/Utilities/FBXCodeCompatibility.m +++ b/WebDriverAgentLib/Utilities/FBXCodeCompatibility.m @@ -65,10 +65,11 @@ - (XCElementSnapshot *)fb_uniqueSnapshotWithError:(NSError **)error - (XCUIElement *)fb_firstMatch { - XCUIElement* match = FBConfiguration.useFirstMatch - ? self.firstMatch - : self.fb_allMatches.firstObject; - return [match exists] ? match : nil; + if (FBConfiguration.useFirstMatch) { + XCUIElement* match = self.firstMatch; + return [match exists] ? match : nil; + } + return self.fb_allMatches.firstObject; } - (NSArray *)fb_allMatches diff --git a/WebDriverAgentTests/IntegrationTests/FBAppiumTouchActionsIntegrationTests.m b/WebDriverAgentTests/IntegrationTests/FBAppiumTouchActionsIntegrationTests.m index bcfef8741..161fc788b 100644 --- a/WebDriverAgentTests/IntegrationTests/FBAppiumTouchActionsIntegrationTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBAppiumTouchActionsIntegrationTests.m @@ -298,7 +298,7 @@ - (void)setUp [self launchApplication]; [self goToAttributesPage]; }); - self.pickerWheel = self.testedApplication.pickerWheels.fb_firstMatch; + self.pickerWheel = self.testedApplication.pickerWheels.allElementsBoundByIndex.firstObject; } - (void)tearDown diff --git a/WebDriverAgentTests/IntegrationTests/FBElementAttributeTests.m b/WebDriverAgentTests/IntegrationTests/FBElementAttributeTests.m index fe0ffb1b1..bc0966f91 100644 --- a/WebDriverAgentTests/IntegrationTests/FBElementAttributeTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBElementAttributeTests.m @@ -61,7 +61,7 @@ - (void)testContainerAccessibilityAttributes - (void)testIgnoredAccessibilityAttributes { // Images are neither accessibility elements nor contain them, so both checks should fail - XCUIElement *imageElement = self.testedApplication.images.fb_firstMatch; + XCUIElement *imageElement = self.testedApplication.images.allElementsBoundByIndex.firstObject; XCTAssertTrue(imageElement.exists); XCTAssertFalse(imageElement.fb_isAccessibilityElement); XCTAssertFalse(imageElement.isWDAccessibilityContainer); diff --git a/WebDriverAgentTests/IntegrationTests/FBElementVisibilityTests.m b/WebDriverAgentTests/IntegrationTests/FBElementVisibilityTests.m index d63b3b3b6..ea4fa2cee 100644 --- a/WebDriverAgentTests/IntegrationTests/FBElementVisibilityTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBElementVisibilityTests.m @@ -36,7 +36,7 @@ - (void)testSpringBoardIcons XCTAssertTrue(self.springboard.icons[@"Reminders"].fb_isVisible); // Check Icons on second screen screen - XCTAssertFalse(self.springboard.icons[@"IntegrationApp"].query.fb_firstMatch.fb_isVisible); + XCTAssertFalse(self.springboard.icons[@"IntegrationApp"].firstMatch.fb_isVisible); } - (void)testSpringBoardSubfolder @@ -59,7 +59,7 @@ - (void)disabled_testIconsFromSearchDashboard XCTAssertFalse(self.springboard.icons[@"Reminders"].fb_isVisible); XCTAssertFalse([[[self.springboard descendantsMatchingType:XCUIElementTypeIcon] matchingIdentifier:@"IntegrationApp"] - fb_firstMatch].fb_isVisible); + firstMatch].fb_isVisible); } - (void)testTableViewCells @@ -72,8 +72,8 @@ - (void)testTableViewCells [self launchApplication]; [self goToScrollPageWithCells:YES]; for (int i = 0 ; i < 10 ; i++) { - FBAssertWaitTillBecomesTrue(self.testedApplication.cells.allElementsBoundByAccessibilityElement[i].fb_isVisible); - FBAssertWaitTillBecomesTrue(self.testedApplication.staticTexts.allElementsBoundByAccessibilityElement[i].fb_isVisible); + FBAssertWaitTillBecomesTrue(self.testedApplication.cells.allElementsBoundByIndex[i].fb_isVisible); + FBAssertWaitTillBecomesTrue(self.testedApplication.staticTexts.allElementsBoundByIndex[i].fb_isVisible); } } diff --git a/WebDriverAgentTests/IntegrationTests/FBPasteboardTests.m b/WebDriverAgentTests/IntegrationTests/FBPasteboardTests.m index 4f407aa64..af3951f2c 100644 --- a/WebDriverAgentTests/IntegrationTests/FBPasteboardTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBPasteboardTests.m @@ -44,7 +44,7 @@ - (void)testSetPasteboard if (![pastItemsQuery.firstMatch waitForExistenceWithTimeout:2.0]) { XCTFail(@"No matched element named 'Paste'"); } - XCUIElement *pasteItem = pastItemsQuery.fb_firstMatch; + XCUIElement *pasteItem = pastItemsQuery.firstMatch; XCTAssertNotNil(pasteItem); [pasteItem tap]; FBAssertWaitTillBecomesTrue([textField.value isEqualToString:text]); diff --git a/WebDriverAgentTests/IntegrationTests/FBPickerWheelSelectTests.m b/WebDriverAgentTests/IntegrationTests/FBPickerWheelSelectTests.m index acea0b284..b9db49243 100644 --- a/WebDriverAgentTests/IntegrationTests/FBPickerWheelSelectTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBPickerWheelSelectTests.m @@ -33,7 +33,7 @@ - (void)setUp - (void)testSelectNextPickerValue { - XCUIElement *element = self.testedApplication.pickerWheels.fb_firstMatch; + XCUIElement *element = self.testedApplication.pickerWheels.allElementsBoundByIndex.firstObject; XCTAssertTrue(element.exists); XCTAssertEqualObjects(element.wdType, @"XCUIElementTypePickerWheel"); NSError *error; diff --git a/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m b/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m index 75ec24bed..ceaf3ed9c 100644 --- a/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m @@ -415,7 +415,7 @@ - (void)setUp [self launchApplication]; [self goToAttributesPage]; }); - self.pickerWheel = self.testedApplication.pickerWheels.fb_firstMatch; + self.pickerWheel = self.testedApplication.pickerWheels.allElementsBoundByIndex.firstObject; } - (void)tearDown diff --git a/WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m b/WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m index 87a66fb25..22983faa6 100644 --- a/WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m @@ -41,7 +41,7 @@ - (void)setUp - (id)destinationSnapshot { - XCUIElement *matchingElement = self.testedView.buttons.fb_firstMatch; + XCUIElement *matchingElement = self.testedView.buttons.allElementsBoundByIndex.firstObject; FBAssertWaitTillBecomesTrue(nil != matchingElement.fb_takeSnapshot); id snapshot = matchingElement.fb_takeSnapshot; diff --git a/WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m b/WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m index b727a20a0..202c48ba9 100644 --- a/WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m +++ b/WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m @@ -48,7 +48,8 @@ - (void)testDescendantsWithClassName @"Deadlock app", @"Touch", ]]; - NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingClassName:@"XCUIElementTypeButton" shouldReturnAfterFirstMatch:NO]; + NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingClassName:@"XCUIElementTypeButton" + shouldReturnAfterFirstMatch:NO]; XCTAssertEqual(matchingSnapshots.count, expectedLabels.count); NSArray *labels = [matchingSnapshots valueForKeyPath:@"@distinctUnionOfObjects.label"]; XCTAssertEqualObjects([NSSet setWithArray:labels], expectedLabels); @@ -60,14 +61,16 @@ - (void)testDescendantsWithClassName - (void)testSingleDescendantWithClassName { - NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingClassName:@"XCUIElementTypeButton" shouldReturnAfterFirstMatch:YES]; + NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingClassName:@"XCUIElementTypeButton" + shouldReturnAfterFirstMatch:YES]; XCTAssertEqual(matchingSnapshots.count, 1); XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton); } - (void)testDescendantsWithIdentifier { - NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingIdentifier:@"Alerts" shouldReturnAfterFirstMatch:NO]; + NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingIdentifier:@"Alerts" + shouldReturnAfterFirstMatch:NO]; int snapshotsCount = 1; if (@available(iOS 13.0, *)) { snapshotsCount = 2; @@ -81,7 +84,8 @@ - (void)testDescendantsWithIdentifier - (void)testSingleDescendantWithIdentifier { - NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingIdentifier:@"Alerts" shouldReturnAfterFirstMatch:YES]; + NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingIdentifier:@"Alerts" + shouldReturnAfterFirstMatch:YES]; XCTAssertEqual(matchingSnapshots.count, 1); XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton); XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts"); @@ -89,7 +93,8 @@ - (void)testSingleDescendantWithIdentifier - (void)testStableInstance { - NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingIdentifier:@"Alerts" shouldReturnAfterFirstMatch:YES]; + NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingIdentifier:@"Alerts" + shouldReturnAfterFirstMatch:YES]; XCTAssertEqual(matchingSnapshots.count, 1); for (XCUIElement *el in @[matchingSnapshots.lastObject, matchingSnapshots.lastObject.fb_stableInstance]) { XCTAssertEqual(el.elementType, XCUIElementTypeButton); @@ -105,7 +110,8 @@ - (void)testSingleDescendantWithMissingIdentifier - (void)testDescendantsWithXPathQuery { - NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton[@label='Alerts']" shouldReturnAfterFirstMatch:NO]; + NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton[@label='Alerts']" + shouldReturnAfterFirstMatch:NO]; XCTAssertEqual(matchingSnapshots.count, 1); XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton); XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts"); @@ -113,14 +119,16 @@ - (void)testDescendantsWithXPathQuery - (void)testSelfWithXPathQuery { - NSArray *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeApplication" shouldReturnAfterFirstMatch:NO]; + NSArray *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeApplication" + shouldReturnAfterFirstMatch:NO]; XCTAssertEqual(matchingSnapshots.count, 1); XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeApplication); } - (void)testSingleDescendantWithXPathQuery { - NSArray *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton" shouldReturnAfterFirstMatch:YES]; + NSArray *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton" + shouldReturnAfterFirstMatch:YES]; XCTAssertEqual(matchingSnapshots.count, 1); XCUIElement *matchingSnapshot = [matchingSnapshots firstObject]; XCTAssertNotNil(matchingSnapshot); @@ -130,26 +138,30 @@ - (void)testSingleDescendantWithXPathQuery - (void)testSingleDescendantWithXPathQueryNoMatches { - XCUIElement *matchingSnapshot = [[self.testedView fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButtonnn" shouldReturnAfterFirstMatch:YES] firstObject]; + XCUIElement *matchingSnapshot = [[self.testedView fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButtonnn" + shouldReturnAfterFirstMatch:YES] firstObject]; XCTAssertNil(matchingSnapshot); } - (void)testSingleLastDescendantWithXPathQuery { - XCUIElement *matchingSnapshot = [[self.testedView fb_descendantsMatchingXPathQuery:@"(//XCUIElementTypeButton)[last()]" shouldReturnAfterFirstMatch:YES] firstObject]; + XCUIElement *matchingSnapshot = [[self.testedView fb_descendantsMatchingXPathQuery:@"(//XCUIElementTypeButton)[last()]" + shouldReturnAfterFirstMatch:YES] firstObject]; XCTAssertNotNil(matchingSnapshot); XCTAssertEqual(matchingSnapshot.elementType, XCUIElementTypeButton); } - (void)testDescendantsWithXPathQueryNoMatches { - NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton[@label='Alerts1']" shouldReturnAfterFirstMatch:NO]; + NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton[@label='Alerts1']" + shouldReturnAfterFirstMatch:NO]; XCTAssertEqual(matchingSnapshots.count, 0); } - (void)testDescendantsWithComplexXPathQuery { - NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingXPathQuery:@"//*[@label='Scrolling']/preceding::*[boolean(string(@label))]" shouldReturnAfterFirstMatch:NO]; + NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingXPathQuery:@"//*[@label='Scrolling']/preceding::*[boolean(string(@label))]" + shouldReturnAfterFirstMatch:NO]; int snapshotsCount = 3; if (@available(iOS 13.0, *)) { snapshotsCount = 6; @@ -159,13 +171,15 @@ - (void)testDescendantsWithComplexXPathQuery - (void)testDescendantsWithWrongXPathQuery { - XCTAssertThrowsSpecificNamed([self.testedView fb_descendantsMatchingXPathQuery:@"//*[blabla(@label, Scrolling')]" shouldReturnAfterFirstMatch:NO], + XCTAssertThrowsSpecificNamed([self.testedView fb_descendantsMatchingXPathQuery:@"//*[blabla(@label, Scrolling')]" + shouldReturnAfterFirstMatch:NO], NSException, FBInvalidXPathException); } - (void)testFirstDescendantWithWrongXPathQuery { - XCTAssertThrowsSpecificNamed([self.testedView fb_descendantsMatchingXPathQuery:@"//*[blabla(@label, Scrolling')]" shouldReturnAfterFirstMatch:YES], + XCTAssertThrowsSpecificNamed([self.testedView fb_descendantsMatchingXPathQuery:@"//*[blabla(@label, Scrolling')]" + shouldReturnAfterFirstMatch:YES], NSException, FBInvalidXPathException); } @@ -200,7 +214,8 @@ - (void)testDescendantsWithPredicateString - (void)testSelfWithPredicateString { NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type == 'XCUIElementTypeApplication'"]; - NSArray *matchingSnapshots = [self.testedApplication fb_descendantsMatchingPredicate:predicate shouldReturnAfterFirstMatch:NO]; + NSArray *matchingSnapshots = [self.testedApplication fb_descendantsMatchingPredicate:predicate + shouldReturnAfterFirstMatch:NO]; XCTAssertEqual(matchingSnapshots.count, 1); XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeApplication); } @@ -223,7 +238,9 @@ - (void)testSingleDescendantWithPredicateStringByIndex - (void)testDescendantsWithPropertyStrict { - NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingProperty:@"label" value:@"Alert" partialSearch:NO]; + NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingProperty:@"label" + value:@"Alert" + partialSearch:NO]; XCTAssertEqual(matchingSnapshots.count, 0); matchingSnapshots = [self.testedView fb_descendantsMatchingProperty:@"label" value:@"Alerts" partialSearch:NO]; int snapshotsCount = 1; @@ -237,7 +254,9 @@ - (void)testDescendantsWithPropertyStrict - (void)testGlobalWithPropertyStrict { - NSArray *matchingSnapshots = [self.testedApplication fb_descendantsMatchingProperty:@"label" value:@"Alert" partialSearch:NO]; + NSArray *matchingSnapshots = [self.testedApplication fb_descendantsMatchingProperty:@"label" + value:@"Alert" + partialSearch:NO]; XCTAssertEqual(matchingSnapshots.count, 0); matchingSnapshots = [self.testedApplication fb_descendantsMatchingProperty:@"label" value:@"Alerts" partialSearch:NO]; int snapshotsCount = 1; @@ -251,7 +270,9 @@ - (void)testGlobalWithPropertyStrict - (void)testDescendantsWithPropertyPartial { - NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingProperty:@"label" value:@"Alerts" partialSearch:NO]; + NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingProperty:@"label" + value:@"Alerts" + partialSearch:NO]; int snapshotsCount = 1; if (@available(iOS 13.0, *)) { snapshotsCount = 2; @@ -265,7 +286,8 @@ - (void)testDescendantsWithClassChain { NSArray *matchingSnapshots; NSString *queryString =@"XCUIElementTypeWindow/XCUIElementTypeOther/**/XCUIElementTypeButton"; - matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString shouldReturnAfterFirstMatch:NO]; + matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString + shouldReturnAfterFirstMatch:NO]; XCTAssertEqual(matchingSnapshots.count, 5); // /XCUIElementTypeButton for (XCUIElement *matchingSnapshot in matchingSnapshots) { XCTAssertEqual(matchingSnapshot.elementType, XCUIElementTypeButton); @@ -279,14 +301,17 @@ - (void)testDescendantsWithClassChainWithIndex if (@available(iOS 13.0, *)) { // iPhone queryString = @"XCUIElementTypeWindow/*/*/*/*[2]/*/*/XCUIElementTypeButton"; - matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString shouldReturnAfterFirstMatch:NO]; + matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString + shouldReturnAfterFirstMatch:NO]; if (matchingSnapshots.count == 0) { // iPad queryString = @"XCUIElementTypeWindow/*/*/*/*/*[2]/*/*/XCUIElementTypeButton"; - matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString shouldReturnAfterFirstMatch:NO]; + matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString + shouldReturnAfterFirstMatch:NO]; } } else { - matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString shouldReturnAfterFirstMatch:NO]; + matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString + shouldReturnAfterFirstMatch:NO]; } XCTAssertEqual(matchingSnapshots.count, 5); // /XCUIElementTypeButton for (XCUIElement *matchingSnapshot in matchingSnapshots) { @@ -298,7 +323,8 @@ - (void)testDescendantsWithClassChainAndPredicates { NSArray *matchingSnapshots; NSString *queryString = @"XCUIElementTypeWindow/**/XCUIElementTypeButton[`label BEGINSWITH 'A'`]"; - matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString shouldReturnAfterFirstMatch:NO]; + matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString + shouldReturnAfterFirstMatch:NO]; XCTAssertEqual(matchingSnapshots.count, 2); XCTAssertEqualObjects([matchingSnapshots firstObject].label, @"Alerts"); XCTAssertEqualObjects([matchingSnapshots lastObject].label, @"Attributes"); @@ -307,8 +333,10 @@ - (void)testDescendantsWithClassChainAndPredicates - (void)testDescendantsWithIndirectClassChainAndPredicates { NSString *queryString = @"XCUIElementTypeWindow/**/XCUIElementTypeButton[`label BEGINSWITH 'A'`]"; - NSArray *simpleQueryMatches = [self.testedApplication fb_descendantsMatchingClassChain:queryString shouldReturnAfterFirstMatch:NO]; - NSArray *deepQueryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"XCUIElementTypeWindow/**/XCUIElementTypeButton[`label BEGINSWITH 'A'`]" shouldReturnAfterFirstMatch:NO]; + NSArray *simpleQueryMatches = [self.testedApplication fb_descendantsMatchingClassChain:queryString + shouldReturnAfterFirstMatch:NO]; + NSArray *deepQueryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"XCUIElementTypeWindow/**/XCUIElementTypeButton[`label BEGINSWITH 'A'`]" + shouldReturnAfterFirstMatch:NO]; XCTAssertEqual(simpleQueryMatches.count, deepQueryMatches.count); XCTAssertEqualObjects([simpleQueryMatches firstObject].label, [deepQueryMatches firstObject].label); XCTAssertEqualObjects([simpleQueryMatches lastObject].label, [deepQueryMatches lastObject].label); @@ -316,8 +344,10 @@ - (void)testDescendantsWithIndirectClassChainAndPredicates - (void)testClassChainWithDescendantPredicate { - NSArray *simpleQueryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"XCUIElementTypeWindow/*/*[1]" shouldReturnAfterFirstMatch:NO]; - NSArray *predicateQueryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"XCUIElementTypeWindow/*/*[$type == 'XCUIElementTypeButton' AND label BEGINSWITH 'A'$]" shouldReturnAfterFirstMatch:NO]; + NSArray *simpleQueryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"XCUIElementTypeWindow/*/*[1]" + shouldReturnAfterFirstMatch:NO]; + NSArray *predicateQueryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"XCUIElementTypeWindow/*/*[$type == 'XCUIElementTypeButton' AND label BEGINSWITH 'A'$]" + shouldReturnAfterFirstMatch:NO]; XCTAssertEqual(simpleQueryMatches.count, predicateQueryMatches.count); XCTAssertEqual([simpleQueryMatches firstObject].elementType, [predicateQueryMatches firstObject].elementType); XCTAssertEqual([simpleQueryMatches lastObject].elementType, [predicateQueryMatches lastObject].elementType); @@ -325,7 +355,8 @@ - (void)testClassChainWithDescendantPredicate - (void)testSingleDescendantWithComplexIndirectClassChain { - NSArray *queryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"**/*/XCUIElementTypeButton[2]" shouldReturnAfterFirstMatch:NO]; + NSArray *queryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"**/*/XCUIElementTypeButton[2]" + shouldReturnAfterFirstMatch:NO]; XCTAssertEqual(queryMatches.count, 1); XCTAssertEqual(queryMatches.lastObject.elementType, XCUIElementTypeButton); XCTAssertEqualObjects(queryMatches.lastObject.label, @"Deadlock app"); @@ -333,7 +364,8 @@ - (void)testSingleDescendantWithComplexIndirectClassChain - (void)testSingleDescendantWithComplexIndirectClassChainAndZeroMatches { - NSArray *queryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"**/*/XCUIElementTypeWindow" shouldReturnAfterFirstMatch:NO]; + NSArray *queryMatches = [self.testedApplication fb_descendantsMatchingClassChain:@"**/*/XCUIElementTypeWindow" + shouldReturnAfterFirstMatch:NO]; XCTAssertEqual(queryMatches.count, 0); } @@ -341,14 +373,16 @@ - (void)testDescendantsWithClassChainAndPredicatesAndIndexes { NSArray *matchingSnapshots; NSString *queryString = @"XCUIElementTypeWindow[`name != 'bla'`]/**/XCUIElementTypeButton[`label BEGINSWITH \"A\"`][1]"; - matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString shouldReturnAfterFirstMatch:NO]; + matchingSnapshots = [self.testedApplication fb_descendantsMatchingClassChain:queryString + shouldReturnAfterFirstMatch:NO]; XCTAssertEqual(matchingSnapshots.count, 1); XCTAssertEqualObjects([matchingSnapshots firstObject].label, @"Alerts"); } - (void)testSingleDescendantWithClassChain { - NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingClassChain:@"XCUIElementTypeButton" shouldReturnAfterFirstMatch:YES]; + NSArray *matchingSnapshots = [self.testedView fb_descendantsMatchingClassChain:@"XCUIElementTypeButton" + shouldReturnAfterFirstMatch:YES]; XCTAssertEqual(matchingSnapshots.count, 1); XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton); @@ -358,19 +392,22 @@ - (void)testSingleDescendantWithClassChain - (void)testSingleDescendantWithClassChainAndNegativeIndex { NSArray *matchingSnapshots; - matchingSnapshots = [self.testedView fb_descendantsMatchingClassChain:@"XCUIElementTypeButton[-1]" shouldReturnAfterFirstMatch:YES]; + matchingSnapshots = [self.testedView fb_descendantsMatchingClassChain:@"XCUIElementTypeButton[-1]" + shouldReturnAfterFirstMatch:YES]; XCTAssertEqual(matchingSnapshots.count, 1); XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeButton); XCTAssertTrue([matchingSnapshots.lastObject.label isEqualToString:@"Touch"]); - matchingSnapshots = [self.testedView fb_descendantsMatchingClassChain:@"XCUIElementTypeButton[-10]" shouldReturnAfterFirstMatch:YES]; + matchingSnapshots = [self.testedView fb_descendantsMatchingClassChain:@"XCUIElementTypeButton[-10]" + shouldReturnAfterFirstMatch:YES]; XCTAssertEqual(matchingSnapshots.count, 0); } - (void)testInvalidQueryWithClassChain { - XCTAssertThrowsSpecificNamed([self.testedView fb_descendantsMatchingClassChain:@"NoXCUIElementTypePrefix" shouldReturnAfterFirstMatch:YES], + XCTAssertThrowsSpecificNamed([self.testedView fb_descendantsMatchingClassChain:@"NoXCUIElementTypePrefix" + shouldReturnAfterFirstMatch:YES], NSException, FBClassChainQueryParseException); } @@ -384,7 +421,8 @@ - (void)testHandleInvalidQueryWithClassChainAsNoElementWithoutError - (void)testClassChainWithInvalidPredicate { - XCTAssertThrowsSpecificNamed([self.testedApplication fb_descendantsMatchingClassChain:@"XCUIElementTypeWindow[`bla != 'bla'`]" shouldReturnAfterFirstMatch:NO], + XCTAssertThrowsSpecificNamed([self.testedApplication fb_descendantsMatchingClassChain:@"XCUIElementTypeWindow[`bla != 'bla'`]" + shouldReturnAfterFirstMatch:NO], NSException, FBUnknownAttributeException);; } @@ -411,8 +449,10 @@ - (void)testNestedQueryWithClassChain queryString = @"XCUIElementTypePicker"; } FBAssertWaitTillBecomesTrue(self.testedApplication.buttons[@"Button"].fb_isVisible); - XCUIElement *datePicker = [self.testedApplication descendantsMatchingType:XCUIElementTypeDatePicker].fb_firstMatch; - NSArray *matches = [datePicker fb_descendantsMatchingClassChain:queryString shouldReturnAfterFirstMatch:NO]; + XCUIElement *datePicker = [self.testedApplication + descendantsMatchingType:XCUIElementTypeDatePicker].allElementsBoundByIndex.firstObject; + NSArray *matches = [datePicker fb_descendantsMatchingClassChain:queryString + shouldReturnAfterFirstMatch:NO]; XCTAssertEqual(matches.count, 1); XCUIElementType expectedType = XCUIElementTypeOther; @@ -440,7 +480,8 @@ - (void)setUp - (void)testInvisibleDescendantWithXPathQuery { - NSArray *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeStaticText[@visible='false']" shouldReturnAfterFirstMatch:NO]; + NSArray *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeStaticText[@visible='false']" + shouldReturnAfterFirstMatch:NO]; XCTAssertGreaterThan(matchingSnapshots.count, 1); XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeStaticText); XCTAssertFalse(matchingSnapshots.lastObject.fb_isVisible); diff --git a/WebDriverAgentTests/IntegrationTests/XCUIElementHelperIntegrationTests.m b/WebDriverAgentTests/IntegrationTests/XCUIElementHelperIntegrationTests.m index c145ea32b..f2d6d3a60 100644 --- a/WebDriverAgentTests/IntegrationTests/XCUIElementHelperIntegrationTests.m +++ b/WebDriverAgentTests/IntegrationTests/XCUIElementHelperIntegrationTests.m @@ -32,9 +32,9 @@ - (void)setUp - (void)testDescendantsFiltering { - NSArray *buttons = self.testedApplication.buttons.allElementsBoundByAccessibilityElement; + NSArray *buttons = self.testedApplication.buttons.allElementsBoundByIndex; XCTAssertTrue(buttons.count > 0); - NSArray *windows = self.testedApplication.windows.allElementsBoundByAccessibilityElement; + NSArray *windows = self.testedApplication.windows.allElementsBoundByIndex; XCTAssertTrue(windows.count > 0); NSMutableArray *allElements = [NSMutableArray array]; From 2f4b3273ca2efc3e84b35988a2ef2b44a8ae305f Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 25 Nov 2022 19:45:21 +0000 Subject: [PATCH 054/240] chore(release): 4.10.10 [skip ci] ## [4.10.10](https://github.com/appium/WebDriverAgent/compare/v4.10.9...v4.10.10) (2022-11-25) ### Bug Fixes * Only check existence if firstMatch is applied ([#638](https://github.com/appium/WebDriverAgent/issues/638)) ([5394fe8](https://github.com/appium/WebDriverAgent/commit/5394fe8cc2eda3d1668685bd00f9f7383e122627)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index abba0c5ed..b07361853 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.10.10](https://github.com/appium/WebDriverAgent/compare/v4.10.9...v4.10.10) (2022-11-25) + + +### Bug Fixes + +* Only check existence if firstMatch is applied ([#638](https://github.com/appium/WebDriverAgent/issues/638)) ([5394fe8](https://github.com/appium/WebDriverAgent/commit/5394fe8cc2eda3d1668685bd00f9f7383e122627)) + ## [4.10.9](https://github.com/appium/WebDriverAgent/compare/v4.10.8...v4.10.9) (2022-11-25) ## [4.10.8](https://github.com/appium/WebDriverAgent/compare/v4.10.7...v4.10.8) (2022-11-24) diff --git a/package.json b/package.json index 43dc8d70c..57bbcec28 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.9", + "version": "4.10.10", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From c8e10649317f460cf2cb7a1c133f8b422069da67 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Nov 2022 13:41:12 +0100 Subject: [PATCH 055/240] chore(deps-dev): bump sinon from 14.0.2 to 15.0.0 (#639) Bumps [sinon](https://github.com/sinonjs/sinon) from 14.0.2 to 15.0.0. - [Release notes](https://github.com/sinonjs/sinon/releases) - [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md) - [Commits](https://github.com/sinonjs/sinon/compare/v14.0.2...v15.0.0) --- updated-dependencies: - dependency-name: sinon dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 57bbcec28..a41673d31 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "pre-commit": "^1.2.2", "prettier": "^2.7.1", "semantic-release": "^19.0.2", - "sinon": "^14.0.0" + "sinon": "^15.0.0" }, "dependencies": { "@appium/base-driver": "^8.7.3", From 99b8a7f8138e9b7faa660b243efa672c8f917287 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 29 Nov 2022 12:53:41 +0000 Subject: [PATCH 056/240] chore(release): 4.10.11 [skip ci] ## [4.10.11](https://github.com/appium/WebDriverAgent/compare/v4.10.10...v4.10.11) (2022-11-29) --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b07361853..cbc76861b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [4.10.11](https://github.com/appium/WebDriverAgent/compare/v4.10.10...v4.10.11) (2022-11-29) + ## [4.10.10](https://github.com/appium/WebDriverAgent/compare/v4.10.9...v4.10.10) (2022-11-25) diff --git a/package.json b/package.json index a41673d31..ed0dd2220 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.10", + "version": "4.10.11", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 72bd32780f26ae0f60b30e0cee8fc585aea600fe Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 8 Dec 2022 20:00:02 +0100 Subject: [PATCH 057/240] fix: Provide proper xcodebuild argument for tvOS (#640) --- lib/xcodebuild.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/xcodebuild.js b/lib/xcodebuild.js index aca528aab..df5cac008 100644 --- a/lib/xcodebuild.js +++ b/lib/xcodebuild.js @@ -161,9 +161,8 @@ class XcodeBuild { } async cleanProject () { - const tmpIsTvOS = isTvOS(this.platformName); - const libScheme = tmpIsTvOS ? LIB_SCHEME_TV : LIB_SCHEME_IOS; - const runnerScheme = tmpIsTvOS ? RUNNER_SCHEME_TV : RUNNER_SCHEME_IOS; + const libScheme = isTvOS(this.platformName) ? LIB_SCHEME_TV : LIB_SCHEME_IOS; + const runnerScheme = isTvOS(this.platformName) ? RUNNER_SCHEME_TV : RUNNER_SCHEME_IOS; for (const scheme of [libScheme, runnerScheme]) { this.log.debug(`Cleaning the project scheme '${scheme}' to make sure there are no leftovers from previous installs`); @@ -215,7 +214,9 @@ class XcodeBuild { const versionMatch = new RegExp(/^(\d+)\.(\d+)/).exec(this.platformVersion); if (versionMatch) { - args.push(`IPHONEOS_DEPLOYMENT_TARGET=${versionMatch[1]}.${versionMatch[2]}`); + args.push( + `${isTvOS(this.platformName) ? 'TV' : 'IPHONE'}OS_DEPLOYMENT_TARGET=${versionMatch[1]}.${versionMatch[2]}` + ); } else { this.log.warn(`Cannot parse major and minor version numbers from platformVersion "${this.platformVersion}". ` + 'Will build for the default platform instead'); From 2239f4b89ab8093660aae247e15944bb005990db Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 8 Dec 2022 19:09:05 +0000 Subject: [PATCH 058/240] chore(release): 4.10.12 [skip ci] ## [4.10.12](https://github.com/appium/WebDriverAgent/compare/v4.10.11...v4.10.12) (2022-12-08) ### Bug Fixes * Provide proper xcodebuild argument for tvOS ([#640](https://github.com/appium/WebDriverAgent/issues/640)) ([72bd327](https://github.com/appium/WebDriverAgent/commit/72bd32780f26ae0f60b30e0cee8fc585aea600fe)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cbc76861b..d61f40a95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.10.12](https://github.com/appium/WebDriverAgent/compare/v4.10.11...v4.10.12) (2022-12-08) + + +### Bug Fixes + +* Provide proper xcodebuild argument for tvOS ([#640](https://github.com/appium/WebDriverAgent/issues/640)) ([72bd327](https://github.com/appium/WebDriverAgent/commit/72bd32780f26ae0f60b30e0cee8fc585aea600fe)) + ## [4.10.11](https://github.com/appium/WebDriverAgent/compare/v4.10.10...v4.10.11) (2022-11-29) ## [4.10.10](https://github.com/appium/WebDriverAgent/compare/v4.10.9...v4.10.10) (2022-11-25) diff --git a/package.json b/package.json index ed0dd2220..6a06bda06 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.11", + "version": "4.10.12", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 21ca8b8771af3441b1b15a8b0cc60393136d8fc9 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Tue, 13 Dec 2022 09:04:47 -0800 Subject: [PATCH 059/240] chore: do not include WebDriverAgentRunner-Runner.app.zip in a package to reduce the package size (#641) --- package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/package.json b/package.json index 6a06bda06..8c136ee5f 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,6 @@ "prepare": "npm run build", "test": "mocha --exit --timeout 1m \"./test/unit/**/*-specs.js\"", "e2e-test": "mocha --exit --timeout 10m \"./test/functional/**/*-specs.js\"", - "prepublishOnly": "npm run bundle", "bundle": "node ./Scripts/build-webdriveragent.js", "fetch-prebuilt-wda": "node ./Scripts/fetch-prebuilt-wda.js" }, @@ -109,7 +108,6 @@ "WebDriverAgentRunner", "WebDriverAgentTests", "XCTWebDriverAgentLib", - "WebDriverAgentRunner-Runner.app.zip", "CHANGELOG.md" ] } From a439be74d42e93053010d7d0763ad4a40d1e2517 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 13 Dec 2022 17:15:36 +0000 Subject: [PATCH 060/240] chore(release): 4.10.13 [skip ci] ## [4.10.13](https://github.com/appium/WebDriverAgent/compare/v4.10.12...v4.10.13) (2022-12-13) --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d61f40a95..7f9880544 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [4.10.13](https://github.com/appium/WebDriverAgent/compare/v4.10.12...v4.10.13) (2022-12-13) + ## [4.10.12](https://github.com/appium/WebDriverAgent/compare/v4.10.11...v4.10.12) (2022-12-08) diff --git a/package.json b/package.json index 8c136ee5f..0c0fc3d09 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.12", + "version": "4.10.13", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From a0bfdbbb4300839179be6e1f3186a827993e0a3c Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Tue, 13 Dec 2022 15:54:15 -0800 Subject: [PATCH 061/240] chorre: update release-notes-generator (#642) --- .releaserc | 21 +++++++++++++++++++-- package.json | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/.releaserc b/.releaserc index e6cf22bff..0cb17f220 100644 --- a/.releaserc +++ b/.releaserc @@ -6,7 +6,24 @@ {"type": "chore", "release": "patch"} ] }], - "@semantic-release/release-notes-generator", + ["@semantic-release/release-notes-generator", { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + {"type": "feat", "section": "Features"}, + {"type": "fix", "section": "Bug Fixes"}, + {"type": "perf", "section": "Performance Improvements"}, + {"type": "revert", "section": "Reverts"}, + {"type": "chore", "section": "Miscellaneous Chores"}, + {"type": "refactor", "section": "Code Refactoring"}, + {"type": "docs", "section": "Documentation", "hidden": true}, + {"type": "style", "section": "Styles", "hidden": true}, + {"type": "test", "section": "Tests", "hidden": true}, + {"type": "build", "section": "Build System", "hidden": true}, + {"type": "ci", "section": "Continuous Integration", "hidden": true} + ] + } + }], ["@semantic-release/changelog", { "changelogFile": "CHANGELOG.md" }], @@ -19,6 +36,6 @@ "assets": [ "WebDriverAgentRunner-Runner.zip", "WebDriverAgentRunner_tvOS-Runner.zip" - ]}], + ]}] ] } diff --git a/package.json b/package.json index 0c0fc3d09..a473c9170 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "appium-xcode": "^4.0.1", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", + "conventional-changelog-conventionalcommits": "^5.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.5.0", "glob": "^8.0.1", From 3ca197ac7526036e408584207b26129847a615ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Dec 2022 16:44:05 +0100 Subject: [PATCH 062/240] chore(deps): bump @appium/support from 2.61.1 to 3.0.0 (#643) Bumps [@appium/support](https://github.com/appium/appium/tree/HEAD/packages/support) from 2.61.1 to 3.0.0. - [Release notes](https://github.com/appium/appium/releases) - [Changelog](https://github.com/appium/appium/blob/master/packages/support/CHANGELOG.md) - [Commits](https://github.com/appium/appium/commits/@appium/support@3.0.0/packages/support) --- updated-dependencies: - dependency-name: "@appium/support" dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a473c9170..ebf6d89f8 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ }, "dependencies": { "@appium/base-driver": "^8.7.3", - "@appium/support": "^2.61.0", + "@appium/support": "^3.0.0", "@babel/runtime": "^7.0.0", "appium-ios-simulator": "^4.0.0", "async-lock": "^1.0.0", From ab8458027457563b7faaeef36d9019b7ac1921b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Dec 2022 16:46:09 +0100 Subject: [PATCH 063/240] chore(deps-dev): bump @appium/test-support from 2.0.2 to 3.0.0 (#644) Bumps [@appium/test-support](https://github.com/appium/appium/tree/HEAD/packages/test-support) from 2.0.2 to 3.0.0. - [Release notes](https://github.com/appium/appium/releases) - [Changelog](https://github.com/appium/appium/blob/master/packages/test-support/CHANGELOG.md) - [Commits](https://github.com/appium/appium/commits/@appium/test-support@3.0.0/packages/test-support) --- updated-dependencies: - dependency-name: "@appium/test-support" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ebf6d89f8..487d07659 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "homepage": "https://github.com/appium/WebDriverAgent#readme", "devDependencies": { "@appium/eslint-config-appium": "^6.0.0", - "@appium/test-support": "^2.0.0", + "@appium/test-support": "^3.0.0", "@babel/cli": "^7.18.10", "@babel/core": "^7.18.10", "@babel/eslint-parser": "^7.18.9", From 91198c5e3c2abe6035622840d40edf07c9baf1ec Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 14 Dec 2022 16:26:00 +0000 Subject: [PATCH 064/240] chore(release): 4.10.14 [skip ci] ## [4.10.14](https://github.com/appium/WebDriverAgent/compare/v4.10.13...v4.10.14) (2022-12-14) ### Miscellaneous Chores * **deps-dev:** bump @appium/test-support from 2.0.2 to 3.0.0 ([#644](https://github.com/appium/WebDriverAgent/issues/644)) ([ab84580](https://github.com/appium/WebDriverAgent/commit/ab8458027457563b7faaeef36d9019b7ac1921b0)) * **deps:** bump @appium/support from 2.61.1 to 3.0.0 ([#643](https://github.com/appium/WebDriverAgent/issues/643)) ([3ca197a](https://github.com/appium/WebDriverAgent/commit/3ca197ac7526036e408584207b26129847a615ca)) --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f9880544..03ee77a12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## [4.10.14](https://github.com/appium/WebDriverAgent/compare/v4.10.13...v4.10.14) (2022-12-14) + + +### Miscellaneous Chores + +* **deps-dev:** bump @appium/test-support from 2.0.2 to 3.0.0 ([#644](https://github.com/appium/WebDriverAgent/issues/644)) ([ab84580](https://github.com/appium/WebDriverAgent/commit/ab8458027457563b7faaeef36d9019b7ac1921b0)) +* **deps:** bump @appium/support from 2.61.1 to 3.0.0 ([#643](https://github.com/appium/WebDriverAgent/issues/643)) ([3ca197a](https://github.com/appium/WebDriverAgent/commit/3ca197ac7526036e408584207b26129847a615ca)) + ## [4.10.13](https://github.com/appium/WebDriverAgent/compare/v4.10.12...v4.10.13) (2022-12-13) ## [4.10.12](https://github.com/appium/WebDriverAgent/compare/v4.10.11...v4.10.12) (2022-12-08) diff --git a/package.json b/package.json index 487d07659..50bb57797 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.13", + "version": "4.10.14", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 7911cbb3607b1d75091bdf3dc436baae3868854a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Dec 2022 15:31:01 +0100 Subject: [PATCH 065/240] chore(deps): bump appium-ios-simulator from 4.2.1 to 5.0.1 (#646) Bumps [appium-ios-simulator](https://github.com/appium/appium-ios-simulator) from 4.2.1 to 5.0.1. - [Release notes](https://github.com/appium/appium-ios-simulator/releases) - [Changelog](https://github.com/appium/appium-ios-simulator/blob/master/CHANGELOG.md) - [Commits](https://github.com/appium/appium-ios-simulator/compare/v4.2.1...v5.0.1) --- updated-dependencies: - dependency-name: appium-ios-simulator dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 50bb57797..3d3d6e9ca 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "@appium/base-driver": "^8.7.3", "@appium/support": "^3.0.0", "@babel/runtime": "^7.0.0", - "appium-ios-simulator": "^4.0.0", + "appium-ios-simulator": "^5.0.1", "async-lock": "^1.0.0", "asyncbox": "^2.5.3", "axios": "^1.x", From 35dd98111f1d8222bc0cb412c11cb1442d10295e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Dec 2022 15:31:22 +0100 Subject: [PATCH 066/240] chore(deps): bump @appium/base-driver from 8.7.3 to 9.0.0 (#645) Bumps [@appium/base-driver](https://github.com/appium/appium/tree/HEAD/packages/base-driver) from 8.7.3 to 9.0.0. - [Release notes](https://github.com/appium/appium/releases) - [Changelog](https://github.com/appium/appium/blob/master/packages/base-driver/CHANGELOG.md) - [Commits](https://github.com/appium/appium/commits/@appium/base-driver@9.0.0/packages/base-driver) --- updated-dependencies: - dependency-name: "@appium/base-driver" dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3d3d6e9ca..9b4e7ad39 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "sinon": "^15.0.0" }, "dependencies": { - "@appium/base-driver": "^8.7.3", + "@appium/base-driver": "^9.0.0", "@appium/support": "^3.0.0", "@babel/runtime": "^7.0.0", "appium-ios-simulator": "^5.0.1", From d88d45a33d2cb4d2ff95f936e725d31054c92f36 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 16 Dec 2022 14:40:45 +0000 Subject: [PATCH 067/240] chore(release): 4.10.15 [skip ci] ## [4.10.15](https://github.com/appium/WebDriverAgent/compare/v4.10.14...v4.10.15) (2022-12-16) ### Miscellaneous Chores * **deps:** bump @appium/base-driver from 8.7.3 to 9.0.0 ([#645](https://github.com/appium/WebDriverAgent/issues/645)) ([35dd981](https://github.com/appium/WebDriverAgent/commit/35dd98111f1d8222bc0cb412c11cb1442d10295e)) * **deps:** bump appium-ios-simulator from 4.2.1 to 5.0.1 ([#646](https://github.com/appium/WebDriverAgent/issues/646)) ([7911cbb](https://github.com/appium/WebDriverAgent/commit/7911cbb3607b1d75091bdf3dc436baae3868854a)) --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03ee77a12..224d9d13b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## [4.10.15](https://github.com/appium/WebDriverAgent/compare/v4.10.14...v4.10.15) (2022-12-16) + + +### Miscellaneous Chores + +* **deps:** bump @appium/base-driver from 8.7.3 to 9.0.0 ([#645](https://github.com/appium/WebDriverAgent/issues/645)) ([35dd981](https://github.com/appium/WebDriverAgent/commit/35dd98111f1d8222bc0cb412c11cb1442d10295e)) +* **deps:** bump appium-ios-simulator from 4.2.1 to 5.0.1 ([#646](https://github.com/appium/WebDriverAgent/issues/646)) ([7911cbb](https://github.com/appium/WebDriverAgent/commit/7911cbb3607b1d75091bdf3dc436baae3868854a)) + ## [4.10.14](https://github.com/appium/WebDriverAgent/compare/v4.10.13...v4.10.14) (2022-12-14) diff --git a/package.json b/package.json index 9b4e7ad39..805b437ab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.14", + "version": "4.10.15", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 63e175d56526d9fb74d9053dbe60fd0c80b9c670 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Thu, 29 Dec 2022 14:35:16 -0800 Subject: [PATCH 068/240] chore: build only arm64 for generic build in a release (#648) --- .github/workflows/wda-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/wda-package.yml b/.github/workflows/wda-package.yml index 767d8e17a..1d4105eaf 100644 --- a/.github/workflows/wda-package.yml +++ b/.github/workflows/wda-package.yml @@ -28,7 +28,7 @@ jobs: -derivedDataPath $PKG_PATH_IOS \ -scheme WebDriverAgentRunner \ -destination generic/platform=iOS \ - CODE_SIGNING_ALLOWED=NO + CODE_SIGNING_ALLOWED=NO ARCHS=arm64 - name: Creating a zip of WebDriverAgentRunner-Runner.app for iOS run: | pushd appium_wda_ios/Build/Products/Debug-iphoneos @@ -42,7 +42,7 @@ jobs: -derivedDataPath $PKG_PATH_TVOS \ -scheme WebDriverAgentRunner_tvOS \ -destination generic/platform=tvOS \ - CODE_SIGNING_ALLOWED=NO + CODE_SIGNING_ALLOWED=NO ARCHS=arm64 - name: Creating a zip of WebDriverAgentRunner-Runner.app for tvOS run: | pushd appium_wda_tvos/Build/Products/Debug-appletvos From 6c3bae1a435053221986625a97ffa7907b472970 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 29 Dec 2022 22:45:45 +0000 Subject: [PATCH 069/240] chore(release): 4.10.16 [skip ci] ## [4.10.16](https://github.com/appium/WebDriverAgent/compare/v4.10.15...v4.10.16) (2022-12-29) ### Miscellaneous Chores * build only arm64 for generic build in a release ([#648](https://github.com/appium/WebDriverAgent/issues/648)) ([63e175d](https://github.com/appium/WebDriverAgent/commit/63e175d56526d9fb74d9053dbe60fd0c80b9c670)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 224d9d13b..4eda2b896 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.10.16](https://github.com/appium/WebDriverAgent/compare/v4.10.15...v4.10.16) (2022-12-29) + + +### Miscellaneous Chores + +* build only arm64 for generic build in a release ([#648](https://github.com/appium/WebDriverAgent/issues/648)) ([63e175d](https://github.com/appium/WebDriverAgent/commit/63e175d56526d9fb74d9053dbe60fd0c80b9c670)) + ## [4.10.15](https://github.com/appium/WebDriverAgent/compare/v4.10.14...v4.10.15) (2022-12-16) diff --git a/package.json b/package.json index 805b437ab..5afa8c398 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.15", + "version": "4.10.16", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 08612aade1833c384914bb618675b5653d5f5118 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Thu, 29 Dec 2022 15:59:15 -0800 Subject: [PATCH 070/240] chore: add ARCHS=arm64 for a release package build (#649) --- .github/workflows/publish.js.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.js.yml b/.github/workflows/publish.js.yml index 571e8632f..a6d0c8720 100644 --- a/.github/workflows/publish.js.yml +++ b/.github/workflows/publish.js.yml @@ -43,7 +43,7 @@ jobs: -derivedDataPath $PKG_PATH_IOS \ -scheme WebDriverAgentRunner \ -destination generic/platform=iOS \ - CODE_SIGNING_ALLOWED=NO + CODE_SIGNING_ALLOWED=NO ARCHS=arm64 - name: Creating a zip of WebDriverAgentRunner-Runner.app for iOS run: | pushd appium_wda_ios/Build/Products/Debug-iphoneos @@ -57,7 +57,7 @@ jobs: -derivedDataPath $PKG_PATH_TVOS \ -scheme WebDriverAgentRunner_tvOS \ -destination generic/platform=tvOS \ - CODE_SIGNING_ALLOWED=NO + CODE_SIGNING_ALLOWED=NO ARCHS=arm64 - name: Creating a zip of WebDriverAgentRunner-Runner.app for tvOS run: | pushd appium_wda_tvos/Build/Products/Debug-appletvos From d9e632852187371aa8e748141f1c0c1c7a302e91 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 30 Dec 2022 00:07:33 +0000 Subject: [PATCH 071/240] chore(release): 4.10.17 [skip ci] ## [4.10.17](https://github.com/appium/WebDriverAgent/compare/v4.10.16...v4.10.17) (2022-12-30) ### Miscellaneous Chores * add ARCHS=arm64 for a release package build ([#649](https://github.com/appium/WebDriverAgent/issues/649)) ([08612aa](https://github.com/appium/WebDriverAgent/commit/08612aade1833c384914bb618675b5653d5f5118)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4eda2b896..50f45bb92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.10.17](https://github.com/appium/WebDriverAgent/compare/v4.10.16...v4.10.17) (2022-12-30) + + +### Miscellaneous Chores + +* add ARCHS=arm64 for a release package build ([#649](https://github.com/appium/WebDriverAgent/issues/649)) ([08612aa](https://github.com/appium/WebDriverAgent/commit/08612aade1833c384914bb618675b5653d5f5118)) + ## [4.10.16](https://github.com/appium/WebDriverAgent/compare/v4.10.15...v4.10.16) (2022-12-29) diff --git a/package.json b/package.json index 5afa8c398..a912cb2ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.16", + "version": "4.10.17", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 6118c3f9b742bd5d40fc7be7a3d5022ac31155b1 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Fri, 30 Dec 2022 10:33:04 -0800 Subject: [PATCH 072/240] ci: tune build environment for release (#650) * ci: tune build environment * ci: update publishment env --- .github/workflows/publish.js.yml | 4 ++-- .github/workflows/wda-package.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish.js.yml b/.github/workflows/publish.js.yml index a6d0c8720..05420d48b 100644 --- a/.github/workflows/publish.js.yml +++ b/.github/workflows/publish.js.yml @@ -10,10 +10,10 @@ on: jobs: build: - runs-on: macos-11 + runs-on: macos-12 env: - XCODE_VERSION: 13.2.1 + XCODE_VERSION: 14.1 ZIP_PKG_NAME_IOS: "WebDriverAgentRunner-Runner.zip" PKG_PATH_IOS: "appium_wda_ios" ZIP_PKG_NAME_TVOS: "WebDriverAgentRunner_tvOS-Runner.zip" diff --git a/.github/workflows/wda-package.yml b/.github/workflows/wda-package.yml index 1d4105eaf..21cfe155a 100644 --- a/.github/workflows/wda-package.yml +++ b/.github/workflows/wda-package.yml @@ -6,10 +6,10 @@ on: jobs: build: name: Build WDA for real iOS and tvOS devices - runs-on: macos-11 + runs-on: macos-12 env: - XCODE_VERSION: 13.2.1 + XCODE_VERSION: 14.1 ZIP_PKG_NAME_IOS: "WebDriverAgentRunner-Runner.zip" PKG_PATH_IOS: "appium_wda_ios" ZIP_PKG_NAME_TVOS: "WebDriverAgentRunner_tvOS-Runner.zip" From 81dab6ca0645f9925a8515abfb4851d6e85da7e9 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Fri, 30 Dec 2022 11:04:03 -0800 Subject: [PATCH 073/240] chore: simplify Script/build-webdriveragent.js (#647) * chore: simplify Script/build-webdriveragent.js * rename the file name * chore: use UPPER_CASE for const * use native zip * use xcodebuild clean --- Scripts/build-webdriveragent.js | 101 +++++++++++--------------------- 1 file changed, 33 insertions(+), 68 deletions(-) diff --git a/Scripts/build-webdriveragent.js b/Scripts/build-webdriveragent.js index 2099c134c..a5739d724 100644 --- a/Scripts/build-webdriveragent.js +++ b/Scripts/build-webdriveragent.js @@ -1,88 +1,53 @@ const path = require('path'); -const os = require('os'); const { asyncify } = require('asyncbox'); -const { logger, fs, mkdirp, zip } = require('@appium/support'); +const { logger, fs } = require('@appium/support'); const { exec } = require('teen_process'); const xcode = require('appium-xcode'); -const log = new logger.getLogger('WDABuild'); -const rootDir = path.resolve(__dirname, '..'); +const LOG = new logger.getLogger('WDABuild'); +const ROOT_DIR = path.resolve(__dirname, '..'); +const DERIVED_DATA_PATH = `${ROOT_DIR}/wdaBuild`; +const WDA_BUNDLE = 'WebDriverAgentRunner-Runner.app'; +const WDA_BUNDLE_PATH = path.join(DERIVED_DATA_PATH, 'Build', 'Products', 'Debug-iphonesimulator'); async function buildWebDriverAgent (xcodeVersion) { + LOG.info(`Cleaning ${DERIVED_DATA_PATH} if exists`); + try { + await exec('xcodebuild', ['clean', '-derivedDataPath', DERIVED_DATA_PATH, '-scheme', 'WebDriverAgentRunner'], { + cwd: ROOT_DIR + }); + } catch (ign) {} + // Get Xcode version xcodeVersion = xcodeVersion || await xcode.getVersion(); - log.info(`Building bundle for Xcode version '${xcodeVersion}'`); - - // Clear WebDriverAgent from derived data - const derivedDataPath = path.resolve(os.homedir(), 'Library', 'Developer', - 'Xcode', 'DerivedData'); - log.info(`Clearing contents of '${derivedDataPath}/WebDriverAgent-*'`); - for (const wdaPath of - await fs.glob('WebDriverAgent-*', {cwd: derivedDataPath, absolute: true}) - ) { - log.info(`Deleting existing WDA: '${wdaPath}'`); - await fs.rimraf(wdaPath); - } + LOG.info(`Building WebDriverAgent for iOS using Xcode version '${xcodeVersion}'`); // Clean and build - log.info('Running ./Scripts/build.sh'); - let env = {TARGET: 'runner', SDK: 'sim'}; try { - await exec('/bin/bash', ['./Scripts/build.sh'], {env, cwd: rootDir}); + await exec('/bin/bash', ['./Scripts/build.sh'], { + env: {TARGET: 'runner', SDK: 'sim', DERIVED_DATA_PATH}, + cwd: ROOT_DIR + }); } catch (e) { - log.error(`===FAILED TO BUILD FOR ${xcodeVersion}`); - log.error(e.stdout); - log.error(e.stderr); - log.error(e.message); + LOG.error(`===FAILED TO BUILD FOR ${xcodeVersion}`); + LOG.error(e.stderr); throw e; } - // Create bundles folder - const pathToBundles = path.resolve(rootDir, 'bundles'); - await mkdirp(pathToBundles); - - // Start creating zip - const uncompressedDir = path.resolve(rootDir, 'uncompressed'); - await fs.rimraf(uncompressedDir); - await mkdirp(uncompressedDir); - log.info('Creating zip'); - - // Move contents of the root to folder called "uncompressed" - await exec('rsync', [ - '-av', '.', uncompressedDir, - '--exclude', 'node_modules', - '--exclude', 'build', - '--exclude', 'ci-jobs', - '--exclude', 'lib', - '--exclude', 'test', - '--exclude', 'bundles', - '--exclude', 'azure-templates', - ], {cwd: rootDir}); - - // Move DerivedData/WebDriverAgent-* from Library to "uncompressed" folder - const wdaPath = (await fs.glob(`${derivedDataPath}/WebDriverAgent-*`))[0]; - await mkdirp(path.resolve(uncompressedDir, 'DerivedData')); - await fs.rename(wdaPath, path.resolve(uncompressedDir, 'DerivedData', 'WebDriverAgent')); - - // Compress the "uncompressed" bundle as a Zip - const pathToZip = path.resolve(pathToBundles, `webdriveragent-xcode_${xcodeVersion}.zip`); - await zip.toArchive( - pathToZip, {cwd: path.join(rootDir, 'uncompressed')} - ); - log.info(`Zip bundled at "${pathToZip}"`); - - // Now just zip the .app and place it in the root directory - // This zip file will be published to NPM - const wdaAppBundle = 'WebDriverAgentRunner-Runner.app'; - const appBundlePath = path.join(uncompressedDir, 'DerivedData', 'WebDriverAgent', - 'Build', 'Products', 'Debug-iphonesimulator', wdaAppBundle); - const appBundleZipPath = path.join(rootDir, `${wdaAppBundle}.zip`); + const zipName = `WebDriverAgentRunner-Runner-Sim-${xcodeVersion}.zip`; + LOG.info(`Creating ${zipName} which includes ${WDA_BUNDLE}`); + const appBundleZipPath = path.join(ROOT_DIR, zipName); await fs.rimraf(appBundleZipPath); - log.info(`Created './${wdaAppBundle}.zip'`); - await zip.toArchive(appBundleZipPath, {cwd: appBundlePath}); - log.info(`Zip bundled at "${appBundleZipPath}"`); - // Clean up the uncompressed directory - await fs.rimraf(uncompressedDir); + LOG.info(`Created './${zipName}'`); + try { + await exec('xattr', ['-cr', WDA_BUNDLE], {cwd: WDA_BUNDLE_PATH}); + await exec('zip', ['-qr', appBundleZipPath, WDA_BUNDLE], {cwd: WDA_BUNDLE_PATH}); + } catch (e) { + LOG.error(`===FAILED TO ZIP ARCHIVE`); + LOG.error(e.stderr); + throw e; + } + LOG.info(`Zip bundled at "${appBundleZipPath}"`); } if (require.main === module) { From a2ed18605115a69e3aa92898d718cc7f2dcb9d0d Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 30 Dec 2022 19:12:26 +0000 Subject: [PATCH 074/240] chore(release): 4.10.18 [skip ci] ## [4.10.18](https://github.com/appium/WebDriverAgent/compare/v4.10.17...v4.10.18) (2022-12-30) ### Miscellaneous Chores * simplify Script/build-webdriveragent.js ([#647](https://github.com/appium/WebDriverAgent/issues/647)) ([81dab6c](https://github.com/appium/WebDriverAgent/commit/81dab6ca0645f9925a8515abfb4851d6e85da7e9)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50f45bb92..87e59a286 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.10.18](https://github.com/appium/WebDriverAgent/compare/v4.10.17...v4.10.18) (2022-12-30) + + +### Miscellaneous Chores + +* simplify Script/build-webdriveragent.js ([#647](https://github.com/appium/WebDriverAgent/issues/647)) ([81dab6c](https://github.com/appium/WebDriverAgent/commit/81dab6ca0645f9925a8515abfb4851d6e85da7e9)) + ## [4.10.17](https://github.com/appium/WebDriverAgent/compare/v4.10.16...v4.10.17) (2022-12-30) diff --git a/package.json b/package.json index a912cb2ad..42c23dba3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.17", + "version": "4.10.18", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 75c247fe82ebe7b2b8ba0d79528cadeda871e229 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Jan 2023 18:59:59 +0100 Subject: [PATCH 075/240] chore(deps-dev): bump appium-xcode from 4.0.5 to 5.0.0 (#652) Bumps [appium-xcode](https://github.com/appium/appium-xcode) from 4.0.5 to 5.0.0. - [Release notes](https://github.com/appium/appium-xcode/releases) - [Changelog](https://github.com/appium/appium-xcode/blob/master/CHANGELOG.md) - [Commits](https://github.com/appium/appium-xcode/compare/v4.0.5...v5.0.0) --- updated-dependencies: - dependency-name: appium-xcode dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 42c23dba3..c2708b5e3 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "@semantic-release/changelog": "^6.0.1", "@semantic-release/git": "^10.0.1", "babel-plugin-source-map-support": "^2.2.0", - "appium-xcode": "^4.0.1", + "appium-xcode": "^5.0.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "conventional-changelog-conventionalcommits": "^5.0.0", From a9a384cd350d4a97768f0d1ed54d7a1860210c9b Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 13 Jan 2023 18:43:30 +0000 Subject: [PATCH 076/240] chore(release): 4.10.19 [skip ci] ## [4.10.19](https://github.com/appium/WebDriverAgent/compare/v4.10.18...v4.10.19) (2023-01-13) ### Miscellaneous Chores * **deps-dev:** bump appium-xcode from 4.0.5 to 5.0.0 ([#652](https://github.com/appium/WebDriverAgent/issues/652)) ([75c247f](https://github.com/appium/WebDriverAgent/commit/75c247fe82ebe7b2b8ba0d79528cadeda871e229)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87e59a286..614b7e33c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.10.19](https://github.com/appium/WebDriverAgent/compare/v4.10.18...v4.10.19) (2023-01-13) + + +### Miscellaneous Chores + +* **deps-dev:** bump appium-xcode from 4.0.5 to 5.0.0 ([#652](https://github.com/appium/WebDriverAgent/issues/652)) ([75c247f](https://github.com/appium/WebDriverAgent/commit/75c247fe82ebe7b2b8ba0d79528cadeda871e229)) + ## [4.10.18](https://github.com/appium/WebDriverAgent/compare/v4.10.17...v4.10.18) (2022-12-30) diff --git a/package.json b/package.json index c2708b5e3..9aeda2192 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.18", + "version": "4.10.19", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From e96c367cb0d9461bb5e443740504969a4cb857e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Jan 2023 22:54:05 -0800 Subject: [PATCH 077/240] chore(deps-dev): bump semantic-release from 19.0.5 to 20.0.2 (#651) Bumps [semantic-release](https://github.com/semantic-release/semantic-release) from 19.0.5 to 20.0.2. - [Release notes](https://github.com/semantic-release/semantic-release/releases) - [Commits](https://github.com/semantic-release/semantic-release/compare/v19.0.5...v20.0.2) --- updated-dependencies: - dependency-name: semantic-release dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9aeda2192..eee1bc42b 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "mocha": "^10.0.0", "pre-commit": "^1.2.2", "prettier": "^2.7.1", - "semantic-release": "^19.0.2", + "semantic-release": "^20.0.2", "sinon": "^15.0.0" }, "dependencies": { From 9d392e9a09e699376b53d1517c7dddf582e2afb5 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 17 Jan 2023 07:00:20 +0000 Subject: [PATCH 078/240] chore(release): 4.10.20 [skip ci] ## [4.10.20](https://github.com/appium/WebDriverAgent/compare/v4.10.19...v4.10.20) (2023-01-17) ### Miscellaneous Chores * **deps-dev:** bump semantic-release from 19.0.5 to 20.0.2 ([#651](https://github.com/appium/WebDriverAgent/issues/651)) ([e96c367](https://github.com/appium/WebDriverAgent/commit/e96c367cb0d9461bb5e443740504969a4cb857e1)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 614b7e33c..8b486b922 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.10.20](https://github.com/appium/WebDriverAgent/compare/v4.10.19...v4.10.20) (2023-01-17) + + +### Miscellaneous Chores + +* **deps-dev:** bump semantic-release from 19.0.5 to 20.0.2 ([#651](https://github.com/appium/WebDriverAgent/issues/651)) ([e96c367](https://github.com/appium/WebDriverAgent/commit/e96c367cb0d9461bb5e443740504969a4cb857e1)) + ## [4.10.19](https://github.com/appium/WebDriverAgent/compare/v4.10.18...v4.10.19) (2023-01-13) diff --git a/package.json b/package.json index eee1bc42b..a39f90761 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.19", + "version": "4.10.20", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 6f99bab5fbdbf65c9ef74c42b5f1b4c658aeaafb Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 26 Jan 2023 19:11:05 +0100 Subject: [PATCH 079/240] fix: Properly update maxDepth while fetching snapshots (#655) --- WebDriverAgent.xcodeproj/project.pbxproj | 12 +++ .../XCAXClient_iOS+FBSnapshotReqParams.h | 26 ++++++ .../XCAXClient_iOS+FBSnapshotReqParams.m | 90 +++++++++++++++++++ WebDriverAgentLib/Utilities/FBConfiguration.h | 7 -- WebDriverAgentLib/Utilities/FBConfiguration.m | 19 +--- .../Utilities/FBXCAXClientProxy.m | 43 +-------- 6 files changed, 134 insertions(+), 63 deletions(-) create mode 100644 WebDriverAgentLib/Categories/XCAXClient_iOS+FBSnapshotReqParams.h create mode 100644 WebDriverAgentLib/Categories/XCAXClient_iOS+FBSnapshotReqParams.m diff --git a/WebDriverAgent.xcodeproj/project.pbxproj b/WebDriverAgent.xcodeproj/project.pbxproj index ea7ae19e0..125c26ef0 100644 --- a/WebDriverAgent.xcodeproj/project.pbxproj +++ b/WebDriverAgent.xcodeproj/project.pbxproj @@ -359,6 +359,10 @@ 714D88CD2733FB970074A925 /* FBXMLGenerationOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 714D88CA2733FB970074A925 /* FBXMLGenerationOptions.h */; }; 714D88CE2733FB970074A925 /* FBXMLGenerationOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 714D88CB2733FB970074A925 /* FBXMLGenerationOptions.m */; }; 714D88CF2733FB970074A925 /* FBXMLGenerationOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 714D88CB2733FB970074A925 /* FBXMLGenerationOptions.m */; }; + 714E14B829805CAE00375DD7 /* XCAXClient_iOS+FBSnapshotReqParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 714E14B629805CAE00375DD7 /* XCAXClient_iOS+FBSnapshotReqParams.h */; }; + 714E14B929805CAE00375DD7 /* XCAXClient_iOS+FBSnapshotReqParams.h in Headers */ = {isa = PBXBuildFile; fileRef = 714E14B629805CAE00375DD7 /* XCAXClient_iOS+FBSnapshotReqParams.h */; }; + 714E14BA29805CAE00375DD7 /* XCAXClient_iOS+FBSnapshotReqParams.m in Sources */ = {isa = PBXBuildFile; fileRef = 714E14B729805CAE00375DD7 /* XCAXClient_iOS+FBSnapshotReqParams.m */; }; + 714E14BB29805CAE00375DD7 /* XCAXClient_iOS+FBSnapshotReqParams.m in Sources */ = {isa = PBXBuildFile; fileRef = 714E14B729805CAE00375DD7 /* XCAXClient_iOS+FBSnapshotReqParams.m */; }; 714EAA0D2673FDFE005C5B47 /* FBCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 714EAA0B2673FDFE005C5B47 /* FBCapabilities.h */; }; 714EAA0E2673FDFE005C5B47 /* FBCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 714EAA0B2673FDFE005C5B47 /* FBCapabilities.h */; }; 714EAA0F2673FDFE005C5B47 /* FBCapabilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 714EAA0C2673FDFE005C5B47 /* FBCapabilities.m */; }; @@ -975,6 +979,8 @@ 714CA3C61DC23186000F12C9 /* FBXPathIntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBXPathIntegrationTests.m; sourceTree = ""; }; 714D88CA2733FB970074A925 /* FBXMLGenerationOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBXMLGenerationOptions.h; sourceTree = ""; }; 714D88CB2733FB970074A925 /* FBXMLGenerationOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBXMLGenerationOptions.m; sourceTree = ""; }; + 714E14B629805CAE00375DD7 /* XCAXClient_iOS+FBSnapshotReqParams.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "XCAXClient_iOS+FBSnapshotReqParams.h"; sourceTree = ""; }; + 714E14B729805CAE00375DD7 /* XCAXClient_iOS+FBSnapshotReqParams.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "XCAXClient_iOS+FBSnapshotReqParams.m"; sourceTree = ""; }; 714EAA0B2673FDFE005C5B47 /* FBCapabilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBCapabilities.h; sourceTree = ""; }; 714EAA0C2673FDFE005C5B47 /* FBCapabilities.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBCapabilities.m; sourceTree = ""; }; 7150348521A6DAD600A0F4BA /* FBImageUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBImageUtils.h; sourceTree = ""; }; @@ -1719,6 +1725,8 @@ EE0D1F601EBCDCF7006A3123 /* NSString+FBVisualLength.m */, 716E0BCC1E917E810087A825 /* NSString+FBXMLSafeString.h */, 716E0BCD1E917E810087A825 /* NSString+FBXMLSafeString.m */, + 714E14B629805CAE00375DD7 /* XCAXClient_iOS+FBSnapshotReqParams.h */, + 714E14B729805CAE00375DD7 /* XCAXClient_iOS+FBSnapshotReqParams.m */, AD6C269A1CF2494200F8B5FF /* XCUIApplication+FBHelpers.h */, AD6C269B1CF2494200F8B5FF /* XCUIApplication+FBHelpers.m */, 71C8E54F25399A6B008572C1 /* XCUIApplication+FBQuiescence.h */, @@ -2284,6 +2292,7 @@ 641EE64B2240C5CA00173FCB /* XCTAsyncActivity.h in Headers */, 641EE64C2240C5CA00173FCB /* XCTestMisuseObserver.h in Headers */, 641EE64D2240C5CA00173FCB /* XCTRunnerDaemonSession.h in Headers */, + 714E14B929805CAE00375DD7 /* XCAXClient_iOS+FBSnapshotReqParams.h in Headers */, 64B2650B228CE4FF002A5025 /* FBTVNavigationTracker-Private.h in Headers */, 641EE64E2240C5CA00173FCB /* FBApplication.h in Headers */, 641EE64F2240C5CA00173FCB /* XCTestExpectationWaiter.h in Headers */, @@ -2525,6 +2534,7 @@ 6496A5D9230D6EB30087F8CB /* AXSettings.h in Headers */, EE35AD301E3B77D600A02D78 /* XCKeyboardKeyMap.h in Headers */, EE35AD5D1E3B77D600A02D78 /* XCTNSPredicateExpectationObject-Protocol.h in Headers */, + 714E14B829805CAE00375DD7 /* XCAXClient_iOS+FBSnapshotReqParams.h in Headers */, EE158B5F1CBD47A000A3E3F0 /* WebDriverAgentLib.h in Headers */, EE158AC01CBD456F00A3E3F0 /* FBFindElementCommands.h in Headers */, 71D475C22538F5A8008D9401 /* XCUIApplicationProcess+FBQuiescence.h in Headers */, @@ -3082,6 +3092,7 @@ 641EE70F2240CE4800173FCB /* FBTVNavigationTracker.m in Sources */, 714D88CF2733FB970074A925 /* FBXMLGenerationOptions.m in Sources */, 641EE5DE2240C5CA00173FCB /* XCUIApplication+FBTouchAction.m in Sources */, + 714E14BB29805CAE00375DD7 /* XCAXClient_iOS+FBSnapshotReqParams.m in Sources */, 641EE5DF2240C5CA00173FCB /* FBWebServer.m in Sources */, 641EE5E02240C5CA00173FCB /* FBTCPSocket.m in Sources */, 641EE5E12240C5CA00173FCB /* FBErrorBuilder.m in Sources */, @@ -3260,6 +3271,7 @@ EE6B64FE1D0F86EF00E85F5D /* XCTestPrivateSymbols.m in Sources */, AD76723E1D6B7CC000610457 /* XCUIElement+FBTyping.m in Sources */, EE158AAF1CBD456F00A3E3F0 /* XCUIElement+FBAccessibility.m in Sources */, + 714E14BA29805CAE00375DD7 /* XCAXClient_iOS+FBSnapshotReqParams.m in Sources */, 7150348821A6DAD600A0F4BA /* FBImageUtils.m in Sources */, E444DCAB24913C220060D7EB /* HTTPResponseProxy.m in Sources */, E444DC6D249131890060D7EB /* HTTPErrorResponse.m in Sources */, diff --git a/WebDriverAgentLib/Categories/XCAXClient_iOS+FBSnapshotReqParams.h b/WebDriverAgentLib/Categories/XCAXClient_iOS+FBSnapshotReqParams.h new file mode 100644 index 000000000..8080f2097 --- /dev/null +++ b/WebDriverAgentLib/Categories/XCAXClient_iOS+FBSnapshotReqParams.h @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import "XCAXClient_iOS.h" + +NS_ASSUME_NONNULL_BEGIN + +extern NSString *const FBSnapshotMaxDepthKey; + +void FBSetCustomParameterForElementSnapshot (NSString* name, id value); + +id __nullable FBGetCustomParameterForElementSnapshot (NSString *name); + +@interface XCAXClient_iOS (FBSnapshotReqParams) + +@end + +NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Categories/XCAXClient_iOS+FBSnapshotReqParams.m b/WebDriverAgentLib/Categories/XCAXClient_iOS+FBSnapshotReqParams.m new file mode 100644 index 000000000..e8ee55560 --- /dev/null +++ b/WebDriverAgentLib/Categories/XCAXClient_iOS+FBSnapshotReqParams.m @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "XCAXClient_iOS+FBSnapshotReqParams.h" + +#import + +/** + Available parameters with their default values for XCTest: + @"maxChildren" : (int)2147483647 + @"traverseFromParentsToChildren" : YES + @"maxArrayCount" : (int)2147483647 + @"snapshotKeyHonorModalViews" : NO + @"maxDepth" : (int)2147483647 + */ +NSString *const FBSnapshotMaxDepthKey = @"maxDepth"; + +static id (*original_defaultParameters)(id, SEL); +static id (*original_snapshotParameters)(id, SEL); +static NSDictionary *defaultRequestParameters; +static NSDictionary *defaultAdditionalRequestParameters; +static NSMutableDictionary *customRequestParameters; + +void FBSetCustomParameterForElementSnapshot (NSString *name, id value) +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + customRequestParameters = [NSMutableDictionary new]; + }); + customRequestParameters[name] = value; +} + +id FBGetCustomParameterForElementSnapshot (NSString *name) +{ + return customRequestParameters[name]; +} + +static id swizzledDefaultParameters(id self, SEL _cmd) +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:original_defaultParameters(self, _cmd)]; + [params addEntriesFromDictionary:defaultAdditionalRequestParameters]; + defaultRequestParameters = params.copy; + }); + if (nil == defaultRequestParameters) { + return original_defaultParameters(self, _cmd); + } + NSMutableDictionary *result = [NSMutableDictionary dictionaryWithDictionary:defaultRequestParameters]; + if (nil != customRequestParameters && customRequestParameters.count > 0) { + [result addEntriesFromDictionary:customRequestParameters]; + } + return result.copy; +} + +static id swizzledSnapshotParameters(id self, SEL _cmd) +{ + NSDictionary *result = original_snapshotParameters(self, _cmd); + if (nil == defaultAdditionalRequestParameters) { + defaultAdditionalRequestParameters = result; + } + return result; +} + + +@implementation XCAXClient_iOS (FBSnapshotReqParams) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-load-method" + ++ (void)load +{ + Method original_defaultParametersMethod = class_getInstanceMethod(self.class, @selector(defaultParameters)); + IMP swizzledDefaultParametersImp = (IMP)swizzledDefaultParameters; + original_defaultParameters = (id (*)(id, SEL)) method_setImplementation(original_defaultParametersMethod, swizzledDefaultParametersImp); + + Method original_snapshotParametersMethod = class_getInstanceMethod(NSClassFromString(@"XCTElementQuery"), NSSelectorFromString(@"snapshotParameters")); + IMP swizzledSnapshotParametersImp = (IMP)swizzledSnapshotParameters; + original_snapshotParameters = (id (*)(id, SEL)) method_setImplementation(original_snapshotParametersMethod, swizzledSnapshotParametersImp); +} + +#pragma clang diagnostic pop + +@end diff --git a/WebDriverAgentLib/Utilities/FBConfiguration.h b/WebDriverAgentLib/Utilities/FBConfiguration.h index 72c01d9c2..7bfbccc43 100644 --- a/WebDriverAgentLib/Utilities/FBConfiguration.h +++ b/WebDriverAgentLib/Utilities/FBConfiguration.h @@ -183,13 +183,6 @@ typedef NS_ENUM(NSInteger, FBConfigurationKeyboardPreference) { */ + (int)snapshotMaxDepth; -/** - Returns parameters for traversing elements tree from parents to children while requesting XCElementSnapshot. - - @return dictionary with parameters for element's snapshot request -*/ -+ (NSDictionary *)snapshotRequestParameters; - /** * Whether to use fast search result matching while searching for elements. * By default this is disabled due to https://github.com/appium/appium/issues/10101 diff --git a/WebDriverAgentLib/Utilities/FBConfiguration.m b/WebDriverAgentLib/Utilities/FBConfiguration.m index d34d7d53d..59cd5eb9b 100644 --- a/WebDriverAgentLib/Utilities/FBConfiguration.m +++ b/WebDriverAgentLib/Utilities/FBConfiguration.m @@ -14,6 +14,7 @@ #include "TargetConditionals.h" #import "FBXCodeCompatibility.h" +#import "XCAXClient_iOS+FBSnapshotReqParams.h" #import "XCTestPrivateSymbols.h" #import "XCTestConfiguration.h" #import "XCUIApplication+FBUIInterruptions.h" @@ -30,7 +31,6 @@ static BOOL FBShouldUseTestManagerForVisibilityDetection = NO; static BOOL FBShouldUseSingletonTestManager = YES; -NSString *const FBSnapshotMaxDepthKey = @"maxDepth"; static NSUInteger FBMjpegScalingFactor = 100; static NSUInteger FBMjpegServerScreenshotQuality = 25; @@ -53,17 +53,11 @@ #if !TARGET_OS_TV static UIInterfaceOrientation FBScreenshotOrientation; #endif -static NSMutableDictionary *FBSnapshotRequestParameters; @implementation FBConfiguration + (void)initialize { - FBSnapshotRequestParameters = [NSMutableDictionary dictionaryWithDictionary:@{ - @"maxArrayCount": @INT_MAX, - @"maxChildren": @INT_MAX, - @"traverseFromParentsToChildren": @1 - }]; [FBConfiguration resetSessionSettings]; } @@ -341,17 +335,12 @@ + (NSTimeInterval)customSnapshotTimeout + (void)setSnapshotMaxDepth:(int)maxDepth { - FBSnapshotRequestParameters[FBSnapshotMaxDepthKey] = @(maxDepth); + FBSetCustomParameterForElementSnapshot(FBSnapshotMaxDepthKey, @(maxDepth)); } + (int)snapshotMaxDepth { - return [FBSnapshotRequestParameters[FBSnapshotMaxDepthKey] intValue]; -} - -+ (NSDictionary *)snapshotRequestParameters -{ - return FBSnapshotRequestParameters; + return [FBGetCustomParameterForElementSnapshot(FBSnapshotMaxDepthKey) intValue]; } + (void)setUseFirstMatch:(BOOL)enabled @@ -468,7 +457,7 @@ + (void)resetSessionSettings FBWaitForIdleTimeout = 10.; FBAnimationCoolOffTimeout = 2.; // 50 should be enough for the majority of the cases. The performance is acceptable for values up to 100. - FBSnapshotRequestParameters[FBSnapshotMaxDepthKey] = @50; + FBSetCustomParameterForElementSnapshot(FBSnapshotMaxDepthKey, @50); #if !TARGET_OS_TV FBScreenshotOrientation = UIInterfaceOrientationUnknown; #endif diff --git a/WebDriverAgentLib/Utilities/FBXCAXClientProxy.m b/WebDriverAgentLib/Utilities/FBXCAXClientProxy.m index f001ea91d..907bb25b1 100644 --- a/WebDriverAgentLib/Utilities/FBXCAXClientProxy.m +++ b/WebDriverAgentLib/Utilities/FBXCAXClientProxy.m @@ -9,47 +9,14 @@ #import "FBXCAXClientProxy.h" -#import - #import "FBXCAccessibilityElement.h" -#import "FBConfiguration.h" #import "FBLogger.h" #import "FBMacros.h" -#import "FBReflectionUtils.h" -#import "XCAXClient_iOS.h" +#import "XCAXClient_iOS+FBSnapshotReqParams.h" #import "XCUIDevice.h" static id FBAXClient = nil; -@implementation XCAXClient_iOS (WebDriverAgent) - -/** - Parameters for traversing elements tree from parents to children while requesting XCElementSnapshot. - - @return dictionary with parameters for element's snapshot request - */ -- (NSDictionary *)fb_getParametersForElementSnapshot -{ - return FBConfiguration.snapshotRequestParameters; -} - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wobjc-load-method" - -+ (void)load -{ - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - SEL originalParametersSelector = @selector(defaultParameters); - SEL swizzledParametersSelector = @selector(fb_getParametersForElementSnapshot); - FBReplaceMethod([self class], originalParametersSelector, swizzledParametersSelector); - }); -} - -#pragma clang diagnostic pop - -@end - @implementation FBXCAXClientProxy + (instancetype)sharedClient @@ -73,14 +40,8 @@ - (BOOL)setAXTimeout:(NSTimeInterval)timeout error:(NSError **)error maxDepth:(nullable NSNumber *)maxDepth error:(NSError **)error { - NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; - // Mimicking XCTest framework behavior (this attribute is added by default unless it is an excludingNonModalElements query) - // See https://github.com/appium/WebDriverAgent/pull/523 - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"13.0")) { - parameters[@"snapshotKeyHonorModalViews"] = @(NO); - } + NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithDictionary:self.defaultParameters]; if (nil != maxDepth) { - [parameters addEntriesFromDictionary:self.defaultParameters]; parameters[FBSnapshotMaxDepthKey] = maxDepth; } From c51ce432127cdc0e7f95701a70f6b2dc93e427d8 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 26 Jan 2023 18:19:58 +0000 Subject: [PATCH 080/240] chore(release): 4.10.21 [skip ci] ## [4.10.21](https://github.com/appium/WebDriverAgent/compare/v4.10.20...v4.10.21) (2023-01-26) ### Bug Fixes * Properly update maxDepth while fetching snapshots ([#655](https://github.com/appium/WebDriverAgent/issues/655)) ([6f99bab](https://github.com/appium/WebDriverAgent/commit/6f99bab5fbdbf65c9ef74c42b5f1b4c658aeaafb)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b486b922..af33b263f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.10.21](https://github.com/appium/WebDriverAgent/compare/v4.10.20...v4.10.21) (2023-01-26) + + +### Bug Fixes + +* Properly update maxDepth while fetching snapshots ([#655](https://github.com/appium/WebDriverAgent/issues/655)) ([6f99bab](https://github.com/appium/WebDriverAgent/commit/6f99bab5fbdbf65c9ef74c42b5f1b4c658aeaafb)) + ## [4.10.20](https://github.com/appium/WebDriverAgent/compare/v4.10.19...v4.10.20) (2023-01-17) diff --git a/package.json b/package.json index a39f90761..430d4dcdb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.20", + "version": "4.10.21", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From d0a26b3daf43198f0e414db09432cef08665f9c3 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Thu, 26 Jan 2023 20:51:56 -1000 Subject: [PATCH 081/240] docs: update creating bundle section (#656) * docs: update creating bundle section * Update README.md --- README.md | 5 ++++- docs/CREATING_BUNDLES.md | 15 --------------- 2 files changed, 4 insertions(+), 16 deletions(-) delete mode 100644 docs/CREATING_BUNDLES.md diff --git a/README.md b/README.md index 3b6fb3bfe..cc969ba3d 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,10 @@ If you are having some issues please checkout [wiki](https://github.com/facebook If you want to help us out, you are more than welcome to. However please make sure you have followed the guidelines in [CONTRIBUTING](CONTRIBUTING.md). ## Creating Bundles -Follow [this doc](docs/CREATING_BUNDLES.md) + +`npm run bundle` + +Then, you will find `WebDriverAgentRunner-Runner-Sim-.zip` file in the current directory. ## License diff --git a/docs/CREATING_BUNDLES.md b/docs/CREATING_BUNDLES.md deleted file mode 100644 index 404b4e505..000000000 --- a/docs/CREATING_BUNDLES.md +++ /dev/null @@ -1,15 +0,0 @@ -# Creating WebDriverAgent bundles using Azure Pipelines - -The [bundle](https://dev.azure.com/AppiumCI/Appium%20CI/_build?definitionId=36&_a=summary) pipeline uses macOS agents on Azure and iterates through every installed version of Xcode and then builds WebDriverAgent using ./scripts/build-webdriveragents.js - -The bundle pipeline is run every time there is a tag and builds to a folder called `prebuilt-agents` and those agents get uploaded to [GitHub Releases](https://github.com/appium/WebDriverAgent/releases). - -The bundle can be run manually as well, but the GitHub release will not be created. This is useful if you wish to test that it bundles correctly but don't wish to publish it. - -# Creating WebDriverAgent bundle locally - -Building a WebDriverAgent bundle locally is useful if Azure pipelines doesn't build one of the Xcode bundles that we want. - -* Run `node ./Scripts/build-webdriveragent.js` -* This will build a single bundle to `prebuilt-agents` -* The bundle will be built using the Xcode version installed locally From d7c397b0260a71568edd6d99ecf7b39ca3503083 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Mon, 30 Jan 2023 11:29:22 +0100 Subject: [PATCH 082/240] fix: Pull defaultAdditionalRequestParameters dynamically (#658) --- .../XCAXClient_iOS+FBSnapshotReqParams.m | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/WebDriverAgentLib/Categories/XCAXClient_iOS+FBSnapshotReqParams.m b/WebDriverAgentLib/Categories/XCAXClient_iOS+FBSnapshotReqParams.m index e8ee55560..356a1ea05 100644 --- a/WebDriverAgentLib/Categories/XCAXClient_iOS+FBSnapshotReqParams.m +++ b/WebDriverAgentLib/Categories/XCAXClient_iOS+FBSnapshotReqParams.m @@ -45,26 +45,18 @@ static id swizzledDefaultParameters(id self, SEL _cmd) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:original_defaultParameters(self, _cmd)]; - [params addEntriesFromDictionary:defaultAdditionalRequestParameters]; - defaultRequestParameters = params.copy; + defaultRequestParameters = original_defaultParameters(self, _cmd); }); - if (nil == defaultRequestParameters) { - return original_defaultParameters(self, _cmd); - } NSMutableDictionary *result = [NSMutableDictionary dictionaryWithDictionary:defaultRequestParameters]; - if (nil != customRequestParameters && customRequestParameters.count > 0) { - [result addEntriesFromDictionary:customRequestParameters]; - } + [result addEntriesFromDictionary:defaultAdditionalRequestParameters ?: @{}]; + [result addEntriesFromDictionary:customRequestParameters ?: @{}]; return result.copy; } static id swizzledSnapshotParameters(id self, SEL _cmd) { NSDictionary *result = original_snapshotParameters(self, _cmd); - if (nil == defaultAdditionalRequestParameters) { - defaultAdditionalRequestParameters = result; - } + defaultAdditionalRequestParameters = result; return result; } From 9c9f256d076aad52219465e7d3b7e047c9f91978 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 30 Jan 2023 10:37:33 +0000 Subject: [PATCH 083/240] chore(release): 4.10.22 [skip ci] ## [4.10.22](https://github.com/appium/WebDriverAgent/compare/v4.10.21...v4.10.22) (2023-01-30) ### Bug Fixes * Pull defaultAdditionalRequestParameters dynamically ([#658](https://github.com/appium/WebDriverAgent/issues/658)) ([d7c397b](https://github.com/appium/WebDriverAgent/commit/d7c397b0260a71568edd6d99ecf7b39ca3503083)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af33b263f..dcfd8e393 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.10.22](https://github.com/appium/WebDriverAgent/compare/v4.10.21...v4.10.22) (2023-01-30) + + +### Bug Fixes + +* Pull defaultAdditionalRequestParameters dynamically ([#658](https://github.com/appium/WebDriverAgent/issues/658)) ([d7c397b](https://github.com/appium/WebDriverAgent/commit/d7c397b0260a71568edd6d99ecf7b39ca3503083)) + ## [4.10.21](https://github.com/appium/WebDriverAgent/compare/v4.10.20...v4.10.21) (2023-01-26) diff --git a/package.json b/package.json index 430d4dcdb..9991d1c06 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.21", + "version": "4.10.22", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 9d2d047fba57a33787c66a1e8a8449b9538c67be Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sat, 4 Feb 2023 21:22:46 -1000 Subject: [PATCH 084/240] chore: bundle:tv for tvOS (#657) * chore: build:tv for tvOS * env check * tweak --- README.md | 2 +- Scripts/build-webdriveragent.js | 32 +++++++++++++++++++++++++++----- package.json | 4 +++- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index cc969ba3d..547559ebc 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ If you want to help us out, you are more than welcome to. However please make su `npm run bundle` -Then, you will find `WebDriverAgentRunner-Runner-Sim-.zip` file in the current directory. +Then, you find `WebDriverAgentRunner-Runner-sim-.zip` for iOS and `WebDriverAgentRunner-Runner-tv_sim-.zip` for tvOS files in the current directory. ## License diff --git a/Scripts/build-webdriveragent.js b/Scripts/build-webdriveragent.js index a5739d724..1958b876d 100644 --- a/Scripts/build-webdriveragent.js +++ b/Scripts/build-webdriveragent.js @@ -10,7 +10,25 @@ const DERIVED_DATA_PATH = `${ROOT_DIR}/wdaBuild`; const WDA_BUNDLE = 'WebDriverAgentRunner-Runner.app'; const WDA_BUNDLE_PATH = path.join(DERIVED_DATA_PATH, 'Build', 'Products', 'Debug-iphonesimulator'); +const WDA_BUNDLE_TV = 'WebDriverAgentRunner_tvOS-Runner.app'; +const WDA_BUNDLE_TV_PATH = path.join(DERIVED_DATA_PATH, 'Build', 'Products', 'Debug-appletvsimulator'); + +const TARGETS = ['runner', 'tv_runner']; +const SDKS = ['sim', 'tv_sim']; + async function buildWebDriverAgent (xcodeVersion) { + const target = process.env.TARGET; + const sdk = process.env.SDK; + + if (!TARGETS.includes(target)) { + throw Error(`Please set TARGETS environment variable from the supported targets ${JSON.stringify(TARGETS)}`); + } + + if (!SDKS.includes(sdk)) { + throw Error(`Please set SDK environment variable from the supported SDKs ${JSON.stringify(SDKS)}`); + } + + LOG.info(`Cleaning ${DERIVED_DATA_PATH} if exists`); try { await exec('xcodebuild', ['clean', '-derivedDataPath', DERIVED_DATA_PATH, '-scheme', 'WebDriverAgentRunner'], { @@ -25,7 +43,7 @@ async function buildWebDriverAgent (xcodeVersion) { // Clean and build try { await exec('/bin/bash', ['./Scripts/build.sh'], { - env: {TARGET: 'runner', SDK: 'sim', DERIVED_DATA_PATH}, + env: {TARGET: target, SDK: sdk, DERIVED_DATA_PATH}, cwd: ROOT_DIR }); } catch (e) { @@ -34,14 +52,18 @@ async function buildWebDriverAgent (xcodeVersion) { throw e; } - const zipName = `WebDriverAgentRunner-Runner-Sim-${xcodeVersion}.zip`; - LOG.info(`Creating ${zipName} which includes ${WDA_BUNDLE}`); + const isTv = target === 'tv_runner'; + const bundle = isTv ? WDA_BUNDLE_TV : WDA_BUNDLE; + const bundle_path = isTv ? WDA_BUNDLE_TV_PATH : WDA_BUNDLE_PATH; + + const zipName = `WebDriverAgentRunner-Runner-${sdk}-${xcodeVersion}.zip`; + LOG.info(`Creating ${zipName} which includes ${bundle}`); const appBundleZipPath = path.join(ROOT_DIR, zipName); await fs.rimraf(appBundleZipPath); LOG.info(`Created './${zipName}'`); try { - await exec('xattr', ['-cr', WDA_BUNDLE], {cwd: WDA_BUNDLE_PATH}); - await exec('zip', ['-qr', appBundleZipPath, WDA_BUNDLE], {cwd: WDA_BUNDLE_PATH}); + await exec('xattr', ['-cr', bundle], {cwd: bundle_path}); + await exec('zip', ['-qr', appBundleZipPath, bundle], {cwd: bundle_path}); } catch (e) { LOG.error(`===FAILED TO ZIP ARCHIVE`); LOG.error(e.stderr); diff --git a/package.json b/package.json index 9991d1c06..7da03bf77 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,9 @@ "prepare": "npm run build", "test": "mocha --exit --timeout 1m \"./test/unit/**/*-specs.js\"", "e2e-test": "mocha --exit --timeout 10m \"./test/functional/**/*-specs.js\"", - "bundle": "node ./Scripts/build-webdriveragent.js", + "bundle": "npm run bundle:ios && npm run bundle:tv", + "bundle:ios": "TARGET=runner SDK=sim node ./Scripts/build-webdriveragent.js", + "bundle:tv": "TARGET=tv_runner SDK=tv_sim node ./Scripts/build-webdriveragent.js", "fetch-prebuilt-wda": "node ./Scripts/fetch-prebuilt-wda.js" }, "engines": { From 3b6ae38c87dd03f37a9a6c63fb81f4bcba4e9374 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 5 Feb 2023 07:32:16 +0000 Subject: [PATCH 085/240] chore(release): 4.10.23 [skip ci] ## [4.10.23](https://github.com/appium/WebDriverAgent/compare/v4.10.22...v4.10.23) (2023-02-05) ### Miscellaneous Chores * bundle:tv for tvOS ([#657](https://github.com/appium/WebDriverAgent/issues/657)) ([9d2d047](https://github.com/appium/WebDriverAgent/commit/9d2d047fba57a33787c66a1e8a8449b9538c67be)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dcfd8e393..7eb636635 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.10.23](https://github.com/appium/WebDriverAgent/compare/v4.10.22...v4.10.23) (2023-02-05) + + +### Miscellaneous Chores + +* bundle:tv for tvOS ([#657](https://github.com/appium/WebDriverAgent/issues/657)) ([9d2d047](https://github.com/appium/WebDriverAgent/commit/9d2d047fba57a33787c66a1e8a8449b9538c67be)) + ## [4.10.22](https://github.com/appium/WebDriverAgent/compare/v4.10.21...v4.10.22) (2023-01-30) diff --git a/package.json b/package.json index 7da03bf77..1b5267ddc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.22", + "version": "4.10.23", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From a191d51afc546622b502e23175bfe4dc15633e79 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Tue, 7 Feb 2023 19:21:33 +0100 Subject: [PATCH 086/240] ci: Update set-output syntax --- .github/workflows/unit-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index da5e37c93..6b44da0f0 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -19,7 +19,7 @@ jobs: lts2=$(cat eol.list | head -2 | tail -1) lts3=$(cat eol.list | head -3 | tail -1) VERSIONS="[$lts1, $lts2, $lts3]" - echo ::set-output name=versions::${VERSIONS} + echo "versions=${VERSIONS}" >> "$GITHUB_OUTPUT" test: needs: From aa22555f0dcf98de43c95cb20be73e911a97741e Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Fri, 17 Feb 2023 22:43:39 +0100 Subject: [PATCH 087/240] fix: Catch unexpected exceptions thrown by the alerts monitor (#660) --- WebDriverAgentLib/Utilities/FBAlertsMonitor.m | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/WebDriverAgentLib/Utilities/FBAlertsMonitor.m b/WebDriverAgentLib/Utilities/FBAlertsMonitor.m index cdb4a9b3e..c2c625084 100644 --- a/WebDriverAgentLib/Utilities/FBAlertsMonitor.m +++ b/WebDriverAgentLib/Utilities/FBAlertsMonitor.m @@ -11,6 +11,7 @@ #import "FBAlert.h" #import "FBApplication.h" +#import "FBLogger.h" #import "XCUIApplication+FBAlert.h" static const NSTimeInterval FB_MONTORING_INTERVAL = 2.0; @@ -50,9 +51,16 @@ - (void)scheduleNextTick dispatch_async(dispatch_get_main_queue(), ^{ NSArray *activeApps = FBApplication.fb_activeApplications; for (FBApplication *activeApp in activeApps) { - XCUIElement *alertElement = activeApp.fb_alertElement; + XCUIElement *alertElement = nil; + @try { + alertElement = activeApp.fb_alertElement; + if (nil != alertElement) { + [self.delegate didDetectAlert:[FBAlert alertWithElement:alertElement]]; + } + } @catch (NSException *e) { + [FBLogger logFmt:@"Got an unexpected exception while monitoring alerts: %@\n%@", e.reason, e.callStackSymbols]; + } if (nil != alertElement) { - [self.delegate didDetectAlert:[FBAlert alertWithElement:alertElement]]; break; } } From b09c508709059629d4c05eb49e85aae284dcbf18 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 17 Feb 2023 21:51:32 +0000 Subject: [PATCH 088/240] chore(release): 4.10.24 [skip ci] ## [4.10.24](https://github.com/appium/WebDriverAgent/compare/v4.10.23...v4.10.24) (2023-02-17) ### Bug Fixes * Catch unexpected exceptions thrown by the alerts monitor ([#660](https://github.com/appium/WebDriverAgent/issues/660)) ([aa22555](https://github.com/appium/WebDriverAgent/commit/aa22555f0dcf98de43c95cb20be73e911a97741e)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7eb636635..207d77ee6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.10.24](https://github.com/appium/WebDriverAgent/compare/v4.10.23...v4.10.24) (2023-02-17) + + +### Bug Fixes + +* Catch unexpected exceptions thrown by the alerts monitor ([#660](https://github.com/appium/WebDriverAgent/issues/660)) ([aa22555](https://github.com/appium/WebDriverAgent/commit/aa22555f0dcf98de43c95cb20be73e911a97741e)) + ## [4.10.23](https://github.com/appium/WebDriverAgent/compare/v4.10.22...v4.10.23) (2023-02-05) diff --git a/package.json b/package.json index 1b5267ddc..d9178e8d4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.23", + "version": "4.10.24", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From bee564e8c6b975aff07fd1244583f0727a0f5470 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Sun, 19 Feb 2023 09:04:56 +0100 Subject: [PATCH 089/240] feat: Add openUrl handler available since Xcode 14.3 (#661) --- .../XCTest/XCTRunnerDaemonSession.h | 4 ++ WebDriverAgent.xcodeproj/project.pbxproj | 4 ++ .../Categories/XCUIDevice+FBHelpers.h | 16 +++++- .../Categories/XCUIDevice+FBHelpers.m | 33 +++++++++--- .../Commands/FBSessionCommands.m | 11 +++- WebDriverAgentLib/Routing/FBResponsePayload.m | 2 +- .../Utilities/FBClassChainQueryParser.m | 48 ++++++++++++----- WebDriverAgentLib/Utilities/FBRuntimeUtils.m | 2 +- .../Utilities/FBXCTestDaemonsProxy.h | 6 +-- .../Utilities/FBXCTestDaemonsProxy.m | 51 +++++++++++++++++++ .../IntegrationTests/XCUIDeviceHelperTests.m | 21 +++++++- WebDriverAgentTests/UnitTests/FBXPathTests.m | 2 +- 12 files changed, 167 insertions(+), 33 deletions(-) diff --git a/PrivateHeaders/XCTest/XCTRunnerDaemonSession.h b/PrivateHeaders/XCTest/XCTRunnerDaemonSession.h index 4ddeff04d..d1986ffe7 100644 --- a/PrivateHeaders/XCTest/XCTRunnerDaemonSession.h +++ b/PrivateHeaders/XCTest/XCTRunnerDaemonSession.h @@ -67,4 +67,8 @@ - (void)_reportInvalidation; - (id)initWithConnection:(id)arg1; +// Since Xcode 14.3 +- (void)openURL:(NSURL *)arg1 usingApplication:(NSString *)arg2 completion:(void (^)(_Bool, NSError *))arg3; +- (void)openDefaultApplicationForURL:(NSURL *)arg1 completion:(void (^)(_Bool, NSError *))arg2; + @end diff --git a/WebDriverAgent.xcodeproj/project.pbxproj b/WebDriverAgent.xcodeproj/project.pbxproj index 125c26ef0..0378351c1 100644 --- a/WebDriverAgent.xcodeproj/project.pbxproj +++ b/WebDriverAgent.xcodeproj/project.pbxproj @@ -3666,6 +3666,7 @@ "-Wno-objc-messaging-id", "-Wno-direct-ivar-access", "-Wno-cast-qual", + "-Wno-declaration-after-statement", ); }; name = Debug; @@ -3728,6 +3729,7 @@ "-Wno-objc-messaging-id", "-Wno-direct-ivar-access", "-Wno-cast-qual", + "-Wno-declaration-after-statement", ); }; name = Release; @@ -3974,6 +3976,7 @@ "-Wno-objc-messaging-id", "-Wno-direct-ivar-access", "-Wno-cast-qual", + "-Wno-declaration-after-statement", ); }; name = Debug; @@ -4033,6 +4036,7 @@ "-Wno-objc-messaging-id", "-Wno-direct-ivar-access", "-Wno-cast-qual", + "-Wno-declaration-after-statement", ); }; name = Release; diff --git a/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.h b/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.h index 384f8a5d2..d9cd5078e 100644 --- a/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.h +++ b/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.h @@ -71,8 +71,9 @@ typedef NS_ENUM(NSUInteger, FBUIInterfaceAppearance) { - (nullable NSString *)fb_wifiIPAddress; /** - Opens the particular url scheme using Siri voice recognition helpers. - This will only work since XCode 8.3/iOS 10.3 + Opens the particular url scheme using the default application assigned to it. + This API only works since XCode 14.3/iOS 16.4 + Older Xcode/iOS version try to use Siri fallback. @param url The url scheme represented as a string, for example https://apple.com @param error If there is an error, upon return contains an NSError object that describes the problem. @@ -80,6 +81,17 @@ typedef NS_ENUM(NSUInteger, FBUIInterfaceAppearance) { */ - (BOOL)fb_openUrl:(NSString *)url error:(NSError **)error; +/** + Opens the particular url scheme using the given application + This API only works since XCode 14.3/iOS 16.4 + + @param url The url scheme represented as a string, for example https://apple.com + @param bundleId The bundle identifier of an application to use in order to open the given URL + @param error If there is an error, upon return contains an NSError object that describes the problem. + @return YES if the operation was successful + */ +- (BOOL)fb_openUrl:(NSString *)url withApplication:(NSString *)bundleId error:(NSError **)error; + /** Presses the corresponding hardware button on the device with duration. diff --git a/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m b/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m index 2e0848251..a68458b33 100644 --- a/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m +++ b/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m @@ -21,6 +21,7 @@ #import "FBScreenshot.h" #import "FBXCDeviceEvent.h" #import "FBXCodeCompatibility.h" +#import "FBXCTestDaemonsProxy.h" #import "XCUIDevice.h" static const NSTimeInterval FBHomeButtonCoolOffTime = 1.; @@ -157,20 +158,38 @@ - (BOOL)fb_openUrl:(NSString *)url error:(NSError **)error buildError:error]; } + NSError *err; + if ([FBXCTestDaemonsProxy openDefaultApplicationForURL:parsedUrl error:&err]) { + return YES; + } + if (![err.description containsString:@"does not support"]) { + if (error) { + *error = err; + } + return NO; + } + id siriService = [self valueForKey:@"siriService"]; if (nil != siriService) { return [self fb_activateSiriVoiceRecognitionWithText:[NSString stringWithFormat:@"Open {%@}", url] error:error]; } -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - // The link never gets opened by this method: https://forums.developer.apple.com/thread/25355 - if (![[UIApplication sharedApplication] openURL:parsedUrl]) { -#pragma clang diagnostic pop + + NSString *description = [NSString stringWithFormat:@"Cannot open '%@' with the default application assigned for it. Consider upgrading to Xcode 14.3+/iOS 16.4+", url]; + return [[[FBErrorBuilder builder] + withDescriptionFormat:@"%@", description] + buildError:error];; +} + +- (BOOL)fb_openUrl:(NSString *)url withApplication:(NSString *)bundleId error:(NSError **)error +{ + NSURL *parsedUrl = [NSURL URLWithString:url]; + if (nil == parsedUrl) { return [[[FBErrorBuilder builder] - withDescriptionFormat:@"The URL %@ cannot be opened", url] + withDescriptionFormat:@"'%@' is not a valid URL", url] buildError:error]; } - return YES; + + return [FBXCTestDaemonsProxy openURL:parsedUrl usingApplication:bundleId error:error]; } - (BOOL)fb_activateSiriVoiceRecognitionWithText:(NSString *)text error:(NSError **)error diff --git a/WebDriverAgentLib/Commands/FBSessionCommands.m b/WebDriverAgentLib/Commands/FBSessionCommands.m index 3100ba710..565939080 100644 --- a/WebDriverAgentLib/Commands/FBSessionCommands.m +++ b/WebDriverAgentLib/Commands/FBSessionCommands.m @@ -66,9 +66,16 @@ + (NSArray *)routes if (!urlString) { return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:@"URL is required" traceback:nil]); } + NSString* bundleId = request.arguments[@"bundleId"]; NSError *error; - if (![XCUIDevice.sharedDevice fb_openUrl:urlString error:&error]) { - return FBResponseWithUnknownError(error); + if (nil == bundleId) { + if (![XCUIDevice.sharedDevice fb_openUrl:urlString error:&error]) { + return FBResponseWithUnknownError(error); + } + } else { + if (![XCUIDevice.sharedDevice fb_openUrl:urlString withApplication:bundleId error:&error]) { + return FBResponseWithUnknownError(error); + } } return FBResponseWithOK(); } diff --git a/WebDriverAgentLib/Routing/FBResponsePayload.m b/WebDriverAgentLib/Routing/FBResponsePayload.m index 1fa81024a..08fcd63fe 100644 --- a/WebDriverAgentLib/Routing/FBResponsePayload.m +++ b/WebDriverAgentLib/Routing/FBResponsePayload.m @@ -24,7 +24,7 @@ NSString *arbitraryAttrPrefix = @"attribute/"; -id FBResponseWithOK() +id FBResponseWithOK(void) { return FBResponseWithStatus(FBCommandStatus.ok); } diff --git a/WebDriverAgentLib/Utilities/FBClassChainQueryParser.m b/WebDriverAgentLib/Utilities/FBClassChainQueryParser.m index cb4ba3077..f04240d0d 100644 --- a/WebDriverAgentLib/Utilities/FBClassChainQueryParser.m +++ b/WebDriverAgentLib/Utilities/FBClassChainQueryParser.m @@ -502,7 +502,9 @@ + (NSError *)compilationErrorWithQuery:(NSString *)originalQuery description:(NS return [[FBErrorBuilder.builder withDescription:fullDescription] build]; } -+ (nullable FBClassChain*)compiledQueryWithTokenizedQuery:(NSArray *)tokenizedQuery originalQuery:(NSString *)originalQuery error:(NSError **)error ++ (nullable FBClassChain*)compiledQueryWithTokenizedQuery:(NSArray *)tokenizedQuery + originalQuery:(NSString *)originalQuery + error:(NSError **)error { NSMutableArray *result = [NSMutableArray array]; XCUIElementType chainElementType = XCUIElementTypeAny; @@ -514,8 +516,10 @@ + (nullable FBClassChain*)compiledQueryWithTokenizedQuery:(NSArray)testRunnerProxy; @@ -28,6 +25,9 @@ NS_ASSUME_NONNULL_BEGIN + (BOOL)synthesizeEventWithRecord:(XCSynthesizedEventRecord *)record error:(NSError *__autoreleasing*)error; ++ (BOOL)openURL:(NSURL *)url usingApplication:(NSString *)bundleId error:(NSError **)error; ++ (BOOL)openDefaultApplicationForURL:(NSURL *)url error:(NSError **)error; + @end NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m b/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m index 708e027f2..b09a46e56 100644 --- a/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m +++ b/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m @@ -12,6 +12,7 @@ #import #import "FBConfiguration.h" +#import "FBErrorBuilder.h" #import "FBLogger.h" #import "FBRunLoopSpinner.h" #import "XCTestDriver.h" @@ -96,4 +97,54 @@ + (BOOL)synthesizeEventWithRecord:(XCSynthesizedEventRecord *)record error:(NSEr return didSucceed; } ++ (BOOL)openURL:(NSURL *)url usingApplication:(NSString *)bundleId error:(NSError *__autoreleasing*)error +{ + XCTRunnerDaemonSession *session = [FBXCTRunnerDaemonSessionClass sharedSession]; + if (![session respondsToSelector:@selector(openURL:usingApplication:completion:)]) { + if (error) { + [[[FBErrorBuilder builder] + withDescriptionFormat:@"The current Xcode SDK does not support opening of URLs with given application"] + buildError:error]; + } + return NO; + } + + __block BOOL didSucceed = NO; + [FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){ + [session openURL:url usingApplication:bundleId completion:^(bool result, NSError *invokeError) { + if (error) { + *error = invokeError; + } + didSucceed = invokeError == nil && result; + completion(); + }]; + }]; + return didSucceed; +} + ++ (BOOL)openDefaultApplicationForURL:(NSURL *)url error:(NSError *__autoreleasing*)error +{ + XCTRunnerDaemonSession *session = [FBXCTRunnerDaemonSessionClass sharedSession]; + if (![session respondsToSelector:@selector(openDefaultApplicationForURL:completion:)]) { + if (error) { + [[[FBErrorBuilder builder] + withDescriptionFormat:@"The current Xcode SDK does not support opening of URLs. Consider upgrading to Xcode 14.3+/iOS 16.4+"] + buildError:error]; + } + return NO; + } + + __block BOOL didSucceed = NO; + [FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){ + [session openDefaultApplicationForURL:url completion:^(bool result, NSError *invokeError) { + if (error) { + *error = invokeError; + } + didSucceed = invokeError == nil && result; + completion(); + }]; + }]; + return didSucceed; +} + @end diff --git a/WebDriverAgentTests/IntegrationTests/XCUIDeviceHelperTests.m b/WebDriverAgentTests/IntegrationTests/XCUIDeviceHelperTests.m index bfa2470a3..953f4a2b9 100644 --- a/WebDriverAgentTests/IntegrationTests/XCUIDeviceHelperTests.m +++ b/WebDriverAgentTests/IntegrationTests/XCUIDeviceHelperTests.m @@ -118,15 +118,32 @@ - (void)testLockUnlockScreen XCTAssertNil(error); } -- (void)disabled_testUrlSchemeActivation +- (void)testUrlSchemeActivation { - // This test is not stable on CI because of system slowness + if (SYSTEM_VERSION_LESS_THAN(@"16.4")) { + return; + } + NSError *error; XCTAssertTrue([XCUIDevice.sharedDevice fb_openUrl:@"https://apple.com" error:&error]); FBAssertWaitTillBecomesTrue([FBApplication.fb_activeApplication.bundleID isEqualToString:@"com.apple.mobilesafari"]); XCTAssertNil(error); } +- (void)testUrlSchemeActivationWithApp +{ + if (SYSTEM_VERSION_LESS_THAN(@"16.4")) { + return; + } + + NSError *error; + XCTAssertTrue([XCUIDevice.sharedDevice fb_openUrl:@"https://apple.com" + withApplication:@"com.apple.mobilesafari" + error:&error]); + FBAssertWaitTillBecomesTrue([FBApplication.fb_activeApplication.bundleID isEqualToString:@"com.apple.mobilesafari"]); + XCTAssertNil(error); +} + - (void)testPressingUnsupportedButton { NSError *error; diff --git a/WebDriverAgentTests/UnitTests/FBXPathTests.m b/WebDriverAgentTests/UnitTests/FBXPathTests.m index a04dab23e..058d6dc89 100644 --- a/WebDriverAgentTests/UnitTests/FBXPathTests.m +++ b/WebDriverAgentTests/UnitTests/FBXPathTests.m @@ -29,7 +29,7 @@ - (NSString *)xmlStringWithElement:(id)element xmlTextWriterPtr writer = xmlNewTextWriterDoc(&doc, 0); NSMutableDictionary *elementStore = [NSMutableDictionary dictionary]; int buffersize; - xmlChar *xmlbuff; + xmlChar *xmlbuff = NULL; int rc = xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL); if (rc >= 0) { rc = [FBXPath xmlRepresentationWithRootElement:element From 6f0fc779466fc5cd4e67cbc402acf756177c92ac Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 19 Feb 2023 08:11:59 +0000 Subject: [PATCH 090/240] chore(release): 4.11.0 [skip ci] ## [4.11.0](https://github.com/appium/WebDriverAgent/compare/v4.10.24...v4.11.0) (2023-02-19) ### Features * Add openUrl handler available since Xcode 14.3 ([#661](https://github.com/appium/WebDriverAgent/issues/661)) ([bee564e](https://github.com/appium/WebDriverAgent/commit/bee564e8c6b975aff07fd1244583f0727a0f5470)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 207d77ee6..58543738e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.11.0](https://github.com/appium/WebDriverAgent/compare/v4.10.24...v4.11.0) (2023-02-19) + + +### Features + +* Add openUrl handler available since Xcode 14.3 ([#661](https://github.com/appium/WebDriverAgent/issues/661)) ([bee564e](https://github.com/appium/WebDriverAgent/commit/bee564e8c6b975aff07fd1244583f0727a0f5470)) + ## [4.10.24](https://github.com/appium/WebDriverAgent/compare/v4.10.23...v4.10.24) (2023-02-17) diff --git a/package.json b/package.json index d9178e8d4..9839a2ba0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.10.24", + "version": "4.11.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From ebb9e60d56c0e0db9f509437ed639a3a39f6011b Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Mon, 20 Feb 2023 08:39:57 +0100 Subject: [PATCH 091/240] feat: Add support of the simulated geolocation setting (#662) --- .../XCTest/XCTRunnerDaemonSession.h | 9 ++ .../Categories/XCUIDevice+FBHelpers.h | 34 ++++++ .../Categories/XCUIDevice+FBHelpers.m | 17 +++ WebDriverAgentLib/Commands/FBCustomCommands.m | 74 +++++++++++-- .../Utilities/FBXCTestDaemonsProxy.h | 11 ++ .../Utilities/FBXCTestDaemonsProxy.m | 103 ++++++++++++++++++ .../IntegrationTests/XCUIDeviceHelperTests.m | 25 +++++ 7 files changed, 263 insertions(+), 10 deletions(-) diff --git a/PrivateHeaders/XCTest/XCTRunnerDaemonSession.h b/PrivateHeaders/XCTest/XCTRunnerDaemonSession.h index d1986ffe7..1afedbbef 100644 --- a/PrivateHeaders/XCTest/XCTRunnerDaemonSession.h +++ b/PrivateHeaders/XCTest/XCTRunnerDaemonSession.h @@ -10,6 +10,9 @@ #import @class NSMutableDictionary, NSXPCConnection, XCSynthesizedEventRecord; +#if !TARGET_OS_TV // tvOS does not provide relevant APIs +@class CLLocation; +#endif @protocol XCTUIApplicationMonitor, XCTAXClient, XCTestManager_ManagerInterface; // iOS since 10.3 @@ -70,5 +73,11 @@ // Since Xcode 14.3 - (void)openURL:(NSURL *)arg1 usingApplication:(NSString *)arg2 completion:(void (^)(_Bool, NSError *))arg3; - (void)openDefaultApplicationForURL:(NSURL *)arg1 completion:(void (^)(_Bool, NSError *))arg2; +#if !TARGET_OS_TV // tvOS does not provide relevant APIs +- (void)setSimulatedLocation:(CLLocation *)arg1 completion:(void (^)(_Bool, NSError *))arg2; +- (void)getSimulatedLocationWithReply:(void (^)(CLLocation *, NSError *))arg1; +- (void)clearSimulatedLocationWithReply:(void (^)(_Bool, NSError *))arg1; +@property(readonly) _Bool supportsLocationSimulation; +#endif @end diff --git a/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.h b/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.h index d9cd5078e..b868e1cc6 100644 --- a/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.h +++ b/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.h @@ -9,6 +9,10 @@ #import +#if !TARGET_OS_TV +#import +#endif + NS_ASSUME_NONNULL_BEGIN typedef NS_ENUM(NSUInteger, FBUIInterfaceAppearance) { @@ -154,6 +158,36 @@ typedef NS_ENUM(NSUInteger, FBUIInterfaceAppearance) { */ - (nullable NSNumber *)fb_getAppearance; +#if !TARGET_OS_TV +/** + Allows to set a simulated geolocation coordinates. + Only works since Xcode 14.3/iOS 16.4 + + @param location The simlated location coordinates to set + @param error If there is an error, upon return contains an NSError object that describes the problem. + @return YES if the simulated location has been successfully set + */ +- (BOOL)fb_setSimulatedLocation:(CLLocation *)location error:(NSError **)error; + +/** + Allows to get a simulated geolocation coordinates. + Only works since Xcode 14.3/iOS 16.4 + + @param error If there is an error, upon return contains an NSError object that describes the problem. + @return The current simulated location or nil in case of failure + */ +- (nullable CLLocation *)fb_getSimulatedLocation:(NSError **)error; + +/** + Allows to clear a previosuly set simulated geolocation coordinates. + Only works since Xcode 14.3/iOS 16.4 + + @param error If there is an error, upon return contains an NSError object that describes the problem. + @return YES if the simulated location has been successfully cleared + */ +- (BOOL)fb_clearSimulatedLocation:(NSError **)error; +#endif + @end NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m b/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m index a68458b33..1bc95a33e 100644 --- a/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m +++ b/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m @@ -355,4 +355,21 @@ - (NSNumber *)fb_getAppearance : nil; } +#if !TARGET_OS_TV +- (BOOL)fb_setSimulatedLocation:(CLLocation *)location error:(NSError **)error +{ + return [FBXCTestDaemonsProxy setSimulatedLocation:location error:error]; +} + +- (nullable CLLocation *)fb_getSimulatedLocation:(NSError **)error +{ + return [FBXCTestDaemonsProxy getSimulatedLocation:error]; +} + +- (BOOL)fb_clearSimulatedLocation:(NSError **)error +{ + return [FBXCTestDaemonsProxy clearSimulatedLocation:error]; +} +#endif + @end diff --git a/WebDriverAgentLib/Commands/FBCustomCommands.m b/WebDriverAgentLib/Commands/FBCustomCommands.m index 2f4f8a6cb..d9f24d6dd 100644 --- a/WebDriverAgentLib/Commands/FBCustomCommands.m +++ b/WebDriverAgentLib/Commands/FBCustomCommands.m @@ -66,6 +66,14 @@ + (NSArray *)routes [[FBRoute POST:@"/wda/device/appearance"].withoutSession respondWithTarget:self action:@selector(handleSetDeviceAppearance:)], [[FBRoute GET:@"/wda/device/location"] respondWithTarget:self action:@selector(handleGetLocation:)], [[FBRoute GET:@"/wda/device/location"].withoutSession respondWithTarget:self action:@selector(handleGetLocation:)], +#if !TARGET_OS_TV // tvOS does not provide relevant APIs + [[FBRoute GET:@"/wda/simulatedLocation"] respondWithTarget:self action:@selector(handleGetSimulatedLocation:)], + [[FBRoute GET:@"/wda/simulatedLocation"].withoutSession respondWithTarget:self action:@selector(handleGetSimulatedLocation:)], + [[FBRoute POST:@"/wda/simulatedLocation"] respondWithTarget:self action:@selector(handleSetSimulatedLocation:)], + [[FBRoute POST:@"/wda/simulatedLocation"].withoutSession respondWithTarget:self action:@selector(handleSetSimulatedLocation:)], + [[FBRoute DELETE:@"/wda/simulatedLocation"] respondWithTarget:self action:@selector(handleClearSimulatedLocation:)], + [[FBRoute DELETE:@"/wda/simulatedLocation"].withoutSession respondWithTarget:self action:@selector(handleClearSimulatedLocation:)], +#endif [[FBRoute OPTIONS:@"/*"].withoutSession respondWithTarget:self action:@selector(handlePingCommand:)], ]; } @@ -106,9 +114,9 @@ + (NSArray *)routes BOOL isDismissed = [request.session.activeApplication fb_dismissKeyboardWithKeyNames:request.arguments[@"keyNames"] error:&error]; return isDismissed - ? FBResponseWithOK() - : FBResponseWithStatus([FBCommandStatus invalidElementStateErrorWithMessage:error.description - traceback:nil]); + ? FBResponseWithOK() + : FBResponseWithStatus([FBCommandStatus invalidElementStateErrorWithMessage:error.description + traceback:nil]); } + (id)handlePingCommand:(FBRouteRequest *)request @@ -123,12 +131,12 @@ + (NSArray *)routes FBSession *session = request.session; CGSize statusBarSize = [FBScreen statusBarSizeForApplication:session.activeApplication]; return FBResponseWithObject( - @{ + @{ @"statusBarSize": @{@"width": @(statusBarSize.width), @"height": @(statusBarSize.height), - }, + }, @"scale": @([FBScreen scale]), - }); + }); } + (id)handleLock:(FBRouteRequest *)request @@ -325,7 +333,7 @@ + (NSDictionary *)processArguments:(XCUIApplication *)app CLAuthorizationStatus authStatus; if ([locationManager respondsToSelector:@selector(authorizationStatus)]) { NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[locationManager class] - instanceMethodSignatureForSelector:@selector(authorizationStatus)]]; + instanceMethodSignatureForSelector:@selector(authorizationStatus)]]; [invocation setSelector:@selector(authorizationStatus)]; [invocation setTarget:locationManager]; [invocation invoke]; @@ -379,8 +387,8 @@ + (NSDictionary *)processArguments:(XCUIApplication *)app } FBUIInterfaceAppearance appearance = [name isEqualToString:@"light"] - ? FBUIInterfaceAppearanceLight - : FBUIInterfaceAppearanceDark; + ? FBUIInterfaceAppearanceLight + : FBUIInterfaceAppearanceDark; NSError *error; if (![XCUIDevice.sharedDevice fb_setAppearance:appearance error:&error]) { return FBResponseWithStatus([FBCommandStatus unknownErrorWithMessage:error.description @@ -397,7 +405,7 @@ + (NSDictionary *)processArguments:(XCUIApplication *)app NSString *currentLocale = [[NSLocale autoupdatingCurrentLocale] localeIdentifier]; NSMutableDictionary *deviceInfo = [NSMutableDictionary dictionaryWithDictionary: - @{ + @{ @"currentLocale": currentLocale, @"timeZone": self.timeZone, @"name": UIDevice.currentDevice.name, @@ -490,4 +498,50 @@ + (NSString *)timeZone return [localTimeZone name]; } +#if !TARGET_OS_TV // tvOS does not provide relevant APIs ++ (id)handleGetSimulatedLocation:(FBRouteRequest *)request +{ + NSError *error; + CLLocation *location = [XCUIDevice.sharedDevice fb_getSimulatedLocation:&error]; + if (nil == location) { + return FBResponseWithStatus([FBCommandStatus unknownErrorWithMessage:error.description + traceback:nil]); + } + return FBResponseWithObject(@{ + @"latitude": @(location.coordinate.latitude), + @"longiture": @(location.coordinate.longitude), + @"altitude": @(location.altitude), + }); +} + ++ (id)handleSetSimulatedLocation:(FBRouteRequest *)request +{ + NSNumber *longitude = request.arguments[@"longitude"]; + NSNumber *latitude = request.arguments[@"latitude"]; + + if (nil == longitude || nil == latitude) { + return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:@"Both latitude and longitude must be provided" + traceback:nil]); + } + NSError *error; + CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude.doubleValue + longitude:longitude.doubleValue]; + if (![XCUIDevice.sharedDevice fb_setSimulatedLocation:location error:&error]) { + return FBResponseWithStatus([FBCommandStatus unknownErrorWithMessage:error.description + traceback:nil]); + } + return FBResponseWithOK(); +} + ++ (id)handleClearSimulatedLocation:(FBRouteRequest *)request +{ + NSError *error; + if (![XCUIDevice.sharedDevice fb_clearSimulatedLocation:&error]) { + return FBResponseWithStatus([FBCommandStatus unknownErrorWithMessage:error.description + traceback:nil]); + } + return FBResponseWithOK(); +} +#endif + @end diff --git a/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.h b/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.h index 9bb2eae60..8c795c5be 100644 --- a/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.h +++ b/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.h @@ -8,6 +8,11 @@ */ #import + +#if !TARGET_OS_TV +#import +#endif + #import "XCSynthesizedEventRecord.h" NS_ASSUME_NONNULL_BEGIN @@ -28,6 +33,12 @@ NS_ASSUME_NONNULL_BEGIN + (BOOL)openURL:(NSURL *)url usingApplication:(NSString *)bundleId error:(NSError **)error; + (BOOL)openDefaultApplicationForURL:(NSURL *)url error:(NSError **)error; +#if !TARGET_OS_TV ++ (BOOL)setSimulatedLocation:(CLLocation *)location error:(NSError **)error; ++ (nullable CLLocation *)getSimulatedLocation:(NSError **)error; ++ (BOOL)clearSimulatedLocation:(NSError **)error; +#endif + @end NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m b/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m index b09a46e56..f6ebcc42c 100644 --- a/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m +++ b/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m @@ -147,4 +147,107 @@ + (BOOL)openDefaultApplicationForURL:(NSURL *)url error:(NSError *__autoreleasin return didSucceed; } +#if !TARGET_OS_TV ++ (BOOL)setSimulatedLocation:(CLLocation *)location error:(NSError *__autoreleasing*)error +{ + XCTRunnerDaemonSession *session = [FBXCTRunnerDaemonSessionClass sharedSession]; + if (![session respondsToSelector:@selector(setSimulatedLocation:completion:)]) { + if (error) { + [[[FBErrorBuilder builder] + withDescriptionFormat:@"The current Xcode SDK does not support location simulation. Consider upgrading to Xcode 14.3+/iOS 16.4+"] + buildError:error]; + } + return NO; + } + if (![session supportsLocationSimulation]) { + if (error) { + [[[FBErrorBuilder builder] + withDescriptionFormat:@"Your device does not support location simulation"] + buildError:error]; + } + return NO; + } + + __block BOOL didSucceed = NO; + [FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){ + [session setSimulatedLocation:location completion:^(bool result, NSError *invokeError) { + if (error) { + *error = invokeError; + } + didSucceed = invokeError == nil && result; + completion(); + }]; + }]; + return didSucceed; +} + ++ (nullable CLLocation *)getSimulatedLocation:(NSError *__autoreleasing*)error; +{ + XCTRunnerDaemonSession *session = [FBXCTRunnerDaemonSessionClass sharedSession]; + if (![session respondsToSelector:@selector(getSimulatedLocationWithReply:)]) { + if (error) { + [[[FBErrorBuilder builder] + withDescriptionFormat:@"The current Xcode SDK does not support location simulation. Consider upgrading to Xcode 14.3+/iOS 16.4+"] + buildError:error]; + } + return nil; + } + if (![session supportsLocationSimulation]) { + if (error) { + [[[FBErrorBuilder builder] + withDescriptionFormat:@"Your device does not support location simulation"] + buildError:error]; + } + return nil; + } + + __block CLLocation *location = nil; + [FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){ + [session getSimulatedLocationWithReply:^(CLLocation *reply, NSError *invokeError) { + if (error) { + *error = invokeError; + } + if (nil == invokeError) { + location = reply; + } + completion(); + }]; + }]; + return location; +} + ++ (BOOL)clearSimulatedLocation:(NSError *__autoreleasing*)error +{ + XCTRunnerDaemonSession *session = [FBXCTRunnerDaemonSessionClass sharedSession]; + if (![session respondsToSelector:@selector(clearSimulatedLocationWithReply:)]) { + if (error) { + [[[FBErrorBuilder builder] + withDescriptionFormat:@"The current Xcode SDK does not support location simulation. Consider upgrading to Xcode 14.3+/iOS 16.4+"] + buildError:error]; + } + return NO; + } + if (![session supportsLocationSimulation]) { + if (error) { + [[[FBErrorBuilder builder] + withDescriptionFormat:@"Your device does not support location simulation"] + buildError:error]; + } + return NO; + } + + __block BOOL didSucceed = NO; + [FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){ + [session clearSimulatedLocationWithReply:^(bool result, NSError *invokeError) { + if (error) { + *error = invokeError; + } + didSucceed = invokeError == nil && result; + completion(); + }]; + }]; + return didSucceed; +} +#endif + @end diff --git a/WebDriverAgentTests/IntegrationTests/XCUIDeviceHelperTests.m b/WebDriverAgentTests/IntegrationTests/XCUIDeviceHelperTests.m index 953f4a2b9..52a910311 100644 --- a/WebDriverAgentTests/IntegrationTests/XCUIDeviceHelperTests.m +++ b/WebDriverAgentTests/IntegrationTests/XCUIDeviceHelperTests.m @@ -144,6 +144,31 @@ - (void)testUrlSchemeActivationWithApp XCTAssertNil(error); } +#if !TARGET_OS_TV +- (void)testSimulatedLocationSetup +{ + if (SYSTEM_VERSION_LESS_THAN(@"16.4")) { + return; + } + + CLLocation *simulatedLocation = [[CLLocation alloc] initWithLatitude:50 longitude:50]; + NSError *error; + XCTAssertTrue([XCUIDevice.sharedDevice fb_setSimulatedLocation:simulatedLocation error:&error]); + XCTAssertNil(error); + CLLocation *currentLocation = [XCUIDevice.sharedDevice fb_getSimulatedLocation:&error]; + XCTAssertNil(error); + XCTAssertNotNil(currentLocation); + XCTAssertEqualWithAccuracy(simulatedLocation.coordinate.latitude, currentLocation.coordinate.latitude, 0.1); + XCTAssertEqualWithAccuracy(simulatedLocation.coordinate.longitude, currentLocation.coordinate.longitude, 0.1); + XCTAssertTrue([XCUIDevice.sharedDevice fb_clearSimulatedLocation:&error]); + XCTAssertNil(error); + currentLocation = [XCUIDevice.sharedDevice fb_getSimulatedLocation:&error]; + XCTAssertNil(error); + XCTAssertNotEqualWithAccuracy(simulatedLocation.coordinate.latitude, currentLocation.coordinate.latitude, 0.1); + XCTAssertNotEqualWithAccuracy(simulatedLocation.coordinate.longitude, currentLocation.coordinate.longitude, 0.1); +} +#endif + - (void)testPressingUnsupportedButton { NSError *error; From 309bfc18f55b078a24428c2bc314f56092931116 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 20 Feb 2023 07:47:24 +0000 Subject: [PATCH 092/240] chore(release): 4.12.0 [skip ci] ## [4.12.0](https://github.com/appium/WebDriverAgent/compare/v4.11.0...v4.12.0) (2023-02-20) ### Features * Add support of the simulated geolocation setting ([#662](https://github.com/appium/WebDriverAgent/issues/662)) ([ebb9e60](https://github.com/appium/WebDriverAgent/commit/ebb9e60d56c0e0db9f509437ed639a3a39f6011b)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58543738e..27c941324 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.12.0](https://github.com/appium/WebDriverAgent/compare/v4.11.0...v4.12.0) (2023-02-20) + + +### Features + +* Add support of the simulated geolocation setting ([#662](https://github.com/appium/WebDriverAgent/issues/662)) ([ebb9e60](https://github.com/appium/WebDriverAgent/commit/ebb9e60d56c0e0db9f509437ed639a3a39f6011b)) + ## [4.11.0](https://github.com/appium/WebDriverAgent/compare/v4.10.24...v4.11.0) (2023-02-19) diff --git a/package.json b/package.json index 9839a2ba0..81bc12bf0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.11.0", + "version": "4.12.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 6a5c48bd2ffc43c0f0d9bf781671bbcf171f9375 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Mon, 20 Feb 2023 20:28:01 +0100 Subject: [PATCH 093/240] fix: Return null if no simulated location has been previously set (#663) --- WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.h | 3 ++- WebDriverAgentLib/Commands/FBCustomCommands.m | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.h b/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.h index b868e1cc6..e60efaa48 100644 --- a/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.h +++ b/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.h @@ -174,7 +174,8 @@ typedef NS_ENUM(NSUInteger, FBUIInterfaceAppearance) { Only works since Xcode 14.3/iOS 16.4 @param error If there is an error, upon return contains an NSError object that describes the problem. - @return The current simulated location or nil in case of failure + @return The current simulated location or nil in case of failure or if no location has previously been seet + (the returned error will be nil in the latter case) */ - (nullable CLLocation *)fb_getSimulatedLocation:(NSError **)error; diff --git a/WebDriverAgentLib/Commands/FBCustomCommands.m b/WebDriverAgentLib/Commands/FBCustomCommands.m index d9f24d6dd..6fd41d6a4 100644 --- a/WebDriverAgentLib/Commands/FBCustomCommands.m +++ b/WebDriverAgentLib/Commands/FBCustomCommands.m @@ -503,14 +503,14 @@ + (NSString *)timeZone { NSError *error; CLLocation *location = [XCUIDevice.sharedDevice fb_getSimulatedLocation:&error]; - if (nil == location) { + if (nil != error) { return FBResponseWithStatus([FBCommandStatus unknownErrorWithMessage:error.description traceback:nil]); } return FBResponseWithObject(@{ - @"latitude": @(location.coordinate.latitude), - @"longiture": @(location.coordinate.longitude), - @"altitude": @(location.altitude), + @"latitude": location ? @(location.coordinate.latitude) : NSNull.null, + @"longitude": location ? @(location.coordinate.longitude) : NSNull.null, + @"altitude": location ? @(location.altitude) : NSNull.null, }); } From 2b9c5bfa29cae982bed0afa56810755eb845112d Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 20 Feb 2023 19:39:13 +0000 Subject: [PATCH 094/240] chore(release): 4.12.1 [skip ci] ## [4.12.1](https://github.com/appium/WebDriverAgent/compare/v4.12.0...v4.12.1) (2023-02-20) ### Bug Fixes * Return null if no simulated location has been previously set ([#663](https://github.com/appium/WebDriverAgent/issues/663)) ([6a5c48b](https://github.com/appium/WebDriverAgent/commit/6a5c48bd2ffc43c0f0d9bf781671bbcf171f9375)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27c941324..3a4876f6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.12.1](https://github.com/appium/WebDriverAgent/compare/v4.12.0...v4.12.1) (2023-02-20) + + +### Bug Fixes + +* Return null if no simulated location has been previously set ([#663](https://github.com/appium/WebDriverAgent/issues/663)) ([6a5c48b](https://github.com/appium/WebDriverAgent/commit/6a5c48bd2ffc43c0f0d9bf781671bbcf171f9375)) + ## [4.12.0](https://github.com/appium/WebDriverAgent/compare/v4.11.0...v4.12.0) (2023-02-20) diff --git a/package.json b/package.json index 81bc12bf0..e253a8f0e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.12.0", + "version": "4.12.1", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From cafe47e9bea9649a0e9b4a2b96ca44434bbac411 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Wed, 22 Feb 2023 10:09:29 +0100 Subject: [PATCH 095/240] chore: Make sure the test is never going to be unexpectedly interrupted (#664) --- WebDriverAgent.xcodeproj/project.pbxproj | 24 ++++++------ .../Categories/XCTIssue+FBPatcher.h | 18 +++++++++ .../Categories/XCTIssue+FBPatcher.m | 33 ++++++++++++++++ .../Utilities/FBFailureProofTestCase.m | 38 ++++++++++--------- ...estCaseImplementationFailureHoldingProxy.h | 29 -------------- ...estCaseImplementationFailureHoldingProxy.m | 38 ------------------- WebDriverAgentLib/WebDriverAgentLib.h | 1 + 7 files changed, 85 insertions(+), 96 deletions(-) create mode 100644 WebDriverAgentLib/Categories/XCTIssue+FBPatcher.h create mode 100644 WebDriverAgentLib/Categories/XCTIssue+FBPatcher.m delete mode 100644 WebDriverAgentLib/Utilities/FBXCTestCaseImplementationFailureHoldingProxy.h delete mode 100644 WebDriverAgentLib/Utilities/FBXCTestCaseImplementationFailureHoldingProxy.m diff --git a/WebDriverAgent.xcodeproj/project.pbxproj b/WebDriverAgent.xcodeproj/project.pbxproj index 0378351c1..7b8cf620e 100644 --- a/WebDriverAgent.xcodeproj/project.pbxproj +++ b/WebDriverAgent.xcodeproj/project.pbxproj @@ -74,7 +74,6 @@ 641EE5F52240C5CA00173FCB /* XCUIElement+FBUID.m in Sources */ = {isa = PBXBuildFile; fileRef = 71B49EC61ED1A58100D51AD6 /* XCUIElement+FBUID.m */; }; 641EE5F62240C5CA00173FCB /* FBRouteRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9AB7881CAEDF0C008C271F /* FBRouteRequest.m */; }; 641EE5F72240C5CA00173FCB /* FBResponseJSONPayload.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9AB7811CAEDF0C008C271F /* FBResponseJSONPayload.m */; }; - 641EE5F82240C5CA00173FCB /* FBXCTestCaseImplementationFailureHoldingProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = EE7E271B1D06C69F001BEC7B /* FBXCTestCaseImplementationFailureHoldingProxy.m */; }; 641EE5F92240C5CA00173FCB /* FBMjpegServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 7155D702211DCEF400166C20 /* FBMjpegServer.m */; }; 641EE5FA2240C5CA00173FCB /* XCUIDevice+FBHealthCheck.m in Sources */ = {isa = PBXBuildFile; fileRef = EEDFE1201D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.m */; }; 641EE5FD2240C5CA00173FCB /* FBBaseActionsSynthesizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 7140974D1FAE20EE008FB2C5 /* FBBaseActionsSynthesizer.m */; }; @@ -275,7 +274,6 @@ 641EE6D72240C5CA00173FCB /* XCTestObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = EE35ACE21E3B77D600A02D78 /* XCTestObserver.h */; settings = {ATTRIBUTES = (Public, ); }; }; 641EE6D82240C5CA00173FCB /* XCUIElement.h in Headers */ = {isa = PBXBuildFile; fileRef = EE35ACFE1E3B77D600A02D78 /* XCUIElement.h */; settings = {ATTRIBUTES = (Public, ); }; }; 641EE6D92240C5CA00173FCB /* XCKeyboardInputSolver.h in Headers */ = {isa = PBXBuildFile; fileRef = EE35ACBE1E3B77D600A02D78 /* XCKeyboardInputSolver.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 641EE6DA2240C5CA00173FCB /* FBXCTestCaseImplementationFailureHoldingProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = EE7E271A1D06C69F001BEC7B /* FBXCTestCaseImplementationFailureHoldingProxy.h */; }; 641EE6DB2240C5CA00173FCB /* FBPasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 71930C4020662E1F00D3AFEC /* FBPasteboard.h */; }; 641EE6DC2240C5CA00173FCB /* FBAppiumActionsSynthesizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 714097451FAE1B32008FB2C5 /* FBAppiumActionsSynthesizer.h */; }; 641EE6DD2240C5CA00173FCB /* FBDebugLogDelegateDecorator.h in Headers */ = {isa = PBXBuildFile; fileRef = EE7E27181D06C69F001BEC7B /* FBDebugLogDelegateDecorator.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -449,6 +447,10 @@ 71A224E51DE2F56600844D55 /* NSPredicate+FBFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 71A224E31DE2F56600844D55 /* NSPredicate+FBFormat.h */; }; 71A224E61DE2F56600844D55 /* NSPredicate+FBFormat.m in Sources */ = {isa = PBXBuildFile; fileRef = 71A224E41DE2F56600844D55 /* NSPredicate+FBFormat.m */; }; 71A224E81DE326C500844D55 /* NSPredicateFBFormatTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 71A224E71DE326C500844D55 /* NSPredicateFBFormatTests.m */; }; + 71A5C67329A4F39600421C37 /* XCTIssue+FBPatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 71A5C67129A4F39600421C37 /* XCTIssue+FBPatcher.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 71A5C67429A4F39600421C37 /* XCTIssue+FBPatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 71A5C67129A4F39600421C37 /* XCTIssue+FBPatcher.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 71A5C67529A4F39600421C37 /* XCTIssue+FBPatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 71A5C67229A4F39600421C37 /* XCTIssue+FBPatcher.m */; }; + 71A5C67629A4F39600421C37 /* XCTIssue+FBPatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 71A5C67229A4F39600421C37 /* XCTIssue+FBPatcher.m */; }; 71A7EAF51E20516B001DA4F2 /* XCUIElement+FBClassChain.h in Headers */ = {isa = PBXBuildFile; fileRef = 71A7EAF31E20516B001DA4F2 /* XCUIElement+FBClassChain.h */; }; 71A7EAF61E20516B001DA4F2 /* XCUIElement+FBClassChain.m in Sources */ = {isa = PBXBuildFile; fileRef = 71A7EAF41E20516B001DA4F2 /* XCUIElement+FBClassChain.m */; }; 71A7EAF91E224648001DA4F2 /* FBClassChainQueryParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 71A7EAF71E224648001DA4F2 /* FBClassChainQueryParser.h */; }; @@ -765,8 +767,6 @@ EE6B64FE1D0F86EF00E85F5D /* XCTestPrivateSymbols.m in Sources */ = {isa = PBXBuildFile; fileRef = EE6B64FC1D0F86EF00E85F5D /* XCTestPrivateSymbols.m */; }; EE7E271C1D06C69F001BEC7B /* FBDebugLogDelegateDecorator.h in Headers */ = {isa = PBXBuildFile; fileRef = EE7E27181D06C69F001BEC7B /* FBDebugLogDelegateDecorator.h */; settings = {ATTRIBUTES = (Public, ); }; }; EE7E271D1D06C69F001BEC7B /* FBDebugLogDelegateDecorator.m in Sources */ = {isa = PBXBuildFile; fileRef = EE7E27191D06C69F001BEC7B /* FBDebugLogDelegateDecorator.m */; }; - EE7E271E1D06C69F001BEC7B /* FBXCTestCaseImplementationFailureHoldingProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = EE7E271A1D06C69F001BEC7B /* FBXCTestCaseImplementationFailureHoldingProxy.h */; }; - EE7E271F1D06C69F001BEC7B /* FBXCTestCaseImplementationFailureHoldingProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = EE7E271B1D06C69F001BEC7B /* FBXCTestCaseImplementationFailureHoldingProxy.m */; }; EE8BA97A1DCCED9A00A9DEF8 /* FBNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = EE8BA9791DCCED9A00A9DEF8 /* FBNavigationController.m */; }; EE8DDD7E20C5733C004D4925 /* XCUIElement+FBForceTouch.m in Sources */ = {isa = PBXBuildFile; fileRef = EE8DDD7C20C5733B004D4925 /* XCUIElement+FBForceTouch.m */; }; EE8DDD7F20C5733C004D4925 /* XCUIElement+FBForceTouch.h in Headers */ = {isa = PBXBuildFile; fileRef = EE8DDD7D20C5733C004D4925 /* XCUIElement+FBForceTouch.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1036,6 +1036,8 @@ 71A224E31DE2F56600844D55 /* NSPredicate+FBFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSPredicate+FBFormat.h"; path = "../Utilities/NSPredicate+FBFormat.h"; sourceTree = ""; }; 71A224E41DE2F56600844D55 /* NSPredicate+FBFormat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSPredicate+FBFormat.m"; path = "../Utilities/NSPredicate+FBFormat.m"; sourceTree = ""; }; 71A224E71DE326C500844D55 /* NSPredicateFBFormatTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSPredicateFBFormatTests.m; sourceTree = ""; }; + 71A5C67129A4F39600421C37 /* XCTIssue+FBPatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "XCTIssue+FBPatcher.h"; sourceTree = ""; }; + 71A5C67229A4F39600421C37 /* XCTIssue+FBPatcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "XCTIssue+FBPatcher.m"; sourceTree = ""; }; 71A7EAF31E20516B001DA4F2 /* XCUIElement+FBClassChain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "XCUIElement+FBClassChain.h"; sourceTree = ""; }; 71A7EAF41E20516B001DA4F2 /* XCUIElement+FBClassChain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "XCUIElement+FBClassChain.m"; sourceTree = ""; }; 71A7EAF71E224648001DA4F2 /* FBClassChainQueryParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBClassChainQueryParser.h; sourceTree = ""; }; @@ -1265,8 +1267,6 @@ EE6B64FC1D0F86EF00E85F5D /* XCTestPrivateSymbols.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XCTestPrivateSymbols.m; sourceTree = ""; }; EE7E27181D06C69F001BEC7B /* FBDebugLogDelegateDecorator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBDebugLogDelegateDecorator.h; sourceTree = ""; }; EE7E27191D06C69F001BEC7B /* FBDebugLogDelegateDecorator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBDebugLogDelegateDecorator.m; sourceTree = ""; }; - EE7E271A1D06C69F001BEC7B /* FBXCTestCaseImplementationFailureHoldingProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBXCTestCaseImplementationFailureHoldingProxy.h; sourceTree = ""; }; - EE7E271B1D06C69F001BEC7B /* FBXCTestCaseImplementationFailureHoldingProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBXCTestCaseImplementationFailureHoldingProxy.m; sourceTree = ""; }; EE836C021C0F118600D87246 /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; EE8BA9781DCCED9A00A9DEF8 /* FBNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBNavigationController.h; sourceTree = ""; }; EE8BA9791DCCED9A00A9DEF8 /* FBNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBNavigationController.m; sourceTree = ""; }; @@ -1727,6 +1727,8 @@ 716E0BCD1E917E810087A825 /* NSString+FBXMLSafeString.m */, 714E14B629805CAE00375DD7 /* XCAXClient_iOS+FBSnapshotReqParams.h */, 714E14B729805CAE00375DD7 /* XCAXClient_iOS+FBSnapshotReqParams.m */, + 71A5C67129A4F39600421C37 /* XCTIssue+FBPatcher.h */, + 71A5C67229A4F39600421C37 /* XCTIssue+FBPatcher.m */, AD6C269A1CF2494200F8B5FF /* XCUIApplication+FBHelpers.h */, AD6C269B1CF2494200F8B5FF /* XCUIApplication+FBHelpers.m */, 71C8E54F25399A6B008572C1 /* XCUIApplication+FBQuiescence.h */, @@ -1940,8 +1942,6 @@ 7157B290221DADD2001C348C /* FBXCAXClientProxy.m */, EE5A24401F136C8D0078B1D9 /* FBXCodeCompatibility.h */, EE5A24411F136C8D0078B1D9 /* FBXCodeCompatibility.m */, - EE7E271A1D06C69F001BEC7B /* FBXCTestCaseImplementationFailureHoldingProxy.h */, - EE7E271B1D06C69F001BEC7B /* FBXCTestCaseImplementationFailureHoldingProxy.m */, EE35AD791E3B80C000A02D78 /* FBXCTestDaemonsProxy.h */, EE35AD7A1E3B80C000A02D78 /* FBXCTestDaemonsProxy.m */, 714D88CA2733FB970074A925 /* FBXMLGenerationOptions.h */, @@ -2349,6 +2349,7 @@ 641EE67B2240C5CA00173FCB /* XCUIRecorderUtilities.h in Headers */, 6496A5DA230D6EB30087F8CB /* AXSettings.h in Headers */, 641EE67C2240C5CA00173FCB /* XCTestCaseRun.h in Headers */, + 71A5C67429A4F39600421C37 /* XCTIssue+FBPatcher.h in Headers */, 641EE67D2240C5CA00173FCB /* XCTestConfiguration.h in Headers */, 641EE67E2240C5CA00173FCB /* _XCTDarwinNotificationExpectationImplementation.h in Headers */, 641EE67F2240C5CA00173FCB /* XCTestExpectation.h in Headers */, @@ -2456,7 +2457,6 @@ 641EE6D72240C5CA00173FCB /* XCTestObserver.h in Headers */, 641EE6D82240C5CA00173FCB /* XCUIElement.h in Headers */, 641EE6D92240C5CA00173FCB /* XCKeyboardInputSolver.h in Headers */, - 641EE6DA2240C5CA00173FCB /* FBXCTestCaseImplementationFailureHoldingProxy.h in Headers */, 718226CB2587443700661B83 /* GCDAsyncUdpSocket.h in Headers */, 641EE6DB2240C5CA00173FCB /* FBPasteboard.h in Headers */, 711CD03525ED1106001C01D2 /* XCUIScreenDataSource-Protocol.h in Headers */, @@ -2619,6 +2619,7 @@ E444DC83249131B10060D7EB /* DDNumber.h in Headers */, EE35AD271E3B77D600A02D78 /* XCApplicationMonitor.h in Headers */, EE8DDD7F20C5733C004D4925 /* XCUIElement+FBForceTouch.h in Headers */, + 71A5C67329A4F39600421C37 /* XCTIssue+FBPatcher.h in Headers */, EE158AEA1CBD456F00A3E3F0 /* FBRuntimeUtils.h in Headers */, 7136A4791E8918E60024FC3D /* XCUIElement+FBPickerWheel.h in Headers */, E444DCB324913C220060D7EB /* RoutingHTTPServer.h in Headers */, @@ -2696,7 +2697,6 @@ EE35AD531E3B77D600A02D78 /* XCTestObserver.h in Headers */, EE35AD6F1E3B77D600A02D78 /* XCUIElement.h in Headers */, EE35AD2F1E3B77D600A02D78 /* XCKeyboardInputSolver.h in Headers */, - EE7E271E1D06C69F001BEC7B /* FBXCTestCaseImplementationFailureHoldingProxy.h in Headers */, 71930C4220662E1F00D3AFEC /* FBPasteboard.h in Headers */, 714097471FAE1B32008FB2C5 /* FBAppiumActionsSynthesizer.h in Headers */, EE7E271C1D06C69F001BEC7B /* FBDebugLogDelegateDecorator.h in Headers */, @@ -3124,7 +3124,6 @@ 641EE5F62240C5CA00173FCB /* FBRouteRequest.m in Sources */, 641EE5F72240C5CA00173FCB /* FBResponseJSONPayload.m in Sources */, 718226D12587443700661B83 /* GCDAsyncUdpSocket.m in Sources */, - 641EE5F82240C5CA00173FCB /* FBXCTestCaseImplementationFailureHoldingProxy.m in Sources */, 641EE5F92240C5CA00173FCB /* FBMjpegServer.m in Sources */, 641EE5FA2240C5CA00173FCB /* XCUIDevice+FBHealthCheck.m in Sources */, 641EE5FD2240C5CA00173FCB /* FBBaseActionsSynthesizer.m in Sources */, @@ -3154,6 +3153,7 @@ 641EE6102240C5CA00173FCB /* FBImageUtils.m in Sources */, 641EE6112240C5CA00173FCB /* FBSession.m in Sources */, 641EE6122240C5CA00173FCB /* FBFindElementCommands.m in Sources */, + 71A5C67629A4F39600421C37 /* XCTIssue+FBPatcher.m in Sources */, 641EE6132240C5CA00173FCB /* FBDebugLogDelegateDecorator.m in Sources */, 641EE6142240C5CA00173FCB /* FBAlertViewCommands.m in Sources */, 71414EDB2670A1EE003A8C5D /* LRUCacheNode.m in Sources */, @@ -3201,6 +3201,7 @@ 7136A47A1E8918E60024FC3D /* XCUIElement+FBPickerWheel.m in Sources */, E444DC84249131B10060D7EB /* DDRange.m in Sources */, 6385F4A7220A40760095BBDB /* XCUIApplicationProcessDelay.m in Sources */, + 71A5C67529A4F39600421C37 /* XCTIssue+FBPatcher.m in Sources */, 711084451DA3AA7500F913D6 /* FBXPath.m in Sources */, 719CD8FD2126C88B00C7D0C2 /* XCUIApplication+FBAlert.m in Sources */, 13DE7A45287C2A8D003243C6 /* FBXCAccessibilityElement.m in Sources */, @@ -3241,7 +3242,6 @@ EE158AE21CBD456F00A3E3F0 /* FBRouteRequest.m in Sources */, EE158ADB1CBD456F00A3E3F0 /* FBResponseJSONPayload.m in Sources */, 714EAA0F2673FDFE005C5B47 /* FBCapabilities.m in Sources */, - EE7E271F1D06C69F001BEC7B /* FBXCTestCaseImplementationFailureHoldingProxy.m in Sources */, 7155D704211DCEF400166C20 /* FBMjpegServer.m in Sources */, EEDFE1221D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.m in Sources */, 714D88CE2733FB970074A925 /* FBXMLGenerationOptions.m in Sources */, diff --git a/WebDriverAgentLib/Categories/XCTIssue+FBPatcher.h b/WebDriverAgentLib/Categories/XCTIssue+FBPatcher.h new file mode 100644 index 000000000..b4cdf1d44 --- /dev/null +++ b/WebDriverAgentLib/Categories/XCTIssue+FBPatcher.h @@ -0,0 +1,18 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface XCTIssue (AMPatcher) + +@end + +NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Categories/XCTIssue+FBPatcher.m b/WebDriverAgentLib/Categories/XCTIssue+FBPatcher.m new file mode 100644 index 000000000..dc27e86a6 --- /dev/null +++ b/WebDriverAgentLib/Categories/XCTIssue+FBPatcher.m @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "XCTIssue+FBPatcher.h" + +#import + +static _Bool swizzledShouldInterruptTest(id self, SEL _cmd) +{ + return NO; +} + +@implementation XCTIssue (AMPatcher) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-load-method" ++ (void)load +{ + SEL originalShouldInterruptTest = NSSelectorFromString(@"shouldInterruptTest"); + if (nil == originalShouldInterruptTest) return; + Method originalShouldInterruptTestMethod = class_getInstanceMethod(self.class, originalShouldInterruptTest); + if (nil == originalShouldInterruptTestMethod) return; + method_setImplementation(originalShouldInterruptTestMethod, (IMP)swizzledShouldInterruptTest); +} +#pragma clang diagnostic pop + +@end diff --git a/WebDriverAgentLib/Utilities/FBFailureProofTestCase.m b/WebDriverAgentLib/Utilities/FBFailureProofTestCase.m index 3a3987e87..72d79ee1c 100644 --- a/WebDriverAgentLib/Utilities/FBFailureProofTestCase.m +++ b/WebDriverAgentLib/Utilities/FBFailureProofTestCase.m @@ -9,13 +9,7 @@ #import "FBFailureProofTestCase.h" -#import "FBExceptions.h" #import "FBLogger.h" -#import "FBXCTestCaseImplementationFailureHoldingProxy.h" - -@interface FBFailureProofTestCase () -@property (nonatomic, assign) BOOL didRegisterAXTestFailure; -@end @implementation FBFailureProofTestCase @@ -28,6 +22,26 @@ - (void)setUp self.shouldHaltWhenReceivesControl = NO; } +- (void)_recordIssue:(XCTIssue *)issue +{ + NSString *description = [NSString stringWithFormat:@"%@ (%@)", issue.compactDescription, issue.associatedError.description]; + [FBLogger logFmt:@"Issue type: %ld", issue.type]; + [self _enqueueFailureWithDescription:description + inFile:issue.sourceCodeContext.location.fileURL.path + atLine:issue.sourceCodeContext.location.lineNumber + // 5 == XCTIssueTypeUnmatchedExpectedFailure + expected:issue.type == 5]; +} + +- (void)_recordIssue:(XCTIssue *)issue forCaughtError:(id)error +{ + [self _recordIssue:issue]; +} + +- (void)recordIssue:(XCTIssue *)issue +{ + [self _recordIssue:issue]; +} /** Override 'recordFailureWithDescription' to not stop by failures. @@ -49,17 +63,7 @@ - (void)_enqueueFailureWithDescription:(NSString *)description expected:(BOOL)expected { [FBLogger logFmt:@"Enqueue Failure: %@ %@ %lu %d", description, filePath, (unsigned long)lineNumber, expected]; - const BOOL isPossibleDeadlock = ([description rangeOfString:@"Failed to get refreshed snapshot"].location != NSNotFound); - if (!isPossibleDeadlock) { - self.didRegisterAXTestFailure = YES; - } - else if (self.didRegisterAXTestFailure) { - self.didRegisterAXTestFailure = NO; // Reseting to NO to enable future deadlock detection - [[NSException exceptionWithName:FBApplicationDeadlockDetectedException - reason:@"Can't communicate with deadlocked application" - userInfo:nil] - raise]; - } + // TODO: Figure out which error types we want to escalate } @end diff --git a/WebDriverAgentLib/Utilities/FBXCTestCaseImplementationFailureHoldingProxy.h b/WebDriverAgentLib/Utilities/FBXCTestCaseImplementationFailureHoldingProxy.h deleted file mode 100644 index 8bf06b2a2..000000000 --- a/WebDriverAgentLib/Utilities/FBXCTestCaseImplementationFailureHoldingProxy.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import - -@class _XCTestCaseImplementation; - -NS_ASSUME_NONNULL_BEGIN - -/** - Class that can be used to proxy existing _XCTestCaseImplementation and - prevent currently running test from being terminated on any XCTest failure - */ -@interface FBXCTestCaseImplementationFailureHoldingProxy : NSProxy - -/** - Constructor for given existing _XCTestCaseImplementation instance - */ -+ (instancetype)proxyWithXCTestCaseImplementation:(_XCTestCaseImplementation *)internalImplementation; - -@end - -NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Utilities/FBXCTestCaseImplementationFailureHoldingProxy.m b/WebDriverAgentLib/Utilities/FBXCTestCaseImplementationFailureHoldingProxy.m deleted file mode 100644 index 23f257416..000000000 --- a/WebDriverAgentLib/Utilities/FBXCTestCaseImplementationFailureHoldingProxy.m +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import "FBXCTestCaseImplementationFailureHoldingProxy.h" - -#import - -@interface FBXCTestCaseImplementationFailureHoldingProxy () -@property (nonatomic, strong) _XCTestCaseImplementation *internalImplementation; -@end - -@implementation FBXCTestCaseImplementationFailureHoldingProxy - -+ (instancetype)proxyWithXCTestCaseImplementation:(_XCTestCaseImplementation *)internalImplementation -{ - FBXCTestCaseImplementationFailureHoldingProxy *proxy = [super alloc]; - proxy.internalImplementation = internalImplementation; - return proxy; -} - -- (id)forwardingTargetForSelector:(SEL)aSelector -{ - return self.internalImplementation; -} - -// This will prevent test from quiting on app crash or any other test failure -- (BOOL)shouldHaltWhenReceivesControl -{ - return NO; -} - -@end diff --git a/WebDriverAgentLib/WebDriverAgentLib.h b/WebDriverAgentLib/WebDriverAgentLib.h index df9b139ed..b8f85e98f 100644 --- a/WebDriverAgentLib/WebDriverAgentLib.h +++ b/WebDriverAgentLib/WebDriverAgentLib.h @@ -50,3 +50,4 @@ FOUNDATION_EXPORT const unsigned char WebDriverAgentLib_VersionString[]; #import #import #import +#import From 2b6d6dda0be0fcce82d948ce3e54379998bd4cd9 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 22 Feb 2023 09:18:07 +0000 Subject: [PATCH 096/240] chore(release): 4.12.2 [skip ci] ## [4.12.2](https://github.com/appium/WebDriverAgent/compare/v4.12.1...v4.12.2) (2023-02-22) ### Miscellaneous Chores * Make sure the test is never going to be unexpectedly interrupted ([#664](https://github.com/appium/WebDriverAgent/issues/664)) ([cafe47e](https://github.com/appium/WebDriverAgent/commit/cafe47e9bea9649a0e9b4a2b96ca44434bbac411)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a4876f6d..9edff0371 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.12.2](https://github.com/appium/WebDriverAgent/compare/v4.12.1...v4.12.2) (2023-02-22) + + +### Miscellaneous Chores + +* Make sure the test is never going to be unexpectedly interrupted ([#664](https://github.com/appium/WebDriverAgent/issues/664)) ([cafe47e](https://github.com/appium/WebDriverAgent/commit/cafe47e9bea9649a0e9b4a2b96ca44434bbac411)) + ## [4.12.1](https://github.com/appium/WebDriverAgent/compare/v4.12.0...v4.12.1) (2023-02-20) diff --git a/package.json b/package.json index e253a8f0e..3f7156ddc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.12.1", + "version": "4.12.2", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 1696f4bb879152ef04408940849708654072c797 Mon Sep 17 00:00:00 2001 From: Dan Maor Date: Thu, 23 Feb 2023 10:39:10 +0200 Subject: [PATCH 097/240] feat: Increase Xpath Lookup Performance (#666) * Increase Xpath lookup performance * moved import * addressing review comments --- .../Categories/XCUIElement+FBResolve.m | 4 +--- .../Categories/XCUIElement+FBUID.m | 18 +++++++++++++++++- .../Categories/XCUIElement+FBUtilities.m | 6 +++--- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m b/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m index 16b5eb190..f52c72bf6 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m @@ -47,9 +47,7 @@ - (XCUIElement *)fb_stableInstance if (nil == uid) { return self; } - NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id snapshot, NSDictionary *bindings) { - return [[FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot] isEqualToString:uid]; - }]; + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K = %@",FBStringify(FBXCElementSnapshotWrapper, fb_uid), uid]; return [query matchingPredicate:predicate].allElementsBoundByIndex.firstObject ?: self; } diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBUID.m b/WebDriverAgentLib/Categories/XCUIElement+FBUID.m index 1af09a4ec..06979a4cf 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBUID.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBUID.m @@ -7,6 +7,8 @@ * of patent rights can be found in the PATENTS file in the same directory. */ +#import + #import "XCUIElement+FBUID.h" #import "FBElementUtils.h" @@ -33,6 +35,17 @@ - (NSString *)fb_uid @implementation FBXCElementSnapshotWrapper (FBUID) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-load-method" ++ (void)load +{ + Class XCElementSnapshotCls = objc_lookUpClass("XCElementSnapshot"); + NSAssert(XCElementSnapshotCls != nil, @"Could not locate XCElementSnapshot class"); + Method uidMethod = class_getInstanceMethod(self.class, @selector(fb_uid)); + class_addMethod(XCElementSnapshotCls, @selector(fb_uid), method_getImplementation(uidMethod), method_getTypeEncoding(uidMethod)); +} +#pragma diagnostic pop + - (unsigned long long)fb_accessibiltyId { return [FBElementUtils idWithAccessibilityElement:self.accessibilityElement]; @@ -45,7 +58,10 @@ + (nullable NSString *)wdUIDWithSnapshot:(id)snapshot - (NSString *)fb_uid { - return [self.class wdUIDWithSnapshot:self.snapshot]; + if ([self isKindOfClass:FBXCElementSnapshotWrapper.class]) { + return [self.class wdUIDWithSnapshot:self.snapshot]; + } + return [FBElementUtils uidWithAccessibilityElement:[self accessibilityElement]]; } @end diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m b/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m index bd8c8135c..d78cfd99e 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m @@ -162,10 +162,10 @@ @implementation XCUIElement (FBUtilities) XCUIElementQuery *query = onlyChildren ? [self.fb_query childrenMatchingType:type] : [self.fb_query descendantsMatchingType:type]; - NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id snapshot, NSDictionary *bindings) { - return [matchedIds containsObject:[FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot] ?: @""]; - }]; + + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K IN %@",FBStringify(FBXCElementSnapshotWrapper, fb_uid), matchedIds]; [matchedElements addObjectsFromArray:[query matchingPredicate:predicate].allElementsBoundByIndex]; + for (XCUIElement *el in matchedElements) { el.fb_isResolvedNatively = @NO; } From 209d01a680003fd4864061487b1c3a4e0b76b2db Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 23 Feb 2023 08:48:54 +0000 Subject: [PATCH 098/240] chore(release): 4.13.0 [skip ci] ## [4.13.0](https://github.com/appium/WebDriverAgent/compare/v4.12.2...v4.13.0) (2023-02-23) ### Features * Increase Xpath Lookup Performance ([#666](https://github.com/appium/WebDriverAgent/issues/666)) ([1696f4b](https://github.com/appium/WebDriverAgent/commit/1696f4bb879152ef04408940849708654072c797)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9edff0371..a46339c1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.13.0](https://github.com/appium/WebDriverAgent/compare/v4.12.2...v4.13.0) (2023-02-23) + + +### Features + +* Increase Xpath Lookup Performance ([#666](https://github.com/appium/WebDriverAgent/issues/666)) ([1696f4b](https://github.com/appium/WebDriverAgent/commit/1696f4bb879152ef04408940849708654072c797)) + ## [4.12.2](https://github.com/appium/WebDriverAgent/compare/v4.12.1...v4.12.2) (2023-02-22) diff --git a/package.json b/package.json index 3f7156ddc..e97383446 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.12.2", + "version": "4.13.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 3e0b1914f87585ed69ba20d960502eabb058941c Mon Sep 17 00:00:00 2001 From: Dan Maor Date: Tue, 4 Apr 2023 22:57:17 +0300 Subject: [PATCH 099/240] fix: Fixed Xpath lookup for Xcode 14.3 (#681) --- .../Categories/XCUIElement+FBUID.m | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBUID.m b/WebDriverAgentLib/Categories/XCUIElement+FBUID.m index 06979a4cf..765b410c1 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBUID.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBUID.m @@ -12,6 +12,7 @@ #import "XCUIElement+FBUID.h" #import "FBElementUtils.h" +#import "FBLogger.h" #import "XCUIApplication.h" #import "XCUIElement+FBUtilities.h" @@ -35,6 +36,10 @@ - (NSString *)fb_uid @implementation FBXCElementSnapshotWrapper (FBUID) +static void swizzled_validatePredicateWithExpressionsAllowed(id self, SEL _cmd, id predicate, BOOL withExpressionsAllowed) +{ +} + #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-load-method" + (void)load @@ -43,6 +48,19 @@ + (void)load NSAssert(XCElementSnapshotCls != nil, @"Could not locate XCElementSnapshot class"); Method uidMethod = class_getInstanceMethod(self.class, @selector(fb_uid)); class_addMethod(XCElementSnapshotCls, @selector(fb_uid), method_getImplementation(uidMethod), method_getTypeEncoding(uidMethod)); + + // Support for Xcode 14.3 requires disabling the new predicate validator, see https://github.com/appium/appium/issues/18444 + Class XCTElementQueryTransformerPredicateValidatorCls = objc_lookUpClass("XCTElementQueryTransformerPredicateValidator"); + if (XCTElementQueryTransformerPredicateValidatorCls == nil) { + return; + } + Method validatePredicateMethod = class_getClassMethod(XCTElementQueryTransformerPredicateValidatorCls, NSSelectorFromString(@"validatePredicate:withExpressionsAllowed:")); + if (validatePredicateMethod == nil) { + [FBLogger log:@"Could not find method +[XCTElementQueryTransformerPredicateValidator validatePredicate:withExpressionsAllowed:]"]; + return; + } + IMP swizzledImp = (IMP)swizzled_validatePredicateWithExpressionsAllowed; + method_setImplementation(validatePredicateMethod, swizzledImp); } #pragma diagnostic pop From eb8c5e4f45092548781c6917c70b46856301d1b4 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 4 Apr 2023 20:11:24 +0000 Subject: [PATCH 100/240] chore(release): 4.13.1 [skip ci] ## [4.13.1](https://github.com/appium/WebDriverAgent/compare/v4.13.0...v4.13.1) (2023-04-04) ### Bug Fixes * Fixed Xpath lookup for Xcode 14.3 ([#681](https://github.com/appium/WebDriverAgent/issues/681)) ([3e0b191](https://github.com/appium/WebDriverAgent/commit/3e0b1914f87585ed69ba20d960502eabb058941c)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a46339c1e..42680f5c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.13.1](https://github.com/appium/WebDriverAgent/compare/v4.13.0...v4.13.1) (2023-04-04) + + +### Bug Fixes + +* Fixed Xpath lookup for Xcode 14.3 ([#681](https://github.com/appium/WebDriverAgent/issues/681)) ([3e0b191](https://github.com/appium/WebDriverAgent/commit/3e0b1914f87585ed69ba20d960502eabb058941c)) + ## [4.13.0](https://github.com/appium/WebDriverAgent/compare/v4.12.2...v4.13.0) (2023-02-23) diff --git a/package.json b/package.json index e97383446..7d2ec051c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.13.0", + "version": "4.13.1", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From edcbf9e6af903c6f490ca90ff915497ad53bb8b5 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Fri, 28 Apr 2023 16:21:40 -0700 Subject: [PATCH 101/240] chore: add withoutSession for pasteboard for debug (#688) --- WebDriverAgentLib/Commands/FBCustomCommands.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WebDriverAgentLib/Commands/FBCustomCommands.m b/WebDriverAgentLib/Commands/FBCustomCommands.m index 6fd41d6a4..1ad36c57d 100644 --- a/WebDriverAgentLib/Commands/FBCustomCommands.m +++ b/WebDriverAgentLib/Commands/FBCustomCommands.m @@ -52,7 +52,9 @@ + (NSArray *)routes [[FBRoute GET:@"/wda/activeAppInfo"].withoutSession respondWithTarget:self action:@selector(handleActiveAppInfo:)], #if !TARGET_OS_TV // tvOS does not provide relevant APIs [[FBRoute POST:@"/wda/setPasteboard"] respondWithTarget:self action:@selector(handleSetPasteboard:)], + [[FBRoute POST:@"/wda/setPasteboard"].withoutSession respondWithTarget:self action:@selector(handleSetPasteboard:)], [[FBRoute POST:@"/wda/getPasteboard"] respondWithTarget:self action:@selector(handleGetPasteboard:)], + [[FBRoute POST:@"/wda/getPasteboard"].withoutSession respondWithTarget:self action:@selector(handleGetPasteboard:)], [[FBRoute GET:@"/wda/batteryInfo"] respondWithTarget:self action:@selector(handleGetBatteryInfo:)], #endif [[FBRoute POST:@"/wda/pressButton"] respondWithTarget:self action:@selector(handlePressButtonCommand:)], From 215a7c97fff7ada1f3ef4ba0b69c13c63ec46a77 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 28 Apr 2023 23:30:45 +0000 Subject: [PATCH 102/240] chore(release): 4.13.2 [skip ci] ## [4.13.2](https://github.com/appium/WebDriverAgent/compare/v4.13.1...v4.13.2) (2023-04-28) ### Miscellaneous Chores * add withoutSession for pasteboard for debug ([#688](https://github.com/appium/WebDriverAgent/issues/688)) ([edcbf9e](https://github.com/appium/WebDriverAgent/commit/edcbf9e6af903c6f490ca90ff915497ad53bb8b5)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42680f5c6..5027151d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.13.2](https://github.com/appium/WebDriverAgent/compare/v4.13.1...v4.13.2) (2023-04-28) + + +### Miscellaneous Chores + +* add withoutSession for pasteboard for debug ([#688](https://github.com/appium/WebDriverAgent/issues/688)) ([edcbf9e](https://github.com/appium/WebDriverAgent/commit/edcbf9e6af903c6f490ca90ff915497ad53bb8b5)) + ## [4.13.1](https://github.com/appium/WebDriverAgent/compare/v4.13.0...v4.13.1) (2023-04-04) diff --git a/package.json b/package.json index 7d2ec051c..a5b994186 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.13.1", + "version": "4.13.2", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From e1c0f836a68ad2efbedfc77343794d0d97ef6090 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Mon, 1 May 2023 23:48:16 -0700 Subject: [PATCH 103/240] feat: start wda process via Xctest in a real device (#687) * move some implementation to wda * tune * Update webdriveragent.js * update review * refactor: set started=true after getStatus * chore: use WDA_RUNNER_BUNDLE_ID * refactor: rename * chore: refer to updatedWDABundleId to build xctrunner * add fixme to not create xcodebuild instance for webDriverAgentUrl * return a bit early * refactor: fix review * refactor: fix review --- lib/constants.js | 4 +- lib/webdriveragent.js | 122 +++++++++++++++++++++++++++++++----------- package.json | 1 + 3 files changed, 96 insertions(+), 31 deletions(-) diff --git a/lib/constants.js b/lib/constants.js index caea65cec..82f005d1c 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -1,6 +1,7 @@ import path from 'path'; const WDA_RUNNER_BUNDLE_ID = 'com.facebook.WebDriverAgentRunner'; +const WDA_RUNNER_BUNDLE_ID_FOR_XCTEST = `${WDA_RUNNER_BUNDLE_ID}.xctrunner`; const WDA_RUNNER_APP = 'WebDriverAgentRunner-Runner.app'; const WDA_SCHEME = 'WebDriverAgentRunner'; const PROJECT_FILE = 'project.pbxproj'; @@ -17,5 +18,6 @@ const WDA_UPGRADE_TIMESTAMP_PATH = path.join('.appium', 'webdriveragent', 'upgra export { WDA_RUNNER_BUNDLE_ID, WDA_RUNNER_APP, PROJECT_FILE, WDA_SCHEME, PLATFORM_NAME_TVOS, PLATFORM_NAME_IOS, - SDK_SIMULATOR, SDK_DEVICE, WDA_BASE_URL, WDA_UPGRADE_TIMESTAMP_PATH + SDK_SIMULATOR, SDK_DEVICE, WDA_BASE_URL, WDA_UPGRADE_TIMESTAMP_PATH, + WDA_RUNNER_BUNDLE_ID_FOR_XCTEST }; diff --git a/lib/webdriveragent.js b/lib/webdriveragent.js index 93898047b..2424a95aa 100644 --- a/lib/webdriveragent.js +++ b/lib/webdriveragent.js @@ -14,8 +14,10 @@ import AsyncLock from 'async-lock'; import { exec } from 'teen_process'; import { bundleWDASim } from './check-dependencies'; import { - WDA_RUNNER_BUNDLE_ID, WDA_RUNNER_APP, WDA_BASE_URL, WDA_UPGRADE_TIMESTAMP_PATH, + WDA_RUNNER_BUNDLE_ID, WDA_RUNNER_BUNDLE_ID_FOR_XCTEST, WDA_RUNNER_APP, + WDA_BASE_URL, WDA_UPGRADE_TIMESTAMP_PATH, } from './constants'; +import {Xctest} from 'appium-ios-device'; const WDA_LAUNCH_TIMEOUT = 60 * 1000; const WDA_AGENT_PORT = 8100; @@ -59,31 +61,47 @@ class WebDriverAgent { this.updatedWDABundleId = args.updatedWDABundleId; - this.xcodebuild = new XcodeBuild(this.xcodeVersion, this.device, { - platformVersion: this.platformVersion, - platformName: this.platformName, - iosSdkVersion: this.iosSdkVersion, - agentPath: this.agentPath, - bootstrapPath: this.bootstrapPath, - realDevice: this.isRealDevice, - showXcodeLog: args.showXcodeLog, - xcodeConfigFile: args.xcodeConfigFile, - xcodeOrgId: args.xcodeOrgId, - xcodeSigningId: args.xcodeSigningId, - keychainPath: args.keychainPath, - keychainPassword: args.keychainPassword, - useSimpleBuildTest: args.useSimpleBuildTest, - usePrebuiltWDA: args.usePrebuiltWDA, - updatedWDABundleId: this.updatedWDABundleId, - launchTimeout: args.wdaLaunchTimeout || WDA_LAUNCH_TIMEOUT, - wdaRemotePort: this.wdaRemotePort, - useXctestrunFile: this.useXctestrunFile, - derivedDataPath: args.derivedDataPath, - mjpegServerPort: this.mjpegServerPort, - allowProvisioningDeviceRegistration: args.allowProvisioningDeviceRegistration, - resultBundlePath: args.resultBundlePath, - resultBundleVersion: args.resultBundleVersion, - }, this.log); + this.usePreinstalledWDA = args.usePreinstalledWDA; + this.xctestApiClient = null; + + // FIXME: maybe 'this.webDriverAgentUrl' also can ignore + // the xcodebuild instance itself. + + this.xcodebuild = this.usePreinstalledWDA + ? null + : new XcodeBuild(this.xcodeVersion, this.device, { + platformVersion: this.platformVersion, + platformName: this.platformName, + iosSdkVersion: this.iosSdkVersion, + agentPath: this.agentPath, + bootstrapPath: this.bootstrapPath, + realDevice: this.isRealDevice, + showXcodeLog: args.showXcodeLog, + xcodeConfigFile: args.xcodeConfigFile, + xcodeOrgId: args.xcodeOrgId, + xcodeSigningId: args.xcodeSigningId, + keychainPath: args.keychainPath, + keychainPassword: args.keychainPassword, + useSimpleBuildTest: args.useSimpleBuildTest, + usePrebuiltWDA: args.usePrebuiltWDA, + updatedWDABundleId: this.updatedWDABundleId, + launchTimeout: args.wdaLaunchTimeout || WDA_LAUNCH_TIMEOUT, + wdaRemotePort: this.wdaRemotePort, + useXctestrunFile: this.useXctestrunFile, + derivedDataPath: args.derivedDataPath, + mjpegServerPort: this.mjpegServerPort, + allowProvisioningDeviceRegistration: args.allowProvisioningDeviceRegistration, + resultBundlePath: args.resultBundlePath, + resultBundleVersion: args.resultBundleVersion, + }, this.log); + } + + /** + * + * @returns {string} Bundle ID for Xctest. + */ + get bundleIdForXctest () { + return `${this.updatedWDABundleId}.xctrunner` || WDA_RUNNER_BUNDLE_ID_FOR_XCTEST; } setWDAPaths (bootstrapPath, agentPath) { @@ -248,6 +266,9 @@ class WebDriverAgent { return; } + if (this.usePreinstalledWDA) { + return; + } try { await this.xcodebuild.cleanProject(); } catch (e) { @@ -255,6 +276,30 @@ class WebDriverAgent { } } + /** + * Launch WDA with preinstalled package without xcodebuild. + * @param {string} sessionId Launch WDA and establish the session with this sessionId + * @return {?object} State Object + */ + async launchWithPreinstalledWDA(sessionId) { + const xctestEnv = { + USE_PORT: this.wdaLocalPort || WDA_AGENT_PORT, + WDA_PRODUCT_BUNDLE_IDENTIFIER: this.bundleIdForXctest + }; + if (this.mjpegServerPort) { + xctestEnv.MJPEG_SERVER_PORT = this.mjpegServerPort; + } + this.log.info('Launching WebDriverAgent on the device without xcodebuild'); + this.xctestApiClient = new Xctest(this.device.udid, this.bundleIdForXctest, null, {env: xctestEnv}); + + await this.xctestApiClient.start(); + + this.setupProxies(sessionId); + const status = await this.getStatus(); + this.started = true; + return status; + } + /** * Return current running WDA's status like below after launching WDA * { @@ -286,6 +331,13 @@ class WebDriverAgent { return await this.getStatus(); } + if (this.usePreinstalledWDA) { + if (this.isRealDevice) { + return await this.launchWithPreinstalledWDA(sessionId); + } + throw new Error('usePreinstalledWDA is available only for a real device.'); + } + this.log.info('Launching WebDriverAgent on the device'); this.setupProxies(sessionId); @@ -393,10 +445,17 @@ class WebDriverAgent { } async quit () { - this.log.info('Shutting down sub-processes'); - - await this.xcodebuild.quit(); - await this.xcodebuild.reset(); + if (this.usePreinstalledWDA) { + if (this.xctestApiClient) { + this.log.info('Stopping the XCTest session'); + this.xctestApiClient.stop(); + this.xctestApiClient = null; + } + } else { + this.log.info('Shutting down sub-processes'); + await this.xcodebuild.quit(); + await this.xcodebuild.reset(); + } if (this.jwproxy) { this.jwproxy.sessionId = null; @@ -437,6 +496,9 @@ class WebDriverAgent { } async retrieveDerivedDataPath () { + if (this.usePreinstalledWDA) { + return; + } return await this.xcodebuild.retrieveDerivedDataPath(); } diff --git a/package.json b/package.json index a5b994186..f8e7a711a 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,7 @@ "@appium/base-driver": "^9.0.0", "@appium/support": "^3.0.0", "@babel/runtime": "^7.0.0", + "appium-ios-device": "^2.5.0", "appium-ios-simulator": "^5.0.1", "async-lock": "^1.0.0", "asyncbox": "^2.5.3", From d280750a66d754032416eb865cb2fef8a75ce219 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 2 May 2023 06:57:24 +0000 Subject: [PATCH 104/240] chore(release): 4.14.0 [skip ci] ## [4.14.0](https://github.com/appium/WebDriverAgent/compare/v4.13.2...v4.14.0) (2023-05-02) ### Features * start wda process via Xctest in a real device ([#687](https://github.com/appium/WebDriverAgent/issues/687)) ([e1c0f83](https://github.com/appium/WebDriverAgent/commit/e1c0f836a68ad2efbedfc77343794d0d97ef6090)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5027151d0..d86cea08a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.14.0](https://github.com/appium/WebDriverAgent/compare/v4.13.2...v4.14.0) (2023-05-02) + + +### Features + +* start wda process via Xctest in a real device ([#687](https://github.com/appium/WebDriverAgent/issues/687)) ([e1c0f83](https://github.com/appium/WebDriverAgent/commit/e1c0f836a68ad2efbedfc77343794d0d97ef6090)) + ## [4.13.2](https://github.com/appium/WebDriverAgent/compare/v4.13.1...v4.13.2) (2023-04-28) diff --git a/package.json b/package.json index f8e7a711a..72215e98a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.13.2", + "version": "4.14.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 0ec74ce32c817a5884228ccb2ec31f0a5a4de9c3 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 4 May 2023 22:10:44 +0200 Subject: [PATCH 105/240] feat: Make isFocused attribute available for iOS elements (#692) * feat: Make isFocused attribute available for iOS elements * Extra line break --- WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m | 2 -- .../Categories/XCUIElement+FBWebDriverAttributes.m | 2 -- WebDriverAgentLib/Routing/FBElement.h | 2 -- 3 files changed, 6 deletions(-) diff --git a/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m b/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m index 022df5b9d..086643296 100644 --- a/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +++ b/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m @@ -126,9 +126,7 @@ + (NSDictionary *)dictionaryForElement:(id)snapshot recursi info[@"isEnabled"] = [@([wrappedSnapshot isWDEnabled]) stringValue]; info[@"isVisible"] = [@([wrappedSnapshot isWDVisible]) stringValue]; info[@"isAccessible"] = [@([wrappedSnapshot isWDAccessible]) stringValue]; -#if TARGET_OS_TV info[@"isFocused"] = [@([wrappedSnapshot isWDFocused]) stringValue]; -#endif if (!recursive) { return info.copy; diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m b/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m index cc2b46daf..2f2368180 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m @@ -154,12 +154,10 @@ - (BOOL)isWDVisible return self.fb_isVisible; } -#if TARGET_OS_TV - (BOOL)isWDFocused { return self.hasFocus; } -#endif - (BOOL)isWDAccessible { diff --git a/WebDriverAgentLib/Routing/FBElement.h b/WebDriverAgentLib/Routing/FBElement.h index 67e4593f9..277a4ccd2 100644 --- a/WebDriverAgentLib/Routing/FBElement.h +++ b/WebDriverAgentLib/Routing/FBElement.h @@ -53,10 +53,8 @@ NS_ASSUME_NONNULL_BEGIN /*! Whether element is an accessibility container (contains children of any depth that are accessible) */ @property (nonatomic, readonly, getter = isWDAccessibilityContainer) BOOL wdAccessibilityContainer; -#if TARGET_OS_TV /*! Whether element is focused */ @property (nonatomic, readonly, getter = isWDFocused) BOOL wdFocused; -#endif /*! Element's index relatively to its parent. Starts from zero */ @property (nonatomic, readonly) NSUInteger wdIndex; From 2ec5a4b8e2f1af70efd3e8fc572f7f503c0b7513 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 4 May 2023 20:18:10 +0000 Subject: [PATCH 106/240] chore(release): 4.15.0 [skip ci] ## [4.15.0](https://github.com/appium/WebDriverAgent/compare/v4.14.0...v4.15.0) (2023-05-04) ### Features * Make isFocused attribute available for iOS elements ([#692](https://github.com/appium/WebDriverAgent/issues/692)) ([0ec74ce](https://github.com/appium/WebDriverAgent/commit/0ec74ce32c817a5884228ccb2ec31f0a5a4de9c3)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d86cea08a..007d1a7aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.15.0](https://github.com/appium/WebDriverAgent/compare/v4.14.0...v4.15.0) (2023-05-04) + + +### Features + +* Make isFocused attribute available for iOS elements ([#692](https://github.com/appium/WebDriverAgent/issues/692)) ([0ec74ce](https://github.com/appium/WebDriverAgent/commit/0ec74ce32c817a5884228ccb2ec31f0a5a4de9c3)) + ## [4.14.0](https://github.com/appium/WebDriverAgent/compare/v4.13.2...v4.14.0) (2023-05-02) diff --git a/package.json b/package.json index 72215e98a..c23a5b31a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.14.0", + "version": "4.15.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 2f7f702805ad1e7f11e53e48dbde7783c732e7fb Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Fri, 5 May 2023 20:54:03 +0200 Subject: [PATCH 107/240] ci: Update node matrix generation --- .github/workflows/unit-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 6b44da0f0..665cf2e5d 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -13,7 +13,7 @@ jobs: id: generate-matrix run: | sudo apt-get install -y lynx - lynx -dump https://endoflife.date/nodejs | grep -E -o '[0-9]+ \(LTS\)' | grep -E -o '([0-9]+)' > eol.list + lynx -dump https://endoflife.date/nodejs | grep -E -o '[0-9]+[( a-zA-Z]+LTS\)' | grep -E -o '([0-9]+)' > eol.list cat eol.list lts1=$(cat eol.list | head -1) lts2=$(cat eol.list | head -2 | tail -1) From d8f1457b591b2dd00040f8336c1a7a728af871d2 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Fri, 5 May 2023 22:13:00 -0700 Subject: [PATCH 108/240] perf: tune webDriverAgentUrl case by skiping xcodebuild stuff (#691) * perf: tune webDriverAgentUrl case by skiping xcodebuild stuff * include a small fix * Update webdriveragent.js --- lib/webdriveragent.js | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/lib/webdriveragent.js b/lib/webdriveragent.js index 2424a95aa..ef6e8e766 100644 --- a/lib/webdriveragent.js +++ b/lib/webdriveragent.js @@ -48,6 +48,9 @@ class WebDriverAgent { this.prebuildWDA = args.prebuildWDA; + // this.args.webDriverAgentUrl guiarantees the capabilities acually + // gave 'appium:webDriverAgentUrl' but 'this.webDriverAgentUrl' + // could be used for caching WDA with xcodebuild. this.webDriverAgentUrl = args.webDriverAgentUrl; this.started = false; @@ -64,10 +67,7 @@ class WebDriverAgent { this.usePreinstalledWDA = args.usePreinstalledWDA; this.xctestApiClient = null; - // FIXME: maybe 'this.webDriverAgentUrl' also can ignore - // the xcodebuild instance itself. - - this.xcodebuild = this.usePreinstalledWDA + this.xcodebuild = this.canSkipXcodebuild ? null : new XcodeBuild(this.xcodeVersion, this.device, { platformVersion: this.platformVersion, @@ -96,12 +96,22 @@ class WebDriverAgent { }, this.log); } + /** + * Return true if the session does not need xcodebuild. + * @returns {boolean} Whether the session needs/has xcodebuild. + */ + get canSkipXcodebuild () { + // Use this.args.webDriverAgentUrl to guarantee + // the capabilities set gave the `appium:webDriverAgentUrl`. + return this.usePreinstalledWDA || this.args.webDriverAgentUrl; + } + /** * * @returns {string} Bundle ID for Xctest. */ get bundleIdForXctest () { - return `${this.updatedWDABundleId}.xctrunner` || WDA_RUNNER_BUNDLE_ID_FOR_XCTEST; + return this.updatedWDABundleId ? `${this.updatedWDABundleId}.xctrunner` : WDA_RUNNER_BUNDLE_ID_FOR_XCTEST; } setWDAPaths (bootstrapPath, agentPath) { @@ -266,7 +276,7 @@ class WebDriverAgent { return; } - if (this.usePreinstalledWDA) { + if (this.canSkipXcodebuild) { return; } try { @@ -451,10 +461,13 @@ class WebDriverAgent { this.xctestApiClient.stop(); this.xctestApiClient = null; } - } else { + } else if (!this.args.webDriverAgentUrl) { this.log.info('Shutting down sub-processes'); await this.xcodebuild.quit(); await this.xcodebuild.reset(); + } else { + this.log.debug('Do not stop xcodebuild nor XCTest session ' + + 'since the WDA session is managed by outside this driver.'); } if (this.jwproxy) { @@ -496,7 +509,7 @@ class WebDriverAgent { } async retrieveDerivedDataPath () { - if (this.usePreinstalledWDA) { + if (this.canSkipXcodebuild) { return; } return await this.xcodebuild.retrieveDerivedDataPath(); From 3b48b6cb0e47e8669892228053e318ba33698ce6 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sat, 6 May 2023 05:23:32 +0000 Subject: [PATCH 109/240] chore(release): 4.15.1 [skip ci] ## [4.15.1](https://github.com/appium/WebDriverAgent/compare/v4.15.0...v4.15.1) (2023-05-06) ### Performance Improvements * tune webDriverAgentUrl case by skiping xcodebuild stuff ([#691](https://github.com/appium/WebDriverAgent/issues/691)) ([d8f1457](https://github.com/appium/WebDriverAgent/commit/d8f1457b591b2dd00040f8336c1a7a728af871d2)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 007d1a7aa..0b57bd88c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.15.1](https://github.com/appium/WebDriverAgent/compare/v4.15.0...v4.15.1) (2023-05-06) + + +### Performance Improvements + +* tune webDriverAgentUrl case by skiping xcodebuild stuff ([#691](https://github.com/appium/WebDriverAgent/issues/691)) ([d8f1457](https://github.com/appium/WebDriverAgent/commit/d8f1457b591b2dd00040f8336c1a7a728af871d2)) + ## [4.15.0](https://github.com/appium/WebDriverAgent/compare/v4.14.0...v4.15.0) (2023-05-04) diff --git a/package.json b/package.json index c23a5b31a..4e54f3d4e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.15.0", + "version": "4.15.1", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 9860a72b902a1c8340f3b1b29f2509e59077e86d Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Fri, 12 May 2023 09:36:31 -0700 Subject: [PATCH 110/240] ci: use Xcode 14.2 for release (#697) --- .github/workflows/publish.js.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.js.yml b/.github/workflows/publish.js.yml index 05420d48b..6d1915ca7 100644 --- a/.github/workflows/publish.js.yml +++ b/.github/workflows/publish.js.yml @@ -13,7 +13,7 @@ jobs: runs-on: macos-12 env: - XCODE_VERSION: 14.1 + XCODE_VERSION: 14.2 ZIP_PKG_NAME_IOS: "WebDriverAgentRunner-Runner.zip" PKG_PATH_IOS: "appium_wda_ios" ZIP_PKG_NAME_TVOS: "WebDriverAgentRunner_tvOS-Runner.zip" From bb562b96db6aad476970ef7bd352cb8df4f1e6c2 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Sun, 14 May 2023 13:16:36 +0200 Subject: [PATCH 111/240] refactor!: Drop workarounds for legacy iOS versions (#696) BREAKING CHANGE: The minimum supported xCode/iOS version is now 13/15.0 --- .../Categories/XCUIApplication+FBAlert.m | 29 ++++--------- .../Categories/XCUIDevice+FBHelpers.m | 6 +-- .../Categories/XCUIElement+FBTap.m | 43 +++---------------- WebDriverAgentLib/Commands/FBCustomCommands.m | 6 +-- .../Utilities/FBBaseActionsSynthesizer.m | 34 ++++----------- WebDriverAgentLib/Utilities/FBKeyboard.m | 3 +- WebDriverAgentLib/Utilities/FBScreen.m | 11 +---- WebDriverAgentLib/Utilities/FBScreenshot.m | 1 - .../Utilities/FBW3CActionsSynthesizer.m | 4 +- 9 files changed, 31 insertions(+), 106 deletions(-) diff --git a/WebDriverAgentLib/Categories/XCUIApplication+FBAlert.m b/WebDriverAgentLib/Categories/XCUIApplication+FBAlert.m index eb23ed6a7..38b6586ef 100644 --- a/WebDriverAgentLib/Categories/XCUIApplication+FBAlert.m +++ b/WebDriverAgentLib/Categories/XCUIApplication+FBAlert.m @@ -36,26 +36,15 @@ - (nullable XCUIElement *)fb_alertElementFromSafariWithScrollView:(XCUIElement * }]; NSPredicate *dstViewContainPredicate1 = [NSPredicate predicateWithFormat:@"elementType == %lu", XCUIElementTypeTextView]; NSPredicate *dstViewContainPredicate2 = [NSPredicate predicateWithFormat:@"elementType == %lu", XCUIElementTypeButton]; - XCUIElement *candidate = nil; - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) { - // Find the first XCUIElementTypeOther which is the grandchild of the web view - // and is horizontally aligned to the center of the screen - candidate = [[[[[[scrollView descendantsMatchingType:XCUIElementTypeAny] - matchingIdentifier:@"WebView"] - descendantsMatchingType:XCUIElementTypeOther] - matchingPredicate:dstViewMatchPredicate] - containingPredicate:dstViewContainPredicate1] - containingPredicate:dstViewContainPredicate2].allElementsBoundByIndex.firstObject; - } else { - NSPredicate *webViewPredicate = [NSPredicate predicateWithFormat:@"elementType == %lu", XCUIElementTypeWebView]; - // Find the first XCUIElementTypeOther which is the descendant of the scroll view - // and is horizontally aligned to the center of the screen - candidate = [[[[[scrollView.fb_query containingPredicate:webViewPredicate] - descendantsMatchingType:XCUIElementTypeOther] - matchingPredicate:dstViewMatchPredicate] - containingPredicate:dstViewContainPredicate1] - containingPredicate:dstViewContainPredicate2].allElementsBoundByIndex.firstObject; - } + // Find the first XCUIElementTypeOther which is the grandchild of the web view + // and is horizontally aligned to the center of the screen + XCUIElement *candidate = [[[[[[scrollView descendantsMatchingType:XCUIElementTypeAny] + matchingIdentifier:@"WebView"] + descendantsMatchingType:XCUIElementTypeOther] + matchingPredicate:dstViewMatchPredicate] + containingPredicate:dstViewContainPredicate1] + containingPredicate:dstViewContainPredicate2].allElementsBoundByIndex.firstObject; + if (nil == candidate) { return nil; } diff --git a/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m b/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m index 1bc95a33e..5f138f381 100644 --- a/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m +++ b/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m @@ -86,11 +86,7 @@ - (BOOL)fb_unlockScreen:(NSError **)error [self pressButton:XCUIDeviceButtonHome]; [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:FBHomeButtonCoolOffTime]]; #if !TARGET_OS_TV - if (SYSTEM_VERSION_LESS_THAN(@"10.0")) { - [[FBApplication fb_activeApplication] swipeRight]; - } else { - [self pressButton:XCUIDeviceButtonHome]; - } + [self pressButton:XCUIDeviceButtonHome]; #else [self pressButton:XCUIDeviceButtonHome]; #endif diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBTap.m b/WebDriverAgentLib/Categories/XCUIElement+FBTap.m index 311e13d8e..c3c4346ae 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBTap.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBTap.m @@ -9,52 +9,23 @@ #import "XCUIElement+FBTap.h" -#import "FBMacros.h" -#import "XCUIApplication+FBTouchAction.h" -#import "XCUIElement+FBUtilities.h" - #if !TARGET_OS_TV @implementation XCUIElement (FBTap) - (BOOL)fb_tapWithError:(NSError **)error { - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"13.0")) { - [self tap]; - return YES; - } - - NSArray *> *tapGesture = - @[ - @{@"action": @"tap", - @"options": @{@"element": self} - } - ]; - return [self.application fb_performAppiumTouchActions:tapGesture elementCache:nil error:error]; + [self tap]; + return YES; } - (BOOL)fb_tapCoordinate:(CGPoint)relativeCoordinate error:(NSError **)error { - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"13.0")) { - // Coordinates calculation issues have been fixed - // for different device orientations since Xcode 11 - XCUICoordinate *startCoordinate = [self coordinateWithNormalizedOffset:CGVectorMake(0, 0)]; - CGVector offset = CGVectorMake(relativeCoordinate.x, relativeCoordinate.y); - XCUICoordinate *dstCoordinate = [startCoordinate coordinateWithOffset:offset]; - [dstCoordinate tap]; - return YES; - } - - NSArray *> *tapGesture = - @[ - @{@"action": @"tap", - @"options": @{@"element": self, - @"x": @(relativeCoordinate.x), - @"y": @(relativeCoordinate.y) - } - } - ]; - return [self.application fb_performAppiumTouchActions:tapGesture elementCache:nil error:error]; + XCUICoordinate *startCoordinate = [self coordinateWithNormalizedOffset:CGVectorMake(0, 0)]; + CGVector offset = CGVectorMake(relativeCoordinate.x, relativeCoordinate.y); + XCUICoordinate *dstCoordinate = [startCoordinate coordinateWithOffset:offset]; + [dstCoordinate tap]; + return YES; } @end diff --git a/WebDriverAgentLib/Commands/FBCustomCommands.m b/WebDriverAgentLib/Commands/FBCustomCommands.m index 1ad36c57d..c2cde607e 100644 --- a/WebDriverAgentLib/Commands/FBCustomCommands.m +++ b/WebDriverAgentLib/Commands/FBCustomCommands.m @@ -423,10 +423,8 @@ + (NSDictionary *)processArguments:(XCUIApplication *)app #endif }]; - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) { - // https://developer.apple.com/documentation/foundation/nsprocessinfothermalstate - deviceInfo[@"thermalState"] = @(NSProcessInfo.processInfo.thermalState); - } + // https://developer.apple.com/documentation/foundation/nsprocessinfothermalstate + deviceInfo[@"thermalState"] = @(NSProcessInfo.processInfo.thermalState); return FBResponseWithObject(deviceInfo); } diff --git a/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.m b/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.m index 24cc054fa..04e492622 100644 --- a/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.m +++ b/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.m @@ -48,24 +48,8 @@ - (CGPoint)fixedHitPointWith:(CGPoint)hitPoint forSnapshot:(id> *ancestors = [FBXCElementSnapshotWrapper ensureWrapped:snapshot].fb_ancestors; - id parentWindow = ancestors.count > 1 ? [ancestors objectAtIndex:ancestors.count - 2] : nil; - CGRect parentWindowFrame = nil == parentWindow ? snapshot.frame : parentWindow.frame; - if ((appFrame.size.height > appFrame.size.width && parentWindowFrame.size.height < parentWindowFrame.size.width) || - (appFrame.size.height < appFrame.size.width && parentWindowFrame.size.height > parentWindowFrame.size.width)) { - /* - This is the indication of the fact that transformation is broken and coordinates should be - recalculated manually. - However, upside-down case cannot be covered this way, which is not important for Appium - */ - return FBInvertPointForApplication(hitPoint, appFrame.size, interfaceOrientation); - } - return hitPoint; + // For Xcode11+ it is always necessary to adjust the tap point coordinates + return FBInvertPointForApplication(hitPoint, self.application.frame.size, interfaceOrientation); } - (nullable NSValue *)hitpointWithElement:(nullable XCUIElement *)element positionOffset:(nullable NSValue *)positionOffset error:(NSError **)error @@ -74,14 +58,12 @@ - (nullable NSValue *)hitpointWithElement:(nullable XCUIElement *)element positi if (nil == element) { // Only absolute offset is defined hitPoint = [positionOffset CGPointValue]; - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) { - /* - Since iOS 10.0 XCTest has a bug when it always returns portrait coordinates for UI elements - even if the device is not in portait mode. That is why we need to recalculate them manually - based on the current orientation value - */ - hitPoint = FBInvertPointForApplication(hitPoint, self.application.frame.size, self.application.interfaceOrientation); - } + /* + Since iOS 10.0 XCTest has a bug when it always returns portrait coordinates for UI elements + even if the device is not in portait mode. That is why we need to recalculate them manually + based on the current orientation value + */ + hitPoint = FBInvertPointForApplication(hitPoint, self.application.frame.size, self.application.interfaceOrientation); } else { // The offset relative to the element is defined diff --git a/WebDriverAgentLib/Utilities/FBKeyboard.m b/WebDriverAgentLib/Utilities/FBKeyboard.m index 3f3a0b016..7d474ac02 100644 --- a/WebDriverAgentLib/Utilities/FBKeyboard.m +++ b/WebDriverAgentLib/Utilities/FBKeyboard.m @@ -63,8 +63,7 @@ + (BOOL)waitUntilVisibleForApplication:(XCUIApplication *)app timeout:(NSTimeInt }]; XCUIElement *firstKey = [[app.keyboard descendantsMatchingType:XCUIElementTypeKey] matchingPredicate:keySearchPredicate].allElementsBoundByIndex.firstObject; - return firstKey.exists - && (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"13.0") ? firstKey.hittable : firstKey.fb_isVisible); + return firstKey.exists && firstKey.hittable; }; NSString* errMessage = @"The on-screen keyboard must be present to send keys"; if (timeout <= 0) { diff --git a/WebDriverAgentLib/Utilities/FBScreen.m b/WebDriverAgentLib/Utilities/FBScreen.m index 81e7b930c..e2b25855b 100644 --- a/WebDriverAgentLib/Utilities/FBScreen.m +++ b/WebDriverAgentLib/Utilities/FBScreen.m @@ -22,17 +22,10 @@ + (double)scale + (CGSize)statusBarSizeForApplication:(XCUIApplication *)application { - XCUIApplication *app = application; - BOOL expectVisibleBar = YES; - + XCUIApplication *app = FBApplication.fb_systemApplication; // Since iOS 13 the status bar is no longer part of the application, it’s part of the SpringBoard - if (@available(iOS 13.0, *)) { - app = FBApplication.fb_systemApplication; - expectVisibleBar = NO; - } - XCUIElement *mainStatusBar = app.statusBars.allElementsBoundByIndex.firstObject; - if (!mainStatusBar || (expectVisibleBar && !mainStatusBar.fb_isVisible)) { + if (nil == mainStatusBar) { return CGSizeZero; } CGSize result = mainStatusBar.frame.size; diff --git a/WebDriverAgentLib/Utilities/FBScreenshot.m b/WebDriverAgentLib/Utilities/FBScreenshot.m index 60e467173..740048e66 100644 --- a/WebDriverAgentLib/Utilities/FBScreenshot.m +++ b/WebDriverAgentLib/Utilities/FBScreenshot.m @@ -228,7 +228,6 @@ + (nullable id)imageEncodingWithUniformTypeIdentifier:(NSString *)uti compressionQuality:(CGFloat)compressionQuality error:(NSError **)error { - // TODO: Use native accessors after we drop the support of Xcode 12.4 and below Class imageEncodingClass = NSClassFromString(@"XCTImageEncoding"); if (nil == imageEncodingClass) { [[[FBErrorBuilder builder] diff --git a/WebDriverAgentLib/Utilities/FBW3CActionsSynthesizer.m b/WebDriverAgentLib/Utilities/FBW3CActionsSynthesizer.m index 33cb559b9..6696f26f0 100644 --- a/WebDriverAgentLib/Utilities/FBW3CActionsSynthesizer.m +++ b/WebDriverAgentLib/Utilities/FBW3CActionsSynthesizer.m @@ -297,9 +297,7 @@ - (nullable NSValue *)positionWithError:(NSError **)error } CGPoint recentPosition = self.previousItem.atPosition; CGPoint offsetRelativeToRecentPosition = (nil == x && nil == y) ? CGPointMake(0.0, 0.0) : CGPointMake(x.floatValue, y.floatValue); - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) { - offsetRelativeToRecentPosition = FBInvertOffsetForOrientation(offsetRelativeToRecentPosition, self.application.interfaceOrientation); - } + offsetRelativeToRecentPosition = FBInvertOffsetForOrientation(offsetRelativeToRecentPosition, self.application.interfaceOrientation); return [NSValue valueWithCGPoint:CGPointMake(recentPosition.x + offsetRelativeToRecentPosition.x, recentPosition.y + offsetRelativeToRecentPosition.y)]; } From 72fb12b7c08e698cb4eeac1ddada89a99b1619b2 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 14 May 2023 11:24:40 +0000 Subject: [PATCH 112/240] chore(release): 5.0.0 [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [5.0.0](https://github.com/appium/WebDriverAgent/compare/v4.15.1...v5.0.0) (2023-05-14) ### ⚠ BREAKING CHANGES * The minimum supported xCode/iOS version is now 13/15.0 ### Code Refactoring * Drop workarounds for legacy iOS versions ([#696](https://github.com/appium/WebDriverAgent/issues/696)) ([bb562b9](https://github.com/appium/WebDriverAgent/commit/bb562b96db6aad476970ef7bd352cb8df4f1e6c2)) --- CHANGELOG.md | 11 +++++++++++ package.json | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b57bd88c..c1b7cd70d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## [5.0.0](https://github.com/appium/WebDriverAgent/compare/v4.15.1...v5.0.0) (2023-05-14) + + +### ⚠ BREAKING CHANGES + +* The minimum supported xCode/iOS version is now 13/15.0 + +### Code Refactoring + +* Drop workarounds for legacy iOS versions ([#696](https://github.com/appium/WebDriverAgent/issues/696)) ([bb562b9](https://github.com/appium/WebDriverAgent/commit/bb562b96db6aad476970ef7bd352cb8df4f1e6c2)) + ## [4.15.1](https://github.com/appium/WebDriverAgent/compare/v4.15.0...v4.15.1) (2023-05-06) diff --git a/package.json b/package.json index 4e54f3d4e..0aeff7451 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "4.15.1", + "version": "5.0.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 025b42c8a34ff0beba4379f4cb0c1d79d2b222ed Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Sun, 14 May 2023 13:27:41 +0200 Subject: [PATCH 113/240] refactor: Remove obsolete coordinate calculation workarounds needed for older xCode SDKs (#698) --- .azure-pipelines.yml | 20 ++-- WebDriverAgent.xcodeproj/project.pbxproj | 20 ---- .../Categories/XCUICoordinate+FBFix.h | 18 ---- .../Categories/XCUICoordinate+FBFix.m | 46 ---------- .../Categories/XCUIElement+FBIsVisible.m | 12 --- .../Categories/XCUIElement+FBPickerWheel.m | 16 +--- .../Categories/XCUIElement+FBScrolling.m | 44 ++------- .../Categories/XCUIElement+FBUtilities.h | 7 -- .../Categories/XCUIElement+FBUtilities.m | 49 ---------- .../Commands/FBElementCommands.m | 6 +- .../Utilities/FBAppiumActionsSynthesizer.m | 38 +++++--- .../Utilities/FBBaseActionsSynthesizer.h | 17 +--- .../Utilities/FBBaseActionsSynthesizer.m | 92 ++++++++----------- WebDriverAgentLib/Utilities/FBMathUtils.h | 6 -- WebDriverAgentLib/Utilities/FBMathUtils.m | 29 ------ .../Utilities/FBW3CActionsSynthesizer.m | 52 +++++------ .../Utilities/FBXCTestDaemonsProxy.h | 4 - .../Utilities/FBXCTestDaemonsProxy.m | 12 --- .../FBAppiumTouchActionsIntegrationTests.m | 16 ---- .../FBElementScreenshotTests.m | 52 ----------- .../FBW3CTouchActionsIntegrationTests.m | 19 ---- .../UnitTests/FBMathUtilsTests.m | 12 --- .../UnitTests/XCUICoordinateFix.m | 63 ------------- 23 files changed, 107 insertions(+), 543 deletions(-) delete mode 100644 WebDriverAgentLib/Categories/XCUICoordinate+FBFix.h delete mode 100644 WebDriverAgentLib/Categories/XCUICoordinate+FBFix.m delete mode 100644 WebDriverAgentTests/IntegrationTests/FBElementScreenshotTests.m delete mode 100644 WebDriverAgentTests/UnitTests/XCUICoordinateFix.m diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index 03ad02e58..864c786f0 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -1,20 +1,20 @@ # https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops&tabs=yaml variables: - MIN_VM_IMAGE: macOS-11 - MIN_XCODE_VERSION: 12.4 - MIN_PLATFORM_VERSION: 14.4 - MIN_TV_PLATFORM_VERSION: 14.3 - MIN_TV_DEVICE_NAME: Apple TV 4K + MIN_VM_IMAGE: macOS-12 + MIN_XCODE_VERSION: 13.1 + MIN_PLATFORM_VERSION: 15.0 + MIN_TV_PLATFORM_VERSION: 15.0 + MIN_TV_DEVICE_NAME: Apple TV 4K (2nd generation) MIN_IPHONE_DEVICE_NAME: iPhone 11 - MIN_IPAD_DEVICE_NAME: iPad Pro (11-inch) (2nd generation) + MIN_IPAD_DEVICE_NAME: iPad Pro (11-inch) (3rd generation) MAX_VM_IMAGE: macOS-12 - MAX_XCODE_VERSION: 13.4 - MAX_PLATFORM_VERSION: 15.5 - MAX_PLATFORM_VERSION_TV: 15.4 + MAX_XCODE_VERSION: 14.2 + MAX_PLATFORM_VERSION: 16.2 + MAX_PLATFORM_VERSION_TV: 16.1 MAX_IPHONE_DEVICE_NAME: iPhone 13 MAX_TV_DEVICE_NAME: Apple TV 4K (2nd generation) MAX_IPAD_DEVICE_NAME: iPad Pro (11-inch) (3rd generation) - DEFAULT_NODE_VERSION: "16.x" + DEFAULT_NODE_VERSION: "18.x" pool: diff --git a/WebDriverAgent.xcodeproj/project.pbxproj b/WebDriverAgent.xcodeproj/project.pbxproj index 7b8cf620e..b719df35b 100644 --- a/WebDriverAgent.xcodeproj/project.pbxproj +++ b/WebDriverAgent.xcodeproj/project.pbxproj @@ -86,7 +86,6 @@ 641EE6042240C5CA00173FCB /* NSString+FBXMLSafeString.m in Sources */ = {isa = PBXBuildFile; fileRef = 716E0BCD1E917E810087A825 /* NSString+FBXMLSafeString.m */; }; 641EE6052240C5CA00173FCB /* FBUnknownCommands.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9AB7651CAEDF0C008C271F /* FBUnknownCommands.m */; }; 641EE6062240C5CA00173FCB /* FBOrientationCommands.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9AB75D1CAEDF0C008C271F /* FBOrientationCommands.m */; }; - 641EE6072240C5CA00173FCB /* XCUICoordinate+FBFix.m in Sources */ = {isa = PBXBuildFile; fileRef = EEC9EED520064FAA00BC0D5B /* XCUICoordinate+FBFix.m */; }; 641EE6082240C5CA00173FCB /* FBRuntimeUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9AB7921CAEDF0C008C271F /* FBRuntimeUtils.m */; }; 641EE6092240C5CA00173FCB /* XCUIElement+FBUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = EEE376401D59F81400ED88DD /* XCUIElement+FBUtilities.m */; }; 641EE60A2240C5CA00173FCB /* FBLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9B76A41CF7A43900275851 /* FBLogger.m */; }; @@ -160,7 +159,6 @@ 641EE65B2240C5CA00173FCB /* XCUIElementHitPointCoordinate.h in Headers */ = {isa = PBXBuildFile; fileRef = EE35AD011E3B77D600A02D78 /* XCUIElementHitPointCoordinate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 641EE65C2240C5CA00173FCB /* XCTDarwinNotificationExpectation.h in Headers */ = {isa = PBXBuildFile; fileRef = EE35ACCE1E3B77D600A02D78 /* XCTDarwinNotificationExpectation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 641EE65D2240C5CA00173FCB /* XCTRunnerAutomationSession.h in Headers */ = {isa = PBXBuildFile; fileRef = EE35ACEE1E3B77D600A02D78 /* XCTRunnerAutomationSession.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 641EE65E2240C5CA00173FCB /* XCUICoordinate+FBFix.h in Headers */ = {isa = PBXBuildFile; fileRef = EEC9EED420064FAA00BC0D5B /* XCUICoordinate+FBFix.h */; }; 641EE65F2240C5CA00173FCB /* XCSourceCodeTreeNodeEnumerator.h in Headers */ = {isa = PBXBuildFile; fileRef = EE35ACC61E3B77D600A02D78 /* XCSourceCodeTreeNodeEnumerator.h */; settings = {ATTRIBUTES = (Public, ); }; }; 641EE6602240C5CA00173FCB /* XCUIElement+FBIsVisible.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9AB7471CAEDF0C008C271F /* XCUIElement+FBIsVisible.h */; settings = {ATTRIBUTES = (Public, ); }; }; 641EE6612240C5CA00173FCB /* XCUIElement+FBTap.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9AB74B1CAEDF0C008C271F /* XCUIElement+FBTap.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -456,7 +454,6 @@ 71A7EAF91E224648001DA4F2 /* FBClassChainQueryParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 71A7EAF71E224648001DA4F2 /* FBClassChainQueryParser.h */; }; 71A7EAFA1E224648001DA4F2 /* FBClassChainQueryParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 71A7EAF81E224648001DA4F2 /* FBClassChainQueryParser.m */; }; 71A7EAFC1E229302001DA4F2 /* FBClassChainTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 71A7EAFB1E229302001DA4F2 /* FBClassChainTests.m */; }; - 71AB82B21FDAE8C000D1D7C3 /* FBElementScreenshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 71AB82B11FDAE8C000D1D7C3 /* FBElementScreenshotTests.m */; }; 71ACF5B8242F2FDC00F0AAD4 /* FBSafariAlertTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 71ACF5B7242F2FDC00F0AAD4 /* FBSafariAlertTests.m */; }; 71B155DA23070ECF00646AFB /* FBHTTPStatusCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 71B155D923070ECF00646AFB /* FBHTTPStatusCodes.h */; settings = {ATTRIBUTES = (Public, ); }; }; 71B155DC230711E900646AFB /* FBCommandStatus.m in Sources */ = {isa = PBXBuildFile; fileRef = 71B155DB230711E900646AFB /* FBCommandStatus.m */; }; @@ -785,9 +782,6 @@ EE9B76AA1CF7A43900275851 /* FBMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9B76A51CF7A43900275851 /* FBMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; EEBBD48B1D47746D00656A81 /* XCUIElement+FBFind.h in Headers */ = {isa = PBXBuildFile; fileRef = EEBBD4891D47746D00656A81 /* XCUIElement+FBFind.h */; settings = {ATTRIBUTES = (Public, ); }; }; EEBBD48C1D47746D00656A81 /* XCUIElement+FBFind.m in Sources */ = {isa = PBXBuildFile; fileRef = EEBBD48A1D47746D00656A81 /* XCUIElement+FBFind.m */; }; - EEC9EED620064FAA00BC0D5B /* XCUICoordinate+FBFix.h in Headers */ = {isa = PBXBuildFile; fileRef = EEC9EED420064FAA00BC0D5B /* XCUICoordinate+FBFix.h */; }; - EEC9EED720064FAA00BC0D5B /* XCUICoordinate+FBFix.m in Sources */ = {isa = PBXBuildFile; fileRef = EEC9EED520064FAA00BC0D5B /* XCUICoordinate+FBFix.m */; }; - EEC9EED920077D8E00BC0D5B /* XCUICoordinateFix.m in Sources */ = {isa = PBXBuildFile; fileRef = EEC9EED820077D8E00BC0D5B /* XCUICoordinateFix.m */; }; EEDFE1211D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = EEDFE11F1D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.h */; settings = {ATTRIBUTES = (Public, ); }; }; EEDFE1221D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.m in Sources */ = {isa = PBXBuildFile; fileRef = EEDFE1201D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.m */; }; EEE16E971D33A25500172525 /* FBConfigurationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = EEE16E961D33A25500172525 /* FBConfigurationTests.m */; }; @@ -1043,7 +1037,6 @@ 71A7EAF71E224648001DA4F2 /* FBClassChainQueryParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBClassChainQueryParser.h; sourceTree = ""; }; 71A7EAF81E224648001DA4F2 /* FBClassChainQueryParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBClassChainQueryParser.m; sourceTree = ""; }; 71A7EAFB1E229302001DA4F2 /* FBClassChainTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBClassChainTests.m; sourceTree = ""; }; - 71AB82B11FDAE8C000D1D7C3 /* FBElementScreenshotTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBElementScreenshotTests.m; sourceTree = ""; }; 71ACF5B7242F2FDC00F0AAD4 /* FBSafariAlertTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSafariAlertTests.m; sourceTree = ""; }; 71B155D923070ECF00646AFB /* FBHTTPStatusCodes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBHTTPStatusCodes.h; sourceTree = ""; }; 71B155DB230711E900646AFB /* FBCommandStatus.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBCommandStatus.m; sourceTree = ""; }; @@ -1353,9 +1346,6 @@ EEC088E41CB56AC000B65968 /* FBElementCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBElementCache.m; sourceTree = ""; }; EEC088E61CB56DA400B65968 /* FBExceptionHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBExceptionHandler.h; sourceTree = ""; }; EEC088E71CB56DA400B65968 /* FBExceptionHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBExceptionHandler.m; sourceTree = ""; }; - EEC9EED420064FAA00BC0D5B /* XCUICoordinate+FBFix.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "XCUICoordinate+FBFix.h"; sourceTree = ""; }; - EEC9EED520064FAA00BC0D5B /* XCUICoordinate+FBFix.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "XCUICoordinate+FBFix.m"; sourceTree = ""; }; - EEC9EED820077D8E00BC0D5B /* XCUICoordinateFix.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XCUICoordinateFix.m; sourceTree = ""; }; EEDBEBBA1CB2681900A790A2 /* WebDriverAgent.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = WebDriverAgent.bundle; sourceTree = ""; }; EEDFE11F1D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "XCUIDevice+FBHealthCheck.h"; sourceTree = ""; }; EEDFE1201D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "XCUIDevice+FBHealthCheck.m"; sourceTree = ""; }; @@ -1737,8 +1727,6 @@ 716C9DFF27315EFF005AD475 /* XCUIApplication+FBUIInterruptions.m */, 71D475C02538F5A8008D9401 /* XCUIApplicationProcess+FBQuiescence.h */, 71D475C12538F5A8008D9401 /* XCUIApplicationProcess+FBQuiescence.m */, - EEC9EED420064FAA00BC0D5B /* XCUICoordinate+FBFix.h */, - EEC9EED520064FAA00BC0D5B /* XCUICoordinate+FBFix.m */, 719CD8FA2126C88B00C7D0C2 /* XCUIApplication+FBAlert.h */, 719CD8FB2126C88B00C7D0C2 /* XCUIApplication+FBAlert.m */, 71BD20711F86116100B36EC2 /* XCUIApplication+FBTouchAction.h */, @@ -1985,7 +1973,6 @@ 719A97AB1F88E7370063B4BD /* FBAppiumMultiTouchActionsIntegrationTests.m */, 719CD8FE2126C90200C7D0C2 /* FBAutoAlertsHandlerTests.m */, EE26409C1D0EBA25009BE6B0 /* FBElementAttributeTests.m */, - 71AB82B11FDAE8C000D1D7C3 /* FBElementScreenshotTests.m */, 71F5BE33252E5B2200EE9EBA /* FBElementSwipingTests.m */, EE006EAC1EB99B15006900A4 /* FBElementVisibilityTests.m */, EE6A89361D0B35920083E92B /* FBFailureProofTestCaseTests.m */, @@ -2045,7 +2032,6 @@ EE9B76581CF7987300275851 /* Info.plist */, 7139145B1DF01A12005896C2 /* NSExpressionFBFormatTests.m */, 71A224E71DE326C500844D55 /* NSPredicateFBFormatTests.m */, - EEC9EED820077D8E00BC0D5B /* XCUICoordinateFix.m */, 713914591DF01989005896C2 /* XCUIElementHelpersTests.m */, ); path = UnitTests; @@ -2311,7 +2297,6 @@ 641EE65B2240C5CA00173FCB /* XCUIElementHitPointCoordinate.h in Headers */, 641EE65C2240C5CA00173FCB /* XCTDarwinNotificationExpectation.h in Headers */, 641EE65D2240C5CA00173FCB /* XCTRunnerAutomationSession.h in Headers */, - 641EE65E2240C5CA00173FCB /* XCUICoordinate+FBFix.h in Headers */, 641EE65F2240C5CA00173FCB /* XCSourceCodeTreeNodeEnumerator.h in Headers */, 641EE6602240C5CA00173FCB /* XCUIElement+FBIsVisible.h in Headers */, 641EE6612240C5CA00173FCB /* XCUIElement+FBTap.h in Headers */, @@ -2548,7 +2533,6 @@ EE35AD3F1E3B77D600A02D78 /* XCTDarwinNotificationExpectation.h in Headers */, EE35AD5F1E3B77D600A02D78 /* XCTRunnerAutomationSession.h in Headers */, 71C9EAAC25E8415A00470CD8 /* FBScreenshot.h in Headers */, - EEC9EED620064FAA00BC0D5B /* XCUICoordinate+FBFix.h in Headers */, EE35AD371E3B77D600A02D78 /* XCSourceCodeTreeNodeEnumerator.h in Headers */, EE158AB01CBD456F00A3E3F0 /* XCUIElement+FBIsVisible.h in Headers */, 71414ED42670A1EE003A8C5D /* LRUCache.h in Headers */, @@ -3141,7 +3125,6 @@ 641EE6052240C5CA00173FCB /* FBUnknownCommands.m in Sources */, 641EE6062240C5CA00173FCB /* FBOrientationCommands.m in Sources */, 641EE7092240CDEB00173FCB /* XCUIElement+FBTVFocuse.m in Sources */, - 641EE6072240C5CA00173FCB /* XCUICoordinate+FBFix.m in Sources */, 641EE6082240C5CA00173FCB /* FBRuntimeUtils.m in Sources */, 641EE6092240C5CA00173FCB /* XCUIElement+FBUtilities.m in Sources */, 641EE60A2240C5CA00173FCB /* FBLogger.m in Sources */, @@ -3259,7 +3242,6 @@ EE158AC51CBD456F00A3E3F0 /* FBOrientationCommands.m in Sources */, 71D475C42538F5A8008D9401 /* XCUIApplicationProcess+FBQuiescence.m in Sources */, 641EE7082240CDEB00173FCB /* XCUIElement+FBTVFocuse.m in Sources */, - EEC9EED720064FAA00BC0D5B /* XCUICoordinate+FBFix.m in Sources */, 71E75E6F254824230099FC87 /* XCUIElementQuery+FBHelpers.m in Sources */, 71D04DCA25356C43008A052C /* XCUIElement+FBCaching.m in Sources */, EE158AEB1CBD456F00A3E3F0 /* FBRuntimeUtils.m in Sources */, @@ -3330,7 +3312,6 @@ 715AFAC41FFA2AAF0053896D /* FBScreenTests.m in Sources */, EE22021E1ECC618900A29571 /* FBTapTest.m in Sources */, 71930C472066434000D3AFEC /* FBPasteboardTests.m in Sources */, - 71AB82B21FDAE8C000D1D7C3 /* FBElementScreenshotTests.m in Sources */, 7150FFF722476B3A00B2EE28 /* FBForceTouchTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3382,7 +3363,6 @@ ADBC39981D07842800327304 /* XCUIElementDouble.m in Sources */, 7139145A1DF01989005896C2 /* XCUIElementHelpersTests.m in Sources */, EE6A89261D0B19E60083E92B /* FBSessionTests.m in Sources */, - EEC9EED920077D8E00BC0D5B /* XCUICoordinateFix.m in Sources */, 71A7EAFC1E229302001DA4F2 /* FBClassChainTests.m in Sources */, EE18883D1DA663EB00307AA8 /* FBMathUtilsTests.m in Sources */, ); diff --git a/WebDriverAgentLib/Categories/XCUICoordinate+FBFix.h b/WebDriverAgentLib/Categories/XCUICoordinate+FBFix.h deleted file mode 100644 index 14c8750eb..000000000 --- a/WebDriverAgentLib/Categories/XCUICoordinate+FBFix.h +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import - -#if !TARGET_OS_TV -@interface XCUICoordinate (FBFix) - -- (CGPoint)fb_screenPoint; - -@end -#endif diff --git a/WebDriverAgentLib/Categories/XCUICoordinate+FBFix.m b/WebDriverAgentLib/Categories/XCUICoordinate+FBFix.m deleted file mode 100644 index 3313cda64..000000000 --- a/WebDriverAgentLib/Categories/XCUICoordinate+FBFix.m +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import "XCUICoordinate+FBFix.h" - -#import "XCUICoordinate.h" -#import "XCUIElement+FBUtilities.h" - -# if !TARGET_OS_TV -@implementation XCUICoordinate (FBFix) - -- (CGPoint)fb_screenPoint -{ - CGPoint referencePoint = CGPointMake(0, 0); - NSValue *referencedElementFrame = nil; - if (self.element) { - CGRect elementFrame = self.element.frame; - if (self.referencedElement == self.element) { - referencedElementFrame = [NSValue valueWithCGRect:elementFrame]; - } - referencePoint = CGPointMake( - CGRectGetMinX(elementFrame) + CGRectGetWidth(elementFrame) * self.normalizedOffset.dx, - CGRectGetMinY(elementFrame) + CGRectGetHeight(elementFrame) * self.normalizedOffset.dy); - } else if (self.coordinate) { - referencePoint = self.coordinate.fb_screenPoint; - } - - CGPoint screenPoint = CGPointMake( - referencePoint.x + self.pointsOffset.dx, - referencePoint.y + self.pointsOffset.dy); - if (nil == referencedElementFrame) { - referencedElementFrame = [NSValue valueWithCGRect:self.referencedElement.frame]; - } - return CGPointMake( - MIN(CGRectGetMaxX(referencedElementFrame.CGRectValue), screenPoint.x), - MIN(CGRectGetMaxY(referencedElementFrame.CGRectValue), screenPoint.y)); -} - -@end -#endif diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBIsVisible.m b/WebDriverAgentLib/Categories/XCUIElement+FBIsVisible.m index c667a48c8..87841fc38 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBIsVisible.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBIsVisible.m @@ -186,18 +186,6 @@ - (BOOL)fb_isVisible } CGPoint midPoint = CGPointMake(visibleRect.origin.x + visibleRect.size.width / 2, visibleRect.origin.y + visibleRect.size.height / 2); -#if !TARGET_OS_TV // TV has no orientation, so it does not need to coordinate - id appElement = ancestors.count > 0 ? [ancestors lastObject] : self; - CGRect appFrame = appElement.frame; - CGRect windowFrame = nil == parentWindow ? selfFrame : parentWindow.frame; - if ((appFrame.size.height > appFrame.size.width && windowFrame.size.height < windowFrame.size.width) || - (appFrame.size.height < appFrame.size.width && windowFrame.size.height > windowFrame.size.width)) { - // This is the indication of the fact that transformation is broken and coordinates should be - // recalculated manually. - // However, upside-down case cannot be covered this way, which is not important for Appium - midPoint = FBInvertPointForApplication(midPoint, appFrame.size, FBApplication.fb_activeApplication.interfaceOrientation); - } -#endif id hitElement = [FBActiveAppDetectionPoint axElementWithPoint:midPoint]; if (nil != hitElement) { if (FBIsAXElementEqualToOther(self.accessibilityElement, hitElement)) { diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBPickerWheel.m b/WebDriverAgentLib/Categories/XCUIElement+FBPickerWheel.m index adce016ff..5aeed18e6 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBPickerWheel.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBPickerWheel.m @@ -12,9 +12,7 @@ #import "FBRunLoopSpinner.h" #import "FBXCElementSnapshot.h" #import "FBXCodeCompatibility.h" -#import "XCUIApplication+FBTouchAction.h" #import "XCUICoordinate.h" -#import "XCUICoordinate+FBFix.h" #import "XCUIElement+FBCaching.h" #import "XCUIElement+FBResolve.h" @@ -31,16 +29,7 @@ - (BOOL)fb_scrollWithOffset:(CGFloat)relativeHeightOffset error:(NSError **)erro NSString *previousValue = snapshot.value; XCUICoordinate *startCoord = [self coordinateWithNormalizedOffset:CGVectorMake(0.5, 0.5)]; XCUICoordinate *endCoord = [startCoord coordinateWithOffset:CGVectorMake(0.0, relativeHeightOffset * snapshot.frame.size.height)]; - CGPoint tapPoint = endCoord.fb_screenPoint; - NSArray *> *gesture = - @[@{ - @"action": @"tap", - @"options": @{ - @"x": @(tapPoint.x), - @"y": @(tapPoint.y), - } - } - ]; + [endCoord tap]; // If picker value is reflected in its accessiblity id // then fetching of the next snapshot may fail with StaleElementReferenceError // because we bound elements by their accessbility ids by default. @@ -48,9 +37,6 @@ - (BOOL)fb_scrollWithOffset:(CGFloat)relativeHeightOffset error:(NSError **)erro // unique element identifier (UID), so it could be found next time even if its // id is different from the initial one. See https://github.com/appium/appium/issues/17569 XCUIElement *stableInstance = self.fb_stableInstance; - if (![self.application fb_performAppiumTouchActions:gesture elementCache:nil error:error]) { - return NO; - } return [[[[FBRunLoopSpinner new] timeout:VALUE_CHANGE_TIMEOUT] timeoutErrorMessage:[NSString stringWithFormat:@"Picker wheel value has not been changed after %@ seconds timeout", @(VALUE_CHANGE_TIMEOUT)]] diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBScrolling.m b/WebDriverAgentLib/Categories/XCUIElement+FBScrolling.m index f9582b52a..52be1a557 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBScrolling.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBScrolling.m @@ -16,11 +16,9 @@ #import "FBXCodeCompatibility.h" #import "FBXCElementSnapshotWrapper.h" #import "FBXCElementSnapshotWrapper+Helpers.h" -#import "XCUIApplication+FBTouchAction.h" #import "XCUIElement+FBCaching.h" #import "XCUIApplication.h" #import "XCUICoordinate.h" -#import "XCUICoordinate+FBFix.h" #import "XCUIElement+FBIsVisible.h" #import "XCUIElement.h" #import "XCUIElement+FBUtilities.h" @@ -28,7 +26,8 @@ const CGFloat FBFuzzyPointThreshold = 20.f; //Smallest determined value that is not interpreted as touch const CGFloat FBScrollToVisibleNormalizedDistance = .5f; -const CGFloat FBTouchEventDelay = 1.f; +const CGFloat FBTouchEventDelay = 0.5f; +const CGFloat FBTouchVelocity = 300; // pixels per sec const CGFloat FBScrollTouchProportion = 0.75f; #if !TARGET_OS_TV @@ -321,45 +320,16 @@ - (BOOL)fb_scrollAncestorScrollViewByVectorWithinScrollViewFrame:(CGVector)vecto XCUICoordinate *appCoordinate = [[XCUICoordinate alloc] initWithElement:application normalizedOffset:CGVectorMake(0.0, 0.0)]; XCUICoordinate *startCoordinate = [[XCUICoordinate alloc] initWithCoordinate:appCoordinate pointsOffset:hitpointOffset]; - CGPoint startPoint = startCoordinate.fb_screenPoint; XCUICoordinate *endCoordinate = [[XCUICoordinate alloc] initWithCoordinate:startCoordinate pointsOffset:vector]; - CGPoint endPoint = endCoordinate.fb_screenPoint; - if (FBPointFuzzyEqualToPoint(startPoint, endPoint, FBFuzzyPointThreshold)) { + if (FBPointFuzzyEqualToPoint(startCoordinate.screenPoint, endCoordinate.screenPoint, FBFuzzyPointThreshold)) { return YES; } - NSArray *> *gesture = - @[@{ - @"action": @"press", - @"options": @{ - @"x": @(startPoint.x), - @"y": @(startPoint.y), - } - }, - @{ - @"action": @"wait", - @"options": @{ - @"ms": @(FBTouchEventDelay * 1000), - } - }, - @{ - @"action": @"moveTo", - @"options": @{ - @"x": @(endPoint.x), - @"y": @(endPoint.y), - } - }, - @{ - @"action": @"release" - } - ]; - if (![application fb_performAppiumTouchActions:gesture - elementCache:nil - error:error]) { - return NO; - } - + [startCoordinate pressForDuration:FBTouchEventDelay + thenDragToCoordinate:endCoordinate + withVelocity:FBTouchVelocity + thenHoldForDuration:FBTouchEventDelay]; return YES; } diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.h b/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.h index de79e563c..66b9ee2c9 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.h +++ b/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.h @@ -98,13 +98,6 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)fb_waitUntilStableWithTimeout:(NSTimeInterval)timeout; -/** - Returns screenshot of the particular element - @param error If there is an error, upon return contains an NSError object that describes the problem. - @return Element screenshot as PNG-encoded data or nil in case of failure - */ -- (nullable NSData *)fb_screenshotWithError:(NSError*__autoreleasing*)error; - @end NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m b/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m index d78cfd99e..b5a072c06 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m @@ -197,53 +197,4 @@ - (void)fb_waitUntilStableWithTimeout:(NSTimeInterval)timeout FBConfiguration.waitForIdleTimeout = previousTimeout; } -- (NSData *)fb_screenshotWithError:(NSError **)error -{ - id selfSnapshot = self.fb_isResolvedFromCache.boolValue - ? self.lastSnapshot - : self.fb_takeSnapshot; - if (CGRectIsEmpty(selfSnapshot.frame)) { - if (error) { - *error = [[FBErrorBuilder.builder withDescription:@"Cannot get a screenshot of zero-sized element"] build]; - } - return nil; - } - - CGRect elementRect = selfSnapshot.frame; -#if !TARGET_OS_TV - UIInterfaceOrientation orientation = self.application.interfaceOrientation; - if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight) { - // Workaround XCTest bug when element frame is returned as in portrait mode even if the screenshot is rotated - NSArray> *ancestors = [FBXCElementSnapshotWrapper ensureWrapped:selfSnapshot].fb_ancestors; - id parentWindow = nil; - if (1 == ancestors.count) { - parentWindow = selfSnapshot; - } else if (ancestors.count > 1) { - parentWindow = [ancestors objectAtIndex:ancestors.count - 2]; - } - if (nil != parentWindow) { - CGRect appFrame = ancestors.lastObject.frame; - CGRect parentWindowFrame = parentWindow.frame; - if (CGRectEqualToRect(appFrame, parentWindowFrame) - || (appFrame.size.width > appFrame.size.height && parentWindowFrame.size.width > parentWindowFrame.size.height) - || (appFrame.size.width < appFrame.size.height && parentWindowFrame.size.width < parentWindowFrame.size.height)) { - CGPoint fixedOrigin = orientation == UIInterfaceOrientationLandscapeLeft ? - CGPointMake(appFrame.size.height - elementRect.origin.y - elementRect.size.height, elementRect.origin.x) : - CGPointMake(elementRect.origin.y, appFrame.size.width - elementRect.origin.x - elementRect.size.width); - elementRect = CGRectMake(fixedOrigin.x, fixedOrigin.y, elementRect.size.height, elementRect.size.width); - } - } - } -#endif - - // adjust element rect for the actual screen scale - XCUIScreen *mainScreen = XCUIScreen.mainScreen; - elementRect = CGRectMake(elementRect.origin.x * mainScreen.scale, elementRect.origin.y * mainScreen.scale, - elementRect.size.width * mainScreen.scale, elementRect.size.height * mainScreen.scale); - - return [FBScreenshot takeInOriginalResolutionWithQuality:FBConfiguration.screenshotQuality - rect:elementRect - error:error]; -} - @end diff --git a/WebDriverAgentLib/Commands/FBElementCommands.m b/WebDriverAgentLib/Commands/FBElementCommands.m index d5feca45e..6734714c6 100644 --- a/WebDriverAgentLib/Commands/FBElementCommands.m +++ b/WebDriverAgentLib/Commands/FBElementCommands.m @@ -594,10 +594,10 @@ + (NSArray *)routes { FBElementCache *elementCache = request.session.elementCache; XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]]; - NSError *error; - NSData *screenshotData = [element fb_screenshotWithError:&error]; + NSData *screenshotData = [element.screenshot PNGRepresentation]; if (nil == screenshotData) { - return FBResponseWithStatus([FBCommandStatus unableToCaptureScreenErrorWithMessage:error.description + NSString *errMsg = [NSString stringWithFormat:@"Cannot take a screenshot of %@", element.description]; + return FBResponseWithStatus([FBCommandStatus unableToCaptureScreenErrorWithMessage:errMsg traceback:nil]); } NSString *screenshot = [screenshotData base64EncodedStringWithOptions:0]; diff --git a/WebDriverAgentLib/Utilities/FBAppiumActionsSynthesizer.m b/WebDriverAgentLib/Utilities/FBAppiumActionsSynthesizer.m index 7aec01b08..235d97e63 100644 --- a/WebDriverAgentLib/Utilities/FBAppiumActionsSynthesizer.m +++ b/WebDriverAgentLib/Utilities/FBAppiumActionsSynthesizer.m @@ -80,7 +80,7 @@ @implementation FBAppiumGestureItem - (nullable instancetype)initWithActionItem:(NSDictionary *)item application:(XCUIApplication *)application - atPosition:(nullable NSValue *)atPosition + atPosition:(nullable XCUICoordinate *)atPosition offset:(double)offset error:(NSError **)error { @@ -90,14 +90,14 @@ - (nullable instancetype)initWithActionItem:(NSDictionary *)item self.application = application; self.offset = offset; id options = [item objectForKey:FB_OPTIONS_KEY]; - if (atPosition) { - self.atPosition = [atPosition CGPointValue]; + if (nil != atPosition) { + self.atPosition = (id) atPosition; } else { - NSValue *result = [self coordinatesWithOptions:options error:error]; + XCUICoordinate *result = [self coordinatesWithOptions:options error:error]; if (nil == result) { return nil; } - self.atPosition = [result CGPointValue]; + self.atPosition = result; } self.duration = [self durationWithOptions:options]; if (self.duration < 0) { @@ -124,7 +124,8 @@ - (double)durationWithOptions:(nullable NSDictionary *)options 0.0; } -- (nullable NSValue *)coordinatesWithOptions:(nullable NSDictionary *)options error:(NSError **)error +- (nullable XCUICoordinate *)coordinatesWithOptions:(nullable NSDictionary *)options + error:(NSError **)error { if (![options isKindOfClass:NSDictionary.class]) { NSString *description = [NSString stringWithFormat:@"'%@' key is mandatory for '%@' action", FB_OPTIONS_KEY, self.class.actionName]; @@ -169,7 +170,7 @@ + (BOOL)hasAbsolutePositioning NSTimeInterval currentOffset = FBMillisToSeconds(self.offset); NSMutableArray *result = [NSMutableArray array]; XCPointerEventPath *currentPath = [[XCPointerEventPath alloc] - initForTouchAtPoint:self.atPosition + initForTouchAtPoint:self.atPosition.screenPoint offset:currentOffset]; [result addObject:currentPath]; currentOffset += FBMillisToSeconds(FB_TAP_DURATION_MS); @@ -180,7 +181,8 @@ + (BOOL)hasAbsolutePositioning NSNumber *tapCount = [options objectForKey:FB_OPTION_COUNT] ?: @1; for (NSInteger times = 1; times < tapCount.integerValue; ++times) { currentOffset += FBMillisToSeconds(FB_INTERTAP_MIN_DURATION_MS); - XCPointerEventPath *nextPath = [[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition offset:currentOffset]; + XCPointerEventPath *nextPath = [[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition.screenPoint + offset:currentOffset]; [result addObject:nextPath]; currentOffset += FBMillisToSeconds(FB_TAP_DURATION_MS); [nextPath liftUpAtOffset:currentOffset]; @@ -204,7 +206,7 @@ @implementation FBPressItem - (nullable instancetype)initWithActionItem:(NSDictionary *)item application:(XCUIApplication *)application - atPosition:(nullable NSValue *)atPosition + atPosition:(nullable XCUICoordinate *)atPosition offset:(double)offset error:(NSError **)error { @@ -239,7 +241,7 @@ + (BOOL)hasAbsolutePositioning error:(NSError **)error { XCPointerEventPath *result = [[XCPointerEventPath alloc] - initForTouchAtPoint:self.atPosition + initForTouchAtPoint:self.atPosition.screenPoint offset:FBMillisToSeconds(self.offset)]; if (nil != self.pressure && nil != result.pointerEvents.lastObject) { XCPointerEvent *pointerEvent = (XCPointerEvent *)result.pointerEvents.lastObject; @@ -272,7 +274,7 @@ + (BOOL)hasAbsolutePositioning currentItemIndex:(NSUInteger)currentItemIndex error:(NSError **)error { - return @[[[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition + return @[[[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition.screenPoint offset:FBMillisToSeconds(self.offset)]]; } @@ -312,7 +314,8 @@ + (BOOL)hasAbsolutePositioning } } NSTimeInterval currentOffset = FBMillisToSeconds(self.offset + self.duration); - XCPointerEventPath *result = [[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition offset:currentOffset]; + XCPointerEventPath *result = [[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition.screenPoint + offset:currentOffset]; if (currentItemIndex == allItems.count - 1) { [result liftUpAtOffset:currentOffset]; } @@ -353,7 +356,8 @@ + (BOOL)hasAbsolutePositioning return nil; } - [eventPath moveToPoint:self.atPosition atOffset:FBMillisToSeconds(self.offset)]; + [eventPath moveToPoint:self.atPosition.screenPoint + atOffset:FBMillisToSeconds(self.offset)]; return @[]; } @@ -509,7 +513,11 @@ @implementation FBAppiumActionsSynthesizer return nil; } FBAppiumGestureItem *lastItem = [chain.items lastObject]; - gestureItem = [[gestureItemClass alloc] initWithActionItem:actionItem application:self.application atPosition:[NSValue valueWithCGPoint:lastItem.atPosition] offset:chain.durationOffset error:error]; + gestureItem = [[gestureItemClass alloc] initWithActionItem:actionItem + application:self.application + atPosition:lastItem.atPosition + offset:chain.durationOffset + error:error]; } if (nil == gestureItem) { return nil; @@ -527,7 +535,7 @@ - (nullable XCSynthesizedEventRecord *)synthesizeWithError:(NSError **)error BOOL isMultiTouch = [self.actions.firstObject isKindOfClass:NSArray.class]; eventRecord = [[XCSynthesizedEventRecord alloc] initWithName:(isMultiTouch ? @"Multi-Finger Touch Action" : @"Single-Finger Touch Action") - interfaceOrientation:[FBXCTestDaemonsProxy orientationWithApplication:self.application]]; + interfaceOrientation:self.application.interfaceOrientation]; for (NSArray *> *action in (isMultiTouch ? self.actions : @[self.actions])) { NSArray *> *preprocessedAction = [self preprocessAction:action]; NSArray *eventPaths = [self eventPathsWithAction:preprocessedAction error:error]; diff --git a/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.h b/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.h index d50408215..5f779194f 100644 --- a/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.h +++ b/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.h @@ -51,19 +51,10 @@ NS_ASSUME_NONNULL_BEGIN @interface FBBaseGestureItem : FBBaseActionItem /*! Absolute position on the screen where the gesure should be performed */ -@property (nonatomic) CGPoint atPosition; +@property (nonatomic) XCUICoordinate *atPosition; /*! Gesture duration in milliseconds */ @property (nonatomic) double duration; -/** - Returns fixed hit point coordinates for the case when XCTest fails to transform element snaapshot properly on screen rotation. - - @param hitPoint The initial hitpoint coordinates - @param snapshot Element's snapshot instance - @return The fixed hit point coordinates, if there is a need to fix them, or the unchanged hit point value - */ -- (CGPoint)fixedHitPointWith:(CGPoint)hitPoint forSnapshot:(id)snapshot; - /** Calculate absolute gesture position on the screen based on provided element and positionOffset values. @@ -72,9 +63,9 @@ NS_ASSUME_NONNULL_BEGIN @param error If there is an error, upon return contains an NSError object that describes the problem @return Adbsolute gesture position on the screen or nil if the calculation fails (for example, the element is invisible) */ -- (nullable NSValue *)hitpointWithElement:(nullable XCUIElement *)element - positionOffset:(nullable NSValue *)positionOffset - error:(NSError **)error; +- (nullable XCUICoordinate *)hitpointWithElement:(nullable XCUIElement *)element + positionOffset:(nullable NSValue *)positionOffset + error:(NSError **)error; @end diff --git a/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.m b/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.m index 04e492622..6d4c046a5 100644 --- a/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.m +++ b/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.m @@ -31,7 +31,10 @@ + (NSString *)actionName return nil; } -- (NSArray *)addToEventPath:(XCPointerEventPath *)eventPath allItems:(NSArray *)allItems currentItemIndex:(NSUInteger)currentItemIndex error:(NSError **)error +- (NSArray *)addToEventPath:(XCPointerEventPath *)eventPath + allItems:(NSArray *)allItems + currentItemIndex:(NSUInteger)currentItemIndex + error:(NSError **)error { @throw [[FBErrorBuilder.builder withDescription:@"Override this method in subclasses"] build]; return nil; @@ -41,66 +44,40 @@ + (NSString *)actionName @implementation FBBaseGestureItem -- (CGPoint)fixedHitPointWith:(CGPoint)hitPoint forSnapshot:(id)snapshot +- (nullable XCUICoordinate *)hitpointWithElement:(nullable XCUIElement *)element + positionOffset:(nullable NSValue *)positionOffset + error:(NSError **)error { - UIInterfaceOrientation interfaceOrientation = self.application.interfaceOrientation; - if (interfaceOrientation == UIInterfaceOrientationPortrait) { - // There is no need to recalculate anything for portrait orientation - return hitPoint; - } - // For Xcode11+ it is always necessary to adjust the tap point coordinates - return FBInvertPointForApplication(hitPoint, self.application.frame.size, interfaceOrientation); -} - -- (nullable NSValue *)hitpointWithElement:(nullable XCUIElement *)element positionOffset:(nullable NSValue *)positionOffset error:(NSError **)error -{ - CGPoint hitPoint; if (nil == element) { + CGVector offset = CGVectorMake(positionOffset.CGPointValue.x, positionOffset.CGPointValue.y); // Only absolute offset is defined - hitPoint = [positionOffset CGPointValue]; - /* - Since iOS 10.0 XCTest has a bug when it always returns portrait coordinates for UI elements - even if the device is not in portait mode. That is why we need to recalculate them manually - based on the current orientation value - */ - hitPoint = FBInvertPointForApplication(hitPoint, self.application.frame.size, self.application.interfaceOrientation); - } else { - // The offset relative to the element is defined - - id snapshot = element.fb_isResolvedFromCache.boolValue - ? element.lastSnapshot - : element.fb_takeSnapshot; - if (nil == positionOffset) { - NSValue *hitPointValue = [FBXCElementSnapshotWrapper ensureWrapped:snapshot].fb_hitPoint; - if (nil != hitPointValue) { - // short circuit element hitpoint - return hitPointValue; - } - [FBLogger logFmt:@"Will use the frame of '%@' for hit point calculation instead", element.debugDescription]; - } - CGRect visibleFrame = snapshot.visibleFrame; - CGRect frame = CGRectIsEmpty(visibleFrame) ? element.frame : visibleFrame; - if (CGRectIsEmpty(frame)) { - [FBLogger log:self.application.fb_descriptionRepresentation]; - NSString *description = [NSString stringWithFormat:@"The element '%@' is not visible on the screen and thus is not interactable", element.description]; - if (error) { - *error = [[FBErrorBuilder.builder withDescription:description] build]; - } - return nil; + return [[self.application coordinateWithNormalizedOffset:CGVectorMake(0, 0)] coordinateWithOffset:offset]; + } + + // The offset relative to the element is defined + if (nil == positionOffset) { + if (element.hittable) { + // short circuit element hitpoint + return element.hitPointCoordinate; } - if (nil == positionOffset) { - hitPoint = CGPointMake(frame.origin.x + frame.size.width / 2, - frame.origin.y + frame.size.height / 2); - } else { - CGPoint origin = frame.origin; - hitPoint = CGPointMake(origin.x, origin.y); - CGPoint offsetValue = [positionOffset CGPointValue]; - hitPoint = CGPointMake(hitPoint.x + offsetValue.x, hitPoint.y + offsetValue.y); - // TODO: Shall we throw an exception if hitPoint is out of the element frame? + [FBLogger logFmt:@"Will use the frame of '%@' for hit point calculation instead", element.debugDescription]; + } + if (CGRectIsEmpty(element.frame)) { + [FBLogger log:self.application.fb_descriptionRepresentation]; + NSString *description = [NSString stringWithFormat:@"The element '%@' is not visible on the screen and thus is not interactable", + element.description]; + if (error) { + *error = [[FBErrorBuilder.builder withDescription:description] build]; } - hitPoint = [self fixedHitPointWith:hitPoint forSnapshot:snapshot]; + return nil; + } + if (nil == positionOffset) { + return [element coordinateWithNormalizedOffset:CGVectorMake(0.5, 0.5)]; } - return [NSValue valueWithCGPoint:hitPoint]; + + CGVector offset = CGVectorMake(positionOffset.CGPointValue.x, positionOffset.CGPointValue.y); + // TODO: Shall we throw an exception if hitPoint is out of the element frame? + return [[element coordinateWithNormalizedOffset:CGVectorMake(0, 0)] coordinateWithOffset:offset]; } @end @@ -161,7 +138,10 @@ - (void)addItem:(FBBaseActionItem *)item __attribute__((noreturn)) @implementation FBBaseActionsSynthesizer -- (instancetype)initWithActions:(NSArray *)actions forApplication:(XCUIApplication *)application elementCache:(nullable FBElementCache *)elementCache error:(NSError **)error +- (instancetype)initWithActions:(NSArray *)actions + forApplication:(XCUIApplication *)application + elementCache:(nullable FBElementCache *)elementCache + error:(NSError **)error { self = [super init]; if (self) { diff --git a/WebDriverAgentLib/Utilities/FBMathUtils.h b/WebDriverAgentLib/Utilities/FBMathUtils.h index 222a2ef67..2d52d3e6d 100644 --- a/WebDriverAgentLib/Utilities/FBMathUtils.h +++ b/WebDriverAgentLib/Utilities/FBMathUtils.h @@ -32,12 +32,6 @@ BOOL FBSizeFuzzyEqualToSize(CGSize size1, CGSize size2, CGFloat threshold); BOOL FBRectFuzzyEqualToRect(CGRect rect1, CGRect rect2, CGFloat threshold); #if !TARGET_OS_TV -/*! Inverts point if necessary to match location on screen */ -CGPoint FBInvertPointForApplication(CGPoint point, CGSize screenSize, UIInterfaceOrientation orientation); - -/*! Inverts offset if necessary to match screen orientation */ -CGPoint FBInvertOffsetForOrientation(CGPoint offset, UIInterfaceOrientation orientation); - /*! Inverts size if necessary to match current screen orientation */ CGSize FBAdjustDimensionsForApplication(CGSize actualSize, UIInterfaceOrientation orientation); #endif diff --git a/WebDriverAgentLib/Utilities/FBMathUtils.m b/WebDriverAgentLib/Utilities/FBMathUtils.m index 0cff32fcf..44ee257dc 100644 --- a/WebDriverAgentLib/Utilities/FBMathUtils.m +++ b/WebDriverAgentLib/Utilities/FBMathUtils.m @@ -46,35 +46,6 @@ BOOL FBRectFuzzyEqualToRect(CGRect rect1, CGRect rect2, CGFloat threshold) } #if !TARGET_OS_TV -CGPoint FBInvertPointForApplication(CGPoint point, CGSize screenSize, UIInterfaceOrientation orientation) -{ - switch (orientation) { - case UIInterfaceOrientationUnknown: - case UIInterfaceOrientationPortrait: - return point; - case UIInterfaceOrientationPortraitUpsideDown: - return CGPointMake(screenSize.width - point.x, screenSize.height - point.y); - case UIInterfaceOrientationLandscapeLeft: - return CGPointMake(point.y, MAX(screenSize.width, screenSize.height) - point.x); - case UIInterfaceOrientationLandscapeRight: - return CGPointMake(MIN(screenSize.width, screenSize.height) - point.y, point.x); - } -} - -CGPoint FBInvertOffsetForOrientation(CGPoint offset, UIInterfaceOrientation orientation) -{ - switch (orientation) { - case UIInterfaceOrientationUnknown: - case UIInterfaceOrientationPortrait: - return offset; - case UIInterfaceOrientationPortraitUpsideDown: - return CGPointMake(-offset.x, -offset.y); - case UIInterfaceOrientationLandscapeLeft: - return CGPointMake(offset.y, -offset.x); - case UIInterfaceOrientationLandscapeRight: - return CGPointMake(-offset.y, offset.x); - } -} CGSize FBAdjustDimensionsForApplication(CGSize actualSize, UIInterfaceOrientation orientation) { diff --git a/WebDriverAgentLib/Utilities/FBW3CActionsSynthesizer.m b/WebDriverAgentLib/Utilities/FBW3CActionsSynthesizer.m index 6696f26f0..dc5060568 100644 --- a/WebDriverAgentLib/Utilities/FBW3CActionsSynthesizer.m +++ b/WebDriverAgentLib/Utilities/FBW3CActionsSynthesizer.m @@ -133,16 +133,16 @@ - (nullable instancetype)initWithActionItem:(NSDictionary *)acti return nil; } self.duration = durationObj.doubleValue; - NSValue *position = [self positionWithError:error]; + XCUICoordinate *position = [self positionWithError:error]; if (nil == position) { return nil; } - self.atPosition = [position CGPointValue]; + self.atPosition = position; } return self; } -- (nullable NSValue *)positionWithError:(NSError **)error +- (nullable XCUICoordinate *)positionWithError:(NSError **)error { if (nil == self.previousItem) { NSString *errorDescription = [NSString stringWithFormat:@"The '%@' action item must be preceded by %@ item", self.actionItem, FB_ACTION_ITEM_TYPE_POINTER_MOVE]; @@ -151,39 +151,32 @@ - (nullable NSValue *)positionWithError:(NSError **)error } return nil; } - return [NSValue valueWithCGPoint:self.previousItem.atPosition]; + return self.previousItem.atPosition; } -- (nullable NSValue *)hitpointWithElement:(nullable XCUIElement *)element - positionOffset:(nullable NSValue *)positionOffset - error:(NSError **)error +- (nullable XCUICoordinate *)hitpointWithElement:(nullable XCUIElement *)element + positionOffset:(nullable NSValue *)positionOffset + error:(NSError **)error { if (nil == element || nil == positionOffset) { return [super hitpointWithElement:element positionOffset:positionOffset error:error]; } // An offset relative to the element is defined - id snapshot = element.fb_isResolvedFromCache.boolValue - ? element.lastSnapshot - : element.fb_takeSnapshot; - CGRect frame = snapshot.frame; - if (CGRectIsEmpty(frame)) { + if (CGRectIsEmpty(element.frame)) { [FBLogger log:self.application.fb_descriptionRepresentation]; - NSString *description = [NSString stringWithFormat:@"The element '%@' is not visible on the screen and thus is not interactable", [FBXCElementSnapshotWrapper ensureWrapped:snapshot].fb_description]; + NSString *description = [NSString stringWithFormat:@"The element '%@' is not visible on the screen and thus is not interactable", + element.description]; if (error) { *error = [[FBErrorBuilder.builder withDescription:description] build]; } return nil; } - CGRect visibleFrame = snapshot.visibleFrame; - frame = CGRectIsEmpty(visibleFrame) ? frame : visibleFrame; + // W3C standard requires that relative element coordinates start at the center of the element's rectangle - CGPoint hitPoint = CGPointMake(frame.origin.x + frame.size.width / 2, frame.origin.y + frame.size.height / 2); - CGPoint offsetValue = [positionOffset CGPointValue]; - hitPoint = CGPointMake(hitPoint.x + offsetValue.x, hitPoint.y + offsetValue.y); + CGVector offset = CGVectorMake(positionOffset.CGPointValue.x, positionOffset.CGPointValue.y); // TODO: Shall we throw an exception if hitPoint is out of the element frame? - hitPoint = [self fixedHitPointWith:hitPoint forSnapshot:snapshot]; - return [NSValue valueWithCGPoint:hitPoint]; + return [[element coordinateWithNormalizedOffset:CGVectorMake(0.5, 0.5)] coordinateWithOffset:offset]; } @end @@ -220,7 +213,7 @@ + (NSString *)actionName } } if (nil == self.pressure) { - XCPointerEventPath *result = [[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition + XCPointerEventPath *result = [[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition.screenPoint offset:FBMillisToSeconds(self.offset)]; return @[result]; } @@ -247,7 +240,7 @@ + (NSString *)actionName @implementation FBPointerMoveItem -- (nullable NSValue *)positionWithError:(NSError **)error +- (nullable XCUICoordinate *)positionWithError:(NSError **)error { static NSArray *supportedOriginTypes; static dispatch_once_t onceToken; @@ -295,10 +288,9 @@ - (nullable NSValue *)positionWithError:(NSError **)error } return nil; } - CGPoint recentPosition = self.previousItem.atPosition; - CGPoint offsetRelativeToRecentPosition = (nil == x && nil == y) ? CGPointMake(0.0, 0.0) : CGPointMake(x.floatValue, y.floatValue); - offsetRelativeToRecentPosition = FBInvertOffsetForOrientation(offsetRelativeToRecentPosition, self.application.interfaceOrientation); - return [NSValue valueWithCGPoint:CGPointMake(recentPosition.x + offsetRelativeToRecentPosition.x, recentPosition.y + offsetRelativeToRecentPosition.y)]; + XCUICoordinate *recentPosition = self.previousItem.atPosition; + CGVector offsetRelativeToRecentPosition = (nil == x && nil == y) ? CGVectorMake(0, 0) : CGVectorMake(x.floatValue, y.floatValue); + return [recentPosition coordinateWithOffset:offsetRelativeToRecentPosition]; } + (NSString *)actionName @@ -312,9 +304,11 @@ + (NSString *)actionName error:(NSError **)error { if (nil == eventPath) { - return @[[[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition offset:FBMillisToSeconds(self.offset + self.duration)]]; + return @[[[XCPointerEventPath alloc] initForTouchAtPoint:self.atPosition.screenPoint + offset:FBMillisToSeconds(self.offset + self.duration)]]; } - [eventPath moveToPoint:self.atPosition atOffset:FBMillisToSeconds(self.offset + self.duration)]; + [eventPath moveToPoint:self.atPosition.screenPoint + atOffset:FBMillisToSeconds(self.offset + self.duration)]; return @[]; } @@ -888,7 +882,7 @@ - (nullable XCSynthesizedEventRecord *)synthesizeWithError:(NSError **)error { XCSynthesizedEventRecord *eventRecord = [[XCSynthesizedEventRecord alloc] initWithName:@"W3C Touch Action" - interfaceOrientation:[FBXCTestDaemonsProxy orientationWithApplication:self.application]]; + interfaceOrientation:self.application.interfaceOrientation]; NSMutableDictionary *> *actionsMapping = [NSMutableDictionary new]; NSMutableArray *actionIds = [NSMutableArray new]; for (NSDictionary *action in self.actions) { diff --git a/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.h b/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.h index 8c795c5be..307edb40d 100644 --- a/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.h +++ b/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.h @@ -23,10 +23,6 @@ NS_ASSUME_NONNULL_BEGIN + (id)testRunnerProxy; -#if !TARGET_OS_TV -+ (UIInterfaceOrientation)orientationWithApplication:(XCUIApplication *)application; -#endif - + (BOOL)synthesizeEventWithRecord:(XCSynthesizedEventRecord *)record error:(NSError *__autoreleasing*)error; diff --git a/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m b/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m index f6ebcc42c..99b9d8ea9 100644 --- a/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m +++ b/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m @@ -30,7 +30,6 @@ @implementation FBXCTestDaemonsProxy + (void)load { - // XCTRunnerDaemonSession class is only available since Xcode 8.3 dispatch_once(&onceTestRunnerDaemonClass, ^{ FBXCTRunnerDaemonSessionClass = objc_lookUpClass("XCTRunnerDaemonSession"); }); @@ -60,17 +59,6 @@ + (void)load return ((XCTRunnerDaemonSession *)[FBXCTRunnerDaemonSessionClass sharedSession]).daemonProxy; } -#if !TARGET_OS_TV -+ (UIInterfaceOrientation)orientationWithApplication:(XCUIApplication *)application -{ - if (nil == FBXCTRunnerDaemonSessionClass || - [[FBXCTRunnerDaemonSessionClass sharedSession] useLegacyEventCoordinateTransformationPath]) { - return application.interfaceOrientation; - } - return UIInterfaceOrientationPortrait; -} -#endif - + (BOOL)synthesizeEventWithRecord:(XCSynthesizedEventRecord *)record error:(NSError *__autoreleasing*)error { __block BOOL didSucceed = NO; diff --git a/WebDriverAgentTests/IntegrationTests/FBAppiumTouchActionsIntegrationTests.m b/WebDriverAgentTests/IntegrationTests/FBAppiumTouchActionsIntegrationTests.m index 161fc788b..d48b3da77 100644 --- a/WebDriverAgentTests/IntegrationTests/FBAppiumTouchActionsIntegrationTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBAppiumTouchActionsIntegrationTests.m @@ -194,14 +194,6 @@ - (void)testTapByCoordinates - (void)testDoubleTap { - if ([UIDevice.currentDevice userInterfaceIdiom] == UIUserInterfaceIdiomPad && - SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) { - // "tap the element" does not work on iPadOS simulator after change the rotation in iOS 15 - // while selecting the element worked. (I confirmed with getting an element screenshot that - // the FBShowAlertButtonName was actually selected after changing the orientation.) - return; - } - NSArray *> *gesture = @[@{ @"action": @"tap", @@ -214,16 +206,8 @@ - (void)testDoubleTap [self verifyGesture:gesture orientation:UIDeviceOrientationLandscapeLeft]; } -// TODO: UIDeviceOrientationLandscapeRight is not so good in iOS 16? (Especially simulators) - (void)testPress { - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) { - // Does not work on iOS 15.0. - // The same action tap the FBShowAlertButtonName after rotating the screen - // worked with W3C actions. `.click` action did not work. - return; - } - NSArray *> *gesture = @[@{ @"action": @"press", diff --git a/WebDriverAgentTests/IntegrationTests/FBElementScreenshotTests.m b/WebDriverAgentTests/IntegrationTests/FBElementScreenshotTests.m deleted file mode 100644 index 08c6a9bcf..000000000 --- a/WebDriverAgentTests/IntegrationTests/FBElementScreenshotTests.m +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import - -#import "FBMacros.h" -#import "FBIntegrationTestCase.h" -#import "XCUIDevice+FBRotation.h" -#import "XCUIElement+FBUtilities.h" -#import "XCUIScreen.h" - -@interface FBElementScreenshotTests : FBIntegrationTestCase -@end - -@implementation FBElementScreenshotTests - -- (void)setUp -{ - [super setUp]; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - [self launchApplication]; - [self goToAlertsPage]; - }); -} - -- (void)tearDown -{ - [self resetOrientation]; - [super tearDown]; -} - -- (void)testElementScreenshot -{ - [[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:UIDeviceOrientationLandscapeLeft]; - XCUIElement *button = self.testedApplication.buttons[FBShowAlertButtonName]; - NSError *error = nil; - NSData *screenshotData = [button fb_screenshotWithError:&error]; - XCTAssertNotNil(screenshotData); - XCTAssertNil(error); - UIImage *image = [UIImage imageWithData:screenshotData]; - XCTAssertNotNil(image); - XCTAssertTrue(image.size.width > image.size.height); -} - -@end diff --git a/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m b/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m index ceaf3ed9c..8549d3016 100644 --- a/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m @@ -294,18 +294,8 @@ - (void)testTap [self verifyGesture:gesture orientation:UIDeviceOrientationPortrait]; } -// TODO: UIDeviceOrientationLandscapeLeft did not work in iOS 16 simumlator. -// UIDeviceOrientationPortrait was ok. - (void)testDoubleTap { - if ([UIDevice.currentDevice userInterfaceIdiom] == UIUserInterfaceIdiomPad && - SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) { - // "tap the element" does not work on iPadOS simulator after change the rotation in iOS 15 - // while selecting the element worked. (I confirmed with getting an element screenshot that - // the FBShowAlertButtonName was actually selected after changing the orientation.) - return; - } - NSArray *> *gesture = @[@{ @"type": @"pointer", @@ -326,17 +316,8 @@ - (void)testDoubleTap [self verifyGesture:gesture orientation:UIDeviceOrientationLandscapeLeft]; } -// TODO: UIDeviceOrientationLandscapeRight did not work in iOS 16 simumlator. -// UIDeviceOrientationPortrait was ok. - (void)testLongPressWithCombinedPause { - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) { - // Xcode 13 x iOS 14 also does not work while Xcode 12.5 x iOS 14 worked. - // Skip this test for iOS 15 since iOS 15 works with Xcode 13 at least. - return; - } - - NSArray *> *gesture = @[@{ @"type": @"pointer", diff --git a/WebDriverAgentTests/UnitTests/FBMathUtilsTests.m b/WebDriverAgentTests/UnitTests/FBMathUtilsTests.m index d586d8a59..14e71ebe1 100644 --- a/WebDriverAgentTests/UnitTests/FBMathUtilsTests.m +++ b/WebDriverAgentTests/UnitTests/FBMathUtilsTests.m @@ -98,18 +98,6 @@ - (void)testFuzzyEqualRectsSymmetry XCTAssertFalse(FBRectFuzzyEqualToRect(referenceRect, CGRectMake(-1, -1, 1, 1), 1)); } - -- (void)testPointInvertion -{ - const CGPoint testPoint = CGPointMake(1, 2); - const CGSize screenSize = CGSizeMake(10, 15); - const CGFloat t = FBDefaultFrameFuzzyThreshold; - XCTAssertTrue(FBPointFuzzyEqualToPoint(CGPointMake(1, 2), FBInvertPointForApplication(testPoint, screenSize, UIInterfaceOrientationPortrait), t)); - XCTAssertTrue(FBPointFuzzyEqualToPoint(CGPointMake(9, 13), FBInvertPointForApplication(testPoint, screenSize, UIInterfaceOrientationPortraitUpsideDown), t)); - XCTAssertTrue(FBPointFuzzyEqualToPoint(CGPointMake(2, 14), FBInvertPointForApplication(testPoint, screenSize, UIInterfaceOrientationLandscapeLeft), t)); - XCTAssertTrue(FBPointFuzzyEqualToPoint(CGPointMake(8, 1), FBInvertPointForApplication(testPoint, screenSize, UIInterfaceOrientationLandscapeRight), t)); -} - - (void)testSizeInversion { const CGSize screenSizePortrait = CGSizeMake(10, 15); diff --git a/WebDriverAgentTests/UnitTests/XCUICoordinateFix.m b/WebDriverAgentTests/UnitTests/XCUICoordinateFix.m deleted file mode 100644 index 562d1105b..000000000 --- a/WebDriverAgentTests/UnitTests/XCUICoordinateFix.m +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import - -#import "FBMathUtils.h" -#import "XCUICoordinate.h" -#import "XCUICoordinate+FBFix.h" -#import "XCUIElementDouble.h" - -@interface XCUICoordinateFix : XCTestCase -@property (nonatomic, strong, nullable) XCUIElement *mockElement; -@property (nonatomic, strong, nullable) XCUICoordinate *defaultCoordinate; -@end - -@implementation XCUICoordinateFix - -- (void)setUp -{ - [super setUp]; - XCUIElementDouble *element = [XCUIElementDouble new]; - element.frame = CGRectMake(1, 2, 9, 10); - self.mockElement = (XCUIElement *)element; - self.defaultCoordinate = [[XCUICoordinate alloc] initWithElement:self.mockElement normalizedOffset:CGVectorMake(0.0, 0.0)]; -} - -- (void)testCoordinateWithElement -{ - XCUICoordinate *coordinate = [[XCUICoordinate alloc] initWithElement:self.mockElement normalizedOffset:CGVectorMake(0.0, 0.0)]; - XCTAssertTrue(FBPointFuzzyEqualToPoint(coordinate.fb_screenPoint, CGPointMake(1, 2), 0.1)); -} - -- (void)testCoordinateWithElementWithOffset -{ - XCUICoordinate *coordinate = [[XCUICoordinate alloc] initWithElement:self.mockElement normalizedOffset:CGVectorMake(0.5, 0.5)]; - XCTAssertTrue(FBPointFuzzyEqualToPoint(coordinate.fb_screenPoint, CGPointMake(5.5, 7), 0.1)); -} - -- (void)testCoordinateWithCoordinate -{ - XCUICoordinate *coordinate = [[XCUICoordinate alloc] initWithCoordinate:self.defaultCoordinate pointsOffset:CGVectorMake(0, 0)]; - XCTAssertTrue(FBPointFuzzyEqualToPoint(coordinate.fb_screenPoint, CGPointMake(1, 2), 0.1)); -} - -- (void)testCoordinateWithCoordinateWithOffset -{ - XCUICoordinate *coordinate = [[XCUICoordinate alloc] initWithCoordinate:self.defaultCoordinate pointsOffset:CGVectorMake(1, 2)]; - XCTAssertTrue(FBPointFuzzyEqualToPoint(coordinate.fb_screenPoint, CGPointMake(2, 4), 0.1)); -} - -- (void)testCoordinateWithCoordinateWithOffsetOffBounds -{ - XCUICoordinate *coordinate = [[XCUICoordinate alloc] initWithCoordinate:self.defaultCoordinate pointsOffset:CGVectorMake(200, 200)]; - XCTAssertTrue(FBPointFuzzyEqualToPoint(coordinate.fb_screenPoint, CGPointMake(10, 12), 0.1)); -} - -@end From fc76aeecb087429974b7b52b725173186e6f0246 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Sun, 14 May 2023 21:56:15 +0200 Subject: [PATCH 114/240] feat: Add a possibility to provide a target picker value (#699) --- .../Categories/XCUIElement+FBPickerWheel.m | 2 +- .../Commands/FBElementCommands.m | 50 +++++++++++++------ 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBPickerWheel.m b/WebDriverAgentLib/Categories/XCUIElement+FBPickerWheel.m index 5aeed18e6..71ebaf652 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBPickerWheel.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBPickerWheel.m @@ -29,7 +29,6 @@ - (BOOL)fb_scrollWithOffset:(CGFloat)relativeHeightOffset error:(NSError **)erro NSString *previousValue = snapshot.value; XCUICoordinate *startCoord = [self coordinateWithNormalizedOffset:CGVectorMake(0.5, 0.5)]; XCUICoordinate *endCoord = [startCoord coordinateWithOffset:CGVectorMake(0.0, relativeHeightOffset * snapshot.frame.size.height)]; - [endCoord tap]; // If picker value is reflected in its accessiblity id // then fetching of the next snapshot may fail with StaleElementReferenceError // because we bound elements by their accessbility ids by default. @@ -37,6 +36,7 @@ - (BOOL)fb_scrollWithOffset:(CGFloat)relativeHeightOffset error:(NSError **)erro // unique element identifier (UID), so it could be found next time even if its // id is different from the initial one. See https://github.com/appium/appium/issues/17569 XCUIElement *stableInstance = self.fb_stableInstance; + [endCoord tap]; return [[[[FBRunLoopSpinner new] timeout:VALUE_CHANGE_TIMEOUT] timeoutErrorMessage:[NSString stringWithFormat:@"Picker wheel value has not been changed after %@ seconds timeout", @(VALUE_CHANGE_TIMEOUT)]] diff --git a/WebDriverAgentLib/Commands/FBElementCommands.m b/WebDriverAgentLib/Commands/FBElementCommands.m index 6734714c6..004a66cfd 100644 --- a/WebDriverAgentLib/Commands/FBElementCommands.m +++ b/WebDriverAgentLib/Commands/FBElementCommands.m @@ -606,36 +606,54 @@ + (NSArray *)routes #if !TARGET_OS_TV -static const CGFloat DEFAULT_OFFSET = (CGFloat)0.2; +static const CGFloat DEFAULT_PICKER_OFFSET = (CGFloat)0.2; +static const NSInteger DEFAULT_MAX_PICKER_ATTEMPTS = 25; + + (id)handleWheelSelect:(FBRouteRequest *)request { FBElementCache *elementCache = request.session.elementCache; XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]]; if ([element.lastSnapshot elementType] != XCUIElementTypePickerWheel) { - return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:[NSString stringWithFormat:@"The element is expected to be a valid Picker Wheel control. '%@' was given instead", element.wdType] traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]); + NSString *errMsg = [NSString stringWithFormat:@"The element is expected to be a valid Picker Wheel control. '%@' was given instead", element.wdType]; + return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:errMsg + traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]); } NSString* order = [request.arguments[@"order"] lowercaseString]; - CGFloat offset = DEFAULT_OFFSET; + CGFloat offset = DEFAULT_PICKER_OFFSET; if (request.arguments[@"offset"]) { offset = (CGFloat)[request.arguments[@"offset"] doubleValue]; if (offset <= 0.0 || offset > 0.5) { - return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:[NSString stringWithFormat:@"'offset' value is expected to be in range (0.0, 0.5]. '%@' was given instead", request.arguments[@"offset"]] traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]); + NSString *errMsg = [NSString stringWithFormat:@"'offset' value is expected to be in range (0.0, 0.5]. '%@' was given instead", request.arguments[@"offset"]]; + return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:errMsg + traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]); } } - BOOL isSuccessful = false; - NSError *error; - if ([order isEqualToString:@"next"]) { - isSuccessful = [element fb_selectNextOptionWithOffset:offset error:&error]; - } else if ([order isEqualToString:@"previous"]) { - isSuccessful = [element fb_selectPreviousOptionWithOffset:offset error:&error]; - } else { - return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:[NSString stringWithFormat:@"Only 'previous' and 'next' order values are supported. '%@' was given instead", request.arguments[@"order"]] traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]); - } - if (!isSuccessful) { - return FBResponseWithStatus([FBCommandStatus invalidElementStateErrorWithMessage:error.description traceback:nil]); + NSNumber *maxAttempts = request.arguments[@"maxAttempts"] ?: @(DEFAULT_MAX_PICKER_ATTEMPTS); + NSString *expectedValue = request.arguments[@"value"]; + NSInteger attempt = 0; + while (attempt < [maxAttempts integerValue]) { + BOOL isSuccessful = false; + NSError *error; + if ([order isEqualToString:@"next"]) { + isSuccessful = [element fb_selectNextOptionWithOffset:offset error:&error]; + } else if ([order isEqualToString:@"previous"]) { + isSuccessful = [element fb_selectPreviousOptionWithOffset:offset error:&error]; + } else { + NSString *errMsg = [NSString stringWithFormat:@"Only 'previous' and 'next' order values are supported. '%@' was given instead", request.arguments[@"order"]]; + return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:errMsg + traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]); + } + if (!isSuccessful) { + return FBResponseWithStatus([FBCommandStatus invalidElementStateErrorWithMessage:error.description traceback:nil]); + } + if (nil == expectedValue || [element.wdValue isEqualToString:expectedValue]) { + return FBResponseWithOK(); + } + attempt++; } - return FBResponseWithOK(); + NSString *errMsg = [NSString stringWithFormat:@"Cannot select the expected picker wheel value '%@' after %ld attempts", expectedValue, attempt]; + return FBResponseWithStatus([FBCommandStatus invalidElementStateErrorWithMessage:errMsg traceback:nil]); } #pragma mark - Helpers From 656f250f23c8f4b373416fafc896470472ebb61e Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 14 May 2023 20:03:57 +0000 Subject: [PATCH 115/240] chore(release): 5.1.0 [skip ci] ## [5.1.0](https://github.com/appium/WebDriverAgent/compare/v5.0.0...v5.1.0) (2023-05-14) ### Features * Add a possibility to provide a target picker value ([#699](https://github.com/appium/WebDriverAgent/issues/699)) ([fc76aee](https://github.com/appium/WebDriverAgent/commit/fc76aeecb087429974b7b52b725173186e6f0246)) ### Code Refactoring * Remove obsolete coordinate calculation workarounds needed for older xCode SDKs ([#698](https://github.com/appium/WebDriverAgent/issues/698)) ([025b42c](https://github.com/appium/WebDriverAgent/commit/025b42c8a34ff0beba4379f4cb0c1d79d2b222ed)) --- CHANGELOG.md | 12 ++++++++++++ package.json | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1b7cd70d..e3edf36bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## [5.1.0](https://github.com/appium/WebDriverAgent/compare/v5.0.0...v5.1.0) (2023-05-14) + + +### Features + +* Add a possibility to provide a target picker value ([#699](https://github.com/appium/WebDriverAgent/issues/699)) ([fc76aee](https://github.com/appium/WebDriverAgent/commit/fc76aeecb087429974b7b52b725173186e6f0246)) + + +### Code Refactoring + +* Remove obsolete coordinate calculation workarounds needed for older xCode SDKs ([#698](https://github.com/appium/WebDriverAgent/issues/698)) ([025b42c](https://github.com/appium/WebDriverAgent/commit/025b42c8a34ff0beba4379f4cb0c1d79d2b222ed)) + ## [5.0.0](https://github.com/appium/WebDriverAgent/compare/v4.15.1...v5.0.0) (2023-05-14) diff --git a/package.json b/package.json index 0aeff7451..6ab281f68 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.0.0", + "version": "5.1.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 94e5c51bce1d4518418e999b4ac466cd46ca3bc3 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Mon, 15 May 2023 20:30:09 +0200 Subject: [PATCH 116/240] fix: Assert app is installed before launching or activating it (#704) --- WebDriverAgentLib/FBApplication.h | 10 ++++++ WebDriverAgentLib/FBApplication.m | 36 +++++++++++++++++++ .../Routing/FBExceptionHandler.m | 3 +- WebDriverAgentLib/Routing/FBExceptions.h | 3 ++ WebDriverAgentLib/Routing/FBExceptions.m | 1 + .../FBSessionIntegrationTests.m | 29 +++++++++++++++ 6 files changed, 81 insertions(+), 1 deletion(-) diff --git a/WebDriverAgentLib/FBApplication.h b/WebDriverAgentLib/FBApplication.h index 00adb527d..2aaa3d888 100644 --- a/WebDriverAgentLib/FBApplication.h +++ b/WebDriverAgentLib/FBApplication.h @@ -44,6 +44,16 @@ NS_ASSUME_NONNULL_BEGIN */ + (BOOL)fb_switchToSystemApplicationWithError:(NSError **)error; +/** + Returns the bundle indentifier of the system app (ususally Springboard) + */ ++ (NSString *)fb_systemApplicationBundleID; + +/** + Checks if the app is installed on the device under test. + */ +- (BOOL)fb_isInstalled; + @end NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/FBApplication.m b/WebDriverAgentLib/FBApplication.m index 8a9a48ba0..095620118 100644 --- a/WebDriverAgentLib/FBApplication.m +++ b/WebDriverAgentLib/FBApplication.m @@ -9,6 +9,7 @@ #import "FBApplication.h" +#import "FBExceptions.h" #import "FBXCAccessibilityElement.h" #import "FBLogger.h" #import "FBRunLoopSpinner.h" @@ -16,6 +17,7 @@ #import "FBActiveAppDetectionPoint.h" #import "FBXCodeCompatibility.h" #import "FBXCTestDaemonsProxy.h" +#import "LSApplicationWorkspace.h" #import "XCUIApplication.h" #import "XCUIApplication+FBHelpers.h" #import "XCUIApplicationImpl.h" @@ -133,6 +135,16 @@ + (instancetype)fb_systemApplication [[FBXCAXClientProxy.sharedClient systemApplication] processIdentifier]]; } ++ (NSString *)fb_systemApplicationBundleID +{ + static dispatch_once_t onceToken; + static NSString *systemAppBundleID; + dispatch_once(&onceToken, ^{ + systemAppBundleID = [[self.class fb_systemApplication] bundleID]; + }); + return systemAppBundleID; +} + + (instancetype)applicationWithPID:(pid_t)processID { if ([NSProcessInfo processInfo].processIdentifier == processID) { @@ -141,14 +153,33 @@ + (instancetype)applicationWithPID:(pid_t)processID return (FBApplication *)[FBXCAXClientProxy.sharedClient monitoredApplicationWithProcessIdentifier:processID]; } +/** + https://github.com/appium/WebDriverAgent/issues/702 + */ +- (void)fb_assertInstalledByAction:(NSString *)action +{ + if (![self.bundleID isEqualToString:[self.class fb_systemApplicationBundleID]] && !self.fb_isInstalled) { + NSString *message = [NSString stringWithFormat:@"The application '%@' cannot be %@ because it is not installed on the device under test", + self.bundleID, action]; + [[NSException exceptionWithName:FBApplicationMissingException reason:message userInfo:nil] raise]; + } +} + - (void)launch { + [self fb_assertInstalledByAction:@"launched"]; [super launch]; if (![self fb_waitForAppElement:APP_STATE_CHANGE_TIMEOUT]) { [FBLogger logFmt:@"The application '%@' is not running in foreground after %.2f seconds", self.bundleID, APP_STATE_CHANGE_TIMEOUT]; } } +- (void)activate +{ + [self fb_assertInstalledByAction:@"activated"]; + [super activate]; +} + - (void)terminate { [super terminate]; @@ -181,4 +212,9 @@ + (BOOL)fb_switchToSystemApplicationWithError:(NSError **)error error:error]; } +- (BOOL)fb_isInstalled +{ + return [[LSApplicationWorkspace defaultWorkspace] applicationIsInstalled:self.bundleID]; +} + @end diff --git a/WebDriverAgentLib/Routing/FBExceptionHandler.m b/WebDriverAgentLib/Routing/FBExceptionHandler.m index 203fcf0e7..7b7a8263f 100644 --- a/WebDriverAgentLib/Routing/FBExceptionHandler.m +++ b/WebDriverAgentLib/Routing/FBExceptionHandler.m @@ -24,7 +24,8 @@ - (void)handleException:(NSException *)exception forResponse:(RouteResponse *)re commandStatus = [FBCommandStatus noSuchDriverErrorWithMessage:exception.reason traceback:traceback]; } else if ([exception.name isEqualToString:FBInvalidArgumentException] - || [exception.name isEqualToString:FBElementAttributeUnknownException]) { + || [exception.name isEqualToString:FBElementAttributeUnknownException] + || [exception.name isEqualToString:FBApplicationMissingException]) { commandStatus = [FBCommandStatus invalidArgumentErrorWithMessage:exception.reason traceback:traceback]; } else if ([exception.name isEqualToString:FBApplicationCrashedException] diff --git a/WebDriverAgentLib/Routing/FBExceptions.h b/WebDriverAgentLib/Routing/FBExceptions.h index 4cbc3e5c4..1c9507a19 100644 --- a/WebDriverAgentLib/Routing/FBExceptions.h +++ b/WebDriverAgentLib/Routing/FBExceptions.h @@ -49,4 +49,7 @@ extern NSString *const FBClassChainQueryParseException; /*! Exception used to notify about application crash */ extern NSString *const FBApplicationCrashedException; +/*! Exception used to notify about the application is not installed */ +extern NSString *const FBApplicationMissingException; + NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Routing/FBExceptions.m b/WebDriverAgentLib/Routing/FBExceptions.m index 5ff6fed85..571cea4fb 100644 --- a/WebDriverAgentLib/Routing/FBExceptions.m +++ b/WebDriverAgentLib/Routing/FBExceptions.m @@ -20,3 +20,4 @@ NSString *const FBXPathQueryEvaluationException = @"FBXPathQueryEvaluationException"; NSString *const FBClassChainQueryParseException = @"FBClassChainQueryParseException"; NSString *const FBApplicationCrashedException = @"FBApplicationCrashedException"; +NSString *const FBApplicationMissingException = @"FBApplicationMissingException"; diff --git a/WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m b/WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m index dc9a9b1af..655d91b85 100644 --- a/WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m @@ -11,6 +11,7 @@ #import "FBIntegrationTestCase.h" #import "FBApplication.h" +#import "FBExceptions.h" #import "FBMacros.h" #import "FBSession.h" #import "FBXCodeCompatibility.h" @@ -100,6 +101,34 @@ - (void)testMainAppCanBeRestartedInScopeOfTheCurrentSession FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString:testedApp.bundleID]); } +- (void)testAppWithInvalidBundleIDCannotBeStarted +{ + FBApplication *testedApp = [[FBApplication alloc] initWithBundleIdentifier:@"yolo"]; + @try { + [testedApp launch]; + XCTFail(@"An exception is expected to be thrown"); + } @catch (NSException *exception) { + XCTAssertEqualObjects(FBApplicationMissingException, exception.name); + } +} + +- (void)testAppWithInvalidBundleIDCannotBeActivated +{ + FBApplication *testedApp = [[FBApplication alloc] initWithBundleIdentifier:@"yolo"]; + @try { + [testedApp activate]; + XCTFail(@"An exception is expected to be thrown"); + } @catch (NSException *exception) { + XCTAssertEqualObjects(FBApplicationMissingException, exception.name); + } +} + +- (void)testAppWithInvalidBundleIDCannotBeTerminated +{ + FBApplication *testedApp = [[FBApplication alloc] initWithBundleIdentifier:@"yolo"]; + [testedApp terminate]; +} + - (void)testLaunchUnattachedApp { [FBUnattachedAppLauncher launchAppWithBundleId:SETTINGS_BUNDLE_ID]; From ff2f5b50a5e47c435ffde423c5f09018f6f8cb22 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 15 May 2023 18:38:50 +0000 Subject: [PATCH 117/240] chore(release): 5.1.1 [skip ci] ## [5.1.1](https://github.com/appium/WebDriverAgent/compare/v5.1.0...v5.1.1) (2023-05-15) ### Bug Fixes * Assert app is installed before launching or activating it ([#704](https://github.com/appium/WebDriverAgent/issues/704)) ([94e5c51](https://github.com/appium/WebDriverAgent/commit/94e5c51bce1d4518418e999b4ac466cd46ca3bc3)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3edf36bb..570dc461b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.1.1](https://github.com/appium/WebDriverAgent/compare/v5.1.0...v5.1.1) (2023-05-15) + + +### Bug Fixes + +* Assert app is installed before launching or activating it ([#704](https://github.com/appium/WebDriverAgent/issues/704)) ([94e5c51](https://github.com/appium/WebDriverAgent/commit/94e5c51bce1d4518418e999b4ac466cd46ca3bc3)) + ## [5.1.0](https://github.com/appium/WebDriverAgent/compare/v5.0.0...v5.1.0) (2023-05-14) diff --git a/package.json b/package.json index 6ab281f68..e6b387d00 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.1.0", + "version": "5.1.1", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 4a9faa5f85e0615c18a5f35090335bdbc7d56ebe Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Mon, 15 May 2023 14:57:40 -0700 Subject: [PATCH 118/240] chore: remove code for old os versions (#694) --- WebDriverAgentLib/Commands/FBElementCommands.m | 14 ++++++-------- WebDriverAgentLib/Utilities/FBConfiguration.m | 4 +--- .../IntegrationTests/FBAutoAlertsHandlerTests.m | 8 -------- .../IntegrationTests/FBConfigurationTests.m | 6 +----- 4 files changed, 8 insertions(+), 24 deletions(-) diff --git a/WebDriverAgentLib/Commands/FBElementCommands.m b/WebDriverAgentLib/Commands/FBElementCommands.m index 004a66cfd..49c3a0231 100644 --- a/WebDriverAgentLib/Commands/FBElementCommands.m +++ b/WebDriverAgentLib/Commands/FBElementCommands.m @@ -696,14 +696,12 @@ + (XCUICoordinate *)gestureCoordinateWithCoordinate:(CGPoint)coordinate See issue #732: https://github.com/facebook/WebDriverAgent/issues/732 */ XCUIElement *element = application; - if (isSDKVersionGreaterThanOrEqualTo(@"11.0")) { - XCUIElement *window = application.windows.allElementsBoundByIndex.firstObject; - if (window) { - element = window; - id snapshot = element.fb_cachedSnapshot ?: element.fb_takeSnapshot; - point.x -= snapshot.frame.origin.x; - point.y -= snapshot.frame.origin.y; - } + XCUIElement *window = application.windows.allElementsBoundByIndex.firstObject; + if (window) { + element = window; + id snapshot = element.fb_cachedSnapshot ?: element.fb_takeSnapshot; + point.x -= snapshot.frame.origin.x; + point.y -= snapshot.frame.origin.y; } return [self gestureCoordinateWithCoordinate:point element:element]; } diff --git a/WebDriverAgentLib/Utilities/FBConfiguration.m b/WebDriverAgentLib/Utilities/FBConfiguration.m index 59cd5eb9b..1c80e5498 100644 --- a/WebDriverAgentLib/Utilities/FBConfiguration.m +++ b/WebDriverAgentLib/Utilities/FBConfiguration.m @@ -275,9 +275,7 @@ + (void)configureDefaultKeyboardPreferences // To dismiss keyboard tutorial on iOS 11+ (iPad) if ([controller respondsToSelector:@selector(setValue:forPreferenceKey:)]) { - if (isSDKVersionGreaterThanOrEqualTo(@"11.0")) { - [controller setValue:@YES forPreferenceKey:@"DidShowGestureKeyboardIntroduction"]; - } + [controller setValue:@YES forPreferenceKey:@"DidShowGestureKeyboardIntroduction"]; if (isSDKVersionGreaterThanOrEqualTo(@"13.0")) { [controller setValue:@YES forPreferenceKey:@"DidShowContinuousPathIntroduction"]; } diff --git a/WebDriverAgentTests/IntegrationTests/FBAutoAlertsHandlerTests.m b/WebDriverAgentTests/IntegrationTests/FBAutoAlertsHandlerTests.m index f0385c05f..5294fb50c 100644 --- a/WebDriverAgentTests/IntegrationTests/FBAutoAlertsHandlerTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBAutoAlertsHandlerTests.m @@ -49,10 +49,6 @@ - (void)tearDown // The test is flaky on slow Travis CI - (void)disabled_testAutoAcceptingOfAlerts { - if (SYSTEM_VERSION_LESS_THAN(@"11.0")) { - return; - } - self.session = [FBSession initWithApplication:FBApplication.fb_activeApplication defaultAlertAction:@"accept"]; @@ -66,10 +62,6 @@ - (void)disabled_testAutoAcceptingOfAlerts // The test is flaky on slow Travis CI - (void)disabled_testAutoDismissingOfAlerts { - if (SYSTEM_VERSION_LESS_THAN(@"11.0")) { - return; - } - self.session = [FBSession initWithApplication:FBApplication.fb_activeApplication defaultAlertAction:@"dismiss"]; diff --git a/WebDriverAgentTests/IntegrationTests/FBConfigurationTests.m b/WebDriverAgentTests/IntegrationTests/FBConfigurationTests.m index 77aaae14c..ca47cdd74 100644 --- a/WebDriverAgentTests/IntegrationTests/FBConfigurationTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBConfigurationTests.m @@ -33,11 +33,7 @@ - (void)testReduceMotion XCTAssertTrue([FBConfiguration reduceMotionEnabled]); [FBConfiguration setReduceMotionEnabled:defaultReduceMotionEnabled]; - if (isSDKVersionLessThan(@"10.0")) { - XCTAssertFalse([FBConfiguration reduceMotionEnabled]); - } else { - XCTAssertEqual([FBConfiguration reduceMotionEnabled], defaultReduceMotionEnabled); - } + XCTAssertEqual([FBConfiguration reduceMotionEnabled], defaultReduceMotionEnabled); } @end From 8c0677fffca9088890bd5192cc885e82c632cc19 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 15 May 2023 22:06:01 +0000 Subject: [PATCH 119/240] chore(release): 5.1.2 [skip ci] ## [5.1.2](https://github.com/appium/WebDriverAgent/compare/v5.1.1...v5.1.2) (2023-05-15) ### Miscellaneous Chores * remove code for old os versions ([#694](https://github.com/appium/WebDriverAgent/issues/694)) ([4a9faa5](https://github.com/appium/WebDriverAgent/commit/4a9faa5f85e0615c18a5f35090335bdbc7d56ebe)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 570dc461b..af8197117 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.1.2](https://github.com/appium/WebDriverAgent/compare/v5.1.1...v5.1.2) (2023-05-15) + + +### Miscellaneous Chores + +* remove code for old os versions ([#694](https://github.com/appium/WebDriverAgent/issues/694)) ([4a9faa5](https://github.com/appium/WebDriverAgent/commit/4a9faa5f85e0615c18a5f35090335bdbc7d56ebe)) + ## [5.1.1](https://github.com/appium/WebDriverAgent/compare/v5.1.0...v5.1.1) (2023-05-15) diff --git a/package.json b/package.json index e6b387d00..64c01ae07 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.1.1", + "version": "5.1.2", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 00baeb2045b9aac98d27fe2e96cedce0dde5e8be Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Tue, 16 May 2023 04:18:26 -0700 Subject: [PATCH 120/240] fix: Revert "fix: Assert app is installed before launching or activating it (#704)" (#705) This reverts commit 94e5c51bce1d4518418e999b4ac466cd46ca3bc3. --- WebDriverAgentLib/FBApplication.h | 10 ------ WebDriverAgentLib/FBApplication.m | 36 ------------------- .../Routing/FBExceptionHandler.m | 3 +- WebDriverAgentLib/Routing/FBExceptions.h | 3 -- WebDriverAgentLib/Routing/FBExceptions.m | 1 - .../FBSessionIntegrationTests.m | 29 --------------- 6 files changed, 1 insertion(+), 81 deletions(-) diff --git a/WebDriverAgentLib/FBApplication.h b/WebDriverAgentLib/FBApplication.h index 2aaa3d888..00adb527d 100644 --- a/WebDriverAgentLib/FBApplication.h +++ b/WebDriverAgentLib/FBApplication.h @@ -44,16 +44,6 @@ NS_ASSUME_NONNULL_BEGIN */ + (BOOL)fb_switchToSystemApplicationWithError:(NSError **)error; -/** - Returns the bundle indentifier of the system app (ususally Springboard) - */ -+ (NSString *)fb_systemApplicationBundleID; - -/** - Checks if the app is installed on the device under test. - */ -- (BOOL)fb_isInstalled; - @end NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/FBApplication.m b/WebDriverAgentLib/FBApplication.m index 095620118..8a9a48ba0 100644 --- a/WebDriverAgentLib/FBApplication.m +++ b/WebDriverAgentLib/FBApplication.m @@ -9,7 +9,6 @@ #import "FBApplication.h" -#import "FBExceptions.h" #import "FBXCAccessibilityElement.h" #import "FBLogger.h" #import "FBRunLoopSpinner.h" @@ -17,7 +16,6 @@ #import "FBActiveAppDetectionPoint.h" #import "FBXCodeCompatibility.h" #import "FBXCTestDaemonsProxy.h" -#import "LSApplicationWorkspace.h" #import "XCUIApplication.h" #import "XCUIApplication+FBHelpers.h" #import "XCUIApplicationImpl.h" @@ -135,16 +133,6 @@ + (instancetype)fb_systemApplication [[FBXCAXClientProxy.sharedClient systemApplication] processIdentifier]]; } -+ (NSString *)fb_systemApplicationBundleID -{ - static dispatch_once_t onceToken; - static NSString *systemAppBundleID; - dispatch_once(&onceToken, ^{ - systemAppBundleID = [[self.class fb_systemApplication] bundleID]; - }); - return systemAppBundleID; -} - + (instancetype)applicationWithPID:(pid_t)processID { if ([NSProcessInfo processInfo].processIdentifier == processID) { @@ -153,33 +141,14 @@ + (instancetype)applicationWithPID:(pid_t)processID return (FBApplication *)[FBXCAXClientProxy.sharedClient monitoredApplicationWithProcessIdentifier:processID]; } -/** - https://github.com/appium/WebDriverAgent/issues/702 - */ -- (void)fb_assertInstalledByAction:(NSString *)action -{ - if (![self.bundleID isEqualToString:[self.class fb_systemApplicationBundleID]] && !self.fb_isInstalled) { - NSString *message = [NSString stringWithFormat:@"The application '%@' cannot be %@ because it is not installed on the device under test", - self.bundleID, action]; - [[NSException exceptionWithName:FBApplicationMissingException reason:message userInfo:nil] raise]; - } -} - - (void)launch { - [self fb_assertInstalledByAction:@"launched"]; [super launch]; if (![self fb_waitForAppElement:APP_STATE_CHANGE_TIMEOUT]) { [FBLogger logFmt:@"The application '%@' is not running in foreground after %.2f seconds", self.bundleID, APP_STATE_CHANGE_TIMEOUT]; } } -- (void)activate -{ - [self fb_assertInstalledByAction:@"activated"]; - [super activate]; -} - - (void)terminate { [super terminate]; @@ -212,9 +181,4 @@ + (BOOL)fb_switchToSystemApplicationWithError:(NSError **)error error:error]; } -- (BOOL)fb_isInstalled -{ - return [[LSApplicationWorkspace defaultWorkspace] applicationIsInstalled:self.bundleID]; -} - @end diff --git a/WebDriverAgentLib/Routing/FBExceptionHandler.m b/WebDriverAgentLib/Routing/FBExceptionHandler.m index 7b7a8263f..203fcf0e7 100644 --- a/WebDriverAgentLib/Routing/FBExceptionHandler.m +++ b/WebDriverAgentLib/Routing/FBExceptionHandler.m @@ -24,8 +24,7 @@ - (void)handleException:(NSException *)exception forResponse:(RouteResponse *)re commandStatus = [FBCommandStatus noSuchDriverErrorWithMessage:exception.reason traceback:traceback]; } else if ([exception.name isEqualToString:FBInvalidArgumentException] - || [exception.name isEqualToString:FBElementAttributeUnknownException] - || [exception.name isEqualToString:FBApplicationMissingException]) { + || [exception.name isEqualToString:FBElementAttributeUnknownException]) { commandStatus = [FBCommandStatus invalidArgumentErrorWithMessage:exception.reason traceback:traceback]; } else if ([exception.name isEqualToString:FBApplicationCrashedException] diff --git a/WebDriverAgentLib/Routing/FBExceptions.h b/WebDriverAgentLib/Routing/FBExceptions.h index 1c9507a19..4cbc3e5c4 100644 --- a/WebDriverAgentLib/Routing/FBExceptions.h +++ b/WebDriverAgentLib/Routing/FBExceptions.h @@ -49,7 +49,4 @@ extern NSString *const FBClassChainQueryParseException; /*! Exception used to notify about application crash */ extern NSString *const FBApplicationCrashedException; -/*! Exception used to notify about the application is not installed */ -extern NSString *const FBApplicationMissingException; - NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Routing/FBExceptions.m b/WebDriverAgentLib/Routing/FBExceptions.m index 571cea4fb..5ff6fed85 100644 --- a/WebDriverAgentLib/Routing/FBExceptions.m +++ b/WebDriverAgentLib/Routing/FBExceptions.m @@ -20,4 +20,3 @@ NSString *const FBXPathQueryEvaluationException = @"FBXPathQueryEvaluationException"; NSString *const FBClassChainQueryParseException = @"FBClassChainQueryParseException"; NSString *const FBApplicationCrashedException = @"FBApplicationCrashedException"; -NSString *const FBApplicationMissingException = @"FBApplicationMissingException"; diff --git a/WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m b/WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m index 655d91b85..dc9a9b1af 100644 --- a/WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m @@ -11,7 +11,6 @@ #import "FBIntegrationTestCase.h" #import "FBApplication.h" -#import "FBExceptions.h" #import "FBMacros.h" #import "FBSession.h" #import "FBXCodeCompatibility.h" @@ -101,34 +100,6 @@ - (void)testMainAppCanBeRestartedInScopeOfTheCurrentSession FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString:testedApp.bundleID]); } -- (void)testAppWithInvalidBundleIDCannotBeStarted -{ - FBApplication *testedApp = [[FBApplication alloc] initWithBundleIdentifier:@"yolo"]; - @try { - [testedApp launch]; - XCTFail(@"An exception is expected to be thrown"); - } @catch (NSException *exception) { - XCTAssertEqualObjects(FBApplicationMissingException, exception.name); - } -} - -- (void)testAppWithInvalidBundleIDCannotBeActivated -{ - FBApplication *testedApp = [[FBApplication alloc] initWithBundleIdentifier:@"yolo"]; - @try { - [testedApp activate]; - XCTFail(@"An exception is expected to be thrown"); - } @catch (NSException *exception) { - XCTAssertEqualObjects(FBApplicationMissingException, exception.name); - } -} - -- (void)testAppWithInvalidBundleIDCannotBeTerminated -{ - FBApplication *testedApp = [[FBApplication alloc] initWithBundleIdentifier:@"yolo"]; - [testedApp terminate]; -} - - (void)testLaunchUnattachedApp { [FBUnattachedAppLauncher launchAppWithBundleId:SETTINGS_BUNDLE_ID]; From f46e86f1049dac80059a8c8c5dfb37b82dd61688 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 16 May 2023 11:27:06 +0000 Subject: [PATCH 121/240] chore(release): 5.1.3 [skip ci] ## [5.1.3](https://github.com/appium/WebDriverAgent/compare/v5.1.2...v5.1.3) (2023-05-16) ### Bug Fixes * Revert "fix: Assert app is installed before launching or activating it ([#704](https://github.com/appium/WebDriverAgent/issues/704))" ([#705](https://github.com/appium/WebDriverAgent/issues/705)) ([00baeb2](https://github.com/appium/WebDriverAgent/commit/00baeb2045b9aac98d27fe2e96cedce0dde5e8be)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af8197117..a5d6cbd33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.1.3](https://github.com/appium/WebDriverAgent/compare/v5.1.2...v5.1.3) (2023-05-16) + + +### Bug Fixes + +* Revert "fix: Assert app is installed before launching or activating it ([#704](https://github.com/appium/WebDriverAgent/issues/704))" ([#705](https://github.com/appium/WebDriverAgent/issues/705)) ([00baeb2](https://github.com/appium/WebDriverAgent/commit/00baeb2045b9aac98d27fe2e96cedce0dde5e8be)) + ## [5.1.2](https://github.com/appium/WebDriverAgent/compare/v5.1.1...v5.1.2) (2023-05-15) diff --git a/package.json b/package.json index 64c01ae07..bf837980d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.1.2", + "version": "5.1.3", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From c4976e3e99afa4d471bd39c3dccfc7d9f58d8bfc Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Tue, 16 May 2023 20:45:30 +0200 Subject: [PATCH 122/240] fix: Prevent freeze on launch/activate of a missing app (#706) --- .../XCTest/XCTRunnerDaemonSession.h | 7 ++ .../Routing/FBExceptionHandler.m | 3 +- WebDriverAgentLib/Routing/FBExceptions.h | 3 + WebDriverAgentLib/Routing/FBExceptions.m | 1 + .../Utilities/FBXCTestDaemonsProxy.m | 81 +++++++++++++------ .../FBSessionIntegrationTests.m | 23 ++++++ 6 files changed, 94 insertions(+), 24 deletions(-) diff --git a/PrivateHeaders/XCTest/XCTRunnerDaemonSession.h b/PrivateHeaders/XCTest/XCTRunnerDaemonSession.h index 1afedbbef..7473b2e0a 100644 --- a/PrivateHeaders/XCTest/XCTRunnerDaemonSession.h +++ b/PrivateHeaders/XCTest/XCTRunnerDaemonSession.h @@ -80,4 +80,11 @@ @property(readonly) _Bool supportsLocationSimulation; #endif +// Since Xcode 10.2 +- (void)launchApplicationWithPath:(NSString *)arg1 + bundleID:(NSString *)arg2 + arguments:(NSArray *)arg3 + environment:(NSDictionary *)arg4 + completion:(void (^)(_Bool, NSError *))arg5; + @end diff --git a/WebDriverAgentLib/Routing/FBExceptionHandler.m b/WebDriverAgentLib/Routing/FBExceptionHandler.m index 203fcf0e7..7b7a8263f 100644 --- a/WebDriverAgentLib/Routing/FBExceptionHandler.m +++ b/WebDriverAgentLib/Routing/FBExceptionHandler.m @@ -24,7 +24,8 @@ - (void)handleException:(NSException *)exception forResponse:(RouteResponse *)re commandStatus = [FBCommandStatus noSuchDriverErrorWithMessage:exception.reason traceback:traceback]; } else if ([exception.name isEqualToString:FBInvalidArgumentException] - || [exception.name isEqualToString:FBElementAttributeUnknownException]) { + || [exception.name isEqualToString:FBElementAttributeUnknownException] + || [exception.name isEqualToString:FBApplicationMissingException]) { commandStatus = [FBCommandStatus invalidArgumentErrorWithMessage:exception.reason traceback:traceback]; } else if ([exception.name isEqualToString:FBApplicationCrashedException] diff --git a/WebDriverAgentLib/Routing/FBExceptions.h b/WebDriverAgentLib/Routing/FBExceptions.h index 4cbc3e5c4..1c9507a19 100644 --- a/WebDriverAgentLib/Routing/FBExceptions.h +++ b/WebDriverAgentLib/Routing/FBExceptions.h @@ -49,4 +49,7 @@ extern NSString *const FBClassChainQueryParseException; /*! Exception used to notify about application crash */ extern NSString *const FBApplicationCrashedException; +/*! Exception used to notify about the application is not installed */ +extern NSString *const FBApplicationMissingException; + NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Routing/FBExceptions.m b/WebDriverAgentLib/Routing/FBExceptions.m index 5ff6fed85..571cea4fb 100644 --- a/WebDriverAgentLib/Routing/FBExceptions.m +++ b/WebDriverAgentLib/Routing/FBExceptions.m @@ -20,3 +20,4 @@ NSString *const FBXPathQueryEvaluationException = @"FBXPathQueryEvaluationException"; NSString *const FBClassChainQueryParseException = @"FBClassChainQueryParseException"; NSString *const FBApplicationCrashedException = @"FBApplicationCrashedException"; +NSString *const FBApplicationMissingException = @"FBApplicationMissingException"; diff --git a/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m b/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m index 99b9d8ea9..2bee1b96c 100644 --- a/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m +++ b/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m @@ -13,6 +13,7 @@ #import "FBConfiguration.h" #import "FBErrorBuilder.h" +#import "FBExceptions.h" #import "FBLogger.h" #import "FBRunLoopSpinner.h" #import "XCTestDriver.h" @@ -20,23 +21,61 @@ #import "XCUIApplication.h" #import "XCUIDevice.h" -@implementation FBXCTestDaemonsProxy +#define LAUNCH_APP_TIMEOUT_SEC 300 + +static void (*originalLaunchAppMethod)(id, SEL, NSString*, NSString*, NSArray*, NSDictionary*, void (^)(_Bool, NSError *)); -static Class FBXCTRunnerDaemonSessionClass = nil; -static dispatch_once_t onceTestRunnerDaemonClass; +static void swizzledLaunchApp(id self, SEL _cmd, NSString *path, NSString *bundleID, + NSArray *arguments, NSDictionary *environment, + void (^reply)(_Bool, NSError *)) +{ + __block BOOL isSuccessful; + __block NSError *error; + dispatch_semaphore_t sem = dispatch_semaphore_create(0); + originalLaunchAppMethod(self, _cmd, path, bundleID, arguments, environment, ^(BOOL passed, NSError *innerError) { + isSuccessful = passed; + error = innerError; + dispatch_semaphore_signal(sem); + }); + int64_t timeoutNs = (int64_t)(LAUNCH_APP_TIMEOUT_SEC * NSEC_PER_SEC); + if (0 != dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, timeoutNs))) { + NSString *message = [NSString stringWithFormat:@"The application '%@' cannot be launched within %d seconds timeout", + bundleID ?: path, LAUNCH_APP_TIMEOUT_SEC]; + @throw [NSException exceptionWithName:FBTimeoutException reason:message userInfo:nil]; + } + if (!isSuccessful || nil != error) { + [FBLogger logFmt:@"%@", error.description]; + NSString *message = error.description ?: [NSString stringWithFormat:@"The application '%@' is not installed on the device under test", + bundleID ?: path]; + @throw [NSException exceptionWithName:FBApplicationMissingException reason:message userInfo:nil]; + } + reply(isSuccessful, error); +} + +@implementation FBXCTestDaemonsProxy #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-load-method" + (void)load { - dispatch_once(&onceTestRunnerDaemonClass, ^{ - FBXCTRunnerDaemonSessionClass = objc_lookUpClass("XCTRunnerDaemonSession"); - }); + [self.class swizzleLaunchApp]; } #pragma clang diagnostic pop ++ (void)swizzleLaunchApp { + Method original = class_getInstanceMethod([XCTRunnerDaemonSession class], + @selector(launchApplicationWithPath:bundleID:arguments:environment:completion:)); + if (original == nil) { + [FBLogger log:@"Could not find method -[XCTRunnerDaemonSession launchApplicationWithPath:]"]; + return; + } + // Workaround for https://github.com/appium/WebDriverAgent/issues/702 + originalLaunchAppMethod = (void(*)(id, SEL, NSString*, NSString*, NSArray*, NSDictionary*, void (^)(_Bool, NSError *))) method_getImplementation(original); + method_setImplementation(original, (IMP)swizzledLaunchApp); +} + + (id)testRunnerProxy { static id proxy = nil; @@ -56,7 +95,7 @@ + (void)load + (id)retrieveTestRunnerProxy { - return ((XCTRunnerDaemonSession *)[FBXCTRunnerDaemonSessionClass sharedSession]).daemonProxy; + return ((XCTRunnerDaemonSession *)[XCTRunnerDaemonSession sharedSession]).daemonProxy; } + (BOOL)synthesizeEventWithRecord:(XCSynthesizedEventRecord *)record error:(NSError *__autoreleasing*)error @@ -70,24 +109,20 @@ + (BOOL)synthesizeEventWithRecord:(XCSynthesizedEventRecord *)record error:(NSEr didSucceed = (invokeError == nil); completion(); }; - - if (nil == FBXCTRunnerDaemonSessionClass) { - [[self testRunnerProxy] _XCT_synthesizeEvent:record completion:errorHandler]; - } else { - XCEventGeneratorHandler handlerBlock = ^(XCSynthesizedEventRecord *innerRecord, NSError *invokeError) { - errorHandler(invokeError); - }; - [[XCUIDevice.sharedDevice eventSynthesizer] synthesizeEvent:record completion:(id)^(BOOL result, NSError *invokeError) { - handlerBlock(record, invokeError); - }]; - } + + XCEventGeneratorHandler handlerBlock = ^(XCSynthesizedEventRecord *innerRecord, NSError *invokeError) { + errorHandler(invokeError); + }; + [[XCUIDevice.sharedDevice eventSynthesizer] synthesizeEvent:record completion:(id)^(BOOL result, NSError *invokeError) { + handlerBlock(record, invokeError); + }]; }]; return didSucceed; } + (BOOL)openURL:(NSURL *)url usingApplication:(NSString *)bundleId error:(NSError *__autoreleasing*)error { - XCTRunnerDaemonSession *session = [FBXCTRunnerDaemonSessionClass sharedSession]; + XCTRunnerDaemonSession *session = [XCTRunnerDaemonSession sharedSession]; if (![session respondsToSelector:@selector(openURL:usingApplication:completion:)]) { if (error) { [[[FBErrorBuilder builder] @@ -112,7 +147,7 @@ + (BOOL)openURL:(NSURL *)url usingApplication:(NSString *)bundleId error:(NSErro + (BOOL)openDefaultApplicationForURL:(NSURL *)url error:(NSError *__autoreleasing*)error { - XCTRunnerDaemonSession *session = [FBXCTRunnerDaemonSessionClass sharedSession]; + XCTRunnerDaemonSession *session = [XCTRunnerDaemonSession sharedSession]; if (![session respondsToSelector:@selector(openDefaultApplicationForURL:completion:)]) { if (error) { [[[FBErrorBuilder builder] @@ -138,7 +173,7 @@ + (BOOL)openDefaultApplicationForURL:(NSURL *)url error:(NSError *__autoreleasin #if !TARGET_OS_TV + (BOOL)setSimulatedLocation:(CLLocation *)location error:(NSError *__autoreleasing*)error { - XCTRunnerDaemonSession *session = [FBXCTRunnerDaemonSessionClass sharedSession]; + XCTRunnerDaemonSession *session = [XCTRunnerDaemonSession sharedSession]; if (![session respondsToSelector:@selector(setSimulatedLocation:completion:)]) { if (error) { [[[FBErrorBuilder builder] @@ -171,7 +206,7 @@ + (BOOL)setSimulatedLocation:(CLLocation *)location error:(NSError *__autoreleas + (nullable CLLocation *)getSimulatedLocation:(NSError *__autoreleasing*)error; { - XCTRunnerDaemonSession *session = [FBXCTRunnerDaemonSessionClass sharedSession]; + XCTRunnerDaemonSession *session = [XCTRunnerDaemonSession sharedSession]; if (![session respondsToSelector:@selector(getSimulatedLocationWithReply:)]) { if (error) { [[[FBErrorBuilder builder] @@ -206,7 +241,7 @@ + (nullable CLLocation *)getSimulatedLocation:(NSError *__autoreleasing*)error; + (BOOL)clearSimulatedLocation:(NSError *__autoreleasing*)error { - XCTRunnerDaemonSession *session = [FBXCTRunnerDaemonSessionClass sharedSession]; + XCTRunnerDaemonSession *session = [XCTRunnerDaemonSession sharedSession]; if (![session respondsToSelector:@selector(clearSimulatedLocationWithReply:)]) { if (error) { [[[FBErrorBuilder builder] diff --git a/WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m b/WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m index dc9a9b1af..ea9fb4cfe 100644 --- a/WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m @@ -11,6 +11,7 @@ #import "FBIntegrationTestCase.h" #import "FBApplication.h" +#import "FBExceptions.h" #import "FBMacros.h" #import "FBSession.h" #import "FBXCodeCompatibility.h" @@ -107,4 +108,26 @@ - (void)testLaunchUnattachedApp XCTAssertEqualObjects(SETTINGS_BUNDLE_ID, FBApplication.fb_activeApplication.bundleID); } +- (void)testAppWithInvalidBundleIDCannotBeStarted +{ + FBApplication *testedApp = [[FBApplication alloc] initWithBundleIdentifier:@"yolo"]; + @try { + [testedApp launch]; + XCTFail(@"An exception is expected to be thrown"); + } @catch (NSException *exception) { + XCTAssertEqualObjects(FBApplicationMissingException, exception.name); + } +} + +- (void)testAppWithInvalidBundleIDCannotBeActivated +{ + FBApplication *testedApp = [[FBApplication alloc] initWithBundleIdentifier:@"yolo"]; + @try { + [testedApp activate]; + XCTFail(@"An exception is expected to be thrown"); + } @catch (NSException *exception) { + XCTAssertEqualObjects(FBApplicationMissingException, exception.name); + } +} + @end From 0bd9ae2e57e34bebbf9db6df30ff672f50c99485 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 16 May 2023 18:58:43 +0000 Subject: [PATCH 123/240] chore(release): 5.1.4 [skip ci] ## [5.1.4](https://github.com/appium/WebDriverAgent/compare/v5.1.3...v5.1.4) (2023-05-16) ### Bug Fixes * Prevent freeze on launch/activate of a missing app ([#706](https://github.com/appium/WebDriverAgent/issues/706)) ([c4976e3](https://github.com/appium/WebDriverAgent/commit/c4976e3e99afa4d471bd39c3dccfc7d9f58d8bfc)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5d6cbd33..bf2c328b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.1.4](https://github.com/appium/WebDriverAgent/compare/v5.1.3...v5.1.4) (2023-05-16) + + +### Bug Fixes + +* Prevent freeze on launch/activate of a missing app ([#706](https://github.com/appium/WebDriverAgent/issues/706)) ([c4976e3](https://github.com/appium/WebDriverAgent/commit/c4976e3e99afa4d471bd39c3dccfc7d9f58d8bfc)) + ## [5.1.3](https://github.com/appium/WebDriverAgent/compare/v5.1.2...v5.1.3) (2023-05-16) diff --git a/package.json b/package.json index bf837980d..90c318a34 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.1.3", + "version": "5.1.4", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 259f7319305b15a3f541957d3ccaa3cb12c9e1a3 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 18 May 2023 09:25:41 +0200 Subject: [PATCH 124/240] chore: Drop obsolete workarounds for coordinates calculation (#701) --- WebDriverAgent.xcodeproj/project.pbxproj | 12 -- .../Categories/XCUIApplication+FBHelpers.m | 4 +- .../Categories/XCUIElement+FBForceTouch.m | 8 +- .../Categories/XCUIElement+FBTap.h | 35 ----- .../Categories/XCUIElement+FBTap.m | 32 ----- .../Categories/XCUIElement+FBTyping.m | 3 +- .../Commands/FBElementCommands.m | 135 ++++++------------ WebDriverAgentLib/FBAlert.m | 24 ++-- WebDriverAgentLib/WebDriverAgentLib.h | 1 - .../IntegrationTests/FBAlertTests.m | 5 +- .../FBAutoAlertsHandlerTests.m | 4 +- .../FBElementAttributeTests.m | 2 +- .../IntegrationTests/FBTapTest.m | 17 +-- 13 files changed, 77 insertions(+), 205 deletions(-) delete mode 100644 WebDriverAgentLib/Categories/XCUIElement+FBTap.h delete mode 100644 WebDriverAgentLib/Categories/XCUIElement+FBTap.m diff --git a/WebDriverAgent.xcodeproj/project.pbxproj b/WebDriverAgent.xcodeproj/project.pbxproj index b719df35b..eafb306ad 100644 --- a/WebDriverAgent.xcodeproj/project.pbxproj +++ b/WebDriverAgent.xcodeproj/project.pbxproj @@ -112,7 +112,6 @@ 641EE6222240C5CA00173FCB /* FBApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9AB7671CAEDF0C008C271F /* FBApplication.m */; }; 641EE6232240C5CA00173FCB /* FBScreen.m in Sources */ = {isa = PBXBuildFile; fileRef = 715AFAC01FFA29180053896D /* FBScreen.m */; }; 641EE6242240C5CA00173FCB /* FBXCTestDaemonsProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = EE35AD7A1E3B80C000A02D78 /* FBXCTestDaemonsProxy.m */; }; - 641EE6252240C5CA00173FCB /* XCUIElement+FBTap.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9AB74C1CAEDF0C008C271F /* XCUIElement+FBTap.m */; }; 641EE6262240C5CA00173FCB /* FBMathUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = EE1888391DA661C400307AA8 /* FBMathUtils.m */; }; 641EE6272240C5CA00173FCB /* FBXCAXClientProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7157B290221DADD2001C348C /* FBXCAXClientProxy.m */; }; 641EE6312240C5CA00173FCB /* XCUIElement+FBWebDriverAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = EEE376471D59FAE900ED88DD /* XCUIElement+FBWebDriverAttributes.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -161,7 +160,6 @@ 641EE65D2240C5CA00173FCB /* XCTRunnerAutomationSession.h in Headers */ = {isa = PBXBuildFile; fileRef = EE35ACEE1E3B77D600A02D78 /* XCTRunnerAutomationSession.h */; settings = {ATTRIBUTES = (Public, ); }; }; 641EE65F2240C5CA00173FCB /* XCSourceCodeTreeNodeEnumerator.h in Headers */ = {isa = PBXBuildFile; fileRef = EE35ACC61E3B77D600A02D78 /* XCSourceCodeTreeNodeEnumerator.h */; settings = {ATTRIBUTES = (Public, ); }; }; 641EE6602240C5CA00173FCB /* XCUIElement+FBIsVisible.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9AB7471CAEDF0C008C271F /* XCUIElement+FBIsVisible.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 641EE6612240C5CA00173FCB /* XCUIElement+FBTap.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9AB74B1CAEDF0C008C271F /* XCUIElement+FBTap.h */; settings = {ATTRIBUTES = (Public, ); }; }; 641EE6622240C5CA00173FCB /* FBResponsePayload.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9AB7821CAEDF0C008C271F /* FBResponsePayload.h */; settings = {ATTRIBUTES = (Public, ); }; }; 641EE6632240C5CA00173FCB /* FBUnknownCommands.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9AB7641CAEDF0C008C271F /* FBUnknownCommands.h */; }; 641EE6642240C5CA00173FCB /* NSPredicate+FBFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 71A224E31DE2F56600844D55 /* NSPredicate+FBFormat.h */; }; @@ -571,8 +569,6 @@ EE158AB11CBD456F00A3E3F0 /* XCUIElement+FBIsVisible.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9AB7481CAEDF0C008C271F /* XCUIElement+FBIsVisible.m */; }; EE158AB21CBD456F00A3E3F0 /* XCUIElement+FBScrolling.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9AB7491CAEDF0C008C271F /* XCUIElement+FBScrolling.h */; settings = {ATTRIBUTES = (Public, ); }; }; EE158AB31CBD456F00A3E3F0 /* XCUIElement+FBScrolling.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9AB74A1CAEDF0C008C271F /* XCUIElement+FBScrolling.m */; }; - EE158AB41CBD456F00A3E3F0 /* XCUIElement+FBTap.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9AB74B1CAEDF0C008C271F /* XCUIElement+FBTap.h */; settings = {ATTRIBUTES = (Public, ); }; }; - EE158AB51CBD456F00A3E3F0 /* XCUIElement+FBTap.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9AB74C1CAEDF0C008C271F /* XCUIElement+FBTap.m */; }; EE158AB81CBD456F00A3E3F0 /* FBAlertViewCommands.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9AB7501CAEDF0C008C271F /* FBAlertViewCommands.h */; }; EE158AB91CBD456F00A3E3F0 /* FBAlertViewCommands.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9AB7511CAEDF0C008C271F /* FBAlertViewCommands.m */; }; EE158ABA1CBD456F00A3E3F0 /* FBCustomCommands.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9AB7521CAEDF0C008C271F /* FBCustomCommands.h */; }; @@ -1272,8 +1268,6 @@ EE9AB7481CAEDF0C008C271F /* XCUIElement+FBIsVisible.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "XCUIElement+FBIsVisible.m"; sourceTree = ""; }; EE9AB7491CAEDF0C008C271F /* XCUIElement+FBScrolling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "XCUIElement+FBScrolling.h"; sourceTree = ""; }; EE9AB74A1CAEDF0C008C271F /* XCUIElement+FBScrolling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "XCUIElement+FBScrolling.m"; sourceTree = ""; }; - EE9AB74B1CAEDF0C008C271F /* XCUIElement+FBTap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "XCUIElement+FBTap.h"; sourceTree = ""; }; - EE9AB74C1CAEDF0C008C271F /* XCUIElement+FBTap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "XCUIElement+FBTap.m"; sourceTree = ""; }; EE9AB7501CAEDF0C008C271F /* FBAlertViewCommands.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBAlertViewCommands.h; sourceTree = ""; }; EE9AB7511CAEDF0C008C271F /* FBAlertViewCommands.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBAlertViewCommands.m; sourceTree = ""; }; EE9AB7521CAEDF0C008C271F /* FBCustomCommands.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBCustomCommands.h; sourceTree = ""; }; @@ -1757,8 +1751,6 @@ EE9AB74A1CAEDF0C008C271F /* XCUIElement+FBScrolling.m */, 71F5BE21252E576C00EE9EBA /* XCUIElement+FBSwiping.h */, 71F5BE22252E576C00EE9EBA /* XCUIElement+FBSwiping.m */, - EE9AB74B1CAEDF0C008C271F /* XCUIElement+FBTap.h */, - EE9AB74C1CAEDF0C008C271F /* XCUIElement+FBTap.m */, AD76723B1D6B7CC000610457 /* XCUIElement+FBTyping.h */, AD76723C1D6B7CC000610457 /* XCUIElement+FBTyping.m */, 71B49EC51ED1A58100D51AD6 /* XCUIElement+FBUID.h */, @@ -2299,7 +2291,6 @@ 641EE65D2240C5CA00173FCB /* XCTRunnerAutomationSession.h in Headers */, 641EE65F2240C5CA00173FCB /* XCSourceCodeTreeNodeEnumerator.h in Headers */, 641EE6602240C5CA00173FCB /* XCUIElement+FBIsVisible.h in Headers */, - 641EE6612240C5CA00173FCB /* XCUIElement+FBTap.h in Headers */, 641EE6622240C5CA00173FCB /* FBResponsePayload.h in Headers */, 641EE6632240C5CA00173FCB /* FBUnknownCommands.h in Headers */, 641EE7062240CDCF00173FCB /* XCUIElement+FBTVFocuse.h in Headers */, @@ -2536,7 +2527,6 @@ EE35AD371E3B77D600A02D78 /* XCSourceCodeTreeNodeEnumerator.h in Headers */, EE158AB01CBD456F00A3E3F0 /* XCUIElement+FBIsVisible.h in Headers */, 71414ED42670A1EE003A8C5D /* LRUCache.h in Headers */, - EE158AB41CBD456F00A3E3F0 /* XCUIElement+FBTap.h in Headers */, EE158ADC1CBD456F00A3E3F0 /* FBResponsePayload.h in Headers */, 13815F6F2328D20400CDAB61 /* FBActiveAppDetectionPoint.h in Headers */, EE158ACC1CBD456F00A3E3F0 /* FBUnknownCommands.h in Headers */, @@ -3159,7 +3149,6 @@ 641EE6232240C5CA00173FCB /* FBScreen.m in Sources */, 71D04DCB25356C43008A052C /* XCUIElement+FBCaching.m in Sources */, 641EE6242240C5CA00173FCB /* FBXCTestDaemonsProxy.m in Sources */, - 641EE6252240C5CA00173FCB /* XCUIElement+FBTap.m in Sources */, 13DE7A58287CA1EC003243C6 /* FBXCElementSnapshotWrapper.m in Sources */, 641EE6262240C5CA00173FCB /* FBMathUtils.m in Sources */, 641EE6272240C5CA00173FCB /* FBXCAXClientProxy.m in Sources */, @@ -3292,7 +3281,6 @@ 715AFAC21FFA29180053896D /* FBScreen.m in Sources */, 71B155DC230711E900646AFB /* FBCommandStatus.m in Sources */, EE35AD7C1E3B80C000A02D78 /* FBXCTestDaemonsProxy.m in Sources */, - EE158AB51CBD456F00A3E3F0 /* XCUIElement+FBTap.m in Sources */, EE18883B1DA661C400307AA8 /* FBMathUtils.m in Sources */, 7157B292221DADD2001C348C /* FBXCAXClientProxy.m in Sources */, ); diff --git a/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m b/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m index 086643296..ec752c5a0 100644 --- a/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +++ b/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m @@ -256,7 +256,7 @@ - (BOOL)fb_dismissKeyboardWithKeyNames:(nullable NSArray *)keyNames continue; } - [matchedKey fb_tapWithError:nil]; + [matchedKey tap]; if (isKeyboardInvisible()) { return YES; } @@ -269,7 +269,7 @@ - (BOOL)fb_dismissKeyboardWithKeyNames:(nullable NSArray *)keyNames @[@(XCUIElementTypeKey), @(XCUIElementTypeButton)]]; NSArray *matchedKeys = findMatchingKeys(searchPredicate); if (matchedKeys.count > 0) { - [matchedKeys[matchedKeys.count - 1] fb_tapWithError:nil]; + [matchedKeys[matchedKeys.count - 1] tap]; } } #endif diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBForceTouch.m b/WebDriverAgentLib/Categories/XCUIElement+FBForceTouch.m index e7629c6bc..1c7a9ce0e 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBForceTouch.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBForceTouch.m @@ -35,10 +35,10 @@ - (BOOL)fb_forceTouchCoordinate:(NSValue *)relativeCoordinate [self pressWithPressure:[pressure doubleValue] duration:[duration doubleValue]]; } } else { - CGSize size = self.frame.size; - CGVector offset = CGVectorMake(size.width > 0 ? relativeCoordinate.CGPointValue.x / size.width : 0, - size.height > 0 ? relativeCoordinate.CGPointValue.y / size.height : 0); - XCUICoordinate *hitPoint = [self coordinateWithNormalizedOffset:offset]; + CGVector offset = CGVectorMake(relativeCoordinate.CGPointValue.x, + relativeCoordinate.CGPointValue.y); + XCUICoordinate *hitPoint = [[self coordinateWithNormalizedOffset:CGVectorMake(0, 0)] + coordinateWithOffset:offset]; if (nil == pressure || nil == duration) { [hitPoint forcePress]; } else { diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBTap.h b/WebDriverAgentLib/Categories/XCUIElement+FBTap.h deleted file mode 100644 index ed92bb6d7..000000000 --- a/WebDriverAgentLib/Categories/XCUIElement+FBTap.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface XCUIElement (FBTap) - -/** - Waits for element to become stable (not move) and performs sync tap on element - - @param error If there is an error, upon return contains an NSError object that describes the problem. - @return YES if the operation succeeds, otherwise NO. -*/ -- (BOOL)fb_tapWithError:(NSError **)error; - -/** - Waits for element to become stable (not move) and performs sync tap on element - - @param relativeCoordinate hit point coordinate relative to the current element position - @param error If there is an error, upon return contains an NSError object that describes the problem. - @return YES if the operation succeeds, otherwise NO. - */ -- (BOOL)fb_tapCoordinate:(CGPoint)relativeCoordinate error:(NSError **)error; - -@end - -NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBTap.m b/WebDriverAgentLib/Categories/XCUIElement+FBTap.m deleted file mode 100644 index c3c4346ae..000000000 --- a/WebDriverAgentLib/Categories/XCUIElement+FBTap.m +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import "XCUIElement+FBTap.h" - - -#if !TARGET_OS_TV -@implementation XCUIElement (FBTap) - -- (BOOL)fb_tapWithError:(NSError **)error -{ - [self tap]; - return YES; -} - -- (BOOL)fb_tapCoordinate:(CGPoint)relativeCoordinate error:(NSError **)error -{ - XCUICoordinate *startCoordinate = [self coordinateWithNormalizedOffset:CGVectorMake(0, 0)]; - CGVector offset = CGVectorMake(relativeCoordinate.x, relativeCoordinate.y); - XCUICoordinate *dstCoordinate = [startCoordinate coordinateWithOffset:offset]; - [dstCoordinate tap]; - return YES; -} - -@end -#endif diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBTyping.m b/WebDriverAgentLib/Categories/XCUIElement+FBTyping.m index aabc6e8bf..a538be380 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBTyping.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBTyping.m @@ -16,7 +16,6 @@ #import "FBXCElementSnapshotWrapper.h" #import "FBXCElementSnapshotWrapper+Helpers.h" #import "XCUIElement+FBCaching.h" -#import "XCUIElement+FBTap.h" #import "XCUIElement+FBUtilities.h" #import "FBXCodeCompatibility.h" @@ -72,7 +71,7 @@ - (void)fb_prepareForTextInputWithSnapshot:(FBXCElementSnapshotWrapper *)snapsho // There is no possibility to open the keyboard by tapping a field in TvOS #if !TARGET_OS_TV [FBLogger logFmt:@"Trying to tap the \"%@\" element to have it focused", snapshot.fb_description]; - [self fb_tapWithError:nil]; + [self tap]; // It might take some time to update the UI [self fb_takeSnapshot]; #endif diff --git a/WebDriverAgentLib/Commands/FBElementCommands.m b/WebDriverAgentLib/Commands/FBElementCommands.m index 49c3a0231..adb5f6092 100644 --- a/WebDriverAgentLib/Commands/FBElementCommands.m +++ b/WebDriverAgentLib/Commands/FBElementCommands.m @@ -30,7 +30,6 @@ #import "XCUIElement+FBIsVisible.h" #import "XCUIElement+FBPickerWheel.h" #import "XCUIElement+FBScrolling.h" -#import "XCUIElement+FBTap.h" #import "XCUIElement+FBForceTouch.h" #import "XCUIElement+FBSwiping.h" #import "XCUIElement+FBTyping.h" @@ -233,14 +232,14 @@ + (NSArray *)routes { FBElementCache *elementCache = request.session.elementCache; XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]]; - NSError *error = nil; #if TARGET_OS_IOS - if (![element fb_tapWithError:&error]) { + [element tap]; #elif TARGET_OS_TV + NSError *error = nil; if (![element fb_selectWithError:&error]) { -#endif return FBResponseWithStatus([FBCommandStatus invalidElementStateErrorWithMessage:error.description traceback:nil]); } +#endif return FBResponseWithOK(); } @@ -296,9 +295,10 @@ + (NSArray *)routes + (id)handleDoubleTapCoordinate:(FBRouteRequest *)request { - CGPoint doubleTapPoint = CGPointMake((CGFloat)[request.arguments[@"x"] doubleValue], (CGFloat)[request.arguments[@"y"] doubleValue]); - XCUICoordinate *doubleTapCoordinate = [self.class gestureCoordinateWithCoordinate:doubleTapPoint - application:request.session.activeApplication]; + CGVector offset = CGVectorMake([request.arguments[@"x"] doubleValue], + [request.arguments[@"y"] doubleValue]); + XCUICoordinate *doubleTapCoordinate = [self.class gestureCoordinateWithOffset:offset + element:request.session.activeApplication]; [doubleTapCoordinate doubleTap]; return FBResponseWithOK(); } @@ -334,9 +334,10 @@ + (NSArray *)routes + (id)handleTouchAndHoldCoordinate:(FBRouteRequest *)request { - CGPoint touchPoint = CGPointMake((CGFloat)[request.arguments[@"x"] doubleValue], (CGFloat)[request.arguments[@"y"] doubleValue]); - XCUICoordinate *pressCoordinate = [self.class gestureCoordinateWithCoordinate:touchPoint - application:request.session.activeApplication]; + CGVector offset = CGVectorMake([request.arguments[@"x"] doubleValue], + [request.arguments[@"y"] doubleValue]); + XCUICoordinate *pressCoordinate = [self.class gestureCoordinateWithOffset:offset + element:request.session.activeApplication]; [pressCoordinate pressForDuration:[request.arguments[@"duration"] doubleValue]]; return FBResponseWithOK(); } @@ -359,18 +360,18 @@ + (NSArray *)routes + (id)handlePressAndDragCoordinateWithVelocity:(FBRouteRequest *)request { FBSession *session = request.session; - CGPoint startPoint = CGPointMake((CGFloat)[request.arguments[@"fromX"] doubleValue], - (CGFloat)[request.arguments[@"fromY"] doubleValue]); - CGPoint endPoint = CGPointMake((CGFloat)[request.arguments[@"toX"] doubleValue], - (CGFloat)[request.arguments[@"toY"] doubleValue]); - XCUICoordinate *endCoordinate = [self.class gestureCoordinateWithCoordinate:endPoint - application:session.activeApplication]; - XCUICoordinate *startCoordinate = [self.class gestureCoordinateWithCoordinate:startPoint - application:session.activeApplication]; + CGVector startOffset = CGVectorMake((CGFloat)[request.arguments[@"fromX"] doubleValue], + (CGFloat)[request.arguments[@"fromY"] doubleValue]); + XCUICoordinate *startCoordinate = [self.class gestureCoordinateWithOffset:startOffset + element:session.activeApplication]; if (![startCoordinate respondsToSelector:@selector(pressForDuration:thenDragToCoordinate:withVelocity:thenHoldForDuration:)]) { return FBResponseWithStatus([FBCommandStatus unsupportedOperationErrorWithMessage:@"This method is only supported in Xcode 12 and above" traceback:nil]); } + CGVector endOffset = CGVectorMake((CGFloat)[request.arguments[@"toX"] doubleValue], + (CGFloat)[request.arguments[@"toY"] doubleValue]); + XCUICoordinate *endCoordinate = [self.class gestureCoordinateWithOffset:endOffset + element:session.activeApplication]; [startCoordinate pressForDuration:[request.arguments[@"pressDuration"] doubleValue] thenDragToCoordinate:endCoordinate withVelocity:[request.arguments[@"velocity"] doubleValue] @@ -444,13 +445,15 @@ + (NSArray *)routes + (id)handleDragCoordinate:(FBRouteRequest *)request { FBSession *session = request.session; - CGPoint startPoint = CGPointMake((CGFloat)[request.arguments[@"fromX"] doubleValue], (CGFloat)[request.arguments[@"fromY"] doubleValue]); - CGPoint endPoint = CGPointMake((CGFloat)[request.arguments[@"toX"] doubleValue], (CGFloat)[request.arguments[@"toY"] doubleValue]); + CGVector startOffset = CGVectorMake([request.arguments[@"fromX"] doubleValue], + [request.arguments[@"fromY"] doubleValue]); + XCUICoordinate *startCoordinate = [self.class gestureCoordinateWithOffset:startOffset + element:session.activeApplication]; + CGVector endOffset = CGVectorMake([request.arguments[@"toX"] doubleValue], + [request.arguments[@"toY"] doubleValue]); + XCUICoordinate *endCoordinate = [self.class gestureCoordinateWithOffset:endOffset + element:session.activeApplication]; NSTimeInterval duration = [request.arguments[@"duration"] doubleValue]; - XCUICoordinate *endCoordinate = [self.class gestureCoordinateWithCoordinate:endPoint - application:session.activeApplication]; - XCUICoordinate *startCoordinate = [self.class gestureCoordinateWithCoordinate:startPoint - application:session.activeApplication]; [startCoordinate pressForDuration:duration thenDragToCoordinate:endCoordinate]; return FBResponseWithOK(); } @@ -460,14 +463,13 @@ + (NSArray *)routes FBSession *session = request.session; FBElementCache *elementCache = session.elementCache; XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]]; - CGRect frame = [(id)element.lastSnapshot frame]; - CGPoint startPoint = CGPointMake((CGFloat)(frame.origin.x + [request.arguments[@"fromX"] doubleValue]), (CGFloat)(frame.origin.y + [request.arguments[@"fromY"] doubleValue])); - CGPoint endPoint = CGPointMake((CGFloat)(frame.origin.x + [request.arguments[@"toX"] doubleValue]), (CGFloat)(frame.origin.y + [request.arguments[@"toY"] doubleValue])); + CGVector startOffset = CGVectorMake([request.arguments[@"fromX"] doubleValue], + [request.arguments[@"fromY"] doubleValue]); + XCUICoordinate *startCoordinate = [self.class gestureCoordinateWithOffset:startOffset element:element]; + CGVector endOffset = CGVectorMake([request.arguments[@"toX"] doubleValue], + [request.arguments[@"toY"] doubleValue]); + XCUICoordinate *endCoordinate = [self.class gestureCoordinateWithOffset:endOffset element:element]; NSTimeInterval duration = [request.arguments[@"duration"] doubleValue]; - XCUICoordinate *endCoordinate = [self.class gestureCoordinateWithCoordinate:endPoint - application:session.activeApplication]; - XCUICoordinate *startCoordinate = [self.class gestureCoordinateWithCoordinate:startPoint - application:session.activeApplication]; [startCoordinate pressForDuration:duration thenDragToCoordinate:endCoordinate]; return FBResponseWithOK(); } @@ -493,19 +495,13 @@ + (NSArray *)routes + (id)handleTap:(FBRouteRequest *)request { FBElementCache *elementCache = request.session.elementCache; - CGPoint tapPoint = CGPointMake((CGFloat)[request.arguments[@"x"] doubleValue], (CGFloat)[request.arguments[@"y"] doubleValue]); - if ([elementCache hasElementWithUUID:request.parameters[@"uuid"]]) { - XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]]; - NSError *error; - if (![element fb_tapCoordinate:tapPoint error:&error]) { - return FBResponseWithStatus([FBCommandStatus invalidElementStateErrorWithMessage:error.description - traceback:nil]); - } - } else { - XCUICoordinate *tapCoordinate = [self.class gestureCoordinateWithCoordinate:tapPoint - application:request.session.activeApplication]; - [tapCoordinate tap]; - } + CGVector offset = CGVectorMake([request.arguments[@"x"] doubleValue], + [request.arguments[@"y"] doubleValue]); + XCUIElement *element = [elementCache hasElementWithUUID:request.parameters[@"uuid"]] + ? [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]] + : request.session.activeApplication; + XCUICoordinate *tapCoordinate = [self.class gestureCoordinateWithOffset:offset element:element]; + [tapCoordinate tap]; return FBResponseWithOK(); } @@ -672,55 +668,18 @@ + (NSArray *)routes } /** - Returns gesture coordinate for the application based on absolute coordinate + Returns gesture coordinate for the element based on absolute coordinate - @param coordinate absolute screen coordinates - @param application the instance of current application under test + @param offset absolute screen offset for the given application + @param element the element instance to perform the gesture on @return translated gesture coordinates ready to be passed to XCUICoordinate methods */ -+ (XCUICoordinate *)gestureCoordinateWithCoordinate:(CGPoint)coordinate - application:(XCUIApplication *)application -{ - CGPoint point = coordinate; - /** - If SDK >= 11, the tap coordinate based on application is not correct when - the application orientation is landscape and - tapX > application portrait width or tapY > application portrait height. - Pass the window element to the method [FBElementCommands gestureCoordinateWithCoordinate:element:] - will resolve the problem. - More details about the bug, please see the following issues: - #705: https://github.com/facebook/WebDriverAgent/issues/705 - #798: https://github.com/facebook/WebDriverAgent/issues/798 - #856: https://github.com/facebook/WebDriverAgent/issues/856 - Notice: On iOS 10, if the application is not launched by wda, no elements will be found. - See issue #732: https://github.com/facebook/WebDriverAgent/issues/732 - */ - XCUIElement *element = application; - XCUIElement *window = application.windows.allElementsBoundByIndex.firstObject; - if (window) { - element = window; - id snapshot = element.fb_cachedSnapshot ?: element.fb_takeSnapshot; - point.x -= snapshot.frame.origin.x; - point.y -= snapshot.frame.origin.y; - } - return [self gestureCoordinateWithCoordinate:point element:element]; -} - -/** - Returns gesture coordinate based on the specified element. - - @param coordinate absolute coordinates based on the element - @param element the element in the current application under test - @return translated gesture coordinates ready to be passed to XCUICoordinate methods - */ -+ (XCUICoordinate *)gestureCoordinateWithCoordinate:(CGPoint)coordinate - element:(XCUIElement *)element ++ (XCUICoordinate *)gestureCoordinateWithOffset:(CGVector)offset + element:(XCUIElement *)element { - XCUICoordinate *appCoordinate = [[XCUICoordinate alloc] initWithElement:element - normalizedOffset:CGVectorMake(0, 0)]; - return [[XCUICoordinate alloc] initWithCoordinate:appCoordinate - pointsOffset:CGVectorMake(coordinate.x, coordinate.y)]; + return [[element coordinateWithNormalizedOffset:CGVectorMake(0, 0)] coordinateWithOffset:offset]; } + #endif @end diff --git a/WebDriverAgentLib/FBAlert.m b/WebDriverAgentLib/FBAlert.m index 705ab3ccc..d692b04b2 100644 --- a/WebDriverAgentLib/FBAlert.m +++ b/WebDriverAgentLib/FBAlert.m @@ -17,7 +17,6 @@ #import "FBXCodeCompatibility.h" #import "XCUIApplication+FBAlert.h" #import "XCUIElement+FBClassChain.h" -#import "XCUIElement+FBTap.h" #import "XCUIElement+FBTyping.h" #import "XCUIElement+FBUtilities.h" #import "XCUIElement+FBWebDriverAttributes.h" @@ -190,11 +189,13 @@ - (BOOL)acceptWithError:(NSError **)error ? buttons.lastObject : buttons.firstObject; } - return nil == acceptButton - ? [[[FBErrorBuilder builder] + if (nil == acceptButton) { + return [[[FBErrorBuilder builder] withDescriptionFormat:@"Failed to find accept button for alert: %@", self.alertElement] - buildError:error] - : [acceptButton fb_tapWithError:error]; + buildError:error]; + } + [acceptButton tap]; + return YES; } - (BOOL)dismissWithError:(NSError **)error @@ -230,11 +231,13 @@ - (BOOL)dismissWithError:(NSError **)error : buttons.lastObject; } - return nil == dismissButton - ? [[[FBErrorBuilder builder] + if (nil == dismissButton) { + return [[[FBErrorBuilder builder] withDescriptionFormat:@"Failed to find dismiss button for alert: %@", self.alertElement] - buildError:error] - : [dismissButton fb_tapWithError:error]; + buildError:error]; + } + [dismissButton tap]; + return YES; } - (BOOL)clickAlertButton:(NSString *)label error:(NSError **)error @@ -251,7 +254,8 @@ - (BOOL)clickAlertButton:(NSString *)label error:(NSError **)error withDescriptionFormat:@"Failed to find button with label '%@' for alert: %@", label, self.alertElement] buildError:error]; } - return [requestedButton fb_tapWithError:error]; + [requestedButton tap]; + return YES; } - (XCUIElement *)alertElement diff --git a/WebDriverAgentLib/WebDriverAgentLib.h b/WebDriverAgentLib/WebDriverAgentLib.h index b8f85e98f..6d9daa1f6 100644 --- a/WebDriverAgentLib/WebDriverAgentLib.h +++ b/WebDriverAgentLib/WebDriverAgentLib.h @@ -46,7 +46,6 @@ FOUNDATION_EXPORT const unsigned char WebDriverAgentLib_VersionString[]; #import #import #import -#import #import #import #import diff --git a/WebDriverAgentTests/IntegrationTests/FBAlertTests.m b/WebDriverAgentTests/IntegrationTests/FBAlertTests.m index e94c4109e..57c48e492 100644 --- a/WebDriverAgentTests/IntegrationTests/FBAlertTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBAlertTests.m @@ -15,7 +15,6 @@ #import "FBIntegrationTestCase.h" #import "FBTestMacros.h" #import "FBMacros.h" -#import "XCUIElement+FBTap.h" @interface FBAlertTests : FBIntegrationTestCase @end @@ -42,13 +41,13 @@ - (void)tearDown - (void)showApplicationAlert { - [self.testedApplication.buttons[FBShowAlertButtonName] fb_tapWithError:nil]; + [self.testedApplication.buttons[FBShowAlertButtonName] tap]; FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count != 0); } - (void)showApplicationSheet { - [self.testedApplication.buttons[FBShowSheetAlertButtonName] fb_tapWithError:nil]; + [self.testedApplication.buttons[FBShowSheetAlertButtonName] tap]; FBAssertWaitTillBecomesTrue(self.testedApplication.sheets.count != 0); } diff --git a/WebDriverAgentTests/IntegrationTests/FBAutoAlertsHandlerTests.m b/WebDriverAgentTests/IntegrationTests/FBAutoAlertsHandlerTests.m index 5294fb50c..25dc39d21 100644 --- a/WebDriverAgentTests/IntegrationTests/FBAutoAlertsHandlerTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBAutoAlertsHandlerTests.m @@ -53,7 +53,7 @@ - (void)disabled_testAutoAcceptingOfAlerts initWithApplication:FBApplication.fb_activeApplication defaultAlertAction:@"accept"]; for (int i = 0; i < 2; i++) { - [self.testedApplication.buttons[FBShowAlertButtonName] fb_tapWithError:nil]; + [self.testedApplication.buttons[FBShowAlertButtonName] tap]; [self.testedApplication fb_waitUntilStable]; FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count == 0); } @@ -66,7 +66,7 @@ - (void)disabled_testAutoDismissingOfAlerts initWithApplication:FBApplication.fb_activeApplication defaultAlertAction:@"dismiss"]; for (int i = 0; i < 2; i++) { - [self.testedApplication.buttons[FBShowAlertButtonName] fb_tapWithError:nil]; + [self.testedApplication.buttons[FBShowAlertButtonName] tap]; [self.testedApplication fb_waitUntilStable]; FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count == 0); } diff --git a/WebDriverAgentTests/IntegrationTests/FBElementAttributeTests.m b/WebDriverAgentTests/IntegrationTests/FBElementAttributeTests.m index bc0966f91..c7cc3505e 100644 --- a/WebDriverAgentTests/IntegrationTests/FBElementAttributeTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBElementAttributeTests.m @@ -160,7 +160,7 @@ - (void)testSwitchAttributes XCTAssertNil(element.wdLabel); XCTAssertEqualObjects(element.wdValue, @"1"); XCTAssertFalse(element.wdSelected); - XCTAssertTrue([element fb_tapWithError:nil]); + [element tap]; XCTAssertEqualObjects(element.wdValue, @"0"); XCTAssertFalse(element.wdSelected); } diff --git a/WebDriverAgentTests/IntegrationTests/FBTapTest.m b/WebDriverAgentTests/IntegrationTests/FBTapTest.m index 30b5f0f9e..9dce4084c 100644 --- a/WebDriverAgentTests/IntegrationTests/FBTapTest.m +++ b/WebDriverAgentTests/IntegrationTests/FBTapTest.m @@ -15,7 +15,6 @@ #import "FBElementCache.h" #import "FBTestMacros.h" #import "XCUIDevice+FBRotation.h" -#import "XCUIElement+FBTap.h" #import "XCUIElement+FBIsVisible.h" @interface FBTapTest : FBIntegrationTestCase @@ -28,8 +27,7 @@ @implementation FBTapTest - (void)verifyTapWithOrientation:(UIDeviceOrientation)orientation { [[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:orientation]; - NSError *error; - [self.testedApplication.buttons[FBShowAlertButtonName] fb_tapWithError:&error]; + [self.testedApplication.buttons[FBShowAlertButtonName] tap]; FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count > 0); } @@ -66,10 +64,7 @@ - (void)testTapInLandscapeRight [self verifyTapWithOrientation:UIDeviceOrientationLandscapeRight]; } -// Visibility detection for upside-down orientation is broken -// and cannot be workarounded properly, but this is not very important for Appium, since -// We don't support such orientation anyway -- (void)disabled_testTapInPortraitUpsideDown +- (void)testTapInPortraitUpsideDown { [self verifyTapWithOrientation:UIDeviceOrientationPortraitUpsideDown]; } @@ -77,9 +72,8 @@ - (void)disabled_testTapInPortraitUpsideDown - (void)verifyTapByCoordinatesWithOrientation:(UIDeviceOrientation)orientation { [[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:orientation]; - NSError *error; XCUIElement *dstButton = self.testedApplication.buttons[FBShowAlertButtonName]; - [dstButton fb_tapCoordinate:CGPointMake(dstButton.frame.size.width / 2, dstButton.frame.size.height / 2) error:&error]; + [[dstButton coordinateWithNormalizedOffset:CGVectorMake(0.5, 0.5)] tap]; FBAssertWaitTillBecomesTrue(self.testedApplication.alerts.count > 0); } @@ -98,10 +92,7 @@ - (void)testTapCoordinatesInLandscapeRight [self verifyTapByCoordinatesWithOrientation:UIDeviceOrientationLandscapeRight]; } -// Visibility detection for upside-down orientation is broken -// and cannot be workarounded properly, but this is not very important for Appium, since -// We don't support such orientation anyway -- (void)disabled_testTapCoordinatesInPortraitUpsideDown +- (void)testTapCoordinatesInPortraitUpsideDown { [self verifyTapByCoordinatesWithOrientation:UIDeviceOrientationPortraitUpsideDown]; } From dc498910133a0d17a91d1d9cf4caa89e1afa1704 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 18 May 2023 07:34:17 +0000 Subject: [PATCH 125/240] chore(release): 5.1.5 [skip ci] ## [5.1.5](https://github.com/appium/WebDriverAgent/compare/v5.1.4...v5.1.5) (2023-05-18) ### Miscellaneous Chores * Drop obsolete workarounds for coordinates calculation ([#701](https://github.com/appium/WebDriverAgent/issues/701)) ([259f731](https://github.com/appium/WebDriverAgent/commit/259f7319305b15a3f541957d3ccaa3cb12c9e1a3)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf2c328b8..f6b245d64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.1.5](https://github.com/appium/WebDriverAgent/compare/v5.1.4...v5.1.5) (2023-05-18) + + +### Miscellaneous Chores + +* Drop obsolete workarounds for coordinates calculation ([#701](https://github.com/appium/WebDriverAgent/issues/701)) ([259f731](https://github.com/appium/WebDriverAgent/commit/259f7319305b15a3f541957d3ccaa3cb12c9e1a3)) + ## [5.1.4](https://github.com/appium/WebDriverAgent/compare/v5.1.3...v5.1.4) (2023-05-16) diff --git a/package.json b/package.json index 90c318a34..0c888e5b1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.1.4", + "version": "5.1.5", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 3e495230674a46db29ecea3b36c2ed0ea1bf2842 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 17:20:52 +0200 Subject: [PATCH 126/240] chore(deps): bump @appium/support from 3.1.11 to 4.0.0 (#710) Bumps [@appium/support](https://github.com/appium/appium/tree/HEAD/packages/support) from 3.1.11 to 4.0.0. - [Release notes](https://github.com/appium/appium/releases) - [Changelog](https://github.com/appium/appium/blob/master/packages/support/CHANGELOG.md) - [Commits](https://github.com/appium/appium/commits/@appium/support@4.0.0/packages/support) --- updated-dependencies: - dependency-name: "@appium/support" dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0c888e5b1..8989cb318 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ }, "dependencies": { "@appium/base-driver": "^9.0.0", - "@appium/support": "^3.0.0", + "@appium/support": "^4.0.0", "@babel/runtime": "^7.0.0", "appium-ios-device": "^2.5.0", "appium-ios-simulator": "^5.0.1", From 5738bb59388f09fde741b02b00a78be937eb98bb Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 18 May 2023 15:29:51 +0000 Subject: [PATCH 127/240] chore(release): 5.1.6 [skip ci] ## [5.1.6](https://github.com/appium/WebDriverAgent/compare/v5.1.5...v5.1.6) (2023-05-18) ### Miscellaneous Chores * **deps:** bump @appium/support from 3.1.11 to 4.0.0 ([#710](https://github.com/appium/WebDriverAgent/issues/710)) ([3e49523](https://github.com/appium/WebDriverAgent/commit/3e495230674a46db29ecea3b36c2ed0ea1bf2842)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6b245d64..de99d00fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.1.6](https://github.com/appium/WebDriverAgent/compare/v5.1.5...v5.1.6) (2023-05-18) + + +### Miscellaneous Chores + +* **deps:** bump @appium/support from 3.1.11 to 4.0.0 ([#710](https://github.com/appium/WebDriverAgent/issues/710)) ([3e49523](https://github.com/appium/WebDriverAgent/commit/3e495230674a46db29ecea3b36c2ed0ea1bf2842)) + ## [5.1.5](https://github.com/appium/WebDriverAgent/compare/v5.1.4...v5.1.5) (2023-05-18) diff --git a/package.json b/package.json index 8989cb318..bc9cd830a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.1.5", + "version": "5.1.6", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 9afc2d79c0b6ae5413cc966346b9240768cd5377 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 18 May 2023 21:27:59 +0200 Subject: [PATCH 128/240] ci: Disable tests that are unstable in CI env with older OS versions (#711) --- .../IntegrationTests/FBScrollingTests.m | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/WebDriverAgentTests/IntegrationTests/FBScrollingTests.m b/WebDriverAgentTests/IntegrationTests/FBScrollingTests.m index 16c9df00e..f1c5e15a0 100644 --- a/WebDriverAgentTests/IntegrationTests/FBScrollingTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBScrollingTests.m @@ -49,6 +49,11 @@ - (void)testCellVisibility - (void)testSimpleScroll { + if (SYSTEM_VERSION_LESS_THAN(@"16.0")) { + // This test is unstable in CI env + return; + } + FBAssertVisibleCell(@"0"); FBAssertVisibleCell(@"10"); [self.scrollView fb_scrollDownByNormalizedDistance:1.0]; @@ -82,6 +87,11 @@ - (void)testFarScrollToVisible - (void)testNativeFarScrollToVisible { + if (SYSTEM_VERSION_LESS_THAN(@"16.0")) { + // This test is unstable in CI env + return; + } + NSString *cellName = @"80"; NSError *error; FBAssertInvisibleCell(cellName); @@ -100,6 +110,12 @@ - (void)testAttributeWithNullScrollToVisible [element fb_scrollToVisibleWithError:&error]; XCTAssertNil(error); XCTAssertTrue(element.fb_isVisible); + + if (SYSTEM_VERSION_LESS_THAN(@"16.0")) { + // This test is unstable in CI env + return; + } + [element tap]; XCTAssertTrue(element.wdSelected); } From cdfae408be0bcf6607f0ca4462925eed2c300f5e Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Sat, 20 May 2023 09:10:41 +0200 Subject: [PATCH 129/240] feat: Replace non-encodable characters in the resulting JSON (#713) --- WebDriverAgent.xcodeproj/project.pbxproj | 15 ++++ .../NSDictionary+FBUtf8SafeDictionary.h | 40 +++++++++ .../NSDictionary+FBUtf8SafeDictionary.m | 88 +++++++++++++++++++ .../Routing/FBResponseJSONPayload.m | 9 ++ .../UnitTests/NSDictionaryFBUtf8SafeTests.m | 35 ++++++++ 5 files changed, 187 insertions(+) create mode 100644 WebDriverAgentLib/Categories/NSDictionary+FBUtf8SafeDictionary.h create mode 100644 WebDriverAgentLib/Categories/NSDictionary+FBUtf8SafeDictionary.m create mode 100644 WebDriverAgentTests/UnitTests/NSDictionaryFBUtf8SafeTests.m diff --git a/WebDriverAgent.xcodeproj/project.pbxproj b/WebDriverAgent.xcodeproj/project.pbxproj index eafb306ad..a5b933127 100644 --- a/WebDriverAgent.xcodeproj/project.pbxproj +++ b/WebDriverAgent.xcodeproj/project.pbxproj @@ -399,6 +399,9 @@ 716E0BCE1E917E810087A825 /* NSString+FBXMLSafeString.h in Headers */ = {isa = PBXBuildFile; fileRef = 716E0BCC1E917E810087A825 /* NSString+FBXMLSafeString.h */; }; 716E0BCF1E917E810087A825 /* NSString+FBXMLSafeString.m in Sources */ = {isa = PBXBuildFile; fileRef = 716E0BCD1E917E810087A825 /* NSString+FBXMLSafeString.m */; }; 716E0BD11E917F260087A825 /* FBXMLSafeStringTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 716E0BD01E917F260087A825 /* FBXMLSafeStringTests.m */; }; + 716F0DA12A16CA1000CDD977 /* NSDictionary+FBUtf8SafeDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 716F0D9F2A16CA1000CDD977 /* NSDictionary+FBUtf8SafeDictionary.h */; }; + 716F0DA32A16CA1000CDD977 /* NSDictionary+FBUtf8SafeDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 716F0DA02A16CA1000CDD977 /* NSDictionary+FBUtf8SafeDictionary.m */; }; + 716F0DA62A17323300CDD977 /* NSDictionaryFBUtf8SafeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 716F0DA52A17323300CDD977 /* NSDictionaryFBUtf8SafeTests.m */; }; 718226CA2587443700661B83 /* GCDAsyncUdpSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 718226C62587443600661B83 /* GCDAsyncUdpSocket.h */; }; 718226CB2587443700661B83 /* GCDAsyncUdpSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 718226C62587443600661B83 /* GCDAsyncUdpSocket.h */; }; 718226CC2587443700661B83 /* GCDAsyncSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 718226C72587443600661B83 /* GCDAsyncSocket.h */; }; @@ -1004,6 +1007,9 @@ 716E0BCC1E917E810087A825 /* NSString+FBXMLSafeString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+FBXMLSafeString.h"; sourceTree = ""; }; 716E0BCD1E917E810087A825 /* NSString+FBXMLSafeString.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+FBXMLSafeString.m"; sourceTree = ""; }; 716E0BD01E917F260087A825 /* FBXMLSafeStringTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBXMLSafeStringTests.m; sourceTree = ""; }; + 716F0D9F2A16CA1000CDD977 /* NSDictionary+FBUtf8SafeDictionary.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+FBUtf8SafeDictionary.h"; sourceTree = ""; }; + 716F0DA02A16CA1000CDD977 /* NSDictionary+FBUtf8SafeDictionary.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+FBUtf8SafeDictionary.m"; sourceTree = ""; }; + 716F0DA52A17323300CDD977 /* NSDictionaryFBUtf8SafeTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NSDictionaryFBUtf8SafeTests.m; sourceTree = ""; }; 717C0D702518ED2800CAA6EC /* TVOSSettings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = TVOSSettings.xcconfig; sourceTree = ""; }; 717C0D862518ED7000CAA6EC /* TVOSTestSettings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = TVOSTestSettings.xcconfig; sourceTree = ""; }; 718226C62587443600661B83 /* GCDAsyncUdpSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GCDAsyncUdpSocket.h; path = WebDriverAgentLib/Vendor/CocoaAsyncSocket/GCDAsyncUdpSocket.h; sourceTree = SOURCE_ROOT; }; @@ -1701,6 +1707,8 @@ EE9AB73E1CAEDF0C008C271F /* Categories */ = { isa = PBXGroup; children = ( + 716F0D9F2A16CA1000CDD977 /* NSDictionary+FBUtf8SafeDictionary.h */, + 716F0DA02A16CA1000CDD977 /* NSDictionary+FBUtf8SafeDictionary.m */, 71555A3B1DEC460A007D4A8B /* NSExpression+FBFormat.h */, 71555A3C1DEC460A007D4A8B /* NSExpression+FBFormat.m */, 71A224E31DE2F56600844D55 /* NSPredicate+FBFormat.h */, @@ -2022,6 +2030,7 @@ 716E0BD01E917F260087A825 /* FBXMLSafeStringTests.m */, 712A0C841DA3E459007D02E5 /* FBXPathTests.m */, EE9B76581CF7987300275851 /* Info.plist */, + 716F0DA52A17323300CDD977 /* NSDictionaryFBUtf8SafeTests.m */, 7139145B1DF01A12005896C2 /* NSExpressionFBFormatTests.m */, 71A224E71DE326C500844D55 /* NSPredicateFBFormatTests.m */, 713914591DF01989005896C2 /* XCUIElementHelpersTests.m */, @@ -2405,6 +2414,7 @@ 641EE6C02240C5CA00173FCB /* XCUIApplication+FBHelpers.h in Headers */, 641EE6C12240C5CA00173FCB /* _XCTestObservationCenterImplementation.h in Headers */, 714EAA0E2673FDFE005C5B47 /* FBCapabilities.h in Headers */, + 716F0DA22A16CA1000CDD977 /* NSDictionary+FBUtf8SafeDictionary.h in Headers */, 641EE6C22240C5CA00173FCB /* XCUIDevice+FBHelpers.h in Headers */, 71D3B3D6267FC7260076473D /* XCUIElement+FBResolve.h in Headers */, 641EE6C32240C5CA00173FCB /* FBClassChainQueryParser.h in Headers */, @@ -2594,6 +2604,7 @@ EE35AD271E3B77D600A02D78 /* XCApplicationMonitor.h in Headers */, EE8DDD7F20C5733C004D4925 /* XCUIElement+FBForceTouch.h in Headers */, 71A5C67329A4F39600421C37 /* XCTIssue+FBPatcher.h in Headers */, + 716F0DA12A16CA1000CDD977 /* NSDictionary+FBUtf8SafeDictionary.h in Headers */, EE158AEA1CBD456F00A3E3F0 /* FBRuntimeUtils.h in Headers */, 7136A4791E8918E60024FC3D /* XCUIElement+FBPickerWheel.h in Headers */, E444DCB324913C220060D7EB /* RoutingHTTPServer.h in Headers */, @@ -3106,6 +3117,7 @@ 641EE5FF2240C5CA00173FCB /* XCUIElement+FBForceTouch.m in Sources */, 716C9E0327315EFF005AD475 /* XCUIApplication+FBUIInterruptions.m in Sources */, 641EE6002240C5CA00173FCB /* FBTouchActionCommands.m in Sources */, + 716F0DA42A16CA1000CDD977 /* NSDictionary+FBUtf8SafeDictionary.m in Sources */, 719DCF182601EAFB000E765F /* FBNotificationsHelper.m in Sources */, 714EAA102673FDFE005C5B47 /* FBCapabilities.m in Sources */, 641EE6012240C5CA00173FCB /* FBImageIOScaler.m in Sources */, @@ -3160,6 +3172,7 @@ buildActionMask = 2147483647; files = ( 64B26508228C5514002A5025 /* XCUIElementDouble.m in Sources */, + 716F0DA72A17323300CDD977 /* NSDictionaryFBUtf8SafeTests.m in Sources */, 64B26504228C5299002A5025 /* FBTVNavigationTrackerTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3229,6 +3242,7 @@ 716E0BCF1E917E810087A825 /* NSString+FBXMLSafeString.m in Sources */, EE158ACD1CBD456F00A3E3F0 /* FBUnknownCommands.m in Sources */, EE158AC51CBD456F00A3E3F0 /* FBOrientationCommands.m in Sources */, + 716F0DA32A16CA1000CDD977 /* NSDictionary+FBUtf8SafeDictionary.m in Sources */, 71D475C42538F5A8008D9401 /* XCUIApplicationProcess+FBQuiescence.m in Sources */, 641EE7082240CDEB00173FCB /* XCUIElement+FBTVFocuse.m in Sources */, 71E75E6F254824230099FC87 /* XCUIElementQuery+FBHelpers.m in Sources */, @@ -3346,6 +3360,7 @@ 7139145C1DF01A12005896C2 /* NSExpressionFBFormatTests.m in Sources */, 71A224E81DE326C500844D55 /* NSPredicateFBFormatTests.m in Sources */, EE6A892B1D0B25820083E92B /* FBApplicationDouble.m in Sources */, + 716F0DA62A17323300CDD977 /* NSDictionaryFBUtf8SafeTests.m in Sources */, EE6A892D1D0B2AF40083E92B /* FBErrorBuilderTests.m in Sources */, 712A0C851DA3E459007D02E5 /* FBXPathTests.m in Sources */, ADBC39981D07842800327304 /* XCUIElementDouble.m in Sources */, diff --git a/WebDriverAgentLib/Categories/NSDictionary+FBUtf8SafeDictionary.h b/WebDriverAgentLib/Categories/NSDictionary+FBUtf8SafeDictionary.h new file mode 100644 index 000000000..0f657ab6f --- /dev/null +++ b/WebDriverAgentLib/Categories/NSDictionary+FBUtf8SafeDictionary.h @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSString (FBUtf8SafeString) + +/** + Converts the string, so it could be properly represented in UTF-8 encoding. All non-encodable characters are replaced with + the given `replacement` + + @param replacement The character to use a a replacement for the lossy encoding + @returns Either the same string or a string with non-encodable chars replaced + */ +- (instancetype)fb_utf8SafeStringWithReplacement:(unichar)replacement; + +@end + +@interface NSDictionary (FBUtf8SafeDictionary) + +/** + Converts the dictionary, so it could be properly represented in UTF-8 encoding. All non-encodable characters + in string values are replaced with the Unocde question mark characters. Nested dictionaries and arrays are + processed recursively. + + @returns Either the same dictionary or a dictionary with non-encodable chars in string values replaced + */ +- (instancetype)fb_utf8SafeDictionary; + +@end + +NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Categories/NSDictionary+FBUtf8SafeDictionary.m b/WebDriverAgentLib/Categories/NSDictionary+FBUtf8SafeDictionary.m new file mode 100644 index 000000000..399769142 --- /dev/null +++ b/WebDriverAgentLib/Categories/NSDictionary+FBUtf8SafeDictionary.m @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "NSDictionary+FBUtf8SafeDictionary.h" + +const unichar REPLACER = 0xfffd; + +@implementation NSString (FBUtf8SafeString) + +- (instancetype)fb_utf8SafeStringWithReplacement:(unichar)replacement +{ + if ([self canBeConvertedToEncoding:NSUTF8StringEncoding]) { + return self; + } + + NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; + NSString *convertedString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + NSMutableString *result = [NSMutableString string]; + NSString *replacementStr = [NSString stringWithCharacters:&replacement length:1]; + NSUInteger originalIdx = 0; + NSUInteger convertedIdx = 0; + while (originalIdx < [self length] && convertedIdx < [convertedString length]) { + unichar originalChar = [self characterAtIndex:originalIdx]; + unichar convertedChar = [convertedString characterAtIndex:convertedIdx]; + + if (originalChar == convertedChar) { + [result appendString:[NSString stringWithCharacters:&originalChar length:1]]; + originalIdx++; + convertedIdx++; + continue; + } + + while (originalChar != convertedChar && originalIdx < [self length]) { + [result appendString:replacementStr]; + originalChar = [self characterAtIndex:++originalIdx]; + } + } + return result.copy; +} + +@end + +@implementation NSArray (FBUtf8SafeArray) + +- (instancetype)fb_utf8SafeArray +{ + NSMutableArray *result = [NSMutableArray array]; + for (id item in self) { + if ([item isKindOfClass:NSString.class]) { + [result addObject:[(NSString *)item fb_utf8SafeStringWithReplacement:REPLACER]]; + } else if ([item isKindOfClass:NSDictionary.class]) { + [result addObject:[(NSDictionary *)item fb_utf8SafeDictionary]]; + } else if ([item isKindOfClass:NSArray.class]) { + [result addObject:[(NSArray *)item fb_utf8SafeArray]]; + } else { + [result addObject:item]; + } + } + return result.copy; +} + +@end + +@implementation NSDictionary (FBUtf8SafeDictionary) + +- (instancetype)fb_utf8SafeDictionary +{ + NSMutableDictionary *result = [self mutableCopy]; + for (id key in self) { + id value = result[key]; + if ([value isKindOfClass:NSString.class]) { + result[key] = [(NSString *)value fb_utf8SafeStringWithReplacement:REPLACER]; + } else if ([value isKindOfClass:NSArray.class]) { + result[key] = [(NSArray *)value fb_utf8SafeArray]; + } else if ([value isKindOfClass:NSDictionary.class]) { + result[key] = [(NSDictionary *)value fb_utf8SafeDictionary]; + } + } + return result.copy; +} + +@end diff --git a/WebDriverAgentLib/Routing/FBResponseJSONPayload.m b/WebDriverAgentLib/Routing/FBResponseJSONPayload.m index d00ed38a7..4ad1c37ad 100644 --- a/WebDriverAgentLib/Routing/FBResponseJSONPayload.m +++ b/WebDriverAgentLib/Routing/FBResponseJSONPayload.m @@ -9,6 +9,8 @@ #import "FBResponseJSONPayload.h" +#import "FBLogger.h" +#import "NSDictionary+FBUtf8SafeDictionary.h" #import "RouteResponse.h" @interface FBResponseJSONPayload () @@ -43,6 +45,13 @@ - (void)dispatchWithResponse:(RouteResponse *)response options:NSJSONWritingPrettyPrinted error:&error]; NSCAssert(jsonData, @"Valid JSON must be responded, error of %@", error); + if (nil == [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]) { + [FBLogger log:@"The incoming data cannot be encoded to UTF-8 JSON. Applying lossy conversion as a workaround."]; + jsonData = [NSJSONSerialization dataWithJSONObject:[self.dictionary fb_utf8SafeDictionary] + options:NSJSONWritingPrettyPrinted + error:&error]; + } + NSCAssert(jsonData, @"Valid JSON must be responded, error of %@", error); [response setHeader:@"Content-Type" value:@"application/json;charset=UTF-8"]; [response setStatusCode:self.httpStatusCode]; [response respondWithData:jsonData]; diff --git a/WebDriverAgentTests/UnitTests/NSDictionaryFBUtf8SafeTests.m b/WebDriverAgentTests/UnitTests/NSDictionaryFBUtf8SafeTests.m new file mode 100644 index 000000000..3f6f465a3 --- /dev/null +++ b/WebDriverAgentTests/UnitTests/NSDictionaryFBUtf8SafeTests.m @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import "NSDictionary+FBUtf8SafeDictionary.h" + +@interface NSDictionaryFBUtf8SafeTests : XCTestCase +@end + +@implementation NSDictionaryFBUtf8SafeTests + +- (void)testEmptySafeDictConversion +{ + NSDictionary *d = @{}; + XCTAssertEqualObjects(d, d.fb_utf8SafeDictionary); +} + +- (void)testNonEmptySafeDictConversion +{ + NSDictionary *d = @{ + @"1": @[@3, @4], + @"5": @{@"6": @7, @"8": @9}, + @"10": @"11" + }; + XCTAssertEqualObjects(d, d.fb_utf8SafeDictionary); +} + +@end From 0cb36e656126755196efc243af66468c4d115c92 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sat, 20 May 2023 07:19:21 +0000 Subject: [PATCH 130/240] chore(release): 5.2.0 [skip ci] ## [5.2.0](https://github.com/appium/WebDriverAgent/compare/v5.1.6...v5.2.0) (2023-05-20) ### Features * Replace non-encodable characters in the resulting JSON ([#713](https://github.com/appium/WebDriverAgent/issues/713)) ([cdfae40](https://github.com/appium/WebDriverAgent/commit/cdfae408be0bcf6607f0ca4462925eed2c300f5e)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de99d00fb..40c8f9b69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.2.0](https://github.com/appium/WebDriverAgent/compare/v5.1.6...v5.2.0) (2023-05-20) + + +### Features + +* Replace non-encodable characters in the resulting JSON ([#713](https://github.com/appium/WebDriverAgent/issues/713)) ([cdfae40](https://github.com/appium/WebDriverAgent/commit/cdfae408be0bcf6607f0ca4462925eed2c300f5e)) + ## [5.1.6](https://github.com/appium/WebDriverAgent/compare/v5.1.5...v5.1.6) (2023-05-18) diff --git a/package.json b/package.json index bc9cd830a..33183142a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.1.6", + "version": "5.2.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 4611792ee5d5d7f39d188b5ebc31017f436c5ace Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Mon, 22 May 2023 09:16:42 +0200 Subject: [PATCH 131/240] feat: Use strongbox to persist the previous version of the module (#714) --- lib/webdriveragent.js | 80 +++++++++++++++++++++---------------------- package.json | 1 + 2 files changed, 41 insertions(+), 40 deletions(-) diff --git a/lib/webdriveragent.js b/lib/webdriveragent.js index ef6e8e766..350353ed2 100644 --- a/lib/webdriveragent.js +++ b/lib/webdriveragent.js @@ -3,7 +3,7 @@ import path from 'path'; import url from 'url'; import B from 'bluebird'; import { JWProxy } from '@appium/base-driver'; -import { fs, util, plist, mkdirp } from '@appium/support'; +import { fs, util, plist } from '@appium/support'; import defaultLogger from './logger'; import { NoSessionProxy } from './no-session-proxy'; import { @@ -15,14 +15,16 @@ import { exec } from 'teen_process'; import { bundleWDASim } from './check-dependencies'; import { WDA_RUNNER_BUNDLE_ID, WDA_RUNNER_BUNDLE_ID_FOR_XCTEST, WDA_RUNNER_APP, - WDA_BASE_URL, WDA_UPGRADE_TIMESTAMP_PATH, + WDA_BASE_URL, WDA_UPGRADE_TIMESTAMP_PATH } from './constants'; import {Xctest} from 'appium-ios-device'; +import {strongbox} from '@appium/strongbox'; const WDA_LAUNCH_TIMEOUT = 60 * 1000; const WDA_AGENT_PORT = 8100; const WDA_CF_BUNDLE_NAME = 'WebDriverAgentRunner-Runner'; const SHARED_RESOURCES_GUARD = new AsyncLock(); +const RECENT_MODULE_VERSION_ITEM_NAME = 'recentWdaModuleVersion'; class WebDriverAgent { constructor (xcodeVersion, args = {}, log = null) { @@ -224,63 +226,61 @@ class WebDriverAgent { } async _cleanupProjectIfFresh () { - const homeFolder = process.env.HOME; - if (!homeFolder) { - this.log.info('The HOME folder path cannot be determined'); - return; - } - - const currentUpgradeTimestamp = await getWDAUpgradeTimestamp(); - if (!_.isInteger(currentUpgradeTimestamp)) { - this.log.info('It is impossible to determine the timestamp of the package'); + if (this.canSkipXcodebuild) { return; } - const timestampPath = path.resolve(homeFolder, WDA_UPGRADE_TIMESTAMP_PATH); - const didTimestampExist = await fs.exists(timestampPath); - if (didTimestampExist) { - try { - await fs.access(timestampPath, fs.W_OK); - } catch (ign) { - this.log.info(`WebDriverAgent upgrade timestamp at '${timestampPath}' is not writeable. ` + - `Skipping sources cleanup`); - return; - } - const recentUpgradeTimestamp = parseInt(await fs.readFile(timestampPath, 'utf8'), 10); - if (_.isInteger(recentUpgradeTimestamp)) { - if (recentUpgradeTimestamp >= currentUpgradeTimestamp) { - this.log.info(`WebDriverAgent does not need a cleanup. The sources are up to date ` + - `(${recentUpgradeTimestamp} >= ${currentUpgradeTimestamp})`); + const packageInfo = JSON.parse(await fs.readFile(path.join(BOOTSTRAP_PATH, 'package.json'), 'utf8')); + const box = strongbox(packageInfo.name); + let boxItem = box.getItem(RECENT_MODULE_VERSION_ITEM_NAME); + if (!boxItem) { + const timestampPath = path.resolve(process.env.HOME, WDA_UPGRADE_TIMESTAMP_PATH); + if (await fs.exists(timestampPath)) { + // TODO: It is probably a bit ugly to hardcode the recent version string, + // TODO: hovewer it should do the job as a temporary transition trick + // TODO: to switch from a hardcoded file path to the strongbox usage. + try { + boxItem = await box.createItemWithContents(RECENT_MODULE_VERSION_ITEM_NAME, '5.0.0'); + } catch (e) { + this.log.warn(`The actual module version cannot be persisted: ${e.message}`); return; } - this.log.info(`WebDriverAgent sources have been upgraded ` + - `(${recentUpgradeTimestamp} < ${currentUpgradeTimestamp})`); } else { - this.log.warn(`The recent upgrade timestamp at '${timestampPath}' is corrupted. Trying to fix it`); + this.log.info('There is no need to perform the project cleanup. A fresh install has been detected'); + try { + await box.createItemWithContents(RECENT_MODULE_VERSION_ITEM_NAME, packageInfo.version); + } catch (e) { + this.log.warn(`The actual module version cannot be persisted: ${e.message}`); + } + return; } } + let recentModuleVersion = await boxItem.read(); try { - await mkdirp(path.dirname(timestampPath)); - await fs.writeFile(timestampPath, `${currentUpgradeTimestamp}`, 'utf8'); - this.log.debug(`Stored the recent WebDriverAgent upgrade timestamp ${currentUpgradeTimestamp} ` + - `at '${timestampPath}'`); + recentModuleVersion = util.coerceVersion(recentModuleVersion, true); } catch (e) { - this.log.info(`Unable to create the recent WebDriverAgent upgrade timestamp at '${timestampPath}'. ` + - `Original error: ${e.message}`); + this.log.warn(`The persisted module version string has been damaged: ${e.message}`); + this.log.info(`Updating it to '${packageInfo.version}' assuming the project clenup is not needed`); + await boxItem.write(packageInfo.version); return; } - if (!didTimestampExist) { - this.log.info('There is no need to perform the project cleanup. A fresh install has been detected'); + if (util.compareVersions(recentModuleVersion, '>=', packageInfo.version)) { + this.log.info( + `WebDriverAgent does not need a cleanup. The project sources are up to date ` + + `(${recentModuleVersion} >= ${packageInfo.version})` + ); return; } - if (this.canSkipXcodebuild) { - return; - } + this.log.info( + `Cleaning up the WebDriverAgent project after the module upgrade has happened ` + + `(${recentModuleVersion} < ${packageInfo.version})` + ); try { await this.xcodebuild.cleanProject(); + await boxItem.write(packageInfo.version); } catch (e) { this.log.warn(`Cannot perform WebDriverAgent project cleanup. Original error: ${e.message}`); } diff --git a/package.json b/package.json index 33183142a..069be4176 100644 --- a/package.json +++ b/package.json @@ -84,6 +84,7 @@ }, "dependencies": { "@appium/base-driver": "^9.0.0", + "@appium/strongbox": "^0.x", "@appium/support": "^4.0.0", "@babel/runtime": "^7.0.0", "appium-ios-device": "^2.5.0", From 1be93e7e2d8f1330680cb72196e8647bf41e1bd0 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 22 May 2023 07:25:17 +0000 Subject: [PATCH 132/240] chore(release): 5.3.0 [skip ci] ## [5.3.0](https://github.com/appium/WebDriverAgent/compare/v5.2.0...v5.3.0) (2023-05-22) ### Features * Use strongbox to persist the previous version of the module ([#714](https://github.com/appium/WebDriverAgent/issues/714)) ([4611792](https://github.com/appium/WebDriverAgent/commit/4611792ee5d5d7f39d188b5ebc31017f436c5ace)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40c8f9b69..3110ef040 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.3.0](https://github.com/appium/WebDriverAgent/compare/v5.2.0...v5.3.0) (2023-05-22) + + +### Features + +* Use strongbox to persist the previous version of the module ([#714](https://github.com/appium/WebDriverAgent/issues/714)) ([4611792](https://github.com/appium/WebDriverAgent/commit/4611792ee5d5d7f39d188b5ebc31017f436c5ace)) + ## [5.2.0](https://github.com/appium/WebDriverAgent/compare/v5.1.6...v5.2.0) (2023-05-20) diff --git a/package.json b/package.json index 069be4176..af98cd09c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.2.0", + "version": "5.3.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 8bc3135f021b529d916846477544f4b8ca890f59 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Thu, 1 Jun 2023 11:14:35 -0700 Subject: [PATCH 133/240] ci: build wda for simulators in a task (#718) * refer to env.HOST * ci: use a shell script * ci: tweak paths * ci: tweak name * add zip for sim * ci: tweak the naming * tweak a bit * tweak the paths * simplify simulators * fix syntax error * fix syntax of runs on * fix synax * remove unnecessary env * try matrix * tweak * tweak naming * tweak * run after a release task as well --- .github/workflows/wda-package.yml | 102 ++++++++++++++++++++---------- Scripts/ci/build-real.sh | 17 +++++ Scripts/ci/build-sim.sh | 19 ++++++ 3 files changed, 105 insertions(+), 33 deletions(-) create mode 100755 Scripts/ci/build-real.sh create mode 100755 Scripts/ci/build-sim.sh diff --git a/.github/workflows/wda-package.yml b/.github/workflows/wda-package.yml index 21cfe155a..d544e927e 100644 --- a/.github/workflows/wda-package.yml +++ b/.github/workflows/wda-package.yml @@ -2,18 +2,35 @@ name: Building WebDriverAgent on: workflow_dispatch: + workflow_run: + workflows: ["Release"] + types: + - completed + +env: + HOST: macos-12 + XCODE_VERSION: 14.2 + DESTINATION_SIM: platform=iOS Simulator,name=iPhone 14 Pro + DESTINATION_SIM_tvOS: platform=tvOS Simulator,name=Apple TV jobs: - build: + host_machine: + runs-on: ubuntu-latest + outputs: + host: ${{ steps.macos_host.outputs.host }} + steps: + - run: | + echo "host=${{ env.HOST }}" >> $GITHUB_OUTPUT + id: macos_host + + for_real_devices: + needs: [host_machine] name: Build WDA for real iOS and tvOS devices - runs-on: macos-12 + runs-on: ${{ needs.host_machine.outputs.host }} env: - XCODE_VERSION: 14.1 ZIP_PKG_NAME_IOS: "WebDriverAgentRunner-Runner.zip" - PKG_PATH_IOS: "appium_wda_ios" ZIP_PKG_NAME_TVOS: "WebDriverAgentRunner_tvOS-Runner.zip" - PKG_PATH_TVOS: "appium_wda_tvos" steps: - name: Checkout @@ -21,34 +38,24 @@ jobs: - uses: maxim-lobanov/setup-xcode@v1 with: xcode-version: "${{ env.XCODE_VERSION }}" - - name: Build iOS - run: | - xcodebuild clean build-for-testing \ - -project WebDriverAgent.xcodeproj \ - -derivedDataPath $PKG_PATH_IOS \ - -scheme WebDriverAgentRunner \ - -destination generic/platform=iOS \ - CODE_SIGNING_ALLOWED=NO ARCHS=arm64 - - name: Creating a zip of WebDriverAgentRunner-Runner.app for iOS - run: | - pushd appium_wda_ios/Build/Products/Debug-iphoneos - zip -r $ZIP_PKG_NAME_IOS WebDriverAgentRunner-Runner.app - popd - mv $PKG_PATH_IOS/Build/Products/Debug-iphoneos/$ZIP_PKG_NAME_IOS ./ - - name: Build tvOS - run: | - xcodebuild clean build-for-testing \ - -project WebDriverAgent.xcodeproj \ - -derivedDataPath $PKG_PATH_TVOS \ - -scheme WebDriverAgentRunner_tvOS \ - -destination generic/platform=tvOS \ - CODE_SIGNING_ALLOWED=NO ARCHS=arm64 - - name: Creating a zip of WebDriverAgentRunner-Runner.app for tvOS - run: | - pushd appium_wda_tvos/Build/Products/Debug-appletvos - zip -r $ZIP_PKG_NAME_TVOS WebDriverAgentRunner_tvOS-Runner.app - popd - mv $PKG_PATH_TVOS/Build/Products/Debug-appletvos/$ZIP_PKG_NAME_TVOS ./ + - name: Create a zip file of WebDriverAgentRunner-Runner.app for iOS + run: sh $GITHUB_WORKSPACE/Scripts/ci/build-real.sh + env: + DERIVED_DATA_PATH: appium_wda_ios + SCHEME: WebDriverAgentRunner + DESTINATION: generic/platform=iOS + WD: appium_wda_ios/Build/Products/Debug-iphoneos + ZIP_PKG_NAME: "${{ env.ZIP_PKG_NAME_IOS }}" + + - name: Create a zip file of WebDriverAgentRunner-Runner.app for tvOS + run: sh $GITHUB_WORKSPACE/Scripts/ci/build-real.sh + env: + DERIVED_DATA_PATH: appium_wda_tvos + SCHEME: WebDriverAgentRunner_tvOS + DESTINATION: generic/platform=tvOS + WD: appium_wda_tvos/Build/Products/Debug-appletvos + ZIP_PKG_NAME: "${{ env.ZIP_PKG_NAME_TVOS }}" + - name: Upload the built generic app package for iOS uses: actions/upload-artifact@v3.1.0 with: @@ -57,3 +64,32 @@ jobs: uses: actions/upload-artifact@v3.1.0 with: path: "${{ env.ZIP_PKG_NAME_TVOS }}" + + for_simulator_devices: + needs: [host_machine] + name: Build WDA for ${{ matrix.target }} simulators + runs-on: ${{ needs.host_machine.outputs.host }} + + strategy: + matrix: + # '' is for iOS + target: ['', '_tvOS'] + arch: [x86_64, arm64] + steps: + - name: Checkout + uses: actions/checkout@v3 + - uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: "${{ env.XCODE_VERSION }}" + - name: Create a zip of WebDriverAgentRunner${{ matrix.target }} for simulator for ${{ matrix.arch }} + run: | + DESTINATION=$DESTINATION_SIM${{ matrix.target }} sh $GITHUB_WORKSPACE/Scripts/ci/build-sim.sh + env: + TARGET: ${{ matrix.target }} + SCHEME: WebDriverAgentRunner${{ matrix.target }} + ARCHS: ${{ matrix.arch }} + ZIP_PKG_NAME: "WebDriverAgentRunner${{ matrix.target }}-Build-Sim-${{ matrix.arch }}.zip" + - name: Upload the built generic app package for WebDriverAgentRunner${{ matrix.target }} with ${{ matrix.arch }} + uses: actions/upload-artifact@v3.1.0 + with: + path: "WebDriverAgentRunner${{ matrix.target }}-Build-Sim-${{ matrix.arch }}.zip" diff --git a/Scripts/ci/build-real.sh b/Scripts/ci/build-real.sh new file mode 100755 index 000000000..9303ffe3b --- /dev/null +++ b/Scripts/ci/build-real.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# To run build script for CI + +xcodebuild clean build-for-testing \ + -project WebDriverAgent.xcodeproj \ + -derivedDataPath $DERIVED_DATA_PATH \ + -scheme $SCHEME \ + -destination "$DESTINATION" \ + CODE_SIGNING_ALLOWED=NO ARCHS=arm64 + +# Only .app is needed. + +pushd $WD +zip -r $ZIP_PKG_NAME $SCHEME-Runner.app +popd +mv $WD/$ZIP_PKG_NAME ./ diff --git a/Scripts/ci/build-sim.sh b/Scripts/ci/build-sim.sh new file mode 100755 index 000000000..de52abccf --- /dev/null +++ b/Scripts/ci/build-sim.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# To run build script for CI + +xcodebuild clean build-for-testing \ + -project WebDriverAgent.xcodeproj \ + -derivedDataPath wda_build \ + -scheme $SCHEME \ + -destination "$DESTINATION" \ + CODE_SIGNING_ALLOWED=NO ARCHS=$ARCHS + +# simulator needs to build entire build files + +pushd wda_build +# to remove unnecessary space consuming files +rm -rf Build/Intermediates.noindex +zip -r $ZIP_PKG_NAME Build +popd +mv wda_build/$ZIP_PKG_NAME ./ From 5f811ac65ba3ac770e42bd7f8614815df8ec990f Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Mon, 5 Jun 2023 21:47:47 -0700 Subject: [PATCH 134/240] fix: remove Parameter of overriding method should be annotated with __attribute__((noescape)) (#720) --- PrivateHeaders/XCTest/XCTestCase.h | 1 - 1 file changed, 1 deletion(-) diff --git a/PrivateHeaders/XCTest/XCTestCase.h b/PrivateHeaders/XCTest/XCTestCase.h index f00038ef9..d68d949c5 100644 --- a/PrivateHeaders/XCTest/XCTestCase.h +++ b/PrivateHeaders/XCTest/XCTestCase.h @@ -51,7 +51,6 @@ - (void)reportMeasurements:(id)arg1 forMetricID:(id)arg2 reportFailures:(BOOL)arg3; - (void)_recordValues:(id)arg1 forPerformanceMetricID:(id)arg2 name:(id)arg3 unitsOfMeasurement:(id)arg4 baselineName:(id)arg5 baselineAverage:(id)arg6 maxPercentRegression:(id)arg7 maxPercentRelativeStandardDeviation:(id)arg8 maxRegression:(id)arg9 maxStandardDeviation:(id)arg10 file:(id)arg11 line:(unsigned long long)arg12; - (id)_symbolicationRecordForTestCodeInAddressStack:(id)arg1; -- (void)measureBlock:(CDUnknownBlockType)arg1; - (void)stopMeasuring; - (void)startMeasuring; - (BOOL)_isMeasuringMetrics; From 244b8b85e671a20f21991fc13e21678848058fad Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 6 Jun 2023 05:00:44 +0000 Subject: [PATCH 135/240] chore(release): 5.3.1 [skip ci] ## [5.3.1](https://github.com/appium/WebDriverAgent/compare/v5.3.0...v5.3.1) (2023-06-06) ### Bug Fixes * remove Parameter of overriding method should be annotated with __attribute__((noescape)) ([#720](https://github.com/appium/WebDriverAgent/issues/720)) ([5f811ac](https://github.com/appium/WebDriverAgent/commit/5f811ac65ba3ac770e42bd7f8614815df8ec990f)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3110ef040..f61b4edc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.3.1](https://github.com/appium/WebDriverAgent/compare/v5.3.0...v5.3.1) (2023-06-06) + + +### Bug Fixes + +* remove Parameter of overriding method should be annotated with __attribute__((noescape)) ([#720](https://github.com/appium/WebDriverAgent/issues/720)) ([5f811ac](https://github.com/appium/WebDriverAgent/commit/5f811ac65ba3ac770e42bd7f8614815df8ec990f)) + ## [5.3.0](https://github.com/appium/WebDriverAgent/compare/v5.2.0...v5.3.0) (2023-05-22) diff --git a/package.json b/package.json index af98cd09c..76d2c5f9d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.3.0", + "version": "5.3.1", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From b22f61eda142ee6ec1db8c74a4788e0270ac7740 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jun 2023 14:17:39 -0700 Subject: [PATCH 136/240] chore(deps-dev): bump conventional-changelog-conventionalcommits (#723) Bumps [conventional-changelog-conventionalcommits](https://github.com/conventional-changelog/conventional-changelog) from 5.0.0 to 6.0.0. - [Release notes](https://github.com/conventional-changelog/conventional-changelog/releases) - [Changelog](https://github.com/conventional-changelog/conventional-changelog/blob/master/.release-please-manifest.json) - [Commits](https://github.com/conventional-changelog/conventional-changelog/compare/conventional-changelog-conventionalcommits-v5.0.0...conventional-changelog-conventionalcommits-v6.0.0) --- updated-dependencies: - dependency-name: conventional-changelog-conventionalcommits dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 76d2c5f9d..f7969b0fd 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "appium-xcode": "^5.0.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", - "conventional-changelog-conventionalcommits": "^5.0.0", + "conventional-changelog-conventionalcommits": "^6.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.5.0", "glob": "^8.0.1", From 28b6e21df8173de8bf96c17452bf7432412fd9c5 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 7 Jun 2023 21:28:12 +0000 Subject: [PATCH 137/240] chore(release): 5.3.2 [skip ci] ## [5.3.2](https://github.com/appium/WebDriverAgent/compare/v5.3.1...v5.3.2) (2023-06-07) ### Miscellaneous Chores * **deps-dev:** bump conventional-changelog-conventionalcommits ([#723](https://github.com/appium/WebDriverAgent/issues/723)) ([b22f61e](https://github.com/appium/WebDriverAgent/commit/b22f61eda142ee6ec1db8c74a4788e0270ac7740)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f61b4edc9..3284ed63a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.3.2](https://github.com/appium/WebDriverAgent/compare/v5.3.1...v5.3.2) (2023-06-07) + + +### Miscellaneous Chores + +* **deps-dev:** bump conventional-changelog-conventionalcommits ([#723](https://github.com/appium/WebDriverAgent/issues/723)) ([b22f61e](https://github.com/appium/WebDriverAgent/commit/b22f61eda142ee6ec1db8c74a4788e0270ac7740)) + ## [5.3.1](https://github.com/appium/WebDriverAgent/compare/v5.3.0...v5.3.1) (2023-06-06) diff --git a/package.json b/package.json index f7969b0fd..3d8c3763f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.3.1", + "version": "5.3.2", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From a070223e0ef43be8dd54d16ee3e3b96603ad5f3a Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 8 Jun 2023 19:31:31 +0000 Subject: [PATCH 138/240] chore: Disable automatic screen recording by default (#726) --- WebDriverAgentLib/Utilities/FBConfiguration.h | 6 +++++- WebDriverAgentLib/Utilities/FBConfiguration.m | 10 ++++++++++ WebDriverAgentRunner/UITestingUITests.m | 5 +++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/WebDriverAgentLib/Utilities/FBConfiguration.h b/WebDriverAgentLib/Utilities/FBConfiguration.h index 7bfbccc43..bcb341a8d 100644 --- a/WebDriverAgentLib/Utilities/FBConfiguration.h +++ b/WebDriverAgentLib/Utilities/FBConfiguration.h @@ -49,10 +49,14 @@ extern NSString *const FBSnapshotMaxDepthKey; /*! Disables XCTest automated screenshots taking */ + (void)disableScreenshots; - /*! Enables XCTest automated screenshots taking */ + (void)enableScreenshots; +/*! Disables XCTest automated videos taking (iOS 17+) */ ++ (void)disableScreenRecordings; +/*! Enables XCTest automated videos taking (iOS 17+) */ ++ (void)enableScreenRecordings; + /* The maximum typing frequency for all typing activities */ + (void)setMaxTypingFrequency:(NSUInteger)value; + (NSUInteger)maxTypingFrequency; diff --git a/WebDriverAgentLib/Utilities/FBConfiguration.m b/WebDriverAgentLib/Utilities/FBConfiguration.m index 1c80e5498..f99c9d148 100644 --- a/WebDriverAgentLib/Utilities/FBConfiguration.m +++ b/WebDriverAgentLib/Utilities/FBConfiguration.m @@ -94,6 +94,16 @@ + (void)enableScreenshots [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"DisableScreenshots"]; } ++ (void)disableScreenRecordings +{ + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"DisableDiagnosticScreenRecordings"]; +} + ++ (void)enableScreenRecordings +{ + [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"DisableDiagnosticScreenRecordings"]; +} + + (NSRange)bindingPortRange { // 'WebDriverAgent --port 8080' can be passed via the arguments to the process diff --git a/WebDriverAgentRunner/UITestingUITests.m b/WebDriverAgentRunner/UITestingUITests.m index c98fbd622..cc7c78073 100644 --- a/WebDriverAgentRunner/UITestingUITests.m +++ b/WebDriverAgentRunner/UITestingUITests.m @@ -26,6 +26,11 @@ + (void)setUp [FBConfiguration disableRemoteQueryEvaluation]; [FBConfiguration configureDefaultKeyboardPreferences]; [FBConfiguration disableApplicationUIInterruptionsHandling]; + if (NSProcessInfo.processInfo.environment[@"ENABLE_AUTOMATIC_SCREEN_RECORDINGS"]) { + [FBConfiguration enableScreenRecordings]; + } else { + [FBConfiguration disableScreenRecordings]; + } if (NSProcessInfo.processInfo.environment[@"ENABLE_AUTOMATIC_SCREENSHOTS"]) { [FBConfiguration enableScreenshots]; } else { From 0c198ed4a7af1eb5434199dddd0fe909ad8bf6c6 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 8 Jun 2023 19:40:28 +0000 Subject: [PATCH 139/240] chore(release): 5.3.3 [skip ci] ## [5.3.3](https://github.com/appium/WebDriverAgent/compare/v5.3.2...v5.3.3) (2023-06-08) ### Miscellaneous Chores * Disable automatic screen recording by default ([#726](https://github.com/appium/WebDriverAgent/issues/726)) ([a070223](https://github.com/appium/WebDriverAgent/commit/a070223e0ef43be8dd54d16ee3e3b96603ad5f3a)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3284ed63a..fdbe0c6ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.3.3](https://github.com/appium/WebDriverAgent/compare/v5.3.2...v5.3.3) (2023-06-08) + + +### Miscellaneous Chores + +* Disable automatic screen recording by default ([#726](https://github.com/appium/WebDriverAgent/issues/726)) ([a070223](https://github.com/appium/WebDriverAgent/commit/a070223e0ef43be8dd54d16ee3e3b96603ad5f3a)) + ## [5.3.2](https://github.com/appium/WebDriverAgent/compare/v5.3.1...v5.3.2) (2023-06-07) diff --git a/package.json b/package.json index 3d8c3763f..0b530ba41 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.3.2", + "version": "5.3.3", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 364b7791393ffae9c048c5cac023e3e7d1813a14 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Fri, 9 Jun 2023 06:34:36 +0000 Subject: [PATCH 140/240] fix: Streamline errors handling for async block calls (#725) --- .../Utilities/FBXCTestDaemonsProxy.m | 118 ++++++++++-------- 1 file changed, 67 insertions(+), 51 deletions(-) diff --git a/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m b/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m index 2bee1b96c..180689800 100644 --- a/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m +++ b/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m @@ -100,13 +100,12 @@ + (void)swizzleLaunchApp { + (BOOL)synthesizeEventWithRecord:(XCSynthesizedEventRecord *)record error:(NSError *__autoreleasing*)error { - __block BOOL didSucceed = NO; + __block NSError *innerError = nil; [FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){ void (^errorHandler)(NSError *) = ^(NSError *invokeError) { - if (error) { - *error = invokeError; + if (nil != invokeError) { + innerError = invokeError; } - didSucceed = (invokeError == nil); completion(); }; @@ -117,31 +116,40 @@ + (BOOL)synthesizeEventWithRecord:(XCSynthesizedEventRecord *)record error:(NSEr handlerBlock(record, invokeError); }]; }]; - return didSucceed; + if (nil != innerError) { + if (error) { + *error = innerError; + } + return NO; + } + return YES; } + (BOOL)openURL:(NSURL *)url usingApplication:(NSString *)bundleId error:(NSError *__autoreleasing*)error { XCTRunnerDaemonSession *session = [XCTRunnerDaemonSession sharedSession]; if (![session respondsToSelector:@selector(openURL:usingApplication:completion:)]) { - if (error) { - [[[FBErrorBuilder builder] - withDescriptionFormat:@"The current Xcode SDK does not support opening of URLs with given application"] - buildError:error]; - } + [[[FBErrorBuilder builder] + withDescriptionFormat:@"The current Xcode SDK does not support opening of URLs with given application"] + buildError:error]; return NO; } + __block NSError *innerError = nil; __block BOOL didSucceed = NO; [FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){ [session openURL:url usingApplication:bundleId completion:^(bool result, NSError *invokeError) { - if (error) { - *error = invokeError; + if (nil != invokeError) { + innerError = invokeError; + } else { + didSucceed = result; } - didSucceed = invokeError == nil && result; completion(); }]; }]; + if (nil != innerError && error) { + *error = innerError; + } return didSucceed; } @@ -149,24 +157,27 @@ + (BOOL)openDefaultApplicationForURL:(NSURL *)url error:(NSError *__autoreleasin { XCTRunnerDaemonSession *session = [XCTRunnerDaemonSession sharedSession]; if (![session respondsToSelector:@selector(openDefaultApplicationForURL:completion:)]) { - if (error) { - [[[FBErrorBuilder builder] - withDescriptionFormat:@"The current Xcode SDK does not support opening of URLs. Consider upgrading to Xcode 14.3+/iOS 16.4+"] - buildError:error]; - } + [[[FBErrorBuilder builder] + withDescriptionFormat:@"The current Xcode SDK does not support opening of URLs. Consider upgrading to Xcode 14.3+/iOS 16.4+"] + buildError:error]; return NO; } + __block NSError *innerError = nil; __block BOOL didSucceed = NO; [FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){ [session openDefaultApplicationForURL:url completion:^(bool result, NSError *invokeError) { - if (error) { - *error = invokeError; + if (nil != invokeError) { + innerError = invokeError; + } else { + didSucceed = result; } - didSucceed = invokeError == nil && result; completion(); }]; }]; + if (nil != innerError && error) { + *error = innerError; + } return didSucceed; } @@ -175,32 +186,33 @@ + (BOOL)setSimulatedLocation:(CLLocation *)location error:(NSError *__autoreleas { XCTRunnerDaemonSession *session = [XCTRunnerDaemonSession sharedSession]; if (![session respondsToSelector:@selector(setSimulatedLocation:completion:)]) { - if (error) { - [[[FBErrorBuilder builder] - withDescriptionFormat:@"The current Xcode SDK does not support location simulation. Consider upgrading to Xcode 14.3+/iOS 16.4+"] - buildError:error]; - } + [[[FBErrorBuilder builder] + withDescriptionFormat:@"The current Xcode SDK does not support location simulation. Consider upgrading to Xcode 14.3+/iOS 16.4+"] + buildError:error]; return NO; } if (![session supportsLocationSimulation]) { - if (error) { - [[[FBErrorBuilder builder] - withDescriptionFormat:@"Your device does not support location simulation"] - buildError:error]; - } + [[[FBErrorBuilder builder] + withDescriptionFormat:@"Your device does not support location simulation"] + buildError:error]; return NO; } + __block NSError *innerError = nil; __block BOOL didSucceed = NO; [FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){ [session setSimulatedLocation:location completion:^(bool result, NSError *invokeError) { - if (error) { - *error = invokeError; + if (nil != invokeError) { + innerError = invokeError; + } else { + didSucceed = result; } - didSucceed = invokeError == nil && result; completion(); }]; }]; + if (nil != innerError && error) { + *error = innerError; + } return didSucceed; } @@ -208,34 +220,33 @@ + (nullable CLLocation *)getSimulatedLocation:(NSError *__autoreleasing*)error; { XCTRunnerDaemonSession *session = [XCTRunnerDaemonSession sharedSession]; if (![session respondsToSelector:@selector(getSimulatedLocationWithReply:)]) { - if (error) { - [[[FBErrorBuilder builder] - withDescriptionFormat:@"The current Xcode SDK does not support location simulation. Consider upgrading to Xcode 14.3+/iOS 16.4+"] - buildError:error]; - } + [[[FBErrorBuilder builder] + withDescriptionFormat:@"The current Xcode SDK does not support location simulation. Consider upgrading to Xcode 14.3+/iOS 16.4+"] + buildError:error]; return nil; } if (![session supportsLocationSimulation]) { - if (error) { - [[[FBErrorBuilder builder] - withDescriptionFormat:@"Your device does not support location simulation"] - buildError:error]; - } + [[[FBErrorBuilder builder] + withDescriptionFormat:@"Your device does not support location simulation"] + buildError:error]; return nil; } + __block NSError *innerError = nil; __block CLLocation *location = nil; [FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){ [session getSimulatedLocationWithReply:^(CLLocation *reply, NSError *invokeError) { - if (error) { - *error = invokeError; - } - if (nil == invokeError) { + if (nil != invokeError) { + innerError = invokeError; + } else { location = reply; } completion(); }]; }]; + if (nil != innerError && error) { + *error = innerError; + } return location; } @@ -259,16 +270,21 @@ + (BOOL)clearSimulatedLocation:(NSError *__autoreleasing*)error return NO; } + __block NSError *innerError = nil; __block BOOL didSucceed = NO; [FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){ [session clearSimulatedLocationWithReply:^(bool result, NSError *invokeError) { - if (error) { - *error = invokeError; + if (nil != invokeError) { + innerError = invokeError; + } else { + didSucceed = result; } - didSucceed = invokeError == nil && result; completion(); }]; }]; + if (nil != innerError && error) { + *error = innerError; + } return didSucceed; } #endif From 4a08d7a843af6b93b378b4e3dc10f123d2e56359 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Fri, 9 Jun 2023 06:34:54 +0000 Subject: [PATCH 141/240] feat: Drop older screenshoting APIs (#721) --- WebDriverAgentLib/Utilities/FBConfiguration.h | 6 +- WebDriverAgentLib/Utilities/FBConfiguration.m | 2 +- WebDriverAgentLib/Utilities/FBImageIOScaler.h | 10 +- WebDriverAgentLib/Utilities/FBImageIOScaler.m | 13 +- WebDriverAgentLib/Utilities/FBMjpegServer.m | 15 +- WebDriverAgentLib/Utilities/FBScreenshot.h | 20 +- WebDriverAgentLib/Utilities/FBScreenshot.m | 176 ++++++------------ .../Utilities/FBUnattachedAppLauncher.m | 3 + .../IntegrationTests/FBImageIOScalerTests.m | 2 - 9 files changed, 89 insertions(+), 158 deletions(-) diff --git a/WebDriverAgentLib/Utilities/FBConfiguration.h b/WebDriverAgentLib/Utilities/FBConfiguration.h index bcb341a8d..8bb9d48ca 100644 --- a/WebDriverAgentLib/Utilities/FBConfiguration.h +++ b/WebDriverAgentLib/Utilities/FBConfiguration.h @@ -93,9 +93,9 @@ extern NSString *const FBSnapshotMaxDepthKey; + (void)setMjpegServerFramerate:(NSUInteger)framerate; /** - The quality of phone display screenshots. The higher quality you set is the bigger screenshot size is. - The highest quality value is 0 (lossless PNG). The lowest quality is 2 (highly compressed JPEG). - The default quality value is 1 (high quality JPEG). + The quality of display screenshots. The higher quality you set is the bigger screenshot size is. + The highest quality value is 0 (lossless PNG) or 3 (lossless HEIC). The lowest quality is 2 (highly compressed JPEG). + The default quality value is 3 (lossless HEIC). See https://developer.apple.com/documentation/xctest/xctimagequality?language=objc */ + (NSUInteger)screenshotQuality; diff --git a/WebDriverAgentLib/Utilities/FBConfiguration.m b/WebDriverAgentLib/Utilities/FBConfiguration.m index f99c9d148..f149d2193 100644 --- a/WebDriverAgentLib/Utilities/FBConfiguration.m +++ b/WebDriverAgentLib/Utilities/FBConfiguration.m @@ -453,7 +453,7 @@ + (void)resetSessionSettings FBShouldUseCompactResponses = YES; FBElementResponseAttributes = @"type,label"; FBMaxTypingFrequency = 60; - FBScreenshotQuality = 1; + FBScreenshotQuality = 3; FBCustomSnapshotTimeout = 15.; FBShouldUseFirstMatch = NO; FBShouldBoundElementsByIndex = NO; diff --git a/WebDriverAgentLib/Utilities/FBImageIOScaler.h b/WebDriverAgentLib/Utilities/FBImageIOScaler.h index d5801142a..476daba04 100644 --- a/WebDriverAgentLib/Utilities/FBImageIOScaler.h +++ b/WebDriverAgentLib/Utilities/FBImageIOScaler.h @@ -10,6 +10,8 @@ #import #import +@class UTType; + NS_ASSUME_NONNULL_BEGIN // Those values define the allowed ranges for the scaling factor and compression quality settings @@ -25,14 +27,12 @@ extern const CGFloat FBMaxCompressionQuality; queue it will be replaced with the new one @param image The image to scale down - @param uti Either kUTTypePNG or kUTTypeJPEG @param completionHandler called after successfully scaling down an image @param scalingFactor the scaling factor in range 0.01..1.0. A value of 1.0 won't perform scaling at all @param compressionQuality the compression quality in range 0.0..1.0 (0.0 for max. compression and 1.0 for lossless compression) - Only applicable for kUTTypeJPEG + Only applicable for UTTypeJPEG */ - (void)submitImage:(NSData *)image - uti:(NSString *)uti scalingFactor:(CGFloat)scalingFactor compressionQuality:(CGFloat)compressionQuality completionHandler:(void (^)(NSData *))completionHandler; @@ -41,7 +41,7 @@ extern const CGFloat FBMaxCompressionQuality; Scales and crops the source image @param image The source image data - @param uti Either kUTTypePNG or kUTTypeJPEG + @param uti Either UTTypePNG or UTTypeJPEG @param rect The cropping rectange for the screenshot. The value is expected to be non-scaled one since it happens after scaling/orientation change. CGRectNull could be used to take a screenshot of the full screen. @@ -52,7 +52,7 @@ extern const CGFloat FBMaxCompressionQuality; @returns Processed image data compressed according to the given UTI or nil in case of a failure */ - (nullable NSData *)scaledImageWithImage:(NSData *)image - uti:(NSString *)uti + uti:(UTType *)uti rect:(CGRect)rect scalingFactor:(CGFloat)scalingFactor compressionQuality:(CGFloat)compressionQuality diff --git a/WebDriverAgentLib/Utilities/FBImageIOScaler.m b/WebDriverAgentLib/Utilities/FBImageIOScaler.m index b0900c2c7..0ca87b747 100644 --- a/WebDriverAgentLib/Utilities/FBImageIOScaler.m +++ b/WebDriverAgentLib/Utilities/FBImageIOScaler.m @@ -11,7 +11,7 @@ #import #import -#import +@import UniformTypeIdentifiers; #import "FBConfiguration.h" #import "FBErrorBuilder.h" @@ -43,7 +43,6 @@ - (id)init } - (void)submitImage:(NSData *)image - uti:(NSString *)uti scalingFactor:(CGFloat)scalingFactor compressionQuality:(CGFloat)compressionQuality completionHandler:(void (^)(NSData *))completionHandler @@ -118,7 +117,7 @@ - (nullable NSData *)scaledJpegImageWithImage:(NSData *)image } - (nullable NSData *)scaledImageWithImage:(NSData *)image - uti:(NSString *)uti + uti:(UTType *)uti rect:(CGRect)rect scalingFactor:(CGFloat)scalingFactor compressionQuality:(CGFloat)compressionQuality @@ -154,7 +153,7 @@ - (nullable NSData *)scaledImageWithImage:(NSData *)image UIGraphicsEndImageContext(); } - return [uti isEqualToString:(__bridge id)kUTTypePNG] + return [uti conformsToType:UTTypePNG] ? UIImagePNGRepresentation(resultImage) : UIImageJPEGRepresentation(resultImage, compressionQuality); } @@ -163,7 +162,11 @@ - (nullable NSData *)jpegDataWithImage:(CGImageRef)imageRef compressionQuality:(CGFloat)compressionQuality { NSMutableData *newImageData = [NSMutableData data]; - CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((CFMutableDataRef)newImageData, kUTTypeJPEG, 1, NULL); + CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData( + (__bridge CFMutableDataRef) newImageData, + (__bridge CFStringRef) UTTypeJPEG.identifier, + 1, + NULL); CFDictionaryRef compressionOptions = (__bridge CFDictionaryRef)@{ (const NSString *)kCGImageDestinationLossyCompressionQuality: @(compressionQuality) }; diff --git a/WebDriverAgentLib/Utilities/FBMjpegServer.m b/WebDriverAgentLib/Utilities/FBMjpegServer.m index beacecc97..51fa48687 100644 --- a/WebDriverAgentLib/Utilities/FBMjpegServer.m +++ b/WebDriverAgentLib/Utilities/FBMjpegServer.m @@ -10,7 +10,7 @@ #import "FBMjpegServer.h" #import -#import +@import UniformTypeIdentifiers; #import "GCDAsyncSocket.h" #import "FBApplication.h" @@ -72,11 +72,6 @@ - (void)scheduleNextScreenshotWithInterval:(uint64_t)timerInterval timeStarted:( - (void)streamScreenshot { - if (![self.class canStreamScreenshots]) { - [FBLogger log:@"MJPEG server cannot start because the current iOS version is not supported"]; - return; - } - NSUInteger framerate = FBConfiguration.mjpegServerFramerate; uint64_t timerInterval = (uint64_t)(1.0 / ((0 == framerate || framerate > MAX_FPS) ? MAX_FPS : framerate) * NSEC_PER_SEC); uint64_t timeStarted = clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW); @@ -96,7 +91,7 @@ - (void)streamScreenshot NSError *error; NSData *screenshotData = [FBScreenshot takeInOriginalResolutionWithScreenID:self.mainScreenID compressionQuality:screenshotCompressionQuality - uti:(__bridge id)kUTTypeJPEG + uti:UTTypeJPEG timeout:FRAME_TIMEOUT error:&error]; if (nil == screenshotData) { @@ -107,7 +102,6 @@ - (void)streamScreenshot if (usesScaling) { [self.imageScaler submitImage:screenshotData - uti:(__bridge id)kUTTypeJPEG scalingFactor:scalingFactor compressionQuality:compressionQuality completionHandler:^(NSData * _Nonnull scaled) { @@ -132,11 +126,6 @@ - (void)sendScreenshot:(NSData *)screenshotData { } } -+ (BOOL)canStreamScreenshots -{ - return [FBScreenshot isNewScreenshotAPISupported]; -} - - (void)didClientConnect:(GCDAsyncSocket *)newClient { [FBLogger logFmt:@"Got screenshots broadcast client connection at %@:%d", newClient.connectedHost, newClient.connectedPort]; diff --git a/WebDriverAgentLib/Utilities/FBScreenshot.h b/WebDriverAgentLib/Utilities/FBScreenshot.h index 52c6b8c29..036a5e1cb 100644 --- a/WebDriverAgentLib/Utilities/FBScreenshot.h +++ b/WebDriverAgentLib/Utilities/FBScreenshot.h @@ -8,22 +8,18 @@ */ #import +@class UTType; NS_ASSUME_NONNULL_BEGIN @interface FBScreenshot : NSObject -/** - Returns YES if the current OS SDK supports advanced screenshoting APIs (added since Xcode SDK 10) - */ -+ (BOOL)isNewScreenshotAPISupported; - /** Retrieves non-scaled screenshot of the whole screen - @param quality The number in range 0-2, where 2 (JPG) is the lowest and 0 (PNG) is the highest quality. + @param quality The number in range 0-3, where 0 is PNG (lossless), 3 is HEIC (lossless), 1- low quality JPEG and 2 - high quality JPEG @param error If there is an error, upon return contains an NSError object that describes the problem. - @return Device screenshot as PNG- or JPG-encoded data or nil in case of failure + @return Device screenshot as PNG-encoded data or nil in case of failure */ + (nullable NSData *)takeInOriginalResolutionWithQuality:(NSUInteger)quality error:(NSError **)error; @@ -31,11 +27,11 @@ NS_ASSUME_NONNULL_BEGIN /** Retrieves non-scaled screenshot of the particular screen rectangle - @param quality The number in range 0-2, where 2 (JPG) is the lowest and 0 (PNG) is the highest quality. + @param quality The number in range 0-3, where 0 is PNG (lossless), 3 is HEIC (lossless), 1- low quality JPEG and 2 - high quality JPEG @param rect The bounding rectange for the screenshot. The value is expected be non-scaled one. CGRectNull could be used to take a screenshot of the full screen. @param error If there is an error, upon return contains an NSError object that describes the problem. - @return Device screenshot as PNG- or JPG-encoded data or nil in case of failure + @return Device screenshot as PNG-encoded data or nil in case of failure */ + (nullable NSData *)takeInOriginalResolutionWithQuality:(NSUInteger)quality rect:(CGRect)rect @@ -46,14 +42,14 @@ NS_ASSUME_NONNULL_BEGIN @param screenID The screen identifier to take the screenshot from @param compressionQuality Normalized screenshot quality value in range 0..1, where 1 is the best quality - @param uti kUTType... constant, which defines the type of the returned screenshot image + @param uti UTType... constant, which defines the type of the returned screenshot image @param timeout how much time to allow for the screenshot to be taken @param error If there is an error, upon return contains an NSError object that describes the problem. - @return Device screenshot as PNG- or JPG-encoded data or nil in case of failure + @return Device screenshot as PNG-, HEIC- or JPG-encoded data or nil in case of failure */ + (nullable NSData *)takeInOriginalResolutionWithScreenID:(long long)screenID compressionQuality:(CGFloat)compressionQuality - uti:(NSString *)uti + uti:(UTType *)uti timeout:(NSTimeInterval)timeout error:(NSError **)error; diff --git a/WebDriverAgentLib/Utilities/FBScreenshot.m b/WebDriverAgentLib/Utilities/FBScreenshot.m index 740048e66..8cea6530d 100644 --- a/WebDriverAgentLib/Utilities/FBScreenshot.m +++ b/WebDriverAgentLib/Utilities/FBScreenshot.m @@ -9,7 +9,7 @@ #import "FBScreenshot.h" -#import +@import UniformTypeIdentifiers; #import "FBConfiguration.h" #import "FBErrorBuilder.h" @@ -33,16 +33,6 @@ @implementation FBScreenshot -+ (BOOL)isNewScreenshotAPISupported -{ - static dispatch_once_t newScreenshotAPISupported; - static BOOL result; - dispatch_once(&newScreenshotAPISupported, ^{ - result = [(NSObject *)[FBXCTestDaemonsProxy testRunnerProxy] respondsToSelector:@selector(_XCT_requestScreenshotOfScreenWithID:withRect:uti:compressionQuality:withReply:)]; - }); - return result; -} - + (CGFloat)compressionQualityWithQuality:(NSUInteger)quality { switch (quality) { @@ -55,14 +45,16 @@ + (CGFloat)compressionQualityWithQuality:(NSUInteger)quality } } -+ (NSString *)imageUtiWithQuality:(NSUInteger)quality ++ (UTType *)imageUtiWithQuality:(NSUInteger)quality { switch (quality) { case 1: case 2: - return (__bridge id)kUTTypeJPEG; + return UTTypeJPEG; + case 3: + return UTTypeHEIC; default: - return (__bridge id)kUTTypePNG; + return UTTypePNG; } } @@ -70,64 +62,28 @@ + (NSData *)takeInOriginalResolutionWithQuality:(NSUInteger)quality rect:(CGRect)rect error:(NSError **)error { - if ([self.class isNewScreenshotAPISupported]) { - XCUIScreen *mainScreen = XCUIScreen.mainScreen; - return [self.class takeWithScreenID:mainScreen.displayID - scale:SCREENSHOT_SCALE - compressionQuality:[self.class compressionQualityWithQuality:FBConfiguration.screenshotQuality] - rect:rect - sourceUTI:[self.class imageUtiWithQuality:FBConfiguration.screenshotQuality] - error:error]; - } - - [[[FBErrorBuilder builder] - withDescription:@"Screenshots of limited areas are only available for newer OS versions"] - buildError:error]; - return nil; + XCUIScreen *mainScreen = XCUIScreen.mainScreen; + return [self.class takeWithScreenID:mainScreen.displayID + scale:SCREENSHOT_SCALE + compressionQuality:[self.class compressionQualityWithQuality:quality] + rect:rect + sourceUTI:[self.class imageUtiWithQuality:quality] + error:error]; } + (NSData *)takeInOriginalResolutionWithQuality:(NSUInteger)quality error:(NSError **)error { - if ([self.class isNewScreenshotAPISupported]) { - XCUIScreen *mainScreen = XCUIScreen.mainScreen; - return [self.class takeWithScreenID:mainScreen.displayID - scale:SCREENSHOT_SCALE - compressionQuality:[self.class compressionQualityWithQuality:FBConfiguration.screenshotQuality] - rect:CGRectNull - sourceUTI:[self.class imageUtiWithQuality:FBConfiguration.screenshotQuality] - error:error]; - } - - id proxy = [FBXCTestDaemonsProxy testRunnerProxy]; - __block NSData *screenshotData = nil; - __block NSError *innerError = nil; - dispatch_semaphore_t sem = dispatch_semaphore_create(0); - [proxy _XCT_requestScreenshotWithReply:^(NSData *data, NSError *screenshotError) { - if (nil == screenshotError) { - screenshotData = data; - } else { - innerError = screenshotError; - } - dispatch_semaphore_signal(sem); - }]; - if (nil != innerError && error) { - *error = innerError; - } - int64_t timeoutNs = (int64_t)(SCREENSHOT_TIMEOUT * NSEC_PER_SEC); - if (0 != dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, timeoutNs))) { - [[[FBErrorBuilder builder] - withDescription:[NSString stringWithFormat:@"Cannot take a screenshot within %@ timeout", formatTimeInterval(SCREENSHOT_TIMEOUT)]] - buildError:error]; - }; - return screenshotData; + return [self.class takeInOriginalResolutionWithQuality:quality + rect:CGRectNull + error:error]; } + (NSData *)takeWithScreenID:(long long)screenID scale:(CGFloat)scale compressionQuality:(CGFloat)compressionQuality rect:(CGRect)rect - sourceUTI:(NSString *)uti + sourceUTI:(UTType *)uti error:(NSError **)error { NSData *screenshotData = [self.class takeInOriginalResolutionWithScreenID:screenID @@ -139,7 +95,7 @@ + (NSData *)takeWithScreenID:(long long)screenID return nil; } return [[[FBImageIOScaler alloc] init] scaledImageWithImage:screenshotData - uti:(__bridge id)kUTTypePNG + uti:UTTypePNG rect:rect scalingFactor:1.0 / scale compressionQuality:FBMaxCompressionQuality @@ -148,7 +104,7 @@ + (NSData *)takeWithScreenID:(long long)screenID + (NSData *)takeInOriginalResolutionWithScreenID:(long long)screenID compressionQuality:(CGFloat)compressionQuality - uti:(NSString *)uti + uti:(UTType *)uti timeout:(NSTimeInterval)timeout error:(NSError **)error { @@ -156,38 +112,23 @@ + (NSData *)takeInOriginalResolutionWithScreenID:(long long)screenID __block NSData *screenshotData = nil; __block NSError *innerError = nil; dispatch_semaphore_t sem = dispatch_semaphore_create(0); - if ([self.class shouldUseScreenshotRequestApiForProxy:(NSObject *)proxy]) { - id screnshotRequest = [self.class screenshotRequestWithScreenID:screenID - rect:CGRectNull - uti:uti - compressionQuality:compressionQuality - error:error]; - if (nil == screnshotRequest) { - return nil; - } - [proxy _XCT_requestScreenshot:screnshotRequest - withReply:^(id image, NSError *err) { - if (nil != err) { - innerError = err; - } else { - screenshotData = [image data]; - } - dispatch_semaphore_signal(sem); - }]; - } else { - [proxy _XCT_requestScreenshotOfScreenWithID:screenID - withRect:CGRectNull - uti:uti - compressionQuality:compressionQuality - withReply:^(NSData *data, NSError *err) { - if (nil != err) { - innerError = err; - } else { - screenshotData = data; - } - dispatch_semaphore_signal(sem); - }]; + id screnshotRequest = [self.class screenshotRequestWithScreenID:screenID + rect:CGRectNull + uti:uti + compressionQuality:compressionQuality + error:error]; + if (nil == screnshotRequest) { + return nil; } + [proxy _XCT_requestScreenshot:screnshotRequest + withReply:^(id image, NSError *err) { + if (nil != err) { + innerError = err; + } else { + screenshotData = [image data]; + } + dispatch_semaphore_signal(sem); + }]; int64_t timeoutNs = (int64_t)(timeout * NSEC_PER_SEC); if (0 != dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, timeoutNs))) { NSString *timeoutMsg = [NSString stringWithFormat:@"Cannot take a screenshot within %@ timeout", formatTimeInterval(SCREENSHOT_TIMEOUT)]; @@ -205,26 +146,7 @@ + (NSData *)takeInOriginalResolutionWithScreenID:(long long)screenID return screenshotData; } -+ (BOOL)shouldUseScreenshotRequestApiForProxy:(NSObject *)proxy -{ - static dispatch_once_t shouldUseSRApi; - static BOOL result; - dispatch_once(&shouldUseSRApi, ^{ - if ([proxy respondsToSelector:@selector(_XCT_requestScreenshot:withReply:)]) { -#if TARGET_OS_SIMULATOR - // Required to support simulators running iOS 14.4 and below with Xcode 12.5 and above due to unsupported API on the simulator side. - result = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"14.5"); -#else - result = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0"); -#endif - } else { - result = NO; - } - }); - return result; -} - -+ (nullable id)imageEncodingWithUniformTypeIdentifier:(NSString *)uti ++ (nullable id)imageEncodingWithUniformTypeIdentifier:(UTType *)uti compressionQuality:(CGFloat)compressionQuality error:(NSError **)error { @@ -235,6 +157,26 @@ + (nullable id)imageEncodingWithUniformTypeIdentifier:(NSString *)uti buildError:error]; return nil; } + + if ([uti conformsToType:UTTypeHEIC]) { + static BOOL isHeicSuppported = NO; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + SEL selector = NSSelectorFromString(@"supportsHEICImageEncoding"); + NSMethodSignature *signature = [imageEncodingClass methodSignatureForSelector:selector]; + if (nil != signature) { + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; + [invocation setSelector:selector]; + [invocation invokeWithTarget:imageEncodingClass]; + [invocation getReturnValue:&isHeicSuppported]; + } + }); + if (!isHeicSuppported) { + [FBLogger logFmt:@"The device under test does not support HEIC image encoding. Falling back to PNG"]; + uti = UTTypePNG; + } + } + id imageEncodingAllocated = [imageEncodingClass alloc]; SEL imageEncodingConstructorSelector = NSSelectorFromString(@"initWithUniformTypeIdentifier:compressionQuality:"); if (![imageEncodingAllocated respondsToSelector:imageEncodingConstructorSelector]) { @@ -246,7 +188,8 @@ + (nullable id)imageEncodingWithUniformTypeIdentifier:(NSString *)uti NSMethodSignature *imageEncodingContructorSignature = [imageEncodingAllocated methodSignatureForSelector:imageEncodingConstructorSelector]; NSInvocation *imageEncodingInitInvocation = [NSInvocation invocationWithMethodSignature:imageEncodingContructorSignature]; [imageEncodingInitInvocation setSelector:imageEncodingConstructorSelector]; - [imageEncodingInitInvocation setArgument:&uti atIndex:2]; + NSString *utiIdentifier = uti.identifier; + [imageEncodingInitInvocation setArgument:&utiIdentifier atIndex:2]; [imageEncodingInitInvocation setArgument:&compressionQuality atIndex:3]; [imageEncodingInitInvocation invokeWithTarget:imageEncodingAllocated]; id __unsafe_unretained imageEncoding; @@ -256,11 +199,10 @@ + (nullable id)imageEncodingWithUniformTypeIdentifier:(NSString *)uti + (nullable id)screenshotRequestWithScreenID:(long long)screenID rect:(struct CGRect)rect - uti:(NSString *)uti + uti:(UTType *)uti compressionQuality:(CGFloat)compressionQuality error:(NSError **)error { - // TODO: Use native accessors after we drop the support of Xcode 12.4 and below id imageEncoding = [self.class imageEncodingWithUniformTypeIdentifier:uti compressionQuality:compressionQuality error:error]; diff --git a/WebDriverAgentLib/Utilities/FBUnattachedAppLauncher.m b/WebDriverAgentLib/Utilities/FBUnattachedAppLauncher.m index 40b2278ab..f877b67c6 100644 --- a/WebDriverAgentLib/Utilities/FBUnattachedAppLauncher.m +++ b/WebDriverAgentLib/Utilities/FBUnattachedAppLauncher.m @@ -8,6 +8,9 @@ */ #import "FBUnattachedAppLauncher.h" + +#import + #import "LSApplicationWorkspace.h" @implementation FBUnattachedAppLauncher diff --git a/WebDriverAgentTests/IntegrationTests/FBImageIOScalerTests.m b/WebDriverAgentTests/IntegrationTests/FBImageIOScalerTests.m index 491e2cfd2..0c2f75b62 100644 --- a/WebDriverAgentTests/IntegrationTests/FBImageIOScalerTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBImageIOScalerTests.m @@ -8,7 +8,6 @@ */ #import -#import #import "FBImageIOScaler.h" #import "FBIntegrationTestCase.h" @@ -55,7 +54,6 @@ - (void)scaleImageWithFactor:(CGFloat)scalingFactor expectedSize:(CGSize)excpect id expScaled = [self expectationWithDescription:@"Receive scaled image"]; [scaler submitImage:self.originalImage - uti:(__bridge id)kUTTypeJPEG scalingFactor:scalingFactor compressionQuality:1.0 completionHandler:^(NSData *scaled) { From 4ac4f0b924cf63a106698b211709d66b51a25fe8 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 9 Jun 2023 07:05:51 +0000 Subject: [PATCH 142/240] chore(release): 5.4.0 [skip ci] ## [5.4.0](https://github.com/appium/WebDriverAgent/compare/v5.3.3...v5.4.0) (2023-06-09) ### Features * Drop older screenshoting APIs ([#721](https://github.com/appium/WebDriverAgent/issues/721)) ([4a08d7a](https://github.com/appium/WebDriverAgent/commit/4a08d7a843af6b93b378b4e3dc10f123d2e56359)) ### Bug Fixes * Streamline errors handling for async block calls ([#725](https://github.com/appium/WebDriverAgent/issues/725)) ([364b779](https://github.com/appium/WebDriverAgent/commit/364b7791393ffae9c048c5cac023e3e7d1813a14)) --- CHANGELOG.md | 12 ++++++++++++ package.json | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fdbe0c6ed..f28b44262 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## [5.4.0](https://github.com/appium/WebDriverAgent/compare/v5.3.3...v5.4.0) (2023-06-09) + + +### Features + +* Drop older screenshoting APIs ([#721](https://github.com/appium/WebDriverAgent/issues/721)) ([4a08d7a](https://github.com/appium/WebDriverAgent/commit/4a08d7a843af6b93b378b4e3dc10f123d2e56359)) + + +### Bug Fixes + +* Streamline errors handling for async block calls ([#725](https://github.com/appium/WebDriverAgent/issues/725)) ([364b779](https://github.com/appium/WebDriverAgent/commit/364b7791393ffae9c048c5cac023e3e7d1813a14)) + ## [5.3.3](https://github.com/appium/WebDriverAgent/compare/v5.3.2...v5.3.3) (2023-06-08) diff --git a/package.json b/package.json index 0b530ba41..03ad37773 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.3.3", + "version": "5.4.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From e6e2dbd86fc0c48ae146905f0e69a6223360e856 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Fri, 9 Jun 2023 17:24:27 +0000 Subject: [PATCH 143/240] fix: Return default testmanagerd version if the info is not available (#728) --- .../Utilities/FBXCodeCompatibility.m | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/WebDriverAgentLib/Utilities/FBXCodeCompatibility.m b/WebDriverAgentLib/Utilities/FBXCodeCompatibility.m index 911c5ec85..4d7bb621d 100644 --- a/WebDriverAgentLib/Utilities/FBXCodeCompatibility.m +++ b/WebDriverAgentLib/Utilities/FBXCodeCompatibility.m @@ -123,12 +123,16 @@ NSInteger FBTestmanagerdVersion(void) static NSInteger testmanagerdVersion; dispatch_once(&getTestmanagerdVersion, ^{ id proxy = [FBXCTestDaemonsProxy testRunnerProxy]; - dispatch_semaphore_t sem = dispatch_semaphore_create(0); - [proxy _XCT_exchangeProtocolVersion:testmanagerdVersion reply:^(unsigned long long code) { - testmanagerdVersion = (NSInteger) code; - dispatch_semaphore_signal(sem); - }]; - dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC))); + if ([(NSObject *)proxy respondsToSelector:@selector(_XCT_exchangeProtocolVersion:reply:)]) { + [FBRunLoopSpinner spinUntilCompletion:^(void(^completion)(void)){ + [proxy _XCT_exchangeProtocolVersion:testmanagerdVersion reply:^(unsigned long long code) { + testmanagerdVersion = (NSInteger) code; + completion(); + }]; + }]; + } else { + testmanagerdVersion = 0xFFFF; + } }); return testmanagerdVersion; } From 6c6b4cfa903bee15ee12a1e96a6c5a2fef74a4fa Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 9 Jun 2023 17:33:23 +0000 Subject: [PATCH 144/240] chore(release): 5.4.1 [skip ci] ## [5.4.1](https://github.com/appium/WebDriverAgent/compare/v5.4.0...v5.4.1) (2023-06-09) ### Bug Fixes * Return default testmanagerd version if the info is not available ([#728](https://github.com/appium/WebDriverAgent/issues/728)) ([e6e2dbd](https://github.com/appium/WebDriverAgent/commit/e6e2dbd86fc0c48ae146905f0e69a6223360e856)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f28b44262..260bb8b6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.4.1](https://github.com/appium/WebDriverAgent/compare/v5.4.0...v5.4.1) (2023-06-09) + + +### Bug Fixes + +* Return default testmanagerd version if the info is not available ([#728](https://github.com/appium/WebDriverAgent/issues/728)) ([e6e2dbd](https://github.com/appium/WebDriverAgent/commit/e6e2dbd86fc0c48ae146905f0e69a6223360e856)) + ## [5.4.0](https://github.com/appium/WebDriverAgent/compare/v5.3.3...v5.4.0) (2023-06-09) diff --git a/package.json b/package.json index 03ad37773..eb2f087da 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.4.0", + "version": "5.4.1", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 78321dd3dafdb142eed136b48ec101f1daed50a4 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Mon, 12 Jun 2023 20:01:13 +0000 Subject: [PATCH 145/240] feat: Add accessibility audit extension (#727) --- .../Categories/XCUIApplication+FBHelpers.h | 20 ++++ .../Categories/XCUIApplication+FBHelpers.m | 104 ++++++++++++++++++ WebDriverAgentLib/Commands/FBCustomCommands.m | 20 ++++ WebDriverAgentLib/FBApplication.m | 1 + .../XCUIApplicationHelperTests.m | 21 ++++ 5 files changed, 166 insertions(+) diff --git a/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.h b/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.h index 9d190a381..13fabcf88 100644 --- a/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.h +++ b/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.h @@ -103,6 +103,26 @@ NS_ASSUME_NONNULL_BEGIN - (BOOL)fb_dismissKeyboardWithKeyNames:(nullable NSArray *)keyNames error:(NSError **)error; +/** + A wrapper over https://developer.apple.com/documentation/xctest/xcuiapplication/4190847-performaccessibilityauditwithaud?language=objc + + @param auditTypes Combination of https://developer.apple.com/documentation/xctest/xcuiaccessibilityaudittype?language=objc + @param error If there is an error, upon return contains an NSError object that describes the problem. + @return List of found issues or nil if there was a failure + */ +- (nullable NSArray *> *)fb_performAccessibilityAuditWithAuditTypesSet:(NSSet *)auditTypes + error:(NSError **)error; + +/** + A wrapper over https://developer.apple.com/documentation/xctest/xcuiapplication/4190847-performaccessibilityauditwithaud?language=objc + + @param auditTypes Combination of https://developer.apple.com/documentation/xctest/xcuiaccessibilityaudittype?language=objc + @param error If there is an error, upon return contains an NSError object that describes the problem. + @return List of found issues or nil if there was a failure + */ +- (nullable NSArray *> *)fb_performAccessibilityAuditWithAuditTypes:(uint64_t)auditTypes + error:(NSError **)error; + @end NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m b/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m index ec752c5a0..7c9ff9967 100644 --- a/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +++ b/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m @@ -12,6 +12,7 @@ #import "FBElementTypeTransformer.h" #import "FBKeyboard.h" #import "FBLogger.h" +#import "FBExceptions.h" #import "FBMacros.h" #import "FBMathUtils.h" #import "FBActiveAppDetectionPoint.h" @@ -33,6 +34,54 @@ static NSString* const FBUnknownBundleId = @"unknown"; +_Nullable id extractIssueProperty(id issue, NSString *propertyName) { + SEL selector = NSSelectorFromString(propertyName); + NSMethodSignature *methodSignature = [issue methodSignatureForSelector:selector]; + if (nil == methodSignature) { + return nil; + } + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; + [invocation setSelector:selector]; + [invocation invokeWithTarget:issue]; + id __unsafe_unretained result; + [invocation getReturnValue:&result]; + return result; +} + +NSDictionary *auditTypeNamesToValues(void) { + static dispatch_once_t onceToken; + static NSDictionary *result; + dispatch_once(&onceToken, ^{ + // https://developer.apple.com/documentation/xctest/xcuiaccessibilityaudittype?language=objc + result = @{ + @"XCUIAccessibilityAuditTypeAction": @(1UL << 32), + @"XCUIAccessibilityAuditTypeAll": @(~0UL), + @"XCUIAccessibilityAuditTypeContrast": @(1UL << 0), + @"XCUIAccessibilityAuditTypeDynamicType": @(1UL << 16), + @"XCUIAccessibilityAuditTypeElementDetection": @(1UL << 1), + @"XCUIAccessibilityAuditTypeHitRegion": @(1UL << 2), + @"XCUIAccessibilityAuditTypeParentChild": @(1UL << 33), + @"XCUIAccessibilityAuditTypeSufficientElementDescription": @(1UL << 3), + @"XCUIAccessibilityAuditTypeTextClipped": @(1UL << 17), + @"XCUIAccessibilityAuditTypeTrait": @(1UL << 18), + }; + }); + return result; +} + +NSDictionary *auditTypeValuesToNames(void) { + static dispatch_once_t onceToken; + static NSDictionary *result; + dispatch_once(&onceToken, ^{ + NSMutableDictionary *inverted = [NSMutableDictionary new]; + [auditTypeNamesToValues() enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSNumber *value, BOOL *stop) { + inverted[value] = key; + }]; + result = inverted.copy; + }); + return result; +} + @implementation XCUIApplication (FBHelpers) @@ -281,4 +330,59 @@ - (BOOL)fb_dismissKeyboardWithKeyNames:(nullable NSArray *)keyNames error:error]; } +- (NSArray *> *)fb_performAccessibilityAuditWithAuditTypesSet:(NSSet *)auditTypes + error:(NSError **)error; +{ + uint64_t numTypes = 0; + NSDictionary *namesMap = auditTypeNamesToValues(); + for (NSString *value in auditTypes) { + NSNumber *typeValue = namesMap[value]; + if (nil == typeValue) { + NSString *reason = [NSString stringWithFormat:@"Audit type value '%@' is not known. Only the following audit types are supported: %@", value, namesMap.allKeys]; + @throw [NSException exceptionWithName:FBInvalidArgumentException reason:reason userInfo:@{}]; + } + numTypes |= [typeValue unsignedLongLongValue]; + } + return [self fb_performAccessibilityAuditWithAuditTypes:numTypes error:error]; +} + +- (NSArray *> *)fb_performAccessibilityAuditWithAuditTypes:(uint64_t)auditTypes + error:(NSError **)error; +{ + SEL selector = NSSelectorFromString(@"performAccessibilityAuditWithAuditTypes:issueHandler:error:"); + if (![self respondsToSelector:selector]) { + [[[FBErrorBuilder alloc] + withDescription:@"Accessibility audit is only supported since iOS 17/Xcode 15"] + buildError:error]; + return nil; + } + + NSMutableArray *resultArray = [NSMutableArray array]; + NSMethodSignature *methodSignature = [self methodSignatureForSelector:selector]; + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; + [invocation setSelector:selector]; + [invocation setArgument:&auditTypes atIndex:2]; + BOOL (^issueHandler)(id) = ^BOOL(id issue) { + NSString *auditType = @""; + NSDictionary *valuesToNamesMap = auditTypeValuesToNames(); + NSNumber *auditTypeValue = [issue valueForKey:@"auditType"]; + if (nil != auditTypeValue) { + auditType = valuesToNamesMap[auditTypeValue] ?: [auditTypeValue stringValue]; + } + [resultArray addObject:@{ + @"detailedDescription": extractIssueProperty(issue, @"detailedDescription") ?: @"", + @"compactDescription": extractIssueProperty(issue, @"compactDescription") ?: @"", + @"auditType": auditType, + @"element": [extractIssueProperty(issue, @"element") description] ?: @"", + }]; + return YES; + }; + [invocation setArgument:&issueHandler atIndex:3]; + [invocation setArgument:&error atIndex:4]; + [invocation invokeWithTarget:self]; + BOOL isSuccessful; + [invocation getReturnValue:&isSuccessful]; + return isSuccessful ? resultArray.copy : nil; +} + @end diff --git a/WebDriverAgentLib/Commands/FBCustomCommands.m b/WebDriverAgentLib/Commands/FBCustomCommands.m index c2cde607e..9d8e324d7 100644 --- a/WebDriverAgentLib/Commands/FBCustomCommands.m +++ b/WebDriverAgentLib/Commands/FBCustomCommands.m @@ -58,6 +58,7 @@ + (NSArray *)routes [[FBRoute GET:@"/wda/batteryInfo"] respondWithTarget:self action:@selector(handleGetBatteryInfo:)], #endif [[FBRoute POST:@"/wda/pressButton"] respondWithTarget:self action:@selector(handlePressButtonCommand:)], + [[FBRoute POST:@"/wda/performAccessibilityAudit"] respondWithTarget:self action:@selector(handlePerformAccessibilityAudit:)], [[FBRoute POST:@"/wda/performIoHidEvent"] respondWithTarget:self action:@selector(handlePeformIOHIDEvent:)], [[FBRoute POST:@"/wda/expectNotification"] respondWithTarget:self action:@selector(handleExpectNotification:)], [[FBRoute POST:@"/wda/siri/activate"] respondWithTarget:self action:@selector(handleActivateSiri:)], @@ -544,4 +545,23 @@ + (NSString *)timeZone } #endif ++ (id)handlePerformAccessibilityAudit:(FBRouteRequest *)request +{ + NSError *error; + NSArray *requestedTypes = request.arguments[@"auditTypes"]; + NSMutableSet *typesSet = [NSMutableSet set]; + if (nil == requestedTypes || 0 == [requestedTypes count]) { + [typesSet addObject:@"XCUIAccessibilityAuditTypeAll"]; + } else { + [typesSet addObjectsFromArray:requestedTypes]; + } + NSArray *result = [request.session.activeApplication fb_performAccessibilityAuditWithAuditTypesSet:typesSet.copy + error:&error]; + if (nil == result) { + return FBResponseWithStatus([FBCommandStatus unknownErrorWithMessage:error.description + traceback:nil]); + } + return FBResponseWithObject(result); +} + @end diff --git a/WebDriverAgentLib/FBApplication.m b/WebDriverAgentLib/FBApplication.m index 8a9a48ba0..fe46393fb 100644 --- a/WebDriverAgentLib/FBApplication.m +++ b/WebDriverAgentLib/FBApplication.m @@ -11,6 +11,7 @@ #import "FBXCAccessibilityElement.h" #import "FBLogger.h" +#import "FBExceptions.h" #import "FBRunLoopSpinner.h" #import "FBMacros.h" #import "FBActiveAppDetectionPoint.h" diff --git a/WebDriverAgentTests/IntegrationTests/XCUIApplicationHelperTests.m b/WebDriverAgentTests/IntegrationTests/XCUIApplicationHelperTests.m index 8a7d47ae7..41ee134a1 100644 --- a/WebDriverAgentTests/IntegrationTests/XCUIApplicationHelperTests.m +++ b/WebDriverAgentTests/IntegrationTests/XCUIApplicationHelperTests.m @@ -14,6 +14,7 @@ #import "FBApplication.h" #import "FBIntegrationTestCase.h" #import "FBElement.h" +#import "FBMacros.h" #import "FBTestMacros.h" #import "XCUIApplication+FBHelpers.h" #import "XCUIElement+FBIsVisible.h" @@ -94,4 +95,24 @@ - (void)testTestmanagerdVersion XCTAssertGreaterThan(FBTestmanagerdVersion(), 0); } +- (void)testAccessbilityAudit +{ + if (SYSTEM_VERSION_LESS_THAN(@"17.0")) { + return; + } + + NSError *error; + NSArray *auditIssues1 = [FBApplication.fb_activeApplication fb_performAccessibilityAuditWithAuditTypes:~0UL + error:&error]; + XCTAssertNotNil(auditIssues1); + XCTAssertNil(error); + + NSMutableSet *set = [NSMutableSet new]; + [set addObject:@"XCUIAccessibilityAuditTypeAll"]; + NSArray *auditIssues2 = [FBApplication.fb_activeApplication fb_performAccessibilityAuditWithAuditTypesSet:set.copy + error:&error]; + XCTAssertEqualObjects(auditIssues1, auditIssues2); + XCTAssertNil(error); +} + @end From 96010a6a3ea8a70a6f4ef8fbb9e8e540ffa6e640 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 12 Jun 2023 20:11:50 +0000 Subject: [PATCH 146/240] chore(release): 5.5.0 [skip ci] ## [5.5.0](https://github.com/appium/WebDriverAgent/compare/v5.4.1...v5.5.0) (2023-06-12) ### Features * Add accessibility audit extension ([#727](https://github.com/appium/WebDriverAgent/issues/727)) ([78321dd](https://github.com/appium/WebDriverAgent/commit/78321dd3dafdb142eed136b48ec101f1daed50a4)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 260bb8b6e..e8b2f6035 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.5.0](https://github.com/appium/WebDriverAgent/compare/v5.4.1...v5.5.0) (2023-06-12) + + +### Features + +* Add accessibility audit extension ([#727](https://github.com/appium/WebDriverAgent/issues/727)) ([78321dd](https://github.com/appium/WebDriverAgent/commit/78321dd3dafdb142eed136b48ec101f1daed50a4)) + ## [5.4.1](https://github.com/appium/WebDriverAgent/compare/v5.4.0...v5.4.1) (2023-06-09) diff --git a/package.json b/package.json index eb2f087da..a0b52f566 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.4.1", + "version": "5.5.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 49770328aeeebacd76011ff1caf13d5b4ed71420 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Fri, 16 Jun 2023 09:42:28 +0200 Subject: [PATCH 147/240] fix: Update strongbox API name --- lib/webdriveragent.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/webdriveragent.js b/lib/webdriveragent.js index 350353ed2..4c52e91d6 100644 --- a/lib/webdriveragent.js +++ b/lib/webdriveragent.js @@ -240,7 +240,7 @@ class WebDriverAgent { // TODO: hovewer it should do the job as a temporary transition trick // TODO: to switch from a hardcoded file path to the strongbox usage. try { - boxItem = await box.createItemWithContents(RECENT_MODULE_VERSION_ITEM_NAME, '5.0.0'); + boxItem = await box.createItemWithValue(RECENT_MODULE_VERSION_ITEM_NAME, '5.0.0'); } catch (e) { this.log.warn(`The actual module version cannot be persisted: ${e.message}`); return; @@ -248,7 +248,7 @@ class WebDriverAgent { } else { this.log.info('There is no need to perform the project cleanup. A fresh install has been detected'); try { - await box.createItemWithContents(RECENT_MODULE_VERSION_ITEM_NAME, packageInfo.version); + await box.createItemWithValue(RECENT_MODULE_VERSION_ITEM_NAME, packageInfo.version); } catch (e) { this.log.warn(`The actual module version cannot be persisted: ${e.message}`); } From c4853da316f3b8da8520de38f07b9388413a9f8a Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 16 Jun 2023 07:51:04 +0000 Subject: [PATCH 148/240] chore(release): 5.5.1 [skip ci] ## [5.5.1](https://github.com/appium/WebDriverAgent/compare/v5.5.0...v5.5.1) (2023-06-16) ### Bug Fixes * Update strongbox API name ([4977032](https://github.com/appium/WebDriverAgent/commit/49770328aeeebacd76011ff1caf13d5b4ed71420)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8b2f6035..9a6d4b57d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.5.1](https://github.com/appium/WebDriverAgent/compare/v5.5.0...v5.5.1) (2023-06-16) + + +### Bug Fixes + +* Update strongbox API name ([4977032](https://github.com/appium/WebDriverAgent/commit/49770328aeeebacd76011ff1caf13d5b4ed71420)) + ## [5.5.0](https://github.com/appium/WebDriverAgent/compare/v5.4.1...v5.5.0) (2023-06-12) diff --git a/package.json b/package.json index a0b52f566..2b67f5207 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.5.0", + "version": "5.5.1", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 15614d030975f2b1eac5919d2353bc015f194d4c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Jul 2023 06:58:52 +0200 Subject: [PATCH 149/240] chore(deps-dev): bump prettier from 2.8.8 to 3.0.0 (#735) Bumps [prettier](https://github.com/prettier/prettier) from 2.8.8 to 3.0.0. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/2.8.8...3.0.0) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2b67f5207..153ed2db9 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "lint-staged": "^13.0.3", "mocha": "^10.0.0", "pre-commit": "^1.2.2", - "prettier": "^2.7.1", + "prettier": "^3.0.0", "semantic-release": "^20.0.2", "sinon": "^15.0.0" }, From 2c24c9db7329e644c97a8a27bd99959b1196772f Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 7 Jul 2023 05:07:35 +0000 Subject: [PATCH 150/240] chore(release): 5.5.2 [skip ci] ## [5.5.2](https://github.com/appium/WebDriverAgent/compare/v5.5.1...v5.5.2) (2023-07-07) ### Miscellaneous Chores * **deps-dev:** bump prettier from 2.8.8 to 3.0.0 ([#735](https://github.com/appium/WebDriverAgent/issues/735)) ([15614d0](https://github.com/appium/WebDriverAgent/commit/15614d030975f2b1eac5919d2353bc015f194d4c)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a6d4b57d..dd046b302 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.5.2](https://github.com/appium/WebDriverAgent/compare/v5.5.1...v5.5.2) (2023-07-07) + + +### Miscellaneous Chores + +* **deps-dev:** bump prettier from 2.8.8 to 3.0.0 ([#735](https://github.com/appium/WebDriverAgent/issues/735)) ([15614d0](https://github.com/appium/WebDriverAgent/commit/15614d030975f2b1eac5919d2353bc015f194d4c)) + ## [5.5.1](https://github.com/appium/WebDriverAgent/compare/v5.5.0...v5.5.1) (2023-06-16) diff --git a/package.json b/package.json index 153ed2db9..97737b0a9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.5.1", + "version": "5.5.2", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 239f04436a4cfbbd7c05935331cead63f699f5c0 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sat, 15 Jul 2023 10:21:09 -0700 Subject: [PATCH 151/240] apply shouldWaitForQuiescence for activate in /wda/apps/launch (#739) --- WebDriverAgentLib/Routing/FBSession.m | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/WebDriverAgentLib/Routing/FBSession.m b/WebDriverAgentLib/Routing/FBSession.m index 88d4385f9..69d0fff78 100644 --- a/WebDriverAgentLib/Routing/FBSession.m +++ b/WebDriverAgentLib/Routing/FBSession.m @@ -178,13 +178,13 @@ - (FBApplication *)launchApplicationWithBundleId:(NSString *)bundleIdentifier environment:(nullable NSDictionary *)environment { FBApplication *app = [[FBApplication alloc] initWithBundleIdentifier:bundleIdentifier]; + if (nil == shouldWaitForQuiescence) { + // Iherit the quiescence check setting from the main app under test by default + app.fb_shouldWaitForQuiescence = nil != self.testedApplicationBundleId && self.shouldAppsWaitForQuiescence; + } else { + app.fb_shouldWaitForQuiescence = [shouldWaitForQuiescence boolValue]; + } if (app.fb_state < 2) { - if (nil == shouldWaitForQuiescence) { - // Iherit the quiescence check setting from the main app under test by default - app.fb_shouldWaitForQuiescence = nil != self.testedApplicationBundleId && self.shouldAppsWaitForQuiescence; - } else { - app.fb_shouldWaitForQuiescence = [shouldWaitForQuiescence boolValue]; - } app.launchArguments = arguments ?: @[]; app.launchEnvironment = environment ?: @{}; [app launch]; From 66ab695f9fa1850145a1d94ef15978b70bc1b032 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sat, 15 Jul 2023 10:50:57 -0700 Subject: [PATCH 152/240] feat: apply shouldWaitForQuiescence for activate in /wda/apps/launch (#739) (#740) This PR is a dummy to release https://github.com/appium/WebDriverAgent/pull/739 The merge via mobile app did not apply expected commit message.. From c204c73081ed210399427917ab43056c07f6f491 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sat, 15 Jul 2023 18:01:46 +0000 Subject: [PATCH 153/240] chore(release): 5.6.0 [skip ci] ## [5.6.0](https://github.com/appium/WebDriverAgent/compare/v5.5.2...v5.6.0) (2023-07-15) ### Features * apply shouldWaitForQuiescence for activate in /wda/apps/launch ([#739](https://github.com/appium/WebDriverAgent/issues/739)) ([#740](https://github.com/appium/WebDriverAgent/issues/740)) ([66ab695](https://github.com/appium/WebDriverAgent/commit/66ab695f9fa1850145a1d94ef15978b70bc1b032)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd046b302..89bea69e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.6.0](https://github.com/appium/WebDriverAgent/compare/v5.5.2...v5.6.0) (2023-07-15) + + +### Features + +* apply shouldWaitForQuiescence for activate in /wda/apps/launch ([#739](https://github.com/appium/WebDriverAgent/issues/739)) ([#740](https://github.com/appium/WebDriverAgent/issues/740)) ([66ab695](https://github.com/appium/WebDriverAgent/commit/66ab695f9fa1850145a1d94ef15978b70bc1b032)) + ## [5.5.2](https://github.com/appium/WebDriverAgent/compare/v5.5.1...v5.5.2) (2023-07-07) diff --git a/package.json b/package.json index 97737b0a9..41c1d1083 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.5.2", + "version": "5.6.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 0b74bf5befaa6d87c93a5306beb690a5a0e1843d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Aug 2023 20:45:20 +0200 Subject: [PATCH 154/240] chore(deps-dev): bump lint-staged from 13.3.0 to 14.0.0 (#750) Bumps [lint-staged](https://github.com/okonet/lint-staged) from 13.3.0 to 14.0.0. - [Release notes](https://github.com/okonet/lint-staged/releases) - [Commits](https://github.com/okonet/lint-staged/compare/v13.3.0...v14.0.0) --- updated-dependencies: - dependency-name: lint-staged dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 41c1d1083..7fc4d6308 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "eslint-plugin-import": "^2.26.0", "eslint-plugin-mocha": "^9.0.0", "eslint-plugin-promise": "^6.0.0", - "lint-staged": "^13.0.3", + "lint-staged": "^14.0.0", "mocha": "^10.0.0", "pre-commit": "^1.2.2", "prettier": "^3.0.0", From 2aee273ceda6ca86fcdaa57bb3067462a79e171b Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 14 Aug 2023 18:59:54 +0000 Subject: [PATCH 155/240] chore(release): 5.6.1 [skip ci] ## [5.6.1](https://github.com/appium/WebDriverAgent/compare/v5.6.0...v5.6.1) (2023-08-14) ### Miscellaneous Chores * **deps-dev:** bump lint-staged from 13.3.0 to 14.0.0 ([#750](https://github.com/appium/WebDriverAgent/issues/750)) ([0b74bf5](https://github.com/appium/WebDriverAgent/commit/0b74bf5befaa6d87c93a5306beb690a5a0e1843d)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89bea69e8..c1bedbf5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.6.1](https://github.com/appium/WebDriverAgent/compare/v5.6.0...v5.6.1) (2023-08-14) + + +### Miscellaneous Chores + +* **deps-dev:** bump lint-staged from 13.3.0 to 14.0.0 ([#750](https://github.com/appium/WebDriverAgent/issues/750)) ([0b74bf5](https://github.com/appium/WebDriverAgent/commit/0b74bf5befaa6d87c93a5306beb690a5a0e1843d)) + ## [5.6.0](https://github.com/appium/WebDriverAgent/compare/v5.5.2...v5.6.0) (2023-07-15) diff --git a/package.json b/package.json index 7fc4d6308..c2d271130 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.6.0", + "version": "5.6.1", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From ee7655e0a2aa39dd1f0c6d80d89065b4f34f264d Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Wed, 23 Aug 2023 19:28:20 +0200 Subject: [PATCH 156/240] chore: Remove unused glob dependency --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index c2d271130..f3cee7cd7 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,6 @@ "conventional-changelog-conventionalcommits": "^6.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.5.0", - "glob": "^8.0.1", "eslint-plugin-import": "^2.26.0", "eslint-plugin-mocha": "^9.0.0", "eslint-plugin-promise": "^6.0.0", From f6978872e7eafe4e77c41f332177a64e9f1e1c84 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 23 Aug 2023 19:09:10 +0000 Subject: [PATCH 157/240] chore(release): 5.6.2 [skip ci] ## [5.6.2](https://github.com/appium/WebDriverAgent/compare/v5.6.1...v5.6.2) (2023-08-23) ### Miscellaneous Chores * Remove unused glob dependency ([ee7655e](https://github.com/appium/WebDriverAgent/commit/ee7655e0a2aa39dd1f0c6d80d89065b4f34f264d)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1bedbf5c..6650bf5a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.6.2](https://github.com/appium/WebDriverAgent/compare/v5.6.1...v5.6.2) (2023-08-23) + + +### Miscellaneous Chores + +* Remove unused glob dependency ([ee7655e](https://github.com/appium/WebDriverAgent/commit/ee7655e0a2aa39dd1f0c6d80d89065b4f34f264d)) + ## [5.6.1](https://github.com/appium/WebDriverAgent/compare/v5.6.0...v5.6.1) (2023-08-14) diff --git a/package.json b/package.json index f3cee7cd7..f69d650d1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.6.1", + "version": "5.6.2", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 76a4c7f066e1895acbb153ab035d6a08604277e4 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 24 Aug 2023 07:36:00 +0200 Subject: [PATCH 158/240] feat: Switch babel to typescript (#753) --- .eslintrc.json | 24 ++++++++++++-- .github/workflows/functional-test.yml | 7 ++++ .mocharc.js | 2 +- babel.config.json | 25 --------------- lib/check-dependencies.js | 7 ++-- lib/utils.js | 17 ++++++---- lib/webdriveragent.js | 23 ++++++++------ lib/xcodebuild.js | 46 +++++++++++++++++++++++---- package.json | 44 +++++++++++++++---------- tsconfig.json | 14 ++++++++ 10 files changed, 136 insertions(+), 73 deletions(-) delete mode 100644 babel.config.json create mode 100644 tsconfig.json diff --git a/.eslintrc.json b/.eslintrc.json index 69a602c5c..3d7db0846 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,11 +1,29 @@ { - "extends": "@appium/eslint-config-appium", + "extends": ["@appium/eslint-config-appium-ts"], "overrides": [ { "files": "test/**/*.js", "rules": { - "func-names": "off" + "func-names": "off", + "@typescript-eslint/no-var-requires": "off" + } + }, + { + "files": "Scripts/**/*.js", + "parserOptions": {"sourceType": "script"}, + "rules": { + "@typescript-eslint/no-var-requires": "off" + } + }, + { + "files": "ci-jobs/scripts/*.js", + "parserOptions": {"sourceType": "script"}, + "rules": { + "@typescript-eslint/no-var-requires": "off" } } - ] + ], + "rules": { + "require-await": "error" + } } diff --git a/.github/workflows/functional-test.yml b/.github/workflows/functional-test.yml index 8c95517e9..e5c1ebad9 100644 --- a/.github/workflows/functional-test.yml +++ b/.github/workflows/functional-test.yml @@ -25,5 +25,12 @@ jobs: npm install mkdir -p ./Resources/WebDriverAgent.bundle name: Install dev dependencies + + - run: | + target_sim_id=$(xcrun simctl list devices available | grep "$DEVICE_NAME (" | cut -d "(" -f2 | cut -d ")" -f1) + open -Fn "$(xcode-select -p)/Applications/Simulator.app" + xcrun simctl bootstatus $target_sim_id -b + name: Preboot Simulator + - run: npm run e2e-test name: Run functional tests diff --git a/.mocharc.js b/.mocharc.js index 66d4a976a..40599e9df 100644 --- a/.mocharc.js +++ b/.mocharc.js @@ -1,4 +1,4 @@ module.exports = { - require: ['@babel/register'], + require: ['ts-node/register'], forbidOnly: Boolean(process.env.CI) }; diff --git a/babel.config.json b/babel.config.json deleted file mode 100644 index 048e9cf60..000000000 --- a/babel.config.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "targets": { - "node": "14" - }, - "shippedProposals": true - } - ] - ], - "plugins": [ - "source-map-support", - "@babel/plugin-transform-runtime" - ], - "comments": false, - "sourceMaps": "both", - "env": { - "test": { - "retainLines": true, - "comments": true - } - } -} diff --git a/lib/check-dependencies.js b/lib/check-dependencies.js index 39b824373..ce145f5a1 100644 --- a/lib/check-dependencies.js +++ b/lib/check-dependencies.js @@ -27,10 +27,9 @@ async function checkForDependencies () { return false; } -async function bundleWDASim (xcodebuild, opts = {}) { +async function bundleWDASim (xcodebuild) { if (xcodebuild && !_.isFunction(xcodebuild.retrieveDerivedDataPath)) { - xcodebuild = new XcodeBuild(); - opts = xcodebuild; + xcodebuild = new XcodeBuild('', {}); } const derivedDataPath = await xcodebuild.retrieveDerivedDataPath(); @@ -38,7 +37,7 @@ async function bundleWDASim (xcodebuild, opts = {}) { if (await fs.exists(wdaBundlePath)) { return wdaBundlePath; } - await buildWDASim(xcodebuild, opts); + await buildWDASim(); return wdaBundlePath; } diff --git a/lib/utils.js b/lib/utils.js index 71cac28ba..4a1191600 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -188,8 +188,8 @@ CODE_SIGN_IDENTITY = ${signingId} * @param {DeviceInfo} deviceInfo * @param {string} sdkVersion - The Xcode SDK version of OS. * @param {string} bootstrapPath - The folder path containing xctestrun file. - * @param {string} wdaRemotePort - The remote port WDA is listening on. - * @return {string} returns xctestrunFilePath for given device + * @param {number|string} wdaRemotePort - The remote port WDA is listening on. + * @return {Promise} returns xctestrunFilePath for given device * @throws if WebDriverAgentRunner_iphoneos${sdkVersion|platformVersion}-arm64.xctestrun for real device * or WebDriverAgentRunner_iphonesimulator${sdkVersion|platformVersion}-x86_64.xctestrun for simulator is not found @bootstrapPath, * then it will throw file not found exception @@ -207,7 +207,7 @@ async function setXctestrunFile (deviceInfo, sdkVersion, bootstrapPath, wdaRemot /** * Return the WDA object which appends existing xctest runner content * @param {string} platformName - The name of the platform - * @param {string} version - The Xcode SDK version of OS. + * @param {number|string} wdaRemotePort - The remote port number * @return {object} returns a runner object which has USE_PORT */ function getAdditionalRunContent (platformName, wdaRemotePort) { @@ -228,6 +228,7 @@ function getAdditionalRunContent (platformName, wdaRemotePort) { * @param {DeviceInfo} deviceInfo * @param {string} sdkVersion - The Xcode SDK version of OS. * @param {string} bootstrapPath - The folder path containing xctestrun file. + * @returns {Promise} */ async function getXctestrunFilePath (deviceInfo, sdkVersion, bootstrapPath) { // First try the SDK path, for Xcode 10 (at least) @@ -256,9 +257,11 @@ async function getXctestrunFilePath (deviceInfo, sdkVersion, bootstrapPath) { } } - log.errorAndThrow(`If you are using 'useXctestrunFile' capability then you ` + + throw new Error( + `If you are using 'useXctestrunFile' capability then you ` + `need to have a xctestrun file (expected: ` + - `'${path.resolve(bootstrapPath, getXctestrunFileName(deviceInfo, sdkVersion))}')`); + `'${path.resolve(bootstrapPath, getXctestrunFileName(deviceInfo, sdkVersion))}')` + ); } @@ -316,7 +319,7 @@ function randomInt (low, high) { /** * Retrieves WDA upgrade timestamp * - * @return {?number} The UNIX timestamp of the package manifest. The manifest only gets modified on + * @return {Promise} The UNIX timestamp of the package manifest. The manifest only gets modified on * package upgrade. */ async function getWDAUpgradeTimestamp () { @@ -356,7 +359,7 @@ async function resetTestProcesses (udid, isSimulator) { * listening on given port, and is expected to return * either true or false to include/exclude the corresponding PID * from the resulting array. - * @returns {Array} - the list of matched process ids. + * @returns {Promise} - the list of matched process ids. */ async function getPIDsListeningOnPort (port, filteringFunc = null) { const result = []; diff --git a/lib/webdriveragent.js b/lib/webdriveragent.js index 4c52e91d6..40196b6ea 100644 --- a/lib/webdriveragent.js +++ b/lib/webdriveragent.js @@ -150,7 +150,7 @@ class WebDriverAgent { /** * Return boolean if WDA is running or not - * @return {boolean} True if WDA is running + * @return {Promise} True if WDA is running * @throws {Error} If there was invalid response code or body */ async isRunning () { @@ -183,7 +183,7 @@ class WebDriverAgent { * } * } * - * @return {?object} State Object + * @return {Promise} State Object * @throws {Error} If there was invalid response code or body */ async getStatus () { @@ -234,7 +234,7 @@ class WebDriverAgent { const box = strongbox(packageInfo.name); let boxItem = box.getItem(RECENT_MODULE_VERSION_ITEM_NAME); if (!boxItem) { - const timestampPath = path.resolve(process.env.HOME, WDA_UPGRADE_TIMESTAMP_PATH); + const timestampPath = path.resolve(process.env.HOME ?? '', WDA_UPGRADE_TIMESTAMP_PATH); if (await fs.exists(timestampPath)) { // TODO: It is probably a bit ugly to hardcode the recent version string, // TODO: hovewer it should do the job as a temporary transition trick @@ -279,6 +279,7 @@ class WebDriverAgent { `(${recentModuleVersion} < ${packageInfo.version})` ); try { + // @ts-ignore xcodebuild should be set await this.xcodebuild.cleanProject(); await boxItem.write(packageInfo.version); } catch (e) { @@ -289,7 +290,7 @@ class WebDriverAgent { /** * Launch WDA with preinstalled package without xcodebuild. * @param {string} sessionId Launch WDA and establish the session with this sessionId - * @return {?object} State Object + * @return {Promise} State Object */ async launchWithPreinstalledWDA(sessionId) { const xctestEnv = { @@ -330,7 +331,7 @@ class WebDriverAgent { * } * * @param {string} sessionId Launch WDA and establish the session with this sessionId - * @return {?object} State Object + * @return {Promise} State Object * @throws {Error} If there was invalid response code or body */ async launch (sessionId) { @@ -374,12 +375,15 @@ class WebDriverAgent { return await this.startWithIDB(); } + // @ts-ignore xcodebuild should be set await this.xcodebuild.init(this.noSessionProxy); // Start the xcodebuild process if (this.prebuildWDA) { + // @ts-ignore xcodebuild should be set await this.xcodebuild.prebuild(); } + // @ts-ignore xcodebuild should be set return await this.xcodebuild.start(); } @@ -463,7 +467,9 @@ class WebDriverAgent { } } else if (!this.args.webDriverAgentUrl) { this.log.info('Shutting down sub-processes'); + // @ts-ignore xcodebuild should be set await this.xcodebuild.quit(); + // @ts-ignore xcodebuild should be set await this.xcodebuild.reset(); } else { this.log.debug('Do not stop xcodebuild nor XCTest session ' + @@ -504,14 +510,15 @@ class WebDriverAgent { return this.started; } - set fullyStarted (started = false) { - this.started = started; + set fullyStarted (started) { + this.started = started ?? false; } async retrieveDerivedDataPath () { if (this.canSkipXcodebuild) { return; } + // @ts-ignore xcodebuild should be set return await this.xcodebuild.retrieveDerivedDataPath(); } @@ -519,8 +526,6 @@ class WebDriverAgent { * Reuse running WDA if it has the same bundle id with updatedWDABundleId. * Or reuse it if it has the default id without updatedWDABundleId. * Uninstall it if the method faces an exception for the above situation. - * - * @param {string} updatedWDABundleId BundleId you'd like to use */ async setupCaching () { const status = await this.getStatus(); diff --git a/lib/xcodebuild.js b/lib/xcodebuild.js index df5cac008..348a4f967 100644 --- a/lib/xcodebuild.js +++ b/lib/xcodebuild.js @@ -11,6 +11,7 @@ import _ from 'lodash'; import path from 'path'; import { EOL } from 'os'; import { WDA_RUNNER_BUNDLE_ID } from './constants'; +import readline from 'node:readline'; const DEFAULT_SIGNING_ID = 'iPhone Developer'; @@ -33,6 +34,12 @@ const xcodeLog = logger.getLogger('Xcode'); class XcodeBuild { + /** + * @param {string} xcodeVersion + * @param {any} device + * @param {any} args + * @param {import('@appium/types').AppiumLogger?} log + */ constructor (xcodeVersion, device, args = {}, log = null) { this.xcodeVersion = xcodeVersion; @@ -201,7 +208,7 @@ class XcodeBuild { args.push('-resultBundleVersion', this.resultBundleVersion); } - if (this.useXctestrunFile) { + if (this.useXctestrunFile && this.xctestrunFilePath) { args.push('-xctestrun', this.xctestrunFilePath); } else { const runnerScheme = isTvOS(this.platformName) ? RUNNER_SCHEME_TV : RUNNER_SCHEME_IOS; @@ -252,6 +259,7 @@ class XcodeBuild { const {cmd, args} = this.getCommand(buildOnly); this.log.debug(`Beginning ${buildOnly ? 'build' : 'test'} with command '${cmd} ${args.join(' ')}' ` + `in directory '${this.bootstrapPath}'`); + /** @type {Record} */ const env = Object.assign({}, process.env, { USE_PORT: this.wdaRemotePort, WDA_PRODUCT_BUNDLE_IDENTIFIER: this.updatedWDABundleId || WDA_RUNNER_BUNDLE_ID, @@ -260,7 +268,7 @@ class XcodeBuild { // https://github.com/appium/WebDriverAgent/pull/105 env.MJPEG_SERVER_PORT = this.mjpegServerPort; } - const upgradeTimestamp = await getWDAUpgradeTimestamp(this.bootstrapPath); + const upgradeTimestamp = await getWDAUpgradeTimestamp(); if (upgradeTimestamp) { env.UPGRADE_TIMESTAMP = upgradeTimestamp; } @@ -283,7 +291,9 @@ class XcodeBuild { if (out.includes('Writing diagnostic log for test session to')) { // pull out the first line that begins with the path separator // which *should* be the line indicating the log file generated + // @ts-ignore logLocation is a custom property xcodebuild.logLocation = _.first(_.remove(out.trim().split('\n'), (v) => v.startsWith(path.sep))); + // @ts-ignore logLocation is a custom property xcodeLog.debug(`Log file for xcodebuild test: ${xcodebuild.logLocation}`); } @@ -295,6 +305,7 @@ class XcodeBuild { logXcodeOutput = true; // terrible hack to handle case where xcode return 0 but is failing + // @ts-ignore _wda_error_occurred is a custom property xcodebuild._wda_error_occurred = true; } @@ -303,6 +314,7 @@ class XcodeBuild { for (const line of out.split(EOL)) { xcodeLog.error(line); if (line) { + // @ts-ignore _wda_error_message is a custom property xcodebuild._wda_error_message += `${EOL}${line}`; } } @@ -315,28 +327,45 @@ class XcodeBuild { async start (buildOnly = false) { this.xcodebuild = await this.createSubProcess(buildOnly); // Store xcodebuild message + // @ts-ignore _wda_error_message is a custom property this.xcodebuild._wda_error_message = ''; // wrap the start procedure in a promise so that we can catch, and report, // any startup errors that are thrown as events return await new B((resolve, reject) => { + // @ts-ignore xcodebuild must be present here this.xcodebuild.on('exit', async (code, signal) => { xcodeLog.error(`xcodebuild exited with code '${code}' and signal '${signal}'`); // print out the xcodebuild file if users have asked for it - if (this.showXcodeLog && this.xcodebuild.logLocation) { + // @ts-ignore logLocation is a custom property + if (this.showXcodeLog && this.xcodebuild?.logLocation) { + // @ts-ignore logLocation is a custom property xcodeLog.error(`Contents of xcodebuild log file '${this.xcodebuild.logLocation}':`); try { - let data = await fs.readFile(this.xcodebuild.logLocation, 'utf8'); - for (let line of data.split('\n')) { + const logFile = readline.createInterface({ + // @ts-ignore logLocation is a custom property + input: fs.createReadStream(this.xcodebuild.logLocation), + terminal: false + }); + logFile.on('line', (line) => { xcodeLog.error(line); - } + }); + await new B((_resolve) => { + logFile.once('close', () => { + logFile.removeAllListeners(); + _resolve(); + }); + }); } catch (err) { xcodeLog.error(`Unable to access xcodebuild log file: '${err.message}'`); } } + // @ts-ignore processExited is a custom property this.xcodebuild.processExited = true; + // @ts-ignore _wda_error_occurred is a custom property if (this.xcodebuild._wda_error_occurred || (!signal && code !== 0)) { return reject(new Error(`xcodebuild failed with code ${code}${EOL}` + + // @ts-ignore _wda_error_message is a custom property `xcodebuild error message:${EOL}${this.xcodebuild._wda_error_message}`)); } // in the case of just building, the process will exit and that is our finish @@ -348,6 +377,7 @@ class XcodeBuild { return (async () => { try { const timer = new timing.Timer().start(); + // @ts-ignore this.xcodebuild must be defined await this.xcodebuild.start(true); if (!buildOnly) { let status = await this.waitForStart(timer); @@ -367,8 +397,9 @@ class XcodeBuild { this.log.debug(`Waiting up to ${this.launchTimeout}ms for WebDriverAgent to start`); let currentStatus = null; try { - let retries = parseInt(this.launchTimeout / 500, 10); + let retries = parseInt(`${this.launchTimeout / 500}`, 10); await retryInterval(retries, 1000, async () => { + // @ts-ignore processExited is a custom property if (this.xcodebuild.processExited) { // there has been an error elsewhere and we need to short-circuit return; @@ -389,6 +420,7 @@ class XcodeBuild { } }); + // @ts-ignore processExited is a custom property if (this.xcodebuild.processExited) { // there has been an error elsewhere and we need to short-circuit return currentStatus; diff --git a/package.json b/package.json index f69d650d1..4068218fd 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,9 @@ "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { - "build": "rm -rf build && babel --out-dir=build/lib lib && babel --out-dir=build index.js", + "build": "tsc -b", "dev": "npm run build -- --watch", + "clean": "npm run build -- --clean", "lint": "eslint .", "lint:fix": "npm run lint -- --fix", "precommit-msg": "echo 'Pre-commit checks...' && exit 0", @@ -54,43 +55,52 @@ }, "homepage": "https://github.com/appium/WebDriverAgent#readme", "devDependencies": { - "@appium/eslint-config-appium": "^6.0.0", + "@appium/eslint-config-appium": "^8.0.4", + "@appium/eslint-config-appium-ts": "^0.3.1", "@appium/test-support": "^3.0.0", - "@babel/cli": "^7.18.10", - "@babel/core": "^7.18.10", - "@babel/eslint-parser": "^7.18.9", - "@babel/plugin-transform-runtime": "^7.18.10", - "@babel/preset-env": "^7.18.10", - "@babel/register": "^7.18.9", + "@appium/tsconfig": "^0.3.0", + "@appium/types": "^0.13.2", "@semantic-release/changelog": "^6.0.1", "@semantic-release/git": "^10.0.1", - "babel-plugin-source-map-support": "^2.2.0", + "@types/bluebird": "^3.5.38", + "@types/chai": "^4.3.5", + "@types/chai-as-promised": "^7.1.5", + "@types/lodash": "^4.14.196", + "@types/mocha": "^10.0.1", + "@types/node": "^20.4.7", + "@types/sinon": "^10.0.16", + "@types/sinon-chai": "^3.2.9", + "@types/teen_process": "2.0.0", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", "appium-xcode": "^5.0.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "conventional-changelog-conventionalcommits": "^6.0.0", - "eslint": "^7.32.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-import": "^2.26.0", - "eslint-plugin-mocha": "^9.0.0", - "eslint-plugin-promise": "^6.0.0", + "eslint": "^8.46.0", + "eslint-config-prettier": "^8.9.0", + "eslint-import-resolver-typescript": "^3.5.5", + "eslint-plugin-import": "^2.28.0", + "eslint-plugin-mocha": "^10.1.0", + "eslint-plugin-promise": "^6.1.1", "lint-staged": "^14.0.0", "mocha": "^10.0.0", "pre-commit": "^1.2.2", "prettier": "^3.0.0", "semantic-release": "^20.0.2", - "sinon": "^15.0.0" + "sinon": "^15.0.0", + "ts-node": "^10.9.1", + "typescript": "^5.1.6" }, "dependencies": { "@appium/base-driver": "^9.0.0", "@appium/strongbox": "^0.x", "@appium/support": "^4.0.0", - "@babel/runtime": "^7.0.0", "appium-ios-device": "^2.5.0", "appium-ios-simulator": "^5.0.1", "async-lock": "^1.0.0", "asyncbox": "^2.5.3", - "axios": "^1.x", + "axios": "^1.4.0", "bluebird": "^3.5.5", "lodash": "^4.17.11", "node-simctl": "^7.0.1", diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..33d83ef45 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@appium/tsconfig/tsconfig.json", + "compilerOptions": { + "strict": false, // TODO: make this flag true + "outDir": "build", + "types": ["node"], + "checkJs": true + }, + "include": [ + "index.js", + "lib" + ] +} From aed7689ea86dba833173bcce5344f549281b9e9f Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 24 Aug 2023 05:46:07 +0000 Subject: [PATCH 159/240] chore(release): 5.7.0 [skip ci] ## [5.7.0](https://github.com/appium/WebDriverAgent/compare/v5.6.2...v5.7.0) (2023-08-24) ### Features * Switch babel to typescript ([#753](https://github.com/appium/WebDriverAgent/issues/753)) ([76a4c7f](https://github.com/appium/WebDriverAgent/commit/76a4c7f066e1895acbb153ab035d6a08604277e4)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6650bf5a9..f864d6fd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.7.0](https://github.com/appium/WebDriverAgent/compare/v5.6.2...v5.7.0) (2023-08-24) + + +### Features + +* Switch babel to typescript ([#753](https://github.com/appium/WebDriverAgent/issues/753)) ([76a4c7f](https://github.com/appium/WebDriverAgent/commit/76a4c7f066e1895acbb153ab035d6a08604277e4)) + ## [5.6.2](https://github.com/appium/WebDriverAgent/compare/v5.6.1...v5.6.2) (2023-08-23) diff --git a/package.json b/package.json index 4068218fd..033a06d26 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.6.2", + "version": "5.7.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 075298b286c83ab5d4a2855e9e0bb915790b3f43 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 24 Aug 2023 22:20:46 +0200 Subject: [PATCH 160/240] feat: Add wdHittable property (#756) --- .../XCUIElement+FBWebDriverAttributes.m | 7 +++++ WebDriverAgentLib/Routing/FBElement.h | 3 ++ WebDriverAgentLib/Utilities/FBMacros.h | 4 +++ WebDriverAgentLib/Utilities/FBXPath.m | 31 ++++++++++++++++--- .../FBElementAttributeTests.m | 1 + .../FBXPathIntegrationTests.m | 7 +++-- .../IntegrationTests/XCUIElementFBFindTests.m | 2 +- .../Doubles/XCElementSnapshotDouble.m | 6 ++++ .../UnitTests/Doubles/XCUIElementDouble.h | 2 ++ .../UnitTests/Doubles/XCUIElementDouble.m | 2 ++ WebDriverAgentTests/UnitTests/FBXPathTests.m | 11 ++++--- .../Doubles/XCUIElementDouble.h | 1 + .../Doubles/XCUIElementDouble.m | 1 + 13 files changed, 65 insertions(+), 13 deletions(-) diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m b/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m index 2f2368180..b29c5a8b2 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m @@ -20,6 +20,7 @@ #import "XCUIElement+FBUtilities.h" #import "FBElementUtils.h" #import "XCTestPrivateSymbols.h" +#import "XCUIHitPointResult.h" #define BROKEN_RECT CGRectMake(-1, -1, 0, 0) @@ -226,6 +227,12 @@ - (NSUInteger)wdIndex return 0; } +- (BOOL)isWDHittable +{ + XCUIHitPointResult *result = [self hitPoint:nil]; + return nil == result ? NO : result.hittable; +} + - (NSDictionary *)wdRect { CGRect frame = self.wdFrame; diff --git a/WebDriverAgentLib/Routing/FBElement.h b/WebDriverAgentLib/Routing/FBElement.h index 277a4ccd2..7cc8f269c 100644 --- a/WebDriverAgentLib/Routing/FBElement.h +++ b/WebDriverAgentLib/Routing/FBElement.h @@ -56,6 +56,9 @@ NS_ASSUME_NONNULL_BEGIN /*! Whether element is focused */ @property (nonatomic, readonly, getter = isWDFocused) BOOL wdFocused; +/*! Whether element is hittable */ +@property (nonatomic, readonly, getter = isWDHittable) BOOL wdHittable; + /*! Element's index relatively to its parent. Starts from zero */ @property (nonatomic, readonly) NSUInteger wdIndex; diff --git a/WebDriverAgentLib/Utilities/FBMacros.h b/WebDriverAgentLib/Utilities/FBMacros.h index ed4e6f7a0..dae0c5faf 100644 --- a/WebDriverAgentLib/Utilities/FBMacros.h +++ b/WebDriverAgentLib/Utilities/FBMacros.h @@ -52,3 +52,7 @@ /*! Converts the given number of milliseconds into seconds */ #define FBMillisToSeconds(ms) ((ms) / 1000.0) + +/*! Converts boolean value to its string representation */ +#define FBBoolToString(b) ((b) ? @"true" : @"false") + diff --git a/WebDriverAgentLib/Utilities/FBXPath.m b/WebDriverAgentLib/Utilities/FBXPath.m index 00c5d44e7..eae3ee438 100644 --- a/WebDriverAgentLib/Utilities/FBXPath.m +++ b/WebDriverAgentLib/Utilities/FBXPath.m @@ -12,6 +12,7 @@ #import "FBConfiguration.h" #import "FBExceptions.h" #import "FBLogger.h" +#import "FBMacros.h" #import "FBXMLGenerationOptions.h" #import "FBXCElementSnapshotWrapper+Helpers.h" #import "NSString+FBXMLSafeString.h" @@ -87,6 +88,10 @@ @interface FBIndexAttribute : FBElementAttribute @end +@interface FBHittableAttribute : FBElementAttribute + +@end + @interface FBInternalIndexAttribute : FBElementAttribute @property (nonatomic, nonnull, readonly) NSString* indexValue; @@ -273,6 +278,9 @@ + (int)xmlRepresentationWithRootElement:(id)root NSMutableSet *includedAttributes; if (nil == query) { includedAttributes = [NSMutableSet setWithArray:FBElementAttribute.supportedAttributes]; + // The hittable attribute is expensive to calculate for each snapshot item + // thus we only include it when requested by an xPath query + [includedAttributes removeObject:FBHittableAttribute.class]; if (nil != excludedAttributes) { for (NSString *excludedAttributeName in excludedAttributes) { for (Class supportedAttribute in FBElementAttribute.supportedAttributes) { @@ -481,6 +489,7 @@ + (int)recordWithWriter:(xmlTextWriterPtr)writer forElement:(id)eleme FBWidthAttribute.class, FBHeightAttribute.class, FBIndexAttribute.class, + FBHittableAttribute.class, ]; } @@ -557,7 +566,7 @@ + (NSString *)name + (NSString *)valueForElement:(id)element { - return element.wdEnabled ? @"true" : @"false"; + return FBBoolToString(element.wdEnabled); } @end @@ -571,7 +580,7 @@ + (NSString *)name + (NSString *)valueForElement:(id)element { - return element.wdVisible ? @"true" : @"false"; + return FBBoolToString(element.wdVisible); } @end @@ -585,7 +594,7 @@ + (NSString *)name + (NSString *)valueForElement:(id)element { - return element.wdAccessible ? @"true" : @"false"; + return FBBoolToString(element.wdAccessible); } @end @@ -601,7 +610,7 @@ + (NSString *)name + (NSString *)valueForElement:(id)element { - return element.wdFocused ? @"true" : @"false"; + return FBBoolToString(element.wdFocused); } @end @@ -667,6 +676,20 @@ + (NSString *)valueForElement:(id)element @end +@implementation FBHittableAttribute + ++ (NSString *)name +{ + return @"hittable"; +} + ++ (NSString *)valueForElement:(id)element +{ + return FBBoolToString(element.wdHittable); +} + +@end + @implementation FBInternalIndexAttribute + (NSString *)name diff --git a/WebDriverAgentTests/IntegrationTests/FBElementAttributeTests.m b/WebDriverAgentTests/IntegrationTests/FBElementAttributeTests.m index c7cc3505e..13cba4e57 100644 --- a/WebDriverAgentTests/IntegrationTests/FBElementAttributeTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBElementAttributeTests.m @@ -160,6 +160,7 @@ - (void)testSwitchAttributes XCTAssertNil(element.wdLabel); XCTAssertEqualObjects(element.wdValue, @"1"); XCTAssertFalse(element.wdSelected); + XCTAssertTrue(element.wdHittable); [element tap]; XCTAssertEqualObjects(element.wdValue, @"0"); XCTAssertFalse(element.wdSelected); diff --git a/WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m b/WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m index 22983faa6..aa1ed56c2 100644 --- a/WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m @@ -10,6 +10,7 @@ #import #import "FBIntegrationTestCase.h" +#import "FBMacros.h" #import "FBTestMacros.h" #import "FBXPath.h" #import "FBXCodeCompatibility.h" @@ -58,7 +59,7 @@ - (void)testSingleDescendantXMLRepresentation NSString *xmlStr = [FBXPath xmlStringWithRootElement:wrappedSnapshot options:nil]; XCTAssertNotNil(xmlStr); - NSString *expectedXml = [NSString stringWithFormat:@"\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\"/>\n", wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, wrappedSnapshot.wdEnabled ? @"true" : @"false", wrappedSnapshot.wdVisible ? @"true" : @"false", wrappedSnapshot.wdAccessible ? @"true" : @"false", [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue], wrappedSnapshot.wdIndex]; + NSString *expectedXml = [NSString stringWithFormat:@"\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\"/>\n", wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, FBBoolToString(wrappedSnapshot.wdEnabled), FBBoolToString(wrappedSnapshot.wdVisible), FBBoolToString(wrappedSnapshot.wdAccessible), [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue], wrappedSnapshot.wdIndex]; XCTAssertEqualObjects(xmlStr, expectedXml); } @@ -71,7 +72,7 @@ - (void)testSingleDescendantXMLRepresentationWithScope NSString *xmlStr = [FBXPath xmlStringWithRootElement:wrappedSnapshot options:options]; XCTAssertNotNil(xmlStr); - NSString *expectedXml = [NSString stringWithFormat:@"\n<%@>\n <%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\"/>\n\n", scope, wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, wrappedSnapshot.wdEnabled ? @"true" : @"false", wrappedSnapshot.wdVisible ? @"true" : @"false", wrappedSnapshot.wdAccessible ? @"true" : @"false", [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue], wrappedSnapshot.wdIndex, scope]; + NSString *expectedXml = [NSString stringWithFormat:@"\n<%@>\n <%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\"/>\n\n", scope, wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, FBBoolToString(wrappedSnapshot.wdEnabled), FBBoolToString(wrappedSnapshot.wdVisible), FBBoolToString(wrappedSnapshot.wdAccessible), [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue], wrappedSnapshot.wdIndex, scope]; XCTAssertEqualObjects(xmlStr, expectedXml); } @@ -84,7 +85,7 @@ - (void)testSingleDescendantXMLRepresentationWithoutAttributes NSString *xmlStr = [FBXPath xmlStringWithRootElement:wrappedSnapshot options:options]; XCTAssertNotNil(xmlStr); - NSString *expectedXml = [NSString stringWithFormat:@"\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\"/>\n", wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, wrappedSnapshot.wdAccessible ? @"true" : @"false", [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue]]; + NSString *expectedXml = [NSString stringWithFormat:@"\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\"/>\n", wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, FBBoolToString(wrappedSnapshot.wdAccessible), [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue]]; XCTAssertEqualObjects(xmlStr, expectedXml); } diff --git a/WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m b/WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m index 202c48ba9..243ebec5d 100644 --- a/WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m +++ b/WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m @@ -127,7 +127,7 @@ - (void)testSelfWithXPathQuery - (void)testSingleDescendantWithXPathQuery { - NSArray *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton" + NSArray *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeButton[@hittable='true']" shouldReturnAfterFirstMatch:YES]; XCTAssertEqual(matchingSnapshots.count, 1); XCUIElement *matchingSnapshot = [matchingSnapshots firstObject]; diff --git a/WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.m b/WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.m index 455e32227..d52c2904c 100644 --- a/WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.m +++ b/WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.m @@ -11,6 +11,7 @@ #import "FBXCAccessibilityElement.h" #import "FBXCElementSnapshot.h" +#import "XCUIHitPointResult.h" @implementation XCElementSnapshotDouble @@ -87,6 +88,11 @@ - (NSDictionary *)additionalAttributes return nil; } +- (XCUIHitPointResult *)hitPoint:(NSError **)error +{ + return [[XCUIHitPointResult alloc] initWithHitPoint:CGPointZero hittable:YES]; +} + - (NSArray *)children { return @[]; diff --git a/WebDriverAgentTests/UnitTests/Doubles/XCUIElementDouble.h b/WebDriverAgentTests/UnitTests/Doubles/XCUIElementDouble.h index 473a40121..d40945545 100644 --- a/WebDriverAgentTests/UnitTests/Doubles/XCUIElementDouble.h +++ b/WebDriverAgentTests/UnitTests/Doubles/XCUIElementDouble.h @@ -32,6 +32,8 @@ @property (nonatomic, readwrite) NSUInteger wdIndex; @property (nonatomic, readwrite, getter=isWDVisible) BOOL wdVisible; @property (nonatomic, readwrite, getter=isWDAccessible) BOOL wdAccessible; +@property (nonatomic, readwrite, getter = isWDFocused) BOOL wdFocused; +@property (nonatomic, readwrite, getter = isWDHittable) BOOL wdHittable; @property (copy, nonnull) NSArray *children; @property (nonatomic, readwrite, assign) XCUIElementType elementType; @property (nonatomic, readwrite, getter=isWDAccessibilityContainer) BOOL wdAccessibilityContainer; diff --git a/WebDriverAgentTests/UnitTests/Doubles/XCUIElementDouble.m b/WebDriverAgentTests/UnitTests/Doubles/XCUIElementDouble.m index b60e50c26..e9792f132 100644 --- a/WebDriverAgentTests/UnitTests/Doubles/XCUIElementDouble.m +++ b/WebDriverAgentTests/UnitTests/Doubles/XCUIElementDouble.m @@ -27,6 +27,8 @@ - (id)init self.wdAccessible = YES; self.wdEnabled = YES; self.wdSelected = YES; + self.wdFocused = YES; + self.wdHittable = YES; self.wdIndex = 0; #if TARGET_OS_TV self.wdFocused = YES; diff --git a/WebDriverAgentTests/UnitTests/FBXPathTests.m b/WebDriverAgentTests/UnitTests/FBXPathTests.m index 058d6dc89..ce9171107 100644 --- a/WebDriverAgentTests/UnitTests/FBXPathTests.m +++ b/WebDriverAgentTests/UnitTests/FBXPathTests.m @@ -9,6 +9,7 @@ #import +#import "FBMacros.h" #import "FBXPath.h" #import "FBXPath-Private.h" #import "XCUIElementDouble.h" @@ -63,7 +64,7 @@ - (void)testDefaultXPathPresentation xpathQuery:nil excludingAttributes:nil]; NSString *expectedXml = [NSString stringWithFormat:@"\n<%@ type=\"%@\" value=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" private_indexPath=\"top\"/>\n", - element.wdType, element.wdType, element.wdValue, element.wdName, element.wdLabel, element.wdEnabled ? @"true" : @"false", element.wdVisible ? @"true" : @"false", element.wdAccessible ? @"true" : @"false", element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex]; + element.wdType, element.wdType, element.wdValue, element.wdName, element.wdLabel, FBBoolToString(element.wdEnabled), FBBoolToString(element.wdVisible), FBBoolToString(element.wdAccessible), element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex]; XCTAssertTrue([resultXml isEqualToString: expectedXml]); } @@ -75,7 +76,7 @@ - (void)testtXPathPresentationWithSomeAttributesExcluded xpathQuery:nil excludingAttributes:@[@"type", @"visible", @"value", @"index"]]; NSString *expectedXml = [NSString stringWithFormat:@"\n<%@ name=\"%@\" label=\"%@\" enabled=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" private_indexPath=\"top\"/>\n", - element.wdType, element.wdName, element.wdLabel, element.wdEnabled ? @"true" : @"false", element.wdAccessible ? @"true" : @"false", element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"]]; + element.wdType, element.wdName, element.wdLabel, FBBoolToString(element.wdEnabled), FBBoolToString(element.wdAccessible), element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"]]; XCTAssertEqualObjects(resultXml, expectedXml); } @@ -88,9 +89,9 @@ - (void)testXPathPresentationBasedOnQueryMatchingAllAttributes NSString *resultXml = [self xmlStringWithElement:element xpathQuery:[NSString stringWithFormat:@"//%@[@*]", element.wdType] excludingAttributes:@[@"visible"]]; - NSString *expectedXml = [NSString stringWithFormat:@"\n<%@ type=\"%@\" value=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" private_indexPath=\"top\"/>\n", - element.wdType, element.wdType, @"йоло<>&"", element.wdName, @"a b", element.wdEnabled ? @"true" : @"false", element.wdVisible ? @"true" : @"false", element.wdAccessible ? @"true" : @"false", element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex]; - XCTAssertTrue([resultXml isEqualToString:expectedXml]); + NSString *expectedXml = [NSString stringWithFormat:@"\n<%@ type=\"%@\" value=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" hittable=\"%@\" private_indexPath=\"top\"/>\n", + element.wdType, element.wdType, @"йоло<>&"", element.wdName, @"a b", FBBoolToString(element.wdEnabled), FBBoolToString(element.wdVisible), FBBoolToString(element.wdAccessible), element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex, FBBoolToString(element.wdHittable)]; + XCTAssertEqualObjects(expectedXml, resultXml); } - (void)testXPathPresentationBasedOnQueryMatchingSomeAttributes diff --git a/WebDriverAgentTests/UnitTests_tvOS/Doubles/XCUIElementDouble.h b/WebDriverAgentTests/UnitTests_tvOS/Doubles/XCUIElementDouble.h index d8f272d31..cb43c334d 100644 --- a/WebDriverAgentTests/UnitTests_tvOS/Doubles/XCUIElementDouble.h +++ b/WebDriverAgentTests/UnitTests_tvOS/Doubles/XCUIElementDouble.h @@ -32,6 +32,7 @@ @property (nonatomic, readwrite, getter=isWDVisible) BOOL wdVisible; @property (nonatomic, readwrite, getter=isWDAccessible) BOOL wdAccessible; @property (nonatomic, readwrite, getter=isWDFocused) BOOL wdFocused; +@property (nonatomic, readwrite, getter = isWDHittable) BOOL wdHittable; @property (copy, nonnull) NSArray *children; @property (nonatomic, readwrite, assign) XCUIElementType elementType; @property (nonatomic, readwrite, getter=isWDAccessibilityContainer) BOOL wdAccessibilityContainer; diff --git a/WebDriverAgentTests/UnitTests_tvOS/Doubles/XCUIElementDouble.m b/WebDriverAgentTests/UnitTests_tvOS/Doubles/XCUIElementDouble.m index f8b39940a..2ed546319 100644 --- a/WebDriverAgentTests/UnitTests_tvOS/Doubles/XCUIElementDouble.m +++ b/WebDriverAgentTests/UnitTests_tvOS/Doubles/XCUIElementDouble.m @@ -27,6 +27,7 @@ - (id)init self.wdAccessible = YES; self.wdEnabled = YES; self.wdSelected = YES; + self.wdHittable = YES; self.wdIndex = 0; #if TARGET_OS_TV self.wdFocused = YES; From 11e62d9e09dc8ec8ead2da998de8e26018bec79f Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 24 Aug 2023 20:29:41 +0000 Subject: [PATCH 161/240] chore(release): 5.8.0 [skip ci] ## [5.8.0](https://github.com/appium/WebDriverAgent/compare/v5.7.0...v5.8.0) (2023-08-24) ### Features * Add wdHittable property ([#756](https://github.com/appium/WebDriverAgent/issues/756)) ([075298b](https://github.com/appium/WebDriverAgent/commit/075298b286c83ab5d4a2855e9e0bb915790b3f43)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f864d6fd3..6dbd23def 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.8.0](https://github.com/appium/WebDriverAgent/compare/v5.7.0...v5.8.0) (2023-08-24) + + +### Features + +* Add wdHittable property ([#756](https://github.com/appium/WebDriverAgent/issues/756)) ([075298b](https://github.com/appium/WebDriverAgent/commit/075298b286c83ab5d4a2855e9e0bb915790b3f43)) + ## [5.7.0](https://github.com/appium/WebDriverAgent/compare/v5.6.2...v5.7.0) (2023-08-24) diff --git a/package.json b/package.json index 033a06d26..2ab81005c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.7.0", + "version": "5.8.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From d86d9a64ca75ad40273cfa10855f49b967d9fd95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Aug 2023 23:04:59 -0700 Subject: [PATCH 162/240] chore(deps-dev): bump semantic-release from 20.1.3 to 21.1.0 (#754) Bumps [semantic-release](https://github.com/semantic-release/semantic-release) from 20.1.3 to 21.1.0. - [Release notes](https://github.com/semantic-release/semantic-release/releases) - [Commits](https://github.com/semantic-release/semantic-release/compare/v20.1.3...v21.1.0) --- updated-dependencies: - dependency-name: semantic-release dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2ab81005c..e073e9428 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "mocha": "^10.0.0", "pre-commit": "^1.2.2", "prettier": "^3.0.0", - "semantic-release": "^20.0.2", + "semantic-release": "^21.1.0", "sinon": "^15.0.0", "ts-node": "^10.9.1", "typescript": "^5.1.6" From 734d13927b9d83deabb945062cc8e44a35960d77 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 25 Aug 2023 06:12:22 +0000 Subject: [PATCH 163/240] chore(release): 5.8.1 [skip ci] ## [5.8.1](https://github.com/appium/WebDriverAgent/compare/v5.8.0...v5.8.1) (2023-08-25) ### Miscellaneous Chores * **deps-dev:** bump semantic-release from 20.1.3 to 21.1.0 ([#754](https://github.com/appium/WebDriverAgent/issues/754)) ([d86d9a6](https://github.com/appium/WebDriverAgent/commit/d86d9a64ca75ad40273cfa10855f49b967d9fd95)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dbd23def..8cb22daf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.8.1](https://github.com/appium/WebDriverAgent/compare/v5.8.0...v5.8.1) (2023-08-25) + + +### Miscellaneous Chores + +* **deps-dev:** bump semantic-release from 20.1.3 to 21.1.0 ([#754](https://github.com/appium/WebDriverAgent/issues/754)) ([d86d9a6](https://github.com/appium/WebDriverAgent/commit/d86d9a64ca75ad40273cfa10855f49b967d9fd95)) + ## [5.8.0](https://github.com/appium/WebDriverAgent/compare/v5.7.0...v5.8.0) (2023-08-24) diff --git a/package.json b/package.json index e073e9428..afd05bd50 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.8.0", + "version": "5.8.1", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From a3047ea70b7a9fd5ccb2a2c93b0964d7de609d38 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 17:41:20 +0200 Subject: [PATCH 164/240] chore(deps-dev): bump conventional-changelog-conventionalcommits (#757) Bumps [conventional-changelog-conventionalcommits](https://github.com/conventional-changelog/conventional-changelog) from 6.1.0 to 7.0.1. - [Release notes](https://github.com/conventional-changelog/conventional-changelog/releases) - [Changelog](https://github.com/conventional-changelog/conventional-changelog/blob/master/.release-please-manifest.json) - [Commits](https://github.com/conventional-changelog/conventional-changelog/compare/conventional-changelog-conventionalcommits-v6.1.0...conventional-changelog-conventionalcommits-v7.0.1) --- updated-dependencies: - dependency-name: conventional-changelog-conventionalcommits dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index afd05bd50..d3193710e 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "appium-xcode": "^5.0.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", - "conventional-changelog-conventionalcommits": "^6.0.0", + "conventional-changelog-conventionalcommits": "^7.0.1", "eslint": "^8.46.0", "eslint-config-prettier": "^8.9.0", "eslint-import-resolver-typescript": "^3.5.5", From 2470883019400d9335d2d7263dab82d11b8c2448 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 28 Aug 2023 17:17:14 +0000 Subject: [PATCH 165/240] chore(release): 5.8.2 [skip ci] ## [5.8.2](https://github.com/appium/WebDriverAgent/compare/v5.8.1...v5.8.2) (2023-08-28) ### Miscellaneous Chores * **deps-dev:** bump conventional-changelog-conventionalcommits ([#757](https://github.com/appium/WebDriverAgent/issues/757)) ([a3047ea](https://github.com/appium/WebDriverAgent/commit/a3047ea70b7a9fd5ccb2a2c93b0964d7de609d38)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cb22daf6..96e1453c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.8.2](https://github.com/appium/WebDriverAgent/compare/v5.8.1...v5.8.2) (2023-08-28) + + +### Miscellaneous Chores + +* **deps-dev:** bump conventional-changelog-conventionalcommits ([#757](https://github.com/appium/WebDriverAgent/issues/757)) ([a3047ea](https://github.com/appium/WebDriverAgent/commit/a3047ea70b7a9fd5ccb2a2c93b0964d7de609d38)) + ## [5.8.1](https://github.com/appium/WebDriverAgent/compare/v5.8.0...v5.8.1) (2023-08-25) diff --git a/package.json b/package.json index d3193710e..b35df82fb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.8.1", + "version": "5.8.2", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 87e87044d6216513f755c5184d61514a76cb0179 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Fri, 1 Sep 2023 07:25:19 +0200 Subject: [PATCH 166/240] fix: Address some typing-related issues (#759) --- lib/webdriveragent.js | 6 ++--- lib/xcodebuild.js | 63 ++++++++++++++++++++++--------------------- 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/lib/webdriveragent.js b/lib/webdriveragent.js index 40196b6ea..fdae2bff6 100644 --- a/lib/webdriveragent.js +++ b/lib/webdriveragent.js @@ -467,10 +467,8 @@ class WebDriverAgent { } } else if (!this.args.webDriverAgentUrl) { this.log.info('Shutting down sub-processes'); - // @ts-ignore xcodebuild should be set - await this.xcodebuild.quit(); - // @ts-ignore xcodebuild should be set - await this.xcodebuild.reset(); + await this.xcodebuild?.quit(); + await this.xcodebuild?.reset(); } else { this.log.debug('Do not stop xcodebuild nor XCTest session ' + 'since the WDA session is managed by outside this driver.'); diff --git a/lib/xcodebuild.js b/lib/xcodebuild.js index 348a4f967..23f365417 100644 --- a/lib/xcodebuild.js +++ b/lib/xcodebuild.js @@ -84,6 +84,13 @@ class XcodeBuild { this.resultBundlePath = args.resultBundlePath; this.resultBundleVersion = args.resultBundleVersion; + + /** @type {string} */ + this._logLocation = ''; + /** @type {string[]} */ + this._wdaErrorMessage = []; + this._didBuildFail = false; + this._didProcessExit = false; } async init (noSessionProxy) { @@ -163,8 +170,10 @@ class XcodeBuild { this.xcodebuild = null; - // pause a moment - await B.delay(this.prebuildDelay); + if (this.prebuildDelay > 0) { + // pause a moment + await B.delay(this.prebuildDelay); + } } async cleanProject () { @@ -272,6 +281,8 @@ class XcodeBuild { if (upgradeTimestamp) { env.UPGRADE_TIMESTAMP = upgradeTimestamp; } + this._logLocation = ''; + this._didBuildFail = false; const xcodebuild = new SubProcess(cmd, args, { cwd: this.bootstrapPath, env, @@ -291,10 +302,8 @@ class XcodeBuild { if (out.includes('Writing diagnostic log for test session to')) { // pull out the first line that begins with the path separator // which *should* be the line indicating the log file generated - // @ts-ignore logLocation is a custom property - xcodebuild.logLocation = _.first(_.remove(out.trim().split('\n'), (v) => v.startsWith(path.sep))); - // @ts-ignore logLocation is a custom property - xcodeLog.debug(`Log file for xcodebuild test: ${xcodebuild.logLocation}`); + this._logLocation = _.first(_.remove(out.trim().split('\n'), (v) => v.startsWith(path.sep))) ?? ''; + xcodeLog.debug(`Log file location for xcodebuild test: ${this._logLocation || 'unknown'}`); } // if we have an error we want to output the logs @@ -304,9 +313,8 @@ class XcodeBuild { if (this.showXcodeLog !== false && out.includes('Error Domain=') && !ignoreError) { logXcodeOutput = true; - // terrible hack to handle case where xcode return 0 but is failing - // @ts-ignore _wda_error_occurred is a custom property - xcodebuild._wda_error_occurred = true; + // handle case where xcode returns 0 but is failing + this._didBuildFail = true; } // do not log permission errors from trying to write to attachments folder @@ -314,8 +322,7 @@ class XcodeBuild { for (const line of out.split(EOL)) { xcodeLog.error(line); if (line) { - // @ts-ignore _wda_error_message is a custom property - xcodebuild._wda_error_message += `${EOL}${line}`; + this._wdaErrorMessage.push(line); } } } @@ -327,24 +334,23 @@ class XcodeBuild { async start (buildOnly = false) { this.xcodebuild = await this.createSubProcess(buildOnly); // Store xcodebuild message - // @ts-ignore _wda_error_message is a custom property - this.xcodebuild._wda_error_message = ''; + this._wdaErrorMessage = []; // wrap the start procedure in a promise so that we can catch, and report, // any startup errors that are thrown as events return await new B((resolve, reject) => { // @ts-ignore xcodebuild must be present here - this.xcodebuild.on('exit', async (code, signal) => { + this.xcodebuild.once('exit', async (code, signal) => { xcodeLog.error(`xcodebuild exited with code '${code}' and signal '${signal}'`); + this.xcodebuild?.removeAllListeners(); + const xcodeErrorMessage = this._wdaErrorMessage.join('\n'); + this._wdaErrorMessage = []; // print out the xcodebuild file if users have asked for it - // @ts-ignore logLocation is a custom property - if (this.showXcodeLog && this.xcodebuild?.logLocation) { - // @ts-ignore logLocation is a custom property - xcodeLog.error(`Contents of xcodebuild log file '${this.xcodebuild.logLocation}':`); + if (this.showXcodeLog && this._logLocation) { + xcodeLog.error(`Contents of xcodebuild log file '${this._logLocation}':`); try { const logFile = readline.createInterface({ - // @ts-ignore logLocation is a custom property - input: fs.createReadStream(this.xcodebuild.logLocation), + input: fs.createReadStream(this._logLocation), terminal: false }); logFile.on('line', (line) => { @@ -360,13 +366,10 @@ class XcodeBuild { xcodeLog.error(`Unable to access xcodebuild log file: '${err.message}'`); } } - // @ts-ignore processExited is a custom property - this.xcodebuild.processExited = true; - // @ts-ignore _wda_error_occurred is a custom property - if (this.xcodebuild._wda_error_occurred || (!signal && code !== 0)) { - return reject(new Error(`xcodebuild failed with code ${code}${EOL}` + - // @ts-ignore _wda_error_message is a custom property - `xcodebuild error message:${EOL}${this.xcodebuild._wda_error_message}`)); + this.didProcessExit = true; + if (this._didBuildFail || (!signal && code !== 0)) { + return reject(new Error(`xcodebuild failed with code ${code}\n` + + `xcodebuild error message:\n${xcodeErrorMessage}`)); } // in the case of just building, the process will exit and that is our finish if (buildOnly) { @@ -399,8 +402,7 @@ class XcodeBuild { try { let retries = parseInt(`${this.launchTimeout / 500}`, 10); await retryInterval(retries, 1000, async () => { - // @ts-ignore processExited is a custom property - if (this.xcodebuild.processExited) { + if (this._didProcessExit) { // there has been an error elsewhere and we need to short-circuit return; } @@ -420,8 +422,7 @@ class XcodeBuild { } }); - // @ts-ignore processExited is a custom property - if (this.xcodebuild.processExited) { + if (this._didProcessExit) { // there has been an error elsewhere and we need to short-circuit return currentStatus; } From 9773d1b7b432736a813bced9bf26efefecdf066f Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Fri, 1 Sep 2023 07:32:23 +0200 Subject: [PATCH 167/240] tests: Fix unit tests --- .github/workflows/unit-test.yml | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 665cf2e5d..ef98e4ca6 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -9,17 +9,9 @@ jobs: outputs: versions: ${{ steps.generate-matrix.outputs.versions }} steps: - - name: Generate Node.js versions matrix + - name: Select 3 most recent LTS versions of Node.js id: generate-matrix - run: | - sudo apt-get install -y lynx - lynx -dump https://endoflife.date/nodejs | grep -E -o '[0-9]+[( a-zA-Z]+LTS\)' | grep -E -o '([0-9]+)' > eol.list - cat eol.list - lts1=$(cat eol.list | head -1) - lts2=$(cat eol.list | head -2 | tail -1) - lts3=$(cat eol.list | head -3 | tail -1) - VERSIONS="[$lts1, $lts2, $lts3]" - echo "versions=${VERSIONS}" >> "$GITHUB_OUTPUT" + run: echo "versions=$(curl -s https://endoflife.date/api/nodejs.json | jq -c '[[.[] | select(.lts != false)][:3] | .[].cycle | tonumber]')" >> "$GITHUB_OUTPUT" test: needs: @@ -33,8 +25,6 @@ jobs: - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - - run: npm i -g npm - name: Update NPM - run: npm install --no-package-lock name: Install dev dependencies - run: npm run lint From 7168159cabdd19b31913a2e4b401f07143f5a732 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 1 Sep 2023 05:41:29 +0000 Subject: [PATCH 168/240] chore(release): 5.8.3 [skip ci] ## [5.8.3](https://github.com/appium/WebDriverAgent/compare/v5.8.2...v5.8.3) (2023-09-01) ### Bug Fixes * Address some typing-related issues ([#759](https://github.com/appium/WebDriverAgent/issues/759)) ([87e8704](https://github.com/appium/WebDriverAgent/commit/87e87044d6216513f755c5184d61514a76cb0179)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96e1453c2..311f82c73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.8.3](https://github.com/appium/WebDriverAgent/compare/v5.8.2...v5.8.3) (2023-09-01) + + +### Bug Fixes + +* Address some typing-related issues ([#759](https://github.com/appium/WebDriverAgent/issues/759)) ([87e8704](https://github.com/appium/WebDriverAgent/commit/87e87044d6216513f755c5184d61514a76cb0179)) + ## [5.8.2](https://github.com/appium/WebDriverAgent/compare/v5.8.1...v5.8.2) (2023-08-28) diff --git a/package.json b/package.json index b35df82fb..a1c2045ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.8.2", + "version": "5.8.3", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 1af64b8834371a3fdb3d0aab82fdfdeff6194555 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 10:21:40 -0700 Subject: [PATCH 169/240] chore(deps-dev): bump @types/teen_process from 2.0.0 to 2.0.1 (#765) Bumps [@types/teen_process](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/teen_process) from 2.0.0 to 2.0.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/teen_process) --- updated-dependencies: - dependency-name: "@types/teen_process" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a1c2045ac..4b3a65883 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@types/node": "^20.4.7", "@types/sinon": "^10.0.16", "@types/sinon-chai": "^3.2.9", - "@types/teen_process": "2.0.0", + "@types/teen_process": "2.0.1", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", "appium-xcode": "^5.0.0", From 10ac5a5ec473c33e4e21791161e3686aa241e3a2 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 14 Sep 2023 17:29:44 +0000 Subject: [PATCH 170/240] chore(release): 5.8.4 [skip ci] ## [5.8.4](https://github.com/appium/WebDriverAgent/compare/v5.8.3...v5.8.4) (2023-09-14) ### Miscellaneous Chores * **deps-dev:** bump @types/teen_process from 2.0.0 to 2.0.1 ([#765](https://github.com/appium/WebDriverAgent/issues/765)) ([1af64b8](https://github.com/appium/WebDriverAgent/commit/1af64b8834371a3fdb3d0aab82fdfdeff6194555)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 311f82c73..57efb91e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.8.4](https://github.com/appium/WebDriverAgent/compare/v5.8.3...v5.8.4) (2023-09-14) + + +### Miscellaneous Chores + +* **deps-dev:** bump @types/teen_process from 2.0.0 to 2.0.1 ([#765](https://github.com/appium/WebDriverAgent/issues/765)) ([1af64b8](https://github.com/appium/WebDriverAgent/commit/1af64b8834371a3fdb3d0aab82fdfdeff6194555)) + ## [5.8.3](https://github.com/appium/WebDriverAgent/compare/v5.8.2...v5.8.3) (2023-09-01) diff --git a/package.json b/package.json index 4b3a65883..052bfd598 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.8.3", + "version": "5.8.4", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 2ffd187b2e8b3c1ed04537320179bdfe9f9635df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Sep 2023 09:38:13 -0700 Subject: [PATCH 171/240] chore(deps-dev): bump sinon from 15.2.0 to 16.0.0 (#766) Bumps [sinon](https://github.com/sinonjs/sinon) from 15.2.0 to 16.0.0. - [Release notes](https://github.com/sinonjs/sinon/releases) - [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md) - [Commits](https://github.com/sinonjs/sinon/compare/v15.2.0...v16.0.0) --- updated-dependencies: - dependency-name: sinon dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 052bfd598..2c9cf024a 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "pre-commit": "^1.2.2", "prettier": "^3.0.0", "semantic-release": "^21.1.0", - "sinon": "^15.0.0", + "sinon": "^16.0.0", "ts-node": "^10.9.1", "typescript": "^5.1.6" }, From 224cfbbb0a3cf6c2f6a593a5c60fb8dd424f5fe5 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 15 Sep 2023 16:45:31 +0000 Subject: [PATCH 172/240] chore(release): 5.8.5 [skip ci] ## [5.8.5](https://github.com/appium/WebDriverAgent/compare/v5.8.4...v5.8.5) (2023-09-15) ### Miscellaneous Chores * **deps-dev:** bump sinon from 15.2.0 to 16.0.0 ([#766](https://github.com/appium/WebDriverAgent/issues/766)) ([2ffd187](https://github.com/appium/WebDriverAgent/commit/2ffd187b2e8b3c1ed04537320179bdfe9f9635df)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57efb91e0..dba290295 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.8.5](https://github.com/appium/WebDriverAgent/compare/v5.8.4...v5.8.5) (2023-09-15) + + +### Miscellaneous Chores + +* **deps-dev:** bump sinon from 15.2.0 to 16.0.0 ([#766](https://github.com/appium/WebDriverAgent/issues/766)) ([2ffd187](https://github.com/appium/WebDriverAgent/commit/2ffd187b2e8b3c1ed04537320179bdfe9f9635df)) + ## [5.8.4](https://github.com/appium/WebDriverAgent/compare/v5.8.3...v5.8.4) (2023-09-14) diff --git a/package.json b/package.json index 2c9cf024a..b8dd1fcd9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.8.4", + "version": "5.8.5", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 3ec962842f121bb6dbfc28ab1b30f69d0adc0123 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Tue, 19 Sep 2023 04:07:47 -0400 Subject: [PATCH 173/240] ci: use Xcode 14.3 to build WDA (#770) * ci: use Xcode 14.3 to build WDA * use the same one in release --- .github/workflows/publish.js.yml | 4 ++-- .github/workflows/wda-package.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish.js.yml b/.github/workflows/publish.js.yml index 6d1915ca7..6cd3a0276 100644 --- a/.github/workflows/publish.js.yml +++ b/.github/workflows/publish.js.yml @@ -10,10 +10,10 @@ on: jobs: build: - runs-on: macos-12 + runs-on: macos-13 env: - XCODE_VERSION: 14.2 + XCODE_VERSION: 14.3.1 ZIP_PKG_NAME_IOS: "WebDriverAgentRunner-Runner.zip" PKG_PATH_IOS: "appium_wda_ios" ZIP_PKG_NAME_TVOS: "WebDriverAgentRunner_tvOS-Runner.zip" diff --git a/.github/workflows/wda-package.yml b/.github/workflows/wda-package.yml index d544e927e..b4b4223f2 100644 --- a/.github/workflows/wda-package.yml +++ b/.github/workflows/wda-package.yml @@ -8,8 +8,8 @@ on: - completed env: - HOST: macos-12 - XCODE_VERSION: 14.2 + HOST: macos-13 + XCODE_VERSION: 14.3.1 DESTINATION_SIM: platform=iOS Simulator,name=iPhone 14 Pro DESTINATION_SIM_tvOS: platform=tvOS Simulator,name=Apple TV From 012af21383829397c7265daa0513829cc4e93aee Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Thu, 21 Sep 2023 16:38:50 -0700 Subject: [PATCH 174/240] chore: add log to leave it in the system log (#772) --- WebDriverAgentLib/Commands/FBSessionCommands.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WebDriverAgentLib/Commands/FBSessionCommands.m b/WebDriverAgentLib/Commands/FBSessionCommands.m index 565939080..17153b8b5 100644 --- a/WebDriverAgentLib/Commands/FBSessionCommands.m +++ b/WebDriverAgentLib/Commands/FBSessionCommands.m @@ -421,6 +421,8 @@ + (NSDictionary *)sessionInformation + (NSDictionary *)currentCapabilities { FBApplication *application = [FBSession activeSession].activeApplication; + // to log the info in the system + [FBLogger logFmt:@"Current active application bundle id is %@", application.bundleID]; return @{ @"device": ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) ? @"ipad" : @"iphone", From 49c135c7ee19336e68c4dca70e4e9eb0e1b2f56f Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 21 Sep 2023 23:45:14 +0000 Subject: [PATCH 175/240] chore(release): 5.8.6 [skip ci] ## [5.8.6](https://github.com/appium/WebDriverAgent/compare/v5.8.5...v5.8.6) (2023-09-21) ### Miscellaneous Chores * add log to leave it in the system log ([#772](https://github.com/appium/WebDriverAgent/issues/772)) ([012af21](https://github.com/appium/WebDriverAgent/commit/012af21383829397c7265daa0513829cc4e93aee)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dba290295..12bb43640 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.8.6](https://github.com/appium/WebDriverAgent/compare/v5.8.5...v5.8.6) (2023-09-21) + + +### Miscellaneous Chores + +* add log to leave it in the system log ([#772](https://github.com/appium/WebDriverAgent/issues/772)) ([012af21](https://github.com/appium/WebDriverAgent/commit/012af21383829397c7265daa0513829cc4e93aee)) + ## [5.8.5](https://github.com/appium/WebDriverAgent/compare/v5.8.4...v5.8.5) (2023-09-15) diff --git a/package.json b/package.json index b8dd1fcd9..fb268bf9e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.8.5", + "version": "5.8.6", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 8481b02fc84de1147e1254ea7fd114f8735b0226 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Thu, 21 Sep 2023 18:36:57 -0700 Subject: [PATCH 176/240] chore: tweak device in currentCapabilities (#773) * chore: tweak device * chore: tweak * keep lower case * Update FBSessionCommands.m --- .../Commands/FBSessionCommands.m | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/WebDriverAgentLib/Commands/FBSessionCommands.m b/WebDriverAgentLib/Commands/FBSessionCommands.m index 17153b8b5..7d8d3e077 100644 --- a/WebDriverAgentLib/Commands/FBSessionCommands.m +++ b/WebDriverAgentLib/Commands/FBSessionCommands.m @@ -257,7 +257,8 @@ + (NSArray *)routes #endif @"ip" : [XCUIDevice sharedDevice].fb_wifiIPAddress ?: [NSNull null] }, - @"build" : buildInfo.copy + @"build" : buildInfo.copy, + @"device": [self.class deviceNameByUserInterfaceIdiom:[UIDevice currentDevice].userInterfaceIdiom] } ); } @@ -418,6 +419,23 @@ + (NSDictionary *)sessionInformation }; } +/* + Return the device kind as lower case +*/ ++ (NSString *)deviceNameByUserInterfaceIdiom:(UIUserInterfaceIdiom) userInterfaceIdiom +{ + if (userInterfaceIdiom == UIUserInterfaceIdiomPad) { + return @"ipad"; + } else if (userInterfaceIdiom == UIUserInterfaceIdiomTV) { + return @"apple tv"; + } else if (userInterfaceIdiom == UIUserInterfaceIdiomPhone) { + return @"iphone"; + } + // CarPlay, Mac, Vision UI or unknown are possible + return @"Unknown"; + +} + + (NSDictionary *)currentCapabilities { FBApplication *application = [FBSession activeSession].activeApplication; @@ -425,7 +443,7 @@ + (NSDictionary *)currentCapabilities [FBLogger logFmt:@"Current active application bundle id is %@", application.bundleID]; return @{ - @"device": ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) ? @"ipad" : @"iphone", + @"device": [self.class deviceNameByUserInterfaceIdiom:[UIDevice currentDevice].userInterfaceIdiom], @"sdkVersion": [[UIDevice currentDevice] systemVersion], @"browserName": application.label ?: [NSNull null], @"CFBundleIdentifier": application.bundleID ?: [NSNull null], From 5d2bd5fe4228cfa624f8700619879b62012ceca8 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 22 Sep 2023 01:42:06 +0000 Subject: [PATCH 177/240] chore(release): 5.8.7 [skip ci] ## [5.8.7](https://github.com/appium/WebDriverAgent/compare/v5.8.6...v5.8.7) (2023-09-22) ### Miscellaneous Chores * tweak device in currentCapabilities ([#773](https://github.com/appium/WebDriverAgent/issues/773)) ([8481b02](https://github.com/appium/WebDriverAgent/commit/8481b02fc84de1147e1254ea7fd114f8735b0226)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12bb43640..946a76c6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.8.7](https://github.com/appium/WebDriverAgent/compare/v5.8.6...v5.8.7) (2023-09-22) + + +### Miscellaneous Chores + +* tweak device in currentCapabilities ([#773](https://github.com/appium/WebDriverAgent/issues/773)) ([8481b02](https://github.com/appium/WebDriverAgent/commit/8481b02fc84de1147e1254ea7fd114f8735b0226)) + ## [5.8.6](https://github.com/appium/WebDriverAgent/compare/v5.8.5...v5.8.6) (2023-09-21) diff --git a/package.json b/package.json index fb268bf9e..177169744 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.8.6", + "version": "5.8.7", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 2784ce440f8b5ab9710db08d9ffda704697ac07c Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Fri, 22 Sep 2023 11:18:11 -0700 Subject: [PATCH 178/240] feat: do not get active process information in a new session request (#774) * fix: improve new session creation performance * Update FBSessionCommands.m --- WebDriverAgentLib/Commands/FBSessionCommands.m | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/WebDriverAgentLib/Commands/FBSessionCommands.m b/WebDriverAgentLib/Commands/FBSessionCommands.m index 7d8d3e077..7bd87a768 100644 --- a/WebDriverAgentLib/Commands/FBSessionCommands.m +++ b/WebDriverAgentLib/Commands/FBSessionCommands.m @@ -410,6 +410,10 @@ + (NSString *)buildTimestamp ]; } +/** + Return current session information. + This response does not have any active application information. +*/ + (NSDictionary *)sessionInformation { return @@ -438,15 +442,10 @@ + (NSString *)deviceNameByUserInterfaceIdiom:(UIUserInterfaceIdiom) userInterfac + (NSDictionary *)currentCapabilities { - FBApplication *application = [FBSession activeSession].activeApplication; - // to log the info in the system - [FBLogger logFmt:@"Current active application bundle id is %@", application.bundleID]; return @{ @"device": [self.class deviceNameByUserInterfaceIdiom:[UIDevice currentDevice].userInterfaceIdiom], - @"sdkVersion": [[UIDevice currentDevice] systemVersion], - @"browserName": application.label ?: [NSNull null], - @"CFBundleIdentifier": application.bundleID ?: [NSNull null], + @"sdkVersion": [[UIDevice currentDevice] systemVersion] }; } From 40a81ebed7730b510b0eacb20d830687276ffb17 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 22 Sep 2023 18:41:08 +0000 Subject: [PATCH 179/240] chore(release): 5.9.0 [skip ci] ## [5.9.0](https://github.com/appium/WebDriverAgent/compare/v5.8.7...v5.9.0) (2023-09-22) ### Features * do not get active process information in a new session request ([#774](https://github.com/appium/WebDriverAgent/issues/774)) ([2784ce4](https://github.com/appium/WebDriverAgent/commit/2784ce440f8b5ab9710db08d9ffda704697ac07c)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 946a76c6f..aadb3e23c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.9.0](https://github.com/appium/WebDriverAgent/compare/v5.8.7...v5.9.0) (2023-09-22) + + +### Features + +* do not get active process information in a new session request ([#774](https://github.com/appium/WebDriverAgent/issues/774)) ([2784ce4](https://github.com/appium/WebDriverAgent/commit/2784ce440f8b5ab9710db08d9ffda704697ac07c)) + ## [5.8.7](https://github.com/appium/WebDriverAgent/compare/v5.8.6...v5.8.7) (2023-09-22) diff --git a/package.json b/package.json index 177169744..4559104ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.8.7", + "version": "5.9.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 51ba527b6cde3773ebcd5323cfa7e0890b2563aa Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Sat, 23 Sep 2023 01:03:00 +0200 Subject: [PATCH 180/240] fix: Provide signing arguments as command line parameters (#779) --- lib/utils.js | 16 ++-------------- lib/xcodebuild.js | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/lib/utils.js b/lib/utils.js index 4a1191600..1474d929f 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,4 +1,4 @@ -import { fs, tempDir, plist } from '@appium/support'; +import { fs, plist } from '@appium/support'; import { exec } from 'teen_process'; import path from 'path'; import log from './logger'; @@ -157,18 +157,6 @@ async function setRealDeviceSecurity (keychainPath, keychainPassword) { await exec('security', ['set-keychain-settings', '-t', '3600', '-l', keychainPath]); } -async function generateXcodeConfigFile (orgId, signingId) { - log.debug(`Generating xcode config file for orgId '${orgId}' and signingId ` + - `'${signingId}'`); - const contents = `DEVELOPMENT_TEAM = ${orgId} -CODE_SIGN_IDENTITY = ${signingId} -`; - const xcconfigPath = await tempDir.path('appium-temp.xcconfig'); - log.debug(`Writing xcode config file to ${xcconfigPath}`); - await fs.writeFile(xcconfigPath, contents, 'utf8'); - return xcconfigPath; -} - /** * Information of the device under test * @typedef {Object} DeviceInfo @@ -394,7 +382,7 @@ async function getPIDsListeningOnPort (port, filteringFunc = null) { } export { updateProjectFile, resetProjectFile, setRealDeviceSecurity, - getAdditionalRunContent, getXctestrunFileName, generateXcodeConfigFile, + getAdditionalRunContent, getXctestrunFileName, setXctestrunFile, getXctestrunFilePath, killProcess, randomInt, getWDAUpgradeTimestamp, resetTestProcesses, getPIDsListeningOnPort, killAppUsingPattern, isTvOS diff --git a/lib/xcodebuild.js b/lib/xcodebuild.js index 23f365417..de6b58818 100644 --- a/lib/xcodebuild.js +++ b/lib/xcodebuild.js @@ -4,7 +4,7 @@ import { fs, logger, timing } from '@appium/support'; import defaultLogger from './logger'; import B from 'bluebird'; import { - setRealDeviceSecurity, generateXcodeConfigFile, setXctestrunFile, + setRealDeviceSecurity, setXctestrunFile, updateProjectFile, resetProjectFile, killProcess, getWDAUpgradeTimestamp, isTvOS } from './utils'; import _ from 'lodash'; @@ -238,9 +238,17 @@ class XcodeBuild { 'Will build for the default platform instead'); } - if (this.realDevice && this.xcodeConfigFile) { - this.log.debug(`Using Xcode configuration file: '${this.xcodeConfigFile}'`); - args.push('-xcconfig', this.xcodeConfigFile); + if (this.realDevice) { + if (this.xcodeConfigFile) { + this.log.debug(`Using Xcode configuration file: '${this.xcodeConfigFile}'`); + args.push('-xcconfig', this.xcodeConfigFile); + } + if (this.xcodeOrgId && this.xcodeSigningId) { + args.push( + `DEVELOPMENT_TEAM=${this.xcodeOrgId}`, + `CODE_SIGN_IDENTITY=${this.xcodeSigningId}`, + ); + } } if (!process.env.APPIUM_XCUITEST_TREAT_WARNINGS_AS_ERRORS) { @@ -260,9 +268,6 @@ class XcodeBuild { if (this.keychainPath && this.keychainPassword) { await setRealDeviceSecurity(this.keychainPath, this.keychainPassword); } - if (this.xcodeOrgId && this.xcodeSigningId && !this.xcodeConfigFile) { - this.xcodeConfigFile = await generateXcodeConfigFile(this.xcodeOrgId, this.xcodeSigningId); - } } const {cmd, args} = this.getCommand(buildOnly); From adf14cc7f6e3a26448315e07a3621bdac7c4aa24 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 22 Sep 2023 23:09:21 +0000 Subject: [PATCH 181/240] chore(release): 5.9.1 [skip ci] ## [5.9.1](https://github.com/appium/WebDriverAgent/compare/v5.9.0...v5.9.1) (2023-09-22) ### Bug Fixes * Provide signing arguments as command line parameters ([#779](https://github.com/appium/WebDriverAgent/issues/779)) ([51ba527](https://github.com/appium/WebDriverAgent/commit/51ba527b6cde3773ebcd5323cfa7e0890b2563aa)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aadb3e23c..26faf0900 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.9.1](https://github.com/appium/WebDriverAgent/compare/v5.9.0...v5.9.1) (2023-09-22) + + +### Bug Fixes + +* Provide signing arguments as command line parameters ([#779](https://github.com/appium/WebDriverAgent/issues/779)) ([51ba527](https://github.com/appium/WebDriverAgent/commit/51ba527b6cde3773ebcd5323cfa7e0890b2563aa)) + ## [5.9.0](https://github.com/appium/WebDriverAgent/compare/v5.8.7...v5.9.0) (2023-09-22) diff --git a/package.json b/package.json index 4559104ad..04337817f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.9.0", + "version": "5.9.1", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From ae6c842f3c4e7deb51fcc7a1a1045d4eeede69fd Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Mon, 25 Sep 2023 16:52:16 -0700 Subject: [PATCH 182/240] feat: remove test frameworks in Frameworks and add device local references as rpath for real devices (#780) * ci: use xcode 15 * Remove embedded frameworks * Update wda-package.yml * tweak * keep using 14.3.1 * explicitly set ENABLE_TESTING_SEARCH_PATHS as YES * add system reference * add FBUtf8SafeDictionary for tv as well * Update publish.js.yml --- .github/workflows/publish.js.yml | 6 ++- Scripts/ci/build-real.sh | 6 +++ WebDriverAgent.xcodeproj/project.pbxproj | 47 ++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish.js.yml b/.github/workflows/publish.js.yml index 6cd3a0276..92299e7a8 100644 --- a/.github/workflows/publish.js.yml +++ b/.github/workflows/publish.js.yml @@ -44,9 +44,10 @@ jobs: -scheme WebDriverAgentRunner \ -destination generic/platform=iOS \ CODE_SIGNING_ALLOWED=NO ARCHS=arm64 - - name: Creating a zip of WebDriverAgentRunner-Runner.app for iOS + - name: Creating a zip of WebDriverAgentRunner-Runner.app for iOS after removing test frameworks run: | pushd appium_wda_ios/Build/Products/Debug-iphoneos + rm -rf WebDriverAgentRunner-Runner.app/Frameworks/XC*.framework zip -r $ZIP_PKG_NAME_IOS WebDriverAgentRunner-Runner.app popd mv $PKG_PATH_IOS/Build/Products/Debug-iphoneos/$ZIP_PKG_NAME_IOS ./ @@ -58,9 +59,10 @@ jobs: -scheme WebDriverAgentRunner_tvOS \ -destination generic/platform=tvOS \ CODE_SIGNING_ALLOWED=NO ARCHS=arm64 - - name: Creating a zip of WebDriverAgentRunner-Runner.app for tvOS + - name: Creating a zip of WebDriverAgentRunner-Runner.app for tvOS after removing test frameworks run: | pushd appium_wda_tvos/Build/Products/Debug-appletvos + rm -rf WebDriverAgentRunner_tvOS-Runner.app/Frameworks/XC*.framework zip -r $ZIP_PKG_NAME_TVOS WebDriverAgentRunner_tvOS-Runner.app popd mv $PKG_PATH_TVOS/Build/Products/Debug-appletvos/$ZIP_PKG_NAME_TVOS ./ diff --git a/Scripts/ci/build-real.sh b/Scripts/ci/build-real.sh index 9303ffe3b..93eec1145 100755 --- a/Scripts/ci/build-real.sh +++ b/Scripts/ci/build-real.sh @@ -12,6 +12,12 @@ xcodebuild clean build-for-testing \ # Only .app is needed. pushd $WD + +# to remove test packages to refer to the device local instead of embedded ones +# XCTAutomationSupport.framework, XCTest.framewor, XCTestCore.framework, +# XCUIAutomation.framework, XCUnit.framework +rm -rf $SCHEME-Runner.app/Frameworks/XC*.framework + zip -r $ZIP_PKG_NAME $SCHEME-Runner.app popd mv $WD/$ZIP_PKG_NAME ./ diff --git a/WebDriverAgent.xcodeproj/project.pbxproj b/WebDriverAgent.xcodeproj/project.pbxproj index a5b933127..3630797a6 100644 --- a/WebDriverAgent.xcodeproj/project.pbxproj +++ b/WebDriverAgent.xcodeproj/project.pbxproj @@ -312,6 +312,8 @@ 64B26508228C5514002A5025 /* XCUIElementDouble.m in Sources */ = {isa = PBXBuildFile; fileRef = 64B26507228C5514002A5025 /* XCUIElementDouble.m */; }; 64B2650A228CE4FF002A5025 /* FBTVNavigationTracker-Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 64B26509228CE4FF002A5025 /* FBTVNavigationTracker-Private.h */; }; 64B2650B228CE4FF002A5025 /* FBTVNavigationTracker-Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 64B26509228CE4FF002A5025 /* FBTVNavigationTracker-Private.h */; }; + 64E3502E2AC0B6EB005F3ACB /* NSDictionary+FBUtf8SafeDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 716F0DA02A16CA1000CDD977 /* NSDictionary+FBUtf8SafeDictionary.m */; }; + 64E3502F2AC0B6FE005F3ACB /* NSDictionary+FBUtf8SafeDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 716F0D9F2A16CA1000CDD977 /* NSDictionary+FBUtf8SafeDictionary.h */; }; 711084441DA3AA7500F913D6 /* FBXPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 711084421DA3AA7500F913D6 /* FBXPath.h */; settings = {ATTRIBUTES = (Public, ); }; }; 711084451DA3AA7500F913D6 /* FBXPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 711084431DA3AA7500F913D6 /* FBXPath.m */; }; 7119097C2152580600BA3C7E /* XCUIScreen.h in Headers */ = {isa = PBXBuildFile; fileRef = 7119097B2152580600BA3C7E /* XCUIScreen.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -2382,6 +2384,7 @@ 641EE6A62240C5CA00173FCB /* FBImageIOScaler.h in Headers */, 641EE6A72240C5CA00173FCB /* FBSession-Private.h in Headers */, 641EE6A82240C5CA00173FCB /* NSString+FBXMLSafeString.h in Headers */, + 64E3502F2AC0B6FE005F3ACB /* NSDictionary+FBUtf8SafeDictionary.h in Headers */, 641EE6A92240C5CA00173FCB /* FBCommandStatus.h in Headers */, 71822702258744A400661B83 /* HTTPResponseProxy.h in Headers */, 71822741258744BB00661B83 /* HTTPLogging.h in Headers */, @@ -2414,7 +2417,6 @@ 641EE6C02240C5CA00173FCB /* XCUIApplication+FBHelpers.h in Headers */, 641EE6C12240C5CA00173FCB /* _XCTestObservationCenterImplementation.h in Headers */, 714EAA0E2673FDFE005C5B47 /* FBCapabilities.h in Headers */, - 716F0DA22A16CA1000CDD977 /* NSDictionary+FBUtf8SafeDictionary.h in Headers */, 641EE6C22240C5CA00173FCB /* XCUIDevice+FBHelpers.h in Headers */, 71D3B3D6267FC7260076473D /* XCUIElement+FBResolve.h in Headers */, 641EE6C32240C5CA00173FCB /* FBClassChainQueryParser.h in Headers */, @@ -3049,6 +3051,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 64E3502E2AC0B6EB005F3ACB /* NSDictionary+FBUtf8SafeDictionary.m in Sources */, 718226CF2587443700661B83 /* GCDAsyncSocket.m in Sources */, E444DCBC24917A5E0060D7EB /* HTTPResponseProxy.m in Sources */, 71D3B3D8267FC7260076473D /* XCUIElement+FBResolve.m in Sources */, @@ -3117,7 +3120,6 @@ 641EE5FF2240C5CA00173FCB /* XCUIElement+FBForceTouch.m in Sources */, 716C9E0327315EFF005AD475 /* XCUIApplication+FBUIInterruptions.m in Sources */, 641EE6002240C5CA00173FCB /* FBTouchActionCommands.m in Sources */, - 716F0DA42A16CA1000CDD977 /* NSDictionary+FBUtf8SafeDictionary.m in Sources */, 719DCF182601EAFB000E765F /* FBNotificationsHelper.m in Sources */, 714EAA102673FDFE005C5B47 /* FBCapabilities.m in Sources */, 641EE6012240C5CA00173FCB /* FBImageIOScaler.m in Sources */, @@ -3172,7 +3174,6 @@ buildActionMask = 2147483647; files = ( 64B26508228C5514002A5025 /* XCUIElementDouble.m in Sources */, - 716F0DA72A17323300CDD977 /* NSDictionaryFBUtf8SafeTests.m in Sources */, 64B26504228C5299002A5025 /* FBTVNavigationTrackerTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3496,12 +3497,17 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Developer"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_TESTING_SEARCH_PATHS = YES; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = WebDriverAgentRunner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", + /System/Developer/Library/Frameworks, + /System/Developer/Library/PrivateFrameworks, + /Developer/Library/PrivateFrameworks, + /Developer/Library/Frameworks, ); MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -3551,12 +3557,17 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Developer"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_TESTING_SEARCH_PATHS = YES; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = WebDriverAgentRunner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", + /System/Developer/Library/Frameworks, + /System/Developer/Library/PrivateFrameworks, + /Developer/Library/PrivateFrameworks, + /Developer/Library/Frameworks, ); MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -3603,6 +3614,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_TESTING_SEARCH_PATHS = YES; FRAMEWORK_SEARCH_PATHS = ( "$(PLATFORM_DIR)/Developer/Library/Frameworks", "$(PLATFORM_DIR)/Developer/Library/PrivateFrameworks", @@ -3614,6 +3626,10 @@ "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", + /System/Developer/Library/Frameworks, + /System/Developer/Library/PrivateFrameworks, + /Developer/Library/PrivateFrameworks, + /Developer/Library/Frameworks, ); OTHER_LDFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = com.facebook.WebDriverAgentLib; @@ -3664,6 +3680,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_TESTING_SEARCH_PATHS = YES; FRAMEWORK_SEARCH_PATHS = ( "$(PLATFORM_DIR)/Developer/Library/Frameworks", "$(PLATFORM_DIR)/Developer/Library/PrivateFrameworks", @@ -3675,6 +3692,10 @@ "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", + /System/Developer/Library/Frameworks, + /System/Developer/Library/PrivateFrameworks, + /Developer/Library/PrivateFrameworks, + /Developer/Library/Frameworks, ); ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ""; @@ -3915,6 +3936,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_TESTING_SEARCH_PATHS = YES; FRAMEWORK_SEARCH_PATHS = ( "$(PLATFORM_DIR)/Developer/Library/Frameworks", "$(PLATFORM_DIR)/Developer/Library/PrivateFrameworks", @@ -3926,6 +3948,10 @@ "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", + /Developer/Library/Frameworks, + /Developer/Library/PrivateFrameworks, + /System/Developer/Library/PrivateFrameworks, + /System/Developer/Library/Frameworks, ); OTHER_LDFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = com.facebook.WebDriverAgentLib; @@ -3974,6 +4000,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_TESTING_SEARCH_PATHS = YES; FRAMEWORK_SEARCH_PATHS = ( "$(PLATFORM_DIR)/Developer/Library/Frameworks", "$(PLATFORM_DIR)/Developer/Library/PrivateFrameworks", @@ -3985,6 +4012,10 @@ "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", + /Developer/Library/Frameworks, + /Developer/Library/PrivateFrameworks, + /System/Developer/Library/PrivateFrameworks, + /System/Developer/Library/Frameworks, ); ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ""; @@ -4212,12 +4243,17 @@ buildSettings = { CLANG_STATIC_ANALYZER_MODE = deep; DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTING_SEARCH_PATHS = YES; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = WebDriverAgentRunner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", + /Developer/Library/Frameworks, + /Developer/Library/PrivateFrameworks, + /System/Developer/Library/PrivateFrameworks, + /System/Developer/Library/Frameworks, ); OTHER_LDFLAGS = ( "$(inherited)", @@ -4259,12 +4295,17 @@ baseConfigurationReference = EEE5CABF1C80361500CBBDD9 /* IOSSettings.xcconfig */; buildSettings = { CLANG_STATIC_ANALYZER_MODE = deep; + ENABLE_TESTING_SEARCH_PATHS = YES; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = WebDriverAgentRunner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", + /Developer/Library/Frameworks, + /Developer/Library/PrivateFrameworks, + /System/Developer/Library/PrivateFrameworks, + /System/Developer/Library/Frameworks, ); ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ( From 7b2c1e58a91c69e66e7403b4b9d262537e164c3b Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 25 Sep 2023 23:58:30 +0000 Subject: [PATCH 183/240] chore(release): 5.10.0 [skip ci] ## [5.10.0](https://github.com/appium/WebDriverAgent/compare/v5.9.1...v5.10.0) (2023-09-25) ### Features * remove test frameworks in Frameworks and add device local references as rpath for real devices ([#780](https://github.com/appium/WebDriverAgent/issues/780)) ([ae6c842](https://github.com/appium/WebDriverAgent/commit/ae6c842f3c4e7deb51fcc7a1a1045d4eeede69fd)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26faf0900..2f1e109ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.10.0](https://github.com/appium/WebDriverAgent/compare/v5.9.1...v5.10.0) (2023-09-25) + + +### Features + +* remove test frameworks in Frameworks and add device local references as rpath for real devices ([#780](https://github.com/appium/WebDriverAgent/issues/780)) ([ae6c842](https://github.com/appium/WebDriverAgent/commit/ae6c842f3c4e7deb51fcc7a1a1045d4eeede69fd)) + ## [5.9.1](https://github.com/appium/WebDriverAgent/compare/v5.9.0...v5.9.1) (2023-09-22) diff --git a/package.json b/package.json index 04337817f..d29c29436 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.9.1", + "version": "5.10.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From f043d67dd90fbfca00b8cf53ccae63dbd67fa150 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 5 Oct 2023 10:36:30 +0200 Subject: [PATCH 184/240] chore: Remove the hardcoded keyboard wait delay from handleKeys (#784) --- WebDriverAgentLib/Commands/FBElementCommands.m | 5 ----- 1 file changed, 5 deletions(-) diff --git a/WebDriverAgentLib/Commands/FBElementCommands.m b/WebDriverAgentLib/Commands/FBElementCommands.m index adb5f6092..0f163521b 100644 --- a/WebDriverAgentLib/Commands/FBElementCommands.m +++ b/WebDriverAgentLib/Commands/FBElementCommands.m @@ -557,11 +557,6 @@ + (NSArray *)routes { NSString *textToType = [request.arguments[@"value"] componentsJoinedByString:@""]; NSUInteger frequency = [request.arguments[@"frequency"] unsignedIntegerValue] ?: [FBConfiguration maxTypingFrequency]; - if (![FBKeyboard waitUntilVisibleForApplication:request.session.activeApplication - timeout:1 - error:nil]) { - [FBLogger log:@"The on-screen keyboard seems to not exist. Continuing with typing anyway"]; - } NSError *error; if (![FBKeyboard typeText:textToType frequency:frequency error:&error]) { return FBResponseWithStatus([FBCommandStatus invalidElementStateErrorWithMessage:error.description From 570866edde713b344efb423b1e3eccf26c7ebab0 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 5 Oct 2023 08:42:01 +0000 Subject: [PATCH 185/240] chore(release): 5.10.1 [skip ci] ## [5.10.1](https://github.com/appium/WebDriverAgent/compare/v5.10.0...v5.10.1) (2023-10-05) ### Miscellaneous Chores * Remove the hardcoded keyboard wait delay from handleKeys ([#784](https://github.com/appium/WebDriverAgent/issues/784)) ([f043d67](https://github.com/appium/WebDriverAgent/commit/f043d67dd90fbfca00b8cf53ccae63dbd67fa150)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f1e109ea..f679c40ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.10.1](https://github.com/appium/WebDriverAgent/compare/v5.10.0...v5.10.1) (2023-10-05) + + +### Miscellaneous Chores + +* Remove the hardcoded keyboard wait delay from handleKeys ([#784](https://github.com/appium/WebDriverAgent/issues/784)) ([f043d67](https://github.com/appium/WebDriverAgent/commit/f043d67dd90fbfca00b8cf53ccae63dbd67fa150)) + ## [5.10.0](https://github.com/appium/WebDriverAgent/compare/v5.9.1...v5.10.0) (2023-09-25) diff --git a/package.json b/package.json index d29c29436..b97e25626 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.10.0", + "version": "5.10.1", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From ae1603a3b5b5c4828ed4959c63d6274254f832a2 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 5 Oct 2023 22:13:00 +0200 Subject: [PATCH 186/240] feat: Add /calibrate endpoint (#785) --- WebDriverAgentLib/Routing/FBWebServer.m | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/WebDriverAgentLib/Routing/FBWebServer.m b/WebDriverAgentLib/Routing/FBWebServer.m index a9b9a0625..7e991e0e2 100644 --- a/WebDriverAgentLib/Routing/FBWebServer.m +++ b/WebDriverAgentLib/Routing/FBWebServer.m @@ -220,6 +220,16 @@ - (void)registerServerKeyRouteHandlers [response respondWithString:@"I-AM-ALIVE"]; }]; + NSString *calibrationPage = @"" + "{\"x\":null,\"y\":null}" + "
" + "" + "
" + ""; + [self.server get:@"/calibrate" withBlock:^(RouteRequest *request, RouteResponse *response) { + [response respondWithString:calibrationPage]; + }]; + [self.server get:@"/wda/shutdown" withBlock:^(RouteRequest *request, RouteResponse *response) { [response respondWithString:@"Shutting down"]; [self.delegate webServerDidRequestShutdown:self]; From a9ced34da71c80a7654358043be37f02af7a1508 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 5 Oct 2023 20:32:08 +0000 Subject: [PATCH 187/240] chore(release): 5.11.0 [skip ci] ## [5.11.0](https://github.com/appium/WebDriverAgent/compare/v5.10.1...v5.11.0) (2023-10-05) ### Features * Add /calibrate endpoint ([#785](https://github.com/appium/WebDriverAgent/issues/785)) ([ae1603a](https://github.com/appium/WebDriverAgent/commit/ae1603a3b5b5c4828ed4959c63d6274254f832a2)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f679c40ad..23f5fd036 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.11.0](https://github.com/appium/WebDriverAgent/compare/v5.10.1...v5.11.0) (2023-10-05) + + +### Features + +* Add /calibrate endpoint ([#785](https://github.com/appium/WebDriverAgent/issues/785)) ([ae1603a](https://github.com/appium/WebDriverAgent/commit/ae1603a3b5b5c4828ed4959c63d6274254f832a2)) + ## [5.10.1](https://github.com/appium/WebDriverAgent/compare/v5.10.0...v5.10.1) (2023-10-05) diff --git a/package.json b/package.json index b97e25626..67a6d23e6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.10.1", + "version": "5.11.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 123eefba5e5e30100cb3cdff09a516179f78afe7 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 19 Oct 2023 15:39:14 +0200 Subject: [PATCH 188/240] chore: Use latest types version --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 67a6d23e6..62dee72a5 100644 --- a/package.json +++ b/package.json @@ -56,10 +56,10 @@ "homepage": "https://github.com/appium/WebDriverAgent#readme", "devDependencies": { "@appium/eslint-config-appium": "^8.0.4", - "@appium/eslint-config-appium-ts": "^0.3.1", + "@appium/eslint-config-appium-ts": "^0.x", "@appium/test-support": "^3.0.0", - "@appium/tsconfig": "^0.3.0", - "@appium/types": "^0.13.2", + "@appium/tsconfig": "^0.x", + "@appium/types": "^0.x", "@semantic-release/changelog": "^6.0.1", "@semantic-release/git": "^10.0.1", "@types/bluebird": "^3.5.38", From 1fb0c4fb7d8de0249dbafde3a563a275477bcd51 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 19 Oct 2023 15:33:00 +0000 Subject: [PATCH 189/240] chore(release): 5.11.1 [skip ci] ## [5.11.1](https://github.com/appium/WebDriverAgent/compare/v5.11.0...v5.11.1) (2023-10-19) ### Miscellaneous Chores * Use latest types version ([123eefb](https://github.com/appium/WebDriverAgent/commit/123eefba5e5e30100cb3cdff09a516179f78afe7)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23f5fd036..588587618 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.11.1](https://github.com/appium/WebDriverAgent/compare/v5.11.0...v5.11.1) (2023-10-19) + + +### Miscellaneous Chores + +* Use latest types version ([123eefb](https://github.com/appium/WebDriverAgent/commit/123eefba5e5e30100cb3cdff09a516179f78afe7)) + ## [5.11.0](https://github.com/appium/WebDriverAgent/compare/v5.10.1...v5.11.0) (2023-10-05) diff --git a/package.json b/package.json index 62dee72a5..bb8c4bcdb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.11.0", + "version": "5.11.1", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 895cdfc1a316117bb7c8b5be0265b439c1e911bc Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 19 Oct 2023 17:40:34 +0200 Subject: [PATCH 190/240] chore: Use latest teen_process types --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bb8c4bcdb..b1f5abf9a 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@types/node": "^20.4.7", "@types/sinon": "^10.0.16", "@types/sinon-chai": "^3.2.9", - "@types/teen_process": "2.0.1", + "@types/teen_process": "^2.0.1", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", "appium-xcode": "^5.0.0", From 18e1dadf5bcdebeb18f25c683c317330af08d479 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 19 Oct 2023 23:09:42 +0000 Subject: [PATCH 191/240] chore(release): 5.11.2 [skip ci] ## [5.11.2](https://github.com/appium/WebDriverAgent/compare/v5.11.1...v5.11.2) (2023-10-19) ### Miscellaneous Chores * Use latest teen_process types ([895cdfc](https://github.com/appium/WebDriverAgent/commit/895cdfc1a316117bb7c8b5be0265b439c1e911bc)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 588587618..178875429 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.11.2](https://github.com/appium/WebDriverAgent/compare/v5.11.1...v5.11.2) (2023-10-19) + + +### Miscellaneous Chores + +* Use latest teen_process types ([895cdfc](https://github.com/appium/WebDriverAgent/commit/895cdfc1a316117bb7c8b5be0265b439c1e911bc)) + ## [5.11.1](https://github.com/appium/WebDriverAgent/compare/v5.11.0...v5.11.1) (2023-10-19) diff --git a/package.json b/package.json index b1f5abf9a..fccb85615 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.11.1", + "version": "5.11.2", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 543c49860d2d35148bcbaa33e14d3e1dab058cef Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sat, 21 Oct 2023 11:44:58 -0700 Subject: [PATCH 192/240] chore: use PRODUCT_BUNDLE_IDENTIFIER to info.plist (#794) --- WebDriverAgentRunner/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebDriverAgentRunner/Info.plist b/WebDriverAgentRunner/Info.plist index 70c8682fd..0b10cd4f3 100644 --- a/WebDriverAgentRunner/Info.plist +++ b/WebDriverAgentRunner/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - com.facebook.wda.runner + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName From 651d2bb06c9f901edb89b6f9c63ba600208ddaaf Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sat, 21 Oct 2023 18:52:42 +0000 Subject: [PATCH 193/240] chore(release): 5.11.3 [skip ci] ## [5.11.3](https://github.com/appium/WebDriverAgent/compare/v5.11.2...v5.11.3) (2023-10-21) ### Miscellaneous Chores * use PRODUCT_BUNDLE_IDENTIFIER to info.plist ([#794](https://github.com/appium/WebDriverAgent/issues/794)) ([543c498](https://github.com/appium/WebDriverAgent/commit/543c49860d2d35148bcbaa33e14d3e1dab058cef)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 178875429..3b320b852 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.11.3](https://github.com/appium/WebDriverAgent/compare/v5.11.2...v5.11.3) (2023-10-21) + + +### Miscellaneous Chores + +* use PRODUCT_BUNDLE_IDENTIFIER to info.plist ([#794](https://github.com/appium/WebDriverAgent/issues/794)) ([543c498](https://github.com/appium/WebDriverAgent/commit/543c49860d2d35148bcbaa33e14d3e1dab058cef)) + ## [5.11.2](https://github.com/appium/WebDriverAgent/compare/v5.11.1...v5.11.2) (2023-10-19) diff --git a/package.json b/package.json index fccb85615..097d7ced6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.11.2", + "version": "5.11.3", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 4921899d96800dbcd59a9c27ba793ad16d0c715b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 20:17:16 +0200 Subject: [PATCH 194/240] chore(deps-dev): bump sinon from 16.1.3 to 17.0.0 (#795) Bumps [sinon](https://github.com/sinonjs/sinon) from 16.1.3 to 17.0.0. - [Release notes](https://github.com/sinonjs/sinon/releases) - [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md) - [Commits](https://github.com/sinonjs/sinon/compare/v16.1.3...v17.0.0) --- updated-dependencies: - dependency-name: sinon dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 097d7ced6..0b7d67eae 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "pre-commit": "^1.2.2", "prettier": "^3.0.0", "semantic-release": "^21.1.0", - "sinon": "^16.0.0", + "sinon": "^17.0.0", "ts-node": "^10.9.1", "typescript": "^5.1.6" }, From d99c79b254f4e83d9de85eac7dd5dd08aab85284 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 23 Oct 2023 20:41:43 +0000 Subject: [PATCH 195/240] chore(release): 5.11.4 [skip ci] ## [5.11.4](https://github.com/appium/WebDriverAgent/compare/v5.11.3...v5.11.4) (2023-10-23) ### Miscellaneous Chores * **deps-dev:** bump sinon from 16.1.3 to 17.0.0 ([#795](https://github.com/appium/WebDriverAgent/issues/795)) ([4921899](https://github.com/appium/WebDriverAgent/commit/4921899d96800dbcd59a9c27ba793ad16d0c715b)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b320b852..dc0c66b0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.11.4](https://github.com/appium/WebDriverAgent/compare/v5.11.3...v5.11.4) (2023-10-23) + + +### Miscellaneous Chores + +* **deps-dev:** bump sinon from 16.1.3 to 17.0.0 ([#795](https://github.com/appium/WebDriverAgent/issues/795)) ([4921899](https://github.com/appium/WebDriverAgent/commit/4921899d96800dbcd59a9c27ba793ad16d0c715b)) + ## [5.11.3](https://github.com/appium/WebDriverAgent/compare/v5.11.2...v5.11.3) (2023-10-21) diff --git a/package.json b/package.json index 0b7d67eae..90fe1b65b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.11.3", + "version": "5.11.4", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 440279d4f6d069e440180faf4bee8e5dc1758787 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 23:41:47 +0200 Subject: [PATCH 196/240] chore(deps-dev): bump lint-staged from 14.0.1 to 15.0.2 (#792) Bumps [lint-staged](https://github.com/okonet/lint-staged) from 14.0.1 to 15.0.2. - [Release notes](https://github.com/okonet/lint-staged/releases) - [Changelog](https://github.com/lint-staged/lint-staged/blob/master/CHANGELOG.md) - [Commits](https://github.com/okonet/lint-staged/compare/v14.0.1...v15.0.2) --- updated-dependencies: - dependency-name: lint-staged dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 90fe1b65b..3fd1bb791 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "eslint-plugin-import": "^2.28.0", "eslint-plugin-mocha": "^10.1.0", "eslint-plugin-promise": "^6.1.1", - "lint-staged": "^14.0.0", + "lint-staged": "^15.0.2", "mocha": "^10.0.0", "pre-commit": "^1.2.2", "prettier": "^3.0.0", From f130961f189f2746d4a2b0a18105fc10203312ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 23:42:02 +0200 Subject: [PATCH 197/240] chore(deps-dev): bump eslint-config-prettier from 8.10.0 to 9.0.0 (#791) Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 8.10.0 to 9.0.0. - [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-config-prettier/compare/v8.10.0...v9.0.0) --- updated-dependencies: - dependency-name: eslint-config-prettier dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3fd1bb791..c09665648 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "chai-as-promised": "^7.1.1", "conventional-changelog-conventionalcommits": "^7.0.1", "eslint": "^8.46.0", - "eslint-config-prettier": "^8.9.0", + "eslint-config-prettier": "^9.0.0", "eslint-import-resolver-typescript": "^3.5.5", "eslint-plugin-import": "^2.28.0", "eslint-plugin-mocha": "^10.1.0", From a96718308dbd6b13feb30e6ce8f01a7d9b74b146 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 23:42:20 +0200 Subject: [PATCH 198/240] chore(deps-dev): bump semantic-release from 21.1.2 to 22.0.5 (#781) Bumps [semantic-release](https://github.com/semantic-release/semantic-release) from 21.1.2 to 22.0.5. - [Release notes](https://github.com/semantic-release/semantic-release/releases) - [Commits](https://github.com/semantic-release/semantic-release/compare/v21.1.2...v22.0.5) --- updated-dependencies: - dependency-name: semantic-release dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c09665648..0466d7f54 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "mocha": "^10.0.0", "pre-commit": "^1.2.2", "prettier": "^3.0.0", - "semantic-release": "^21.1.0", + "semantic-release": "^22.0.5", "sinon": "^17.0.0", "ts-node": "^10.9.1", "typescript": "^5.1.6" From 8f8e582c4f8b51e878791ddbd7f1dac47555ab23 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 23 Oct 2023 23:44:22 +0000 Subject: [PATCH 199/240] chore(release): 5.11.5 [skip ci] ## [5.11.5](https://github.com/appium/WebDriverAgent/compare/v5.11.4...v5.11.5) (2023-10-23) ### Miscellaneous Chores * **deps-dev:** bump eslint-config-prettier from 8.10.0 to 9.0.0 ([#791](https://github.com/appium/WebDriverAgent/issues/791)) ([f130961](https://github.com/appium/WebDriverAgent/commit/f130961f189f2746d4a2b0a18105fc10203312ca)) * **deps-dev:** bump lint-staged from 14.0.1 to 15.0.2 ([#792](https://github.com/appium/WebDriverAgent/issues/792)) ([440279d](https://github.com/appium/WebDriverAgent/commit/440279d4f6d069e440180faf4bee8e5dc1758787)) * **deps-dev:** bump semantic-release from 21.1.2 to 22.0.5 ([#781](https://github.com/appium/WebDriverAgent/issues/781)) ([a967183](https://github.com/appium/WebDriverAgent/commit/a96718308dbd6b13feb30e6ce8f01a7d9b74b146)) --- CHANGELOG.md | 9 +++++++++ package.json | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc0c66b0b..01869dbf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [5.11.5](https://github.com/appium/WebDriverAgent/compare/v5.11.4...v5.11.5) (2023-10-23) + + +### Miscellaneous Chores + +* **deps-dev:** bump eslint-config-prettier from 8.10.0 to 9.0.0 ([#791](https://github.com/appium/WebDriverAgent/issues/791)) ([f130961](https://github.com/appium/WebDriverAgent/commit/f130961f189f2746d4a2b0a18105fc10203312ca)) +* **deps-dev:** bump lint-staged from 14.0.1 to 15.0.2 ([#792](https://github.com/appium/WebDriverAgent/issues/792)) ([440279d](https://github.com/appium/WebDriverAgent/commit/440279d4f6d069e440180faf4bee8e5dc1758787)) +* **deps-dev:** bump semantic-release from 21.1.2 to 22.0.5 ([#781](https://github.com/appium/WebDriverAgent/issues/781)) ([a967183](https://github.com/appium/WebDriverAgent/commit/a96718308dbd6b13feb30e6ce8f01a7d9b74b146)) + ## [5.11.4](https://github.com/appium/WebDriverAgent/compare/v5.11.3...v5.11.4) (2023-10-23) diff --git a/package.json b/package.json index 0466d7f54..1bdb2802e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.11.4", + "version": "5.11.5", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From e2f4405a3449f1f4d390eae06bf91a220e81b58b Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Wed, 25 Oct 2023 11:08:27 -0700 Subject: [PATCH 200/240] chore: disable debugger for wda (#768) --- .../xcshareddata/xcschemes/WebDriverAgentRunner.xcscheme | 4 ++-- .../xcshareddata/xcschemes/WebDriverAgentRunner_tvOS.xcscheme | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/WebDriverAgent.xcodeproj/xcshareddata/xcschemes/WebDriverAgentRunner.xcscheme b/WebDriverAgent.xcodeproj/xcshareddata/xcschemes/WebDriverAgentRunner.xcscheme index 82f803a90..8857b934c 100644 --- a/WebDriverAgent.xcodeproj/xcshareddata/xcschemes/WebDriverAgentRunner.xcscheme +++ b/WebDriverAgent.xcodeproj/xcshareddata/xcschemes/WebDriverAgentRunner.xcscheme @@ -24,8 +24,8 @@ diff --git a/WebDriverAgent.xcodeproj/xcshareddata/xcschemes/WebDriverAgentRunner_tvOS.xcscheme b/WebDriverAgent.xcodeproj/xcshareddata/xcschemes/WebDriverAgentRunner_tvOS.xcscheme index 198d2e6cc..e55655225 100644 --- a/WebDriverAgent.xcodeproj/xcshareddata/xcschemes/WebDriverAgentRunner_tvOS.xcscheme +++ b/WebDriverAgent.xcodeproj/xcshareddata/xcschemes/WebDriverAgentRunner_tvOS.xcscheme @@ -24,8 +24,8 @@ From b2b6de43ab448d359f92adfb8dc0b6de302de827 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 25 Oct 2023 19:24:31 +0000 Subject: [PATCH 201/240] chore(release): 5.11.6 [skip ci] ## [5.11.6](https://github.com/appium/WebDriverAgent/compare/v5.11.5...v5.11.6) (2023-10-25) ### Miscellaneous Chores * disable debugger for wda ([#768](https://github.com/appium/WebDriverAgent/issues/768)) ([e2f4405](https://github.com/appium/WebDriverAgent/commit/e2f4405a3449f1f4d390eae06bf91a220e81b58b)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01869dbf2..161e35a0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.11.6](https://github.com/appium/WebDriverAgent/compare/v5.11.5...v5.11.6) (2023-10-25) + + +### Miscellaneous Chores + +* disable debugger for wda ([#768](https://github.com/appium/WebDriverAgent/issues/768)) ([e2f4405](https://github.com/appium/WebDriverAgent/commit/e2f4405a3449f1f4d390eae06bf91a220e81b58b)) + ## [5.11.5](https://github.com/appium/WebDriverAgent/compare/v5.11.4...v5.11.5) (2023-10-23) diff --git a/package.json b/package.json index 1bdb2802e..bd447f321 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.11.5", + "version": "5.11.6", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From dabf141acd3186b1c27231ef52826fa42208c980 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Oct 2023 22:44:50 +0200 Subject: [PATCH 202/240] chore(deps-dev): bump @typescript-eslint/eslint-plugin from 5.62.0 to 6.9.0 (#796) * chore(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.62.0 to 6.9.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.9.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Bump parser --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mykola Mokhnach --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index bd447f321..8f668c0c0 100644 --- a/package.json +++ b/package.json @@ -71,8 +71,8 @@ "@types/sinon": "^10.0.16", "@types/sinon-chai": "^3.2.9", "@types/teen_process": "^2.0.1", - "@typescript-eslint/eslint-plugin": "^5.62.0", - "@typescript-eslint/parser": "^5.62.0", + "@typescript-eslint/eslint-plugin": "^6.9.0", + "@typescript-eslint/parser": "^6.9.0", "appium-xcode": "^5.0.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", From ea6fb73f4906f33697e2877361f800a69c0effbc Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 25 Oct 2023 20:52:59 +0000 Subject: [PATCH 203/240] chore(release): 5.11.7 [skip ci] ## [5.11.7](https://github.com/appium/WebDriverAgent/compare/v5.11.6...v5.11.7) (2023-10-25) ### Miscellaneous Chores * **deps-dev:** bump @typescript-eslint/eslint-plugin from 5.62.0 to 6.9.0 ([#796](https://github.com/appium/WebDriverAgent/issues/796)) ([dabf141](https://github.com/appium/WebDriverAgent/commit/dabf141acd3186b1c27231ef52826fa42208c980)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 161e35a0a..23456c82b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.11.7](https://github.com/appium/WebDriverAgent/compare/v5.11.6...v5.11.7) (2023-10-25) + + +### Miscellaneous Chores + +* **deps-dev:** bump @typescript-eslint/eslint-plugin from 5.62.0 to 6.9.0 ([#796](https://github.com/appium/WebDriverAgent/issues/796)) ([dabf141](https://github.com/appium/WebDriverAgent/commit/dabf141acd3186b1c27231ef52826fa42208c980)) + ## [5.11.6](https://github.com/appium/WebDriverAgent/compare/v5.11.5...v5.11.6) (2023-10-25) diff --git a/package.json b/package.json index 8f668c0c0..fd9ca5401 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.11.6", + "version": "5.11.7", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From aaf70c9196e4dcb2073da151cda23b2b221d4dae Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 26 Oct 2023 16:52:20 +0200 Subject: [PATCH 204/240] feat: Add an endpoint for keyboard input (#797) --- WebDriverAgentLib/Commands/FBCustomCommands.m | 45 +++++++++++++ WebDriverAgentLib/Utilities/FBKeyboard.h | 10 +++ WebDriverAgentLib/Utilities/FBKeyboard.m | 65 +++++++++++++++++++ 3 files changed, 120 insertions(+) diff --git a/WebDriverAgentLib/Commands/FBCustomCommands.m b/WebDriverAgentLib/Commands/FBCustomCommands.m index 9d8e324d7..934cdf73f 100644 --- a/WebDriverAgentLib/Commands/FBCustomCommands.m +++ b/WebDriverAgentLib/Commands/FBCustomCommands.m @@ -70,6 +70,9 @@ + (NSArray *)routes [[FBRoute GET:@"/wda/device/location"] respondWithTarget:self action:@selector(handleGetLocation:)], [[FBRoute GET:@"/wda/device/location"].withoutSession respondWithTarget:self action:@selector(handleGetLocation:)], #if !TARGET_OS_TV // tvOS does not provide relevant APIs +#if __clang_major__ >= 15 + [[FBRoute POST:@"/wda/element/:uuid/keyboardInput"] respondWithTarget:self action:@selector(handleKeyboardInput:)], +#endif [[FBRoute GET:@"/wda/simulatedLocation"] respondWithTarget:self action:@selector(handleGetSimulatedLocation:)], [[FBRoute GET:@"/wda/simulatedLocation"].withoutSession respondWithTarget:self action:@selector(handleGetSimulatedLocation:)], [[FBRoute POST:@"/wda/simulatedLocation"] respondWithTarget:self action:@selector(handleSetSimulatedLocation:)], @@ -543,6 +546,48 @@ + (NSString *)timeZone } return FBResponseWithOK(); } + +#if __clang_major__ >= 15 ++ (id)handleKeyboardInput:(FBRouteRequest *)request +{ + FBElementCache *elementCache = request.session.elementCache; + BOOL hasElement = nil != request.parameters[@"uuid"]; + XCUIElement *destination = hasElement + ? [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]] + : request.session.activeApplication; + id keys = request.arguments[@"keys"]; + if (![keys isKindOfClass:NSArray.class]) { + NSString *message = @"The 'keys' argument must be an array"; + return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:message + traceback:nil]); + } + for (id item in (NSArray *)keys) { + if ([item isKindOfClass:NSString.class]) { + NSString *keyValue = [FBKeyboard keyValueForName:item] ?: item; + [destination typeKey:keyValue modifierFlags:XCUIKeyModifierNone]; + } else if ([item isKindOfClass:NSDictionary.class]) { + id key = [(NSDictionary *)item objectForKey:@"key"]; + if (![key isKindOfClass:NSString.class]) { + NSString *message = [NSString stringWithFormat:@"All dictionaries of 'keys' array must have the 'key' item of type string. Got '%@' instead in the item %@", key, item]; + return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:message + traceback:nil]); + } + id modifiers = [(NSDictionary *)item objectForKey:@"modifierFlags"]; + NSUInteger modifierFlags = XCUIKeyModifierNone; + if ([modifiers isKindOfClass:NSNumber.class]) { + modifierFlags = [(NSNumber *)modifiers unsignedIntValue]; + } + NSString *keyValue = [FBKeyboard keyValueForName:item] ?: key; + [destination typeKey:keyValue modifierFlags:modifierFlags]; + } else { + NSString *message = @"All items of the 'keys' array must be either dictionaries or strings"; + return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:message + traceback:nil]); + } + } + return FBResponseWithOK(); +} +#endif #endif + (id)handlePerformAccessibilityAudit:(FBRouteRequest *)request diff --git a/WebDriverAgentLib/Utilities/FBKeyboard.h b/WebDriverAgentLib/Utilities/FBKeyboard.h index cbe1180cd..5a16e1aed 100644 --- a/WebDriverAgentLib/Utilities/FBKeyboard.h +++ b/WebDriverAgentLib/Utilities/FBKeyboard.h @@ -13,6 +13,16 @@ NS_ASSUME_NONNULL_BEGIN @interface FBKeyboard : NSObject +#if (!TARGET_OS_TV && __clang_major__ >= 15) +/** + Transforms key name to its string representation, which could be used with XCTest + + @param name one of available keyboard key names defined in https://developer.apple.com/documentation/xctest/xcuikeyboardkey?language=objc + @return Either the key value or nil if no matches have been found + */ ++ (nullable NSString *)keyValueForName:(NSString *)name; +#endif + /** Types a string into active element. There must be element with keyboard focus; otherwise an error is raised. diff --git a/WebDriverAgentLib/Utilities/FBKeyboard.m b/WebDriverAgentLib/Utilities/FBKeyboard.m index 7d474ac02..0cf9964c6 100644 --- a/WebDriverAgentLib/Utilities/FBKeyboard.m +++ b/WebDriverAgentLib/Utilities/FBKeyboard.m @@ -80,4 +80,69 @@ + (BOOL)waitUntilVisibleForApplication:(XCUIApplication *)app timeout:(NSTimeInt error:error]; } +#if (!TARGET_OS_TV && __clang_major__ >= 15) + ++ (NSString *)keyValueForName:(NSString *)name +{ + static dispatch_once_t onceKeys; + static NSDictionary *keysMapping; + dispatch_once(&onceKeys, ^{ + keysMapping = @{ + @"XCUIKeyboardKeyDelete": XCUIKeyboardKeyDelete, + @"XCUIKeyboardKeyReturn": XCUIKeyboardKeyReturn, + @"XCUIKeyboardKeyEnter": XCUIKeyboardKeyEnter, + @"XCUIKeyboardKeyTab": XCUIKeyboardKeyTab, + @"XCUIKeyboardKeySpace": XCUIKeyboardKeySpace, + @"XCUIKeyboardKeyEscape": XCUIKeyboardKeyEscape, + + @"XCUIKeyboardKeyUpArrow": XCUIKeyboardKeyUpArrow, + @"XCUIKeyboardKeyDownArrow": XCUIKeyboardKeyDownArrow, + @"XCUIKeyboardKeyLeftArrow": XCUIKeyboardKeyLeftArrow, + @"XCUIKeyboardKeyRightArrow": XCUIKeyboardKeyRightArrow, + + @"XCUIKeyboardKeyF1": XCUIKeyboardKeyF1, + @"XCUIKeyboardKeyF2": XCUIKeyboardKeyF2, + @"XCUIKeyboardKeyF3": XCUIKeyboardKeyF3, + @"XCUIKeyboardKeyF4": XCUIKeyboardKeyF4, + @"XCUIKeyboardKeyF5": XCUIKeyboardKeyF5, + @"XCUIKeyboardKeyF6": XCUIKeyboardKeyF6, + @"XCUIKeyboardKeyF7": XCUIKeyboardKeyF7, + @"XCUIKeyboardKeyF8": XCUIKeyboardKeyF8, + @"XCUIKeyboardKeyF9": XCUIKeyboardKeyF9, + @"XCUIKeyboardKeyF10": XCUIKeyboardKeyF10, + @"XCUIKeyboardKeyF11": XCUIKeyboardKeyF11, + @"XCUIKeyboardKeyF12": XCUIKeyboardKeyF12, + @"XCUIKeyboardKeyF13": XCUIKeyboardKeyF13, + @"XCUIKeyboardKeyF14": XCUIKeyboardKeyF14, + @"XCUIKeyboardKeyF15": XCUIKeyboardKeyF15, + @"XCUIKeyboardKeyF16": XCUIKeyboardKeyF16, + @"XCUIKeyboardKeyF17": XCUIKeyboardKeyF17, + @"XCUIKeyboardKeyF18": XCUIKeyboardKeyF18, + @"XCUIKeyboardKeyF19": XCUIKeyboardKeyF19, + + @"XCUIKeyboardKeyForwardDelete": XCUIKeyboardKeyForwardDelete, + @"XCUIKeyboardKeyHome": XCUIKeyboardKeyHome, + @"XCUIKeyboardKeyEnd": XCUIKeyboardKeyEnd, + @"XCUIKeyboardKeyPageUp": XCUIKeyboardKeyPageUp, + @"XCUIKeyboardKeyPageDown": XCUIKeyboardKeyPageDown, + @"XCUIKeyboardKeyClear": XCUIKeyboardKeyClear, + @"XCUIKeyboardKeyHelp": XCUIKeyboardKeyHelp, + + @"XCUIKeyboardKeyCapsLock": XCUIKeyboardKeyCapsLock, + @"XCUIKeyboardKeyShift": XCUIKeyboardKeyShift, + @"XCUIKeyboardKeyControl": XCUIKeyboardKeyControl, + @"XCUIKeyboardKeyOption": XCUIKeyboardKeyOption, + @"XCUIKeyboardKeyCommand": XCUIKeyboardKeyCommand, + @"XCUIKeyboardKeyRightShift": XCUIKeyboardKeyRightShift, + @"XCUIKeyboardKeyRightControl": XCUIKeyboardKeyRightControl, + @"XCUIKeyboardKeyRightOption": XCUIKeyboardKeyRightOption, + @"XCUIKeyboardKeyRightCommand": XCUIKeyboardKeyRightCommand, + @"XCUIKeyboardKeySecondaryFn": XCUIKeyboardKeySecondaryFn + }; + }); + return keysMapping[name]; +} + +#endif + @end From beb413e37a22d6802f8096b18a68427307caacfd Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 26 Oct 2023 15:03:58 +0000 Subject: [PATCH 205/240] chore(release): 5.12.0 [skip ci] ## [5.12.0](https://github.com/appium/WebDriverAgent/compare/v5.11.7...v5.12.0) (2023-10-26) ### Features * Add an endpoint for keyboard input ([#797](https://github.com/appium/WebDriverAgent/issues/797)) ([aaf70c9](https://github.com/appium/WebDriverAgent/commit/aaf70c9196e4dcb2073da151cda23b2b221d4dae)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23456c82b..77b02b2f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.12.0](https://github.com/appium/WebDriverAgent/compare/v5.11.7...v5.12.0) (2023-10-26) + + +### Features + +* Add an endpoint for keyboard input ([#797](https://github.com/appium/WebDriverAgent/issues/797)) ([aaf70c9](https://github.com/appium/WebDriverAgent/commit/aaf70c9196e4dcb2073da151cda23b2b221d4dae)) + ## [5.11.7](https://github.com/appium/WebDriverAgent/compare/v5.11.6...v5.11.7) (2023-10-25) diff --git a/package.json b/package.json index fd9ca5401..aa2b8e157 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.11.7", + "version": "5.12.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 58ebe8eb52966963ee30a5c066beb3bf9fed3161 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sat, 28 Oct 2023 15:02:37 -0700 Subject: [PATCH 206/240] fix: when 0 is given for handleKeyboardInput (#798) --- WebDriverAgentLib/Commands/FBCustomCommands.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebDriverAgentLib/Commands/FBCustomCommands.m b/WebDriverAgentLib/Commands/FBCustomCommands.m index 934cdf73f..21b67173f 100644 --- a/WebDriverAgentLib/Commands/FBCustomCommands.m +++ b/WebDriverAgentLib/Commands/FBCustomCommands.m @@ -551,7 +551,7 @@ + (NSString *)timeZone + (id)handleKeyboardInput:(FBRouteRequest *)request { FBElementCache *elementCache = request.session.elementCache; - BOOL hasElement = nil != request.parameters[@"uuid"]; + BOOL hasElement = ![request.parameters[@"uuid"] isEqual:@"0"]; XCUIElement *destination = hasElement ? [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]] : request.session.activeApplication; From deb3c05998d100c0eece079e8d8662ad23ae7c5d Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sat, 28 Oct 2023 23:00:37 +0000 Subject: [PATCH 207/240] chore(release): 5.12.1 [skip ci] ## [5.12.1](https://github.com/appium/WebDriverAgent/compare/v5.12.0...v5.12.1) (2023-10-28) ### Bug Fixes * when 0 is given for handleKeyboardInput ([#798](https://github.com/appium/WebDriverAgent/issues/798)) ([58ebe8e](https://github.com/appium/WebDriverAgent/commit/58ebe8eb52966963ee30a5c066beb3bf9fed3161)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77b02b2f4..7fd267cc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.12.1](https://github.com/appium/WebDriverAgent/compare/v5.12.0...v5.12.1) (2023-10-28) + + +### Bug Fixes + +* when 0 is given for handleKeyboardInput ([#798](https://github.com/appium/WebDriverAgent/issues/798)) ([58ebe8e](https://github.com/appium/WebDriverAgent/commit/58ebe8eb52966963ee30a5c066beb3bf9fed3161)) + ## [5.12.0](https://github.com/appium/WebDriverAgent/compare/v5.11.7...v5.12.0) (2023-10-26) diff --git a/package.json b/package.json index aa2b8e157..d95bb937e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.12.0", + "version": "5.12.1", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 247ace68f373c09054fabc3be088061089946806 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sun, 29 Oct 2023 15:25:18 -0700 Subject: [PATCH 208/240] chore: return operation error in `handleKeyboardInput` (#799) * fix: when 0 is given * chore: return explicit unsupported error * Update FBCustomCommands.m --- WebDriverAgentLib/Commands/FBCustomCommands.m | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/WebDriverAgentLib/Commands/FBCustomCommands.m b/WebDriverAgentLib/Commands/FBCustomCommands.m index 21b67173f..5b1ce72ae 100644 --- a/WebDriverAgentLib/Commands/FBCustomCommands.m +++ b/WebDriverAgentLib/Commands/FBCustomCommands.m @@ -556,6 +556,13 @@ + (NSString *)timeZone ? [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]] : request.session.activeApplication; id keys = request.arguments[@"keys"]; + + if (![destination respondsToSelector:@selector(typeKey:modifierFlags:)]) { + NSString *message = @"typeKey API is only supported since Xcode15 and iPadOS 17"; + return FBResponseWithStatus([FBCommandStatus unsupportedOperationErrorWithMessage:message + traceback:nil]); + } + if (![keys isKindOfClass:NSArray.class]) { NSString *message = @"The 'keys' argument must be an array"; return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:message From 2aa2a28631a7731d3a6951b1378c042cfcdda59f Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 29 Oct 2023 22:31:33 +0000 Subject: [PATCH 209/240] chore(release): 5.12.2 [skip ci] ## [5.12.2](https://github.com/appium/WebDriverAgent/compare/v5.12.1...v5.12.2) (2023-10-29) ### Miscellaneous Chores * return operation error in `handleKeyboardInput` ([#799](https://github.com/appium/WebDriverAgent/issues/799)) ([247ace6](https://github.com/appium/WebDriverAgent/commit/247ace68f373c09054fabc3be088061089946806)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fd267cc7..421164cf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.12.2](https://github.com/appium/WebDriverAgent/compare/v5.12.1...v5.12.2) (2023-10-29) + + +### Miscellaneous Chores + +* return operation error in `handleKeyboardInput` ([#799](https://github.com/appium/WebDriverAgent/issues/799)) ([247ace6](https://github.com/appium/WebDriverAgent/commit/247ace68f373c09054fabc3be088061089946806)) + ## [5.12.1](https://github.com/appium/WebDriverAgent/compare/v5.12.0...v5.12.1) (2023-10-28) diff --git a/package.json b/package.json index d95bb937e..571d5d356 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.12.1", + "version": "5.12.2", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 796d5e743676b174221e27e739a0164f4b91533c Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Tue, 31 Oct 2023 08:50:43 +0100 Subject: [PATCH 210/240] chore: Return better error on WDA startup timeout (#801) --- lib/xcodebuild.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/xcodebuild.js b/lib/xcodebuild.js index de6b58818..8194d1984 100644 --- a/lib/xcodebuild.js +++ b/lib/xcodebuild.js @@ -405,12 +405,13 @@ class XcodeBuild { this.log.debug(`Waiting up to ${this.launchTimeout}ms for WebDriverAgent to start`); let currentStatus = null; try { - let retries = parseInt(`${this.launchTimeout / 500}`, 10); + const retries = Math.trunc(this.launchTimeout / 500); await retryInterval(retries, 1000, async () => { if (this._didProcessExit) { // there has been an error elsewhere and we need to short-circuit - return; + return currentStatus; } + const proxyTimeout = this.noSessionProxy.timeout; this.noSessionProxy.timeout = 1000; try { @@ -434,10 +435,11 @@ class XcodeBuild { this.log.debug(`WebDriverAgent successfully started after ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`); } catch (err) { - // at this point, if we have not had any errors from xcode itself (reported - // elsewhere), we can let this go through and try to create the session - this.log.debug(err.message); - this.log.warn(`Getting status of WebDriverAgent on device timed out. Continuing`); + this.log.debug(err.stack); + throw new Error( + `We were not able to retrieve the /status response from the WebDriverAgent server after ${this.launchTimeout}ms timeout.` + + `Try to increase the value of 'appium:wdaLaunchTimeout' capability as a possible workaround.` + ); } return currentStatus; } From d92c98535f5bde04a4c89a1843aea690ded8e286 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 31 Oct 2023 07:56:58 +0000 Subject: [PATCH 211/240] chore(release): 5.12.3 [skip ci] ## [5.12.3](https://github.com/appium/WebDriverAgent/compare/v5.12.2...v5.12.3) (2023-10-31) ### Miscellaneous Chores * Return better error on WDA startup timeout ([#801](https://github.com/appium/WebDriverAgent/issues/801)) ([796d5e7](https://github.com/appium/WebDriverAgent/commit/796d5e743676b174221e27e739a0164f4b91533c)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 421164cf9..bcd3ee38f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.12.3](https://github.com/appium/WebDriverAgent/compare/v5.12.2...v5.12.3) (2023-10-31) + + +### Miscellaneous Chores + +* Return better error on WDA startup timeout ([#801](https://github.com/appium/WebDriverAgent/issues/801)) ([796d5e7](https://github.com/appium/WebDriverAgent/commit/796d5e743676b174221e27e739a0164f4b91533c)) + ## [5.12.2](https://github.com/appium/WebDriverAgent/compare/v5.12.1...v5.12.2) (2023-10-29) diff --git a/package.json b/package.json index 571d5d356..7696d13c9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.12.2", + "version": "5.12.3", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 9925af44ec5fbfb66e6f034dfd93a6c25de48661 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Tue, 31 Oct 2023 20:24:12 +0100 Subject: [PATCH 212/240] feat: Add "elementDescription" property to audit issues containing the debug description of an element (#802) --- WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m | 1 + 1 file changed, 1 insertion(+) diff --git a/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m b/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m index 7c9ff9967..4faaed1ae 100644 --- a/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +++ b/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m @@ -374,6 +374,7 @@ - (BOOL)fb_dismissKeyboardWithKeyNames:(nullable NSArray *)keyNames @"compactDescription": extractIssueProperty(issue, @"compactDescription") ?: @"", @"auditType": auditType, @"element": [extractIssueProperty(issue, @"element") description] ?: @"", + @"elementDescription": [extractIssueProperty(issue, @"element") debugDescription] ?: @"", }]; return YES; }; From d3d9107139bb9d7a6149b224b75edc184a8180a6 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 31 Oct 2023 19:32:28 +0000 Subject: [PATCH 213/240] chore(release): 5.13.0 [skip ci] ## [5.13.0](https://github.com/appium/WebDriverAgent/compare/v5.12.3...v5.13.0) (2023-10-31) ### Features * Add "elementDescription" property to audit issues containing the debug description of an element ([#802](https://github.com/appium/WebDriverAgent/issues/802)) ([9925af4](https://github.com/appium/WebDriverAgent/commit/9925af44ec5fbfb66e6f034dfd93a6c25de48661)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bcd3ee38f..ed392b5b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.13.0](https://github.com/appium/WebDriverAgent/compare/v5.12.3...v5.13.0) (2023-10-31) + + +### Features + +* Add "elementDescription" property to audit issues containing the debug description of an element ([#802](https://github.com/appium/WebDriverAgent/issues/802)) ([9925af4](https://github.com/appium/WebDriverAgent/commit/9925af44ec5fbfb66e6f034dfd93a6c25de48661)) + ## [5.12.3](https://github.com/appium/WebDriverAgent/compare/v5.12.2...v5.12.3) (2023-10-31) diff --git a/package.json b/package.json index 7696d13c9..bec7dbf83 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.12.3", + "version": "5.13.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 0f2305d2559dc0807d7df0d0e06f7fc3c549701c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 17:41:52 +0100 Subject: [PATCH 214/240] chore(deps): bump asyncbox from 2.9.4 to 3.0.0 (#803) Bumps [asyncbox](https://github.com/jlipps/asyncbox) from 2.9.4 to 3.0.0. - [Commits](https://github.com/jlipps/asyncbox/commits/v3.0.0) --- updated-dependencies: - dependency-name: asyncbox dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bec7dbf83..50ec457f1 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "appium-ios-device": "^2.5.0", "appium-ios-simulator": "^5.0.1", "async-lock": "^1.0.0", - "asyncbox": "^2.5.3", + "asyncbox": "^3.0.0", "axios": "^1.4.0", "bluebird": "^3.5.5", "lodash": "^4.17.11", From 29fd2e2b7060182e9aa21a40da335d76fcfe0546 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 1 Nov 2023 16:53:48 +0000 Subject: [PATCH 215/240] chore(release): 5.13.1 [skip ci] ## [5.13.1](https://github.com/appium/WebDriverAgent/compare/v5.13.0...v5.13.1) (2023-11-01) ### Miscellaneous Chores * **deps:** bump asyncbox from 2.9.4 to 3.0.0 ([#803](https://github.com/appium/WebDriverAgent/issues/803)) ([0f2305d](https://github.com/appium/WebDriverAgent/commit/0f2305d2559dc0807d7df0d0e06f7fc3c549701c)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed392b5b4..c503cf2dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.13.1](https://github.com/appium/WebDriverAgent/compare/v5.13.0...v5.13.1) (2023-11-01) + + +### Miscellaneous Chores + +* **deps:** bump asyncbox from 2.9.4 to 3.0.0 ([#803](https://github.com/appium/WebDriverAgent/issues/803)) ([0f2305d](https://github.com/appium/WebDriverAgent/commit/0f2305d2559dc0807d7df0d0e06f7fc3c549701c)) + ## [5.13.0](https://github.com/appium/WebDriverAgent/compare/v5.12.3...v5.13.0) (2023-10-31) diff --git a/package.json b/package.json index 50ec457f1..349f6a3cb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.13.0", + "version": "5.13.1", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 824f74c69769973858350bd5db0061510c546b09 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 17:50:18 +0100 Subject: [PATCH 216/240] chore(deps-dev): bump @types/sinon from 10.0.20 to 17.0.0 (#805) Bumps [@types/sinon](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/sinon) from 10.0.20 to 17.0.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/sinon) --- updated-dependencies: - dependency-name: "@types/sinon" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 349f6a3cb..4097a0993 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "@types/lodash": "^4.14.196", "@types/mocha": "^10.0.1", "@types/node": "^20.4.7", - "@types/sinon": "^10.0.16", + "@types/sinon": "^17.0.0", "@types/sinon-chai": "^3.2.9", "@types/teen_process": "^2.0.1", "@typescript-eslint/eslint-plugin": "^6.9.0", From c6c5df1851b30285696a0ac3fd1945955d1cf0eb Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 6 Nov 2023 17:14:37 +0000 Subject: [PATCH 217/240] chore(release): 5.13.2 [skip ci] ## [5.13.2](https://github.com/appium/WebDriverAgent/compare/v5.13.1...v5.13.2) (2023-11-06) ### Miscellaneous Chores * **deps-dev:** bump @types/sinon from 10.0.20 to 17.0.0 ([#805](https://github.com/appium/WebDriverAgent/issues/805)) ([824f74c](https://github.com/appium/WebDriverAgent/commit/824f74c69769973858350bd5db0061510c546b09)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c503cf2dd..c862368a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.13.2](https://github.com/appium/WebDriverAgent/compare/v5.13.1...v5.13.2) (2023-11-06) + + +### Miscellaneous Chores + +* **deps-dev:** bump @types/sinon from 10.0.20 to 17.0.0 ([#805](https://github.com/appium/WebDriverAgent/issues/805)) ([824f74c](https://github.com/appium/WebDriverAgent/commit/824f74c69769973858350bd5db0061510c546b09)) + ## [5.13.1](https://github.com/appium/WebDriverAgent/compare/v5.13.0...v5.13.1) (2023-11-01) diff --git a/package.json b/package.json index 4097a0993..762e03f5e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.13.1", + "version": "5.13.2", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 79832bc6c69e289091fbbb97aee6a1f1d17ca4c3 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Thu, 9 Nov 2023 23:05:55 -0800 Subject: [PATCH 218/240] fix: unrecognized selector sent to instance 0x2829adb20 error in clear (#809) --- WebDriverAgentLib/Categories/XCUIElement+FBTyping.m | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBTyping.m b/WebDriverAgentLib/Categories/XCUIElement+FBTyping.m index a538be380..54b0d5362 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBTyping.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBTyping.m @@ -143,7 +143,12 @@ - (BOOL)fb_clearTextWithSnapshot:(FBXCElementSnapshotWrapper *)snapshot do { if (retry >= MAX_CLEAR_RETRIES - 1) { // Last chance retry. Tripple-tap the field to select its content - [self tapWithNumberOfTaps:3 numberOfTouches:1]; + + if ([self respondsToSelector:@selector(tapWithNumberOfTaps:numberOfTouches:)]) { + // e.g. tvOS 17 raised unrecognized selector error for XCUIElementTypeSearchField + // while following typeText worked. + [self tapWithNumberOfTaps:3 numberOfTouches:1]; + } return [FBKeyboard typeText:backspaceDeleteSequence error:error]; } From 518858a8eee914e35c3d4e3c3783611bdedc4577 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 10 Nov 2023 07:11:28 +0000 Subject: [PATCH 219/240] chore(release): 5.13.3 [skip ci] ## [5.13.3](https://github.com/appium/WebDriverAgent/compare/v5.13.2...v5.13.3) (2023-11-10) ### Bug Fixes * unrecognized selector sent to instance 0x2829adb20 error in clear ([#809](https://github.com/appium/WebDriverAgent/issues/809)) ([79832bc](https://github.com/appium/WebDriverAgent/commit/79832bc6c69e289091fbbb97aee6a1f1d17ca4c3)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c862368a2..e93f006e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.13.3](https://github.com/appium/WebDriverAgent/compare/v5.13.2...v5.13.3) (2023-11-10) + + +### Bug Fixes + +* unrecognized selector sent to instance 0x2829adb20 error in clear ([#809](https://github.com/appium/WebDriverAgent/issues/809)) ([79832bc](https://github.com/appium/WebDriverAgent/commit/79832bc6c69e289091fbbb97aee6a1f1d17ca4c3)) + ## [5.13.2](https://github.com/appium/WebDriverAgent/compare/v5.13.1...v5.13.2) (2023-11-06) diff --git a/package.json b/package.json index 762e03f5e..e59934abe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.13.2", + "version": "5.13.3", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From dd093ea0b7209c3d2f3d0b1fa7f3a7b58507dd2d Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Fri, 10 Nov 2023 14:50:59 -0800 Subject: [PATCH 220/240] feat: use khidusage_keyboardclear to `clear` for iOS/iPad as the 1st attempt, tune tvOS (#811) * feat: Add khidusage_keyboardclear as possible option for text field clear on iOS * feat: tune clear text * revert * revert another place * tune for tvOS * leave testing note * remove unnecessary MAX_CLEAR_RETRIES * Update XCUIElement+FBTyping.m * Update XCUIElement+FBTyping.m --------- Co-authored-by: Mykola Mokhnach --- .../Categories/XCUIElement+FBTyping.m | 45 ++++++++++++------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/WebDriverAgentLib/Categories/XCUIElement+FBTyping.m b/WebDriverAgentLib/Categories/XCUIElement+FBTyping.m index 54b0d5362..c6e31f4fc 100644 --- a/WebDriverAgentLib/Categories/XCUIElement+FBTyping.m +++ b/WebDriverAgentLib/Categories/XCUIElement+FBTyping.m @@ -15,11 +15,12 @@ #import "NSString+FBVisualLength.h" #import "FBXCElementSnapshotWrapper.h" #import "FBXCElementSnapshotWrapper+Helpers.h" +#import "XCUIDevice+FBHelpers.h" #import "XCUIElement+FBCaching.h" #import "XCUIElement+FBUtilities.h" #import "FBXCodeCompatibility.h" -#define MAX_CLEAR_RETRIES 2 +#define MAX_CLEAR_RETRIES 3 @interface NSString (FBRepeat) @@ -136,27 +137,32 @@ - (BOOL)fb_clearTextWithSnapshot:(FBXCElementSnapshotWrapper *)snapshot backspaceDeleteSequence = [[NSString alloc] initWithData:(NSData *)[@"\\u0008\\u007F" dataUsingEncoding:NSASCIIStringEncoding] encoding:NSNonLossyASCIIStringEncoding]; }); - + + NSUInteger preClearTextLength = [currentValue fb_visualLength]; + NSString *backspacesToType = [backspaceDeleteSequence fb_repeatTimes:preClearTextLength]; + +#if TARGET_OS_IOS NSUInteger retry = 0; NSString *placeholderValue = snapshot.placeholderValue; - NSUInteger preClearTextLength = [currentValue fb_visualLength]; do { - if (retry >= MAX_CLEAR_RETRIES - 1) { - // Last chance retry. Tripple-tap the field to select its content - - if ([self respondsToSelector:@selector(tapWithNumberOfTaps:numberOfTouches:)]) { - // e.g. tvOS 17 raised unrecognized selector error for XCUIElementTypeSearchField - // while following typeText worked. - [self tapWithNumberOfTaps:3 numberOfTouches:1]; - } - return [FBKeyboard typeText:backspaceDeleteSequence error:error]; - } - - NSString *textToType = [backspaceDeleteSequence fb_repeatTimes:preClearTextLength]; + // the ios needs to have keyboard focus to clear text if (shouldPrepareForInput && 0 == retry) { [self fb_prepareForTextInputWithSnapshot:snapshot]; } - if (![FBKeyboard typeText:textToType error:error]) { + + if (retry == 0) { + // 1st attempt is via the IOHIDEvent as the fastest operation + // https://github.com/appium/appium/issues/19389 + [[XCUIDevice sharedDevice] fb_performIOHIDEventWithPage:0x07 // kHIDPage_KeyboardOrKeypad + usage:0x9c // kHIDUsage_KeyboardClear + duration:0.01 + error:nil]; + } else if (retry >= MAX_CLEAR_RETRIES - 1) { + // Last chance retry. Tripple-tap the field to select its content + [self tapWithNumberOfTaps:3 numberOfTouches:1]; + return [FBKeyboard typeText:backspaceDeleteSequence error:error]; + } else if (![FBKeyboard typeText:backspacesToType error:error]) { + // 2nd operation return NO; } @@ -170,6 +176,13 @@ - (BOOL)fb_clearTextWithSnapshot:(FBXCElementSnapshotWrapper *)snapshot retry++; } while (preClearTextLength > 0); return YES; +#else + // tvOS does not need a focus. + // kHIDPage_KeyboardOrKeypad did not work for tvOS's search field. (tvOS 17 at least) + // Tested XCUIElementTypeSearchField and XCUIElementTypeTextView whch were + // common search field and email/passowrd input in tvOS apps. + return [FBKeyboard typeText:backspacesToType error:error]; +#endif } @end From b67222eac62a828a4b42fce80819281035830e7c Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 10 Nov 2023 22:58:13 +0000 Subject: [PATCH 221/240] chore(release): 5.14.0 [skip ci] ## [5.14.0](https://github.com/appium/WebDriverAgent/compare/v5.13.3...v5.14.0) (2023-11-10) ### Features * use khidusage_keyboardclear to `clear` for iOS/iPad as the 1st attempt, tune tvOS ([#811](https://github.com/appium/WebDriverAgent/issues/811)) ([dd093ea](https://github.com/appium/WebDriverAgent/commit/dd093ea0b7209c3d2f3d0b1fa7f3a7b58507dd2d)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e93f006e4..69b8f87f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.14.0](https://github.com/appium/WebDriverAgent/compare/v5.13.3...v5.14.0) (2023-11-10) + + +### Features + +* use khidusage_keyboardclear to `clear` for iOS/iPad as the 1st attempt, tune tvOS ([#811](https://github.com/appium/WebDriverAgent/issues/811)) ([dd093ea](https://github.com/appium/WebDriverAgent/commit/dd093ea0b7209c3d2f3d0b1fa7f3a7b58507dd2d)) + ## [5.13.3](https://github.com/appium/WebDriverAgent/compare/v5.13.2...v5.13.3) (2023-11-10) diff --git a/package.json b/package.json index e59934abe..77f598f2f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.13.3", + "version": "5.14.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 0d7e4a697adb7355279583eaa05118f396056e6f Mon Sep 17 00:00:00 2001 From: Ilya Kharebashvili Date: Thu, 16 Nov 2023 12:26:43 +0200 Subject: [PATCH 222/240] feat: Add element attributes to the performAccessibilityAudit output (#808) --- .../Categories/XCUIApplication+FBHelpers.m | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m b/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m index 4faaed1ae..2656de7d6 100644 --- a/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +++ b/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m @@ -369,12 +369,19 @@ - (BOOL)fb_dismissKeyboardWithKeyNames:(nullable NSArray *)keyNames if (nil != auditTypeValue) { auditType = valuesToNamesMap[auditTypeValue] ?: [auditTypeValue stringValue]; } + + id extractedElement = extractIssueProperty(issue, @"element"); + + id elementSnapshot = [extractedElement fb_takeSnapshot]; + NSDictionary *elementAttributes = elementSnapshot ? [self.class dictionaryForElement:elementSnapshot recursive:NO] : @{}; + [resultArray addObject:@{ @"detailedDescription": extractIssueProperty(issue, @"detailedDescription") ?: @"", @"compactDescription": extractIssueProperty(issue, @"compactDescription") ?: @"", @"auditType": auditType, - @"element": [extractIssueProperty(issue, @"element") description] ?: @"", - @"elementDescription": [extractIssueProperty(issue, @"element") debugDescription] ?: @"", + @"element": [extractedElement description] ?: @"", + @"elementDescription": [extractedElement debugDescription] ?: @"", + @"elementAttributes": elementAttributes ?: @{}, }]; return YES; }; From 1e1905c5bf94cdd4dc4a2a917ac0a3bf9890a7c7 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 16 Nov 2023 10:32:25 +0000 Subject: [PATCH 223/240] chore(release): 5.15.0 [skip ci] ## [5.15.0](https://github.com/appium/WebDriverAgent/compare/v5.14.0...v5.15.0) (2023-11-16) ### Features * Add element attributes to the performAccessibilityAudit output ([#808](https://github.com/appium/WebDriverAgent/issues/808)) ([0d7e4a6](https://github.com/appium/WebDriverAgent/commit/0d7e4a697adb7355279583eaa05118f396056e6f)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69b8f87f7..539251658 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.15.0](https://github.com/appium/WebDriverAgent/compare/v5.14.0...v5.15.0) (2023-11-16) + + +### Features + +* Add element attributes to the performAccessibilityAudit output ([#808](https://github.com/appium/WebDriverAgent/issues/808)) ([0d7e4a6](https://github.com/appium/WebDriverAgent/commit/0d7e4a697adb7355279583eaa05118f396056e6f)) + ## [5.14.0](https://github.com/appium/WebDriverAgent/compare/v5.13.3...v5.14.0) (2023-11-10) diff --git a/package.json b/package.json index 77f598f2f..d5568caef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.14.0", + "version": "5.15.0", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 0b41757c0d21004afab32860b4e510d4bc426018 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 16 Nov 2023 15:59:31 +0100 Subject: [PATCH 224/240] refactor: Optimize screenshots preprocessing (#812) --- WebDriverAgent.xcodeproj/project.pbxproj | 40 ++-- .../Commands/FBSessionCommands.m | 4 + WebDriverAgentLib/Utilities/FBConfiguration.h | 17 +- WebDriverAgentLib/Utilities/FBConfiguration.m | 10 + WebDriverAgentLib/Utilities/FBImageIOScaler.m | 195 ------------------ .../{FBImageIOScaler.h => FBImageProcessor.h} | 25 +-- .../Utilities/FBImageProcessor.m | 171 +++++++++++++++ WebDriverAgentLib/Utilities/FBImageUtils.h | 6 + WebDriverAgentLib/Utilities/FBImageUtils.m | 34 +++ WebDriverAgentLib/Utilities/FBMjpegServer.m | 33 ++- WebDriverAgentLib/Utilities/FBScreenshot.h | 13 -- WebDriverAgentLib/Utilities/FBScreenshot.m | 16 +- WebDriverAgentLib/Utilities/FBSettings.h | 1 + WebDriverAgentLib/Utilities/FBSettings.m | 1 + ...OScalerTests.m => FBImageProcessorTests.m} | 44 ++-- .../IntegrationTests/XCUIDeviceHelperTests.m | 12 +- 16 files changed, 313 insertions(+), 309 deletions(-) delete mode 100644 WebDriverAgentLib/Utilities/FBImageIOScaler.m rename WebDriverAgentLib/Utilities/{FBImageIOScaler.h => FBImageProcessor.h} (64%) create mode 100644 WebDriverAgentLib/Utilities/FBImageProcessor.m rename WebDriverAgentTests/IntegrationTests/{FBImageIOScalerTests.m => FBImageProcessorTests.m} (59%) diff --git a/WebDriverAgent.xcodeproj/project.pbxproj b/WebDriverAgent.xcodeproj/project.pbxproj index 3630797a6..836267cce 100644 --- a/WebDriverAgent.xcodeproj/project.pbxproj +++ b/WebDriverAgent.xcodeproj/project.pbxproj @@ -38,11 +38,11 @@ 315A15072518CC2800A3A064 /* TouchSpotView.m in Sources */ = {isa = PBXBuildFile; fileRef = 315A15062518CC2800A3A064 /* TouchSpotView.m */; }; 315A150A2518D6F400A3A064 /* TouchViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 315A15092518D6F400A3A064 /* TouchViewController.m */; }; 6385F4A7220A40760095BBDB /* XCUIApplicationProcessDelay.m in Sources */ = {isa = PBXBuildFile; fileRef = 6385F4A5220A40760095BBDB /* XCUIApplicationProcessDelay.m */; }; - 63CCF91221ECE4C700E94ABD /* FBImageIOScaler.h in Headers */ = {isa = PBXBuildFile; fileRef = 63CCF91021ECE4C700E94ABD /* FBImageIOScaler.h */; }; - 63CCF91321ECE4C700E94ABD /* FBImageIOScaler.m in Sources */ = {isa = PBXBuildFile; fileRef = 63CCF91121ECE4C700E94ABD /* FBImageIOScaler.m */; }; - 63FD950221F9D06100A3E356 /* FBImageIOScalerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 631B523421F6174300625362 /* FBImageIOScalerTests.m */; }; - 63FD950321F9D06100A3E356 /* FBImageIOScalerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 631B523421F6174300625362 /* FBImageIOScalerTests.m */; }; - 63FD950421F9D06200A3E356 /* FBImageIOScalerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 631B523421F6174300625362 /* FBImageIOScalerTests.m */; }; + 63CCF91221ECE4C700E94ABD /* FBImageProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 63CCF91021ECE4C700E94ABD /* FBImageProcessor.h */; }; + 63CCF91321ECE4C700E94ABD /* FBImageProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = 63CCF91121ECE4C700E94ABD /* FBImageProcessor.m */; }; + 63FD950221F9D06100A3E356 /* FBImageProcessorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 631B523421F6174300625362 /* FBImageProcessorTests.m */; }; + 63FD950321F9D06100A3E356 /* FBImageProcessorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 631B523421F6174300625362 /* FBImageProcessorTests.m */; }; + 63FD950421F9D06200A3E356 /* FBImageProcessorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 631B523421F6174300625362 /* FBImageProcessorTests.m */; }; 641EE3452240C1C800173FCB /* UITestingUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9AB7FD1CAEE048008C271F /* UITestingUITests.m */; }; 641EE5D72240C5CA00173FCB /* FBScreenshotCommands.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9AB75F1CAEDF0C008C271F /* FBScreenshotCommands.m */; }; 641EE5D92240C5CA00173FCB /* XCUIElement+FBPickerWheel.m in Sources */ = {isa = PBXBuildFile; fileRef = 7136A4781E8918E60024FC3D /* XCUIElement+FBPickerWheel.m */; }; @@ -80,7 +80,7 @@ 641EE5FE2240C5CA00173FCB /* XCUIElement+FBWebDriverAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = EEE376481D59FAE900ED88DD /* XCUIElement+FBWebDriverAttributes.m */; }; 641EE5FF2240C5CA00173FCB /* XCUIElement+FBForceTouch.m in Sources */ = {isa = PBXBuildFile; fileRef = EE8DDD7C20C5733B004D4925 /* XCUIElement+FBForceTouch.m */; }; 641EE6002240C5CA00173FCB /* FBTouchActionCommands.m in Sources */ = {isa = PBXBuildFile; fileRef = 71241D7A1FAE3D2500B9559F /* FBTouchActionCommands.m */; }; - 641EE6012240C5CA00173FCB /* FBImageIOScaler.m in Sources */ = {isa = PBXBuildFile; fileRef = 63CCF91121ECE4C700E94ABD /* FBImageIOScaler.m */; }; + 641EE6012240C5CA00173FCB /* FBImageProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = 63CCF91121ECE4C700E94ABD /* FBImageProcessor.m */; }; 641EE6022240C5CA00173FCB /* FBTouchIDCommands.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9AB7631CAEDF0C008C271F /* FBTouchIDCommands.m */; }; 641EE6032240C5CA00173FCB /* FBDebugCommands.m in Sources */ = {isa = PBXBuildFile; fileRef = EE9AB7551CAEDF0C008C271F /* FBDebugCommands.m */; }; 641EE6042240C5CA00173FCB /* NSString+FBXMLSafeString.m in Sources */ = {isa = PBXBuildFile; fileRef = 716E0BCD1E917E810087A825 /* NSString+FBXMLSafeString.m */; }; @@ -222,7 +222,7 @@ 641EE6A32240C5CA00173FCB /* XCUIApplication+FBTouchAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 71BD20711F86116100B36EC2 /* XCUIApplication+FBTouchAction.h */; }; 641EE6A42240C5CA00173FCB /* FBCommandHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9AB7751CAEDF0C008C271F /* FBCommandHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; 641EE6A52240C5CA00173FCB /* FBSessionCommands.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9AB7601CAEDF0C008C271F /* FBSessionCommands.h */; }; - 641EE6A62240C5CA00173FCB /* FBImageIOScaler.h in Headers */ = {isa = PBXBuildFile; fileRef = 63CCF91021ECE4C700E94ABD /* FBImageIOScaler.h */; }; + 641EE6A62240C5CA00173FCB /* FBImageProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 63CCF91021ECE4C700E94ABD /* FBImageProcessor.h */; }; 641EE6A72240C5CA00173FCB /* FBSession-Private.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9AB7891CAEDF0C008C271F /* FBSession-Private.h */; }; 641EE6A82240C5CA00173FCB /* NSString+FBXMLSafeString.h in Headers */ = {isa = PBXBuildFile; fileRef = 716E0BCC1E917E810087A825 /* NSString+FBXMLSafeString.h */; }; 641EE6A92240C5CA00173FCB /* FBCommandStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = EE9AB7761CAEDF0C008C271F /* FBCommandStatus.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -918,11 +918,11 @@ 315A15082518D6F400A3A064 /* TouchViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TouchViewController.h; sourceTree = ""; }; 315A15092518D6F400A3A064 /* TouchViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TouchViewController.m; sourceTree = ""; }; 44757A831D42CE8300ECF35E /* XCUIDeviceRotationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XCUIDeviceRotationTests.m; sourceTree = ""; }; - 631B523421F6174300625362 /* FBImageIOScalerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBImageIOScalerTests.m; sourceTree = ""; }; + 631B523421F6174300625362 /* FBImageProcessorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBImageProcessorTests.m; sourceTree = ""; }; 633E904A220DEE7F007CADF9 /* XCUIApplicationProcessDelay.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XCUIApplicationProcessDelay.h; sourceTree = ""; }; 6385F4A5220A40760095BBDB /* XCUIApplicationProcessDelay.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XCUIApplicationProcessDelay.m; sourceTree = ""; }; - 63CCF91021ECE4C700E94ABD /* FBImageIOScaler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBImageIOScaler.h; sourceTree = ""; }; - 63CCF91121ECE4C700E94ABD /* FBImageIOScaler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBImageIOScaler.m; sourceTree = ""; }; + 63CCF91021ECE4C700E94ABD /* FBImageProcessor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBImageProcessor.h; sourceTree = ""; }; + 63CCF91121ECE4C700E94ABD /* FBImageProcessor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBImageProcessor.m; sourceTree = ""; }; 641EE2DA2240BBE300173FCB /* WebDriverAgentRunner_tvOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WebDriverAgentRunner_tvOS.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 641EE6F82240C5CA00173FCB /* WebDriverAgentLib_tvOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = WebDriverAgentLib_tvOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 641EE7042240CDCF00173FCB /* XCUIElement+FBTVFocuse.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "XCUIElement+FBTVFocuse.h"; sourceTree = ""; }; @@ -1890,8 +1890,8 @@ EE3A18611CDE618F00DE4205 /* FBErrorBuilder.m */, EE6A89381D0B38640083E92B /* FBFailureProofTestCase.h */, EE6A89391D0B38640083E92B /* FBFailureProofTestCase.m */, - 63CCF91021ECE4C700E94ABD /* FBImageIOScaler.h */, - 63CCF91121ECE4C700E94ABD /* FBImageIOScaler.m */, + 63CCF91021ECE4C700E94ABD /* FBImageProcessor.h */, + 63CCF91121ECE4C700E94ABD /* FBImageProcessor.m */, 7150348521A6DAD600A0F4BA /* FBImageUtils.h */, 7150348621A6DAD600A0F4BA /* FBImageUtils.m */, EE9B76A31CF7A43900275851 /* FBLogger.h */, @@ -2004,7 +2004,7 @@ 71E504941DF59BAD0020C32A /* XCUIElementAttributesTests.m */, EEBBD48D1D4785FC00656A81 /* XCUIElementFBFindTests.m */, EE1E06E11D181CC9007CF043 /* XCUIElementHelperIntegrationTests.m */, - 631B523421F6174300625362 /* FBImageIOScalerTests.m */, + 631B523421F6174300625362 /* FBImageProcessorTests.m */, 644D9CCD230E1F1A00C90459 /* FBConfigurationTests.m */, ); path = IntegrationTests; @@ -2381,7 +2381,7 @@ 641EE6A42240C5CA00173FCB /* FBCommandHandler.h in Headers */, 641EE6A52240C5CA00173FCB /* FBSessionCommands.h in Headers */, 641EE70C2240CE2D00173FCB /* FBTVNavigationTracker.h in Headers */, - 641EE6A62240C5CA00173FCB /* FBImageIOScaler.h in Headers */, + 641EE6A62240C5CA00173FCB /* FBImageProcessor.h in Headers */, 641EE6A72240C5CA00173FCB /* FBSession-Private.h in Headers */, 641EE6A82240C5CA00173FCB /* NSString+FBXMLSafeString.h in Headers */, 64E3502F2AC0B6FE005F3ACB /* NSDictionary+FBUtf8SafeDictionary.h in Headers */, @@ -2622,7 +2622,7 @@ EE158AC81CBD456F00A3E3F0 /* FBSessionCommands.h in Headers */, 71C8E55125399A6B008572C1 /* XCUIApplication+FBQuiescence.h in Headers */, 641EE70B2240CE2D00173FCB /* FBTVNavigationTracker.h in Headers */, - 63CCF91221ECE4C700E94ABD /* FBImageIOScaler.h in Headers */, + 63CCF91221ECE4C700E94ABD /* FBImageProcessor.h in Headers */, EE158AE31CBD456F00A3E3F0 /* FBSession-Private.h in Headers */, 716E0BCE1E917E810087A825 /* NSString+FBXMLSafeString.h in Headers */, EE158ACF1CBD456F00A3E3F0 /* FBCommandStatus.h in Headers */, @@ -3122,7 +3122,7 @@ 641EE6002240C5CA00173FCB /* FBTouchActionCommands.m in Sources */, 719DCF182601EAFB000E765F /* FBNotificationsHelper.m in Sources */, 714EAA102673FDFE005C5B47 /* FBCapabilities.m in Sources */, - 641EE6012240C5CA00173FCB /* FBImageIOScaler.m in Sources */, + 641EE6012240C5CA00173FCB /* FBImageProcessor.m in Sources */, 641EE6022240C5CA00173FCB /* FBTouchIDCommands.m in Sources */, 641EE6032240C5CA00173FCB /* FBDebugCommands.m in Sources */, 641EE6042240C5CA00173FCB /* NSString+FBXMLSafeString.m in Sources */, @@ -3236,7 +3236,7 @@ EEE3764A1D59FAE900ED88DD /* XCUIElement+FBWebDriverAttributes.m in Sources */, EE8DDD7E20C5733C004D4925 /* XCUIElement+FBForceTouch.m in Sources */, 71241D7C1FAE3D2500B9559F /* FBTouchActionCommands.m in Sources */, - 63CCF91321ECE4C700E94ABD /* FBImageIOScaler.m in Sources */, + 63CCF91321ECE4C700E94ABD /* FBImageProcessor.m in Sources */, EE158ACB1CBD456F00A3E3F0 /* FBTouchIDCommands.m in Sources */, 71F5BE51252F14EB00EE9EBA /* FBExceptions.m in Sources */, EE158ABD1CBD456F00A3E3F0 /* FBDebugCommands.m in Sources */, @@ -3307,7 +3307,7 @@ files = ( 71241D801FAF087500B9559F /* FBW3CMultiTouchActionsIntegrationTests.m in Sources */, 71241D7E1FAF084E00B9559F /* FBW3CTouchActionsIntegrationTests.m in Sources */, - 63FD950221F9D06100A3E356 /* FBImageIOScalerTests.m in Sources */, + 63FD950221F9D06100A3E356 /* FBImageProcessorTests.m in Sources */, 719CD8FF2126C90200C7D0C2 /* FBAutoAlertsHandlerTests.m in Sources */, EE2202131ECC612200A29571 /* FBIntegrationTestCase.m in Sources */, 71BD20781F869E0F00B36EC2 /* FBAppiumTouchActionsIntegrationTests.m in Sources */, @@ -3324,7 +3324,7 @@ buildActionMask = 2147483647; files = ( EE5095E51EBCC9090028E2FE /* FBTypingTest.m in Sources */, - 63FD950321F9D06100A3E356 /* FBImageIOScalerTests.m in Sources */, + 63FD950321F9D06100A3E356 /* FBImageProcessorTests.m in Sources */, EE5095EB1EBCC9090028E2FE /* XCElementSnapshotHitPointTests.m in Sources */, EE5095EC1EBCC9090028E2FE /* XCUIApplicationHelperTests.m in Sources */, 7136C0F9243A182400921C76 /* FBW3CTypeActionsTests.m in Sources */, @@ -3397,7 +3397,7 @@ 7119E1EC1E891F8600D0B125 /* FBPickerWheelSelectTests.m in Sources */, 71ACF5B8242F2FDC00F0AAD4 /* FBSafariAlertTests.m in Sources */, EE1E06DA1D1808C2007CF043 /* FBIntegrationTestCase.m in Sources */, - 63FD950421F9D06200A3E356 /* FBImageIOScalerTests.m in Sources */, + 63FD950421F9D06200A3E356 /* FBImageProcessorTests.m in Sources */, EE05BAFA1D13003C00A3EB00 /* FBKeyboardTests.m in Sources */, EE55B3271D1D54CF003AAAEC /* FBScrollingTests.m in Sources */, EE6A89371D0B35920083E92B /* FBFailureProofTestCaseTests.m in Sources */, diff --git a/WebDriverAgentLib/Commands/FBSessionCommands.m b/WebDriverAgentLib/Commands/FBSessionCommands.m index 7bd87a768..4a7ae1a8d 100644 --- a/WebDriverAgentLib/Commands/FBSessionCommands.m +++ b/WebDriverAgentLib/Commands/FBSessionCommands.m @@ -280,6 +280,7 @@ + (NSArray *)routes FB_SETTING_MJPEG_SERVER_SCREENSHOT_QUALITY: @([FBConfiguration mjpegServerScreenshotQuality]), FB_SETTING_MJPEG_SERVER_FRAMERATE: @([FBConfiguration mjpegServerFramerate]), FB_SETTING_MJPEG_SCALING_FACTOR: @([FBConfiguration mjpegScalingFactor]), + FB_SETTING_MJPEG_FIX_ORIENTATION: @([FBConfiguration mjpegShouldFixOrientation]), FB_SETTING_SCREENSHOT_QUALITY: @([FBConfiguration screenshotQuality]), FB_SETTING_KEYBOARD_AUTOCORRECTION: @([FBConfiguration keyboardAutocorrection]), FB_SETTING_KEYBOARD_PREDICTION: @([FBConfiguration keyboardPrediction]), @@ -327,6 +328,9 @@ + (NSArray *)routes if (nil != [settings objectForKey:FB_SETTING_MJPEG_SCALING_FACTOR]) { [FBConfiguration setMjpegScalingFactor:[[settings objectForKey:FB_SETTING_MJPEG_SCALING_FACTOR] unsignedIntegerValue]]; } + if (nil != [settings objectForKey:FB_SETTING_MJPEG_FIX_ORIENTATION]) { + [FBConfiguration setMjpegShouldFixOrientation:[[settings objectForKey:FB_SETTING_MJPEG_FIX_ORIENTATION] boolValue]]; + } if (nil != [settings objectForKey:FB_SETTING_KEYBOARD_AUTOCORRECTION]) { [FBConfiguration setKeyboardAutocorrection:[[settings objectForKey:FB_SETTING_KEYBOARD_AUTOCORRECTION] boolValue]]; } diff --git a/WebDriverAgentLib/Utilities/FBConfiguration.h b/WebDriverAgentLib/Utilities/FBConfiguration.h index 8bb9d48ca..dd0015e56 100644 --- a/WebDriverAgentLib/Utilities/FBConfiguration.h +++ b/WebDriverAgentLib/Utilities/FBConfiguration.h @@ -84,6 +84,16 @@ extern NSString *const FBSnapshotMaxDepthKey; + (NSUInteger)mjpegServerScreenshotQuality; + (void)setMjpegServerScreenshotQuality:(NSUInteger)quality; +/** + Whether to apply orientation fixes to the streamed JPEG images. + This is an expensive operation and it is disabled by default, so screenshots + are returned in portrait, but their actual orientation value could still be found in the EXIF + metadata. + ! Enablement of this setting may lead to WDA process termination because of an excessive CPU usage. + */ ++ (BOOL)mjpegShouldFixOrientation; ++ (void)setMjpegShouldFixOrientation:(BOOL)enabled; + /** The framerate at which the background screenshots broadcaster should broadcast screenshots in range 1..60. The default value is 10 (Frames Per Second). @@ -93,7 +103,7 @@ extern NSString *const FBSnapshotMaxDepthKey; + (void)setMjpegServerFramerate:(NSUInteger)framerate; /** - The quality of display screenshots. The higher quality you set is the bigger screenshot size is. + The quality of display screenshots. The higher quality you set is the bigger screenshot size is. The highest quality value is 0 (lossless PNG) or 3 (lossless HEIC). The lowest quality is 2 (highly compressed JPEG). The default quality value is 3 (lossless HEIC). See https://developer.apple.com/documentation/xctest/xctimagequality?language=objc @@ -112,7 +122,10 @@ extern NSString *const FBSnapshotMaxDepthKey; + (NSInteger)mjpegServerPort; /** - The scaling factor for frames of the mjpeg stream (Default values is 100 and does not perform scaling). + The scaling factor for frames of the mjpeg stream. The default (and maximum) value is 100, + which does not perform any scaling. The minimum value must be greater than zero. + ! Setting this to a value less than 100, especially together with orientation fixing enabled + ! may lead to WDA process termination because of an excessive CPU usage. */ + (NSUInteger)mjpegScalingFactor; + (void)setMjpegScalingFactor:(NSUInteger)scalingFactor; diff --git a/WebDriverAgentLib/Utilities/FBConfiguration.m b/WebDriverAgentLib/Utilities/FBConfiguration.m index f149d2193..03b6a6b1b 100644 --- a/WebDriverAgentLib/Utilities/FBConfiguration.m +++ b/WebDriverAgentLib/Utilities/FBConfiguration.m @@ -33,6 +33,7 @@ static BOOL FBShouldUseSingletonTestManager = YES; static NSUInteger FBMjpegScalingFactor = 100; +static BOOL FBMjpegShouldFixOrientation = NO; static NSUInteger FBMjpegServerScreenshotQuality = 25; static NSUInteger FBMjpegServerFramerate = 10; @@ -143,6 +144,15 @@ + (void)setMjpegScalingFactor:(NSUInteger)scalingFactor { FBMjpegScalingFactor = scalingFactor; } ++ (BOOL)mjpegShouldFixOrientation +{ + return FBMjpegShouldFixOrientation; +} + ++ (void)setMjpegShouldFixOrientation:(BOOL)enabled { + FBMjpegShouldFixOrientation = enabled; +} + + (BOOL)verboseLoggingEnabled { return [NSProcessInfo.processInfo.environment[@"VERBOSE_LOGGING"] boolValue]; diff --git a/WebDriverAgentLib/Utilities/FBImageIOScaler.m b/WebDriverAgentLib/Utilities/FBImageIOScaler.m deleted file mode 100644 index 0ca87b747..000000000 --- a/WebDriverAgentLib/Utilities/FBImageIOScaler.m +++ /dev/null @@ -1,195 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import "FBImageIOScaler.h" - -#import -#import -@import UniformTypeIdentifiers; - -#import "FBConfiguration.h" -#import "FBErrorBuilder.h" -#import "FBLogger.h" - -const CGFloat FBMinScalingFactor = 0.01f; -const CGFloat FBMaxScalingFactor = 1.0f; -const CGFloat FBMinCompressionQuality = 0.0f; -const CGFloat FBMaxCompressionQuality = 1.0f; - -@interface FBImageIOScaler () - -@property (nonatomic) NSData *nextImage; -@property (nonatomic, readonly) NSLock *nextImageLock; -@property (nonatomic, readonly) dispatch_queue_t scalingQueue; - -@end - -@implementation FBImageIOScaler - -- (id)init -{ - self = [super init]; - if (self) { - _nextImageLock = [[NSLock alloc] init]; - _scalingQueue = dispatch_queue_create("image.scaling.queue", NULL); - } - return self; -} - -- (void)submitImage:(NSData *)image - scalingFactor:(CGFloat)scalingFactor - compressionQuality:(CGFloat)compressionQuality - completionHandler:(void (^)(NSData *))completionHandler -{ - [self.nextImageLock lock]; - if (self.nextImage != nil) { - [FBLogger verboseLog:@"Discarding screenshot"]; - } - scalingFactor = MAX(FBMinScalingFactor, MIN(FBMaxScalingFactor, scalingFactor)); - compressionQuality = MAX(FBMinCompressionQuality, MIN(FBMaxCompressionQuality, compressionQuality)); - self.nextImage = image; - [self.nextImageLock unlock]; - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wcompletion-handler" - dispatch_async(self.scalingQueue, ^{ - [self.nextImageLock lock]; - NSData *next = self.nextImage; - self.nextImage = nil; - [self.nextImageLock unlock]; - if (next == nil) { - return; - } - - NSError *error; - NSData *scaled = [self scaledJpegImageWithImage:next - scalingFactor:scalingFactor - compressionQuality:compressionQuality - error:&error]; - if (scaled == nil) { - [FBLogger logFmt:@"%@", error.description]; - return; - } - completionHandler(scaled); - }); -#pragma clang diagnostic pop -} - -// This method is more optimized for JPEG scaling -// and should be used in `submitImage` API, while the `scaledImageWithImage` -// one is more generic -- (nullable NSData *)scaledJpegImageWithImage:(NSData *)image - scalingFactor:(CGFloat)scalingFactor - compressionQuality:(CGFloat)compressionQuality - error:(NSError **)error -{ - CGImageSourceRef imageData = CGImageSourceCreateWithData((CFDataRef)image, nil); - CGSize size = [self.class imageSizeWithImage:imageData]; - CGFloat scaledMaxPixelSize = MAX(size.width, size.height) * scalingFactor; - CFDictionaryRef params = (__bridge CFDictionaryRef)@{ - (const NSString *)kCGImageSourceCreateThumbnailWithTransform: @(YES), - (const NSString *)kCGImageSourceCreateThumbnailFromImageIfAbsent: @(YES), - (const NSString *)kCGImageSourceThumbnailMaxPixelSize: @(scaledMaxPixelSize) - }; - CGImageRef scaled = CGImageSourceCreateThumbnailAtIndex(imageData, 0, params); - CFRelease(imageData); - if (nil == scaled) { - [[[FBErrorBuilder builder] - withDescriptionFormat:@"Failed to scale the image"] - buildError:error]; - return nil; - } - NSData *resData = [self jpegDataWithImage:scaled - compressionQuality:compressionQuality]; - if (nil == resData) { - [[[FBErrorBuilder builder] - withDescriptionFormat:@"Failed to compress the image to JPEG format"] - buildError:error]; - } - CGImageRelease(scaled); - return resData; -} - -- (nullable NSData *)scaledImageWithImage:(NSData *)image - uti:(UTType *)uti - rect:(CGRect)rect - scalingFactor:(CGFloat)scalingFactor - compressionQuality:(CGFloat)compressionQuality - error:(NSError **)error -{ - UIImage *uiImage = [UIImage imageWithData:image]; - CGSize size = uiImage.size; - CGSize scaledSize = CGSizeMake(size.width * scalingFactor, size.height * scalingFactor); - UIGraphicsBeginImageContext(scaledSize); - UIImageOrientation orientation = uiImage.imageOrientation; -#if !TARGET_OS_TV - if (FBConfiguration.screenshotOrientation == UIInterfaceOrientationPortrait) { - orientation = UIImageOrientationUp; - } else if (FBConfiguration.screenshotOrientation == UIInterfaceOrientationPortraitUpsideDown) { - orientation = UIImageOrientationDown; - } else if (FBConfiguration.screenshotOrientation == UIInterfaceOrientationLandscapeLeft) { - orientation = UIImageOrientationRight; - } else if (FBConfiguration.screenshotOrientation == UIInterfaceOrientationLandscapeRight) { - orientation = UIImageOrientationLeft; - } -#endif - uiImage = [UIImage imageWithCGImage:(CGImageRef)uiImage.CGImage - scale:uiImage.scale - orientation:orientation]; - [uiImage drawInRect:CGRectMake(0, 0, scaledSize.width, scaledSize.height)]; - UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - - if (!CGRectIsNull(rect)) { - UIGraphicsBeginImageContext(rect.size); - [resultImage drawAtPoint:CGPointMake(-rect.origin.x, -rect.origin.y)]; - resultImage = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - } - - return [uti conformsToType:UTTypePNG] - ? UIImagePNGRepresentation(resultImage) - : UIImageJPEGRepresentation(resultImage, compressionQuality); -} - -- (nullable NSData *)jpegDataWithImage:(CGImageRef)imageRef - compressionQuality:(CGFloat)compressionQuality -{ - NSMutableData *newImageData = [NSMutableData data]; - CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData( - (__bridge CFMutableDataRef) newImageData, - (__bridge CFStringRef) UTTypeJPEG.identifier, - 1, - NULL); - CFDictionaryRef compressionOptions = (__bridge CFDictionaryRef)@{ - (const NSString *)kCGImageDestinationLossyCompressionQuality: @(compressionQuality) - }; - CGImageDestinationAddImage(imageDestination, imageRef, compressionOptions); - if(!CGImageDestinationFinalize(imageDestination)) { - [FBLogger log:@"Failed to write the image"]; - newImageData = nil; - } - CFRelease(imageDestination); - return newImageData; -} - -+ (CGSize)imageSizeWithImage:(CGImageSourceRef)imageSource -{ - NSDictionary *options = @{ - (const NSString *)kCGImageSourceShouldCache: @(NO) - }; - CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, (CFDictionaryRef)options); - NSNumber *width = [(__bridge NSDictionary *)properties objectForKey:(const NSString *)kCGImagePropertyPixelWidth]; - NSNumber *height = [(__bridge NSDictionary *)properties objectForKey:(const NSString *)kCGImagePropertyPixelHeight]; - CGSize size = CGSizeMake([width floatValue], [height floatValue]); - CFRelease(properties); - return size; -} - -@end diff --git a/WebDriverAgentLib/Utilities/FBImageIOScaler.h b/WebDriverAgentLib/Utilities/FBImageProcessor.h similarity index 64% rename from WebDriverAgentLib/Utilities/FBImageIOScaler.h rename to WebDriverAgentLib/Utilities/FBImageProcessor.h index 476daba04..a350bd9ce 100644 --- a/WebDriverAgentLib/Utilities/FBImageIOScaler.h +++ b/WebDriverAgentLib/Utilities/FBImageProcessor.h @@ -20,7 +20,7 @@ extern const CGFloat FBMaxScalingFactor; extern const CGFloat FBMinCompressionQuality; extern const CGFloat FBMaxCompressionQuality; -@interface FBImageIOScaler : NSObject +@interface FBImageProcessor : NSObject /** Puts the passed image on the queue and dispatches a scaling operation. If there is already a image on the @@ -29,34 +29,27 @@ extern const CGFloat FBMaxCompressionQuality; @param image The image to scale down @param completionHandler called after successfully scaling down an image @param scalingFactor the scaling factor in range 0.01..1.0. A value of 1.0 won't perform scaling at all - @param compressionQuality the compression quality in range 0.0..1.0 (0.0 for max. compression and 1.0 for lossless compression) - Only applicable for UTTypeJPEG */ -- (void)submitImage:(NSData *)image - scalingFactor:(CGFloat)scalingFactor - compressionQuality:(CGFloat)compressionQuality - completionHandler:(void (^)(NSData *))completionHandler; +- (void)submitImageData:(NSData *)image + scalingFactor:(CGFloat)scalingFactor + completionHandler:(void (^)(NSData *))completionHandler; /** Scales and crops the source image @param image The source image data @param uti Either UTTypePNG or UTTypeJPEG - @param rect The cropping rectange for the screenshot. The value is expected to be non-scaled one - since it happens after scaling/orientation change. - CGRectNull could be used to take a screenshot of the full screen. @param scalingFactor Scaling factor in range 0.01..1.0. A value of 1.0 won't perform scaling at all @param compressionQuality the compression quality in range 0.0..1.0 (0.0 for max. compression and 1.0 for lossless compression). Only works if UTI is set to kUTTypeJPEG @param error The actual error instance if the returned result is nil @returns Processed image data compressed according to the given UTI or nil in case of a failure */ -- (nullable NSData *)scaledImageWithImage:(NSData *)image - uti:(UTType *)uti - rect:(CGRect)rect - scalingFactor:(CGFloat)scalingFactor - compressionQuality:(CGFloat)compressionQuality - error:(NSError **)error; +- (nullable NSData *)scaledImageWithData:(NSData *)image + uti:(UTType *)uti + scalingFactor:(CGFloat)scalingFactor + compressionQuality:(CGFloat)compressionQuality + error:(NSError **)error; @end diff --git a/WebDriverAgentLib/Utilities/FBImageProcessor.m b/WebDriverAgentLib/Utilities/FBImageProcessor.m new file mode 100644 index 000000000..16601ce8e --- /dev/null +++ b/WebDriverAgentLib/Utilities/FBImageProcessor.m @@ -0,0 +1,171 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "FBImageProcessor.h" + +#import +#import +@import UniformTypeIdentifiers; + +#import "FBConfiguration.h" +#import "FBErrorBuilder.h" +#import "FBImageUtils.h" +#import "FBLogger.h" + +const CGFloat FBMinScalingFactor = 0.01f; +const CGFloat FBMaxScalingFactor = 1.0f; +const CGFloat FBMinCompressionQuality = 0.0f; +const CGFloat FBMaxCompressionQuality = 1.0f; + +@interface FBImageProcessor () + +@property (nonatomic) NSData *nextImage; +@property (nonatomic, readonly) NSLock *nextImageLock; +@property (nonatomic, readonly) dispatch_queue_t scalingQueue; + +@end + +@implementation FBImageProcessor + +- (id)init +{ + self = [super init]; + if (self) { + _nextImageLock = [[NSLock alloc] init]; + _scalingQueue = dispatch_queue_create("image.scaling.queue", NULL); + } + return self; +} + +- (void)submitImageData:(NSData *)image + scalingFactor:(CGFloat)scalingFactor + completionHandler:(void (^)(NSData *))completionHandler +{ + [self.nextImageLock lock]; + if (self.nextImage != nil) { + [FBLogger verboseLog:@"Discarding screenshot"]; + } + self.nextImage = image; + [self.nextImageLock unlock]; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wcompletion-handler" + dispatch_async(self.scalingQueue, ^{ + [self.nextImageLock lock]; + NSData *nextImageData = self.nextImage; + self.nextImage = nil; + [self.nextImageLock unlock]; + if (nextImageData == nil) { + return; + } + + // We do not want this value to be too high because then we get images larger in size than original ones + // Although, we also don't want to lose too much of the quality on recompression + CGFloat recompressionQuality = MAX(0.9, + MIN(FBMaxCompressionQuality, FBConfiguration.mjpegServerScreenshotQuality / 100.0)); + NSData *thumbnailData = [self.class fixedImageDataWithImageData:nextImageData + scalingFactor:scalingFactor + uti:UTTypeJPEG + compressionQuality:recompressionQuality + // iOS always returns screnshots in portrait orientation, but puts the real value into the metadata + // Use it with care. See https://github.com/appium/WebDriverAgent/pull/812 + fixOrientation:FBConfiguration.mjpegShouldFixOrientation + desiredOrientation:nil]; + completionHandler(thumbnailData ?: nextImageData); + }); +#pragma clang diagnostic pop +} + ++ (nullable NSData *)fixedImageDataWithImageData:(NSData *)imageData + scalingFactor:(CGFloat)scalingFactor + uti:(UTType *)uti + compressionQuality:(CGFloat)compressionQuality + fixOrientation:(BOOL)fixOrientation + desiredOrientation:(nullable NSNumber *)orientation +{ + scalingFactor = MAX(FBMinScalingFactor, MIN(FBMaxScalingFactor, scalingFactor)); + BOOL usesScaling = scalingFactor > 0.0 && scalingFactor < FBMaxScalingFactor; + @autoreleasepool { + if (!usesScaling && !fixOrientation) { + return [uti conformsToType:UTTypePNG] ? FBToPngData(imageData) : FBToJpegData(imageData, compressionQuality); + } + + UIImage *image = [UIImage imageWithData:imageData]; + if (nil == image + || ((image.imageOrientation == UIImageOrientationUp || !fixOrientation) && !usesScaling)) { + return [uti conformsToType:UTTypePNG] ? FBToPngData(imageData) : FBToJpegData(imageData, compressionQuality); + } + + CGSize scaledSize = CGSizeMake(image.size.width * scalingFactor, image.size.height * scalingFactor); + if (!fixOrientation && usesScaling) { + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + __block UIImage *result = nil; + [image prepareThumbnailOfSize:scaledSize + completionHandler:^(UIImage * _Nullable thumbnail) { + result = thumbnail; + dispatch_semaphore_signal(semaphore); + }]; + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + if (nil == result) { + return [uti conformsToType:UTTypePNG] ? FBToPngData(imageData) : FBToJpegData(imageData, compressionQuality); + } + return [uti conformsToType:UTTypePNG] + ? UIImagePNGRepresentation(result) + : UIImageJPEGRepresentation(result, compressionQuality); + } + + UIGraphicsImageRendererFormat *format = [[UIGraphicsImageRendererFormat alloc] init]; + format.scale = scalingFactor; + UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:scaledSize + format:format]; + UIImageOrientation desiredOrientation = orientation == nil + ? image.imageOrientation + : (UIImageOrientation)orientation.integerValue; + UIImage *uiImage = [UIImage imageWithCGImage:(CGImageRef)image.CGImage + scale:image.scale + orientation:desiredOrientation]; + return [uti conformsToType:UTTypePNG] + ? [renderer PNGDataWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) { + [uiImage drawInRect:CGRectMake(0, 0, scaledSize.width, scaledSize.height)]; + }] + : [renderer JPEGDataWithCompressionQuality:compressionQuality + actions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) { + [uiImage drawInRect:CGRectMake(0, 0, scaledSize.width, scaledSize.height)]; + }]; + } +} + +- (nullable NSData *)scaledImageWithData:(NSData *)imageData + uti:(UTType *)uti + scalingFactor:(CGFloat)scalingFactor + compressionQuality:(CGFloat)compressionQuality + error:(NSError **)error +{ + NSNumber *orientation = nil; +#if !TARGET_OS_TV + if (FBConfiguration.screenshotOrientation == UIInterfaceOrientationPortrait) { + orientation = @(UIImageOrientationUp); + } else if (FBConfiguration.screenshotOrientation == UIInterfaceOrientationPortraitUpsideDown) { + orientation = @(UIImageOrientationDown); + } else if (FBConfiguration.screenshotOrientation == UIInterfaceOrientationLandscapeLeft) { + orientation = @(UIImageOrientationRight); + } else if (FBConfiguration.screenshotOrientation == UIInterfaceOrientationLandscapeRight) { + orientation = @(UIImageOrientationLeft); + } +#endif + NSData *resultData = [self.class fixedImageDataWithImageData:imageData + scalingFactor:scalingFactor + uti:uti + compressionQuality:compressionQuality + fixOrientation:YES + desiredOrientation:orientation]; + return resultData ?: imageData; +} + +@end diff --git a/WebDriverAgentLib/Utilities/FBImageUtils.h b/WebDriverAgentLib/Utilities/FBImageUtils.h index 96ea15a6b..15a04f6fe 100644 --- a/WebDriverAgentLib/Utilities/FBImageUtils.h +++ b/WebDriverAgentLib/Utilities/FBImageUtils.h @@ -17,4 +17,10 @@ BOOL FBIsPngImage(NSData *imageData); /*! Converts the given image data to a PNG representation if necessary */ NSData *_Nullable FBToPngData(NSData *imageData); +/*! Returns YES if the data contains a JPG image */ +BOOL FBIsJpegImage(NSData *imageData); + +/*! Converts the given image data to a JPG representation if necessary */ +NSData *_Nullable FBToJpegData(NSData *imageData, CGFloat compressionQuality); + NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentLib/Utilities/FBImageUtils.m b/WebDriverAgentLib/Utilities/FBImageUtils.m index 5983ddc30..b1d2f9b5b 100644 --- a/WebDriverAgentLib/Utilities/FBImageUtils.m +++ b/WebDriverAgentLib/Utilities/FBImageUtils.m @@ -12,8 +12,11 @@ #import "FBMacros.h" #import "FBConfiguration.h" +// https://en.wikipedia.org/wiki/List_of_file_signatures static uint8_t PNG_MAGIC[] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }; static const NSUInteger PNG_MAGIC_LEN = 8; +static uint8_t JPG_MAGIC[] = { 0xff, 0xd8, 0xff }; +static const NSUInteger JPG_MAGIC_LEN = 3; BOOL FBIsPngImage(NSData *imageData) { @@ -45,3 +48,34 @@ BOOL FBIsPngImage(NSData *imageData) UIImage *image = [UIImage imageWithData:imageData]; return nil == image ? nil : (NSData *)UIImagePNGRepresentation(image); } + +BOOL FBIsJpegImage(NSData *imageData) +{ + if (nil == imageData || [imageData length] < JPG_MAGIC_LEN) { + return NO; + } + + static NSData* jpgMagicStartData = nil; + static dispatch_once_t onceJpgToken; + dispatch_once(&onceJpgToken, ^{ + jpgMagicStartData = [NSData dataWithBytesNoCopy:(void*)JPG_MAGIC length:JPG_MAGIC_LEN freeWhenDone:NO]; + }); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wassign-enum" + NSRange range = [imageData rangeOfData:jpgMagicStartData options:kNilOptions range:NSMakeRange(0, JPG_MAGIC_LEN)]; +#pragma clang diagnostic pop + return range.location != NSNotFound; +} + +NSData *FBToJpegData(NSData *imageData, CGFloat compressionQuality) { + if (nil == imageData || [imageData length] < JPG_MAGIC_LEN) { + return nil; + } + if (FBIsJpegImage(imageData)) { + return imageData; + } + + UIImage *image = [UIImage imageWithData:imageData]; + return nil == image ? nil : (NSData *)UIImageJPEGRepresentation(image, compressionQuality); +} diff --git a/WebDriverAgentLib/Utilities/FBMjpegServer.m b/WebDriverAgentLib/Utilities/FBMjpegServer.m index 51fa48687..a0970e256 100644 --- a/WebDriverAgentLib/Utilities/FBMjpegServer.m +++ b/WebDriverAgentLib/Utilities/FBMjpegServer.m @@ -17,7 +17,8 @@ #import "FBConfiguration.h" #import "FBLogger.h" #import "FBScreenshot.h" -#import "FBImageIOScaler.h" +#import "FBImageProcessor.h" +#import "FBImageUtils.h" #import "XCUIScreen.h" static const NSUInteger MAX_FPS = 60; @@ -31,7 +32,7 @@ @interface FBMjpegServer() @property (nonatomic, readonly) dispatch_queue_t backgroundQueue; @property (nonatomic, readonly) NSMutableArray *listeningClients; -@property (nonatomic, readonly) FBImageIOScaler *imageScaler; +@property (nonatomic, readonly) FBImageProcessor *imageProcessor; @property (nonatomic, readonly) long long mainScreenID; @end @@ -48,7 +49,7 @@ - (instancetype)init dispatch_async(_backgroundQueue, ^{ [self streamScreenshot]; }); - _imageScaler = [[FBImageIOScaler alloc] init]; + _imageProcessor = [[FBImageProcessor alloc] init]; _mainScreenID = [XCUIScreen.mainScreen displayID]; } return self; @@ -82,15 +83,11 @@ - (void)streamScreenshot } } - CGFloat scalingFactor = [FBConfiguration mjpegScalingFactor] / 100.0f; - BOOL usesScaling = fabs(FBMaxScalingFactor - scalingFactor) > DBL_EPSILON; - CGFloat compressionQuality = FBConfiguration.mjpegServerScreenshotQuality / 100.0f; - // If scaling is applied we perform another JPEG compression after scaling - // To get the desired compressionQuality we need to do a lossless compression here - CGFloat screenshotCompressionQuality = usesScaling ? FBMaxCompressionQuality : compressionQuality; NSError *error; + CGFloat compressionQuality = MAX(FBMinCompressionQuality, + MIN(FBMaxCompressionQuality, FBConfiguration.mjpegServerScreenshotQuality / 100.0)); NSData *screenshotData = [FBScreenshot takeInOriginalResolutionWithScreenID:self.mainScreenID - compressionQuality:screenshotCompressionQuality + compressionQuality:compressionQuality uti:UTTypeJPEG timeout:FRAME_TIMEOUT error:&error]; @@ -100,16 +97,12 @@ - (void)streamScreenshot return; } - if (usesScaling) { - [self.imageScaler submitImage:screenshotData - scalingFactor:scalingFactor - compressionQuality:compressionQuality - completionHandler:^(NSData * _Nonnull scaled) { - [self sendScreenshot:scaled]; - }]; - } else { - [self sendScreenshot:screenshotData]; - } + CGFloat scalingFactor = FBConfiguration.mjpegScalingFactor / 100.0; + [self.imageProcessor submitImageData:screenshotData + scalingFactor:scalingFactor + completionHandler:^(NSData * _Nonnull scaled) { + [self sendScreenshot:scaled]; + }]; [self scheduleNextScreenshotWithInterval:timerInterval timeStarted:timeStarted]; } diff --git a/WebDriverAgentLib/Utilities/FBScreenshot.h b/WebDriverAgentLib/Utilities/FBScreenshot.h index 036a5e1cb..74e6b5886 100644 --- a/WebDriverAgentLib/Utilities/FBScreenshot.h +++ b/WebDriverAgentLib/Utilities/FBScreenshot.h @@ -24,19 +24,6 @@ NS_ASSUME_NONNULL_BEGIN + (nullable NSData *)takeInOriginalResolutionWithQuality:(NSUInteger)quality error:(NSError **)error; -/** - Retrieves non-scaled screenshot of the particular screen rectangle - - @param quality The number in range 0-3, where 0 is PNG (lossless), 3 is HEIC (lossless), 1- low quality JPEG and 2 - high quality JPEG - @param rect The bounding rectange for the screenshot. The value is expected be non-scaled one. - CGRectNull could be used to take a screenshot of the full screen. - @param error If there is an error, upon return contains an NSError object that describes the problem. - @return Device screenshot as PNG-encoded data or nil in case of failure - */ -+ (nullable NSData *)takeInOriginalResolutionWithQuality:(NSUInteger)quality - rect:(CGRect)rect - error:(NSError **)error; - /** Retrieves non-scaled screenshot of the whole screen diff --git a/WebDriverAgentLib/Utilities/FBScreenshot.m b/WebDriverAgentLib/Utilities/FBScreenshot.m index 8cea6530d..3d9716dea 100644 --- a/WebDriverAgentLib/Utilities/FBScreenshot.m +++ b/WebDriverAgentLib/Utilities/FBScreenshot.m @@ -13,7 +13,7 @@ #import "FBConfiguration.h" #import "FBErrorBuilder.h" -#import "FBImageIOScaler.h" +#import "FBImageProcessor.h" #import "FBLogger.h" #import "FBMacros.h" #import "FBXCodeCompatibility.h" @@ -59,30 +59,19 @@ + (UTType *)imageUtiWithQuality:(NSUInteger)quality } + (NSData *)takeInOriginalResolutionWithQuality:(NSUInteger)quality - rect:(CGRect)rect error:(NSError **)error { XCUIScreen *mainScreen = XCUIScreen.mainScreen; return [self.class takeWithScreenID:mainScreen.displayID scale:SCREENSHOT_SCALE compressionQuality:[self.class compressionQualityWithQuality:quality] - rect:rect sourceUTI:[self.class imageUtiWithQuality:quality] error:error]; } -+ (NSData *)takeInOriginalResolutionWithQuality:(NSUInteger)quality - error:(NSError **)error -{ - return [self.class takeInOriginalResolutionWithQuality:quality - rect:CGRectNull - error:error]; -} - + (NSData *)takeWithScreenID:(long long)screenID scale:(CGFloat)scale compressionQuality:(CGFloat)compressionQuality - rect:(CGRect)rect sourceUTI:(UTType *)uti error:(NSError **)error { @@ -94,9 +83,8 @@ + (NSData *)takeWithScreenID:(long long)screenID if (nil == screenshotData) { return nil; } - return [[[FBImageIOScaler alloc] init] scaledImageWithImage:screenshotData + return [[[FBImageProcessor alloc] init] scaledImageWithData:screenshotData uti:UTTypePNG - rect:rect scalingFactor:1.0 / scale compressionQuality:FBMaxCompressionQuality error:error]; diff --git a/WebDriverAgentLib/Utilities/FBSettings.h b/WebDriverAgentLib/Utilities/FBSettings.h index 8235cb337..dd82d740c 100644 --- a/WebDriverAgentLib/Utilities/FBSettings.h +++ b/WebDriverAgentLib/Utilities/FBSettings.h @@ -17,6 +17,7 @@ extern NSString* const FB_SETTING_USE_COMPACT_RESPONSES; extern NSString* const FB_SETTING_ELEMENT_RESPONSE_ATTRIBUTES; extern NSString* const FB_SETTING_MJPEG_SERVER_SCREENSHOT_QUALITY; extern NSString* const FB_SETTING_MJPEG_SERVER_FRAMERATE; +extern NSString* const FB_SETTING_MJPEG_FIX_ORIENTATION; extern NSString* const FB_SETTING_MJPEG_SCALING_FACTOR; extern NSString* const FB_SETTING_SCREENSHOT_QUALITY; extern NSString* const FB_SETTING_KEYBOARD_AUTOCORRECTION; diff --git a/WebDriverAgentLib/Utilities/FBSettings.m b/WebDriverAgentLib/Utilities/FBSettings.m index 26bae07e0..6b12a4cd4 100644 --- a/WebDriverAgentLib/Utilities/FBSettings.m +++ b/WebDriverAgentLib/Utilities/FBSettings.m @@ -14,6 +14,7 @@ NSString* const FB_SETTING_MJPEG_SERVER_SCREENSHOT_QUALITY = @"mjpegServerScreenshotQuality"; NSString* const FB_SETTING_MJPEG_SERVER_FRAMERATE = @"mjpegServerFramerate"; NSString* const FB_SETTING_MJPEG_SCALING_FACTOR = @"mjpegScalingFactor"; +NSString* const FB_SETTING_MJPEG_FIX_ORIENTATION = @"mjpegFixOrientation"; NSString* const FB_SETTING_SCREENSHOT_QUALITY = @"screenshotQuality"; NSString* const FB_SETTING_KEYBOARD_AUTOCORRECTION = @"keyboardAutocorrection"; NSString* const FB_SETTING_KEYBOARD_PREDICTION = @"keyboardPrediction"; diff --git a/WebDriverAgentTests/IntegrationTests/FBImageIOScalerTests.m b/WebDriverAgentTests/IntegrationTests/FBImageProcessorTests.m similarity index 59% rename from WebDriverAgentTests/IntegrationTests/FBImageIOScalerTests.m rename to WebDriverAgentTests/IntegrationTests/FBImageProcessorTests.m index 0c2f75b62..28fa9d7ee 100644 --- a/WebDriverAgentTests/IntegrationTests/FBImageIOScalerTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBImageProcessorTests.m @@ -9,62 +9,62 @@ #import -#import "FBImageIOScaler.h" +#import "FBImageProcessor.h" #import "FBIntegrationTestCase.h" -@interface FBImageIOScalerTests : FBIntegrationTestCase +@interface FBImageProcessorTests : FBIntegrationTestCase @property (nonatomic) NSData *originalImage; @property (nonatomic) CGSize originalSize; @end -@implementation FBImageIOScalerTests +@implementation FBImageProcessorTests - (void)setUp { XCUIApplication *app = [[XCUIApplication alloc] init]; [app launch]; XCUIScreenshot *screenshot = app.screenshot; self.originalImage = UIImageJPEGRepresentation(screenshot.image, 1.0); - self.originalSize = [FBImageIOScalerTests scaledSizeFromImage:screenshot.image]; + self.originalSize = [FBImageProcessorTests scaledSizeFromImage:screenshot.image]; } - (void)testScaling { CGFloat halfScale = 0.5; - CGSize expectedHalfScaleSize = [FBImageIOScalerTests sizeFromSize:self.originalSize scalingFactor:0.5]; + CGSize expectedHalfScaleSize = [FBImageProcessorTests sizeFromSize:self.originalSize scalingFactor:0.5]; [self scaleImageWithFactor:halfScale expectedSize:expectedHalfScaleSize]; - // 1 is the smalles scaling factor we accept + // 0 is the smalles scaling factor we accept CGFloat minScale = 0.0; - CGSize expectedMinScaleSize = [FBImageIOScalerTests sizeFromSize:self.originalSize scalingFactor:0.01]; + CGSize expectedMinScaleSize = [FBImageProcessorTests sizeFromSize:self.originalSize scalingFactor:0.01]; [self scaleImageWithFactor:minScale expectedSize:expectedMinScaleSize]; // For scaling factors above 100 we don't perform any scaling and just return the unmodified image - CGFloat unscaled = 2.0; - [self scaleImageWithFactor:unscaled + [self scaleImageWithFactor:1.0 + expectedSize:self.originalSize]; + [self scaleImageWithFactor:2.0 expectedSize:self.originalSize]; } - (void)scaleImageWithFactor:(CGFloat)scalingFactor expectedSize:(CGSize)excpectedSize { - FBImageIOScaler *scaler = [[FBImageIOScaler alloc] init]; + FBImageProcessor *scaler = [[FBImageProcessor alloc] init]; id expScaled = [self expectationWithDescription:@"Receive scaled image"]; - [scaler submitImage:self.originalImage - scalingFactor:scalingFactor - compressionQuality:1.0 - completionHandler:^(NSData *scaled) { - UIImage *scaledImage = [UIImage imageWithData:scaled]; - CGSize scaledSize = [FBImageIOScalerTests scaledSizeFromImage:scaledImage]; - - XCTAssertEqualWithAccuracy(scaledSize.width, excpectedSize.width, 1.0); - XCTAssertEqualWithAccuracy(scaledSize.height, excpectedSize.height, 1.0); - - [expScaled fulfill]; - }]; + [scaler submitImageData:self.originalImage + scalingFactor:scalingFactor + completionHandler:^(NSData *scaled) { + UIImage *scaledImage = [UIImage imageWithData:scaled]; + CGSize scaledSize = [FBImageProcessorTests scaledSizeFromImage:scaledImage]; + + XCTAssertEqualWithAccuracy(scaledSize.width, excpectedSize.width, 1.0); + XCTAssertEqualWithAccuracy(scaledSize.height, excpectedSize.height, 1.0); + + [expScaled fulfill]; + }]; [self waitForExpectations:@[expScaled] timeout:0.5]; diff --git a/WebDriverAgentTests/IntegrationTests/XCUIDeviceHelperTests.m b/WebDriverAgentTests/IntegrationTests/XCUIDeviceHelperTests.m index 52a910311..ca79b2fa4 100644 --- a/WebDriverAgentTests/IntegrationTests/XCUIDeviceHelperTests.m +++ b/WebDriverAgentTests/IntegrationTests/XCUIDeviceHelperTests.m @@ -78,14 +78,12 @@ - (void)testLandscapeScreenshot XCTAssertTrue(screenshot.size.width > screenshot.size.height); XCUIScreen *mainScreen = XCUIScreen.mainScreen; - // TODO: This screenshot rotation was not landscape in an iOS 16 beta simulator. UIImage *screenshotExact = ((XCUIScreenshot *)mainScreen.screenshot).image; - XCTAssertEqualWithAccuracy(screenshotExact.size.height * mainScreen.scale, - screenshot.size.height, - FLT_EPSILON); - XCTAssertEqualWithAccuracy(screenshotExact.size.width * mainScreen.scale, - screenshot.size.width, - FLT_EPSILON); + CGSize realMainScreenSize = screenshotExact.size.height > screenshot.size.width + ? CGSizeMake(screenshotExact.size.height * mainScreen.scale, screenshotExact.size.width * mainScreen.scale) + : CGSizeMake(screenshotExact.size.width * mainScreen.scale, screenshotExact.size.height * mainScreen.scale); + XCTAssertEqualWithAccuracy(realMainScreenSize.height, screenshot.size.height, FLT_EPSILON); + XCTAssertEqualWithAccuracy(realMainScreenSize.width, screenshot.size.width, FLT_EPSILON); } - (void)testWifiAddress From b4704dafc4567e1f0dc8675facfc48a195aae4bf Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 16 Nov 2023 22:15:35 +0100 Subject: [PATCH 225/240] fix: Content-Type of the MJPEG server --- WebDriverAgentLib/Utilities/FBMjpegServer.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebDriverAgentLib/Utilities/FBMjpegServer.m b/WebDriverAgentLib/Utilities/FBMjpegServer.m index a0970e256..14a734c94 100644 --- a/WebDriverAgentLib/Utilities/FBMjpegServer.m +++ b/WebDriverAgentLib/Utilities/FBMjpegServer.m @@ -108,7 +108,7 @@ - (void)streamScreenshot } - (void)sendScreenshot:(NSData *)screenshotData { - NSString *chunkHeader = [NSString stringWithFormat:@"--BoundaryString\r\nContent-type: image/jpg\r\nContent-Length: %@\r\n\r\n", @(screenshotData.length)]; + NSString *chunkHeader = [NSString stringWithFormat:@"--BoundaryString\r\nContent-type: image/jpeg\r\nContent-Length: %@\r\n\r\n", @(screenshotData.length)]; NSMutableData *chunk = [[chunkHeader dataUsingEncoding:NSUTF8StringEncoding] mutableCopy]; [chunk appendData:screenshotData]; [chunk appendData:(id)[@"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; From d0dbbb87de7cce3d3687bda3bd53807af14dd795 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 16 Nov 2023 21:20:34 +0000 Subject: [PATCH 226/240] chore(release): 5.15.1 [skip ci] ## [5.15.1](https://github.com/appium/WebDriverAgent/compare/v5.15.0...v5.15.1) (2023-11-16) ### Bug Fixes * Content-Type of the MJPEG server ([b4704da](https://github.com/appium/WebDriverAgent/commit/b4704dafc4567e1f0dc8675facfc48a195aae4bf)) ### Code Refactoring * Optimize screenshots preprocessing ([#812](https://github.com/appium/WebDriverAgent/issues/812)) ([0b41757](https://github.com/appium/WebDriverAgent/commit/0b41757c0d21004afab32860b4e510d4bc426018)) --- CHANGELOG.md | 12 ++++++++++++ package.json | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 539251658..cf1bd97e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## [5.15.1](https://github.com/appium/WebDriverAgent/compare/v5.15.0...v5.15.1) (2023-11-16) + + +### Bug Fixes + +* Content-Type of the MJPEG server ([b4704da](https://github.com/appium/WebDriverAgent/commit/b4704dafc4567e1f0dc8675facfc48a195aae4bf)) + + +### Code Refactoring + +* Optimize screenshots preprocessing ([#812](https://github.com/appium/WebDriverAgent/issues/812)) ([0b41757](https://github.com/appium/WebDriverAgent/commit/0b41757c0d21004afab32860b4e510d4bc426018)) + ## [5.15.0](https://github.com/appium/WebDriverAgent/compare/v5.14.0...v5.15.0) (2023-11-16) diff --git a/package.json b/package.json index d5568caef..ea8a6b721 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.15.0", + "version": "5.15.1", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 08388fd602ee9d588a8780e8d141d748813782ed Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Thu, 23 Nov 2023 01:30:47 -0800 Subject: [PATCH 227/240] chore: a dummy commit to check a package release From 014d04df956e47fef67938b089511e80d344f007 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Thu, 23 Nov 2023 02:22:36 -0800 Subject: [PATCH 228/240] fix: fix run test ci (#814) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ea8a6b721..30e48bd49 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "semantic-release": "^22.0.5", "sinon": "^17.0.0", "ts-node": "^10.9.1", - "typescript": "^5.1.6" + "typescript": "~5.2" }, "dependencies": { "@appium/base-driver": "^9.0.0", From 8c76380bc22e84c76b5429b7db2c29e9c024dba5 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 23 Nov 2023 10:28:49 +0000 Subject: [PATCH 229/240] chore(release): 5.15.2 [skip ci] ## [5.15.2](https://github.com/appium/WebDriverAgent/compare/v5.15.1...v5.15.2) (2023-11-23) ### Bug Fixes * fix run test ci ([#814](https://github.com/appium/WebDriverAgent/issues/814)) ([014d04d](https://github.com/appium/WebDriverAgent/commit/014d04df956e47fef67938b089511e80d344f007)) ### Miscellaneous Chores * a dummy commit to check a package release ([08388fd](https://github.com/appium/WebDriverAgent/commit/08388fd602ee9d588a8780e8d141d748813782ed)) --- CHANGELOG.md | 12 ++++++++++++ package.json | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf1bd97e8..87c1177aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## [5.15.2](https://github.com/appium/WebDriverAgent/compare/v5.15.1...v5.15.2) (2023-11-23) + + +### Bug Fixes + +* fix run test ci ([#814](https://github.com/appium/WebDriverAgent/issues/814)) ([014d04d](https://github.com/appium/WebDriverAgent/commit/014d04df956e47fef67938b089511e80d344f007)) + + +### Miscellaneous Chores + +* a dummy commit to check a package release ([08388fd](https://github.com/appium/WebDriverAgent/commit/08388fd602ee9d588a8780e8d141d748813782ed)) + ## [5.15.1](https://github.com/appium/WebDriverAgent/compare/v5.15.0...v5.15.1) (2023-11-16) diff --git a/package.json b/package.json index 30e48bd49..ac2e671fb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.15.1", + "version": "5.15.2", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 2d7fc0370b30e5e3adc9a13002fa95f607c4c160 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Fri, 24 Nov 2023 18:55:16 +0100 Subject: [PATCH 230/240] chore: Make xcodebuild error message more helpful (#816) --- lib/utils.js | 9 +++++- lib/xcodebuild.js | 72 +++++++++++++---------------------------------- 2 files changed, 28 insertions(+), 53 deletions(-) diff --git a/lib/utils.js b/lib/utils.js index 1474d929f..f52ec6fe0 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -265,12 +265,19 @@ function getXctestrunFileName (deviceInfo, version) { : `WebDriverAgentRunner_iphone${deviceInfo.isRealDevice ? `os${version}-arm64` : `simulator${version}-x86_64`}.xctestrun`; } +/** + * Ensures the process is killed after the timeout + * + * @param {string} name + * @param {import('teen_process').SubProcess} proc + * @returns {Promise} + */ async function killProcess (name, proc) { if (!proc || !proc.isRunning) { return; } - log.info(`Shutting down '${name}' process (pid '${proc.proc.pid}')`); + log.info(`Shutting down '${name}' process (pid '${proc.proc?.pid}')`); log.info(`Sending 'SIGTERM'...`); try { diff --git a/lib/xcodebuild.js b/lib/xcodebuild.js index 8194d1984..bdd484db2 100644 --- a/lib/xcodebuild.js +++ b/lib/xcodebuild.js @@ -1,17 +1,17 @@ import { retryInterval } from 'asyncbox'; import { SubProcess, exec } from 'teen_process'; -import { fs, logger, timing } from '@appium/support'; +import { logger, timing } from '@appium/support'; import defaultLogger from './logger'; import B from 'bluebird'; import { setRealDeviceSecurity, setXctestrunFile, updateProjectFile, resetProjectFile, killProcess, - getWDAUpgradeTimestamp, isTvOS } from './utils'; + getWDAUpgradeTimestamp, isTvOS +} from './utils'; import _ from 'lodash'; import path from 'path'; import { EOL } from 'os'; import { WDA_RUNNER_BUNDLE_ID } from './constants'; -import readline from 'node:readline'; const DEFAULT_SIGNING_ID = 'iPhone Developer'; @@ -34,6 +34,9 @@ const xcodeLog = logger.getLogger('Xcode'); class XcodeBuild { + /** @type {SubProcess} */ + xcodebuild; + /** * @param {string} xcodeVersion * @param {any} device @@ -85,10 +88,6 @@ class XcodeBuild { this.resultBundlePath = args.resultBundlePath; this.resultBundleVersion = args.resultBundleVersion; - /** @type {string} */ - this._logLocation = ''; - /** @type {string[]} */ - this._wdaErrorMessage = []; this._didBuildFail = false; this._didProcessExit = false; } @@ -168,8 +167,6 @@ class XcodeBuild { this.usePrebuiltWDA = true; await this.start(true); - this.xcodebuild = null; - if (this.prebuildDelay > 0) { // pause a moment await B.delay(this.prebuildDelay); @@ -286,7 +283,6 @@ class XcodeBuild { if (upgradeTimestamp) { env.UPGRADE_TIMESTAMP = upgradeTimestamp; } - this._logLocation = ''; this._didBuildFail = false; const xcodebuild = new SubProcess(cmd, args, { cwd: this.bootstrapPath, @@ -302,14 +298,6 @@ class XcodeBuild { this.log.debug(`${logMsg}. To change this, use 'showXcodeLog' desired capability`); xcodebuild.on('output', (stdout, stderr) => { let out = stdout || stderr; - // we want to pull out the log file that is created, and highlight it - // for diagnostic purposes - if (out.includes('Writing diagnostic log for test session to')) { - // pull out the first line that begins with the path separator - // which *should* be the line indicating the log file generated - this._logLocation = _.first(_.remove(out.trim().split('\n'), (v) => v.startsWith(path.sep))) ?? ''; - xcodeLog.debug(`Log file location for xcodebuild test: ${this._logLocation || 'unknown'}`); - } // if we have an error we want to output the logs // otherwise the failure is inscrutible @@ -326,9 +314,6 @@ class XcodeBuild { if (logXcodeOutput && !ignoreError) { for (const line of out.split(EOL)) { xcodeLog.error(line); - if (line) { - this._wdaErrorMessage.push(line); - } } } }); @@ -338,43 +323,27 @@ class XcodeBuild { async start (buildOnly = false) { this.xcodebuild = await this.createSubProcess(buildOnly); - // Store xcodebuild message - this._wdaErrorMessage = []; // wrap the start procedure in a promise so that we can catch, and report, // any startup errors that are thrown as events return await new B((resolve, reject) => { - // @ts-ignore xcodebuild must be present here - this.xcodebuild.once('exit', async (code, signal) => { + this.xcodebuild.once('exit', (code, signal) => { xcodeLog.error(`xcodebuild exited with code '${code}' and signal '${signal}'`); - this.xcodebuild?.removeAllListeners(); - const xcodeErrorMessage = this._wdaErrorMessage.join('\n'); - this._wdaErrorMessage = []; - // print out the xcodebuild file if users have asked for it - if (this.showXcodeLog && this._logLocation) { - xcodeLog.error(`Contents of xcodebuild log file '${this._logLocation}':`); - try { - const logFile = readline.createInterface({ - input: fs.createReadStream(this._logLocation), - terminal: false - }); - logFile.on('line', (line) => { - xcodeLog.error(line); - }); - await new B((_resolve) => { - logFile.once('close', () => { - logFile.removeAllListeners(); - _resolve(); - }); - }); - } catch (err) { - xcodeLog.error(`Unable to access xcodebuild log file: '${err.message}'`); - } - } + this.xcodebuild.removeAllListeners(); this.didProcessExit = true; if (this._didBuildFail || (!signal && code !== 0)) { - return reject(new Error(`xcodebuild failed with code ${code}\n` + - `xcodebuild error message:\n${xcodeErrorMessage}`)); + let errorMessage = `xcodebuild failed with code ${code}.` + + ` This usually indicates an issue with the local Xcode setup or WebDriverAgent` + + ` project configuration or the driver-to-platform version mismatch.`; + if (!this.showXcodeLog) { + errorMessage += ` Consider setting 'showXcodeLog' capability to true in` + + ` order to check the Appium server log for build-related error messages.`; + } else if (this.realDevice) { + errorMessage += ` Consider checking the WebDriverAgent configuration guide` + + ` for real iOS devices at` + + ` https://github.com/appium/appium-xcuitest-driver/blob/master/docs/real-device-config.md.`; + } + return reject(new Error(errorMessage)); } // in the case of just building, the process will exit and that is our finish if (buildOnly) { @@ -385,7 +354,6 @@ class XcodeBuild { return (async () => { try { const timer = new timing.Timer().start(); - // @ts-ignore this.xcodebuild must be defined await this.xcodebuild.start(true); if (!buildOnly) { let status = await this.waitForStart(timer); From 0267f49da7c8f2637c5d6e936ae3f90b6fd934a6 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 24 Nov 2023 18:04:50 +0000 Subject: [PATCH 231/240] chore(release): 5.15.3 [skip ci] ## [5.15.3](https://github.com/appium/WebDriverAgent/compare/v5.15.2...v5.15.3) (2023-11-24) ### Miscellaneous Chores * Make xcodebuild error message more helpful ([#816](https://github.com/appium/WebDriverAgent/issues/816)) ([2d7fc03](https://github.com/appium/WebDriverAgent/commit/2d7fc0370b30e5e3adc9a13002fa95f607c4c160)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87c1177aa..324828e67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.15.3](https://github.com/appium/WebDriverAgent/compare/v5.15.2...v5.15.3) (2023-11-24) + + +### Miscellaneous Chores + +* Make xcodebuild error message more helpful ([#816](https://github.com/appium/WebDriverAgent/issues/816)) ([2d7fc03](https://github.com/appium/WebDriverAgent/commit/2d7fc0370b30e5e3adc9a13002fa95f607c4c160)) + ## [5.15.2](https://github.com/appium/WebDriverAgent/compare/v5.15.1...v5.15.2) (2023-11-23) diff --git a/package.json b/package.json index ac2e671fb..bb4b9740f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.15.2", + "version": "5.15.3", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 357a2cbca106daf42bc892b251802bfa00895598 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Thu, 7 Dec 2023 09:15:39 -0800 Subject: [PATCH 232/240] fix: set appearance in iOS 17+ (#818) * fix: set appearance in iOS 17+ * only xcode 15+ * set proper clang version * simplify * fix Xcode warning --- WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m b/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m index 5f138f381..b0b008348 100644 --- a/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m +++ b/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m @@ -339,6 +339,16 @@ - (BOOL)fb_setAppearance:(FBUIInterfaceAppearance)appearance error:(NSError **)e [invocation invoke]; return YES; } + +#if __clang_major__ >= 15 || (__clang_major__ >= 14 && __clang_minor__ >= 0 && __clang_patchlevel__ >= 3) + // Xcode 14.3.1 can build these values. + // For iOS 17+ + if ([self respondsToSelector:NSSelectorFromString(@"appearance")]) { + self.appearance = (XCUIDeviceAppearance) appearance; + return YES; + } +#endif + return [[[FBErrorBuilder builder] withDescriptionFormat:@"Current Xcode SDK does not support appearance changing"] buildError:error]; From 4ac009e616e7b0888c58989e1fe5a925835678fb Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 7 Dec 2023 17:22:07 +0000 Subject: [PATCH 233/240] chore(release): 5.15.4 [skip ci] ## [5.15.4](https://github.com/appium/WebDriverAgent/compare/v5.15.3...v5.15.4) (2023-12-07) ### Bug Fixes * set appearance in iOS 17+ ([#818](https://github.com/appium/WebDriverAgent/issues/818)) ([357a2cb](https://github.com/appium/WebDriverAgent/commit/357a2cbca106daf42bc892b251802bfa00895598)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 324828e67..98a0f22d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.15.4](https://github.com/appium/WebDriverAgent/compare/v5.15.3...v5.15.4) (2023-12-07) + + +### Bug Fixes + +* set appearance in iOS 17+ ([#818](https://github.com/appium/WebDriverAgent/issues/818)) ([357a2cb](https://github.com/appium/WebDriverAgent/commit/357a2cbca106daf42bc892b251802bfa00895598)) + ## [5.15.3](https://github.com/appium/WebDriverAgent/compare/v5.15.2...v5.15.3) (2023-11-24) diff --git a/package.json b/package.json index bb4b9740f..73702b7f8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.15.3", + "version": "5.15.4", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 296c19b96210b6d8660099a2b6c7f30797144bc0 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sat, 9 Dec 2023 08:46:25 -0800 Subject: [PATCH 234/240] ci: tune trigger of .azure-pipelines.yml --- .azure-pipelines.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index 864c786f0..a324a9b7d 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -16,6 +16,15 @@ variables: MAX_IPAD_DEVICE_NAME: iPad Pro (11-inch) (3rd generation) DEFAULT_NODE_VERSION: "18.x" +trigger: + batch: true + branches: + include: [master] + +pr: + autoCancel: true + branches: + include: [master] pool: vmImage: "$(MAX_VM_IMAGE)" From de124e1bb02a5897da7b1b99cb6fbfc5569ab6bd Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sat, 9 Dec 2023 23:11:05 -0800 Subject: [PATCH 235/240] ci: use ruby 3 (#821) * ci: use ruby 3 * set output type to not use result bundle * try no multi_scan * adjust params * ci: make build fail when test fails --- Fastlane/Fastfile | 28 +++------------------------- Fastlane/Pluginfile | 2 -- Gemfile | 4 +--- azure-templates/bootstrap_steps.yml | 2 +- 4 files changed, 5 insertions(+), 31 deletions(-) diff --git a/Fastlane/Fastfile b/Fastlane/Fastfile index 39bb9f491..41fd63669 100644 --- a/Fastlane/Fastfile +++ b/Fastlane/Fastfile @@ -1,34 +1,12 @@ XC_PROJECT = File.absolute_path('../WebDriverAgent.xcodeproj') -RETRIES = 3 lane :test do - test_run_block = lambda do |testrun_info| - failed_test_count = testrun_info[:failed].size - - if failed_test_count > 0 - UI.important("Failed tests count: #{failed_test_count}") - - try_attempt = testrun_info[:try_count] - if try_attempt < RETRIES - UI.header("Re-running failing tests (attempt #{try_attempt} of #{RETRIES})") - reset_simulator_contents - end - end - end - # https://docs.fastlane.tools/actions/scan/ - result = multi_scan( + run_tests( project: XC_PROJECT, - try_count: RETRIES, - fail_build: false, + fail_build: true, scheme: ENV['SCHEME'], sdk: ENV['SDK'], destination: ENV['DEST'], - testrun_completed_block: test_run_block ) - unless result[:failed_testcount].zero? - msg = "There are #{result[:failed_testcount]} legitimate failing tests" - UI.message(msg) - raise msg - end -end \ No newline at end of file +end diff --git a/Fastlane/Pluginfile b/Fastlane/Pluginfile index dc2f2aa91..273a6b6f4 100644 --- a/Fastlane/Pluginfile +++ b/Fastlane/Pluginfile @@ -1,5 +1,3 @@ # Autogenerated by fastlane # # Ensure this file is checked in to source control! - -gem 'fastlane-plugin-test_center', '3.15.3' diff --git a/Gemfile b/Gemfile index f8456a949..90c93561d 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,3 @@ source "https://rubygems.org" -gem "fastlane", '2.162.0' -plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') -eval_gemfile(plugins_path) if File.exist?(plugins_path) +gem "fastlane", '2.217.0' diff --git a/azure-templates/bootstrap_steps.yml b/azure-templates/bootstrap_steps.yml index 83847eb74..6c96e9ead 100644 --- a/azure-templates/bootstrap_steps.yml +++ b/azure-templates/bootstrap_steps.yml @@ -3,5 +3,5 @@ steps: - script: mkdir -p ./Resources/WebDriverAgent.bundle - task: UseRubyVersion@0 inputs: - versionSpec: '<3.0' + versionSpec: '3' addToPath: true From 89e233d8aef5a19491785fee0823fd8eddbd5fcc Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Tue, 12 Dec 2023 19:26:14 -0800 Subject: [PATCH 236/240] chore: use appearance for get as well if available (#825) --- WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m b/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m index b0b008348..959ae2831 100644 --- a/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m +++ b/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m @@ -356,6 +356,14 @@ - (BOOL)fb_setAppearance:(FBUIInterfaceAppearance)appearance error:(NSError **)e - (NSNumber *)fb_getAppearance { +#if __clang_major__ >= 15 || (__clang_major__ >= 14 && __clang_minor__ >= 0 && __clang_patchlevel__ >= 3) + // Xcode 14.3.1 can build these values. + // For iOS 17+ + if ([self respondsToSelector:NSSelectorFromString(@"appearance")]) { + return [NSNumber numberWithLongLong:[self appearance]]; + } +#endif + return [self respondsToSelector:@selector(appearanceMode)] ? [NSNumber numberWithLongLong:[self appearanceMode]] : nil; From 3e506a9ac244ea9afedef9f63e600a3bb90bfd38 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 13 Dec 2023 03:33:01 +0000 Subject: [PATCH 237/240] chore(release): 5.15.5 [skip ci] ## [5.15.5](https://github.com/appium/WebDriverAgent/compare/v5.15.4...v5.15.5) (2023-12-13) ### Miscellaneous Chores * use appearance for get as well if available ([#825](https://github.com/appium/WebDriverAgent/issues/825)) ([89e233d](https://github.com/appium/WebDriverAgent/commit/89e233d8aef5a19491785fee0823fd8eddbd5fcc)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98a0f22d0..e4eb6d86a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.15.5](https://github.com/appium/WebDriverAgent/compare/v5.15.4...v5.15.5) (2023-12-13) + + +### Miscellaneous Chores + +* use appearance for get as well if available ([#825](https://github.com/appium/WebDriverAgent/issues/825)) ([89e233d](https://github.com/appium/WebDriverAgent/commit/89e233d8aef5a19491785fee0823fd8eddbd5fcc)) + ## [5.15.4](https://github.com/appium/WebDriverAgent/compare/v5.15.3...v5.15.4) (2023-12-07) diff --git a/package.json b/package.json index 73702b7f8..e5927c1fb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "appium-webdriveragent", - "version": "5.15.4", + "version": "5.15.5", "description": "Package bundling WebDriverAgent", "main": "./build/index.js", "scripts": { From 3480bd4667fdfffbd2771519862c37f53aef1e70 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Thu, 14 Dec 2023 19:01:21 -0800 Subject: [PATCH 238/240] ci: teak tests (#824) * ci: teak tests * ci: skip one test to reduce flakiness * ci: skip some tests for ipad * use UIDevice * ci: skip long press * use number_of_retries to add -test-iterations and -retry-tests-on-failure for xcodebuild --- Fastlane/Fastfile | 1 + Fastlane/Pluginfile | 3 --- .../IntegrationTests/FBAlertTests.m | 3 +++ .../FBAppiumTouchActionsIntegrationTests.m | 3 +++ .../IntegrationTests/FBElementSwipingTests.m | 6 ++++++ .../IntegrationTests/FBKeyboardTests.m | 3 +++ WebDriverAgentTests/IntegrationTests/FBTapTest.m | 15 ++++++++++----- .../FBW3CTouchActionsIntegrationTests.m | 3 +++ 8 files changed, 29 insertions(+), 8 deletions(-) delete mode 100644 Fastlane/Pluginfile diff --git a/Fastlane/Fastfile b/Fastlane/Fastfile index 41fd63669..6e657a74e 100644 --- a/Fastlane/Fastfile +++ b/Fastlane/Fastfile @@ -8,5 +8,6 @@ lane :test do scheme: ENV['SCHEME'], sdk: ENV['SDK'], destination: ENV['DEST'], + number_of_retries: 3 ) end diff --git a/Fastlane/Pluginfile b/Fastlane/Pluginfile deleted file mode 100644 index 273a6b6f4..000000000 --- a/Fastlane/Pluginfile +++ /dev/null @@ -1,3 +0,0 @@ -# Autogenerated by fastlane -# -# Ensure this file is checked in to source control! diff --git a/WebDriverAgentTests/IntegrationTests/FBAlertTests.m b/WebDriverAgentTests/IntegrationTests/FBAlertTests.m index 57c48e492..3729c4d54 100644 --- a/WebDriverAgentTests/IntegrationTests/FBAlertTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBAlertTests.m @@ -154,8 +154,11 @@ - (void)testNotificationAlert XCTAssertTrue([alert.text containsString:@"Notifications may include"]); } +// It worked locally but CI did not. - (void)testCameraRollAlert { + XCTSkip(@"The alert depends on the permission condition. Azure CI env might have an issue to handle permission."); + FBAlert *alert = [FBAlert alertWithApplication:self.testedApplication]; XCTAssertNil(alert.text); diff --git a/WebDriverAgentTests/IntegrationTests/FBAppiumTouchActionsIntegrationTests.m b/WebDriverAgentTests/IntegrationTests/FBAppiumTouchActionsIntegrationTests.m index d48b3da77..51525e435 100644 --- a/WebDriverAgentTests/IntegrationTests/FBAppiumTouchActionsIntegrationTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBAppiumTouchActionsIntegrationTests.m @@ -244,6 +244,9 @@ - (void)testPress - (void)testLongPress { + if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) { + XCTSkip(@"Failed on Azure Pipeline. Local run succeeded."); + } UIDeviceOrientation orientation = UIDeviceOrientationLandscapeLeft; [[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:orientation]; CGRect elementFrame = self.testedApplication.buttons[FBShowAlertButtonName].frame; diff --git a/WebDriverAgentTests/IntegrationTests/FBElementSwipingTests.m b/WebDriverAgentTests/IntegrationTests/FBElementSwipingTests.m index caf5d9020..0a9d2f5c4 100644 --- a/WebDriverAgentTests/IntegrationTests/FBElementSwipingTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBElementSwipingTests.m @@ -67,6 +67,9 @@ - (void)testSwipeDown - (void)testSwipeDownWithVelocity { + if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) { + XCTSkip(@"Failed on Azure Pipeline. Local run succeeded."); + } [self.scrollView fb_swipeWithDirection:@"up" velocity:@2500]; FBAssertInvisibleCell(@"0"); [self.scrollView fb_swipeWithDirection:@"down" velocity:@2500]; @@ -113,6 +116,9 @@ - (void)testSwipeDown - (void)testSwipeDownWithVelocity { + if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) { + XCTSkip(@"Failed on Azure Pipeline. Local run succeeded."); + } [self.testedApplication fb_swipeWithDirection:@"up" velocity:@2500]; FBAssertInvisibleCell(@"0"); [self.testedApplication fb_swipeWithDirection:@"down" velocity:@2500]; diff --git a/WebDriverAgentTests/IntegrationTests/FBKeyboardTests.m b/WebDriverAgentTests/IntegrationTests/FBKeyboardTests.m index 3da52e370..beca0c791 100644 --- a/WebDriverAgentTests/IntegrationTests/FBKeyboardTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBKeyboardTests.m @@ -29,6 +29,9 @@ - (void)setUp - (void)testTextTyping { + if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) { + XCTSkip(@"Failed on Azure Pipeline. Local run succeeded."); + } NSString *text = @"Happy typing"; XCUIElement *textField = self.testedApplication.textFields[@"aIdentifier"]; [textField tap]; diff --git a/WebDriverAgentTests/IntegrationTests/FBTapTest.m b/WebDriverAgentTests/IntegrationTests/FBTapTest.m index 9dce4084c..5b79711fc 100644 --- a/WebDriverAgentTests/IntegrationTests/FBTapTest.m +++ b/WebDriverAgentTests/IntegrationTests/FBTapTest.m @@ -33,12 +33,10 @@ - (void)verifyTapWithOrientation:(UIDeviceOrientation)orientation - (void)setUp { + // Launch the app everytime to ensure the orientation for each test. [super setUp]; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - [self launchApplication]; - [self goToAlertsPage]; - }); + [self launchApplication]; + [self goToAlertsPage]; [self clearAlert]; } @@ -61,11 +59,15 @@ - (void)testTapInLandscapeLeft - (void)testTapInLandscapeRight { + [self verifyTapWithOrientation:UIDeviceOrientationLandscapeRight]; } - (void)testTapInPortraitUpsideDown { + if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) { + XCTSkip(@"Failed on Azure Pipeline. Local run succeeded."); + } [self verifyTapWithOrientation:UIDeviceOrientationPortraitUpsideDown]; } @@ -94,6 +96,9 @@ - (void)testTapCoordinatesInLandscapeRight - (void)testTapCoordinatesInPortraitUpsideDown { + if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) { + XCTSkip(@"Failed on Azure Pipeline. Local run succeeded."); + } [self verifyTapByCoordinatesWithOrientation:UIDeviceOrientationPortraitUpsideDown]; } diff --git a/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m b/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m index 8549d3016..598cc66c9 100644 --- a/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m @@ -338,6 +338,9 @@ - (void)testLongPressWithCombinedPause - (void)testLongPress { + if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) { + XCTSkip(@"Failed on Azure Pipeline. Local run succeeded."); + } UIDeviceOrientation orientation = UIDeviceOrientationLandscapeLeft; [[XCUIDevice sharedDevice] fb_setDeviceInterfaceOrientation:orientation]; CGRect elementFrame = self.testedApplication.buttons[FBShowAlertButtonName].frame; From 766be59ef31753f4029c57c7a13cc01b1312cb9e Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sun, 17 Dec 2023 07:59:54 -0800 Subject: [PATCH 239/240] ci: tune testCameraRollAlert for CI env (#828) --- WebDriverAgentTests/IntegrationTests/FBAlertTests.m | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/WebDriverAgentTests/IntegrationTests/FBAlertTests.m b/WebDriverAgentTests/IntegrationTests/FBAlertTests.m index 3729c4d54..a7cf04418 100644 --- a/WebDriverAgentTests/IntegrationTests/FBAlertTests.m +++ b/WebDriverAgentTests/IntegrationTests/FBAlertTests.m @@ -154,21 +154,22 @@ - (void)testNotificationAlert XCTAssertTrue([alert.text containsString:@"Notifications may include"]); } -// It worked locally but CI did not. +// This test case depends on the local app permission state. - (void)testCameraRollAlert { - XCTSkip(@"The alert depends on the permission condition. Azure CI env might have an issue to handle permission."); - FBAlert *alert = [FBAlert alertWithApplication:self.testedApplication]; XCTAssertNil(alert.text); [self.testedApplication.buttons[@"Create Camera Roll Alert"] tap]; FBAssertWaitTillBecomesTrue(alert.isPresent); - XCTAssertTrue([alert.text containsString:@"Would Like to Access Your Photos"]); + // "Would Like to Access Your Photos" or "Would Like to Access Your Photo Library" displayes on the alert button. + XCTAssertTrue([alert.text containsString:@"Would Like to Access Your Photo"]); // iOS 15 has different UI flow if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) { [[FBAlert alertWithApplication:self.testedApplication] dismissWithError:nil]; + // CI env could take longer time to show up the button, thus it needs to wait a bit. + XCTAssertTrue([self.testedApplication.buttons[@"Cancel"] waitForExistenceWithTimeout:30.0]); [self.testedApplication.buttons[@"Cancel"] tap]; } } From 654db992df7816aaa667bfe02a6e465ebbdf3ed4 Mon Sep 17 00:00:00 2001 From: liuxiaodong Date: Thu, 21 Dec 2023 17:30:22 +0800 Subject: [PATCH 240/240] merge --- WebDriverAgent.xcodeproj/project.pbxproj | 8 ++-- .../Commands/FBScreenshotCommands.m | 14 +++++- .../Commands/UUElementCommands.m | 44 ------------------- WebDriverAgentLib/FBAlert.h | 4 -- WebDriverAgentLib/FBAlert.m | 41 ----------------- 5 files changed, 16 insertions(+), 95 deletions(-) diff --git a/WebDriverAgent.xcodeproj/project.pbxproj b/WebDriverAgent.xcodeproj/project.pbxproj index 96878d22b..4579803c8 100644 --- a/WebDriverAgent.xcodeproj/project.pbxproj +++ b/WebDriverAgent.xcodeproj/project.pbxproj @@ -4348,7 +4348,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = 7J7278KZZ5; + DEVELOPMENT_TEAM = VDZ6WAVGC2; INFOPLIST_FILE = WebDriverAgentTests/IntegrationApp/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -4368,7 +4368,7 @@ CLANG_ANALYZER_NONNULL = YES; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 7J7278KZZ5; + DEVELOPMENT_TEAM = VDZ6WAVGC2; INFOPLIST_FILE = WebDriverAgentTests/IntegrationApp/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -4429,7 +4429,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = 7J7278KZZ5; + DEVELOPMENT_TEAM = VDZ6WAVGC2; ENABLE_TESTING_SEARCH_PATHS = YES; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = WebDriverAgentRunner/Info.plist; @@ -4487,7 +4487,7 @@ CLANG_STATIC_ANALYZER_MODE = deep; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 7J7278KZZ5; + DEVELOPMENT_TEAM = VDZ6WAVGC2; ENABLE_TESTING_SEARCH_PATHS = YES; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = WebDriverAgentRunner/Info.plist; diff --git a/WebDriverAgentLib/Commands/FBScreenshotCommands.m b/WebDriverAgentLib/Commands/FBScreenshotCommands.m index 7457b2b9b..a39d1cc30 100644 --- a/WebDriverAgentLib/Commands/FBScreenshotCommands.m +++ b/WebDriverAgentLib/Commands/FBScreenshotCommands.m @@ -24,9 +24,9 @@ #import "FBLogger.h" #import "FBScreenshot.h" #import "FBMacros.h" -#import "FBImageIOScaler.h" #import "FBConfiguration.h" #import "FBErrorBuilder.h" +#import "FBImageProcessor.h" static const NSTimeInterval SCREENSHOT_TIMEOUT = 0.5; @@ -94,7 +94,7 @@ + (NSArray *)routes rect = CGRectNull; } - if ([FBScreenshot isNewScreenshotAPISupported]) { + if ([FBScreenshotCommands isNewScreenshotAPISupported]) { id proxy = [FBXCTestDaemonsProxy testRunnerProxy]; __block NSError *innerError = nil; dispatch_semaphore_t sem = dispatch_semaphore_create(0); @@ -306,5 +306,15 @@ + (nullable NSData *)jpegDataWithImage:(CGImageRef)imageRef return newImageData; } ++ (BOOL)isNewScreenshotAPISupported +{ + static dispatch_once_t newScreenshotAPISupported; + static BOOL result; + dispatch_once(&newScreenshotAPISupported, ^{ + result = [(NSObject *)[FBXCTestDaemonsProxy testRunnerProxy] respondsToSelector:@selector(_XCT_requestScreenshotOfScreenWithID:withRect:uti:compressionQuality:withReply:)]; + }); + return result; +} + @end diff --git a/WebDriverAgentLib/Commands/UUElementCommands.m b/WebDriverAgentLib/Commands/UUElementCommands.m index 15df64a98..e10ca698f 100644 --- a/WebDriverAgentLib/Commands/UUElementCommands.m +++ b/WebDriverAgentLib/Commands/UUElementCommands.m @@ -31,7 +31,6 @@ #import "XCUIElement+FBIsVisible.h" #import "XCUIElement+FBPickerWheel.h" #import "XCUIElement+FBScrolling.h" -#import "XCUIElement+FBTap.h" #import "XCUIElement+FBTyping.h" #import "XCUIElement+FBUtilities.h" #import "XCUIElement+FBWebDriverAttributes.h" @@ -203,46 +202,6 @@ + (NSArray *)routes { return FBResponseWithOK(); } -+ (id)uuDealAlert:(FBRouteRequest *)request { - FBApplication *application = request.session.activeApplication ?: [FBApplication fb_activeApplication]; - FBAlert *alert = [FBAlert alertWithApplication:application]; - NSError *error; - NSInteger counts = 0; - while (alert.isPresent && counts < 10) { - [alert uuAcceptWithError:&error]; - alert = [FBAlert alertWithApplication:application]; - counts += 1; - } - if (error) { - return FBResponseWithUnknownError(error); - } - return FBResponseWithOK(); -} - -+ (id)uuDealAlertWithParam:(FBRouteRequest *)request { - FBApplication *application = request.session.activeApplication ?: [FBApplication fb_activeApplication]; - BOOL accept = [request.arguments[@"accept"] boolValue]; - FBAlert *alert = [FBAlert alertWithApplication:application]; - if (nil == alert) { - return FBResponseWithOK(); - } - NSError *error; - NSInteger counts = 0; - while (alert.isPresent && counts < 10) { - if (accept) { - [alert uuAcceptWithError:&error]; - } else { - [alert uuDismissWithError:&error]; - } - alert = [FBAlert alertWithApplication:application]; - counts += 1; - } - if (error) { - return FBResponseWithUnknownError(error); - } - return FBResponseWithOK(); -} - + (id)uuGetSysInfo:(FBRouteRequest *)request { [[BatteryInfoManager sharedManager] startBatteryMonitoring]; @@ -581,9 +540,6 @@ screen orientation is different from the default one (which is portrait). */ + (XCUICoordinate *)uuGestureCoordinateWithCoordinate:(CGPoint)coordinate application:(XCUIApplication *)application shouldApplyOrientationWorkaround:(BOOL)shouldApplyOrientationWorkaround { CGPoint point = coordinate; - if (shouldApplyOrientationWorkaround) { - point = FBInvertPointForApplication(coordinate, application.frame.size, application.interfaceOrientation); - } XCUICoordinate *appCoordinate = [[XCUICoordinate alloc] initWithElement:application normalizedOffset:CGVectorMake(0, 0)]; return [[XCUICoordinate alloc] initWithCoordinate:appCoordinate pointsOffset:CGVectorMake(point.x, point.y)]; } diff --git a/WebDriverAgentLib/FBAlert.h b/WebDriverAgentLib/FBAlert.h index 2d9bf48e4..22f28a710 100644 --- a/WebDriverAgentLib/FBAlert.h +++ b/WebDriverAgentLib/FBAlert.h @@ -56,8 +56,6 @@ NS_ASSUME_NONNULL_BEGIN */ - (BOOL)acceptWithError:(NSError **)error; -- (BOOL)uuAcceptWithError:(NSError **)error; - /** Dismisses alert, if present @@ -66,8 +64,6 @@ NS_ASSUME_NONNULL_BEGIN */ - (BOOL)dismissWithError:(NSError **)error; -- (BOOL)uuDismissWithError:(NSError **)error; - /** Clicks on an alert button, if present diff --git a/WebDriverAgentLib/FBAlert.m b/WebDriverAgentLib/FBAlert.m index c4e47c200..ff6b98c74 100644 --- a/WebDriverAgentLib/FBAlert.m +++ b/WebDriverAgentLib/FBAlert.m @@ -276,45 +276,4 @@ - (XCUIElement *)alertElement } -- (BOOL)uuAcceptWithError:(NSError **)error -{ - XCUIElement *alertElement = self.alertElement; - NSArray *buttons = [alertElement descendantsMatchingType:XCUIElementTypeButton].allElementsBoundByIndex; - - XCUIElement *defaultButton; - if (alertElement.elementType == XCUIElementTypeAlert && [buttons count] < 3) { - defaultButton = buttons.lastObject; - } else { - defaultButton = buttons.firstObject; - } - if (!defaultButton) { - return - [[[FBErrorBuilder builder] - withDescriptionFormat:@"Failed to find accept button for alert: %@", alertElement] - buildError:error]; - } - return [defaultButton fb_tapWithError:error]; -} - -- (BOOL)uuDismissWithError:(NSError **)error -{ - XCUIElement *cancelButton; - XCUIElement *alertElement = self.alertElement; - NSArray *buttons = [alertElement descendantsMatchingType:XCUIElementTypeButton].allElementsBoundByIndex; - - if (alertElement.elementType == XCUIElementTypeAlert) { - cancelButton = buttons.firstObject; - } else { - cancelButton = buttons.lastObject; - } - if (!cancelButton) { - return - [[[FBErrorBuilder builder] - withDescriptionFormat:@"Failed to find dismiss button for alert: %@", alertElement] - buildError:error]; - return NO; - } - return [cancelButton fb_tapWithError:error]; -} - @end