UITest User Guide
Overview
UITest provides UI search and operation simulation capabilities for key scenarios of automated UI tests, including accurate UI component search, UI interaction operations (such as tap, swipe, and text input), and peripheral behavior simulation (such as keyboard input, mouse operation, touchpad gesture, and stylus action).
Capabilities
UITest supports both ArkTS APIs and commands, providing flexible and efficient technical support for automated UI tests.
ArkTS script development: UITest provides simple and easy-to-use APIs for various test scenarios. It supports common UI interaction operations, such as tap, double-tap, long press, and swipe, helping you quickly develop automated test scripts based on UI interaction logic.
Command line testing: UITest supports diversified test operations through commands, including obtaining the current screen screenshot, obtaining the component tree, recording the screen operation process, and easily injecting UI simulation events.
UITest consists of the client and server.
Client: Provides a cross-language communication layer and IPC module to export APIs and launch UITest. The client is loaded by the test application and runs in the application process. The cross-language communication layer exports APIs, processes JSON serialization objects, converts ArkTS APIs into C++ APIs, and parses and verifies parameters. In addition, this module involves invoking ArkTS callback functions from the C++ layer. Therefore, the cross-language communication layer manages and invokes ArkTS callbacks.
Server: Runs as an independent process and communicates with the client through IPC. After the server starts, it establishes a connection with the client through broadcast. The IPC ensures that the connection is not interrupted. The server listens for the client process status and starts or stops the client process as required. The server processes the core logic of UITest, which consists of the following parts:
- General framework running capability: processes IPC messages, manages processes, C++ APIs, and error codes, and listens for API calling.
- UI test capability: parses accessibility nodes to build a page component tree, matches and searches for components, constructs operation events, injects multimodal events, listens for UI events, and controls screen display.
Using ArkTS APIs to Perform UI Tests
The following describes how to use the ArkTS APIs of UITest.
The UITest API is called based on JsUnit. For details about the APIs and parameters, see @ohos.UiTest.
UI Test Example
The following example describes how to develop a UI test based on the JsUnit script. The functionalities are as follows:
- Call the AbilityDelegator capability to start the target application and check the application running status.
- Call the UITest capability to perform a tap operation on the page.
- Add an assertion to check whether the actual changes on the current page are as expected.
Perform the following steps:
-
Write the clickToAfter.ets page code in the main > ets > pages folder as the test demo.
@Entry @Component struct Index { @State message: string = 'Hello World'; @State text: string = ''; build() { Row() { Column() { Text(this.message) .fontSize(50) .fontWeight(FontWeight.Bold) Text('Next') .fontSize(50) .margin({ top: 20 }) .fontWeight(FontWeight.Bold) .onClick((event?: ClickEvent) => { if (event) { this.text = 'after click'; } }) .width('100%') Text(this.text).margin(15) } } .height('100%') } } -
Create the test file in the ohosTest > ets > test folder and write the test code.
import { describe, expect, it, Level } from '@ohos/hypium'; // Import the test dependencies. import { abilityDelegatorRegistry, Driver, ON } from '@kit.TestKit'; import { UIAbility, Want } from '@kit.AbilityKit'; const delegator: abilityDelegatorRegistry.AbilityDelegator = abilityDelegatorRegistry.getAbilityDelegator(); export default function abilityTest() { describe('ActsAbilityTest', () => { it('testUiExample', Level.LEVEL3, async (done: Function) => { // Initialize the Driver object. const driver = Driver.create(); const bundleName = abilityDelegatorRegistry.getArguments().bundleName; // Specify the bundle name and ability name of the application to be tested. const want: Want = { bundleName: bundleName, abilityName: 'EntryAbility' } // Start the application to be tested. await delegator.startAbility(want); // Wait until the application starts. await driver.waitForIdle(4000, 5000); // Ensure that the top ability of the application is the specified ability. const ability: UIAbility = await delegator.getCurrentTopAbility(); expect(ability.context.abilityInfo.name).assertEqual('EntryAbility'); // Search for the target component based on the specified text Next. const next = await driver.findComponent(ON.text('Next')); // Tap the target component. await next.click(); await driver.waitForIdle(4000, 5000); // Assert the component with text "after click" exists to ensure the page changes as expected. await driver.assertComponentExist(ON.text('after click')); await driver.pressBack(); done(); }) }) }
Searching for and Operating Components
With UITest, you can create a matcher based on attributes to search for one or more target components on the current page and return the component object. You can also search for target component inside the scroll component and operate component objects or obtain component attributes.
The following example shows how to search for and operate a component. Before executing the following code, implement the code of the Index.ets page by referring to "UI Test Example".
import { describe, it, TestType } from '@ohos/hypium';
// Import the test dependencies.
import { Component, Driver, ON, On } from '@kit.TestKit';
export default function abilityTest() {
describe('componentOperationTest', () => {
/**
* Search for the Button component and click it.
*/
it('componentSearchAndOperation', TestType.FUNCTION, async () => {
let driver: Driver = Driver.create();
await driver.delayMs(1000);
let button: Component = await driver.findComponent(ON.type('Button'));
await button.click();
})
/**
* Search for the Scroll component whose text is '123' using relative position.
*/
it('relativePositioncomponentSearch', TestType.FUNCTION, async () => {
let driver: Driver = Driver.create();
let on: On = ON.text('123').within(ON.type('Scroll'));
let items: Array<Component> = await driver.findComponents(on);
})
/**
* Search for the Image component and pinch it out.
*/
it('componentPinch', TestType.FUNCTION, async () => {
let driver: Driver = Driver.create();
let image: Component = await driver.findComponent(ON.type('Image'));
await image.pinchOut(1.5);
})
})
}
Simulating Touch Operations
UITest supports simulating events such as tap, double-tap, long press, swipe, drag, and multi-finger operations.
The following example shows how to simulate touch operations at the coordinate level. Before executing the following code, implement the Index.ets page code by referring to "UI Test Example".
import { describe, it, Level, Size, TestType } from '@ohos/hypium';
// Import the test dependencies.
import { Driver, PointerMatrix, UiDirection } from '@kit.TestKit';
export default function abilityTest() {
describe('touchScreen_sample', () => {
/**
* Simulate touch operations based on coordinates.
*/
it('touchScreenOperation', TestType.FUNCTION, async () => {
let driver: Driver = Driver.create();
// Tap.
await driver.click(100, 100);
// Tap on a specified display. This method is supported since API version 20.
await driver.clickAt({ x: 100, y: 100, displayId: 0 });
// Swipe.
await driver.swipe(100, 100, 200, 200, 600);
// Swipe on a specified display. This method is supported since API version 20.
await driver.swipeBetween({ x: 100, y: 100, displayId: 0 }, { x: 1000, y: 1000, displayId: 0 }, 800);
// Fling.
await driver.fling({ x: 100, y: 100 }, { x: 200, y: 200 }, 5, 600);
// Fling in a specified direction.
await driver.fling(UiDirection.DOWN, 10000);
// Drag.
await driver.drag(100, 100, 200, 200, 600);
// Specify the display ID and the long-press time before dragging. This method is supported since API version 20.
await driver.dragBetween({ x: 100, y: 100, displayId: 0 }, { x: 1000, y: 1000, displayId: 0 }, 800, 1500);
// Simulate a two-finger operation, with each finger scrolling based on two coordinates.
let pointers: PointerMatrix = PointerMatrix.create(2, 2);
pointers.setPoint(0, 0, { x: 100, y: 100 });
pointers.setPoint(0, 1, { x: 200, y: 100 });
pointers.setPoint(1, 0, { x: 100, y: 200 });
pointers.setPoint(1, 1, { x: 200, y: 200 });
await driver.injectMultiPointerAction(pointers);
})
})
}
Waiting for Page Loading Completion
When interacting with a page, you can determine whether the page redirection is complete by waiting for a component to appear or waiting for the page to be idle within a specified period of time.
The following example describes how to wait for page loading completion. Before executing the following code, implement the Index.ets page code by referring to "UI Test Example".
import { describe, it, Level, Size, TestType } from '@ohos/hypium';
// Import the test dependencies.
import { abilityDelegatorRegistry, Driver, ON } from '@kit.TestKit';
const delegator: abilityDelegatorRegistry.AbilityDelegator = abilityDelegatorRegistry.getAbilityDelegator();
// Specify the bundle name and ability name of the application to be tested.
const bundleName: string = 'com.uitestScene.acts';
const abilityName: string = 'com.uitestScene.acts.MainAbility';
export default function abilityTest() {
describe('waitForComp_sample', () => {
it('testWaitForComponent_static', TestType.FUNCTION | Size.MEDIUMTEST | Level.LEVEL3,
async (done: Function): Promise<void> => {
let driver = Driver.create();
// Start the target application.
await delegator.executeShellCommand(`aa start -b ${bundleName} -a ${abilityName}`).then(result => {
}).catch((err: Error) => {
done();
})
// Wait for the specified component on the target application's home screen to appear, confirming that the application has started.
let button = await driver.waitForComponent(ON.text('StartAbility Success!'), 1000);
})
})
}
Simulating Text Input
UITest supports text input at a specified coordinate or to a specified component. Specified input mode is also supported, that is, whether to copy and paste the text or add the text.
The following example describes how to input text based on components and coordinates. Before running the following code, implement the Index.ets page code by referring to "UI Test Example".
import { describe, it, Level, Size, TestType } from '@ohos/hypium';
// Import the test dependencies.
import { Driver, ON } from '@kit.TestKit';
export default function abilityTest() {
describe('inputTextTest', () => {
/**
* Clear the text by default and then inputs the specified text based on the component.
* If the input text does not contain Chinese characters or special characters and its length does not exceed 200 characters, it is input word by word by default.
*/
it('componentInputText', TestType.FUNCTION, async () => {
let driver = Driver.create();
let input = await driver.findComponent(ON.type('TextInput'));
await input.inputText('abc');
})
/**
* Inject specified text in copy and paste mode based on the component.
* Input text in addition mode. That is, the original content is not cleared when the text is input.
*/
it('componentInputTextAddition', TestType.FUNCTION, async () => {
let driver = Driver.create();
let input = await driver.findComponent(ON.type('TextInput'));
// This API is supported since API version 20.
await input.inputText('abc', { paste: true, addition: true });
})
/**
* Focus the text box by tapping the specified position and input the specified text at the cursor based on the coordinates.
* If the input text does not contain Chinese characters or special characters and its length does not exceed 200 characters, it is input word by word by default.
*/
it('pointInputText', TestType.FUNCTION | Size.MEDIUMTEST | Level.LEVEL3, async () => {
let driver = Driver.create();
let input = await driver.findComponent(ON.type('TextInput'));
let center = await input.getBoundsCenter();
await driver.inputText(center, 'abc');
})
/**
* Inject specified text in copy and paste mode based on the coordinates.
* Input in addition mode, that is, after the text box is focused by tapping the specified position, the cursor is moved to the end of the original text and then the specified text is input.
*/
it('pointInputTextAddition', TestType.FUNCTION | Size.MEDIUMTEST | Level.LEVEL3, async () => {
let driver = Driver.create();
let input = await driver.findComponent(ON.type('TextInput'));
let center = await input.getBoundsCenter();
// This API is supported since API version 20.
await driver.inputText(center, '123', { paste: true, addition: true });
})
/**
* Inject specified text in copy and paste mode based on the coordinates.
* Input in addition mode, that is, after the text box is focused by tapping the specified position, the cursor is moved to the end of the original text and then the specified text is input.
* If the input content contains Chinese characters or special characters, the text can be input only in copy and paste mode, and the paste field does not take effect.
*/
it('pointInputTextChinese', TestType.FUNCTION | Size.MEDIUMTEST | Level.LEVEL3, async () => {
let driver = Driver.create();
let input = await driver.findComponent(ON.type('TextInput'));
let center = await input.getBoundsCenter();
// This API is supported since API version 20.
await driver.inputText(center, 'Hello', { paste: false, addition: true });
})
})
}
Capturing Screenshots
Note:
- You need to specify the path for saving screenshots to the sandbox directory of the application.
- The Ability Privilege Level (APL) of the test HAP is normal. Therefore, the application sandbox path in the user-level encryption area must be used. In addition, the file should be saved in the subdirectory for saving the application's persistent data on the device.
The following example shows how to capture a screenshot with the display ID and area specified and save the screenshot to a specified path. Before running the following code, implement the Index.ets page code by referring to "UI Test Example". In the multi-display scenario, to capture a screenshot of a specified display, you can call the API of the display module to obtain the display object, and then obtain display properties.
import { describe, it, Level, Size, TestType } from '@ohos/hypium';
// Import the test dependencies.
import { Driver } from '@kit.TestKit';
import { display } from '@kit.ArkUI';
export default function abilityTest() {
describe('screenCap_sample', () => {
/**
* Capture the screen of a specified area and save the screenshot to a specified path.
*/
it('screenCapture', TestType.FUNCTION, async () => {
let driver = Driver.create();
// Application sandbox path. el2 indicates the user-level encryption, and base indicates the subdirectory for saving the application's persistent data on the device.
// Use the actual path.
let savePath = '/data/storage/el2/base/cache/1.png';
let res = await driver.screenCapture(savePath, {
left: 0,
top: 0,
right: 100,
bottom: 100
});
})
/**
* Capture the full screen based on the specified display ID and save it to the specified path.
*/
it('screenCapWithId', TestType.FUNCTION | Size.MEDIUMTEST | Level.LEVEL3, async () => {
let driver = Driver.create();
// Obtain the default display object.
let disPlay = display.getDefaultDisplaySync();
let savePath = '/data/storage/el2/base/cache/1.png';
// This method is supported since API version 20.
let res = await driver.screenCap(savePath, disPlay.id); // Obtain the default display ID.
})
})
}
Listening for UI Events
The following example describes how to listen for UI events, including setting the listening callback, listening for the Toast and Dialog components, and proceeding after an event occurs. Before running the following code, implement the Index.ets page code by referring to "UI Test Example".
import { describe, it, TestType } from '@ohos/hypium';
// Import the test dependencies.
import { Driver, UIElementInfo } from '@kit.TestKit';
export default function abilityTest() {
describe('eventObserver_sample', () => {
// Listen for the display of the Toast component.
it('toastObserver', TestType.FUNCTION, async () => {
let driver = Driver.create();
let observer = driver.createUIEventObserver();
let callback = (uiElementInfo: UIElementInfo) => {
let bundleName = uiElementInfo.bundleName;
let text = uiElementInfo.text;
let type = uiElementInfo.type;
}
observer.once('toastShow', callback);
})
})
}
Simulating Keyboard and Mouse Operations
The following example describes how to simulate keyboard and mouse operations, including single key and combination key input, mouse click, move, and drag, and key and mouse combination operations. Before running the following code, implement the Index.ets page code by referring to "UI Test Example".
import { describe, it, Level, Size, TestType } from '@ohos/hypium';
// Import the test dependencies.
import { Driver, MouseButton } from '@kit.TestKit';
import { KeyCode } from '@kit.InputKit';
export default function abilityTest() {
describe('mouseAndKey_sample', () => {
// Simulate key input and combination key input.
it('keyBoardOperation', TestType.FUNCTION | Size.MEDIUMTEST | Level.LEVEL3, async () => {
let driver = Driver.create();
// Simulate key input (inject the Back key).
await driver.triggerKey(KeyCode.KEYCODE_BACK);
// Simulate combination key input (inject the Save combination key).
await driver.triggerCombineKeys(KeyCode.KEYCODE_CTRL_LEFT, KeyCode.KEYCODE_S);
})
// Simulate the operations of left-clicking, moving, and dragging the mouse.
it('mouseOperation', TestType.FUNCTION | Size.MEDIUMTEST | Level.LEVEL3, async () => {
let driver = Driver.create();
// Left-click the mouse.
await driver.mouseClick({ x: 100, y: 100 }, MouseButton.MOUSE_BUTTON_LEFT);
// Move the mouse.
await driver.mouseMoveTo({ x: 100, y: 100 });
// Drag the mouse.
await driver.mouseDrag({ x: 100, y: 100 }, { x: 200, y: 200 }, 600);
})
// Simulate key and mouse combination operations.
it('combinedOperation', TestType.FUNCTION | Size.MEDIUMTEST | Level.LEVEL3, async () => {
let driver = Driver.create();
// Press the left Ctrl key and scroll the mouse wheel.
await driver.mouseScroll({ x: 100, y: 100 }, true, 30, KeyCode.KEYCODE_CTRL_LEFT);
// Press the left Ctrl key and long-click the left mouse button.
await driver.mouseLongClick({ x: 100, y: 100 }, MouseButton.MOUSE_BUTTON_LEFT, KeyCode.KEYCODE_CTRL_LEFT);
})
})
}
Searching for and Operating Windows
The following example describes how to search for and minimize a window based on the window properties. Before running the following code, implement the Index.ets page code by referring to "UI Test Example".
import { describe, expect, it, TestType } from '@ohos/hypium';
// Import the test dependencies.
import { Driver } from '@kit.TestKit';
// Error code when the device is not supported.
const DeviceErrorCode = 17000005;
export default function abilityTest() {
describe('findWindowAndOp_sample', () => {
// Search for an active window based on specified properties and minimize the window.
it('windowSearchAndOperation', TestType.FUNCTION, async () => {
let driver = Driver.create();
try {
let window = await driver.findWindow({ active: true });
await window.minimize();
} catch (error) {
// If the minimize API is called on a device that does not support window operations, the 17000005 error code will be thrown.
expect(error.code).assertEqual(DeviceErrorCode);
}
})
})
}
Simulating Touchpad Operations
The following example describes how to simulate the touchpad operations of swiping up with three fingers to return to the home screen and swiping down with three fingers to return to the application window. Before running the following code, implement the Index.ets page code by referring to "UI Test Example".
import { describe, expect, it, Level, Size, TestType } from '@ohos/hypium';
// Import the test dependencies.
import { Driver, UiDirection } from '@kit.TestKit';
// Error code when the device is not supported.
const DeviceErrorCode = 17000005;
export default function abilityTest() {
describe('touchPadOp_sample', () => {
// Simulate the three-finger swipe up (to return to the home screen) and three-finger swipe down (to restore the window) operations on the touchpad in the PC/2-in-1 device.
it('touchPadOperation', TestType.FUNCTION | Size.MEDIUMTEST | Level.LEVEL3, async () => {
let driver = Driver.create();
try {
// Swipe up with three fingers to return to the home screen.
await driver.touchPadMultiFingerSwipe(3, UiDirection.UP);
// Swipe down with three fingers to restore the application window.
await driver.touchPadMultiFingerSwipe(3, UiDirection.DOWN);
} catch (error) {
// If this API is called on a device that does not support touchpad operations, the 17000005 error code will be thrown.
expect(error.code).assertEqual(DeviceErrorCode);
}
})
})
}
Simulating Stylus Operations
The following example describes how to simulate stylus operations such as clicking, swiping, and setting pressure. Before running the following code, implement the Index.ets page code by referring to "UI Test Example".
import { describe, it, Level, Size, TestType } from '@ohos/hypium';
// Import the test dependencies.
import { Driver } from '@kit.TestKit';
export default function abilityTest() {
describe('penOp_sample', () => {
// Simulate stylus operations such as click, double-click, long-click, and swipe.
it('penOperation', TestType.FUNCTION | Size.MEDIUMTEST | Level.LEVEL3, async () => {
let driver = Driver.create();
// Click with the stylus.
await driver.penClick({ x: 100, y: 100 });
// Double-click with the stylus.
await driver.penDoubleClick({ x: 100, y: 100 });
// Long-click with the stylus.
await driver.penLongClick({ x: 100, y: 100 }, 0.5);
// Swipe with the stylus.
await driver.penSwipe({ x: 100, y: 100 }, { x: 100, y: 500 }, 600, 0.5);
})
})
}
Simulating Crown Operations
The following example shows how to simulate clockwise and counter-clockwise crown rotations. Before running the following code, implement the Index.ets page code by referring to "UI Test Example".
import { describe, expect, it, Level, Size, TestType } from '@ohos/hypium';
// Import the test dependencies.
import { Driver } from '@kit.TestKit';
// Error code when the device is not supported.
const CapabilityCode = 801;
export default function abilityTest() {
describe('watchOp_sample', () => {
// Simulate clockwise and counter-clockwise crown rotations. This API is supported since API version 20.
it('crownRotate', TestType.FUNCTION | Size.MEDIUMTEST | Level.LEVEL3, async () => {
let driver = Driver.create();
try {
// Rotate 50 ticks clockwise at a speed of 30 ticks per second.
await driver.crownRotate(50, 30);
// Rotate 20 ticks counterclockwise at a speed of 30 ticks per second.
await driver.crownRotate(-20, 30);
} catch (error) {
// driver.crownRotate is valid only on smart watches. If it is called on other devices, error code 801 will be thrown.
expect(error.code).assertEqual(CapabilityCode);
}
})
})
}
Simulating Display Operations
The following example shows how to simulate display operations, including obtaining display properties such as size and density, waking up the display, and rotating it. Before running the following code, implement the Index.ets page code by referring to "UI Test Example".
import { describe, it, Level, Size, TestType } from '@ohos/hypium';
// Import the test dependencies.
import { DisplayRotation, Driver, Point } from '@kit.TestKit';
export default function abilityTest() {
describe('displayOp_sample', () => {
// Obtain display properties and operate the display.
it('displayOperation', TestType.FUNCTION | Size.MEDIUMTEST | Level.LEVEL3, async () => {
let driver = Driver.create();
// Obtain the display size.
let size: Point = await driver.getDisplaySize();
// Obtain the display density.
let density: Point = await driver.getDisplayDensity();
// Wake up the display.
await driver.wakeUpDisplay();
// Rotate the display clockwise by 90 degrees.
await driver.setDisplayRotation(DisplayRotation.ROTATION_90);
})
})
}
Using Commands to Perform UI Tests
During development, you can use commands to quickly perform test operations such as capturing screenshots, recording UI operations, injecting UI simulation operations, and obtaining the component tree.
Environment Setup
The environment for OpenHarmony Device Connector (hdc) has been set up. For details, see Environment Setup. The devices are properly connected and hdc shell is executed.
Commands
| Command | Parameter | Description |
|---|---|---|
| help | - | Displays the commands supported by the UITest tool. |
| screenCap | [-p] [-d] | Captures a screenshot. For details about the parameters, see Obtaining a Screenshot. |
| dumpLayout | [-p] <-i | -a | -b | -w | -m | -d> | Obtains the component tree. For details about the parameters, see Obtaining the Component Tree. |
| uiRecord | <record | read> | Records UI operations. record: starts recording the operations on the current page to /data/local/tmp/record.csv. To stop recording, press Ctrl+C. read: reads and prints recorded data. For details about the parameters, see Recording UI Operations. |
| uiInput | <help | click | doubleClick | longClick | fling | swipe | drag | dircFling | inputText | keyEvent | text> | Injects UI simulation operations. For details about the parameters, see Injecting UI Simulation Operations. |
| --version | - | Obtains the version information about the current UITest tool. |
| start-daemon | - | Starts the UITest process. |
Obtaining a Screenshot
| Parameter | Level-2 Parameter | Description |
|---|---|---|
| -p | <savePath> | Used to specify storage path and file name, which must be /data/local/tmp/. The default path is /data/local/tmp, and the file name format is Timestamp+.png. |
| -d | <displayId> | Used to specify the ID of the display to capture in the multi-display scenario. Note: This command is supported since API version 20. |
# Save the file in the format of Timestamp + .png in /data/local/tmp.
hdc shell uitest screenCap
# Specify the file name and save the file in /data/local/tmp/.
hdc shell uitest screenCap -p /data/local/tmp/1.png
Obtaining the Component Tree
| Parameter | Level-2 Parameter | Description |
|---|---|---|
| -p | <savePath> | Used to specify storage path and file name, which must be /data/local/tmp/. The default path is /data/local/tmp, and the file name format is Timestamp+.json. |
| -i | - | Used to disable filtering of invisible components and window merging. |
| -a | - | Used to save the BackgroundColor, Content, FontColor, FontSize, and extraAttrs attributes of the component. Note: By default, the preceding attributes are not saved. The -a and -i parameters cannot be used at the same time. |
| -b | <bundleName> | Used to obtain the component tree information of the target window based on the specified bundle name. |
| -w | <windowId> | Used to obtain the component tree information of the target window based on the specified window ID. Note: You can use hidumper to obtain the window ID of an application. For details, see Obtaining Application Window Information. |
| -m | <true|false> | Used to specify whether to merge the window information when the component tree information is obtained. The value true means to merge window information, and false means the opposite. If this parameter is not set, the default value true is used. |
| -d | <displayId> | Used to specify the ID of the display whose component tree is to be obtained in the multi-display scenario. Note: 1. This command is supported since API version 20. 2. You can use hidumper to obtain the display ID of an application. For details, see Obtaining Application Window Information. |
# Specify the file name and save the file in /data/local/tmp/.
hdc shell uitest dumpLayout -p /data/local/tmp/1.json
Recording UI Operations
NOTE
During the recording, you should perform the next operation after the recognition result of the current operation is displayed in the CLI.
Parameters
| Parameter | Level-2 Parameter | Description |
|---|---|---|
| -W | <true/false> | Used to specify whether to save the component information corresponding to the operation coordinates to the /data/local/tmp/record.csv file during recording. The value true means to save the component information, and false means to record only the coordinate information. The default value is true. Note: This command is supported since API version 20. |
| -l | - | Used to save the current layout information after each operation. The file storage path is /data/local/tmp/layout_Recording start timestamp_Operation ID.json. Note: This command is supported since API version 20. |
| -c | <true/false> | Used to specify whether to print the recorded operation event information to the console. The value true means to print the information, and false means the opposite. The default value is true. Note: This command is supported since API version 20. |
# Record the current UI operations to /data/local/tmp/record.csv and press Ctrl+C to stop the recording.
hdc shell uitest uiRecord record
# Record only the coordinates of the operation and do not match the target component.
hdc shell uitest uiRecord record -W false
# Save the page layout in /data/local/tmp/layout_Recording start timestamp_Operation ID.json after each operation.
hdc shell uitest uiRecord record -l
# Do not print the recorded operation event information to the console.
hdc shell uitest uiRecord record -c false
# Read and print record data.
hdc shell uitest uiRecord read
The fields in the record data are as follows:
{
"ABILITY": "com.ohos.launcher.MainAbility", // Ability name of the target application.
"BUNDLE": "com.ohos.launcher", // Bundle name of the target application.
"CENTER_X": "", // Reserved field.
"CENTER_Y": "", // Reserved field.
"EVENT_TYPE": "pointer", // Operation type.
"LENGTH": "0", // Total length.
"OP_TYPE": "click", // Event type. Currently, click, double-click, long-press, drag, pinch, swipe, and fling events are supported.
"VELO": "0.000000", // Hands-off velocity.
"direction.X": "0.000000",// Movement along the x-axis.
"direction.Y": "0.000000", // Movement along the y-axis.
"duration": 33885000.0, // Gesture duration.
"fingerList": [{
"LENGTH": "0", // Total length.
"MAX_VEL": "40000", // Maximum velocity.
"VELO": "0.000000", // Hands-off velocity.
"W1_BOUNDS": "{"bottom":361,"left":37,"right":118,"top":280}", // Bounds of the start component.
"W1_HIER": "ROOT,3,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0", // Page level of the start component.
"W1_ID": "", // ID of the start component.
"W1_Text": "", // Text of the start component.
"W1_Type": "Image", // Type of the start component.
"W2_BOUNDS": "{"bottom":361,"left":37,"right":118,"top":280}", // Bounds of the end component.
"W2_HIER": "ROOT,3,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0", // Page level of the end component.
"W2_ID": "", // ID of the end component.
"W2_Text": "", // Text of the end component.
"W2_Type": "Image", // Type of the end component.
"X2_POSI": "47", // X coordinate of the end point.
"X_POSI": "47", // X coordinate of the start point.
"Y2_POSI": "301", // Y coordinate of the end point.
"Y_POSI": "301", // Y coordinate of the start point.
"direction.X": "0.000000", // Movement along the x-axis.
"direction.Y": "0.000000" // Movement along the y-axis.
}],
"fingerNumber": "1" // Number of fingers.
}
Injecting UI Simulation Operations
| Parameter | Description |
|---|---|
| help | Used to display the help information about the uiInput command. |
| click | Used to simulate a click. For details, see Examples of Running the uiInput-click/doubleClick/longClick Command. |
| doubleClick | Used to simulate a double-click. For details, see Examples of Running the uiInput click/doubleClick/longClick Command. |
| longClick | Used to simulate a long-click. For details, see Examples of Running the uiInput click/doubleClick/longClick Command. |
| fling | Used to simulate a fling. That is, the page scrolls inertially after the operation is complete. For details, see Examples of Running the uiInput fling Command. |
| swipe | Used to simulate a swipe. For details, see Examples of Running the uiInput swipe/drag Command. |
| drag | Used to simulate a drag. For details, see Examples of Running the uiInput swipe/drag Command. |
| dircFling | Used to simulate a directional fling. For details, see Examples of Running the uiInput dircFling Command. |
| inputText | Used to simulate text input in a text box at specified coordinates. For details, see Examples of Running the uiInput inputText Command. |
| text | Used to simulate text input in a text box at the focused position without specified coordinates. For details, see Examples of Running the uiInput text Command. Note: This command is supported since API version 18. |
| keyEvent | Used to simulate a physical key event (such as pressing a keyboard key, pressing the power key, returning to the previous page, and returning to the home screen) or a combination key operation. For details, see Examples of Running the uiInput keyEvent Command. |
- Example of Running the click/doubleClick/longClick Command
| Parameter | Mandatory | Description |
|---|---|---|
| point_x | Yes | X-coordinate point to click. |
| point_y | Yes | Y-coordinate point to click. |
# Execute the click event.
hdc shell uitest uiInput click 100 100
# Execute the double-click event.
hdc shell uitest uiInput doubleClick 100 100
# Execute a long-click event.
hdc shell uitest uiInput longClick 100 100
- Example of Running the uiInput fling Command
| Parameter | Mandatory | Description |
|---|---|---|
| from_x | Yes | X-coordinate of the start point. |
| from_y | Yes | Y-coordinate of the start point. |
| to_x | Yes | X-coordinate of the end point. |
| to_y | Yes | Y-coordinate of the end point. |
| swipeVelocityPps_ | No | Swipe speed, in px/s. The value ranges from 200 to 40000. Default value: 600. If the value is out of the range, the default value is used. |
| stepLength_ | No | Step length, in pixels. The default value is the swipe distance divided by 50. Note: The swipe distance is calculated based on the specified start and end coordinates. To achieve better simulation effect, you are advised to use the default value. |
# Execute the fling operation with the default stepLength_ value.
hdc shell uitest uiInput fling 10 10 200 200 500
- Example of Running the uiInput swipe/drag Command
| Parameter | Mandatory | Description |
|---|---|---|
| from_x | Yes | X-coordinate of the start point. |
| from_y | Yes | Y-coordinate of the start point. |
| to_x | Yes | X-coordinate of the end point. |
| to_y | Yes | Y-coordinate of the end point. |
| swipeVelocityPps_ | No | Swipe speed, in px/s. The value ranges from 200 to 40000. Default value: 600. If the value is out of the range, the default value is used. |
# Execute the swipe operation.
hdc shell uitest uiInput swipe 10 10 200 200 500
# Execute the drag operation.
hdc shell uitest uiInput drag 10 10 100 100 500
- Example of Running the uiInput dircFling Command
| Parameter | Mandatory | Description |
|---|---|---|
| direction | No | Swipe direction, which can be 0, 1, 2, or 3. The default value is 0. The value 0 indicates leftward, 1 indicates rightward, 2 indicates upward, and 3 indicates downward. |
| swipeVelocityPps_ | No | Swipe speed, in px/s. The value ranges from 200 to 40000. Default value: 600. If the value is out of the range, the default value is used. |
| stepLength | No | Step length, in pixels. Default value: When the swipe direction is 0 or 1, the default value is the screen width divided by 200. When the swipe direction is 2 or 3, the default value is the screen height divided by 200. To achieve better simulation effect, you are advised to use the default value. |
# Execute the leftward fling operation.
hdc shell uitest uiInput dircFling 0 500
# Execute the rightward fling operation.
hdc shell uitest uiInput dircFling 1 600
# Execute the upward fling operation.
hdc shell uitest uiInput dircFling 2
# Execute the downward fling operation.
hdc shell uitest uiInput dircFling 3
- Example of Running the uiInput inputText Command
| Parameter | Mandatory | Description |
|---|---|---|
| point_x | Yes | X-coordinate of the text box. |
| point_y | Yes | Y-coordinate of the text box. |
| text | Yes | Text in the text box. |
# Execute the text input operation.
hdc shell uitest uiInput inputText 100 100 hello
- Example of Running the uiInput text Command
| Parameter | Mandatory | Description |
|---|---|---|
| text | Yes | Text in the text box. |
# Execute the text input operation at the focused position. If the current focused position does not support text input, the operation does not take effect.
hdc shell uitest uiInput text hello
- Example of Running the uiInput keyEvent Command
| Parameter | Mandatory | Description |
|---|---|---|
| keyID1 | Yes | ID of a physical key, which can be Back, Home, Power, or a keycode value. When the value is set to Back, Home, or Power, combination keys are not supported. Currently, the Caps Lock key (KeyCode = 2074) does not take effect. Use composition keys to input uppercase letters. For example, press Shift+V to input uppercase letter V. |
| keyID2 | No | ID of the physical key. For details about the value range, see KeyCode. This parameter is left empty by default. |
| keyID3 | No | ID of the physical key. For details about the value range, see KeyCode. This parameter is left empty by default. |
# Back to home page.
hdc shell uitest uiInput keyEvent Home
# Back to the previous page.
hdc shell uitest uiInput keyEvent Back
# Use combination keys to paste.
hdc shell uitest uiInput keyEvent 2072 2038
# Input the lowercase letter v.
hdc shell uitest uiInput keyEvent 2038
# Input the uppercase letter V.
hdc shell uitest uiInput keyEvent 2047 2038
Obtain the version information.
hdc shell uitest --version
Starting the UItest Process
NOTE
The UITest capability can be called only by the test HAP started by ability via aa test, and the Ability Privilege Level (APL) of the test HAP must be normal.
hdc shell uitest start-daemon
UI Test Script Examples
Example of Searching for Specified Components
For details about how to search for a component in an application UI by specifying the attributes of the component, see Example of Searching for Specified Components.
Example of Simulating Click Events
For details about how to simulate the click, long-click or double-click event, see Example of Simulating Click Events.
Example of Simulating Mouse Events
For details about how to simulate the left-click, right-click, or scroll event using a mouse, see Example of Simulating Mouse Events.
Example of Simulating Text Input Events
For details about how to simulate Chinese and English text input, see Example of Simulating Text Input Events.
Example of Simulating Screenshot Capture Events
For details about how to simulate capturing a screenshot (in a specified area), see Example of Simulating Screenshot Capture Events.
Example of Simulating Fling Events
For details about how to simulate a fling event (the finger leaves the screen after swiping), see Example of Simulating Fling Events.
Example of Simulating Swipe Events
For details about how to simulate a swipe event (the finger stays on the screen after swiping), see Example of Simulating Swipe Events.
Example of Simulating Pinch Events
For details about how to simulate a zoom-in and zoom-out operation on pictures, see Example of Simulating Pinch Events.
Example of Simulating Scroll Events
For details about how to simulate components scrolling, see Example of Simulating Scroll Events.
Example of Searching for Specified Windows
For details about how to search for an application window based on the bundle name, see Example of Searching for Specified Windows.
Example of Simulating Window Movement Events
For details about how to simulate the window movement to a specified position, see Example of Simulating Window Movement Events.
Example of Simulating Window Size Adjustments
For details about how to simulate a window size adjustment in a specified direction, see Example of Simulating Window Size Adjustments.
FAQs
What should I do if the failure log contains "uitest-api does not allow calling concurrently"?
Symptom
The UI test fails. The HiLog file contains the error message "uitest-api does not allow calling concurrently".
Possible Causes
- The await syntax sugar is not added to the asynchronous API provided by UITest.
- The UI test case is executed in multiple processes. As a result, multiple UITest processes are started, which is not supported.
Solution
- Check the case implementation and add the await syntax sugar to the asynchronous API.
- Do not execute UI test cases in multiple processes.
What should I do if the failure log contains "does not exist on current UI! Check if the UI has changed after you got the widget object"?
Symptom
The UI test case fails. The HiLog file contains the error message "does not exist on current UI! Check if the UI has changed after you got the widget object".
Possible Causes
After the target component is found, the device UI changes, resulting in component loss and simulation failure.
Solution
Run the UI test case again to ensure that the component exists on the UI during the simulation operation.
What should I do if the failure log contains "Cannot connect to AAMS, RET_ERR_CONNECTION_EXIST"?
Symptom
The UI test case fails. The HiLog contains the error message "Cannot connect to AAMS, RET_ERR_CONNECTION_EXIST".
Possible Causes
Other test tools that depend on UITest are used during the case execution.
Solution
Disable the test tools that depend on UITest or restart the device.