Skip to content

Commit

Permalink
feat: add increase contrast and content size commands (#2520)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
KazuCocoa authored Jan 29, 2025
1 parent 1cbd80e commit a3fc183
Show file tree
Hide file tree
Showing 9 changed files with 293 additions and 3 deletions.
74 changes: 74 additions & 0 deletions docs/reference/execute-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
70 changes: 70 additions & 0 deletions lib/commands/content-size.js
Original file line number Diff line number Diff line change
@@ -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<ContentSizeResult>} 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
*/
52 changes: 52 additions & 0 deletions lib/commands/increase-contrast.js
Original file line number Diff line number Diff line change
@@ -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<IncreaseContrastResult>} 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
*/
4 changes: 4 additions & 0 deletions lib/commands/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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';
Expand Down Expand Up @@ -55,6 +57,7 @@ export default {
certificateExtensions,
clipboardExtensions,
conditionExtensions,
contentSizeExtensions,
contextExtensions,
deviceInfoExtensions,
elementExtensions,
Expand All @@ -64,6 +67,7 @@ export default {
generalExtensions,
geolocationExtensions,
gestureExtensions,
increaseContrastExtensions,
iohidExtensions,
keychainsExtensions,
keyboardExtensions,
Expand Down
54 changes: 54 additions & 0 deletions lib/commands/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 14 additions & 0 deletions lib/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
+------------+*/
Expand Down
18 changes: 18 additions & 0 deletions lib/execute-method-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
6 changes: 5 additions & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -536,4 +539,5 @@ export {

/**
* @typedef {import('appium-xcode').XcodeVersion} XcodeVersion
* @typedef {import('appium-ios-simulator').Simulator} Simulator
*/
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down

0 comments on commit a3fc183

Please sign in to comment.