@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,361 @@
1
+ # Assertions & Waiting
2
+
3
+ ## Table of Contents
4
+
5
+ 1. [Web-First Assertions](#web-first-assertions)
6
+ 2. [Generic Assertions](#generic-assertions)
7
+ 3. [Soft Assertions](#soft-assertions)
8
+ 4. [Waiting Strategies](#waiting-strategies)
9
+ 5. [Polling & Retrying](#polling--retrying)
10
+ 6. [Custom Matchers](#custom-matchers)
11
+
12
+ ## Web-First Assertions
13
+
14
+ Auto-retry until condition is met or timeout. Always prefer these over generic assertions.
15
+
16
+ ### Locator Assertions
17
+
18
+ ```typescript
19
+ import { expect } from "@playwright/test";
20
+
21
+ // Visibility
22
+ await expect(page.getByRole("button")).toBeVisible();
23
+ await expect(page.getByRole("button")).toBeHidden();
24
+ await expect(page.getByRole("button")).not.toBeVisible();
25
+
26
+ // Enabled/Disabled
27
+ await expect(page.getByRole("button")).toBeEnabled();
28
+ await expect(page.getByRole("button")).toBeDisabled();
29
+
30
+ // Text content
31
+ await expect(page.getByRole("heading")).toHaveText("Welcome");
32
+ await expect(page.getByRole("heading")).toHaveText(/welcome/i);
33
+ await expect(page.getByRole("heading")).toContainText("Welcome");
34
+
35
+ // Count
36
+ await expect(page.getByRole("listitem")).toHaveCount(5);
37
+
38
+ // Attributes
39
+ await expect(page.getByRole("link")).toHaveAttribute("href", "/home");
40
+ await expect(page.getByRole("img")).toHaveAttribute("alt", /logo/i);
41
+
42
+ // CSS
43
+ await expect(page.getByRole("button")).toHaveClass(/primary/);
44
+ await expect(page.getByRole("button")).toHaveCSS("color", "rgb(0, 0, 255)");
45
+
46
+ // Input values
47
+ await expect(page.getByLabel("Email")).toHaveValue("user@example.com");
48
+ await expect(page.getByLabel("Email")).toBeEmpty();
49
+
50
+ // Focus
51
+ await expect(page.getByLabel("Email")).toBeFocused();
52
+
53
+ // Checked state
54
+ await expect(page.getByRole("checkbox")).toBeChecked();
55
+ await expect(page.getByRole("checkbox")).not.toBeChecked();
56
+
57
+ // Editable state
58
+ await expect(page.getByLabel("Name")).toBeEditable();
59
+ ```
60
+
61
+ ### Page Assertions
62
+
63
+ ```typescript
64
+ // URL
65
+ await expect(page).toHaveURL("/dashboard");
66
+ await expect(page).toHaveURL(/\/dashboard/);
67
+
68
+ // Title
69
+ await expect(page).toHaveTitle("Dashboard - MyApp");
70
+ await expect(page).toHaveTitle(/dashboard/i);
71
+ ```
72
+
73
+ ### Response Assertions
74
+
75
+ ```typescript
76
+ const response = await page.request.get("/api/users");
77
+ await expect(response).toBeOK();
78
+ await expect(response).not.toBeOK();
79
+ ```
80
+
81
+ ## Generic Assertions
82
+
83
+ Use for non-UI values. Do NOT retry - execute immediately.
84
+
85
+ ```typescript
86
+ // Equality
87
+ expect(value).toBe(5);
88
+ expect(object).toEqual({ name: "Test" });
89
+ expect(array).toContain("item");
90
+
91
+ // Truthiness
92
+ expect(value).toBeTruthy();
93
+ expect(value).toBeFalsy();
94
+ expect(value).toBeNull();
95
+ expect(value).toBeUndefined();
96
+ expect(value).toBeDefined();
97
+
98
+ // Numbers
99
+ expect(value).toBeGreaterThan(5);
100
+ expect(value).toBeLessThanOrEqual(10);
101
+ expect(value).toBeCloseTo(5.5, 1);
102
+
103
+ // Strings
104
+ expect(string).toMatch(/pattern/);
105
+ expect(string).toContain("substring");
106
+
107
+ // Arrays/Objects
108
+ expect(array).toHaveLength(3);
109
+ expect(object).toHaveProperty("key", "value");
110
+
111
+ // Exceptions
112
+ expect(() => fn()).toThrow();
113
+ expect(() => fn()).toThrow("error message");
114
+ await expect(asyncFn()).rejects.toThrow();
115
+ ```
116
+
117
+ ## Soft Assertions
118
+
119
+ Continue test execution after failure, report all failures at end.
120
+
121
+ ```typescript
122
+ test("check multiple elements", async ({ page }) => {
123
+ await page.goto("/dashboard");
124
+
125
+ // Won't stop on first failure
126
+ await expect.soft(page.getByRole("heading")).toHaveText("Dashboard");
127
+ await expect.soft(page.getByRole("button", { name: "Save" })).toBeEnabled();
128
+ await expect.soft(page.getByText("Welcome")).toBeVisible();
129
+
130
+ // Test continues; all failures reported at end
131
+ });
132
+ ```
133
+
134
+ ### Soft Assertions with Early Exit
135
+
136
+ ```typescript
137
+ test("check form", async ({ page }) => {
138
+ await expect.soft(page.getByRole("form")).toBeVisible();
139
+
140
+ // Exit early if form not visible (pointless to check fields)
141
+ if (expect.soft.hasFailures()) {
142
+ return;
143
+ }
144
+
145
+ await expect.soft(page.getByLabel("Name")).toBeVisible();
146
+ await expect.soft(page.getByLabel("Email")).toBeVisible();
147
+ });
148
+ ```
149
+
150
+ ## Waiting Strategies
151
+
152
+ ### Auto-Waiting (Default)
153
+
154
+ Actions automatically wait for:
155
+
156
+ - Element to be attached to DOM
157
+ - Element to be visible
158
+ - Element to be stable (no animations)
159
+ - Element to be enabled
160
+ - Element to receive events
161
+
162
+ ```typescript
163
+ // These auto-wait
164
+ await page.click("button");
165
+ await page.fill("input", "text");
166
+ await page.getByRole("button").click();
167
+ ```
168
+
169
+ ### Wait for Navigation
170
+
171
+ ```typescript
172
+ // Wait for URL change
173
+ await page.waitForURL("/dashboard");
174
+ await page.waitForURL(/\/dashboard/);
175
+
176
+ // Wait for navigation after action
177
+ await Promise.all([
178
+ page.waitForURL("**/dashboard"),
179
+ page.click('a[href="/dashboard"]'),
180
+ ]);
181
+
182
+ // Or without Promise.all
183
+ const urlPromise = page.waitForURL("**/dashboard");
184
+ await page.click("a");
185
+ await urlPromise;
186
+ ```
187
+
188
+ ### Wait for Network
189
+
190
+ ```typescript
191
+ // Wait for specific response
192
+ const responsePromise = page.waitForResponse("**/api/users");
193
+ await page.click("button");
194
+ const response = await responsePromise;
195
+ expect(response.status()).toBe(200);
196
+
197
+ // Wait for request
198
+ const requestPromise = page.waitForRequest("**/api/submit");
199
+ await page.click("button");
200
+ const request = await requestPromise;
201
+
202
+ // Wait for no network activity
203
+ await page.waitForLoadState("networkidle");
204
+ ```
205
+
206
+ ### Wait for Element State
207
+
208
+ ```typescript
209
+ // Wait for element to appear
210
+ await page.getByRole("dialog").waitFor({ state: "visible" });
211
+
212
+ // Wait for element to disappear
213
+ await page.getByText("Loading...").waitFor({ state: "hidden" });
214
+
215
+ // Wait for element to be attached
216
+ await page.getByTestId("result").waitFor({ state: "attached" });
217
+
218
+ // Wait for element to be detached
219
+ await page.getByTestId("modal").waitFor({ state: "detached" });
220
+ ```
221
+
222
+ ### Wait for Function
223
+
224
+ ```typescript
225
+ // Wait for arbitrary condition
226
+ await page.waitForFunction(() => {
227
+ return document.querySelector(".loaded") !== null;
228
+ });
229
+
230
+ // With arguments
231
+ await page.waitForFunction(
232
+ (selector) => document.querySelector(selector)?.textContent === "Ready",
233
+ ".status",
234
+ );
235
+ ```
236
+
237
+ ## Polling & Retrying
238
+
239
+ ### toPass() for Polling
240
+
241
+ Retry until block passes or times out:
242
+
243
+ ```typescript
244
+ await expect(async () => {
245
+ const response = await page.request.get("/api/status");
246
+ expect(response.status()).toBe(200);
247
+
248
+ const data = await response.json();
249
+ expect(data.ready).toBe(true);
250
+ }).toPass({
251
+ intervals: [1000, 2000, 5000], // Retry intervals
252
+ timeout: 30000,
253
+ });
254
+ ```
255
+
256
+ ### expect.poll()
257
+
258
+ Poll a function until assertion passes:
259
+
260
+ ```typescript
261
+ // Poll API until condition met
262
+ await expect
263
+ .poll(
264
+ async () => {
265
+ const response = await page.request.get("/api/job/123");
266
+ return (await response.json()).status;
267
+ },
268
+ {
269
+ intervals: [1000, 2000, 5000],
270
+ timeout: 30000,
271
+ },
272
+ )
273
+ .toBe("completed");
274
+
275
+ // Poll DOM value
276
+ await expect.poll(() => page.getByTestId("counter").textContent()).toBe("10");
277
+ ```
278
+
279
+ ## Custom Matchers
280
+
281
+ ```typescript
282
+ // playwright.config.ts or fixtures
283
+ import { expect } from "@playwright/test";
284
+
285
+ expect.extend({
286
+ async toHaveDataLoaded(page: Page) {
287
+ const locator = page.getByTestId("data-container");
288
+ let pass = false;
289
+ let message = "";
290
+
291
+ try {
292
+ await expect(locator).toBeVisible();
293
+ await expect(locator).not.toContainText("Loading");
294
+ pass = true;
295
+ } catch (e) {
296
+ message = `Expected data to be loaded but found loading state`;
297
+ }
298
+
299
+ return { pass, message: () => message };
300
+ },
301
+ });
302
+
303
+ // Extend TypeScript types
304
+ declare global {
305
+ namespace PlaywrightTest {
306
+ interface Matchers<R> {
307
+ toHaveDataLoaded(): Promise<R>;
308
+ }
309
+ }
310
+ }
311
+
312
+ // Usage
313
+ await expect(page).toHaveDataLoaded();
314
+ ```
315
+
316
+ ## Timeouts
317
+
318
+ ### Configure Timeouts
319
+
320
+ ```typescript
321
+ // playwright.config.ts
322
+ export default defineConfig({
323
+ timeout: 30000, // Test timeout
324
+ expect: {
325
+ timeout: 5000, // Assertion timeout
326
+ },
327
+ });
328
+
329
+ // Per-test timeout
330
+ test("long test", async ({ page }) => {
331
+ test.setTimeout(60000);
332
+ // ...
333
+ });
334
+
335
+ // Per-assertion timeout
336
+ await expect(page.getByRole("button")).toBeVisible({ timeout: 10000 });
337
+ ```
338
+
339
+ ## Best Practices
340
+
341
+ | Do | Don't |
342
+ | ------------------------------ | ------------------------------ |
343
+ | Use web-first assertions | Use generic assertions for DOM |
344
+ | Let auto-waiting work | Add unnecessary explicit waits |
345
+ | Use `toPass()` for polling | Write manual retry loops |
346
+ | Configure appropriate timeouts | Use `waitForTimeout()` |
347
+ | Check specific conditions | Wait for arbitrary time |
348
+
349
+ ## Anti-Patterns to Avoid
350
+
351
+ | Anti-Pattern | Problem | Solution |
352
+ | --------------------------------------------------------- | ----------------------------- | -------------------------------------------- |
353
+ | `await page.waitForTimeout(5000)` | Slow, flaky, arbitrary timing | Use auto-waiting or `waitForResponse` |
354
+ | `await new Promise(resolve => setTimeout(resolve, 1000))` | Same as above | Use `waitForResponse` or element state waits |
355
+ | Generic assertions on DOM elements | No auto-retry, flaky | Use web-first assertions with `expect()` |
356
+
357
+ ## Related References
358
+
359
+ - **Debugging timeout issues**: See [debugging.md](../debugging/debugging.md) for troubleshooting
360
+ - **Fixing flaky tests**: See [debugging.md](../debugging/debugging.md) for race condition solutions
361
+ - **Network interception**: See [test-suite-structure.md](test-suite-structure.md) for API mocking