@arcadialdev/arcality 2.4.28 → 2.4.30

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 (83) hide show
  1. package/README.md +2 -2
  2. package/package.json +3 -7
  3. package/scripts/gen-and-run.mjs +5 -18
  4. package/src/KnowledgeService.ts +256 -0
  5. package/src/arcalityClient.mjs +2 -1
  6. package/src/consoleBanner.ts +32 -0
  7. package/src/envSetup.ts +205 -0
  8. package/src/index.ts +25 -0
  9. package/src/projectInspector.ts +42 -0
  10. package/src/services/collectiveMemoryService.ts +178 -0
  11. package/src/services/securityScanner.ts +128 -0
  12. package/src/testRunner.ts +201 -0
  13. package/tests/_helpers/agentic-runner.bundle.spec.js +2912 -83
  14. package/.agents/skills/e2e-testing-expert/SKILL.md +0 -28
  15. package/.agents/skills/frontend-design/LICENSE.txt +0 -177
  16. package/.agents/skills/frontend-design/SKILL.md +0 -42
  17. package/.agents/skills/nodejs-backend-patterns/SKILL.md +0 -639
  18. package/.agents/skills/nodejs-backend-patterns/references/advanced-patterns.md +0 -430
  19. package/.agents/skills/playwright-best-practices/LICENSE.md +0 -7
  20. package/.agents/skills/playwright-best-practices/README.md +0 -147
  21. package/.agents/skills/playwright-best-practices/SKILL.md +0 -303
  22. package/.agents/skills/playwright-best-practices/advanced/authentication-flows.md +0 -360
  23. package/.agents/skills/playwright-best-practices/advanced/authentication.md +0 -871
  24. package/.agents/skills/playwright-best-practices/advanced/clock-mocking.md +0 -364
  25. package/.agents/skills/playwright-best-practices/advanced/mobile-testing.md +0 -409
  26. package/.agents/skills/playwright-best-practices/advanced/multi-context.md +0 -288
  27. package/.agents/skills/playwright-best-practices/advanced/multi-user.md +0 -393
  28. package/.agents/skills/playwright-best-practices/advanced/network-advanced.md +0 -452
  29. package/.agents/skills/playwright-best-practices/advanced/third-party.md +0 -464
  30. package/.agents/skills/playwright-best-practices/architecture/pom-vs-fixtures.md +0 -363
  31. package/.agents/skills/playwright-best-practices/architecture/test-architecture.md +0 -369
  32. package/.agents/skills/playwright-best-practices/architecture/when-to-mock.md +0 -383
  33. package/.agents/skills/playwright-best-practices/browser-apis/browser-apis.md +0 -391
  34. package/.agents/skills/playwright-best-practices/browser-apis/iframes.md +0 -403
  35. package/.agents/skills/playwright-best-practices/browser-apis/service-workers.md +0 -504
  36. package/.agents/skills/playwright-best-practices/browser-apis/websockets.md +0 -403
  37. package/.agents/skills/playwright-best-practices/core/annotations.md +0 -424
  38. package/.agents/skills/playwright-best-practices/core/assertions-waiting.md +0 -361
  39. package/.agents/skills/playwright-best-practices/core/configuration.md +0 -452
  40. package/.agents/skills/playwright-best-practices/core/fixtures-hooks.md +0 -417
  41. package/.agents/skills/playwright-best-practices/core/global-setup.md +0 -434
  42. package/.agents/skills/playwright-best-practices/core/locators.md +0 -242
  43. package/.agents/skills/playwright-best-practices/core/page-object-model.md +0 -315
  44. package/.agents/skills/playwright-best-practices/core/projects-dependencies.md +0 -453
  45. package/.agents/skills/playwright-best-practices/core/test-data.md +0 -492
  46. package/.agents/skills/playwright-best-practices/core/test-suite-structure.md +0 -361
  47. package/.agents/skills/playwright-best-practices/core/test-tags.md +0 -298
  48. package/.agents/skills/playwright-best-practices/debugging/console-errors.md +0 -420
  49. package/.agents/skills/playwright-best-practices/debugging/debugging.md +0 -504
  50. package/.agents/skills/playwright-best-practices/debugging/error-testing.md +0 -360
  51. package/.agents/skills/playwright-best-practices/debugging/flaky-tests.md +0 -496
  52. package/.agents/skills/playwright-best-practices/frameworks/angular.md +0 -530
  53. package/.agents/skills/playwright-best-practices/frameworks/nextjs.md +0 -469
  54. package/.agents/skills/playwright-best-practices/frameworks/react.md +0 -531
  55. package/.agents/skills/playwright-best-practices/frameworks/vue.md +0 -574
  56. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/ci-cd.md +0 -468
  57. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/docker.md +0 -283
  58. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/github-actions.md +0 -546
  59. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/gitlab.md +0 -397
  60. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/other-providers.md +0 -521
  61. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/parallel-sharding.md +0 -371
  62. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/performance.md +0 -453
  63. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/reporting.md +0 -424
  64. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/test-coverage.md +0 -497
  65. package/.agents/skills/playwright-best-practices/testing-patterns/accessibility.md +0 -359
  66. package/.agents/skills/playwright-best-practices/testing-patterns/api-testing.md +0 -719
  67. package/.agents/skills/playwright-best-practices/testing-patterns/browser-extensions.md +0 -506
  68. package/.agents/skills/playwright-best-practices/testing-patterns/canvas-webgl.md +0 -493
  69. package/.agents/skills/playwright-best-practices/testing-patterns/component-testing.md +0 -500
  70. package/.agents/skills/playwright-best-practices/testing-patterns/drag-drop.md +0 -576
  71. package/.agents/skills/playwright-best-practices/testing-patterns/electron.md +0 -509
  72. package/.agents/skills/playwright-best-practices/testing-patterns/file-operations.md +0 -377
  73. package/.agents/skills/playwright-best-practices/testing-patterns/file-upload-download.md +0 -562
  74. package/.agents/skills/playwright-best-practices/testing-patterns/forms-validation.md +0 -561
  75. package/.agents/skills/playwright-best-practices/testing-patterns/graphql-testing.md +0 -331
  76. package/.agents/skills/playwright-best-practices/testing-patterns/i18n.md +0 -508
  77. package/.agents/skills/playwright-best-practices/testing-patterns/performance-testing.md +0 -476
  78. package/.agents/skills/playwright-best-practices/testing-patterns/security-testing.md +0 -430
  79. package/.agents/skills/playwright-best-practices/testing-patterns/visual-regression.md +0 -634
  80. package/.agents/skills/security-qa/SKILL.md +0 -254
  81. package/public/ArcalityImagen.png +0 -0
  82. package/public/logo-arcadial-blanco.png +0 -0
  83. package/public/logo.png +0 -0
