@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,464 @@
1
+ # Third-Party Service Mocking
2
+
3
+ ## Table of Contents
4
+
5
+ 1. [OAuth/SSO Mocking](#oauthsso-mocking)
6
+ 2. [Payment Gateway Mocking](#payment-gateway-mocking)
7
+ 3. [Email Verification](#email-verification)
8
+ 4. [SMS Verification](#sms-verification)
9
+ 5. [Analytics & Tracking](#analytics--tracking)
10
+
11
+ ## OAuth/SSO Mocking
12
+
13
+ ### Mock Google OAuth
14
+
15
+ ```typescript
16
+ test("Google OAuth login", async ({ page }) => {
17
+ // Mock the OAuth callback
18
+ await page.route("**/auth/google/callback**", (route) => {
19
+ const url = new URL(route.request().url());
20
+ // Simulate successful OAuth by redirecting with token
21
+ route.fulfill({
22
+ status: 302,
23
+ headers: {
24
+ Location: "/dashboard?token=mock-jwt-token",
25
+ },
26
+ });
27
+ });
28
+
29
+ // Mock the token verification endpoint
30
+ await page.route("**/api/auth/verify", (route) =>
31
+ route.fulfill({
32
+ json: {
33
+ valid: true,
34
+ user: {
35
+ id: "123",
36
+ email: "test@gmail.com",
37
+ name: "Test User",
38
+ },
39
+ },
40
+ }),
41
+ );
42
+
43
+ await page.goto("/login");
44
+ await page.getByRole("button", { name: "Sign in with Google" }).click();
45
+
46
+ await expect(page.getByText("Welcome, Test User")).toBeVisible();
47
+ });
48
+ ```
49
+
50
+ ### OAuth Fixture
51
+
52
+ ```typescript
53
+ // fixtures/oauth.fixture.ts
54
+ type OAuthProvider = "google" | "github" | "microsoft";
55
+
56
+ type OAuthUser = {
57
+ id: string;
58
+ email: string;
59
+ name: string;
60
+ avatar?: string;
61
+ };
62
+
63
+ type OAuthFixtures = {
64
+ mockOAuth: (provider: OAuthProvider, user: OAuthUser) => Promise<void>;
65
+ };
66
+
67
+ export const test = base.extend<OAuthFixtures>({
68
+ mockOAuth: async ({ page }, use) => {
69
+ await use(async (provider, user) => {
70
+ // Mock callback redirect
71
+ await page.route(`**/auth/${provider}/callback**`, (route) =>
72
+ route.fulfill({
73
+ status: 302,
74
+ headers: { Location: `/auth/success?provider=${provider}` },
75
+ }),
76
+ );
77
+
78
+ // Mock session/user endpoint
79
+ await page.route("**/api/auth/session", (route) =>
80
+ route.fulfill({
81
+ json: { user, provider, authenticated: true },
82
+ }),
83
+ );
84
+
85
+ // Mock user info endpoint
86
+ await page.route("**/api/me", (route) => route.fulfill({ json: user }));
87
+ });
88
+ },
89
+ });
90
+
91
+ // Usage
92
+ test("login with GitHub", async ({ page, mockOAuth }) => {
93
+ await mockOAuth("github", {
94
+ id: "gh-123",
95
+ email: "dev@github.com",
96
+ name: "GitHub User",
97
+ });
98
+
99
+ await page.goto("/login");
100
+ await page.getByRole("button", { name: "Sign in with GitHub" }).click();
101
+
102
+ await expect(page.getByText("Welcome, GitHub User")).toBeVisible();
103
+ });
104
+ ```
105
+
106
+ ### Mock SAML SSO
107
+
108
+ ```typescript
109
+ test("SAML SSO login", async ({ page }) => {
110
+ // Mock SAML assertion consumer service
111
+ await page.route("**/saml/acs", async (route) => {
112
+ route.fulfill({
113
+ status: 302,
114
+ headers: {
115
+ Location: "/dashboard",
116
+ "Set-Cookie": "session=mock-saml-session; Path=/; HttpOnly",
117
+ },
118
+ });
119
+ });
120
+
121
+ // Mock session validation
122
+ await page.route("**/api/session", (route) =>
123
+ route.fulfill({
124
+ json: {
125
+ user: { email: "user@company.com", name: "SSO User" },
126
+ provider: "saml",
127
+ },
128
+ }),
129
+ );
130
+
131
+ await page.goto("/login");
132
+ await page.getByRole("button", { name: "SSO Login" }).click();
133
+
134
+ await expect(page).toHaveURL("/dashboard");
135
+ });
136
+ ```
137
+
138
+ ## Payment Gateway Mocking
139
+
140
+ ### Mock Stripe
141
+
142
+ ```typescript
143
+ test("Stripe checkout", async ({ page }) => {
144
+ // Mock Stripe.js
145
+ await page.addInitScript(() => {
146
+ (window as any).Stripe = () => ({
147
+ elements: () => ({
148
+ create: () => ({
149
+ mount: () => {},
150
+ on: () => {},
151
+ destroy: () => {},
152
+ }),
153
+ }),
154
+ confirmCardPayment: async () => ({
155
+ paymentIntent: { status: "succeeded", id: "pi_mock_123" },
156
+ }),
157
+ createPaymentMethod: async () => ({
158
+ paymentMethod: { id: "pm_mock_123" },
159
+ }),
160
+ });
161
+ });
162
+
163
+ // Mock backend payment endpoint
164
+ await page.route("**/api/create-payment-intent", (route) =>
165
+ route.fulfill({
166
+ json: { clientSecret: "pi_mock_123_secret_mock" },
167
+ }),
168
+ );
169
+
170
+ await page.route("**/api/confirm-payment", (route) =>
171
+ route.fulfill({
172
+ json: { success: true, orderId: "order-123" },
173
+ }),
174
+ );
175
+
176
+ await page.goto("/checkout");
177
+ await page.getByRole("button", { name: "Pay $99.99" }).click();
178
+
179
+ await expect(page.getByText("Payment successful")).toBeVisible();
180
+ });
181
+ ```
182
+
183
+ ### Mock PayPal
184
+
185
+ ```typescript
186
+ test("PayPal checkout", async ({ page }) => {
187
+ // Mock PayPal SDK
188
+ await page.addInitScript(() => {
189
+ (window as any).paypal = {
190
+ Buttons: () => ({
191
+ render: () => Promise.resolve(),
192
+ isEligible: () => true,
193
+ }),
194
+ FUNDING: { PAYPAL: "paypal", CARD: "card" },
195
+ };
196
+ });
197
+
198
+ // Mock PayPal order creation
199
+ await page.route("**/api/paypal/create-order", (route) =>
200
+ route.fulfill({
201
+ json: { orderId: "PAYPAL-ORDER-123" },
202
+ }),
203
+ );
204
+
205
+ // Mock PayPal capture
206
+ await page.route("**/api/paypal/capture", (route) =>
207
+ route.fulfill({
208
+ json: { success: true, transactionId: "TXN-123" },
209
+ }),
210
+ );
211
+
212
+ await page.goto("/checkout");
213
+
214
+ // Simulate PayPal approval callback
215
+ await page.evaluate(() => {
216
+ (window as any).onPayPalApprove?.({ orderID: "PAYPAL-ORDER-123" });
217
+ });
218
+
219
+ await expect(page.getByText("Order confirmed")).toBeVisible();
220
+ });
221
+ ```
222
+
223
+ ### Payment Fixture
224
+
225
+ ```typescript
226
+ // fixtures/payment.fixture.ts
227
+ type PaymentFixtures = {
228
+ mockStripe: (options?: { failPayment?: boolean }) => Promise<void>;
229
+ };
230
+
231
+ export const test = base.extend<PaymentFixtures>({
232
+ mockStripe: async ({ page }, use) => {
233
+ await use(async (options = {}) => {
234
+ await page.addInitScript(
235
+ ([shouldFail]) => {
236
+ (window as any).Stripe = () => ({
237
+ elements: () => ({
238
+ create: () => ({
239
+ mount: () => {},
240
+ on: (event: string, handler: Function) => {
241
+ if (event === "ready") setTimeout(handler, 100);
242
+ },
243
+ destroy: () => {},
244
+ }),
245
+ }),
246
+ confirmCardPayment: async () => {
247
+ if (shouldFail) {
248
+ return { error: { message: "Card declined" } };
249
+ }
250
+ return { paymentIntent: { status: "succeeded" } };
251
+ },
252
+ });
253
+ },
254
+ [options.failPayment],
255
+ );
256
+ });
257
+ },
258
+ });
259
+
260
+ // Usage
261
+ test("handles declined card", async ({ page, mockStripe }) => {
262
+ await mockStripe({ failPayment: true });
263
+
264
+ await page.goto("/checkout");
265
+ await page.getByRole("button", { name: "Pay" }).click();
266
+
267
+ await expect(page.getByText("Card declined")).toBeVisible();
268
+ });
269
+ ```
270
+
271
+ ## Email Verification
272
+
273
+ ### Mock Email API
274
+
275
+ ```typescript
276
+ test("email verification flow", async ({ page, request }) => {
277
+ let verificationToken: string;
278
+
279
+ // Capture the verification email
280
+ await page.route("**/api/send-verification", async (route) => {
281
+ const body = route.request().postDataJSON();
282
+ verificationToken = `mock-token-${Date.now()}`;
283
+
284
+ // Don't actually send email, just store token
285
+ route.fulfill({
286
+ json: { sent: true, messageId: "msg-123" },
287
+ });
288
+ });
289
+
290
+ // Mock token verification
291
+ await page.route("**/api/verify-email**", (route) => {
292
+ const url = new URL(route.request().url());
293
+ const token = url.searchParams.get("token");
294
+
295
+ if (token === verificationToken) {
296
+ route.fulfill({ json: { verified: true } });
297
+ } else {
298
+ route.fulfill({ status: 400, json: { error: "Invalid token" } });
299
+ }
300
+ });
301
+
302
+ await page.goto("/signup");
303
+ await page.getByLabel("Email").fill("test@example.com");
304
+ await page.getByRole("button", { name: "Sign Up" }).click();
305
+
306
+ await expect(page.getByText("Check your email")).toBeVisible();
307
+
308
+ // Simulate clicking email link
309
+ await page.goto(`/verify?token=${verificationToken}`);
310
+
311
+ await expect(page.getByText("Email verified")).toBeVisible();
312
+ });
313
+ ```
314
+
315
+ ### Use Mailinator/Temp Mail
316
+
317
+ ```typescript
318
+ // fixtures/email.fixture.ts
319
+ type EmailFixtures = {
320
+ getVerificationEmail: (inbox: string) => Promise<{ link: string }>;
321
+ };
322
+
323
+ export const test = base.extend<EmailFixtures>({
324
+ getVerificationEmail: async ({ request }, use) => {
325
+ await use(async (inbox) => {
326
+ // Poll Mailinator API for new email
327
+ const response = await request.get(
328
+ `https://api.mailinator.com/v2/domains/public/inboxes/${inbox}`,
329
+ {
330
+ headers: {
331
+ Authorization: `Bearer ${process.env.MAILINATOR_API_KEY}`,
332
+ },
333
+ },
334
+ );
335
+
336
+ const messages = await response.json();
337
+ const latest = messages.msgs[0];
338
+
339
+ // Get full message
340
+ const msgResponse = await request.get(
341
+ `https://api.mailinator.com/v2/domains/public/inboxes/${inbox}/messages/${latest.id}`,
342
+ {
343
+ headers: {
344
+ Authorization: `Bearer ${process.env.MAILINATOR_API_KEY}`,
345
+ },
346
+ },
347
+ );
348
+
349
+ const message = await msgResponse.json();
350
+
351
+ // Extract verification link from HTML
352
+ const linkMatch = message.parts[0].body.match(
353
+ /href="([^"]*verify[^"]*)"/,
354
+ );
355
+ return { link: linkMatch?.[1] || "" };
356
+ });
357
+ },
358
+ });
359
+ ```
360
+
361
+ ## SMS Verification
362
+
363
+ ### Mock SMS API
364
+
365
+ ```typescript
366
+ test("SMS verification", async ({ page }) => {
367
+ let smsCode: string;
368
+
369
+ // Capture SMS send
370
+ await page.route("**/api/send-sms", (route) => {
371
+ smsCode = Math.random().toString().slice(2, 8); // 6-digit code
372
+
373
+ route.fulfill({
374
+ json: { sent: true, messageId: "sms-123" },
375
+ });
376
+ });
377
+
378
+ // Mock code verification
379
+ await page.route("**/api/verify-sms", (route) => {
380
+ const body = route.request().postDataJSON();
381
+
382
+ if (body.code === smsCode) {
383
+ route.fulfill({ json: { verified: true } });
384
+ } else {
385
+ route.fulfill({ status: 400, json: { error: "Invalid code" } });
386
+ }
387
+ });
388
+
389
+ await page.goto("/verify-phone");
390
+ await page.getByLabel("Phone").fill("+1234567890");
391
+ await page.getByRole("button", { name: "Send Code" }).click();
392
+
393
+ // Enter the code
394
+ await page.getByLabel("Verification Code").fill(smsCode);
395
+ await page.getByRole("button", { name: "Verify" }).click();
396
+
397
+ await expect(page.getByText("Phone verified")).toBeVisible();
398
+ });
399
+ ```
400
+
401
+ ## Analytics & Tracking
402
+
403
+ ### Block Analytics in Tests
404
+
405
+ ```typescript
406
+ test.beforeEach(async ({ page }) => {
407
+ // Block all analytics/tracking
408
+ await page.route(
409
+ /google-analytics|googletagmanager|facebook|hotjar|segment|mixpanel|amplitude/,
410
+ (route) => route.abort(),
411
+ );
412
+ });
413
+ ```
414
+
415
+ ### Mock Analytics for Verification
416
+
417
+ ```typescript
418
+ test("tracks purchase event", async ({ page }) => {
419
+ const analyticsEvents: any[] = [];
420
+
421
+ // Capture analytics calls
422
+ await page.route("**/api/analytics/**", (route) => {
423
+ analyticsEvents.push(route.request().postDataJSON());
424
+ route.fulfill({ status: 200 });
425
+ });
426
+
427
+ // Mock analytics SDK
428
+ await page.addInitScript(() => {
429
+ (window as any).analytics = {
430
+ track: (event: string, props: any) => {
431
+ fetch("/api/analytics/track", {
432
+ method: "POST",
433
+ body: JSON.stringify({ event, props }),
434
+ });
435
+ },
436
+ };
437
+ });
438
+
439
+ await page.goto("/checkout");
440
+ await page.getByRole("button", { name: "Complete Purchase" }).click();
441
+
442
+ // Verify analytics event was sent
443
+ expect(analyticsEvents).toContainEqual(
444
+ expect.objectContaining({
445
+ event: "Purchase Completed",
446
+ props: expect.objectContaining({ amount: expect.any(Number) }),
447
+ }),
448
+ );
449
+ });
450
+ ```
451
+
452
+ ## Anti-Patterns to Avoid
453
+
454
+ | Anti-Pattern | Problem | Solution |
455
+ | ------------------------- | ------------------------------ | ----------------------- |
456
+ | Using real OAuth in tests | Slow, needs credentials, flaky | Mock OAuth endpoints |
457
+ | Real payment processing | Charges real money, slow | Use test mode or mock |
458
+ | Waiting for real emails | Very slow, unreliable | Mock email API |
459
+ | Not mocking analytics | Pollutes analytics data | Block or mock analytics |
460
+
461
+ ## Related References
462
+
463
+ - **Network Mocking**: See [network-advanced.md](network-advanced.md) for route patterns
464
+ - **Authentication**: See [fixtures-hooks.md](../core/fixtures-hooks.md) for auth patterns