Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Improve the documentation on unlock #979

Merged
merged 1 commit into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,10 @@ appium:noSign | Set it to `true` in order to skip application signing. By defaul

Capability Name | Description
--- | ---
appium:skipUnlock | Whether to skip the check for lock screen presence (`true`). By default Espresso driver tries to detect if the device's screen is locked before starting the test and to unlock that (which sometimes might be unstable). Note, that this operation takes some time, so it is highly recommended to set this capability to `false` and disable screen locking on devices under test.
appium:unlockType | Set one of the possible types of Android lock screens to unlock. Read the [Unlock tutorial](https://github.com/appium/appium-android-driver/blob/master/docs/UNLOCK.md) for more details.
appium:unlockKey | Allows to set an unlock key. Read the [Unlock tutorial](https://github.com/appium/appium-android-driver/blob/master/docs/UNLOCK.md) for more details.
appium:unlockStrategy | Either 'locksettings' (default) or 'uiautomator'. Setting it to 'uiautomator' will enforce the driver to avoid using special ADB shortcuts in order to speed up the unlock procedure.
appium:unlockSuccessTimeout | Maximum number of milliseconds to wait until the device is unlocked. `2000` ms by default
appium:skipUnlock | Whether to skip the check for lock screen presence (`true`). By default Espresso driver tries to detect if the device's screen is locked before starting the test and to unlock that (which sometimes might be unstable). Note, that this operation takes some time, so it is recommended to set this capability to `false` and disable screen locking on devices under test. Read the [Unlock tutorial](./docs/unlock/main.md) for more details.
appium:unlockType | Set one of the possible types of Android lock screens to unlock. Read the [Unlock tutorial](./docs/unlock/main.md) for more details.
appium:unlockKey | Allows to set an unlock key. Read the [Unlock tutorial](./docs/unlock/main.md) for more details.
appium:unlockSuccessTimeout | Maximum number of milliseconds to wait until the device is unlocked. `2000` ms by default. Read the [Unlock tutorial](./docs/unlock/main.md) for more details.

### Web Context

Expand Down Expand Up @@ -1190,7 +1189,6 @@ Name | Type | Required | Description | Example
--- | --- | --- | --- | ---
key | string | yes | The unlock key. See the documentation on [appium:unlockKey](#device-locking) capability for more details | 12345
type | string | yes | The unlock type. See the documentation on [appium:unlockType](#device-locking) capability for more details | password
strategy | string | no | Unlock strategy. See the documentation on [appium:unlockStrategy](#device-locking) capability for more details | uiautomator
timeoutMs | number | no | Unlock timeout. See the documentation on [appium:unlockSuccessTimeout](#device-locking) capability for more details | 5000

### mobile: isLocked
Expand Down
77 changes: 77 additions & 0 deletions docs/unlock/main.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Unlock

Espresso driver allows dealing with the Android lock screen using various APIs.
This article describes the available APIs and their options.

## Unlock On Session Startup

Espresso driver provides the following [capabilities](../../README.md#device-locking) to deal
with the system lock screen:

- appium:unlockSuccessTimeout
- appium:skipUnlock
- appium:unlockType
- appium:unlockKey

These capabilities could be used to unlock the device under test during the driver session initialization
as well as deal with different lock screen types.

### appium:unlockSuccessTimeout

Maximum number of milliseconds to wait until the device is unlocked. `2000` ms by default

### appium:skipUnlock

The `appium:skipUnlock` capability is enabled by default and makes the driver to detect and handle the lock screen
upon session startup _if it is present_. If the lock screen cannot be detected upon session startup then nothing will be
done. By default, it is assumed the device has a "simple" lock screen, which could be removed by waking up the device.
In case the device has a different type of the lock screen configured in its settings then the information about it
must be provided in the below capability values.

### appium:unlockType and appium:unlockKey

This capability supports the following possible values:

#### pin

Assumes the device is protected with a PIN code. Expects the `appium:unlockKey` to contain a valid pin consisting
of digits in range 0-9, for example `1111`.

#### password

Assumes the device is protected with a password. Expects the `appium:unlockKey` to contain a valid password consisting
of latin characters, for example `abcd1234`.

#### pattern

Assumes the device is protected with a secret pattern. Check the example below for more details on the `appium:unlockKey`
value for this particular unlock type.

##### Example

Let say you have a device that is locked with a pattern similar to the one on the image below,
and you want to run a test over that device.

<img src="./screen1.png" />

We treat the pattern pins similarly to numbers on a digital phone dial. So, in this case the *unlockKey* is `729854163`

<img src="./screen2.png" />

and capabilities are:

```json
{
"appium:unlockType": "pattern",
"appium:unlockKey": "729854163"
}
```

## Mid-Session Unlock

There is also a possibility to interact with the device's lock screen while the test session is running.
Use the following mobile extensions for this purpose:

- [mobile: lock](../../README.md#mobile-lock)
- [mobile: unlock](../../README.md#mobile-unlock)
- [mobile: isLocked](../../README.md#mobile-islocked)
Binary file added docs/unlock/screen1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/unlock/screen2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions lib/commands/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* @this {import('../driver').EspressoDriver}
* @param {import('@appium/types').StringRecord[]} actions
* @returns {Promise<void>}
*/
export async function performActions(actions) {
this.log.debug(`Received the following W3C actions: ${JSON.stringify(actions, null, ' ')}`);
// This is needed because Selenium API uses MOUSE as the default pointer type
const preprocessedActions = actions.map((action) =>
Object.assign(
{},
action,
action.type === 'pointer' ? {parameters: {pointerType: 'touch'}} : {}
)
);
this.log.debug(`Preprocessed actions: ${JSON.stringify(preprocessedActions, null, ' ')}`);
await this.espresso.jwproxy.command('/actions', 'POST', {actions: preprocessedActions});
}
3 changes: 3 additions & 0 deletions lib/driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import * as servicesCmds from './commands/services';
import * as screenshotCmds from './commands/screenshot';
import * as idlingResourcesCmds from './commands/idling-resources';
import * as actionsCmds from './commands/actions';
import { DEFAULT_ADB_PORT } from 'appium-adb';
import { AndroidDriver, utils } from 'appium-android-driver';
import { SETTINGS_HELPER_ID } from 'io.appium.settings';
Expand Down Expand Up @@ -667,19 +668,19 @@
}

// eslint-disable-next-line no-unused-vars
proxyActive (sessionId) {

Check warning on line 671 in lib/driver.ts

View workflow job for this annotation

GitHub Actions / node_test (20)

'sessionId' is defined but never used

Check warning on line 671 in lib/driver.ts

View workflow job for this annotation

GitHub Actions / node_test (18)

'sessionId' is defined but never used

Check warning on line 671 in lib/driver.ts

View workflow job for this annotation

GitHub Actions / node_test (16)

'sessionId' is defined but never used
// we always have an active proxy to the espresso server
return true;
}

// eslint-disable-next-line no-unused-vars
canProxy (sessionId) {

Check warning on line 677 in lib/driver.ts

View workflow job for this annotation

GitHub Actions / node_test (20)

'sessionId' is defined but never used

Check warning on line 677 in lib/driver.ts

View workflow job for this annotation

GitHub Actions / node_test (18)

'sessionId' is defined but never used

Check warning on line 677 in lib/driver.ts

View workflow job for this annotation

GitHub Actions / node_test (16)

'sessionId' is defined but never used
// we can always proxy to the espresso server
return true;
}

// eslint-disable-next-line no-unused-vars
getProxyAvoidList (sessionId) {

Check warning on line 683 in lib/driver.ts

View workflow job for this annotation

GitHub Actions / node_test (20)

'sessionId' is defined but never used

Check warning on line 683 in lib/driver.ts

View workflow job for this annotation

GitHub Actions / node_test (18)

'sessionId' is defined but never used

Check warning on line 683 in lib/driver.ts

View workflow job for this annotation

GitHub Actions / node_test (16)

'sessionId' is defined but never used
// we are maintaining two sets of NO_PROXY lists, one for chromedriver(CHROME_NO_PROXY)
// and one for Espresso(NO_PROXY), based on current context will return related NO_PROXY list
this.jwpProxyAvoid = _.isNil(this.chromedriver) ? NO_PROXY : CHROME_NO_PROXY;
Expand All @@ -697,6 +698,8 @@
return !this.opts.app && this.helpers.isPackageOrBundle(this.opts.appPackage!);
}

performActions = actionsCmds.performActions;

executeMobile = executeCmds.executeMobile;

launchApp = appManagementCmds.launchApp;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
],
"dependencies": {
"appium-adb": "^12.0.0",
"appium-android-driver": "^8.1.6",
"appium-android-driver": "^8.3.0",
"asyncbox": "^3.0.0",
"bluebird": "^3.5.0",
"io.appium.settings": "^5.7.2",
Expand Down
Loading