@taqwright/taqwright 0.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +108 -0
- package/dist/auto-appium.d.ts +12 -0
- package/dist/auto-appium.js +77 -0
- package/dist/bin/branding.d.ts +6 -0
- package/dist/bin/branding.js +22 -0
- package/dist/bin/index.d.ts +2 -0
- package/dist/bin/index.js +321 -0
- package/dist/bin/init.d.ts +26 -0
- package/dist/bin/init.js +902 -0
- package/dist/bin/inspect.d.ts +9 -0
- package/dist/bin/inspect.js +91 -0
- package/dist/bin/report-branding.d.ts +2 -0
- package/dist/bin/report-branding.js +42 -0
- package/dist/branding-assets.d.ts +1 -0
- package/dist/branding-assets.js +1 -0
- package/dist/capabilities-helpers.d.ts +7 -0
- package/dist/capabilities-helpers.js +14 -0
- package/dist/capabilities.d.ts +6 -0
- package/dist/capabilities.js +86 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.js +235 -0
- package/dist/discovery-setup.d.ts +1 -0
- package/dist/discovery-setup.js +61 -0
- package/dist/discovery.d.ts +17 -0
- package/dist/discovery.js +55 -0
- package/dist/docs/configuration.html +376 -0
- package/dist/docs/custom-reporters.html +265 -0
- package/dist/docs/docker.html +339 -0
- package/dist/docs/docs.js +173 -0
- package/dist/docs/generating-tests.html +161 -0
- package/dist/docs/images/taqwright-html-report.png +0 -0
- package/dist/docs/index.html +13 -0
- package/dist/docs/installation.html +686 -0
- package/dist/docs/parallel.html +271 -0
- package/dist/docs/running-tests.html +385 -0
- package/dist/docs/styles.css +460 -0
- package/dist/docs/writing-tests.html +565 -0
- package/dist/doctor.d.ts +33 -0
- package/dist/doctor.js +508 -0
- package/dist/expect.d.ts +38 -0
- package/dist/expect.js +96 -0
- package/dist/fixture/artifact-mode.d.ts +2 -0
- package/dist/fixture/artifact-mode.js +7 -0
- package/dist/fixture/index.d.ts +15 -0
- package/dist/fixture/index.js +324 -0
- package/dist/images/taqwright-html-report.png +0 -0
- package/dist/images/taqwright_favicon.png +0 -0
- package/dist/images/taqwright_logo.png +0 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +7 -0
- package/dist/inspector/codegen-appium.d.ts +3 -0
- package/dist/inspector/codegen-appium.js +228 -0
- package/dist/inspector/devices.d.ts +41 -0
- package/dist/inspector/devices.js +422 -0
- package/dist/inspector/locator-suggester.d.ts +23 -0
- package/dist/inspector/locator-suggester.js +539 -0
- package/dist/inspector/recorder.d.ts +128 -0
- package/dist/inspector/recorder.js +162 -0
- package/dist/inspector/server.d.ts +39 -0
- package/dist/inspector/server.js +1210 -0
- package/dist/inspector/session.d.ts +84 -0
- package/dist/inspector/session.js +262 -0
- package/dist/inspector/ui.d.ts +1 -0
- package/dist/inspector/ui.js +5508 -0
- package/dist/keys.d.ts +3 -0
- package/dist/keys.js +28 -0
- package/dist/locator/index.d.ts +206 -0
- package/dist/locator/index.js +1506 -0
- package/dist/logger.d.ts +5 -0
- package/dist/logger.js +5 -0
- package/dist/mobile/index.d.ts +130 -0
- package/dist/mobile/index.js +762 -0
- package/dist/network/android.d.ts +5 -0
- package/dist/network/android.js +87 -0
- package/dist/network/ca.d.ts +10 -0
- package/dist/network/ca.js +136 -0
- package/dist/network/har.d.ts +90 -0
- package/dist/network/har.js +101 -0
- package/dist/network/host-proxy.d.ts +16 -0
- package/dist/network/host-proxy.js +134 -0
- package/dist/network/index.d.ts +26 -0
- package/dist/network/index.js +105 -0
- package/dist/network/ios-sim.d.ts +3 -0
- package/dist/network/ios-sim.js +29 -0
- package/dist/network/proxy.d.ts +13 -0
- package/dist/network/proxy.js +310 -0
- package/dist/providers/appium.d.ts +23 -0
- package/dist/providers/appium.js +288 -0
- package/dist/providers/browserstack/index.d.ts +5 -0
- package/dist/providers/browserstack/index.js +77 -0
- package/dist/providers/browserstack/utils.d.ts +1 -0
- package/dist/providers/browserstack/utils.js +6 -0
- package/dist/providers/cloud.d.ts +53 -0
- package/dist/providers/cloud.js +117 -0
- package/dist/providers/emulator/index.d.ts +8 -0
- package/dist/providers/emulator/index.js +47 -0
- package/dist/providers/index.d.ts +10 -0
- package/dist/providers/index.js +33 -0
- package/dist/providers/lambdatest/index.d.ts +28 -0
- package/dist/providers/lambdatest/index.js +99 -0
- package/dist/providers/lambdatest/utils.d.ts +1 -0
- package/dist/providers/lambdatest/utils.js +6 -0
- package/dist/providers/local/index.d.ts +9 -0
- package/dist/providers/local/index.js +53 -0
- package/dist/providers/local-session.d.ts +16 -0
- package/dist/providers/local-session.js +55 -0
- package/dist/setup/archive.d.ts +2 -0
- package/dist/setup/archive.js +43 -0
- package/dist/setup/avd.d.ts +12 -0
- package/dist/setup/avd.js +103 -0
- package/dist/setup/index.d.ts +6 -0
- package/dist/setup/index.js +55 -0
- package/dist/setup/install-android.d.ts +2 -0
- package/dist/setup/install-android.js +70 -0
- package/dist/setup/install-appium.d.ts +1 -0
- package/dist/setup/install-appium.js +64 -0
- package/dist/setup/install-jdk.d.ts +1 -0
- package/dist/setup/install-jdk.js +58 -0
- package/dist/setup/paths.d.ts +16 -0
- package/dist/setup/paths.js +88 -0
- package/dist/setup/spawn-tool.d.ts +3 -0
- package/dist/setup/spawn-tool.js +11 -0
- package/dist/tracer/index.d.ts +34 -0
- package/dist/tracer/index.js +687 -0
- package/dist/tracer/proxy.d.ts +3 -0
- package/dist/tracer/proxy.js +60 -0
- package/dist/types/index.d.ts +189 -0
- package/dist/types/index.js +6 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +37 -0
- package/package.json +79 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Custom reporters · taqwright</title>
|
|
7
|
+
<meta name="description" content="Build a custom report for taqwright runs. taqwright forwards the reporter option to Playwright, so any Playwright Reporter works — including ones that consume the taqwright-trace and taqwright-video attachments.">
|
|
8
|
+
<link rel="stylesheet" href="styles.css">
|
|
9
|
+
<script>try{var t=localStorage.getItem('tw-theme');if(t==='light'||(!t&&typeof matchMedia==='function'&&matchMedia('(prefers-color-scheme: light)').matches))document.documentElement.setAttribute('data-theme','light');}catch(e){}</script>
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
|
|
13
|
+
<header class="topbar">
|
|
14
|
+
<button class="menu-toggle" id="menu-toggle" aria-label="Toggle navigation">☰</button>
|
|
15
|
+
<a class="brand" href="installation.html"><span class="accent">taq</span>wright</a>
|
|
16
|
+
<nav class="primary">
|
|
17
|
+
<a href="installation.html" class="current">Docs</a>
|
|
18
|
+
<a href="generating-tests.html">Inspector</a>
|
|
19
|
+
<a href="writing-tests.html#actions">API</a>
|
|
20
|
+
</nav>
|
|
21
|
+
<span class="spacer"></span>
|
|
22
|
+
<div class="search" title="Search (placeholder)">
|
|
23
|
+
<span>Search docs…</span>
|
|
24
|
+
<span class="kbd">⌘K</span>
|
|
25
|
+
</div>
|
|
26
|
+
<button class="theme-toggle" id="theme-toggle" aria-label="Switch to light theme" title="Switch to light theme"></button>
|
|
27
|
+
<a class="gh-link" href="https://github.com/taqelah/taqwright" title="GitHub">
|
|
28
|
+
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .5a11.5 11.5 0 0 0-3.64 22.42c.58.1.79-.25.79-.55v-2.02c-3.2.7-3.88-1.36-3.88-1.36-.52-1.33-1.28-1.68-1.28-1.68-1.05-.71.08-.7.08-.7 1.16.08 1.77 1.19 1.77 1.19 1.03 1.77 2.7 1.26 3.36.96.1-.75.4-1.26.73-1.55-2.55-.29-5.24-1.28-5.24-5.7 0-1.26.45-2.29 1.19-3.1-.12-.29-.52-1.47.11-3.06 0 0 .97-.31 3.18 1.18a11 11 0 0 1 5.79 0c2.21-1.49 3.18-1.18 3.18-1.18.63 1.59.23 2.77.11 3.06.74.81 1.18 1.84 1.18 3.1 0 4.43-2.7 5.4-5.27 5.69.41.36.78 1.06.78 2.14v3.17c0 .31.21.66.8.55A11.5 11.5 0 0 0 12 .5Z"/></svg>
|
|
29
|
+
</a>
|
|
30
|
+
</header>
|
|
31
|
+
|
|
32
|
+
<div class="shell">
|
|
33
|
+
|
|
34
|
+
<aside class="sidebar" id="sidebar">
|
|
35
|
+
<h3>Getting started</h3>
|
|
36
|
+
<ul>
|
|
37
|
+
<li><a href="installation.html">Installation</a></li>
|
|
38
|
+
<li><a href="writing-tests.html">Writing tests</a></li>
|
|
39
|
+
<li><a href="generating-tests.html">Generating tests</a></li>
|
|
40
|
+
<li><a href="running-tests.html">Running & debugging</a></li>
|
|
41
|
+
<li><a href="custom-reporters.html" class="current">Custom reporters</a></li>
|
|
42
|
+
<li class="sub"><a href="custom-reporters.html#overview">Overview</a></li>
|
|
43
|
+
<li class="sub"><a href="custom-reporters.html#writing">Writing a reporter</a></li>
|
|
44
|
+
<li class="sub"><a href="custom-reporters.html#wiring">Wiring it in</a></li>
|
|
45
|
+
<li class="sub"><a href="custom-reporters.html#artifacts">Consuming artifacts</a></li>
|
|
46
|
+
<li class="sub"><a href="custom-reporters.html#typescript">TypeScript & deps</a></li>
|
|
47
|
+
<li><a href="parallel.html">Parallel runs</a></li>
|
|
48
|
+
<li><a href="docker.html">Run in Docker</a></li>
|
|
49
|
+
</ul>
|
|
50
|
+
|
|
51
|
+
<h3>Taqwright Test</h3>
|
|
52
|
+
<ul>
|
|
53
|
+
<li><a href="configuration.html">Configuration</a></li>
|
|
54
|
+
</ul>
|
|
55
|
+
|
|
56
|
+
<h3>Reference</h3>
|
|
57
|
+
<ul>
|
|
58
|
+
<li><a href="https://playwright.dev/docs/test-reporters">Playwright reporters ↗</a></li>
|
|
59
|
+
<li><a href="https://playwright.dev/docs/api/class-reporter">Reporter API ↗</a></li>
|
|
60
|
+
</ul>
|
|
61
|
+
</aside>
|
|
62
|
+
|
|
63
|
+
<main>
|
|
64
|
+
|
|
65
|
+
<div class="breadcrumb">
|
|
66
|
+
<a href="installation.html">Docs</a> / Getting started / Custom reporters
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
<h1>Custom reporters</h1>
|
|
70
|
+
<p class="lede">
|
|
71
|
+
Taqwright has <strong>no reporting layer of its own</strong> — it forwards the <code>reporter</code> option straight to Playwright's runner. So <strong>any Playwright reporter works unchanged</strong>, including a fully custom one you write. And because taqwright's device trace and screen recording are attached as standard Playwright attachments, your custom reporter can pull them into whatever report format you want.
|
|
72
|
+
</p>
|
|
73
|
+
|
|
74
|
+
<h2 id="overview">Overview</h2>
|
|
75
|
+
<p>
|
|
76
|
+
When you run <code>npx taqwright test</code>, taqwright locates your <code>taqwright.config.ts</code> and spawns Playwright's own runner against it. <code>defineConfig()</code> returns a real Playwright <code>TestConfig</code> and passes <code>reporter</code> through verbatim — there is no whitelist, no wrapper, and no forced reporter. The built-in presets (<code>list</code>, <code>html</code>, <code>json</code>, <code>junit</code>, <code>blob</code>, <code>github</code>, …) are covered in <a href="running-tests.html#reports">Running & debugging → Reports</a>. This page is about writing your <em>own</em>.
|
|
77
|
+
</p>
|
|
78
|
+
|
|
79
|
+
<div class="callout">
|
|
80
|
+
<strong>What "custom report" means here.</strong> A custom reporter is a small module that implements Playwright's <code>Reporter</code> interface. Playwright calls your hooks as tests run; you decide what to emit — a bespoke HTML dashboard, a Slack message, a CSV, a row in your own DB. It's the same mechanism Playwright's own <code>html</code> / <code>json</code> reporters use.
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<h2 id="writing">Writing a custom reporter</h2>
|
|
84
|
+
<p>
|
|
85
|
+
Implement the <code>Reporter</code> interface from <code>@playwright/test/reporter</code>. The three hooks you'll almost always want are <code>onBegin</code>, <code>onTestEnd</code>, and <code>onEnd</code>:
|
|
86
|
+
</p>
|
|
87
|
+
|
|
88
|
+
<div class="codeblock">
|
|
89
|
+
<div class="filename">reporters/my-reporter.ts</div>
|
|
90
|
+
<pre class="code"><button class="copy">Copy</button><code>import type {
|
|
91
|
+
Reporter, FullConfig, Suite, TestCase, TestResult, FullResult,
|
|
92
|
+
} from '@playwright/test/reporter';
|
|
93
|
+
|
|
94
|
+
export default class MyReporter implements Reporter {
|
|
95
|
+
private rows: Array<Record<string, unknown>> = [];
|
|
96
|
+
|
|
97
|
+
onBegin(config: FullConfig, suite: Suite) {
|
|
98
|
+
console.log(`Starting ${suite.allTests().length} tests`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
onTestEnd(test: TestCase, result: TestResult) {
|
|
102
|
+
this.rows.push({
|
|
103
|
+
title: test.titlePath().join(' › '),
|
|
104
|
+
project: test.parent.project()?.name,
|
|
105
|
+
status: result.status, // 'passed' | 'failed' | 'timedOut' | 'skipped'
|
|
106
|
+
durationMs: result.duration,
|
|
107
|
+
retry: result.retry,
|
|
108
|
+
error: result.error?.message,
|
|
109
|
+
attachments: result.attachments.map((a) => a.name),
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async onEnd(result: FullResult) {
|
|
114
|
+
const fs = await import('node:fs/promises');
|
|
115
|
+
await fs.writeFile(
|
|
116
|
+
'reports/custom.json',
|
|
117
|
+
JSON.stringify({ status: result.status, tests: this.rows }, null, 2),
|
|
118
|
+
);
|
|
119
|
+
console.log(`Custom report written — overall: ${result.status}`);
|
|
120
|
+
}
|
|
121
|
+
}</code></pre>
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
<p>
|
|
125
|
+
Every Playwright reporter hook is available (<code>onStdOut</code>, <code>onStdErr</code>, <code>onStepBegin</code>/<code>onStepEnd</code>, <code>onError</code>, <code>printsToStdio</code>, …). taqwright doesn't intercept any of them — your reporter sees exactly what a Playwright web reporter would: standard <code>TestCase</code> / <code>TestResult</code> objects, the Playwright-managed <code>result.status</code>, and the full attachment list.
|
|
126
|
+
</p>
|
|
127
|
+
|
|
128
|
+
<h2 id="wiring">Wiring it in</h2>
|
|
129
|
+
<p>
|
|
130
|
+
Reference the reporter module from <code>taqwright.config.ts</code>. Use the <strong>array tuple form</strong> — <code>[modulePath]</code> or <code>[modulePath, options]</code> — and stack it alongside any built-ins:
|
|
131
|
+
</p>
|
|
132
|
+
|
|
133
|
+
<div class="codeblock">
|
|
134
|
+
<div class="filename">taqwright.config.ts</div>
|
|
135
|
+
<pre class="code"><button class="copy">Copy</button><code>import { defineConfig, Platform } from 'taqwright';
|
|
136
|
+
|
|
137
|
+
export default defineConfig({
|
|
138
|
+
reporter: [
|
|
139
|
+
['list'], // keep a console reporter
|
|
140
|
+
['./reporters/my-reporter.ts'], // your custom reporter
|
|
141
|
+
['./reporters/my-reporter.ts', { slackWebhook: process.env.SLACK_URL }],
|
|
142
|
+
],
|
|
143
|
+
projects: [ /* ... */ ],
|
|
144
|
+
});</code></pre>
|
|
145
|
+
</div>
|
|
146
|
+
|
|
147
|
+
<div class="callout warn">
|
|
148
|
+
<strong>Use the array form, not a bare string.</strong>
|
|
149
|
+
taqwright's <code>reporter</code> type is <code>presets | Array<[string] | [string, unknown]></code>. The bare-string custom-module form (<code>reporter: './reporters/my-reporter.ts'</code>) is <em>not</em> in the type union, so TypeScript will flag it even though Playwright would accept it at runtime. Always wrap a custom reporter in the tuple form: <code>reporter: [['./reporters/my-reporter.ts']]</code>.
|
|
150
|
+
</div>
|
|
151
|
+
|
|
152
|
+
<p>
|
|
153
|
+
You can also pass it per-run on the CLI — <code>taqwright test</code> forwards <code>--reporter</code> to Playwright:
|
|
154
|
+
</p>
|
|
155
|
+
|
|
156
|
+
<div class="codeblock"><pre class="code"><button class="copy">Copy</button><code>npx taqwright test --reporter=./reporters/my-reporter.ts
|
|
157
|
+
# or stack with a preset:
|
|
158
|
+
npx taqwright test --reporter=list,./reporters/my-reporter.ts</code></pre></div>
|
|
159
|
+
|
|
160
|
+
<h2 id="artifacts">Consuming taqwright's trace & video</h2>
|
|
161
|
+
<p>
|
|
162
|
+
This is the part unique to taqwright. When <a href="running-tests.html#tracing"><code>trace</code></a> or <a href="running-tests.html#video"><code>video</code></a> is enabled, taqwright writes its artifacts as <strong>standard Playwright attachments</strong> on the test result — so a custom reporter reads them straight off <code>result.attachments</code>, no taqwright import required:
|
|
163
|
+
</p>
|
|
164
|
+
|
|
165
|
+
<table class="api">
|
|
166
|
+
<thead><tr><th>Attachment name</th><th><code>contentType</code></th><th>What it is</th></tr></thead>
|
|
167
|
+
<tbody>
|
|
168
|
+
<tr><td><code>taqwright-trace</code></td><td><code>text/html</code></td><td>Self-contained per-action timeline (screenshots + page-source) as one <code>trace.html</code>.</td></tr>
|
|
169
|
+
<tr><td><code>taqwright-video</code></td><td><code>video/mp4</code></td><td>Full-run on-device screen recording, <code>screen.mp4</code>.</td></tr>
|
|
170
|
+
</tbody>
|
|
171
|
+
</table>
|
|
172
|
+
|
|
173
|
+
<p>
|
|
174
|
+
They are deliberately <em>not</em> named <code>trace</code> / <code>video</code> — Playwright's own HTML report reserves those names for its browser <code>.zip</code> traces and recordings. Each attachment is the normal Playwright shape (<code>{ name, contentType, path }</code>, occasionally <code>body</code>), so you can copy, embed, or link them however your report needs:
|
|
175
|
+
</p>
|
|
176
|
+
|
|
177
|
+
<div class="codeblock">
|
|
178
|
+
<div class="filename">reporters/my-reporter.ts (excerpt)</div>
|
|
179
|
+
<pre class="code"><button class="copy">Copy</button><code>onTestEnd(test: TestCase, result: TestResult) {
|
|
180
|
+
for (const att of result.attachments) {
|
|
181
|
+
if (att.name === 'taqwright-trace' && att.path) {
|
|
182
|
+
// e.g. copy next to your report and link it
|
|
183
|
+
this.traceFor[test.id] = att.path; // .../trace.html (text/html)
|
|
184
|
+
}
|
|
185
|
+
if (att.name === 'taqwright-video' && att.path) {
|
|
186
|
+
this.videoFor[test.id] = att.path; // .../screen.mp4 (video/mp4)
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}</code></pre>
|
|
190
|
+
</div>
|
|
191
|
+
|
|
192
|
+
<div class="callout">
|
|
193
|
+
<strong>Retention follows the artifact mode.</strong> An attachment only exists when the run's outcome matches the configured mode (<code>'on'</code> always; <code>'on-failure'</code> / <code>'retain-on-failure'</code> only for failed tests). Always guard on <code>att.path</code> being present — don't assume every test result carries the trace/video.
|
|
194
|
+
</div>
|
|
195
|
+
|
|
196
|
+
<h2 id="typescript">TypeScript & dependencies</h2>
|
|
197
|
+
<ul>
|
|
198
|
+
<li><strong>A <code>.ts</code> reporter is fine.</strong> Playwright transpiles the reporter module the same way it transpiles your <code>taqwright.config.ts</code> — no separate build step needed.</li>
|
|
199
|
+
<li><strong>Type imports come from <code>@playwright/test/reporter</code>.</strong> taqwright doesn't re-export the reporter types. <code>@playwright/test</code> is a direct dependency of taqwright, so it already resolves in your project's <code>node_modules</code>; for clean, version-pinned editor types add it explicitly: <code>npm i -D @playwright/test</code>.</li>
|
|
200
|
+
<li><strong>Nothing taqwright-specific is required</strong> to write the reporter — it's a pure Playwright reporter. taqwright only affects <em>what</em> is in the attachments, not the reporter contract.</li>
|
|
201
|
+
</ul>
|
|
202
|
+
|
|
203
|
+
<div class="pager">
|
|
204
|
+
<a href="running-tests.html">
|
|
205
|
+
<div class="label">← Previous</div>
|
|
206
|
+
<div class="title">Running & debugging tests</div>
|
|
207
|
+
</a>
|
|
208
|
+
<a class="next" href="parallel.html">
|
|
209
|
+
<div class="label">Next →</div>
|
|
210
|
+
<div class="title">Parallel runs</div>
|
|
211
|
+
</a>
|
|
212
|
+
</div>
|
|
213
|
+
|
|
214
|
+
</main>
|
|
215
|
+
|
|
216
|
+
<aside class="onthispage">
|
|
217
|
+
<h4>On this page</h4>
|
|
218
|
+
<ol>
|
|
219
|
+
<li><a href="#overview">Overview</a></li>
|
|
220
|
+
<li><a href="#writing">Writing a custom reporter</a></li>
|
|
221
|
+
<li><a href="#wiring">Wiring it in</a></li>
|
|
222
|
+
<li><a href="#artifacts">Consuming trace & video</a></li>
|
|
223
|
+
<li><a href="#typescript">TypeScript & deps</a></li>
|
|
224
|
+
</ol>
|
|
225
|
+
</aside>
|
|
226
|
+
|
|
227
|
+
</div>
|
|
228
|
+
|
|
229
|
+
<footer class="bot">
|
|
230
|
+
<div class="cols">
|
|
231
|
+
<div>
|
|
232
|
+
<h5>Getting started</h5>
|
|
233
|
+
<ul>
|
|
234
|
+
<li><a href="installation.html">Installation</a></li>
|
|
235
|
+
<li><a href="writing-tests.html">Writing tests</a></li>
|
|
236
|
+
<li><a href="generating-tests.html">Generating tests</a></li>
|
|
237
|
+
<li><a href="running-tests.html">Running & debugging</a></li>
|
|
238
|
+
</ul>
|
|
239
|
+
</div>
|
|
240
|
+
<div>
|
|
241
|
+
<h5>Guides</h5>
|
|
242
|
+
<ul>
|
|
243
|
+
<li><a href="custom-reporters.html">Custom reporters</a></li>
|
|
244
|
+
<li><a href="parallel.html">Parallel runs</a></li>
|
|
245
|
+
<li><a href="docker.html">Run in Docker</a></li>
|
|
246
|
+
<li><a href="writing-tests.html#actions">API surface</a></li>
|
|
247
|
+
</ul>
|
|
248
|
+
</div>
|
|
249
|
+
<div>
|
|
250
|
+
<h5>Built on</h5>
|
|
251
|
+
<ul>
|
|
252
|
+
<li><a href="https://playwright.dev/">Playwright</a></li>
|
|
253
|
+
<li><a href="https://appium.io/">Appium 3</a></li>
|
|
254
|
+
</ul>
|
|
255
|
+
</div>
|
|
256
|
+
</div>
|
|
257
|
+
<div class="copy">
|
|
258
|
+
Apache-2.0 licensed · Built on Playwright + Appium
|
|
259
|
+
</div>
|
|
260
|
+
</footer>
|
|
261
|
+
|
|
262
|
+
<script src="docs.js"></script>
|
|
263
|
+
|
|
264
|
+
</body>
|
|
265
|
+
</html>
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Run in Docker · taqwright</title>
|
|
7
|
+
<meta name="description" content="Skip the local toolchain — run taqwright in the bundled Docker image. Local Android over ADB-TCP, and cloud Android / iOS in CI.">
|
|
8
|
+
<link rel="stylesheet" href="styles.css">
|
|
9
|
+
<script>try{var t=localStorage.getItem('tw-theme');if(t==='light'||(!t&&typeof matchMedia==='function'&&matchMedia('(prefers-color-scheme: light)').matches))document.documentElement.setAttribute('data-theme','light');}catch(e){}</script>
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
|
|
13
|
+
<header class="topbar">
|
|
14
|
+
<button class="menu-toggle" id="menu-toggle" aria-label="Toggle navigation">☰</button>
|
|
15
|
+
<a class="brand" href="installation.html"><span class="accent">taq</span>wright</a>
|
|
16
|
+
<nav class="primary">
|
|
17
|
+
<a href="installation.html" class="current">Docs</a>
|
|
18
|
+
<a href="generating-tests.html">Inspector</a>
|
|
19
|
+
<a href="writing-tests.html#actions">API</a>
|
|
20
|
+
</nav>
|
|
21
|
+
<span class="spacer"></span>
|
|
22
|
+
<div class="search" title="Search (placeholder)">
|
|
23
|
+
<span>Search docs…</span>
|
|
24
|
+
<span class="kbd">⌘K</span>
|
|
25
|
+
</div>
|
|
26
|
+
<button class="theme-toggle" id="theme-toggle" aria-label="Switch to light theme" title="Switch to light theme"></button>
|
|
27
|
+
<a class="gh-link" href="https://github.com/taqelah/taqwright" title="GitHub">
|
|
28
|
+
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .5a11.5 11.5 0 0 0-3.64 22.42c.58.1.79-.25.79-.55v-2.02c-3.2.7-3.88-1.36-3.88-1.36-.52-1.33-1.28-1.68-1.28-1.68-1.05-.71.08-.7.08-.7 1.16.08 1.77 1.19 1.77 1.19 1.03 1.77 2.7 1.26 3.36.96.1-.75.4-1.26.73-1.55-2.55-.29-5.24-1.28-5.24-5.7 0-1.26.45-2.29 1.19-3.1-.12-.29-.52-1.47.11-3.06 0 0 .97-.31 3.18 1.18a11 11 0 0 1 5.79 0c2.21-1.49 3.18-1.18 3.18-1.18.63 1.59.23 2.77.11 3.06.74.81 1.18 1.84 1.18 3.1 0 4.43-2.7 5.4-5.27 5.69.41.36.78 1.06.78 2.14v3.17c0 .31.21.66.8.55A11.5 11.5 0 0 0 12 .5Z"/></svg>
|
|
29
|
+
</a>
|
|
30
|
+
</header>
|
|
31
|
+
|
|
32
|
+
<div class="shell">
|
|
33
|
+
|
|
34
|
+
<aside class="sidebar" id="sidebar">
|
|
35
|
+
<h3>Getting started</h3>
|
|
36
|
+
<ul>
|
|
37
|
+
<li><a href="installation.html">Installation</a></li>
|
|
38
|
+
<li><a href="writing-tests.html">Writing tests</a></li>
|
|
39
|
+
<li><a href="generating-tests.html">Generating tests</a></li>
|
|
40
|
+
<li><a href="running-tests.html">Running & debugging</a></li>
|
|
41
|
+
<li><a href="custom-reporters.html">Custom reporters</a></li>
|
|
42
|
+
<li><a href="parallel.html">Parallel runs</a></li>
|
|
43
|
+
<li><a href="docker.html" class="current">Run in Docker</a></li>
|
|
44
|
+
<li class="sub"><a href="docker.html#docker-build">Build the image</a></li>
|
|
45
|
+
<li class="sub"><a href="docker.html#docker-local-android">Local Android</a></li>
|
|
46
|
+
<li class="sub"><a href="docker.html#docker-ci-android">CI: cloud Android</a></li>
|
|
47
|
+
<li class="sub"><a href="docker.html#docker-ci-ios">CI: cloud iOS</a></li>
|
|
48
|
+
<li class="sub"><a href="docker.html#docker-verify">Verify</a></li>
|
|
49
|
+
</ul>
|
|
50
|
+
|
|
51
|
+
<h3>Taqwright Test</h3>
|
|
52
|
+
<ul>
|
|
53
|
+
<li><a href="configuration.html">Configuration</a></li>
|
|
54
|
+
</ul>
|
|
55
|
+
|
|
56
|
+
<h3>Reference</h3>
|
|
57
|
+
<ul>
|
|
58
|
+
<li><a href="https://playwright.dev/docs/intro">Playwright runner ↗</a></li>
|
|
59
|
+
<li><a href="https://appium.io/docs/en/latest/">Appium 3 ↗</a></li>
|
|
60
|
+
</ul>
|
|
61
|
+
</aside>
|
|
62
|
+
|
|
63
|
+
<main>
|
|
64
|
+
|
|
65
|
+
<div class="breadcrumb">
|
|
66
|
+
<a href="installation.html">Docs</a> / Getting started / Run in Docker
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
<h1>Run in Docker</h1>
|
|
70
|
+
<p class="lede">
|
|
71
|
+
Skip the local toolchain install — the repo's Docker setup bundles Node 24, Appium 3, JDK, the Android SDK command-line tools, and the UiAutomator2 driver into one image. Useful for reproducible CI and zero-setup onboarding.
|
|
72
|
+
</p>
|
|
73
|
+
|
|
74
|
+
<h2 id="docker">Run in Docker (optional)</h2>
|
|
75
|
+
<p>
|
|
76
|
+
Skip the local toolchain install — the repo's <a href="https://docs.docker.com/get-docker/">Docker</a> setup bundles Node 24, Appium 3, JDK 21, the Android SDK command-line tools, and the UiAutomator2 driver into one image. Useful for CI (reproducible runs against a cloud device) and onboarding (contributors who don't want to install Appium / Android Studio locally).
|
|
77
|
+
</p>
|
|
78
|
+
|
|
79
|
+
<div class="callout">
|
|
80
|
+
<strong>Coverage:</strong> Android works fully inside Docker. iOS goes through a cloud provider (BrowserStack / LambdaTest) — XCUITest needs Xcode, which only runs on macOS, so it can't go in a container. Real-device USB passthrough is Linux-only; Mac users connect to emulators via ADB-over-TCP.
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<p>The repo ships a <code>Dockerfile</code> and a <code>docker-compose.yml</code> with three profiles. Pick the one that matches what you're doing.</p>
|
|
84
|
+
|
|
85
|
+
<h3 id="docker-build">Build the image (one-time)</h3>
|
|
86
|
+
<p>
|
|
87
|
+
All three profile services share one image (<code>taqwright:local</code>). Build it once — subsequent <code>up</code> / <code>run</code> commands reuse the cache.
|
|
88
|
+
</p>
|
|
89
|
+
|
|
90
|
+
<div class="codeblock"><pre class="code"><button class="copy">Copy</button><code>docker compose build appium</code></pre></div>
|
|
91
|
+
|
|
92
|
+
<div class="callout">
|
|
93
|
+
<strong>Why <code>appium</code>?</strong>
|
|
94
|
+
All three services in <code>docker-compose.yml</code> are profile-gated, so a bare <code>docker compose build</code> sees no services and prints <code>No services to build</code>. Naming any service builds the shared image. Equivalent:
|
|
95
|
+
<code>docker compose --profile local-android build</code>.
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<p>First-time build: 3–6 minutes on Apple Silicon (Rosetta-emulating the amd64 SDK), 2–4 minutes on Linux/Intel. Final image: ~1.3 GB.</p>
|
|
99
|
+
|
|
100
|
+
<h4 id="docker-contents">What's in the image</h4>
|
|
101
|
+
<p>Source of truth is the <a href="https://github.com/taqelah/taqwright/blob/main/Dockerfile"><code>Dockerfile</code></a> at the repo root. At a glance, the build layers are:</p>
|
|
102
|
+
|
|
103
|
+
<table class="api">
|
|
104
|
+
<thead><tr><th>Layer</th><th>What & why</th><th>~Size</th></tr></thead>
|
|
105
|
+
<tbody>
|
|
106
|
+
<tr>
|
|
107
|
+
<td><code>node:24-bookworm</code></td>
|
|
108
|
+
<td>Debian-based Node 24 LTS — matches <code>engines.node</code> in <code>package.json</code>.</td>
|
|
109
|
+
<td>~250 MB</td>
|
|
110
|
+
</tr>
|
|
111
|
+
<tr>
|
|
112
|
+
<td>System tools</td>
|
|
113
|
+
<td><code>openjdk-17-jre-headless</code> (Appium's UiAutomator2 driver needs 11+; 17 is what Debian bookworm ships by default) plus Debian's <code>adb</code> package (built for both amd64 and arm64 — Google's own platform-tools is x86_64-only on Linux, so we use Debian's so the image runs natively on Apple Silicon). Plus <code>curl</code> + <code>unzip</code> + <code>ca-certificates</code> for the SDK download.</td>
|
|
114
|
+
<td>~210 MB</td>
|
|
115
|
+
</tr>
|
|
116
|
+
<tr>
|
|
117
|
+
<td>Android cmdline-tools</td>
|
|
118
|
+
<td>Downloaded from Google's CDN at build time. Gives you <code>sdkmanager</code> (used at build time to accept SDK licenses). Java-based, so arch-neutral. We skip installing the platform-tools / system-images / emulator via sdkmanager — Debian's <code>adb</code> covers our adb need, and emulators don't work in Docker Desktop anyway.</td>
|
|
119
|
+
<td>~150 MB</td>
|
|
120
|
+
</tr>
|
|
121
|
+
<tr>
|
|
122
|
+
<td>Appium 3 + UiAutomator2 driver</td>
|
|
123
|
+
<td><code>npm install -g appium@^3</code> then <code>appium driver install uiautomator2</code>. No XCUITest — iOS goes through cloud providers.</td>
|
|
124
|
+
<td>~200 MB</td>
|
|
125
|
+
</tr>
|
|
126
|
+
</tbody>
|
|
127
|
+
</table>
|
|
128
|
+
|
|
129
|
+
<p>Env baked in (no shell setup needed inside the container):</p>
|
|
130
|
+
|
|
131
|
+
<div class="codeblock"><pre class="code"><code>JAVA_HOME=/usr/lib/jvm/java-17-openjdk-{amd64,arm64} # arch-suffix set by buildx
|
|
132
|
+
ANDROID_HOME=/opt/android-sdk
|
|
133
|
+
ANDROID_SDK_ROOT=/opt/android-sdk
|
|
134
|
+
PATH=$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$PATH</code></pre></div>
|
|
135
|
+
|
|
136
|
+
<p>Default command: <code>appium --address 0.0.0.0 --port 4723 --base-path /</code>. The cloud-profile services override this with <code>npx taqwright test --project=…</code>.</p>
|
|
137
|
+
|
|
138
|
+
<div class="callout">
|
|
139
|
+
<strong>When to rebuild</strong>: the <code>Dockerfile</code> itself changes, <code>engines.node</code> moves in <code>package.json</code>, or the pinned Appium / UiAutomator2 versions change. Other code changes don't require a rebuild — the test sources mount in via <code>volumes: - .:/work</code>.
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
<h3 id="docker-local-android">Local dev — Android emulator on the host</h3>
|
|
143
|
+
<p>
|
|
144
|
+
Appium runs in the container; the emulator runs on your <strong>host</strong>. The container's <code>adb</code> connects to the emulator over TCP (port 5555). Works on macOS, Windows, and Linux Docker Desktop. Setup is five steps — three on the host, two inside the container.
|
|
145
|
+
</p>
|
|
146
|
+
|
|
147
|
+
<div class="callout">
|
|
148
|
+
<strong>Why the emulator stays on the host:</strong>
|
|
149
|
+
Android emulators need hardware virtualization (Apple's Hypervisor.framework on Mac, <code>/dev/kvm</code> on Linux). Docker Desktop on Mac / Windows runs Docker itself inside a VM — nested virtualization isn't passed through, so an emulator in the container would either refuse to boot or crawl. The container is the Appium runtime; the device is always external.
|
|
150
|
+
</div>
|
|
151
|
+
|
|
152
|
+
<p><strong>Prerequisite:</strong> at least one AVD created in Android Studio (or via <code>avdmanager</code>). Check what you have:</p>
|
|
153
|
+
|
|
154
|
+
<div class="codeblock"><pre class="code"><button class="copy">Copy</button><code>emulator -list-avds
|
|
155
|
+
# Pixel_7_API_34 ← if you see names, you're set
|
|
156
|
+
# # if empty: open Android Studio → Device Manager → Create Device</code></pre></div>
|
|
157
|
+
|
|
158
|
+
<h4 id="docker-local-host-side">Host-side setup (per emulator session)</h4>
|
|
159
|
+
|
|
160
|
+
<div class="codeblock"><pre class="code"><button class="copy">Copy</button><code># 1. Boot the emulator in the background:
|
|
161
|
+
emulator -avd Pixel_7_API_34 &
|
|
162
|
+
|
|
163
|
+
# 2. Wait for Android to finish booting (~30s typically):
|
|
164
|
+
adb wait-for-device
|
|
165
|
+
adb shell getprop sys.boot_completed # prints "1" when ready
|
|
166
|
+
|
|
167
|
+
# 3. Confirm host sees it:
|
|
168
|
+
adb devices
|
|
169
|
+
# List of devices attached
|
|
170
|
+
# emulator-5554 device
|
|
171
|
+
|
|
172
|
+
# 4. Put it into TCP-listen mode so the container can reach it on :5555.
|
|
173
|
+
# NOTE: this gets reset every emulator reboot — re-run after each boot.
|
|
174
|
+
adb tcpip 5555
|
|
175
|
+
# restarting in TCP mode port: 5555</code></pre></div>
|
|
176
|
+
|
|
177
|
+
<h4 id="docker-local-container-side">Container-side setup</h4>
|
|
178
|
+
|
|
179
|
+
<p>What the compose file wires up for you (no manual config needed):</p>
|
|
180
|
+
<ul>
|
|
181
|
+
<li><strong>Port 4723</strong> mapped to your host — so <code>localhost:4723</code> reaches Appium inside the container.</li>
|
|
182
|
+
<li><strong><code>~/.android</code> (read-only volume)</strong> — shares your host's adb keypair (<code>adbkey</code> / <code>adbkey.pub</code>) with the container. Emulators you've already authorized on the host accept the container's adb without prompting again. Without this, <code>adb connect</code> would fail with <code>failed to authenticate</code>.</li>
|
|
183
|
+
<li><strong><code>host.docker.internal:host-gateway</code></strong> — makes the hostname resolve to your host's IP from inside the container (built-in on Docker Desktop, explicit on Linux).</li>
|
|
184
|
+
</ul>
|
|
185
|
+
|
|
186
|
+
<div class="codeblock"><pre class="code"><button class="copy">Copy</button><code># 5. Start the Appium container (detached so you can exec into it):
|
|
187
|
+
docker compose --profile local-android up -d appium
|
|
188
|
+
|
|
189
|
+
# 6. From inside the container, connect adb to the host emulator:
|
|
190
|
+
docker compose exec appium adb connect host.docker.internal:5555
|
|
191
|
+
# connected to host.docker.internal:5555
|
|
192
|
+
|
|
193
|
+
# 7. Verify the container now sees the emulator:
|
|
194
|
+
docker compose exec appium adb devices
|
|
195
|
+
# List of devices attached
|
|
196
|
+
# host.docker.internal:5555 device ← anything other than "device"
|
|
197
|
+
# means try again from step 4</code></pre></div>
|
|
198
|
+
|
|
199
|
+
<p>The chain is live: <strong>host emulator ← TCP :5555 ← container's adb ← Appium → port :4723 → your host</strong>. Verify Appium is reachable:</p>
|
|
200
|
+
|
|
201
|
+
<div class="codeblock"><pre class="code"><button class="copy">Copy</button><code>curl -s http://localhost:4723/status
|
|
202
|
+
# {"value":{"ready":true,"message":"The server is ready...","build":{"version":"3.x.x"}}}</code></pre></div>
|
|
203
|
+
|
|
204
|
+
<p>From here, you can:</p>
|
|
205
|
+
<ul>
|
|
206
|
+
<li><strong>Run codegen</strong> against the containerized Appium: <code>cd</code> into your taqwright project, run <code>npx taqwright codegen</code>. The inspector opens in your browser, defaults to <code>localhost:4723</code> — just enter your app's <code>appium:appPackage</code> + <code>appium:appActivity</code> (pre-install the APK via <code>adb install</code> on the host first).</li>
|
|
207
|
+
<li><strong>Run tests</strong> from your host shell: <code>npx taqwright test</code> against a project whose <code>use.appium</code> points at <code>localhost:4723</code>.</li>
|
|
208
|
+
</ul>
|
|
209
|
+
|
|
210
|
+
<div class="callout warn">
|
|
211
|
+
<strong>If step 7 prints <code>offline</code>, empty, or step 6 says <code>failed to authenticate</code>:</strong>
|
|
212
|
+
<ul>
|
|
213
|
+
<li><strong><code>failed to authenticate</code></strong> → the container's adb has a different keypair than your host. The compose file mounts <code>~/.android</code> from your host into the container (read-only) so the keys match — make sure that volume is present. If you're running an older compose that doesn't have it, copy the keys manually:
|
|
214
|
+
<code>docker compose cp ~/.android/adbkey appium:/root/.android/adbkey && docker compose cp ~/.android/adbkey.pub appium:/root/.android/adbkey.pub && docker compose exec appium adb kill-server</code>, then retry step 6.</li>
|
|
215
|
+
<li>Emulator went to sleep → <code>adb disconnect host.docker.internal:5555</code> in the container, then re-run step 6.</li>
|
|
216
|
+
<li>Emulator was rebooted → re-run step 4 (<code>adb tcpip 5555</code>) on the host, then step 6.</li>
|
|
217
|
+
<li>Host shows no device in step 3 → no emulator running. Boot one via step 1.</li>
|
|
218
|
+
<li>The emulator may show <strong>"Allow USB debugging from this computer?"</strong> — click <strong>Always allow</strong>.</li>
|
|
219
|
+
</ul>
|
|
220
|
+
</div>
|
|
221
|
+
|
|
222
|
+
<p>When you're done, kill the emulator: <code>adb emu kill</code> (or close its window). And tear down the container: <code>docker compose --profile local-android down</code>.</p>
|
|
223
|
+
|
|
224
|
+
<h3 id="docker-ci-android">CI — cloud Android (BrowserStack / LambdaTest)</h3>
|
|
225
|
+
<p>
|
|
226
|
+
No local Appium and no local emulator. The test runner container talks directly to the cloud provider. Define an <code>android-cloud</code> project in your <code>taqwright.config.ts</code> with <code>device.provider: 'browserstack'</code> (or <code>'lambdatest'</code>) and your credentials in env.
|
|
227
|
+
</p>
|
|
228
|
+
|
|
229
|
+
<div class="codeblock"><pre class="code"><button class="copy">Copy</button><code>export BROWSERSTACK_USERNAME=...
|
|
230
|
+
export BROWSERSTACK_ACCESS_KEY=...
|
|
231
|
+
|
|
232
|
+
docker compose --profile ci-cloud-android run --rm tests-cloud-android</code></pre></div>
|
|
233
|
+
|
|
234
|
+
<p>The container mounts your repo at <code>/work</code>, forwards your credentials, and runs <code>npx taqwright test --project=android-cloud</code>. Results land in <code>./playwright-report/</code> on the host.</p>
|
|
235
|
+
|
|
236
|
+
<h3 id="docker-ci-ios">CI — cloud iOS</h3>
|
|
237
|
+
<p>
|
|
238
|
+
Same image, same env vars; just a different project name. Your <code>ios-cloud</code> project in <code>taqwright.config.ts</code> needs <code>platform: Platform.IOS</code> and <code>device.provider: 'browserstack'</code> (or <code>'lambdatest'</code>) — the cloud handles all the iOS-specific machinery.
|
|
239
|
+
</p>
|
|
240
|
+
|
|
241
|
+
<div class="codeblock"><pre class="code"><button class="copy">Copy</button><code>export BROWSERSTACK_USERNAME=...
|
|
242
|
+
export BROWSERSTACK_ACCESS_KEY=...
|
|
243
|
+
|
|
244
|
+
docker compose --profile ci-cloud-ios run --rm tests-cloud-ios</code></pre></div>
|
|
245
|
+
|
|
246
|
+
<h3 id="docker-verify">Verify the image</h3>
|
|
247
|
+
<p>Run the doctor inside the container — it'll confirm Node / Appium / adb / java are all present:</p>
|
|
248
|
+
|
|
249
|
+
<div class="codeblock"><pre class="code"><button class="copy">Copy</button><code>docker compose run --rm tests-cloud-android npx taqwright doctor</code></pre></div>
|
|
250
|
+
|
|
251
|
+
<p>Expected output — the macOS-only lines (<code>xcrun</code>, <code>Xcode</code>, <code>ffmpeg</code>, <code>iOS simulator</code>) are absent because the container is Linux, and only the <code>uiautomator2</code> Appium driver is in the image (iOS goes through the cloud):</p>
|
|
252
|
+
|
|
253
|
+
<div class="codeblock"><pre class="code"><code>taqwright doctor (v0.0.1)
|
|
254
|
+
[ok] Node.js >= 24 — v24.x.x
|
|
255
|
+
[ok] adb (Android SDK) — on PATH
|
|
256
|
+
[ok] ANDROID_HOME (Appium adb lookup) — ANDROID_HOME=/opt/android-sdk
|
|
257
|
+
[ok] java (JDK for UiAutomator2) — on PATH
|
|
258
|
+
[ok] JAVA_HOME (UiAutomator2 JDK) — JAVA_HOME=/usr/lib/jvm/java-17-openjdk-arm64
|
|
259
|
+
[ok] Appium (test server) — on PATH (v3.x.x)
|
|
260
|
+
[ok] Appium drivers — uiautomator2; not installed: xcuitest (iOS)</code></pre></div>
|
|
261
|
+
|
|
262
|
+
<div class="callout">
|
|
263
|
+
<strong>Apple Silicon Macs:</strong>
|
|
264
|
+
the image is amd64; Docker Desktop runs it under Rosetta. Initial build is slower (SDK download under emulation) but test runs are fine. A native arm64 variant is on the roadmap.
|
|
265
|
+
</div>
|
|
266
|
+
|
|
267
|
+
<div class="pager">
|
|
268
|
+
<a href="parallel.html">
|
|
269
|
+
<div class="label">← Previous</div>
|
|
270
|
+
<div class="title">Parallel runs</div>
|
|
271
|
+
</a>
|
|
272
|
+
<a class="next" href="installation.html">
|
|
273
|
+
<div class="label">Next →</div>
|
|
274
|
+
<div class="title">Back to Installation</div>
|
|
275
|
+
</a>
|
|
276
|
+
</div>
|
|
277
|
+
|
|
278
|
+
</main>
|
|
279
|
+
|
|
280
|
+
<aside class="onthispage">
|
|
281
|
+
<h4>On this page</h4>
|
|
282
|
+
<ol>
|
|
283
|
+
<li><a href="#docker">Overview</a></li>
|
|
284
|
+
<li><a href="#docker-build">Build the image</a>
|
|
285
|
+
<ol class="sub">
|
|
286
|
+
<li><a href="#docker-contents">What's in the image</a></li>
|
|
287
|
+
</ol>
|
|
288
|
+
</li>
|
|
289
|
+
<li><a href="#docker-local-android">Local Android</a>
|
|
290
|
+
<ol class="sub">
|
|
291
|
+
<li><a href="#docker-local-host-side">Host setup</a></li>
|
|
292
|
+
<li><a href="#docker-local-container-side">Container setup</a></li>
|
|
293
|
+
</ol>
|
|
294
|
+
</li>
|
|
295
|
+
<li><a href="#docker-ci-android">CI: cloud Android</a></li>
|
|
296
|
+
<li><a href="#docker-ci-ios">CI: cloud iOS</a></li>
|
|
297
|
+
<li><a href="#docker-verify">Verify</a></li>
|
|
298
|
+
</ol>
|
|
299
|
+
</aside>
|
|
300
|
+
|
|
301
|
+
</div>
|
|
302
|
+
|
|
303
|
+
<footer class="bot">
|
|
304
|
+
<div class="cols">
|
|
305
|
+
<div>
|
|
306
|
+
<h5>Getting started</h5>
|
|
307
|
+
<ul>
|
|
308
|
+
<li><a href="installation.html">Installation</a></li>
|
|
309
|
+
<li><a href="writing-tests.html">Writing tests</a></li>
|
|
310
|
+
<li><a href="generating-tests.html">Generating tests</a></li>
|
|
311
|
+
<li><a href="running-tests.html">Running & debugging</a></li>
|
|
312
|
+
</ul>
|
|
313
|
+
</div>
|
|
314
|
+
<div>
|
|
315
|
+
<h5>Guides</h5>
|
|
316
|
+
<ul>
|
|
317
|
+
<li><a href="custom-reporters.html">Custom reporters</a></li>
|
|
318
|
+
<li><a href="parallel.html">Parallel runs</a></li>
|
|
319
|
+
<li><a href="docker.html">Run in Docker</a></li>
|
|
320
|
+
<li><a href="writing-tests.html#actions">API surface</a></li>
|
|
321
|
+
</ul>
|
|
322
|
+
</div>
|
|
323
|
+
<div>
|
|
324
|
+
<h5>Built on</h5>
|
|
325
|
+
<ul>
|
|
326
|
+
<li><a href="https://playwright.dev/">Playwright</a></li>
|
|
327
|
+
<li><a href="https://appium.io/">Appium 3</a></li>
|
|
328
|
+
</ul>
|
|
329
|
+
</div>
|
|
330
|
+
</div>
|
|
331
|
+
<div class="copy">
|
|
332
|
+
Apache-2.0 licensed · Built on Playwright + Appium
|
|
333
|
+
</div>
|
|
334
|
+
</footer>
|
|
335
|
+
|
|
336
|
+
<script src="docs.js"></script>
|
|
337
|
+
|
|
338
|
+
</body>
|
|
339
|
+
</html>
|