@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,371 @@
|
|
|
1
|
+
# Sharding and Parallel Execution
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
1. [CLI Commands](#cli-commands)
|
|
6
|
+
2. [Patterns](#patterns)
|
|
7
|
+
3. [Decision Guide](#decision-guide)
|
|
8
|
+
4. [Anti-Patterns](#anti-patterns)
|
|
9
|
+
5. [Troubleshooting](#troubleshooting)
|
|
10
|
+
|
|
11
|
+
> **When to use**: Speeding up test suites by running tests concurrently on one machine (workers) or splitting across multiple CI jobs (sharding).
|
|
12
|
+
|
|
13
|
+
## CLI Commands
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Parallelism within one machine
|
|
17
|
+
npx playwright test --workers=4
|
|
18
|
+
npx playwright test --workers=50%
|
|
19
|
+
|
|
20
|
+
# Splitting across CI jobs
|
|
21
|
+
npx playwright test --shard=1/4
|
|
22
|
+
npx playwright test --shard=2/4
|
|
23
|
+
|
|
24
|
+
# Merging shard outputs
|
|
25
|
+
npx playwright merge-reports ./blob-report
|
|
26
|
+
npx playwright merge-reports --reporter=html,json ./blob-report
|
|
27
|
+
|
|
28
|
+
# Override config for single run
|
|
29
|
+
npx playwright test --fully-parallel
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Patterns
|
|
33
|
+
|
|
34
|
+
### Worker Configuration
|
|
35
|
+
|
|
36
|
+
**Use when**: Controlling concurrent test execution on a single machine.
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
// playwright.config.ts
|
|
40
|
+
import { defineConfig } from "@playwright/test";
|
|
41
|
+
|
|
42
|
+
export default defineConfig({
|
|
43
|
+
// Tests WITHIN a file also run in parallel
|
|
44
|
+
fullyParallel: true,
|
|
45
|
+
|
|
46
|
+
// Worker count options:
|
|
47
|
+
// - undefined: auto-detect (half CPU cores)
|
|
48
|
+
// - number: fixed count
|
|
49
|
+
// - string: percentage of cores
|
|
50
|
+
workers: process.env.CI ? "50%" : undefined,
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**`fullyParallel` behavior:**
|
|
55
|
+
|
|
56
|
+
| Setting | Files parallel | Tests in file parallel |
|
|
57
|
+
| -------------------------------- | -------------- | ---------------------- |
|
|
58
|
+
| `fullyParallel: false` (default) | Yes | No (serial) |
|
|
59
|
+
| `fullyParallel: true` | Yes | Yes |
|
|
60
|
+
|
|
61
|
+
**Serial execution for specific files:**
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
// tests/checkout-flow.spec.ts
|
|
65
|
+
import { test, expect } from "@playwright/test";
|
|
66
|
+
|
|
67
|
+
test.describe.configure({ mode: "serial" });
|
|
68
|
+
|
|
69
|
+
test("add items to cart", async ({ page }) => {
|
|
70
|
+
// ...
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("complete payment", async ({ page }) => {
|
|
74
|
+
// ...
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Sharding Across CI Machines
|
|
79
|
+
|
|
80
|
+
**Use when**: Suite exceeds 5 minutes even with maximum workers.
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Job 1 Job 2 Job 3 Job 4
|
|
84
|
+
--shard=1/4 --shard=2/4 --shard=3/4 --shard=4/4
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Config for sharded runs:**
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
// playwright.config.ts
|
|
91
|
+
import { defineConfig } from "@playwright/test";
|
|
92
|
+
|
|
93
|
+
export default defineConfig({
|
|
94
|
+
fullyParallel: true,
|
|
95
|
+
workers: process.env.CI ? "50%" : undefined,
|
|
96
|
+
|
|
97
|
+
reporter: process.env.CI
|
|
98
|
+
? [["blob"], ["github"]]
|
|
99
|
+
: [["html", { open: "on-failure" }]],
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Merging Shard Reports
|
|
104
|
+
|
|
105
|
+
**Use when**: Combining blob reports from multiple shards into a unified report.
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Merge all blobs into HTML
|
|
109
|
+
npx playwright merge-reports --reporter=html ./all-blob-reports
|
|
110
|
+
|
|
111
|
+
# Multiple formats
|
|
112
|
+
npx playwright merge-reports --reporter=html,json,junit ./all-blob-reports
|
|
113
|
+
|
|
114
|
+
# Custom output location
|
|
115
|
+
PLAYWRIGHT_HTML_REPORT=merged-report npx playwright merge-reports --reporter=html ./all-blob-reports
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**GitHub Actions merge job:**
|
|
119
|
+
|
|
120
|
+
```yaml
|
|
121
|
+
merge-reports:
|
|
122
|
+
if: ${{ !cancelled() }}
|
|
123
|
+
needs: test
|
|
124
|
+
runs-on: ubuntu-latest
|
|
125
|
+
steps:
|
|
126
|
+
- uses: actions/checkout@v4
|
|
127
|
+
- run: npm ci
|
|
128
|
+
|
|
129
|
+
- uses: actions/download-artifact@v4
|
|
130
|
+
with:
|
|
131
|
+
path: all-blob-reports
|
|
132
|
+
pattern: blob-report-*
|
|
133
|
+
merge-multiple: true
|
|
134
|
+
|
|
135
|
+
- run: npx playwright merge-reports --reporter=html ./all-blob-reports
|
|
136
|
+
|
|
137
|
+
- uses: actions/upload-artifact@v4
|
|
138
|
+
with:
|
|
139
|
+
name: playwright-report
|
|
140
|
+
path: playwright-report/
|
|
141
|
+
retention-days: 14
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Worker-Scoped Fixtures
|
|
145
|
+
|
|
146
|
+
**Use when**: Expensive resources (DB connections, auth tokens) should be created once per worker, not per test.
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
// fixtures.ts
|
|
150
|
+
import { test as base } from "@playwright/test";
|
|
151
|
+
|
|
152
|
+
type WorkerFixtures = {
|
|
153
|
+
dbClient: DatabaseClient;
|
|
154
|
+
apiToken: string;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export const test = base.extend<{}, WorkerFixtures>({
|
|
158
|
+
dbClient: [
|
|
159
|
+
async ({}, use) => {
|
|
160
|
+
const client = await DatabaseClient.connect(process.env.DB_URL!);
|
|
161
|
+
await use(client);
|
|
162
|
+
await client.disconnect();
|
|
163
|
+
},
|
|
164
|
+
{ scope: "worker" },
|
|
165
|
+
],
|
|
166
|
+
|
|
167
|
+
apiToken: [
|
|
168
|
+
async ({}, use, workerInfo) => {
|
|
169
|
+
const res = await fetch(`${process.env.API_URL}/auth`, {
|
|
170
|
+
method: "POST",
|
|
171
|
+
headers: { "Content-Type": "application/json" },
|
|
172
|
+
body: JSON.stringify({
|
|
173
|
+
user: `test-user-${workerInfo.workerIndex}`,
|
|
174
|
+
password: process.env.TEST_PASSWORD,
|
|
175
|
+
}),
|
|
176
|
+
});
|
|
177
|
+
const { token } = await res.json();
|
|
178
|
+
await use(token);
|
|
179
|
+
},
|
|
180
|
+
{ scope: "worker" },
|
|
181
|
+
],
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
export { expect } from "@playwright/test";
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Test Isolation for Parallelism
|
|
188
|
+
|
|
189
|
+
**Use when**: Preparing tests to run without interference.
|
|
190
|
+
|
|
191
|
+
Each test must create its own state. No test should depend on or modify shared state.
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
// BAD: Shared user causes race conditions
|
|
195
|
+
test("edit settings", async ({ page }) => {
|
|
196
|
+
await page.goto("/users/test-user/settings");
|
|
197
|
+
await page.getByLabel("Email").fill("new@example.com");
|
|
198
|
+
await page.getByRole("button", { name: "Save" }).click();
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
// GOOD: Unique user per test
|
|
202
|
+
test("edit settings", async ({ page, request }) => {
|
|
203
|
+
const res = await request.post("/api/users", {
|
|
204
|
+
data: { name: `user-${Date.now()}`, email: `${Date.now()}@test.com` },
|
|
205
|
+
});
|
|
206
|
+
const user = await res.json();
|
|
207
|
+
|
|
208
|
+
await page.goto(`/users/${user.id}/settings`);
|
|
209
|
+
await page.getByLabel("Email").fill("updated@example.com");
|
|
210
|
+
await page.getByRole("button", { name: "Save" }).click();
|
|
211
|
+
await expect(page.getByLabel("Email")).toHaveValue("updated@example.com");
|
|
212
|
+
|
|
213
|
+
await request.delete(`/api/users/${user.id}`);
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Using `testInfo` for unique identifiers:**
|
|
218
|
+
|
|
219
|
+
```ts
|
|
220
|
+
import { test, expect } from "@playwright/test";
|
|
221
|
+
|
|
222
|
+
test("submit order", async ({ page }, testInfo) => {
|
|
223
|
+
const orderId = `order-${testInfo.workerIndex}-${Date.now()}`;
|
|
224
|
+
await page.goto(`/orders/new?ref=${orderId}`);
|
|
225
|
+
// ...
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Dynamic Shard Count
|
|
230
|
+
|
|
231
|
+
**Use when**: Automatically adjusting shards based on test count.
|
|
232
|
+
|
|
233
|
+
```yaml
|
|
234
|
+
# .github/workflows/playwright.yml
|
|
235
|
+
jobs:
|
|
236
|
+
calculate-shards:
|
|
237
|
+
runs-on: ubuntu-latest
|
|
238
|
+
outputs:
|
|
239
|
+
shard-count: ${{ steps.calc.outputs.count }}
|
|
240
|
+
shard-matrix: ${{ steps.calc.outputs.matrix }}
|
|
241
|
+
steps:
|
|
242
|
+
- uses: actions/checkout@v4
|
|
243
|
+
- run: npm ci
|
|
244
|
+
- id: calc
|
|
245
|
+
run: |
|
|
246
|
+
TEST_COUNT=$(npx playwright test --list --reporter=json 2>/dev/null | node -e "
|
|
247
|
+
const data = require('fs').readFileSync('/dev/stdin', 'utf8');
|
|
248
|
+
const parsed = JSON.parse(data);
|
|
249
|
+
console.log(parsed.suites?.reduce((acc, s) => acc + (s.specs?.length || 0), 0) || 0);
|
|
250
|
+
")
|
|
251
|
+
# 1 shard per 20 tests, min 1, max 8
|
|
252
|
+
SHARDS=$(( (TEST_COUNT + 19) / 20 ))
|
|
253
|
+
SHARDS=$(( SHARDS > 8 ? 8 : SHARDS ))
|
|
254
|
+
SHARDS=$(( SHARDS < 1 ? 1 : SHARDS ))
|
|
255
|
+
MATRIX="["
|
|
256
|
+
for i in $(seq 1 $SHARDS); do
|
|
257
|
+
[ $i -gt 1 ] && MATRIX+=","
|
|
258
|
+
MATRIX+="\"$i/$SHARDS\""
|
|
259
|
+
done
|
|
260
|
+
MATRIX+="]"
|
|
261
|
+
echo "count=$SHARDS" >> $GITHUB_OUTPUT
|
|
262
|
+
echo "matrix=$MATRIX" >> $GITHUB_OUTPUT
|
|
263
|
+
|
|
264
|
+
test:
|
|
265
|
+
needs: calculate-shards
|
|
266
|
+
runs-on: ubuntu-latest
|
|
267
|
+
strategy:
|
|
268
|
+
fail-fast: false
|
|
269
|
+
matrix:
|
|
270
|
+
shard: ${{ fromJson(needs.calculate-shards.outputs.shard-matrix) }}
|
|
271
|
+
steps:
|
|
272
|
+
- uses: actions/checkout@v4
|
|
273
|
+
- run: npm ci
|
|
274
|
+
- run: npx playwright install --with-deps
|
|
275
|
+
- run: npx playwright test --shard=${{ matrix.shard }}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Decision Guide
|
|
279
|
+
|
|
280
|
+
| Scenario | Workers | Shards | Reason |
|
|
281
|
+
| -------------------------------- | -------------- | ------ | --------------------------------------- |
|
|
282
|
+
| < 50 tests, < 5 min | Auto (default) | None | No optimization needed |
|
|
283
|
+
| 50-200 tests, 5-15 min | `'50%'` in CI | 2-4 | Balance speed and cost |
|
|
284
|
+
| 200+ tests, > 15 min | `'50%'` in CI | 4-8 | Keep feedback under 10 min |
|
|
285
|
+
| Flaky due to resource contention | Reduce to 2 | Keep | Less CPU/memory pressure |
|
|
286
|
+
| Tests modify shared database | 1 or isolate | Useful | Sharding splits files; workers run them |
|
|
287
|
+
| CI has limited resources | 1 or `'25%'` | More | Compensate with more machines |
|
|
288
|
+
|
|
289
|
+
| Aspect | Workers (in-process) | Shards (across machines) |
|
|
290
|
+
| -------------- | ------------------------- | -------------------------- |
|
|
291
|
+
| What it splits | Tests across CPU cores | Test files across CI jobs |
|
|
292
|
+
| Controlled by | Config or `--workers` CLI | `--shard=X/Y` CLI flag |
|
|
293
|
+
| Shares memory | Yes | No |
|
|
294
|
+
| Report merging | Not needed | Required (`merge-reports`) |
|
|
295
|
+
| Cost | Free (same machine) | More CI minutes |
|
|
296
|
+
|
|
297
|
+
## Anti-Patterns
|
|
298
|
+
|
|
299
|
+
| Anti-Pattern | Problem | Solution |
|
|
300
|
+
| --------------------------------------- | ---------------------------------------- | ---------------------------------------------------- |
|
|
301
|
+
| `fullyParallel: false` without reason | Tests in files run serially | Set `fullyParallel: true` unless tests need serial |
|
|
302
|
+
| `workers: 1` in CI "for safety" | Negates parallelism | Fix isolation issues; use `workers: '50%'` |
|
|
303
|
+
| Hardcoded shared user account | Race conditions in parallel runs | Each test creates unique data |
|
|
304
|
+
| Sharding without blob reporter | Each shard produces separate HTML report | Configure `reporter: [['blob']]` for CI |
|
|
305
|
+
| Sharding with 3 tests | Setup overhead exceeds time saved | Only shard when suite > 5 minutes |
|
|
306
|
+
| `test.describe.serial()` everywhere | Kills parallelism, creates dependencies | Use only when tests genuinely need prior state |
|
|
307
|
+
| Workers > CPU cores | Context switching overhead | Use `'50%'` or auto-detect |
|
|
308
|
+
| Missing `fail-fast: false` in CI matrix | One shard failure cancels others | Always set `fail-fast: false` for sharded strategies |
|
|
309
|
+
|
|
310
|
+
## Troubleshooting
|
|
311
|
+
|
|
312
|
+
### Tests pass solo but fail together
|
|
313
|
+
|
|
314
|
+
- **Shared state**. Make test data unique:
|
|
315
|
+
```ts
|
|
316
|
+
test("create item", async ({ request }, ti) => {
|
|
317
|
+
await request.post("/api/items", {
|
|
318
|
+
data: { name: `Item-${ti.workerIndex}-${Date.now()}` },
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### "No tests found" in some shards
|
|
324
|
+
|
|
325
|
+
- **Too many shards**. Never exceed file count:
|
|
326
|
+
```bash
|
|
327
|
+
npx playwright test --shard=1/10 # ok if 10 files
|
|
328
|
+
npx playwright test --shard=1/20 # too many, some shards empty
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Merged report missing results
|
|
332
|
+
|
|
333
|
+
- **Blob reports collide**. Use unique names:
|
|
334
|
+
```yaml
|
|
335
|
+
# Each shard
|
|
336
|
+
- uses: actions/upload-artifact@v4
|
|
337
|
+
with:
|
|
338
|
+
name: blob-report-${{ strategy.job-index }}
|
|
339
|
+
path: blob-report/
|
|
340
|
+
# Merge step
|
|
341
|
+
- uses: actions/download-artifact@v4
|
|
342
|
+
with:
|
|
343
|
+
pattern: blob-report-*
|
|
344
|
+
merge-multiple: true
|
|
345
|
+
path: all-blob-reports
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Worker-scoped fixture not working
|
|
349
|
+
|
|
350
|
+
- **Missing `{ scope: 'worker' }`**. Fix:
|
|
351
|
+
```ts
|
|
352
|
+
export const test = base.extend({
|
|
353
|
+
resource: [
|
|
354
|
+
async ({}, use) => {
|
|
355
|
+
const r = await Resource.create();
|
|
356
|
+
await use(r);
|
|
357
|
+
await r.destroy();
|
|
358
|
+
},
|
|
359
|
+
{ scope: "worker" },
|
|
360
|
+
],
|
|
361
|
+
});
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### More workers = Slower
|
|
365
|
+
|
|
366
|
+
- **Too many workers thrash**. Limit in CI:
|
|
367
|
+
```ts
|
|
368
|
+
export default defineConfig({
|
|
369
|
+
workers: process.env.CI ? 2 : undefined,
|
|
370
|
+
});
|
|
371
|
+
```
|