# Core

> Native mobile apps, used as people use them: launched, or opened with a deep link straight at the screen a scenario tests; their controls tapped and filled, found by the names people see; what they show checked, waiting as apps take their time.

Source: https://axx.nimbusxr.us/references/packs/mobile-core/

Native mobile apps, used as people use them: launched, or opened with a deep link straight at the screen a scenario tests; their controls tapped and filled, found by the names people see; what they show checked, waiting as apps take their time.

The steps every app takes, on a phone or a desktop, are `app-core`'s, which this pack carries out for phones; its own are the steps of phones alone: deep links, the background, swipes, the system's dialogs and notifications. The apps are registered, and run, by the platform packs: `mobile-android` (Android emulators and devices) and, later, `mobile-ios`. They drive the apps through the platforms' own drivers: the UiAutomator2 server on Android, which Axx runs itself, and WebDriverAgent on iOS, through [Appium](https://appium.io); Axx downloads them on first use. **Each scenario has a device to itself, and a clean app:** the platform pack leases a device for the scenario and resets the app, and what it can see, before the scenario starts. Every step names its app, so a scenario can drive two, and use a web app too.

Controls are found by the name people see: a button's text, a field's label, a list item's text. When no name tells a control apart, `id=` (the Android resource ID or the iOS accessibility identifier) or `xpath=` finds it.

