From a3fc18322fcded1842acf7ce7d56ad82cb4312ca Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Wed, 29 Jan 2025 14:28:28 -0800 Subject: [PATCH 1/3] feat: add increase contrast and content size commands (#2520) * feat: add content size stuff * add increase contrast and documents * case insensitive was fine * add doc * bump ios simulator * fix lint * Update execute-methods.md * rename command names * return simulator instance * remove redundant lines * reflect review * remove redundant * * address simulator only --- docs/reference/execute-methods.md | 74 +++++++++++++++++++++++++++++++ lib/commands/content-size.js | 70 +++++++++++++++++++++++++++++ lib/commands/increase-contrast.js | 52 ++++++++++++++++++++++ lib/commands/index.js | 4 ++ lib/commands/types.ts | 54 ++++++++++++++++++++++ lib/driver.js | 14 ++++++ lib/execute-method-map.ts | 18 ++++++++ lib/utils.js | 6 ++- package.json | 4 +- 9 files changed, 293 insertions(+), 3 deletions(-) create mode 100644 lib/commands/content-size.js create mode 100644 lib/commands/increase-contrast.js diff --git a/docs/reference/execute-methods.md b/docs/reference/execute-methods.md index a17b0aed4..412143c19 100644 --- a/docs/reference/execute-methods.md +++ b/docs/reference/execute-methods.md @@ -702,6 +702,80 @@ Name | Type | Required | Description | Example --- | --- | --- | --- | --- style | string | yes | Either `light` or `dark` | dark +### mobile: getIncreaseContrast + +Get the device's "increase contrast" accessibility mode. +This API only works on simulators. An exception is thrown if executed with real devices. + +#### Returned Result + +One of below: + +- `enabled`: Increase Contrast is enabled. +- `disabled`: Increase Contrast is disabled. +- `unsupported`: The platform or runtime version does not support the Increase Contrast setting. +- `unknown`: The current setting is unknown or there was an error detecting it. + + +### mobile: setIncreaseContrast + +Enable or disable the device's "increase contrast" accessibility mode. +This API only works on simulators. An exception is thrown if executed with real devices. + +#### Arguments + +Name | Type | Required | Description | Example +--- | --- | --- | --- | --- +increaseContrast | string | yes | Either `enabled` or `disabled` (case insensitive) | 'enabled' + +### mobile: contentSize + +Get the device's content size. +This API only works on simulators. An exception is thrown if executed with real devices. + +#### Returned Result + +One of below: + +- `extra-small` +- `small` +- `medium` +- `large` +- `extra-large` +- `extra-extra-large` +- `extra-extra-extra-large` +- `accessibility-medium` +- `accessibility-large` +- `accessibility-extra-large` +- `accessibility-extra-extra-large` +- `accessibility-extra-extra-extra-large` +- `unknown` +- `unsupported` + +### mobile: setContentSize + +Set the device's content size. +This API only works on simulators. An exception is thrown if executed with real devices. + +#### Arguments + +Name | Type | Required | Description | Example +--- | --- | --- | --- | --- +size | string | yes | One of the content sizes listed below in case-insensitive. | large + +- `extra-small` +- `small` +- `medium` +- `large` +- `extra-large` +- `extra-extra-large` +- `extra-extra-extra-large` +- `accessibility-medium` +- `accessibility-large` +- `accessibility-extra-large` +- `accessibility-extra-extra-large` +- `accessibility-extra-extra-extra-large` + ### mobile: getClipboard Gets the content of the primary clipboard on the device under test. diff --git a/lib/commands/content-size.js b/lib/commands/content-size.js new file mode 100644 index 000000000..75aeb59b1 --- /dev/null +++ b/lib/commands/content-size.js @@ -0,0 +1,70 @@ +import _ from 'lodash'; +import {assertSimulator as _assertSimulator} from '../utils'; +import { errors } from 'appium/driver'; + +const assertSimulator = _.partial(_assertSimulator, 'Content size ui command'); + +const CONTENT_SIZE = [ + 'extra-small', + 'small', + 'medium', + 'large', + 'extra-large', + 'extra-extra-large', + 'extra-extra-extra-large', + 'accessibility-medium', + 'accessibility-large', + 'accessibility-extra-large', + 'accessibility-extra-extra-large', + 'accessibility-extra-extra-extra-large', + 'increment', + 'decrement' +]; + +export default { + /** + * Sets content size for the given simulator. + * + * @since Xcode 15 (but lower xcode could have this command) + * @param {ContentSizeAction} size - The content size action to set. Acceptable value is + * extra-small, small, medium, large, extra-large, extra-extra-large, + * extra-extra-extra-large, accessibility-medium, accessibility-large, + * accessibility-extra-large, accessibility-extra-extra-large, + * accessibility-extra-extra-extra-large with Xcode 16.2. + * @throws {Error} if the current platform does not support content size appearance changes + * @this {XCUITestDriver} + */ + async mobileSetContentSize(size) { + const simulator = assertSimulator(this); + + if (!CONTENT_SIZE.includes(_.lowerCase(size))) { + throw new errors.InvalidArgumentError( + `The 'size' value is expected to be one of ${CONTENT_SIZE.join(',')}` + ); + } + + await simulator.setContentSize(size); + }, + + /** + * Retrieves the current content size value from the given simulator. + * + * @since Xcode 15 (but lower xcode could have this command) + * @returns {Promise} the content size value. Possible return value is + * extra-small, small, medium, large, extra-large, extra-extra-large, + * extra-extra-extra-large, accessibility-medium, accessibility-large, + * accessibility-extra-large, accessibility-extra-extra-large, + * accessibility-extra-extra-extra-large, + * unknown or unsupported with Xcode 16.2. + * @this {XCUITestDriver} + */ + async mobileGetContentSize() { + return /** @type {ContentSizeResult} */ (await assertSimulator(this).getContentSize()); + }, +}; + +/** + * @typedef {import('../driver').XCUITestDriver} XCUITestDriver + * @typedef {import('./types').ContentSizeAction} ContentSizeAction + * @typedef {import('./types').ContentSizeResult} ContentSizeResult + */ diff --git a/lib/commands/increase-contrast.js b/lib/commands/increase-contrast.js new file mode 100644 index 000000000..60305e5ae --- /dev/null +++ b/lib/commands/increase-contrast.js @@ -0,0 +1,52 @@ +import _ from 'lodash'; +import {assertSimulator as _assertSimulator} from '../utils'; +import { errors } from 'appium/driver'; + +const assertSimulator = _.partial(_assertSimulator, 'Content size ui command'); + +const INCREASE_CONTRAST_CONFIG = [ + 'enabled', + 'disabled', +]; + +export default { + /** + * Sets the increase contrast configuration for the given simulator. + * + * @since Xcode 15 (but lower xcode could have this command) + * @param {IncreaseContrastAction} increaseContrast valid increase constrast configuration value. + * Acceptable value is 'enabled' or 'disabled' with Xcode 16.2. + * @throws {Error} if the current platform does not support content size appearance changes + * @this {XCUITestDriver} + */ + async mobileSetIncreaseContrast(increaseContrast) { + const simulator = assertSimulator(this); + + if (!INCREASE_CONTRAST_CONFIG.includes(_.lowerCase(increaseContrast))) { + throw new errors.InvalidArgumentError( + `The 'increaseContrast' value is expected to be one of ${INCREASE_CONTRAST_CONFIG.join(',')}` + ); + } + + await simulator.setIncreaseContrast(increaseContrast); + }, + + /** + * Retrieves the current increase contrast configuration value from the given simulator. + * + * @since Xcode 15 (but lower xcode could have this command) + * @returns {Promise} the contrast configuration value. + * Possible return value is 'enabled', 'disabled', + * 'unsupported' or 'unknown' with Xcode 16.2. + * @this {XCUITestDriver} + */ + async mobileGetIncreaseContrast() { + return /** @type {IncreaseContrastResult} */ (await assertSimulator(this).getIncreaseContrast()); + }, +}; + +/** + * @typedef {import('../driver').XCUITestDriver} XCUITestDriver + * @typedef {import('./types').IncreaseContrastAction} IncreaseContrastAction + * @typedef {import('./types').IncreaseContrastResult} IncreaseContrastResult + */ diff --git a/lib/commands/index.js b/lib/commands/index.js index 8e643c358..8416ae4ba 100644 --- a/lib/commands/index.js +++ b/lib/commands/index.js @@ -9,6 +9,7 @@ import biometricExtensions from './biometric'; import certificateExtensions from './certificate'; import clipboardExtensions from './clipboard'; import conditionExtensions from './condition'; +import contentSizeExtensions from './content-size'; import contextExtensions from './context'; import deviceInfoExtensions from './deviceInfo'; import elementExtensions from './element'; @@ -18,6 +19,7 @@ import findExtensions from './find'; import generalExtensions from './general'; import geolocationExtensions from './geolocation'; import gestureExtensions from './gesture'; +import increaseContrastExtensions from './increase-contrast'; import iohidExtensions from './iohid'; import keychainsExtensions from './keychains'; import keyboardExtensions from './keyboard'; @@ -55,6 +57,7 @@ export default { certificateExtensions, clipboardExtensions, conditionExtensions, + contentSizeExtensions, contextExtensions, deviceInfoExtensions, elementExtensions, @@ -64,6 +67,7 @@ export default { generalExtensions, geolocationExtensions, gestureExtensions, + increaseContrastExtensions, iohidExtensions, keychainsExtensions, keyboardExtensions, diff --git a/lib/commands/types.ts b/lib/commands/types.ts index acb255596..a609480b5 100644 --- a/lib/commands/types.ts +++ b/lib/commands/types.ts @@ -337,6 +337,60 @@ export type ButtonName = AnyCase< */ export type Style = 'dark' | 'light' | 'unsupported' | 'unknown'; +/** + * Returned in the {@linkcode XCUITest.mobileGetIncreaseContrast mobile: getIncreaseContrast} command response. + */ +export type IncreaseContrastResult = + | 'enabled' + | 'disabled' + | 'unsupported' + | 'unknown'; + +/** + * Argument in the {@linkcode XCUITest.mobileSetIncreaseContrast mobile: setIncreaseContrast} command. + */ +export type IncreaseContrastAction = + | 'enabled' + | 'disabled'; + +/** + * Argument in the {@linkcode XCUITest.mobileSetContentSize mobile: setContentSize} command. + */ +export type ContentSizeAction = + | 'extra-small' + | 'small' + | 'medium' + | 'large' + | 'extra-large' + | 'extra-extra-large' + | 'extra-extra-extra-large' + | 'accessibility-medium' + | 'accessibility-large' + | 'accessibility-extra-large' + | 'accessibility-extra-extra-large' + | 'accessibility-extra-extra-extra-large' + | 'increment' + | 'decrement'; + +/** + * Returned in the {@linkcode XCUITest.mobileGetContentSize mobile: getContentSize} command response. + */ +export type ContentSizeResult = + | 'extra-small' + | 'small' + | 'medium' + | 'large' + | 'extra-large' + | 'extra-extra-large' + | 'extra-extra-extra-large' + | 'accessibility-medium' + | 'accessibility-large' + | 'accessibility-extra-large' + | 'accessibility-extra-extra-large' + | 'accessibility-extra-extra-extra-large' + | 'unknown' + | 'unsupported'; + export interface ScreenInfo { /** * Status bar dimensions diff --git a/lib/driver.js b/lib/driver.js index 67d68d72c..19f2d7f0e 100644 --- a/lib/driver.js +++ b/lib/driver.js @@ -1825,6 +1825,20 @@ export class XCUITestDriver extends BaseDriver { mobileSetAppearance = commands.appearanceExtensions.mobileSetAppearance; mobileGetAppearance = commands.appearanceExtensions.mobileGetAppearance; + /*------------+ + | INCREASE CONTRAST | + +------------+*/ + + mobileSetIncreaseContrast = commands.increaseContrastExtensions.mobileSetIncreaseContrast; + mobileGetIncreaseContrast = commands.increaseContrastExtensions.mobileGetIncreaseContrast; + + /*------------+ + | CONTENT SIZE | + +------------+*/ + + mobileSetContentSize = commands.contentSizeExtensions.mobileSetContentSize; + mobileGetContentSize = commands.contentSizeExtensions.mobileGetContentSize; + /*------------+ | AUDIT | +------------+*/ diff --git a/lib/execute-method-map.ts b/lib/execute-method-map.ts index 519149d3f..c960d790d 100644 --- a/lib/execute-method-map.ts +++ b/lib/execute-method-map.ts @@ -333,6 +333,24 @@ export const executeMethodMap = { required: ['style'], }, }, + 'mobile: getIncreaseContrast': { + command: 'mobileGetIncreaseContrast' + }, + 'mobile: setIncreaseContrast': { + command: 'mobileSetIncreaseContrast', + params: { + required: ['increaseContrast'], + }, + }, + 'mobile: contentSize': { + command: 'mobileGetContentSize' + }, + 'mobile: setContentSize': { + command: 'mobileSetContentSize', + params: { + required: ['size'], + }, + }, 'mobile: getClipboard': { command: 'getClipboard', params: { diff --git a/lib/utils.js b/lib/utils.js index 6d2b26728..c5f7108f3 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -466,15 +466,18 @@ function requireArgs(argNames, opts = {}) { } /** - * Asserts that the given driver is running on a Simulator. + * Asserts that the given driver is running on a Simulator and return + * the simlator instance. * * @param {string} action - Description of action * @param {import('./driver').XCUITestDriver} driver + * @returns {Simulator} */ export function assertSimulator(action, driver) { if (!driver.isSimulator()) { throw new Error(`${_.upperFirst(action)} can only be performed on Simulator`); } + return /** @type{Simulator} */ (driver.device); } /** @@ -536,4 +539,5 @@ export { /** * @typedef {import('appium-xcode').XcodeVersion} XcodeVersion + * @typedef {import('appium-ios-simulator').Simulator} Simulator */ diff --git a/package.json b/package.json index c327573d1..524a3d596 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "@colors/colors": "^1.6.0", "appium-idb": "^1.6.13", "appium-ios-device": "^2.8.0", - "appium-ios-simulator": "^6.1.7", + "appium-ios-simulator": "^6.2.0", "appium-remote-debugger": "^12.1.1", "appium-webdriveragent": "^9.0.1", "appium-xcode": "^5.1.4", @@ -92,7 +92,7 @@ "lru-cache": "^10.0.0", "moment": "^2.29.4", "moment-timezone": "^0.x", - "node-simctl": "^7.6.0", + "node-simctl": "^7.7.1", "portscanner": "^2.2.0", "semver": "^7.5.4", "source-map-support": "^0.x", From 2e0bafdf48e94196885463ba11b60abfb9a46d51 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 29 Jan 2025 22:30:14 +0000 Subject: [PATCH 2/3] chore(release): 8.2.0 [skip ci] ## [8.2.0](https://github.com/appium/appium-xcuitest-driver/compare/v8.1.0...v8.2.0) (2025-01-29) ### Features * add increase contrast and content size commands ([#2520](https://github.com/appium/appium-xcuitest-driver/issues/2520)) ([a3fc183](https://github.com/appium/appium-xcuitest-driver/commit/a3fc18322fcded1842acf7ce7d56ad82cb4312ca)) --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cc12a2d1..5b192abf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## [8.2.0](https://github.com/appium/appium-xcuitest-driver/compare/v8.1.0...v8.2.0) (2025-01-29) + +### Features + +* add increase contrast and content size commands ([#2520](https://github.com/appium/appium-xcuitest-driver/issues/2520)) ([a3fc183](https://github.com/appium/appium-xcuitest-driver/commit/a3fc18322fcded1842acf7ce7d56ad82cb4312ca)) + ## [8.1.0](https://github.com/appium/appium-xcuitest-driver/compare/v8.0.0...v8.1.0) (2025-01-21) ### Features diff --git a/package.json b/package.json index 524a3d596..b06a4cc0e 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "xcuitest", "xctest" ], - "version": "8.1.0", + "version": "8.2.0", "author": "Appium Contributors", "license": "Apache-2.0", "repository": { From 2f96435b28d0264d0632db6f02588aa20a16b92e Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 30 Jan 2025 01:59:02 +0100 Subject: [PATCH 3/3] ci: Replace SDK 14.3 with SDK 16.2 in functional tests (#2523) --- .github/workflows/functional-test.yml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/functional-test.yml b/.github/workflows/functional-test.yml index e7814395f..656d021b3 100644 --- a/.github/workflows/functional-test.yml +++ b/.github/workflows/functional-test.yml @@ -30,14 +30,14 @@ jobs: - driver - web - long - xcodeVersion: ['14.3.1', '15.4'] + xcodeVersion: ['16.2', '15.4'] include: - - xcodeVersion: '14.3.1' - iosVersion: '16.4' - deviceName: 'iPhone 14' - tvosVersion: '16.4' + - xcodeVersion: '16.2' + iosVersion: '18.2' + deviceName: 'iPhone 16' + tvosVersion: '18.2' tvosDeviceName: 'Apple TV' - platform: macos-13 + platform: macos-15 - xcodeVersion: '15.4' iosVersion: '17.5' deviceName: 'iPhone 15' @@ -70,13 +70,12 @@ jobs: name: List Runtimes - name: Prepare iOS simulator id: prepareSimulator - uses: futureware-tech/simulator-action@v3 + uses: futureware-tech/simulator-action@v4 with: model: "${{ matrix.deviceName }}" os_version: "${{ matrix.iosVersion }}" shutdown_after_job: false - - run: xcrun simctl bootstatus ${{ steps.prepareSimulator.outputs.udid }} -b - name: Wait for Simulator to finish booting + wait_for_boot: true - run: | npm install --no-save mjpeg-consumer