@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,331 +0,0 @@
1
- # GraphQL Testing
2
-
3
- ## Table of Contents
4
-
5
- 1. [Patterns](#patterns)
6
- 2. [Anti-Patterns](#anti-patterns)
7
- 3. [Troubleshooting](#troubleshooting)
8
-
9
- > **When to use**: Testing GraphQL APIs — queries, mutations, variables, and error handling.
10
-
11
- ## Patterns
12
-
13
- ### Basic Query with Variables
14
-
15
- All GraphQL requests go through `POST` to a single endpoint. Send `query`, `variables`, and optionally `operationName` in the JSON body.
16
-
17
- ```typescript
18
- import { test, expect } from "@playwright/test";
19
-
20
- const GQL_ENDPOINT = "/graphql";
21
-
22
- test("query with variables", async ({ request }) => {
23
- const resp = await request.post(GQL_ENDPOINT, {
24
- data: {
25
- query: `
26
- query FetchItem($id: ID!) {
27
- item(id: $id) {
28
- id
29
- title
30
- price
31
- reviews { id rating }
32
- }
33
- }
34
- `,
35
- variables: { id: "101" },
36
- },
37
- });
38
-
39
- expect(resp.ok()).toBeTruthy();
40
- const { data, errors } = await resp.json();
41
-
42
- // GraphQL returns 200 even on errors — always check both
43
- expect(errors).toBeUndefined();
44
- expect(data.item).toMatchObject({
45
- id: "101",
46
- title: expect.any(String),
47
- price: expect.any(Number),
48
- });
49
- expect(data.item.reviews).toEqual(
50
- expect.arrayContaining([
51
- expect.objectContaining({
52
- id: expect.any(String),
53
- rating: expect.any(Number),
54
- }),
55
- ])
56
- );
57
- });
58
- ```
59
-
60
- ### Mutations
61
-
62
- ```typescript
63
- import { test, expect } from "@playwright/test";
64
-
65
- const GQL_ENDPOINT = "/graphql";
66
-
67
- test("mutation creates resource", async ({ request }) => {
68
- const resp = await request.post(GQL_ENDPOINT, {
69
- data: {
70
- query: `
71
- mutation AddItem($input: ItemInput!) {
72
- addItem(input: $input) {
73
- id
74
- title
75
- status
76
- }
77
- }
78
- `,
79
- variables: {
80
- input: {
81
- title: "New Widget",
82
- price: 15.0,
83
- status: "DRAFT",
84
- },
85
- },
86
- },
87
- });
88
-
89
- const { data, errors } = await resp.json();
90
- expect(errors).toBeUndefined();
91
- expect(data.addItem).toMatchObject({
92
- id: expect.any(String),
93
- title: "New Widget",
94
- status: "DRAFT",
95
- });
96
- });
97
- ```
98
-
99
- ### Validation Errors
100
-
101
- ```typescript
102
- import { test, expect } from "@playwright/test";
103
-
104
- const GQL_ENDPOINT = "/graphql";
105
-
106
- test("handles validation errors", async ({ request }) => {
107
- const resp = await request.post(GQL_ENDPOINT, {
108
- data: {
109
- query: `
110
- mutation AddItem($input: ItemInput!) {
111
- addItem(input: $input) { id }
112
- }
113
- `,
114
- variables: { input: { title: "" } },
115
- },
116
- });
117
-
118
- const { data, errors } = await resp.json();
119
- expect(errors).toBeDefined();
120
- expect(errors.length).toBeGreaterThan(0);
121
- expect(errors[0].message).toContain("title");
122
- expect(errors[0].extensions?.code).toBe("BAD_USER_INPUT");
123
- });
124
- ```
125
-
126
- ### Authorization Errors
127
-
128
- ```typescript
129
- import { test, expect } from "@playwright/test";
130
-
131
- const GQL_ENDPOINT = "/graphql";
132
-
133
- test("handles authorization errors", async ({ request }) => {
134
- const resp = await request.post(GQL_ENDPOINT, {
135
- data: {
136
- query: `
137
- query AdminDashboard {
138
- adminMetrics { revenue activeUsers }
139
- }
140
- `,
141
- },
142
- });
143
-
144
- const { data, errors } = await resp.json();
145
- expect(errors).toBeDefined();
146
- expect(errors[0].extensions?.code).toBe("UNAUTHORIZED");
147
- expect(data?.adminMetrics).toBeNull();
148
- });
149
- ```
150
-
151
- ### Authenticated GraphQL Fixture
152
-
153
- ```typescript
154
- // fixtures/graphql-fixtures.ts
155
- import { test as base, expect, APIRequestContext } from "@playwright/test";
156
-
157
- type GraphQLFixtures = {
158
- gqlClient: APIRequestContext;
159
- adminGqlClient: APIRequestContext;
160
- };
161
-
162
- export const test = base.extend<GraphQLFixtures>({
163
- gqlClient: async ({ playwright }, use) => {
164
- const ctx = await playwright.request.newContext({
165
- baseURL: "https://api.myapp.io",
166
- extraHTTPHeaders: {
167
- Authorization: `Bearer ${process.env.API_TOKEN}`,
168
- "Content-Type": "application/json",
169
- },
170
- });
171
- await use(ctx);
172
- await ctx.dispose();
173
- },
174
-
175
- adminGqlClient: async ({ playwright }, use) => {
176
- const loginCtx = await playwright.request.newContext({
177
- baseURL: "https://api.myapp.io",
178
- });
179
- const loginResp = await loginCtx.post("/graphql", {
180
- data: {
181
- query: `
182
- mutation Login($email: String!, $password: String!) {
183
- login(email: $email, password: $password) { token }
184
- }
185
- `,
186
- variables: {
187
- email: process.env.ADMIN_EMAIL,
188
- password: process.env.ADMIN_PASSWORD,
189
- },
190
- },
191
- });
192
- const { data } = await loginResp.json();
193
-
194
- if (!data?.login?.token) {
195
- throw new Error(`Admin login failed: status ${loginResp.status()}, response: ${JSON.stringify(data)}`);
196
- }
197
-
198
- await loginCtx.dispose();
199
-
200
- const ctx = await playwright.request.newContext({
201
- baseURL: "https://api.myapp.io",
202
- extraHTTPHeaders: {
203
- Authorization: `Bearer ${data.login.token}`,
204
- "Content-Type": "application/json",
205
- },
206
- });
207
- await use(ctx);
208
- await ctx.dispose();
209
- },
210
- });
211
-
212
- export { expect };
213
- ```
214
-
215
- ### GraphQL Helper Function
216
-
217
- ```typescript
218
- // utils/graphql.ts
219
- import { APIRequestContext, expect } from "@playwright/test";
220
-
221
- export async function gqlQuery<T = any>(
222
- request: APIRequestContext,
223
- query: string,
224
- variables?: Record<string, any>
225
- ): Promise<{ data: T; errors?: any[] }> {
226
- const resp = await request.post("/graphql", {
227
- data: { query, variables },
228
- });
229
- expect(resp.ok()).toBeTruthy();
230
- return resp.json();
231
- }
232
-
233
- export async function gqlMutation<T = any>(
234
- request: APIRequestContext,
235
- mutation: string,
236
- variables?: Record<string, any>
237
- ): Promise<{ data: T; errors?: any[] }> {
238
- return gqlQuery<T>(request, mutation, variables);
239
- }
240
- ```
241
-
242
- ```typescript
243
- // tests/api/items.spec.ts
244
- import { test, expect } from "@playwright/test";
245
- import { gqlQuery, gqlMutation } from "../../utils/graphql";
246
-
247
- test("fetch and update item", async ({ request }) => {
248
- const { data: fetchData } = await gqlQuery(
249
- request,
250
- `query GetItem($id: ID!) { item(id: $id) { id title } }`,
251
- { id: "101" }
252
- );
253
- expect(fetchData.item.title).toBeDefined();
254
-
255
- const { data: updateData, errors } = await gqlMutation(
256
- request,
257
- `mutation UpdateItem($id: ID!, $title: String!) {
258
- updateItem(id: $id, title: $title) { id title }
259
- }`,
260
- { id: "101", title: "Updated Title" }
261
- );
262
- expect(errors).toBeUndefined();
263
- expect(updateData.updateItem.title).toBe("Updated Title");
264
- });
265
- ```
266
-
267
- ## Anti-Patterns
268
-
269
- | Don't Do This | Problem | Do This Instead |
270
- | --- | --- | --- |
271
- | Check only `response.ok()` | GraphQL returns 200 even on errors — `errors` array is the real signal | Always check both `data` and `errors` in the response body |
272
- | Ignore `errors` array | Validation and auth errors appear in `errors`, not HTTP status | Destructure and assert: `expect(errors).toBeUndefined()` |
273
- | Hardcode query strings inline everywhere | Duplicated queries are hard to maintain | Extract queries to constants or use a helper function |
274
- | Skip variable validation | Invalid variables cause cryptic server errors | Validate input shape before sending |
275
-
276
- ## Troubleshooting
277
-
278
- ### GraphQL returns 200 but data is null
279
-
280
- **Cause**: GraphQL servers return HTTP 200 even when the query has errors. The actual error is in the `errors` array.
281
-
282
- **Fix**: Always destructure and check both `data` and `errors`.
283
-
284
- ```typescript
285
- const { data, errors } = await resp.json();
286
- if (errors) {
287
- console.error("GraphQL errors:", JSON.stringify(errors, null, 2));
288
- }
289
- expect(errors).toBeUndefined();
290
- expect(data.item).toBeDefined();
291
- ```
292
-
293
- ### "Cannot query field X on type Y"
294
-
295
- **Cause**: The field doesn't exist in the schema, or you're querying the wrong type.
296
-
297
- **Fix**: Verify the schema. Use introspection or check your GraphQL IDE for available fields.
298
-
299
- ```typescript
300
- // Introspection query to debug schema
301
- const { data } = await request.post("/graphql", {
302
- data: {
303
- query: `{ __type(name: "Item") { fields { name type { name } } } }`,
304
- },
305
- });
306
- console.log(data.__type.fields);
307
- ```
308
-
309
- ### Variables not being applied
310
-
311
- **Cause**: Variable names in the query don't match the `variables` object keys, or types don't match.
312
-
313
- **Fix**: Ensure variable names match exactly (case-sensitive) and types align with the schema.
314
-
315
- ```typescript
316
- // Wrong: variable name mismatch
317
- const resp = await request.post("/graphql", {
318
- data: {
319
- query: `query GetItem($itemId: ID!) { item(id: $itemId) { id } }`,
320
- variables: { id: "101" }, // Should be { itemId: "101" }
321
- },
322
- });
323
-
324
- // Correct
325
- const resp = await request.post("/graphql", {
326
- data: {
327
- query: `query GetItem($itemId: ID!) { item(id: $itemId) { id } }`,
328
- variables: { itemId: "101" },
329
- },
330
- });
331
- ```