@arcadialdev/arcality 2.2.0
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/.agents/skills/e2e-testing-expert/SKILL.md +28 -0
- package/.agents/skills/frontend-design/LICENSE.txt +177 -0
- package/.agents/skills/frontend-design/SKILL.md +42 -0
- package/.agents/skills/nodejs-backend-patterns/SKILL.md +639 -0
- package/.agents/skills/nodejs-backend-patterns/references/advanced-patterns.md +430 -0
- package/.agents/skills/playwright-best-practices/LICENSE.md +7 -0
- package/.agents/skills/playwright-best-practices/README.md +147 -0
- package/.agents/skills/playwright-best-practices/SKILL.md +303 -0
- package/.agents/skills/playwright-best-practices/advanced/authentication-flows.md +360 -0
- package/.agents/skills/playwright-best-practices/advanced/authentication.md +871 -0
- package/.agents/skills/playwright-best-practices/advanced/clock-mocking.md +364 -0
- package/.agents/skills/playwright-best-practices/advanced/mobile-testing.md +409 -0
- package/.agents/skills/playwright-best-practices/advanced/multi-context.md +288 -0
- package/.agents/skills/playwright-best-practices/advanced/multi-user.md +393 -0
- package/.agents/skills/playwright-best-practices/advanced/network-advanced.md +452 -0
- package/.agents/skills/playwright-best-practices/advanced/third-party.md +464 -0
- package/.agents/skills/playwright-best-practices/architecture/pom-vs-fixtures.md +363 -0
- package/.agents/skills/playwright-best-practices/architecture/test-architecture.md +369 -0
- package/.agents/skills/playwright-best-practices/architecture/when-to-mock.md +383 -0
- package/.agents/skills/playwright-best-practices/browser-apis/browser-apis.md +391 -0
- package/.agents/skills/playwright-best-practices/browser-apis/iframes.md +403 -0
- package/.agents/skills/playwright-best-practices/browser-apis/service-workers.md +504 -0
- package/.agents/skills/playwright-best-practices/browser-apis/websockets.md +403 -0
- package/.agents/skills/playwright-best-practices/core/annotations.md +424 -0
- package/.agents/skills/playwright-best-practices/core/assertions-waiting.md +361 -0
- package/.agents/skills/playwright-best-practices/core/configuration.md +452 -0
- package/.agents/skills/playwright-best-practices/core/fixtures-hooks.md +417 -0
- package/.agents/skills/playwright-best-practices/core/global-setup.md +434 -0
- package/.agents/skills/playwright-best-practices/core/locators.md +242 -0
- package/.agents/skills/playwright-best-practices/core/page-object-model.md +315 -0
- package/.agents/skills/playwright-best-practices/core/projects-dependencies.md +453 -0
- package/.agents/skills/playwright-best-practices/core/test-data.md +492 -0
- package/.agents/skills/playwright-best-practices/core/test-suite-structure.md +361 -0
- package/.agents/skills/playwright-best-practices/core/test-tags.md +298 -0
- package/.agents/skills/playwright-best-practices/debugging/console-errors.md +420 -0
- package/.agents/skills/playwright-best-practices/debugging/debugging.md +504 -0
- package/.agents/skills/playwright-best-practices/debugging/error-testing.md +360 -0
- package/.agents/skills/playwright-best-practices/debugging/flaky-tests.md +496 -0
- package/.agents/skills/playwright-best-practices/frameworks/angular.md +530 -0
- package/.agents/skills/playwright-best-practices/frameworks/nextjs.md +469 -0
- package/.agents/skills/playwright-best-practices/frameworks/react.md +531 -0
- package/.agents/skills/playwright-best-practices/frameworks/vue.md +574 -0
- package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/ci-cd.md +468 -0
- package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/docker.md +283 -0
- package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/github-actions.md +546 -0
- package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/gitlab.md +397 -0
- package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/other-providers.md +521 -0
- package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/parallel-sharding.md +371 -0
- package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/performance.md +453 -0
- package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/reporting.md +424 -0
- package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/test-coverage.md +497 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/accessibility.md +359 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/api-testing.md +719 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/browser-extensions.md +506 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/canvas-webgl.md +493 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/component-testing.md +500 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/drag-drop.md +576 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/electron.md +509 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/file-operations.md +377 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/file-upload-download.md +562 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/forms-validation.md +561 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/graphql-testing.md +331 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/i18n.md +508 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/performance-testing.md +476 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/security-testing.md +430 -0
- package/.agents/skills/playwright-best-practices/testing-patterns/visual-regression.md +634 -0
- package/.env.example +21 -0
- package/README.md +30 -0
- package/bin/arcality.mjs +86 -0
- package/package.json +66 -0
- package/playwright.config.ts +12 -0
- package/scripts/cleanup-qmsdev.mjs +63 -0
- package/scripts/discover-view.mjs +52 -0
- package/scripts/extract-view.mjs +64 -0
- package/scripts/gen-and-run.mjs +838 -0
- package/scripts/init.mjs +290 -0
- package/scripts/migrate-to-central-out.mjs +157 -0
- package/scripts/postinstall.mjs +63 -0
- package/scripts/rebrand-report.mjs +241 -0
- package/scripts/setup.mjs +166 -0
- package/src/KnowledgeService.ts +239 -0
- package/src/arcalityClient.mjs +266 -0
- package/src/configLoader.mjs +179 -0
- package/src/configManager.mjs +172 -0
- package/src/consoleBanner.ts +32 -0
- package/src/envSetup.ts +205 -0
- package/src/index.ts +25 -0
- package/src/projectInspector.ts +42 -0
- package/src/services/collectiveMemoryService.ts +178 -0
- package/src/testRunner.ts +201 -0
- package/tests/_helpers/ArcalityReporter.ts +490 -0
- package/tests/_helpers/agentic-runner.spec.ts +741 -0
- package/tests/_helpers/ai-agent-helper.ts +1573 -0
- package/tests/_helpers/discover-view.spec.ts +238 -0
- package/tests/_helpers/extract-view.spec.ts +118 -0
- package/tests/_helpers/qa-tools.ts +333 -0
- package/tests/_helpers/smart-action.spec.ts +1458 -0
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
# Playwright Configuration
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
1. [CLI Quick Reference](#cli-quick-reference)
|
|
6
|
+
2. [Decision Guide](#decision-guide)
|
|
7
|
+
3. [Production-Ready Config](#production-ready-config)
|
|
8
|
+
4. [Patterns](#patterns)
|
|
9
|
+
5. [Anti-Patterns](#anti-patterns)
|
|
10
|
+
6. [Troubleshooting](#troubleshooting)
|
|
11
|
+
7. [Related](#related)
|
|
12
|
+
|
|
13
|
+
> **When to use**: Setting up a new project, adjusting timeouts, adding browser targets, configuring CI behavior, or managing environment-specific settings.
|
|
14
|
+
|
|
15
|
+
## CLI Quick Reference
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx playwright init # scaffold config + first test
|
|
19
|
+
npx playwright test --config=custom.config.ts # use alternate config
|
|
20
|
+
npx playwright test --project=chromium # run single project
|
|
21
|
+
npx playwright test --reporter=html # override reporter
|
|
22
|
+
npx playwright test --grep @smoke # run tests tagged @smoke
|
|
23
|
+
npx playwright test --grep-invert @slow # exclude @slow tests
|
|
24
|
+
npx playwright show-report # open last HTML report
|
|
25
|
+
DEBUG=pw:api npx playwright test # verbose logging
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Decision Guide
|
|
29
|
+
|
|
30
|
+
### Timeout Selection
|
|
31
|
+
|
|
32
|
+
| Symptom | Setting | Default | Recommended |
|
|
33
|
+
|---------|---------|---------|-------------|
|
|
34
|
+
| Test takes too long overall | `timeout` | 30s | 30-60s (max 120s) |
|
|
35
|
+
| Assertion retries too long/short | `expect.timeout` | 5s | 5-10s |
|
|
36
|
+
| `page.goto()` or `waitForURL()` times out | `navigationTimeout` | 30s | 10-30s |
|
|
37
|
+
| `click()`, `fill()` time out | `actionTimeout` | 0 (unlimited) | 10-15s |
|
|
38
|
+
| Dev server slow to start | `webServer.timeout` | 60s | 60-180s |
|
|
39
|
+
|
|
40
|
+
### Server Management
|
|
41
|
+
|
|
42
|
+
| Scenario | Approach |
|
|
43
|
+
|----------|----------|
|
|
44
|
+
| App in same repo | `webServer` with `reuseExistingServer: !process.env.CI` |
|
|
45
|
+
| Separate repos | Manual start or Docker Compose |
|
|
46
|
+
| Testing deployed environment | No `webServer`; set `baseURL` via env |
|
|
47
|
+
| Multiple services | Array of `webServer` entries |
|
|
48
|
+
|
|
49
|
+
### Single vs Multi-Project
|
|
50
|
+
|
|
51
|
+
| Scenario | Approach |
|
|
52
|
+
|----------|----------|
|
|
53
|
+
| Early development | Single project (chromium only) |
|
|
54
|
+
| Pre-release validation | Multi-project: chromium + firefox + webkit |
|
|
55
|
+
| Mobile-responsive app | Add mobile projects alongside desktop |
|
|
56
|
+
| Auth + non-auth tests | Setup project with dependencies |
|
|
57
|
+
| Tight CI budget | Chromium on PRs; all browsers on main |
|
|
58
|
+
|
|
59
|
+
### globalSetup vs Setup Projects vs Fixtures
|
|
60
|
+
|
|
61
|
+
| Need | Use |
|
|
62
|
+
|------|-----|
|
|
63
|
+
| One-time DB seed | `globalSetup` |
|
|
64
|
+
| Shared browser auth | Setup project with `dependencies` |
|
|
65
|
+
| Per-test isolated state | Custom fixture via `test.extend()` |
|
|
66
|
+
| Cleanup after all tests | `globalTeardown` |
|
|
67
|
+
|
|
68
|
+
## Production-Ready Config
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
// playwright.config.ts
|
|
72
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
73
|
+
import dotenv from 'dotenv';
|
|
74
|
+
import path from 'path';
|
|
75
|
+
|
|
76
|
+
dotenv.config({ path: path.resolve(__dirname, '.env') });
|
|
77
|
+
|
|
78
|
+
export default defineConfig({
|
|
79
|
+
testDir: './e2e',
|
|
80
|
+
testMatch: '**/*.spec.ts',
|
|
81
|
+
|
|
82
|
+
fullyParallel: true,
|
|
83
|
+
forbidOnly: !!process.env.CI,
|
|
84
|
+
retries: process.env.CI ? 2 : 0,
|
|
85
|
+
workers: process.env.CI ? '50%' : undefined,
|
|
86
|
+
|
|
87
|
+
reporter: process.env.CI
|
|
88
|
+
? [['html', { open: 'never' }], ['github']]
|
|
89
|
+
: [['html', { open: 'on-failure' }]],
|
|
90
|
+
|
|
91
|
+
timeout: 30_000,
|
|
92
|
+
expect: { timeout: 5_000 },
|
|
93
|
+
|
|
94
|
+
use: {
|
|
95
|
+
baseURL: process.env.BASE_URL || 'http://localhost:4000',
|
|
96
|
+
actionTimeout: 10_000,
|
|
97
|
+
navigationTimeout: 15_000,
|
|
98
|
+
trace: 'on-first-retry',
|
|
99
|
+
screenshot: 'only-on-failure',
|
|
100
|
+
video: 'retain-on-failure',
|
|
101
|
+
locale: 'en-US',
|
|
102
|
+
timezoneId: 'America/Los_Angeles',
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
projects: [
|
|
106
|
+
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
|
|
107
|
+
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
|
|
108
|
+
{ name: 'webkit', use: { ...devices['Desktop Safari'] } },
|
|
109
|
+
{ name: 'mobile-chrome', use: { ...devices['Pixel 7'] } },
|
|
110
|
+
{ name: 'mobile-safari', use: { ...devices['iPhone 14'] } },
|
|
111
|
+
],
|
|
112
|
+
|
|
113
|
+
webServer: {
|
|
114
|
+
command: 'npm run start',
|
|
115
|
+
url: 'http://localhost:4000',
|
|
116
|
+
reuseExistingServer: !process.env.CI,
|
|
117
|
+
timeout: 120_000,
|
|
118
|
+
stdout: 'pipe',
|
|
119
|
+
stderr: 'pipe',
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Patterns
|
|
125
|
+
|
|
126
|
+
### Environment-Specific Configuration
|
|
127
|
+
|
|
128
|
+
**Use when**: Tests run against dev, staging, and production environments.
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
// playwright.config.ts
|
|
132
|
+
import { defineConfig } from '@playwright/test';
|
|
133
|
+
import dotenv from 'dotenv';
|
|
134
|
+
import path from 'path';
|
|
135
|
+
|
|
136
|
+
const ENV = process.env.TEST_ENV || 'local';
|
|
137
|
+
dotenv.config({ path: path.resolve(__dirname, `.env.${ENV}`) });
|
|
138
|
+
|
|
139
|
+
const envConfig: Record<string, { baseURL: string; retries: number }> = {
|
|
140
|
+
local: { baseURL: 'http://localhost:4000', retries: 0 },
|
|
141
|
+
staging: { baseURL: 'https://staging.myapp.com', retries: 2 },
|
|
142
|
+
prod: { baseURL: 'https://myapp.com', retries: 2 },
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export default defineConfig({
|
|
146
|
+
testDir: './e2e',
|
|
147
|
+
retries: envConfig[ENV].retries,
|
|
148
|
+
use: { baseURL: envConfig[ENV].baseURL },
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
TEST_ENV=staging npx playwright test
|
|
154
|
+
TEST_ENV=prod npx playwright test --grep @smoke
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Setup Project with Dependencies
|
|
158
|
+
|
|
159
|
+
**Use when**: Tests need shared authentication state before running.
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
// playwright.config.ts
|
|
163
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
164
|
+
|
|
165
|
+
export default defineConfig({
|
|
166
|
+
testDir: './e2e',
|
|
167
|
+
projects: [
|
|
168
|
+
{
|
|
169
|
+
name: 'setup',
|
|
170
|
+
testMatch: /auth\.setup\.ts/,
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
name: 'chromium',
|
|
174
|
+
use: {
|
|
175
|
+
...devices['Desktop Chrome'],
|
|
176
|
+
storageState: 'playwright/.auth/session.json',
|
|
177
|
+
},
|
|
178
|
+
dependencies: ['setup'],
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
name: 'firefox',
|
|
182
|
+
use: {
|
|
183
|
+
...devices['Desktop Firefox'],
|
|
184
|
+
storageState: 'playwright/.auth/session.json',
|
|
185
|
+
},
|
|
186
|
+
dependencies: ['setup'],
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
});
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
// e2e/auth.setup.ts
|
|
194
|
+
import { test as setup, expect } from '@playwright/test';
|
|
195
|
+
|
|
196
|
+
const authFile = 'playwright/.auth/session.json';
|
|
197
|
+
|
|
198
|
+
setup('authenticate', async ({ page }) => {
|
|
199
|
+
await page.goto('/login');
|
|
200
|
+
await page.getByLabel('Username').fill('testuser@example.com');
|
|
201
|
+
await page.getByLabel('Password').fill(process.env.TEST_PASSWORD!);
|
|
202
|
+
await page.getByRole('button', { name: 'Log in' }).click();
|
|
203
|
+
await expect(page.getByRole('heading', { name: 'Home' })).toBeVisible();
|
|
204
|
+
await page.context().storageState({ path: authFile });
|
|
205
|
+
});
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### webServer with Build Step
|
|
209
|
+
|
|
210
|
+
**Use when**: Tests need a running application server managed by Playwright.
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
// playwright.config.ts
|
|
214
|
+
import { defineConfig } from '@playwright/test';
|
|
215
|
+
|
|
216
|
+
export default defineConfig({
|
|
217
|
+
testDir: './e2e',
|
|
218
|
+
use: { baseURL: 'http://localhost:4000' },
|
|
219
|
+
webServer: {
|
|
220
|
+
command: process.env.CI
|
|
221
|
+
? 'npm run build && npm run preview'
|
|
222
|
+
: 'npm run dev',
|
|
223
|
+
url: 'http://localhost:4000',
|
|
224
|
+
reuseExistingServer: !process.env.CI,
|
|
225
|
+
timeout: 120_000,
|
|
226
|
+
env: {
|
|
227
|
+
NODE_ENV: 'test',
|
|
228
|
+
DB_URL: process.env.DB_URL || 'postgresql://localhost:5432/testdb',
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### globalSetup / globalTeardown
|
|
235
|
+
|
|
236
|
+
**Use when**: One-time non-browser work like seeding a database. Runs once per test run.
|
|
237
|
+
|
|
238
|
+
```ts
|
|
239
|
+
// playwright.config.ts
|
|
240
|
+
import { defineConfig } from '@playwright/test';
|
|
241
|
+
|
|
242
|
+
export default defineConfig({
|
|
243
|
+
testDir: './e2e',
|
|
244
|
+
globalSetup: './e2e/setup.ts',
|
|
245
|
+
globalTeardown: './e2e/teardown.ts',
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
```ts
|
|
250
|
+
// e2e/setup.ts
|
|
251
|
+
import { FullConfig } from '@playwright/test';
|
|
252
|
+
|
|
253
|
+
export default async function globalSetup(config: FullConfig) {
|
|
254
|
+
const { execSync } = await import('child_process');
|
|
255
|
+
execSync('npx prisma db seed', { stdio: 'inherit' });
|
|
256
|
+
process.env.TEST_RUN_ID = `run-${Date.now()}`;
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
```ts
|
|
261
|
+
// e2e/teardown.ts
|
|
262
|
+
import { FullConfig } from '@playwright/test';
|
|
263
|
+
|
|
264
|
+
export default async function globalTeardown(config: FullConfig) {
|
|
265
|
+
const { execSync } = await import('child_process');
|
|
266
|
+
execSync('npx prisma db push --force-reset', { stdio: 'inherit' });
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Environment Variables with .env
|
|
271
|
+
|
|
272
|
+
**Use when**: Managing secrets, URLs, or feature flags without hardcoding.
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
# .env.example (commit this)
|
|
276
|
+
BASE_URL=http://localhost:4000
|
|
277
|
+
TEST_PASSWORD=
|
|
278
|
+
API_KEY=
|
|
279
|
+
|
|
280
|
+
# .env.local (gitignored)
|
|
281
|
+
BASE_URL=http://localhost:4000
|
|
282
|
+
TEST_PASSWORD=secret123
|
|
283
|
+
API_KEY=dev-key-abc
|
|
284
|
+
|
|
285
|
+
# .env.staging (gitignored)
|
|
286
|
+
BASE_URL=https://staging.myapp.com
|
|
287
|
+
TEST_PASSWORD=staging-pass
|
|
288
|
+
API_KEY=staging-key-xyz
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
# .gitignore
|
|
293
|
+
.env
|
|
294
|
+
.env.local
|
|
295
|
+
.env.staging
|
|
296
|
+
.env.production
|
|
297
|
+
playwright/.auth/
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Install dotenv:
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
npm install -D dotenv
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Tag-Based Test Filtering
|
|
307
|
+
|
|
308
|
+
**Use when**: Running subsets of tests in different CI stages (PR vs nightly).
|
|
309
|
+
|
|
310
|
+
```ts
|
|
311
|
+
// playwright.config.ts
|
|
312
|
+
import { defineConfig } from '@playwright/test';
|
|
313
|
+
|
|
314
|
+
export default defineConfig({
|
|
315
|
+
testDir: './e2e',
|
|
316
|
+
|
|
317
|
+
// Filter by tags in CI
|
|
318
|
+
grep: process.env.CI ? /@smoke|@critical/ : undefined,
|
|
319
|
+
grepInvert: process.env.CI ? /@flaky/ : undefined,
|
|
320
|
+
});
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
**Project-specific filtering:**
|
|
324
|
+
|
|
325
|
+
```ts
|
|
326
|
+
// playwright.config.ts
|
|
327
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
328
|
+
|
|
329
|
+
export default defineConfig({
|
|
330
|
+
testDir: './e2e',
|
|
331
|
+
projects: [
|
|
332
|
+
{
|
|
333
|
+
name: 'smoke',
|
|
334
|
+
grep: /@smoke/,
|
|
335
|
+
use: { ...devices['Desktop Chrome'] },
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
name: 'regression',
|
|
339
|
+
grepInvert: /@smoke/,
|
|
340
|
+
use: { ...devices['Desktop Chrome'] },
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
name: 'critical-only',
|
|
344
|
+
grep: /@critical/,
|
|
345
|
+
use: { ...devices['Desktop Chrome'] },
|
|
346
|
+
},
|
|
347
|
+
],
|
|
348
|
+
});
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
# Run specific project
|
|
353
|
+
npx playwright test --project=smoke
|
|
354
|
+
npx playwright test --project=regression
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### Artifact Collection Strategy
|
|
358
|
+
|
|
359
|
+
| Setting | Local | CI | Reason |
|
|
360
|
+
|---------|-------|-----|--------|
|
|
361
|
+
| `trace` | `'off'` | `'on-first-retry'` | Traces are large; collect on failure only |
|
|
362
|
+
| `screenshot` | `'off'` | `'only-on-failure'` | Useful for CI debugging |
|
|
363
|
+
| `video` | `'off'` | `'retain-on-failure'` | Recording slows tests |
|
|
364
|
+
|
|
365
|
+
```ts
|
|
366
|
+
// playwright.config.ts
|
|
367
|
+
import { defineConfig } from '@playwright/test';
|
|
368
|
+
|
|
369
|
+
export default defineConfig({
|
|
370
|
+
testDir: './e2e',
|
|
371
|
+
use: {
|
|
372
|
+
trace: process.env.CI ? 'on-first-retry' : 'off',
|
|
373
|
+
screenshot: process.env.CI ? 'only-on-failure' : 'off',
|
|
374
|
+
video: process.env.CI ? 'retain-on-failure' : 'off',
|
|
375
|
+
},
|
|
376
|
+
});
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
## Anti-Patterns
|
|
380
|
+
|
|
381
|
+
| Don't | Problem | Do Instead |
|
|
382
|
+
|-------|---------|------------|
|
|
383
|
+
| `timeout: 300_000` globally | Masks flaky tests; slow CI | Fix root cause; keep 30s default |
|
|
384
|
+
| Hardcoded URLs: `page.goto('http://localhost:4000/login')` | Breaks in other environments | Use `baseURL` + relative paths |
|
|
385
|
+
| All browsers on every PR | 3x CI time | Chromium on PRs; all on main |
|
|
386
|
+
| `trace: 'on'` always | Huge artifacts, slow uploads | `trace: 'on-first-retry'` |
|
|
387
|
+
| `video: 'on'` always | Massive storage; slow tests | `video: 'retain-on-failure'` |
|
|
388
|
+
| Config in test files: `test.use({ viewport: {...} })` everywhere | Scattered, inconsistent | Define once in project config |
|
|
389
|
+
| `retries: 3` locally | Hides flakiness | `retries: 0` local, `retries: 2` CI |
|
|
390
|
+
| No `forbidOnly` in CI | Committed `test.only` runs single test | `forbidOnly: !!process.env.CI` |
|
|
391
|
+
| `globalSetup` for browser auth | No browser context available | Use setup project with dependencies |
|
|
392
|
+
| Committing `.env` with credentials | Security risk | Commit `.env.example` only |
|
|
393
|
+
|
|
394
|
+
## Troubleshooting
|
|
395
|
+
|
|
396
|
+
### baseURL Not Working
|
|
397
|
+
|
|
398
|
+
**Cause**: Using absolute URL in `page.goto()` ignores `baseURL`.
|
|
399
|
+
|
|
400
|
+
```ts
|
|
401
|
+
// Wrong - ignores baseURL
|
|
402
|
+
await page.goto('http://localhost:4000/dashboard');
|
|
403
|
+
|
|
404
|
+
// Correct - uses baseURL
|
|
405
|
+
await page.goto('/dashboard');
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### webServer Starts But Tests Get Connection Refused
|
|
409
|
+
|
|
410
|
+
**Cause**: `webServer.url` doesn't match actual server address or health check returns non-200.
|
|
411
|
+
|
|
412
|
+
```ts
|
|
413
|
+
webServer: {
|
|
414
|
+
command: 'npm run dev',
|
|
415
|
+
url: 'http://localhost:4000/api/health', // use real endpoint
|
|
416
|
+
reuseExistingServer: !process.env.CI,
|
|
417
|
+
timeout: 120_000,
|
|
418
|
+
},
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
### Tests Pass Locally But Timeout in CI
|
|
422
|
+
|
|
423
|
+
**Cause**: CI machines are slower. Increase timeouts and reduce workers:
|
|
424
|
+
|
|
425
|
+
```ts
|
|
426
|
+
export default defineConfig({
|
|
427
|
+
workers: process.env.CI ? '50%' : undefined,
|
|
428
|
+
use: {
|
|
429
|
+
navigationTimeout: process.env.CI ? 30_000 : 15_000,
|
|
430
|
+
actionTimeout: process.env.CI ? 15_000 : 10_000,
|
|
431
|
+
},
|
|
432
|
+
});
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### "Target page, context or browser has been closed"
|
|
436
|
+
|
|
437
|
+
**Cause**: Test exceeded `timeout` and Playwright tore down browser during action.
|
|
438
|
+
|
|
439
|
+
**Fix**: Don't increase global timeout. Find slow step using trace:
|
|
440
|
+
|
|
441
|
+
```bash
|
|
442
|
+
npx playwright test --trace on
|
|
443
|
+
npx playwright show-report
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
## Related
|
|
447
|
+
|
|
448
|
+
- [test-tags.md](./test-tags.md) - tagging and filtering tests with `--grep`
|
|
449
|
+
- [fixtures-hooks.md](./fixtures-hooks.md) - custom fixtures for per-test state
|
|
450
|
+
- [test-suite-structure.md](test-suite-structure.md) - file structure and naming
|
|
451
|
+
- [authentication.md](../advanced/authentication.md) - setup projects for shared auth
|
|
452
|
+
- [projects-dependencies.md](./projects-dependencies.md) - advanced multi-project patterns
|