Skip to content

Latest commit

 

History

History
68 lines (54 loc) · 3.54 KB

File metadata and controls

68 lines (54 loc) · 3.54 KB

Writing tests

The device is a web page at /device/{udid}?app={bundleId}, so Playwright, Cypress, or Puppeteer drive it with ordinary selectors — the app's accessibility ids become data-testid, roles and labels become ARIA. Nothing mobile-specific.

Getting a first test

You don't need a mobile test suite to start:

  • Let your agent write it — the four steps in the README.
  • Record it. Playwright's playwright-cli records what you do on the device page (recording-start … recording-stop) and writes ordinary locators — here is a recorded login. Add one wait for the device to echo typed text before submitting (see Drive it below).
  • Start from an example — copy a project from examples/ and point it at your app.

Setup

  • Point your framework's baseURL at http://127.0.0.1:8787.

  • Run one worker per device — see below.

  • Launch the app fresh in a fixture so the first action lands:

    await request.post(`/api/devices/${UDID}/app/launch`, { data: { app: APP } });

    It blocks until the app is taking input — absorbing the boot, the engine warm-up, and the post-launch tap-swallow window. It clears the app's data first, so the test starts at a first-run screen; post to /app/launch?reset=no to resume where the app was left instead.

  • Let Playwright start DeviceDeck, if you installed it with npm:

    webServer: { command: 'npx devicedeck --app path/to/MyApp.app', url: 'http://127.0.0.1:8787', reuseExistingServer: true },

Drive it

await page.goto(`/device/${UDID}?app=${APP}`);
await page.getByTestId('username-input').fill('devicelab');
await page.getByTestId('login-button').click();
await expect(page.getByTestId('cart-button')).toBeVisible();
  • Typing: locator.fill(text). It returns once the device holds the value, so there is nothing to wait for before submitting. Avoid keyboard.type: key by key it raises Android's soft keyboard, and the next tap can be spent closing it. The device's own read-back of a field is on data-dd-device-value (a secure field reports bullets).
  • The device in a spec: read it from an environment variable (DEVICEDECK_UDID) rather than hard-coding the UDID of your simulator, so the spec runs on a teammate's Mac and in CI.
  • First render waits on the tree-engine warm-up, so give the first selector ~30s.
  • Native gestures a DOM event can't express, on window.devicedeck: page.evaluate(() => devicedeck.gesture('home')) — also swipe, button, key and screenshot(); see behaviors. The HTTP equivalents are in the CLI reference.

One device, one worker

A device takes one driver at a time: two clients tapping at once would interleave into nonsense, so a second one is refused and told who holds the device. Test runners go parallel by default, so set one worker per device (workers: 1 in Playwright) — and to run in parallel, boot more devices and give each worker its own. A tab left open on the device in the console counts as a driver too.

Frameworks

Runnable projects, each with a login + checkout journey: examples/playwright · examples/cypress · examples/puppeteer. They drive the same DOM; only the idiom differs — Playwright auto-waits, Cypress retries via .should(), Puppeteer waits manually.