@@ -1,377 +0,0 @@
1
- # File Upload & Download Testing
2
-
3
- > For advanced patterns (progress tracking, cancellation, retry logic), see [file-upload-download.md](./file-upload-download.md)
4
-
5
- ## Table of Contents
6
-
7
- 1. [File Downloads](#file-downloads)
8
- 2. [File Uploads](#file-uploads)
9
- 3. [Drag and Drop](#drag-and-drop)
10
- 4. [File Content Verification](#file-content-verification)
11
-
12
- ## File Downloads
13
-
14
- ### Basic Download
15
-
16
- ```typescript
17
- test("download PDF report", async ({ page }) => {
18
- await page.goto("/reports");
19
-
20
- // Start waiting for download before clicking
21
- const downloadPromise = page.waitForEvent("download");
22
- await page.getByRole("button", { name: "Download PDF" }).click();
23
- const download = await downloadPromise;
24
-
25
- // Verify filename
26
- expect(download.suggestedFilename()).toBe("report.pdf");
27
-
28
- // Save to specific path
29
- await download.saveAs("./downloads/report.pdf");
30
- });
31
- ```
32
-
33
- ### Download with Custom Path
34
-
35
- ```typescript
36
- test("download to temp directory", async ({ page }, testInfo) => {
37
- await page.goto("/exports");
38
-
39
- const downloadPromise = page.waitForEvent("download");
40
- await page.getByRole("link", { name: "Export CSV" }).click();
41
- const download = await downloadPromise;
42
-
43
- // Save to test output directory
44
- const path = testInfo.outputPath(download.suggestedFilename());
45
- await download.saveAs(path);
46
-
47
- // Attach to test report
48
- await testInfo.attach("downloaded-file", { path });
49
- });
50
- ```
51
-
52
- ### Verify Download Content
53
-
54
- ```typescript
55
- import fs from "fs";
56
- import path from "path";
57
-
58
- test("verify CSV content", async ({ page }, testInfo) => {
59
- await page.goto("/data");
60
-
61
- const downloadPromise = page.waitForEvent("download");
62
- await page.getByRole("button", { name: "Export" }).click();
63
- const download = await downloadPromise;
64
-
65
- const filePath = testInfo.outputPath("export.csv");
66
- await download.saveAs(filePath);
67
-
68
- // Read and verify content
69
- const content = fs.readFileSync(filePath, "utf-8");
70
- expect(content).toContain("Name,Email,Status");
71
- expect(content).toContain("John Doe");
72
-
73
- // Verify row count
74
- const rows = content.trim().split("\n");
75
- expect(rows.length).toBeGreaterThan(1);
76
- });
77
- ```
78
-
79
- ### Multiple Downloads
80
-
81
- ```typescript
82
- test("download multiple files", async ({ page }) => {
83
- await page.goto("/batch-export");
84
-
85
- await page.getByRole("checkbox", { name: "Select All" }).check();
86
-
87
- // Collect all downloads
88
- const downloads: Download[] = [];
89
- page.on("download", (download) => downloads.push(download));
90
-
91
- await page.getByRole("button", { name: "Download Selected" }).click();
92
-
93
- // Wait for all downloads
94
- await expect.poll(() => downloads.length, { timeout: 30000 }).toBe(5);
95
-
96
- // Verify each download
97
- for (const download of downloads) {
98
- expect(download.suggestedFilename()).toMatch(/\.pdf$/);
99
- }
100
- });
101
- ```
102
-
103
- ### Download Fixture
104
-
105
- ```typescript
106
- // fixtures/download.fixture.ts
107
- import { test as base, Download } from "@playwright/test";
108
- import fs from "fs";
109
- import path from "path";
110
-
111
- type DownloadFixtures = {
112
- downloadDir: string;
113
- downloadAndVerify: (
114
- trigger: () => Promise<void>,
115
- expectedFilename: string,
116
- ) => Promise<string>;
117
- };
118
-
119
- export const test = base.extend<DownloadFixtures>({
120
- downloadDir: async ({}, use, testInfo) => {
121
- const dir = testInfo.outputPath("downloads");
122
- fs.mkdirSync(dir, { recursive: true });
123
- await use(dir);
124
- },
125
-
126
- downloadAndVerify: async ({ page, downloadDir }, use) => {
127
- await use(async (trigger, expectedFilename) => {
128
- const downloadPromise = page.waitForEvent("download");
129
- await trigger();
130
- const download = await downloadPromise;
131
-
132
- expect(download.suggestedFilename()).toBe(expectedFilename);
133
-
134
- const filePath = path.join(downloadDir, expectedFilename);
135
- await download.saveAs(filePath);
136
- return filePath;
137
- });
138
- },
139
- });
140
- ```
141
-
142
- ## File Uploads
143
-
144
- ### Basic Upload
145
-
146
- ```typescript
147
- test("upload profile picture", async ({ page }) => {
148
- await page.goto("/settings/profile");
149
-
150
- // Upload file
151
- await page
152
- .getByLabel("Profile Picture")
153
- .setInputFiles("./fixtures/avatar.png");
154
-
155
- // Verify preview
156
- await expect(page.getByAltText("Profile preview")).toBeVisible();
157
-
158
- await page.getByRole("button", { name: "Save" }).click();
159
- await expect(page.getByText("Profile updated")).toBeVisible();
160
- });
161
- ```
162
-
163
- ### Multiple File Upload
164
-
165
- ```typescript
166
- test("upload multiple documents", async ({ page }) => {
167
- await page.goto("/documents/upload");
168
-
169
- await page
170
- .getByLabel("Documents")
171
- .setInputFiles([
172
- "./fixtures/doc1.pdf",
173
- "./fixtures/doc2.pdf",
174
- "./fixtures/doc3.pdf",
175
- ]);
176
-
177
- // Verify all files listed
178
- await expect(page.getByText("doc1.pdf")).toBeVisible();
179
- await expect(page.getByText("doc2.pdf")).toBeVisible();
180
- await expect(page.getByText("doc3.pdf")).toBeVisible();
181
-
182
- await page.getByRole("button", { name: "Upload All" }).click();
183
- await expect(page.getByText("3 files uploaded")).toBeVisible();
184
- });
185
- ```
186
-
187
- ### Upload with File Chooser
188
-
189
- ```typescript
190
- test("upload via file chooser dialog", async ({ page }) => {
191
- await page.goto("/upload");
192
-
193
- // Handle file chooser
194
- const fileChooserPromise = page.waitForEvent("filechooser");
195
- await page.getByRole("button", { name: "Choose File" }).click();
196
- const fileChooser = await fileChooserPromise;
197
-
198
- await fileChooser.setFiles("./fixtures/document.pdf");
199
-
200
- await expect(page.getByText("document.pdf")).toBeVisible();
201
- });
202
- ```
203
-
204
- ### Clear and Re-upload
205
-
206
- ```typescript
207
- test("replace uploaded file", async ({ page }) => {
208
- await page.goto("/upload");
209
-
210
- const input = page.getByLabel("Document");
211
-
212
- // Upload first file
213
- await input.setInputFiles("./fixtures/old.pdf");
214
- await expect(page.getByText("old.pdf")).toBeVisible();
215
-
216
- // Clear selection
217
- await input.setInputFiles([]);
218
-
219
- // Upload new file
220
- await input.setInputFiles("./fixtures/new.pdf");
221
- await expect(page.getByText("new.pdf")).toBeVisible();
222
- await expect(page.getByText("old.pdf")).toBeHidden();
223
- });
224
- ```
225
-
226
- ### Upload from Buffer
227
-
228
- ```typescript
229
- test("upload generated file", async ({ page }) => {
230
- await page.goto("/upload");
231
-
232
- // Create file content dynamically
233
- const content = "Name,Email\nJohn,john@example.com";
234
-
235
- await page.getByLabel("CSV File").setInputFiles({
236
- name: "users.csv",
237
- mimeType: "text/csv",
238
- buffer: Buffer.from(content),
239
- });
240
-
241
- await expect(page.getByText("users.csv")).toBeVisible();
242
- });
243
- ```
244
-
245
- ## Drag and Drop
246
-
247
- ### Drag and Drop Upload
248
-
249
- ```typescript
250
- test("drag and drop file upload", async ({ page }) => {
251
- await page.goto("/upload");
252
-
253
- const dropzone = page.getByTestId("dropzone");
254
-
255
- // Create a DataTransfer with the file
256
- const dataTransfer = await page.evaluateHandle(() => new DataTransfer());
257
-
258
- // Read file and add to DataTransfer
259
- const buffer = fs.readFileSync("./fixtures/image.png");
260
- await page.evaluate(
261
- async ([dataTransfer, data]) => {
262
- const file = new File([new Uint8Array(data)], "image.png", {
263
- type: "image/png",
264
- });
265
- dataTransfer.items.add(file);
266
- },
267
- [dataTransfer, [...buffer]] as const,
268
- );
269
-
270
- // Dispatch drop event
271
- await dropzone.dispatchEvent("drop", { dataTransfer });
272
-
273
- await expect(page.getByText("image.png uploaded")).toBeVisible();
274
- });
275
- ```
276
-
277
- ### Simpler Drag and Drop
278
-
279
- ```typescript
280
- test("drag and drop with setInputFiles", async ({ page }) => {
281
- await page.goto("/upload");
282
-
283
- // Most dropzones have a hidden file input
284
- const input = page.locator('input[type="file"]');
285
-
286
- // This works even if the input is hidden
287
- await input.setInputFiles("./fixtures/document.pdf");
288
-
289
- await expect(page.getByText("document.pdf")).toBeVisible();
290
- });
291
- ```
292
-
293
- ## File Content Verification
294
-
295
- ### Verify PDF Content
296
-
297
- ```typescript
298
- import pdf from "pdf-parse";
299
-
300
- test("verify PDF content", async ({ page }, testInfo) => {
301
- await page.goto("/invoice/123");
302
-
303
- const downloadPromise = page.waitForEvent("download");
304
- await page.getByRole("button", { name: "Download Invoice" }).click();
305
- const download = await downloadPromise;
306
-
307
- const path = testInfo.outputPath("invoice.pdf");
308
- await download.saveAs(path);
309
-
310
- // Parse PDF
311
- const dataBuffer = fs.readFileSync(path);
312
- const data = await pdf(dataBuffer);
313
-
314
- expect(data.text).toContain("Invoice #123");
315
- expect(data.text).toContain("Total: $99.99");
316
- });
317
- ```
318
-
319
- ### Verify Excel Content
320
-
321
- ```typescript
322
- import XLSX from "xlsx";
323
-
324
- test("verify Excel export", async ({ page }, testInfo) => {
325
- await page.goto("/reports");
326
-
327
- const downloadPromise = page.waitForEvent("download");
328
- await page.getByRole("button", { name: "Export Excel" }).click();
329
- const download = await downloadPromise;
330
-
331
- const path = testInfo.outputPath("report.xlsx");
332
- await download.saveAs(path);
333
-
334
- // Parse Excel
335
- const workbook = XLSX.readFile(path);
336
- const sheet = workbook.Sheets[workbook.SheetNames[0]];
337
- const data = XLSX.utils.sheet_to_json(sheet);
338
-
339
- expect(data).toHaveLength(10);
340
- expect(data[0]).toHaveProperty("Name");
341
- expect(data[0]).toHaveProperty("Email");
342
- });
343
- ```
344
-
345
- ### Verify JSON Download
346
-
347
- ```typescript
348
- test("verify JSON export", async ({ page }, testInfo) => {
349
- await page.goto("/api-data");
350
-
351
- const downloadPromise = page.waitForEvent("download");
352
- await page.getByRole("button", { name: "Export JSON" }).click();
353
- const download = await downloadPromise;
354
-
355
- const path = testInfo.outputPath("data.json");
356
- await download.saveAs(path);
357
-
358
- const content = JSON.parse(fs.readFileSync(path, "utf-8"));
359
-
360
- expect(content.users).toHaveLength(5);
361
- expect(content.exportDate).toBeDefined();
362
- });
363
- ```
364
-
365
- ## Anti-Patterns to Avoid
366
-
367
- | Anti-Pattern | Problem | Solution |
368
- | ------------------------------------- | ------------------------------- | --------------------------------------------- |
369
- | Not waiting for download | Race condition, test fails | Always use `waitForEvent("download")` |
370
- | Hardcoded download paths | Conflicts in parallel runs | Use `testInfo.outputPath()` |
371
- | Skipping content verification | Download might be empty/corrupt | Verify file content when possible |
372
- | Using `force: true` for hidden inputs | May not trigger proper events | Use `setInputFiles` on hidden inputs directly |
373
-
374
- ## Related References
375
-
376
- - **Fixtures**: See [fixtures-hooks.md](../core/fixtures-hooks.md) for download fixture patterns
377
- - **Debugging**: See [debugging.md](../debugging/debugging.md) for troubleshooting download issues