Add it to a project with `axx pack add mobile-core`; it builds on [`app-core`](https://axx.nimbusxr.us/references/packs/app-core/), which comes with it.

## Settings

In `axx.yaml`, under `packs.mobile-core`:

| Setting | Takes | Values | Default |
|---|---|---|---|
| `screenshots.folder` | The folder of the apps' screenshots, in the project. Unset, each feature keeps its screenshots in a screenshots folder next to its file. | text | |
| `screenshots.tolerance` | The share of a screenshot's pixels that may differ. | a number, 0 to 1 | `0` |
| `screenshots.update` | Take every screenshot again, as the app looks now, instead of comparing. | `true`, `false` | |
| `traces` | Which scenarios keep a trace of each app in .axx/mobile/traces: its screen after each step, and its controls where it failed. | `failed`, `always`, `never` | `never` |
| `videos` | Which scenarios keep a video in .axx/mobile/videos: their phones as they ran, each touch drawn, with their steps beside them. | `failed`, `always`, `never` | `never` |

## Steps

### `mobile-core.link`

```gherkin
When the {word} app is opened with the {string} link
```

Open a link in the app, as tapping it in another app would: a deep link jumps straight to the screen a scenario tests. The app is launched first when it is not running.

| Parameter | Takes | For example |
|---|---|---|
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |
| `{string}` | text in double or single quotes, which the step leaves out | `"Get a quote"`, `'Express'` |

**Example:**

```gherkin
When the courier app is opened with the "parcels-courier://deliveries/PX-MOB-9401" link
```

_Since 0.1.5._

### `mobile-core.background`

```gherkin
When the {word} app is sent to the background
```

Send the app to the background, as switching to another app does.

| Parameter | Takes | For example |
|---|---|---|
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |

**Example:**

```gherkin
When the courier app is sent to the background
```

_Since 0.1.5._

### `mobile-core.foreground`

```gherkin
When the {word} app is brought back
```

Bring the app back to the front from the background, where it left off.

| Parameter | Takes | For example |
|---|---|---|
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |

**Example:**

```gherkin
When the courier app is brought back
```

_Since 0.1.5._

### `mobile-core.swipe`

```gherkin
When the {word} app is swiped {direction}
```

Swipe across the screen: down, from the top, refreshes a list that pulls to refresh; left and right page through what pages.

| Parameter | Takes | Values | For example |
|---|---|---|---|
| `{word}` | one word, with no spaces |  | `parcels`, `PX-4101` |
| `{direction}` | where a swipe goes, as the finger moves (`down` from the top pulls a list to refresh); or which way a phone moves or turns in the scene its camera sees, where it also moves `forward` and `back` | `up`, `down`, `left`, `right`, `forward`, `back` | `down`, `left` |

**Example:**

```gherkin
When the courier app is swiped down
```

_Since 0.1.5._

### `mobile-core.dialog.accepted`

```gherkin
When the {word} app's dialog is accepted
```

Answer the dialog the system shows over the app, like a request for a permission: accepted allows, dismissed does not. It waits for the dialog. A dialog of the app's own is part of its screen: tap its buttons.

| Parameter | Takes | For example |
|---|---|---|
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |

**Example:**

```gherkin
When the courier app's dialog is accepted
```

_Since 0.1.5._

### `mobile-core.dialog.dismissed`

```gherkin
When the {word} app's dialog is dismissed
```

Answer the dialog the system shows over the app, like a request for a permission: accepted allows, dismissed does not. It waits for the dialog. A dialog of the app's own is part of its screen: tap its buttons.

| Parameter | Takes | For example |
|---|---|---|
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |

**Example:**

```gherkin
When the courier app's dialog is dismissed
```

_Since 0.1.5._

### `mobile-core.dialog.shows`

```gherkin
Then [[within {duration} ]]the {word} app's dialog shows {string}
```

Check the text of the dialog the system shows over the app: it waits for the dialog (10 seconds, or `within`).

| Parameter | Takes | For example |
|---|---|---|
| `{duration}` | a duration in seconds (`s`) or minutes (`m`) | `5s`, `2m` |
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |
| `{string}` | text in double or single quotes, which the step leaves out | `"Get a quote"`, `'Express'` |

**Variants**, the parts in `[[...]]` said or left out:

- `the {word} app's dialog shows {string}`
- `within {duration} the {word} app's dialog shows {string}`

**Example:**

```gherkin
Then the courier app's dialog shows "send you notifications"
```

_Since 0.1.5._

### `mobile-core.camera-sees`

```gherkin
Given the {word} app's camera sees {filepath}
```

The app's camera sees a 3D scene, a glTF file (.glb or .gltf), or an image (PNG or JPEG, and HEIC on iOS) or a video (MP4 or MOV; H.264 on Android), as the phone held upright sees it: Axx plays the camera of an iOS simulator, which has none, and of an Android emulator it starts, and, from a scene, the app's AR. A scene's camera is where the phone is, which the phone's steps move; the app's AR finds the scene's surfaces and objects where they are. A video plays in a loop. A running app starts again, to see it.

| Parameter | Takes | For example |
|---|---|---|
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |
| `{filepath}` | a file of the project: a path relative to the feature file's directory, the `resources` directories or axx.yaml's directory (looked for in that order), or an absolute path, quoted when it has a space | `seeds/parcels.yaml`, `kafka/scan-delivered.json` |

**Example:**

```gherkin
Given the courier app's camera sees scenes/parcel-on-porch.glb
Given the courier app's camera sees labels/label-PX-IOS-9621.png
```

_Since 0.1.5._

### `mobile-core.phone-to-camera`

```gherkin
When the {word} app's phone moves to the scene's {string} camera
```

Put the phone where one of the scene's cameras is, looking the way it looks: a place the scene names, with a camera there. The app's camera sees the scene from there.

| Parameter | Takes | For example |
|---|---|---|
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |
| `{string}` | text in double or single quotes, which the step leaves out | `"Get a quote"`, `'Express'` |

**Example:**

```gherkin
When the courier app's phone moves to the scene's "crouched beside the parcel" camera
```

_Since 0.1.5._

### `mobile-core.phone-path`

```gherkin
When the {word} app's phone {travel} the scene's {string} path[[ at {speed}]]
```

Carry the phone along one of the scene's paths: an animation that moves a camera (the phone's, or another the phone follows), as it was recorded. With no speed, the phone keeps to the animation's own times; `at 2x` goes twice as fast; `at 1.4 m/s` keeps one speed along the way. `travels` waits for the phone to arrive; `starts traveling` lets the scenario go on while it moves, and a later step waits for it to reach the end. The phone stays where the path ends.

| Parameter | Takes | Values | For example |
|---|---|---|---|
| `{word}` | one word, with no spaces |  | `parcels`, `PX-4101` |
| `{travel}` | whether the step waits for the phone to arrive (`travels`), or lets the scenario go on while it moves (`starts traveling`) | `travels`, `starts traveling` | `travels`, `starts traveling` |
| `{string}` | text in double or single quotes, which the step leaves out |  | `"Get a quote"`, `'Express'` |
| `{speed}` | how fast a phone travels: `25 mph`, `40 km/h` or `11 m/s`; or, for a GPX file with times, how many times its own pace: `4x` |  | `25 mph`, `40 km/h` |

**Variants**, the parts in `[[...]]` said or left out:

- `the {word} app's phone {travel} the scene's {string} path`
- `the {word} app's phone {travel} the scene's {string} path at {speed}`

**Example:**

```gherkin
When the courier app's phone travels the scene's "up the garden path" path
When the courier app's phone starts traveling the scene's "up the garden path" path at 2x
```

_Since 0.1.5._

### `mobile-core.phone-move`

```gherkin
When the {word} app's phone moves {float} m {direction}
```

Step with the phone, as the person holding it steps, still facing the same way, at a walking pace: `forward` and `back` along the ground the way the phone looks, `left` and `right` across it, `up` and `down`.

