@arcadialdev/arcality 2.4.29 → 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 (80) hide show
  1. package/package.json +3 -4
  2. package/src/arcalityClient.mjs +2 -1
  3. package/.agents/skills/e2e-testing-expert/SKILL.md +0 -28
  4. package/.agents/skills/frontend-design/LICENSE.txt +0 -177
  5. package/.agents/skills/frontend-design/SKILL.md +0 -42
  6. package/.agents/skills/nodejs-backend-patterns/SKILL.md +0 -639
  7. package/.agents/skills/nodejs-backend-patterns/references/advanced-patterns.md +0 -430
  8. package/.agents/skills/playwright-best-practices/LICENSE.md +0 -7
  9. package/.agents/skills/playwright-best-practices/README.md +0 -147
  10. package/.agents/skills/playwright-best-practices/SKILL.md +0 -303
  11. package/.agents/skills/playwright-best-practices/advanced/authentication-flows.md +0 -360
  12. package/.agents/skills/playwright-best-practices/advanced/authentication.md +0 -871
  13. package/.agents/skills/playwright-best-practices/advanced/clock-mocking.md +0 -364
  14. package/.agents/skills/playwright-best-practices/advanced/mobile-testing.md +0 -409
  15. package/.agents/skills/playwright-best-practices/advanced/multi-context.md +0 -288
  16. package/.agents/skills/playwright-best-practices/advanced/multi-user.md +0 -393
  17. package/.agents/skills/playwright-best-practices/advanced/network-advanced.md +0 -452
  18. package/.agents/skills/playwright-best-practices/advanced/third-party.md +0 -464
  19. package/.agents/skills/playwright-best-practices/architecture/pom-vs-fixtures.md +0 -363
  20. package/.agents/skills/playwright-best-practices/architecture/test-architecture.md +0 -369
  21. package/.agents/skills/playwright-best-practices/architecture/when-to-mock.md +0 -383
  22. package/.agents/skills/playwright-best-practices/browser-apis/browser-apis.md +0 -391
  23. package/.agents/skills/playwright-best-practices/browser-apis/iframes.md +0 -403
  24. package/.agents/skills/playwright-best-practices/browser-apis/service-workers.md +0 -504
  25. package/.agents/skills/playwright-best-practices/browser-apis/websockets.md +0 -403
  26. package/.agents/skills/playwright-best-practices/core/annotations.md +0 -424
  27. package/.agents/skills/playwright-best-practices/core/assertions-waiting.md +0 -361
  28. package/.agents/skills/playwright-best-practices/core/configuration.md +0 -452
  29. package/.agents/skills/playwright-best-practices/core/fixtures-hooks.md +0 -417
  30. package/.agents/skills/playwright-best-practices/core/global-setup.md +0 -434
  31. package/.agents/skills/playwright-best-practices/core/locators.md +0 -242
  32. package/.agents/skills/playwright-best-practices/core/page-object-model.md +0 -315
  33. package/.agents/skills/playwright-best-practices/core/projects-dependencies.md +0 -453
  34. package/.agents/skills/playwright-best-practices/core/test-data.md +0 -492
  35. package/.agents/skills/playwright-best-practices/core/test-suite-structure.md +0 -361
  36. package/.agents/skills/playwright-best-practices/core/test-tags.md +0 -298
  37. package/.agents/skills/playwright-best-practices/debugging/console-errors.md +0 -420
  38. package/.agents/skills/playwright-best-practices/debugging/debugging.md +0 -504
  39. package/.agents/skills/playwright-best-practices/debugging/error-testing.md +0 -360
  40. package/.agents/skills/playwright-best-practices/debugging/flaky-tests.md +0 -496
  41. package/.agents/skills/playwright-best-practices/frameworks/angular.md +0 -530
  42. package/.agents/skills/playwright-best-practices/frameworks/nextjs.md +0 -469
  43. package/.agents/skills/playwright-best-practices/frameworks/react.md +0 -531
  44. package/.agents/skills/playwright-best-practices/frameworks/vue.md +0 -574
  45. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/ci-cd.md +0 -468
  46. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/docker.md +0 -283
  47. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/github-actions.md +0 -546
  48. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/gitlab.md +0 -397
  49. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/other-providers.md +0 -521
  50. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/parallel-sharding.md +0 -371
  51. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/performance.md +0 -453
  52. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/reporting.md +0 -424
  53. package/.agents/skills/playwright-best-practices/infrastructure-ci-cd/test-coverage.md +0 -497
  54. package/.agents/skills/playwright-best-practices/testing-patterns/accessibility.md +0 -359
  55. package/.agents/skills/playwright-best-practices/testing-patterns/api-testing.md +0 -719
  56. package/.agents/skills/playwright-best-practices/testing-patterns/browser-extensions.md +0 -506
  57. package/.agents/skills/playwright-best-practices/testing-patterns/canvas-webgl.md +0 -493
  58. package/.agents/skills/playwright-best-practices/testing-patterns/component-testing.md +0 -500
  59. package/.agents/skills/playwright-best-practices/testing-patterns/drag-drop.md +0 -576
  60. package/.agents/skills/playwright-best-practices/testing-patterns/electron.md +0 -509
  61. package/.agents/skills/playwright-best-practices/testing-patterns/file-operations.md +0 -377
  62. package/.agents/skills/playwright-best-practices/testing-patterns/file-upload-download.md +0 -562
  63. package/.agents/skills/playwright-best-practices/testing-patterns/forms-validation.md +0 -561
  64. package/.agents/skills/playwright-best-practices/testing-patterns/graphql-testing.md +0 -331
  65. package/.agents/skills/playwright-best-practices/testing-patterns/i18n.md +0 -508
  66. package/.agents/skills/playwright-best-practices/testing-patterns/performance-testing.md +0 -476
  67. package/.agents/skills/playwright-best-practices/testing-patterns/security-testing.md +0 -430
  68. package/.agents/skills/playwright-best-practices/testing-patterns/visual-regression.md +0 -634
  69. package/.agents/skills/security-qa/SKILL.md +0 -254
  70. package/public/ArcalityImagen.png +0 -0
  71. package/public/logo-arcadial-blanco.png +0 -0
  72. package/public/logo.png +0 -0
  73. package/tests/_helpers/ArcalityReporter.ts +0 -733
  74. package/tests/_helpers/agentic-runner.spec.ts +0 -783
  75. package/tests/_helpers/ai-agent-helper.ts +0 -1660
  76. package/tests/_helpers/discover-view.spec.ts +0 -238
  77. package/tests/_helpers/extract-view.spec.ts +0 -118
  78. package/tests/_helpers/qa-security-tools.ts +0 -265
  79. package/tests/_helpers/qa-tools.ts +0 -333
  80. package/tests/_helpers/smart-action.spec.ts +0 -1458
@@ -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