@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,369 @@
1
+ # Choosing Test Types: E2E, Component, or API
2
+
3
+ ## Table of Contents
4
+
5
+ 1. [Decision Matrix](#decision-matrix)
6
+ 2. [API Tests](#api-tests)
7
+ 3. [Component Tests](#component-tests)
8
+ 4. [E2E Tests](#e2e-tests)
9
+ 5. [Layering Test Types](#layering-test-types)
10
+ 6. [Common Mistakes](#common-mistakes)
11
+ 7. [Related](#related)
12
+
13
+ > **When to use**: Deciding which test type to write for a feature. Ask: "What's the cheapest test that gives confidence this works?"
14
+
15
+ ## Decision Matrix
16
+
17
+ | Scenario | Recommended Type | Rationale |
18
+ | --------------------------- | ---------------- | --------------------------------------------- |
19
+ | Login / auth flow | E2E | Cross-page, cookies, redirects, session state |
20
+ | Form submission | Component | Isolated validation logic, error states |
21
+ | CRUD operations | API | Data integrity matters more than UI |
22
+ | Search with results UI | Component + API | API for query logic; component for rendering |
23
+ | Cross-page navigation | E2E | Routing, history, deep linking |
24
+ | API error handling | API | Status codes, error shapes, edge cases |
25
+ | UI error feedback | Component | Toast, banner, inline error rendering |
26
+ | Accessibility | Component | ARIA roles, keyboard nav per-component |
27
+ | Responsive layout | Component | Viewport-specific rendering without full app |
28
+ | API contract validation | API | Response shapes, headers, auth |
29
+ | WebSocket/real-time | E2E | Requires full browser environment |
30
+ | Payment / checkout | E2E | Multi-step, third-party iframes |
31
+ | Onboarding wizard | E2E | Multi-step, state persists across pages |
32
+ | Widget behavior | Component | Toggle, accordion, date picker, modal |
33
+ | Permissions / authorization | API | Role-based access is backend logic |
34
+
35
+ ## API Tests
36
+
37
+ **Ideal for**:
38
+
39
+ - CRUD operations (create, read, update, delete)
40
+ - Input validation and error responses (400, 422)
41
+ - Permission and authorization checks
42
+ - Data integrity and business rules
43
+ - API contract verification
44
+ - Edge cases expensive to reproduce through UI
45
+ - Test data setup/teardown for E2E tests
46
+
47
+ **Avoid for**:
48
+
49
+ - Testing how errors display to users
50
+ - Browser-specific behavior (cookies, redirects)
51
+ - Visual layout or responsive design
52
+ - Flows requiring JavaScript execution or DOM interaction
53
+ - Third-party iframe interactions
54
+
55
+ ```typescript
56
+ import { test, expect } from "@playwright/test";
57
+
58
+ test.describe("Products API", () => {
59
+ let token: string;
60
+
61
+ test.beforeAll(async ({ request }) => {
62
+ const res = await request.post("/api/auth/token", {
63
+ data: { email: "manager@shop.io", password: "mgr-secret" },
64
+ });
65
+ token = (await res.json()).accessToken;
66
+ });
67
+
68
+ test("creates product with valid payload", async ({ request }) => {
69
+ const res = await request.post("/api/products", {
70
+ headers: { Authorization: `Bearer ${token}` },
71
+ data: { name: "Widget Pro", sku: "WGT-100", price: 29.99 },
72
+ });
73
+
74
+ expect(res.status()).toBe(201);
75
+ const product = await res.json();
76
+ expect(product).toMatchObject({ name: "Widget Pro", sku: "WGT-100" });
77
+ expect(product).toHaveProperty("id");
78
+ });
79
+
80
+ test("rejects duplicate SKU with 409", async ({ request }) => {
81
+ const res = await request.post("/api/products", {
82
+ headers: { Authorization: `Bearer ${token}` },
83
+ data: { name: "Duplicate", sku: "WGT-100", price: 19.99 },
84
+ });
85
+
86
+ expect(res.status()).toBe(409);
87
+ expect((await res.json()).message).toContain("already exists");
88
+ });
89
+
90
+ test("returns 422 for missing required fields", async ({ request }) => {
91
+ const res = await request.post("/api/products", {
92
+ headers: { Authorization: `Bearer ${token}` },
93
+ data: { name: "Incomplete" },
94
+ });
95
+
96
+ expect(res.status()).toBe(422);
97
+ const err = await res.json();
98
+ expect(err.errors).toContainEqual(
99
+ expect.objectContaining({ field: "sku" })
100
+ );
101
+ });
102
+
103
+ test("staff role cannot delete products", async ({ request }) => {
104
+ const staffLogin = await request.post("/api/auth/token", {
105
+ data: { email: "staff@shop.io", password: "staff-pass" },
106
+ });
107
+ const staffToken = (await staffLogin.json()).accessToken;
108
+
109
+ const res = await request.delete("/api/products/123", {
110
+ headers: { Authorization: `Bearer ${staffToken}` },
111
+ });
112
+
113
+ expect(res.status()).toBe(403);
114
+ });
115
+
116
+ test("lists products with pagination", async ({ request }) => {
117
+ const res = await request.get("/api/products", {
118
+ headers: { Authorization: `Bearer ${token}` },
119
+ params: { page: "1", limit: "20" },
120
+ });
121
+
122
+ expect(res.status()).toBe(200);
123
+ const body = await res.json();
124
+ expect(body.items).toBeInstanceOf(Array);
125
+ expect(body.items.length).toBeLessThanOrEqual(20);
126
+ expect(body).toHaveProperty("totalCount");
127
+ });
128
+ });
129
+ ```
130
+
131
+ ## Component Tests
132
+
133
+ **Ideal for**:
134
+
135
+ - Form validation (required fields, format rules, error messages)
136
+ - Interactive widgets (modals, dropdowns, accordions, date pickers)
137
+ - Conditional rendering (show/hide, loading states, empty states)
138
+ - Accessibility per-component (ARIA attributes, keyboard navigation)
139
+ - Responsive layout at different viewports
140
+ - Visual states (hover, focus, disabled, selected)
141
+
142
+ **Avoid for**:
143
+
144
+ - Testing routing or navigation between pages
145
+ - Flows requiring real cookies, sessions, or server-side state
146
+ - Data persistence or API contract validation
147
+ - Third-party iframe interactions
148
+ - Anything requiring multiple pages or browser contexts
149
+
150
+ ```typescript
151
+ import { test, expect } from "@playwright/experimental-ct-react";
152
+ import { ContactForm } from "../src/components/ContactForm";
153
+
154
+ test.describe("ContactForm component", () => {
155
+ test("displays validation errors on empty submit", async ({ mount }) => {
156
+ const component = await mount(<ContactForm onSubmit={() => {}} />);
157
+
158
+ await component.getByRole("button", { name: "Send message" }).click();
159
+
160
+ await expect(component.getByText("Name is required")).toBeVisible();
161
+ await expect(component.getByText("Email is required")).toBeVisible();
162
+ });
163
+
164
+ test("rejects malformed email", async ({ mount }) => {
165
+ const component = await mount(<ContactForm onSubmit={() => {}} />);
166
+
167
+ await component.getByLabel("Name").fill("Alex");
168
+ await component.getByLabel("Email").fill("invalid-email");
169
+ await component.getByLabel("Message").fill("Hello");
170
+ await component.getByRole("button", { name: "Send message" }).click();
171
+
172
+ await expect(component.getByText("Enter a valid email")).toBeVisible();
173
+ });
174
+
175
+ test("invokes onSubmit with form data", async ({ mount }) => {
176
+ const submissions: Array<{ name: string; email: string; message: string }> =
177
+ [];
178
+ const component = await mount(
179
+ <ContactForm onSubmit={(data) => submissions.push(data)} />
180
+ );
181
+
182
+ await component.getByLabel("Name").fill("Alex");
183
+ await component.getByLabel("Email").fill("alex@company.org");
184
+ await component.getByLabel("Message").fill("Inquiry about pricing");
185
+ await component.getByRole("button", { name: "Send message" }).click();
186
+
187
+ expect(submissions).toHaveLength(1);
188
+ expect(submissions[0]).toEqual({
189
+ name: "Alex",
190
+ email: "alex@company.org",
191
+ message: "Inquiry about pricing",
192
+ });
193
+ });
194
+
195
+ test("disables button during submission", async ({ mount }) => {
196
+ const component = await mount(
197
+ <ContactForm onSubmit={() => {}} submitting={true} />
198
+ );
199
+
200
+ await expect(
201
+ component.getByRole("button", { name: "Sending..." })
202
+ ).toBeDisabled();
203
+ });
204
+
205
+ test("associates labels with inputs for accessibility", async ({ mount }) => {
206
+ const component = await mount(<ContactForm onSubmit={() => {}} />);
207
+
208
+ await expect(
209
+ component.getByRole("textbox", { name: "Name" })
210
+ ).toBeVisible();
211
+ await expect(
212
+ component.getByRole("textbox", { name: "Email" })
213
+ ).toBeVisible();
214
+ });
215
+ });
216
+ ```
217
+
218
+ ## E2E Tests
219
+
220
+ **Ideal for**:
221
+
222
+ - Critical user flows that generate revenue (checkout, signup)
223
+ - Authentication flows (login, SSO, MFA, password reset)
224
+ - Multi-page workflows where state carries across navigation
225
+ - Flows involving third-party iframes (payment widgets)
226
+ - Smoke tests validating the entire stack
227
+ - Real-time collaboration requiring multiple browser contexts
228
+
229
+ **Avoid for**:
230
+
231
+ - Testing every form validation permutation
232
+ - CRUD operations where UI is a thin wrapper
233
+ - Verifying individual component states
234
+ - Testing API response shapes or error codes
235
+ - Responsive layout at every breakpoint
236
+ - Edge cases that only affect the backend
237
+
238
+ ```typescript
239
+ import { test, expect } from "@playwright/test";
240
+
241
+ test.describe("subscription flow", () => {
242
+ test.beforeEach(async ({ page }) => {
243
+ await page.request.post("/api/test/seed-account", {
244
+ data: { plan: "free", email: "subscriber@demo.io" },
245
+ });
246
+ await page.goto("/account/upgrade");
247
+ });
248
+
249
+ test("upgrades to premium plan", async ({ page }) => {
250
+ await test.step("select plan", async () => {
251
+ await expect(
252
+ page.getByRole("heading", { name: "Choose Your Plan" })
253
+ ).toBeVisible();
254
+ await page.getByRole("button", { name: "Select Premium" }).click();
255
+ });
256
+
257
+ await test.step("enter billing details", async () => {
258
+ await page.getByLabel("Cardholder name").fill("Sam Johnson");
259
+ await page.getByLabel("Billing address").fill("456 Oak Ave");
260
+ await page.getByLabel("City").fill("Seattle");
261
+ await page.getByRole("combobox", { name: "State" }).selectOption("WA");
262
+ await page.getByLabel("Postal code").fill("98101");
263
+ await page.getByRole("button", { name: "Continue" }).click();
264
+ });
265
+
266
+ await test.step("complete payment", async () => {
267
+ const paymentFrame = page.frameLocator('iframe[title="Secure Payment"]');
268
+ await paymentFrame.getByLabel("Card number").fill("5555555555554444");
269
+ await paymentFrame.getByLabel("Expiry").fill("09/29");
270
+ await paymentFrame.getByLabel("CVV").fill("456");
271
+ await page.getByRole("button", { name: "Subscribe now" }).click();
272
+ });
273
+
274
+ await test.step("verify success", async () => {
275
+ await page.waitForURL("**/account/subscription/success**");
276
+ await expect(
277
+ page.getByRole("heading", { name: "Welcome to Premium" })
278
+ ).toBeVisible();
279
+ await expect(page.getByText(/Subscription #\d+/)).toBeVisible();
280
+ });
281
+ });
282
+ });
283
+ ```
284
+
285
+ ## Layering Test Types
286
+
287
+ Effective test suites combine all three types. Example for an "inventory management" feature:
288
+
289
+ ### API Layer (60% of tests)
290
+
291
+ Cover every backend logic permutation. Cheap to run and maintain.
292
+
293
+ ```
294
+ tests/api/inventory.spec.ts
295
+ - creates item with valid data (201)
296
+ - rejects duplicate SKU (409)
297
+ - rejects invalid quantity format (422)
298
+ - rejects missing required fields (422)
299
+ - warehouse-staff cannot delete items (403)
300
+ - unauthenticated request returns 401
301
+ - lists items with pagination
302
+ - filters items by category
303
+ - updates item stock level
304
+ - archives an item
305
+ - prevents archiving items with pending orders
306
+ ```
307
+
308
+ ### Component Layer (30% of tests)
309
+
310
+ Cover every visual state and interaction.
311
+
312
+ ```
313
+ tests/components/InventoryForm.spec.tsx
314
+ - shows validation errors on empty submit
315
+ - shows inline error for invalid SKU format
316
+ - disables submit while saving
317
+ - calls onSubmit with form data
318
+ - resets form after successful save
319
+
320
+ tests/components/InventoryTable.spec.tsx
321
+ - renders item rows from props
322
+ - shows empty state when no items
323
+ - handles archive confirmation modal
324
+ - sorts by column header click
325
+ - shows stock level badges with correct colors
326
+ ```
327
+
328
+ ### E2E Layer (10% of tests)
329
+
330
+ Cover only critical paths proving full stack works.
331
+
332
+ ```
333
+ tests/e2e/inventory.spec.ts
334
+ - manager creates item and sees it in list
335
+ - manager updates item stock level
336
+ - warehouse-staff cannot access admin settings
337
+ ```
338
+
339
+ ### Execution Profile
340
+
341
+ For this feature:
342
+
343
+ - **11 API tests** — ~2 seconds total, no browser
344
+ - **10 component tests** — ~5 seconds total, real browser but no server
345
+ - **3 E2E tests** — ~15 seconds total, full stack
346
+
347
+ Total: 24 tests, ~22 seconds. API tests catch most regressions. Component tests catch UI bugs. E2E tests prove wiring works. If E2E fails but API and component pass, the problem is in integration (routing, state management, API client).
348
+
349
+ ## Common Mistakes
350
+
351
+ | Anti-Pattern | Problem | Better Approach |
352
+ | ----------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------------- |
353
+ | E2E for every validation rule | 30-second browser test for something API covers in 200ms | API test for validation, one component test for error display |
354
+ | No API tests, all E2E | Slow suite, flaky from UI timing, hard to diagnose | API tests for data/logic, E2E for critical paths only |
355
+ | Component tests mocking everything | Tests pass but app broken because mocks drift | Mock only external boundaries; API tests verify real contracts |
356
+ | Same assertion in API, component, AND E2E | Triple maintenance cost | Each layer tests what it uniquely verifies |
357
+ | E2E creating test data via UI | 2-minute test where 90 seconds is setup | Seed via API in `beforeEach`, test actual flow |
358
+ | Testing third-party behavior | Testing that Stripe validates cards (Stripe's job) | Mock Stripe; trust their contract |
359
+ | Skipping API layer | Can't tell if bug is frontend or backend | API tests isolate backend; component tests isolate frontend |
360
+ | One giant E2E for entire feature | 5-minute test failing somewhere with no clear cause | Focused E2E per critical path; use `test.step()` |
361
+
362
+ ## Related
363
+
364
+ - [test-suite-structure.md](../core/test-suite-structure.md) — file structure and naming
365
+ - [api-testing.md](../testing-patterns/api-testing.md) — Playwright's `request` API for HTTP testing
366
+ - [component-testing.md](../testing-patterns/component-testing.md) — setting up component tests
367
+ - [authentication.md](../advanced/authentication.md) — auth flow patterns with `storageState`
368
+ - [when-to-mock.md](when-to-mock.md) — when to mock vs hit real services
369
+ - [pom-vs-fixtures.md](pom-vs-fixtures.md) — organizing shared test logic