| Parameter | Takes | Values | For example |
|---|---|---|---|
| `{word}` | one word, with no spaces |  | `parcels`, `PX-4101` |
| `{float}` | a decimal number |  | `2.5`, `0.1` |
| `{direction}` | where a swipe goes, as the finger moves (`down` from the top pulls a list to refresh); or which way a phone moves or turns in the scene its camera sees, where it also moves `forward` and `back` | `up`, `down`, `left`, `right`, `forward`, `back` | `down`, `left` |

**Example:**

```gherkin
When the courier app's phone moves 1.5 m right
```

_Since 0.1.5._

### `mobile-core.phone-turn`

```gherkin
When the {word} app's phone turns {int} degrees {direction}
```

Turn the phone where it stands, as the person holding it turns: `left` and `right` about the upright, keeping its tilt; `up` and `down`, tilting it.

| Parameter | Takes | Values | For example |
|---|---|---|---|
| `{word}` | one word, with no spaces |  | `parcels`, `PX-4101` |
| `{int}` | a whole number |  | `200`, `3` |
| `{direction}` | where a swipe goes, as the finger moves (`down` from the top pulls a list to refresh); or which way a phone moves or turns in the scene its camera sees, where it also moves `forward` and `back` | `up`, `down`, `left`, `right`, `forward`, `back` | `down`, `left` |

**Example:**

```gherkin
When the courier app's phone turns 90 degrees left
```

_Since 0.1.5._

### `mobile-core.camera-tap`

```gherkin
When the {string} in the {word} app's camera view is tapped
```

Tap what the app's camera shows, by its name in the scene the camera sees: the tap lands where the object shows on the screen (its middle, or where the scene's _tap point for it says), as a finger would.

| Parameter | Takes | For example |
|---|---|---|
| `{string}` | text in double or single quotes, which the step leaves out | `"Get a quote"`, `'Express'` |
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |

**Example:**

```gherkin
When the "left end of the parcel" in the courier app's camera view is tapped
```

_Since 0.1.5._

### `mobile-core.notification`

```gherkin
Then [[within {duration} ]]the {word} app shows a notification {string}
```

Check that the device shows a notification with a text, in its title or its text: it opens the notifications (Android's notification shade, iOS's Notification Center), looks, and closes them. It waits for the notification (10 seconds, or `within`).

| Parameter | Takes | For example |
|---|---|---|
| `{duration}` | a duration in seconds (`s`) or minutes (`m`) | `5s`, `2m` |
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |
| `{string}` | text in double or single quotes, which the step leaves out | `"Get a quote"`, `'Express'` |

**Variants**, the parts in `[[...]]` said or left out:

- `the {word} app shows a notification {string}`
- `within {duration} the {word} app shows a notification {string}`

**Example:**

```gherkin
Then the courier app shows a notification "PX-MOB-9401 delivered"
```

_Since 0.1.5._

### `mobile-core.notification-action`

```gherkin
When the {string} action of the {string} notification is tapped in the {word} app
```

Tap one of a notification's actions, the notification found by a text in its title or its text: on Android a button under it (opened out first, if it is not), on iOS in the menu a long press shows. It waits for the notification (10 seconds). The notification itself, as a person opens it, is tapped with `the "PX-MOB-9401 delivered" notification is tapped in the courier app`.

| Parameter | Takes | For example |
|---|---|---|
| `{string}` | text in double or single quotes, which the step leaves out | `"Get a quote"`, `'Express'` |
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |

**Example:**

```gherkin
When the "Next delivery" action of the "PX-MOB-9401 delivered" notification is tapped in the courier app
```

_Since 0.1.5._

### `mobile-core.background-task`

```gherkin
When the {string} background task is run in the {word} app
```

