@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.
Files changed (97) hide show
  1. package/.agents/skills/e2e-testing-expert/SKILL.md +28 -0
  2. package/.agents/skills/frontend-design/LICENSE.txt +177 -0
  3. package/.agents/skills/frontend-design/SKILL.md +42 -0
  4. package/.agents/skills/nodejs-backend-patterns/SKILL.md +639 -0
  5. package/.agents/skills/nodejs-backend-patterns/references/advanced-patterns.md +430 -0
  6. package/.agents/skills/playwright-best-practices/LICENSE.md +7 -0
  7. package/.agents/skills/playwright-best-practices/README.md +147 -0
  8. package/.agents/skills/playwright-best-practices/SKILL.md +303 -0
  9. package/.agents/skills/playwright-best-practices/advanced/authentication-flows.md +360 -0
  10. package/.agents/skills/playwright-best-practices/advanced/authentication.md +871 -0
  11. package/.agents/skills/playwright-best-practices/advanced/clock-mocking.md +364 -0
  12. package/.agents/skills/playwright-best-practices/advanced/mobile-testing.md +409 -0
  13. package/.agents/skills/playwright-best-practices/advanced/multi-context.md +288 -0
  14. package/.agents/skills/playwright-best-practices/advanced/multi-user.md +393 -0
  15. package/.agents/skills/playwright-best-practices/advanced/network-advanced.md +452 -0
  16. package/.agents/skills/playwright-best-practices/advanced/third-party.md +464 -0
  17. package/.agents/skills/playwright-best-practices/architecture/pom-vs-fixtures.md +363 -0
  18. package/.agents/skills/playwright-best-practices/architecture/test-architecture.md +369 -0
  19. package/.agents/skills/playwright-best-practices/architecture/when-to-mock.md +383 -0
  20. package/.agents/skills/playwright-best-practices/browser-apis/browser-apis.md +391 -0
  21. package/.agents/skills/playwright-best-practices/browser-apis/iframes.md +403 -0
  22. package/.agents/skills/playwright-best-practices/browser-apis/service-workers.md +504 -0
  23. package/.agents/skills/playwright-best-practices/browser-apis/websockets.md +403 -0
  24. package/.agents/skills/playwright-best-practices/core/annotations.md +424 -0
  25. package/.agents/skills/playwright-best-practices/core/assertions-waiting.md +361 -0
  26. package/.agents/skills/playwright-best-practices/core/configuration.md +452 -0
  27. package/.agents/skills/playwright-best-practices/core/fixtures-hooks.md +417 -0
  28. package/.agents/skills/playwright-best-practices/core/global-setup.md +434 -0
  29. package/.agents/skills/playwright-best-practices/core/locators.md +242 -0
  30. package/.agents/skills/playwright-best-practices/core/page-object-model.md +315 -0
  31. package/.agents/skills/playwright-best-practices/core/projects-dependencies.md +453 -0
  32. package/.agents/skills/playwright-best-practices/core/test-data.md +492 -0
  33. package/.agents/skills/playwright-best-practices/core/test-suite-structure.md +361 -0
  34. package/.agents/skills/playwright-best-practices/core/test-tags.md +298 -0
  35. package/.agents/skills/playwright-best-practices/debugging/console-errors.md +420 -0
  36. package/.agents/skills/playwright-best-practices/debugging/debugging.md +504 -0
  37. package/.agents/skills/playwright-best-practices/debugging/error-testing.md +360 -0
  38. package/.agents/skills/playwright-best-practices/debugging/flaky-tests.md +496 -0
  39. package/.agents/skills/playwright-best-practices/frameworks/angular.md +530 -0
  40. package/.agents/skills/playwright-best-practices/frameworks/nextjs.md +469 -0
  41. package/.agents/skills/playwright-best-practices/frameworks/react.md +531 -0
  42. package/.agents/skills/playwright-best-practices/frameworks/vue.md +574 -0
  43. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/ci-cd.md +468 -0
  44. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/docker.md +283 -0
  45. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/github-actions.md +546 -0
  46. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/gitlab.md +397 -0
  47. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/other-providers.md +521 -0
  48. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/parallel-sharding.md +371 -0
  49. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/performance.md +453 -0
  50. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/reporting.md +424 -0
  51. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/test-coverage.md +497 -0
  52. package/.agents/skills/playwright-best-practices/testing-patterns/accessibility.md +359 -0
  53. package/.agents/skills/playwright-best-practices/testing-patterns/api-testing.md +719 -0
  54. package/.agents/skills/playwright-best-practices/testing-patterns/browser-extensions.md +506 -0
  55. package/.agents/skills/playwright-best-practices/testing-patterns/canvas-webgl.md +493 -0
  56. package/.agents/skills/playwright-best-practices/testing-patterns/component-testing.md +500 -0
  57. package/.agents/skills/playwright-best-practices/testing-patterns/drag-drop.md +576 -0
  58. package/.agents/skills/playwright-best-practices/testing-patterns/electron.md +509 -0
  59. package/.agents/skills/playwright-best-practices/testing-patterns/file-operations.md +377 -0
  60. package/.agents/skills/playwright-best-practices/testing-patterns/file-upload-download.md +562 -0
  61. package/.agents/skills/playwright-best-practices/testing-patterns/forms-validation.md +561 -0
  62. package/.agents/skills/playwright-best-practices/testing-patterns/graphql-testing.md +331 -0
  63. package/.agents/skills/playwright-best-practices/testing-patterns/i18n.md +508 -0
  64. package/.agents/skills/playwright-best-practices/testing-patterns/performance-testing.md +476 -0
  65. package/.agents/skills/playwright-best-practices/testing-patterns/security-testing.md +430 -0
  66. package/.agents/skills/playwright-best-practices/testing-patterns/visual-regression.md +634 -0
  67. package/.env.example +21 -0
  68. package/README.md +30 -0
  69. package/bin/arcality.mjs +86 -0
  70. package/package.json +66 -0
  71. package/playwright.config.ts +12 -0
  72. package/scripts/cleanup-qmsdev.mjs +63 -0
  73. package/scripts/discover-view.mjs +52 -0
  74. package/scripts/extract-view.mjs +64 -0
  75. package/scripts/gen-and-run.mjs +838 -0
  76. package/scripts/init.mjs +290 -0
  77. package/scripts/migrate-to-central-out.mjs +157 -0
  78. package/scripts/postinstall.mjs +63 -0
  79. package/scripts/rebrand-report.mjs +241 -0
  80. package/scripts/setup.mjs +166 -0
  81. package/src/KnowledgeService.ts +239 -0
  82. package/src/arcalityClient.mjs +266 -0
  83. package/src/configLoader.mjs +179 -0
  84. package/src/configManager.mjs +172 -0
  85. package/src/consoleBanner.ts +32 -0
  86. package/src/envSetup.ts +205 -0
  87. package/src/index.ts +25 -0
  88. package/src/projectInspector.ts +42 -0
  89. package/src/services/collectiveMemoryService.ts +178 -0
  90. package/src/testRunner.ts +201 -0
  91. package/tests/_helpers/ArcalityReporter.ts +490 -0
  92. package/tests/_helpers/agentic-runner.spec.ts +741 -0
  93. package/tests/_helpers/ai-agent-helper.ts +1573 -0
  94. package/tests/_helpers/discover-view.spec.ts +238 -0
  95. package/tests/_helpers/extract-view.spec.ts +118 -0
  96. package/tests/_helpers/qa-tools.ts +333 -0
  97. 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
+ ```