testeiya 0.10.1 → 0.10.2
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.
- package/README.md +7 -19
- package/dist/prompt/clis.d.ts +7 -0
- package/dist/prompt/pipeline-report.d.ts +1 -0
- package/dist/prompt/report.d.ts +10 -0
- package/dist/prompt/system-prompt.d.ts +22 -0
- package/dist/prompt/testomat.io.d.ts +19 -0
- package/dist/prompt/thread.d.ts +73 -0
- package/dist/src/args.d.ts +39 -0
- package/dist/src/attribution-extension.d.ts +3 -0
- package/dist/src/checkpoint.d.ts +30 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +27 -32
- package/dist/src/cli.js.map +1 -1
- package/dist/src/doctor.d.ts +11 -0
- package/dist/src/env.d.ts +30 -0
- package/dist/src/exec.d.ts +11 -0
- package/dist/src/git.d.ts +41 -0
- package/dist/src/langfuse-extension.d.ts +7 -0
- package/dist/src/langfuse.d.ts +67 -0
- package/dist/src/mcp.d.ts +19 -0
- package/dist/src/model.d.ts +20 -0
- package/dist/src/models.d.ts +1 -0
- package/dist/src/output.d.ts +84 -0
- package/dist/src/pipeline/command-stage.d.ts +12 -0
- package/dist/src/pipeline/crash-guard.d.ts +12 -0
- package/dist/src/pipeline/crash-guard.js +21 -0
- package/dist/src/pipeline/crash-guard.js.map +1 -0
- package/dist/src/pipeline/diagram.d.ts +24 -0
- package/dist/src/pipeline/gate.d.ts +21 -0
- package/dist/src/pipeline/launcher.d.ts +33 -0
- package/dist/src/pipeline/launcher.js +16 -3
- package/dist/src/pipeline/launcher.js.map +1 -1
- package/dist/src/pipeline/log.d.ts +29 -0
- package/dist/src/pipeline/log.js +9 -0
- package/dist/src/pipeline/log.js.map +1 -1
- package/dist/src/pipeline/overlay.d.ts +29 -0
- package/dist/src/pipeline/pipeline-file.d.ts +44 -0
- package/dist/src/pipeline/pipeline.d.ts +78 -0
- package/dist/src/pipeline/pipeline.js +22 -0
- package/dist/src/pipeline/pipeline.js.map +1 -1
- package/dist/src/pipeline/report.d.ts +26 -0
- package/dist/src/pipeline/report.js +13 -0
- package/dist/src/pipeline/report.js.map +1 -1
- package/dist/src/pipeline/spec.d.ts +63 -0
- package/dist/src/pipeline/stage-env.d.ts +13 -0
- package/dist/src/pipeline/stage-env.js +31 -0
- package/dist/src/pipeline/stage-env.js.map +1 -0
- package/dist/src/pipeline/stage.d.ts +71 -0
- package/dist/src/pipeline/stage.js.map +1 -1
- package/dist/src/pipeline/state.d.ts +63 -0
- package/dist/src/pipeline/summary-stage.d.ts +24 -0
- package/dist/src/pipeline/task-stage.d.ts +24 -0
- package/dist/src/pipeline/task-stage.js +86 -2
- package/dist/src/pipeline/task-stage.js.map +1 -1
- package/dist/src/pipeline/variables.d.ts +20 -0
- package/dist/src/result.d.ts +6 -0
- package/dist/src/run.d.ts +69 -0
- package/dist/src/run.js +116 -60
- package/dist/src/run.js.map +1 -1
- package/dist/src/session.d.ts +43 -0
- package/dist/src/sessions.d.ts +23 -0
- package/dist/src/skills.d.ts +29 -0
- package/package.json +11 -2
- package/pipelines/api-testing.yml +1 -1
- package/scripts/vendor-skills.js +62 -0
- package/skills/codeceptjs/ci-fix-tests/SKILL.md +0 -119
- package/skills/codeceptjs/codeceptjs-auth/SKILL.md +0 -141
- package/skills/codeceptjs/codeceptjs-exploration/SKILL.md +0 -100
- package/skills/codeceptjs/codeceptjs-fundamentals/SKILL.md +0 -196
- package/skills/codeceptjs/codeceptjs-run-analysis/SKILL.md +0 -83
- package/skills/codeceptjs/debugging-codeceptjs-tests/SKILL.md +0 -126
- package/skills/codeceptjs/lint-codeceptjs-tests/SKILL.md +0 -104
- package/skills/codeceptjs/migrate-codeceptjs-4/SKILL.md +0 -109
- package/skills/codeceptjs/migrate-cypress-to-codeceptjs/SKILL.md +0 -295
- package/skills/codeceptjs/migrate-protractor-to-codeceptjs/SKILL.md +0 -339
- package/skills/codeceptjs/migrate-selenium-java-to-codeceptjs/SKILL.md +0 -459
- package/skills/codeceptjs/migrate-testcafe-to-codeceptjs/SKILL.md +0 -338
- package/skills/codeceptjs/refactoring-codeceptjs-tests/SKILL.md +0 -78
- package/skills/codeceptjs/writing-codeceptjs-tests/SKILL.md +0 -102
- package/skills/playwright/playwright-best-practices/SKILL.md +0 -303
- package/skills/playwright/playwright-best-practices/advanced/authentication-flows.md +0 -360
- package/skills/playwright/playwright-best-practices/advanced/authentication.md +0 -871
- package/skills/playwright/playwright-best-practices/advanced/clock-mocking.md +0 -364
- package/skills/playwright/playwright-best-practices/advanced/mobile-testing.md +0 -409
- package/skills/playwright/playwright-best-practices/advanced/multi-context.md +0 -288
- package/skills/playwright/playwright-best-practices/advanced/multi-user.md +0 -393
- package/skills/playwright/playwright-best-practices/advanced/network-advanced.md +0 -452
- package/skills/playwright/playwright-best-practices/advanced/third-party.md +0 -464
- package/skills/playwright/playwright-best-practices/architecture/pom-vs-fixtures.md +0 -363
- package/skills/playwright/playwright-best-practices/architecture/test-architecture.md +0 -369
- package/skills/playwright/playwright-best-practices/architecture/when-to-mock.md +0 -383
- package/skills/playwright/playwright-best-practices/browser-apis/browser-apis.md +0 -391
- package/skills/playwright/playwright-best-practices/browser-apis/iframes.md +0 -403
- package/skills/playwright/playwright-best-practices/browser-apis/service-workers.md +0 -504
- package/skills/playwright/playwright-best-practices/browser-apis/websockets.md +0 -403
- package/skills/playwright/playwright-best-practices/core/annotations.md +0 -424
- package/skills/playwright/playwright-best-practices/core/assertions-waiting.md +0 -361
- package/skills/playwright/playwright-best-practices/core/configuration.md +0 -452
- package/skills/playwright/playwright-best-practices/core/fixtures-hooks.md +0 -417
- package/skills/playwright/playwright-best-practices/core/global-setup.md +0 -434
- package/skills/playwright/playwright-best-practices/core/locators.md +0 -242
- package/skills/playwright/playwright-best-practices/core/page-object-model.md +0 -315
- package/skills/playwright/playwright-best-practices/core/projects-dependencies.md +0 -453
- package/skills/playwright/playwright-best-practices/core/test-data.md +0 -492
- package/skills/playwright/playwright-best-practices/core/test-suite-structure.md +0 -361
- package/skills/playwright/playwright-best-practices/core/test-tags.md +0 -298
- package/skills/playwright/playwright-best-practices/debugging/console-errors.md +0 -420
- package/skills/playwright/playwright-best-practices/debugging/debugging.md +0 -504
- package/skills/playwright/playwright-best-practices/debugging/error-testing.md +0 -360
- package/skills/playwright/playwright-best-practices/debugging/flaky-tests.md +0 -496
- package/skills/playwright/playwright-best-practices/frameworks/angular.md +0 -530
- package/skills/playwright/playwright-best-practices/frameworks/nextjs.md +0 -469
- package/skills/playwright/playwright-best-practices/frameworks/react.md +0 -531
- package/skills/playwright/playwright-best-practices/frameworks/vue.md +0 -574
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/ci-cd.md +0 -468
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/docker.md +0 -283
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/github-actions.md +0 -546
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/gitlab.md +0 -397
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/other-providers.md +0 -521
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/parallel-sharding.md +0 -371
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/performance.md +0 -453
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/reporting.md +0 -424
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/test-coverage.md +0 -497
- package/skills/playwright/playwright-best-practices/testing-patterns/accessibility.md +0 -359
- package/skills/playwright/playwright-best-practices/testing-patterns/api-testing.md +0 -719
- package/skills/playwright/playwright-best-practices/testing-patterns/browser-extensions.md +0 -506
- package/skills/playwright/playwright-best-practices/testing-patterns/canvas-webgl.md +0 -493
- package/skills/playwright/playwright-best-practices/testing-patterns/component-testing.md +0 -500
- package/skills/playwright/playwright-best-practices/testing-patterns/drag-drop.md +0 -576
- package/skills/playwright/playwright-best-practices/testing-patterns/electron.md +0 -509
- package/skills/playwright/playwright-best-practices/testing-patterns/file-operations.md +0 -377
- package/skills/playwright/playwright-best-practices/testing-patterns/file-upload-download.md +0 -562
- package/skills/playwright/playwright-best-practices/testing-patterns/forms-validation.md +0 -561
- package/skills/playwright/playwright-best-practices/testing-patterns/graphql-testing.md +0 -331
- package/skills/playwright/playwright-best-practices/testing-patterns/i18n.md +0 -508
- package/skills/playwright/playwright-best-practices/testing-patterns/performance-testing.md +0 -476
- package/skills/playwright/playwright-best-practices/testing-patterns/security-testing.md +0 -430
- package/skills/playwright/playwright-best-practices/testing-patterns/visual-regression.md +0 -634
- package/skills/playwright/playwright-cli/SKILL.md +0 -489
- package/skills/playwright/playwright-cli/references/element-attributes.md +0 -23
- package/skills/playwright/playwright-cli/references/playwright-tests.md +0 -39
- package/skills/playwright/playwright-cli/references/pr-attachments.md +0 -60
- package/skills/playwright/playwright-cli/references/request-mocking.md +0 -87
- package/skills/playwright/playwright-cli/references/running-code.md +0 -245
- package/skills/playwright/playwright-cli/references/session-management.md +0 -227
- package/skills/playwright/playwright-cli/references/storage-state.md +0 -275
- package/skills/playwright/playwright-cli/references/test-generation.md +0 -433
- package/skills/playwright/playwright-cli/references/tracing.md +0 -139
- package/skills/playwright/playwright-cli/references/video-recording.md +0 -216
- package/skills/skills.lock.json +0 -89
- package/skills/skills.yaml +0 -35
- /package/skills/{testomatio/explorbot → explorbot}/explorbot-fundamentals/SKILL.md +0 -0
- /package/skills/{testomatio/explorbot → explorbot}/explorbot-fundamentals/references/no-install.md +0 -0
- /package/skills/{testomatio/explorbot → explorbot}/explorbot-plan/SKILL.md +0 -0
- /package/skills/{testomatio/explorbot → explorbot}/explorbot-setup/SKILL.md +0 -0
- /package/skills/{testomatio/explorbot → explorbot}/prima/SKILL.md +0 -0
- /package/skills/{testomatio/qa-process → qa-process}/qa-lead-strategy-advisor/SKILL.md +0 -0
- /package/skills/{testomatio/qa-process → qa-process}/qa-lead-strategy-advisor/references/output-format.md +0 -0
- /package/skills/{testomatio/qa-process → qa-process}/qa-review-pr/SKILL.md +0 -0
- /package/skills/{testomatio/qa-process → qa-process}/testing-workflow/SKILL.md +0 -0
- /package/skills/{testomatio/requirements → requirements}/catalog-features/SKILL.md +0 -0
- /package/skills/{testomatio/requirements → requirements}/catalog-features/references/layout.md +0 -0
- /package/skills/{testomatio/requirements → requirements}/detect-product-mismatches/SKILL.md +0 -0
- /package/skills/{testomatio/requirements → requirements}/detect-product-mismatches/references/features.md +0 -0
- /package/skills/{testomatio/requirements → requirements}/detect-product-mismatches/references/layout.md +0 -0
- /package/skills/{testomatio/requirements → requirements}/pull-request-diff-analyzer/SKILL.md +0 -0
- /package/skills/{testomatio/requirements → requirements}/qa-explain-behavior/SKILL.md +0 -0
- /package/skills/{testomatio/requirements → requirements}/qa-explain-behavior/references/answer-shapes.md +0 -0
- /package/skills/{testomatio/requirements → requirements}/qa-explain-behavior/references/examples.md +0 -0
- /package/skills/{testomatio/requirements → requirements}/qa-pr-requirements-analyzer/SKILL.md +0 -0
- /package/skills/{testomatio/requirements → requirements}/qa-pr-requirements-analyzer/references/summary-example.md +0 -0
- /package/skills/{testomatio/requirements → requirements}/qa-requirement-reviewer/SKILL.md +0 -0
- /package/skills/{testomatio/requirements → requirements}/qa-requirement-reviewer/references/requirements_reviewer_examples.md +0 -0
- /package/skills/{testomatio/requirements → requirements}/qa-thinking/SKILL.md +0 -0
- /package/skills/{testomatio/requirements → requirements}/wiki-from-code/SKILL.md +0 -0
- /package/skills/{testomatio/requirements → requirements}/wiki-from-code/references/behaviors.md +0 -0
- /package/skills/{testomatio/requirements → requirements}/wiki-from-code/references/layout.md +0 -0
- /package/skills/{testomatio/requirements → requirements}/write-user-story/SKILL.md +0 -0
- /package/skills/{testomatio/test-automation → test-automation}/automate-manual-test-cases/CLAUDE.md +0 -0
- /package/skills/{testomatio/test-automation → test-automation}/automate-manual-test-cases/SKILL.md +0 -0
- /package/skills/{testomatio/test-automation → test-automation}/automate-manual-test-cases/references/CODECEPTJS_BEST_PRACTICES.md +0 -0
- /package/skills/{testomatio/test-automation → test-automation}/automate-manual-test-cases/references/FINAL_SUMMARY_TEMPLATE.md +0 -0
- /package/skills/{testomatio/test-automation → test-automation}/automate-manual-test-cases/references/PLAYWRIGHT_BEST_PRACTICES.md +0 -0
- /package/skills/{testomatio/test-automation → test-automation}/automate-manual-test-cases/references/POM_BEST_PRACTICES.md +0 -0
- /package/skills/{testomatio/test-automation → test-automation}/automate-manual-test-cases/references/TEST_DATA_MANAGEMENT.md +0 -0
- /package/skills/{testomatio/test-automation → test-automation}/debug-fix-failed-flaky-autotests/SKILL.md +0 -0
- /package/skills/{testomatio/test-automation → test-automation}/debug-fix-failed-flaky-autotests/references/DEBUGGING_QUICK_REFERENCE.md +0 -0
- /package/skills/{testomatio/test-automation → test-automation}/epic-requirements-specification/SKILL.md +0 -0
- /package/skills/{testomatio/test-automation → test-automation}/qa-automation-test-consolidation/SKILL.md +0 -0
- /package/skills/{testomatio/test-automation → test-automation}/qa-data-seeder/SKILL.md +0 -0
- /package/skills/{testomatio/test-automation → test-automation}/run-tests-with-testomatio-reporter/SKILL.md +0 -0
- /package/skills/{testomatio/test-automation → test-automation}/setup-change-aware-pr-testing/SKILL.md +0 -0
- /package/skills/{testomatio/test-automation → test-automation}/setup-ci-automation/SKILL.md +0 -0
- /package/skills/{testomatio/test-automation → test-automation}/testomat-allure-adapter/SKILL.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/detect-duplicate-test-cases/SKILL.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/detect-duplicate-test-cases/references/DUPLICATE_INSTRUCTIONS.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/detect-useless-tests/SKILL.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/improve-test-cases/SKILL.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/improve-test-cases/references/TESTOMAT_MARKDOWN_EXAMPLE.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/migrate-to-testomatio/SKILL.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/migrate-to-testomatio/references/CSV_MIGRATION.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/migrate-to-testomatio/references/CUSTOM_MIGRATION.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/migrate-to-testomatio/references/TESTMO_MIGRATION.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/migrate-to-testomatio/references/TESTRAIL_MIGRATION.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/migrate-to-testomatio/references/XRAY_MIGRATION.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/qa-e2e-tests-reporting/SKILL.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/qa-e2e-tests-reporting/references/TESTOMATIO_ARTIFACTS.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/qa-e2e-tests-reporting/references/TESTOMATIO_HTML_REPORT.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/qa-e2e-tests-reporting/references/TESTOMATIO_REPORTERS_CONFIG.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/qa-split-testing-levels-pyramid/SKILL.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/qa-sprint-report-by-testomatio/SKILL.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/qa-sprint-report-by-testomatio/references/qa-sprint-report.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/qa-test-code-coverage/SKILL.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/qa-test-code-coverage/references/COVERAGE_FILE_FORMAT.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/qa-test-code-coverage/references/E2E_FRAMEWORKS.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/qa-test-code-coverage/scripts/check-coverage.mjs +0 -0
- /package/skills/{testomatio/test-management → test-management}/qa-write-test-cases/SKILL.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/qa-write-test-cases/references/test-case-format.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/qa-write-test-cases/references/testomat-tms-guide.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/qa-write-test-cases/references/writing-rule.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/scan-automation-project/SKILL.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/sync-test-cases-with-tms/SKILL.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/sync-test-cases-with-tms/references/TESTOMATIO_CLI.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/testomatio-mcp/SKILL.md +0 -0
- /package/skills/{testomatio/test-management → test-management}/testomatio-mcp/references/MCP_SETUP.md +0 -0
|
@@ -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
|
-
```
|