Have the phone run one of the app's background tasks now, as it does when the task's time comes: the app's own code runs, in the app, and does what it does then (a sync, a reminder). Axx only moves the moment: the app must have scheduled the task (Axx waits up to 15 seconds for it to, as an app does a moment after it launches), and on Android the conditions it set (a network, say) still apply. The task is named as the app names it: on Android, its WorkManager work's unique name or one of its tags (each is tagged with its worker's class); on iOS, its identifier (BGTaskSchedulerPermittedIdentifiers). The step waits for the task to be done: on iOS, until the app says so, in the 30 seconds iOS gives a task; on Android, until the work ends.

| Parameter | Takes | For example |
|---|---|---|
| `{string}` | text in double or single quotes, which the step leaves out | `"Get a quote"`, `'Express'` |
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |

**Example:**

```gherkin
When the "round-reminder" background task is run in the courier app
When the "example.parcels.courier.round-reminder" background task is run in the courier app
```

_Since 0.1.5._

### `mobile-core.travel-through`

```gherkin
When the {word} app's phone {travel} at {speed} through:
  | latitude | longitude |
```

The table may start with the row naming its columns, as above, or go straight to its rows.

Move the phone along a route, as its GPS reports a person walking or driving it: from the first point of the table to the last, each a latitude and a longitude, at a steady speed. The app sees where the phone is, how fast it moves and which way. `travels` waits for the phone to arrive; `starts traveling` lets the scenario go on while it moves, and a later step waits for it to reach the end. The phone stays at the last point.

| Parameter | Takes | Values | For example |
|---|---|---|---|
| `{word}` | one word, with no spaces |  | `parcels`, `PX-4101` |
| `{travel}` | whether the step waits for the phone to arrive (`travels`), or lets the scenario go on while it moves (`starts traveling`) | `travels`, `starts traveling` | `travels`, `starts traveling` |
| `{speed}` | how fast a phone travels: `25 mph`, `40 km/h` or `11 m/s`; or, for a GPX file with times, how many times its own pace: `4x` |  | `25 mph`, `40 km/h` |

A row is a point the route goes through, in order.

**Example:**

```gherkin
When the courier app's phone travels at 30 km/h through:
  | 51.3397 | 12.3731 |
  | 51.3397 | 12.3760 |
```

_Since 0.1.5._

### `mobile-core.travel-route`

```gherkin
When the {word} app's phone {travel} the {filepath} route[[ at {speed}]]
```

Move the phone along a GPX file's route, as its GPS reports it: its track, else its route, else its waypoints. With no speed, the phone keeps to the file's own times; `at 4x` goes four times as fast; `at 25 mph` keeps one speed throughout. `travels` waits for the phone to arrive; `starts traveling` lets the scenario go on while it moves.

| Parameter | Takes | Values | For example |
|---|---|---|---|
| `{word}` | one word, with no spaces |  | `parcels`, `PX-4101` |
| `{travel}` | whether the step waits for the phone to arrive (`travels`), or lets the scenario go on while it moves (`starts traveling`) | `travels`, `starts traveling` | `travels`, `starts traveling` |
| `{filepath}` | a file of the project: a path relative to the feature file's directory, the `resources` directories or axx.yaml's directory (looked for in that order), or an absolute path, quoted when it has a space |  | `seeds/parcels.yaml`, `kafka/scan-delivered.json` |
| `{speed}` | how fast a phone travels: `25 mph`, `40 km/h` or `11 m/s`; or, for a GPX file with times, how many times its own pace: `4x` |  | `25 mph`, `40 km/h` |

**Variants**, the parts in `[[...]]` said or left out:

- `the {word} app's phone {travel} the {filepath} route`
- `the {word} app's phone {travel} the {filepath} route at {speed}`

**Example:**

```gherkin
When the courier app's phone travels the routes/grimmaische-strasse.gpx route
When the courier app's phone starts traveling the routes/grimmaische-strasse.gpx route at 4x
```

_Since 0.1.5._

### `mobile-core.route-end`

```gherkin
Then [[within {duration} ]]the {word} app's phone reaches the end of its route
```

Wait for the phone a `starts traveling` step set off to arrive at the last point of its route, or the end of the scene's path it travels (the route's own time and 10 seconds, or `within`).

| Parameter | Takes | For example |
|---|---|---|
| `{duration}` | a duration in seconds (`s`) or minutes (`m`) | `5s`, `2m` |
| `{word}` | one word, with no spaces | `parcels`, `PX-4101` |

**Variants**, the parts in `[[...]]` said or left out:

- `the {word} app's phone reaches the end of its route`
- `within {duration} the {word} app's phone reaches the end of its route`

**Example:**

```gherkin
Then within 2m the courier app's phone reaches the end of its route
```

_Since 0.1.5._

## Parameter types

| Parameter | Takes | Values | For example |
|---|---|---|---|
| `{direction}` | where a swipe goes, as the finger moves (`down` from the top pulls a list to refresh); or which way a phone moves or turns in the scene its camera sees, where it also moves `forward` and `back` | `up`, `down`, `left`, `right`, `forward`, `back` | `down`, `left`, `forward` |
| `{speed}` | how fast a phone travels: `25 mph`, `40 km/h` or `11 m/s`; or, for a GPX file with times, how many times its own pace: `4x` |  | `25 mph`, `40 km/h`, `4x` |
| `{travel}` | whether the step waits for the phone to arrive (`travels`), or lets the scenario go on while it moves (`starts traveling`) | `travels`, `starts traveling` | `travels`, `starts traveling` |
