@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,360 @@
1
+ # Error & Edge Case Testing
2
+
3
+ ## Table of Contents
4
+
5
+ 1. [Error Boundaries](#error-boundaries)
6
+ 2. [Network Failures](#network-failures)
7
+ 3. [Offline Testing](#offline-testing)
8
+ 4. [Loading States](#loading-states)
9
+ 5. [Form Validation](#form-validation)
10
+
11
+ ## Error Boundaries
12
+
13
+ ### Test Component Errors
14
+
15
+ ```typescript
16
+ test("error boundary catches component error", async ({ page }) => {
17
+ // Trigger error via mock
18
+ await page.route("**/api/user", (route) => {
19
+ route.fulfill({
20
+ json: null, // Will cause component to throw
21
+ });
22
+ });
23
+
24
+ await page.goto("/profile");
25
+
26
+ // Error boundary should render fallback
27
+ await expect(page.getByText("Something went wrong")).toBeVisible();
28
+ await expect(page.getByRole("button", { name: "Try Again" })).toBeVisible();
29
+ });
30
+ ```
31
+
32
+ ### Test Error Recovery
33
+
34
+ ```typescript
35
+ test("recover from error state", async ({ page }) => {
36
+ let requestCount = 0;
37
+
38
+ await page.route("**/api/data", (route) => {
39
+ requestCount++;
40
+ if (requestCount === 1) {
41
+ return route.fulfill({ status: 500 });
42
+ }
43
+ return route.fulfill({
44
+ json: { data: "success" },
45
+ });
46
+ });
47
+
48
+ await page.goto("/dashboard");
49
+
50
+ // Error state
51
+ await expect(page.getByText("Failed to load")).toBeVisible();
52
+
53
+ // Retry
54
+ await page.getByRole("button", { name: "Retry" }).click();
55
+
56
+ // Success state
57
+ await expect(page.getByText("success")).toBeVisible();
58
+ });
59
+ ```
60
+
61
+ ### Test JavaScript Errors
62
+
63
+ ```typescript
64
+ test("handles runtime error gracefully", async ({ page }) => {
65
+ const errors: string[] = [];
66
+
67
+ page.on("pageerror", (error) => {
68
+ errors.push(error.message);
69
+ });
70
+
71
+ await page.goto("/buggy-page");
72
+
73
+ // App should still be functional despite error
74
+ await expect(page.getByRole("navigation")).toBeVisible();
75
+
76
+ // Error was logged
77
+ expect(errors.length).toBeGreaterThan(0);
78
+ });
79
+ ```
80
+
81
+ ## Network Failures
82
+
83
+ ### Test API Errors
84
+
85
+ ```typescript
86
+ test.describe("API error handling", () => {
87
+ const errorCodes = [400, 401, 403, 404, 500, 502, 503];
88
+
89
+ for (const status of errorCodes) {
90
+ test(`handles ${status} error`, async ({ page }) => {
91
+ await page.route("**/api/data", (route) =>
92
+ route.fulfill({
93
+ status,
94
+ json: { error: `Error ${status}` },
95
+ }),
96
+ );
97
+
98
+ await page.goto("/dashboard");
99
+
100
+ // Appropriate error message shown
101
+ await expect(page.getByRole("alert")).toBeVisible();
102
+ });
103
+ }
104
+ });
105
+ ```
106
+
107
+ ### Test Timeout
108
+
109
+ ```typescript
110
+ test("handles request timeout", async ({ page }) => {
111
+ await page.route("**/api/slow", async (route) => {
112
+ // Never respond - simulates timeout
113
+ await new Promise(() => {});
114
+ });
115
+
116
+ await page.goto("/slow-page");
117
+
118
+ // Should show timeout message (app should have its own timeout)
119
+ await expect(page.getByText("Request timed out")).toBeVisible({
120
+ timeout: 15000,
121
+ });
122
+ });
123
+ ```
124
+
125
+ ### Test Connection Reset
126
+
127
+ ```typescript
128
+ test("handles connection failure", async ({ page }) => {
129
+ await page.route("**/api/data", (route) => {
130
+ route.abort("connectionfailed");
131
+ });
132
+
133
+ await page.goto("/dashboard");
134
+
135
+ await expect(page.getByText("Connection failed")).toBeVisible();
136
+ await expect(page.getByRole("button", { name: "Retry" })).toBeVisible();
137
+ });
138
+ ```
139
+
140
+ ### Test Mid-Request Failure
141
+
142
+ ```typescript
143
+ test("handles failure during request", async ({ page }) => {
144
+ let requestStarted = false;
145
+
146
+ await page.route("**/api/upload", async (route) => {
147
+ requestStarted = true;
148
+ // Abort after small delay (mid-request)
149
+ await new Promise((resolve) => setTimeout(resolve, 500));
150
+ route.abort("failed");
151
+ });
152
+
153
+ await page.goto("/upload");
154
+ await page.getByLabel("File").setInputFiles("./fixtures/large-file.pdf");
155
+ await page.getByRole("button", { name: "Upload" }).click();
156
+
157
+ // Should show failure, not hang
158
+ await expect(page.getByText("Upload failed")).toBeVisible();
159
+ expect(requestStarted).toBe(true);
160
+ });
161
+ ```
162
+
163
+ ## Offline Testing
164
+
165
+ This section covers **unexpected network failures** and error recovery. For **offline-first apps (PWAs)** with service workers, caching, and background sync, see [service-workers.md](service-workers.md#offline-testing).
166
+
167
+ ### Go Offline During Session
168
+
169
+ ```typescript
170
+ test("handles going offline", async ({ page, context }) => {
171
+ await page.goto("/dashboard");
172
+ await expect(page.getByTestId("data")).toBeVisible();
173
+
174
+ // Go offline unexpectedly
175
+ await context.setOffline(true);
176
+
177
+ // Try to refresh data
178
+ await page.getByRole("button", { name: "Refresh" }).click();
179
+
180
+ // Should show offline indicator
181
+ await expect(page.getByText("You're offline")).toBeVisible();
182
+
183
+ // Go back online
184
+ await context.setOffline(false);
185
+
186
+ // Should recover
187
+ await page.getByRole("button", { name: "Refresh" }).click();
188
+ await expect(page.getByText("You're offline")).toBeHidden();
189
+ });
190
+ ```
191
+
192
+ ### Test Network Recovery
193
+
194
+ ```typescript
195
+ test("recovers gracefully when connection returns", async ({
196
+ page,
197
+ context,
198
+ }) => {
199
+ await page.goto("/dashboard");
200
+
201
+ // Simulate connection drop
202
+ await context.setOffline(true);
203
+
204
+ // App should show degraded state
205
+ await expect(page.getByRole("alert")).toContainText(/offline|connection/i);
206
+
207
+ // Connection restored
208
+ await context.setOffline(false);
209
+
210
+ // Retry should work
211
+ await page.getByRole("button", { name: "Retry" }).click();
212
+ await expect(page.getByTestId("data")).toBeVisible();
213
+ });
214
+ ```
215
+
216
+ ## Loading States
217
+
218
+ ### Test Skeleton Loaders
219
+
220
+ ```typescript
221
+ test("shows skeleton during load", async ({ page }) => {
222
+ // Add delay to API response
223
+ await page.route("**/api/posts", async (route) => {
224
+ await new Promise((resolve) => setTimeout(resolve, 1000));
225
+ route.fulfill({
226
+ json: [{ id: 1, title: "Post 1" }],
227
+ });
228
+ });
229
+
230
+ await page.goto("/posts");
231
+
232
+ // Skeleton should appear immediately
233
+ await expect(page.getByTestId("skeleton")).toBeVisible();
234
+
235
+ // Then content replaces skeleton
236
+ await expect(page.getByText("Post 1")).toBeVisible();
237
+ await expect(page.getByTestId("skeleton")).toBeHidden();
238
+ });
239
+ ```
240
+
241
+ ### Test Loading Indicators
242
+
243
+ ```typescript
244
+ test("shows loading state for actions", async ({ page }) => {
245
+ await page.route("**/api/save", async (route) => {
246
+ await new Promise((resolve) => setTimeout(resolve, 500));
247
+ route.fulfill({ json: { success: true } });
248
+ });
249
+
250
+ await page.goto("/editor");
251
+ await page.getByLabel("Content").fill("New content");
252
+
253
+ const saveButton = page.getByRole("button", { name: "Save" });
254
+ await saveButton.click();
255
+
256
+ // Button should show loading state
257
+ await expect(saveButton).toBeDisabled();
258
+ await expect(page.getByTestId("spinner")).toBeVisible();
259
+
260
+ // Then success state
261
+ await expect(saveButton).toBeEnabled();
262
+ await expect(page.getByText("Saved")).toBeVisible();
263
+ });
264
+ ```
265
+
266
+ ### Test Empty States
267
+
268
+ ```typescript
269
+ test("shows empty state when no data", async ({ page }) => {
270
+ await page.route("**/api/items", (route) => route.fulfill({ json: [] }));
271
+
272
+ await page.goto("/items");
273
+
274
+ await expect(page.getByText("No items yet")).toBeVisible();
275
+ await expect(
276
+ page.getByRole("button", { name: "Create First Item" }),
277
+ ).toBeVisible();
278
+ });
279
+ ```
280
+
281
+ ## Form Validation
282
+
283
+ ### Test Client-Side Validation
284
+
285
+ ```typescript
286
+ test("validates required fields", async ({ page }) => {
287
+ await page.goto("/signup");
288
+
289
+ // Submit empty form
290
+ await page.getByRole("button", { name: "Sign Up" }).click();
291
+
292
+ // Should show validation errors
293
+ await expect(page.getByText("Email is required")).toBeVisible();
294
+ await expect(page.getByText("Password is required")).toBeVisible();
295
+
296
+ // Form should not submit
297
+ await expect(page).toHaveURL("/signup");
298
+ });
299
+ ```
300
+
301
+ ### Test Format Validation
302
+
303
+ ```typescript
304
+ test("validates email format", async ({ page }) => {
305
+ await page.goto("/signup");
306
+
307
+ await page.getByLabel("Email").fill("invalid-email");
308
+ await page.getByLabel("Email").blur();
309
+
310
+ await expect(page.getByText("Invalid email address")).toBeVisible();
311
+
312
+ // Fix the error
313
+ await page.getByLabel("Email").fill("valid@email.com");
314
+ await page.getByLabel("Email").blur();
315
+
316
+ await expect(page.getByText("Invalid email address")).toBeHidden();
317
+ });
318
+ ```
319
+
320
+ ### Test Server-Side Validation
321
+
322
+ ```typescript
323
+ test("handles server validation errors", async ({ page }) => {
324
+ await page.route("**/api/register", (route) =>
325
+ route.fulfill({
326
+ status: 422,
327
+ json: {
328
+ errors: {
329
+ email: "Email already exists",
330
+ username: "Username is taken",
331
+ },
332
+ },
333
+ }),
334
+ );
335
+
336
+ await page.goto("/signup");
337
+ await page.getByLabel("Email").fill("taken@email.com");
338
+ await page.getByLabel("Username").fill("takenuser");
339
+ await page.getByLabel("Password").fill("password123");
340
+ await page.getByRole("button", { name: "Sign Up" }).click();
341
+
342
+ // Server errors should display
343
+ await expect(page.getByText("Email already exists")).toBeVisible();
344
+ await expect(page.getByText("Username is taken")).toBeVisible();
345
+ });
346
+ ```
347
+
348
+ ## Anti-Patterns to Avoid
349
+
350
+ | Anti-Pattern | Problem | Solution |
351
+ | ------------------------ | ------------------------------ | -------------------------------------- |
352
+ | Only testing happy path | Misses error handling bugs | Test all error scenarios |
353
+ | No network failure tests | App crashes on poor connection | Test offline/slow/failed requests |
354
+ | Skipping loading states | Janky UX not caught | Assert loading UI appears |
355
+ | Ignoring validation | Form bugs slip through | Test both client and server validation |
356
+
357
+ ## Related References
358
+
359
+ - **Network Mocking**: See [network-advanced.md](../advanced/network-advanced.md) for mock patterns
360
+ - **Assertions**: See [assertions-waiting.md](../core/assertions-waiting.md) for error assertions