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.
Files changed (225) hide show
  1. package/README.md +7 -19
  2. package/dist/prompt/clis.d.ts +7 -0
  3. package/dist/prompt/pipeline-report.d.ts +1 -0
  4. package/dist/prompt/report.d.ts +10 -0
  5. package/dist/prompt/system-prompt.d.ts +22 -0
  6. package/dist/prompt/testomat.io.d.ts +19 -0
  7. package/dist/prompt/thread.d.ts +73 -0
  8. package/dist/src/args.d.ts +39 -0
  9. package/dist/src/attribution-extension.d.ts +3 -0
  10. package/dist/src/checkpoint.d.ts +30 -0
  11. package/dist/src/cli.d.ts +2 -0
  12. package/dist/src/cli.js +27 -32
  13. package/dist/src/cli.js.map +1 -1
  14. package/dist/src/doctor.d.ts +11 -0
  15. package/dist/src/env.d.ts +30 -0
  16. package/dist/src/exec.d.ts +11 -0
  17. package/dist/src/git.d.ts +41 -0
  18. package/dist/src/langfuse-extension.d.ts +7 -0
  19. package/dist/src/langfuse.d.ts +67 -0
  20. package/dist/src/mcp.d.ts +19 -0
  21. package/dist/src/model.d.ts +20 -0
  22. package/dist/src/models.d.ts +1 -0
  23. package/dist/src/output.d.ts +84 -0
  24. package/dist/src/pipeline/command-stage.d.ts +12 -0
  25. package/dist/src/pipeline/crash-guard.d.ts +12 -0
  26. package/dist/src/pipeline/crash-guard.js +21 -0
  27. package/dist/src/pipeline/crash-guard.js.map +1 -0
  28. package/dist/src/pipeline/diagram.d.ts +24 -0
  29. package/dist/src/pipeline/gate.d.ts +21 -0
  30. package/dist/src/pipeline/launcher.d.ts +33 -0
  31. package/dist/src/pipeline/launcher.js +16 -3
  32. package/dist/src/pipeline/launcher.js.map +1 -1
  33. package/dist/src/pipeline/log.d.ts +29 -0
  34. package/dist/src/pipeline/log.js +9 -0
  35. package/dist/src/pipeline/log.js.map +1 -1
  36. package/dist/src/pipeline/overlay.d.ts +29 -0
  37. package/dist/src/pipeline/pipeline-file.d.ts +44 -0
  38. package/dist/src/pipeline/pipeline.d.ts +78 -0
  39. package/dist/src/pipeline/pipeline.js +22 -0
  40. package/dist/src/pipeline/pipeline.js.map +1 -1
  41. package/dist/src/pipeline/report.d.ts +26 -0
  42. package/dist/src/pipeline/report.js +13 -0
  43. package/dist/src/pipeline/report.js.map +1 -1
  44. package/dist/src/pipeline/spec.d.ts +63 -0
  45. package/dist/src/pipeline/stage-env.d.ts +13 -0
  46. package/dist/src/pipeline/stage-env.js +31 -0
  47. package/dist/src/pipeline/stage-env.js.map +1 -0
  48. package/dist/src/pipeline/stage.d.ts +71 -0
  49. package/dist/src/pipeline/stage.js.map +1 -1
  50. package/dist/src/pipeline/state.d.ts +63 -0
  51. package/dist/src/pipeline/summary-stage.d.ts +24 -0
  52. package/dist/src/pipeline/task-stage.d.ts +24 -0
  53. package/dist/src/pipeline/task-stage.js +86 -2
  54. package/dist/src/pipeline/task-stage.js.map +1 -1
  55. package/dist/src/pipeline/variables.d.ts +20 -0
  56. package/dist/src/result.d.ts +6 -0
  57. package/dist/src/run.d.ts +69 -0
  58. package/dist/src/run.js +116 -60
  59. package/dist/src/run.js.map +1 -1
  60. package/dist/src/session.d.ts +43 -0
  61. package/dist/src/sessions.d.ts +23 -0
  62. package/dist/src/skills.d.ts +29 -0
  63. package/package.json +11 -2
  64. package/pipelines/api-testing.yml +1 -1
  65. package/scripts/vendor-skills.js +62 -0
  66. package/skills/codeceptjs/ci-fix-tests/SKILL.md +0 -119
  67. package/skills/codeceptjs/codeceptjs-auth/SKILL.md +0 -141
  68. package/skills/codeceptjs/codeceptjs-exploration/SKILL.md +0 -100
  69. package/skills/codeceptjs/codeceptjs-fundamentals/SKILL.md +0 -196
  70. package/skills/codeceptjs/codeceptjs-run-analysis/SKILL.md +0 -83
  71. package/skills/codeceptjs/debugging-codeceptjs-tests/SKILL.md +0 -126
  72. package/skills/codeceptjs/lint-codeceptjs-tests/SKILL.md +0 -104
  73. package/skills/codeceptjs/migrate-codeceptjs-4/SKILL.md +0 -109
  74. package/skills/codeceptjs/migrate-cypress-to-codeceptjs/SKILL.md +0 -295
  75. package/skills/codeceptjs/migrate-protractor-to-codeceptjs/SKILL.md +0 -339
  76. package/skills/codeceptjs/migrate-selenium-java-to-codeceptjs/SKILL.md +0 -459
  77. package/skills/codeceptjs/migrate-testcafe-to-codeceptjs/SKILL.md +0 -338
  78. package/skills/codeceptjs/refactoring-codeceptjs-tests/SKILL.md +0 -78
  79. package/skills/codeceptjs/writing-codeceptjs-tests/SKILL.md +0 -102
  80. package/skills/playwright/playwright-best-practices/SKILL.md +0 -303
  81. package/skills/playwright/playwright-best-practices/advanced/authentication-flows.md +0 -360
  82. package/skills/playwright/playwright-best-practices/advanced/authentication.md +0 -871
  83. package/skills/playwright/playwright-best-practices/advanced/clock-mocking.md +0 -364
  84. package/skills/playwright/playwright-best-practices/advanced/mobile-testing.md +0 -409
  85. package/skills/playwright/playwright-best-practices/advanced/multi-context.md +0 -288
  86. package/skills/playwright/playwright-best-practices/advanced/multi-user.md +0 -393
  87. package/skills/playwright/playwright-best-practices/advanced/network-advanced.md +0 -452
  88. package/skills/playwright/playwright-best-practices/advanced/third-party.md +0 -464
  89. package/skills/playwright/playwright-best-practices/architecture/pom-vs-fixtures.md +0 -363
  90. package/skills/playwright/playwright-best-practices/architecture/test-architecture.md +0 -369
  91. package/skills/playwright/playwright-best-practices/architecture/when-to-mock.md +0 -383
  92. package/skills/playwright/playwright-best-practices/browser-apis/browser-apis.md +0 -391
  93. package/skills/playwright/playwright-best-practices/browser-apis/iframes.md +0 -403
  94. package/skills/playwright/playwright-best-practices/browser-apis/service-workers.md +0 -504
  95. package/skills/playwright/playwright-best-practices/browser-apis/websockets.md +0 -403
  96. package/skills/playwright/playwright-best-practices/core/annotations.md +0 -424
  97. package/skills/playwright/playwright-best-practices/core/assertions-waiting.md +0 -361
  98. package/skills/playwright/playwright-best-practices/core/configuration.md +0 -452
  99. package/skills/playwright/playwright-best-practices/core/fixtures-hooks.md +0 -417
  100. package/skills/playwright/playwright-best-practices/core/global-setup.md +0 -434
  101. package/skills/playwright/playwright-best-practices/core/locators.md +0 -242
  102. package/skills/playwright/playwright-best-practices/core/page-object-model.md +0 -315
  103. package/skills/playwright/playwright-best-practices/core/projects-dependencies.md +0 -453
  104. package/skills/playwright/playwright-best-practices/core/test-data.md +0 -492
  105. package/skills/playwright/playwright-best-practices/core/test-suite-structure.md +0 -361
  106. package/skills/playwright/playwright-best-practices/core/test-tags.md +0 -298
  107. package/skills/playwright/playwright-best-practices/debugging/console-errors.md +0 -420
  108. package/skills/playwright/playwright-best-practices/debugging/debugging.md +0 -504
  109. package/skills/playwright/playwright-best-practices/debugging/error-testing.md +0 -360
  110. package/skills/playwright/playwright-best-practices/debugging/flaky-tests.md +0 -496
  111. package/skills/playwright/playwright-best-practices/frameworks/angular.md +0 -530
  112. package/skills/playwright/playwright-best-practices/frameworks/nextjs.md +0 -469
  113. package/skills/playwright/playwright-best-practices/frameworks/react.md +0 -531
  114. package/skills/playwright/playwright-best-practices/frameworks/vue.md +0 -574
  115. package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/ci-cd.md +0 -468
  116. package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/docker.md +0 -283
  117. package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/github-actions.md +0 -546
  118. package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/gitlab.md +0 -397
  119. package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/other-providers.md +0 -521
  120. package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/parallel-sharding.md +0 -371
  121. package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/performance.md +0 -453
  122. package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/reporting.md +0 -424
  123. package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/test-coverage.md +0 -497
  124. package/skills/playwright/playwright-best-practices/testing-patterns/accessibility.md +0 -359
  125. package/skills/playwright/playwright-best-practices/testing-patterns/api-testing.md +0 -719
  126. package/skills/playwright/playwright-best-practices/testing-patterns/browser-extensions.md +0 -506
  127. package/skills/playwright/playwright-best-practices/testing-patterns/canvas-webgl.md +0 -493
  128. package/skills/playwright/playwright-best-practices/testing-patterns/component-testing.md +0 -500
  129. package/skills/playwright/playwright-best-practices/testing-patterns/drag-drop.md +0 -576
  130. package/skills/playwright/playwright-best-practices/testing-patterns/electron.md +0 -509
  131. package/skills/playwright/playwright-best-practices/testing-patterns/file-operations.md +0 -377
  132. package/skills/playwright/playwright-best-practices/testing-patterns/file-upload-download.md +0 -562
  133. package/skills/playwright/playwright-best-practices/testing-patterns/forms-validation.md +0 -561
  134. package/skills/playwright/playwright-best-practices/testing-patterns/graphql-testing.md +0 -331
  135. package/skills/playwright/playwright-best-practices/testing-patterns/i18n.md +0 -508
  136. package/skills/playwright/playwright-best-practices/testing-patterns/performance-testing.md +0 -476
  137. package/skills/playwright/playwright-best-practices/testing-patterns/security-testing.md +0 -430
  138. package/skills/playwright/playwright-best-practices/testing-patterns/visual-regression.md +0 -634
  139. package/skills/playwright/playwright-cli/SKILL.md +0 -489
  140. package/skills/playwright/playwright-cli/references/element-attributes.md +0 -23
  141. package/skills/playwright/playwright-cli/references/playwright-tests.md +0 -39
  142. package/skills/playwright/playwright-cli/references/pr-attachments.md +0 -60
  143. package/skills/playwright/playwright-cli/references/request-mocking.md +0 -87
  144. package/skills/playwright/playwright-cli/references/running-code.md +0 -245
  145. package/skills/playwright/playwright-cli/references/session-management.md +0 -227
  146. package/skills/playwright/playwright-cli/references/storage-state.md +0 -275
  147. package/skills/playwright/playwright-cli/references/test-generation.md +0 -433
  148. package/skills/playwright/playwright-cli/references/tracing.md +0 -139
  149. package/skills/playwright/playwright-cli/references/video-recording.md +0 -216
  150. package/skills/skills.lock.json +0 -89
  151. package/skills/skills.yaml +0 -35
  152. /package/skills/{testomatio/explorbot → explorbot}/explorbot-fundamentals/SKILL.md +0 -0
  153. /package/skills/{testomatio/explorbot → explorbot}/explorbot-fundamentals/references/no-install.md +0 -0
  154. /package/skills/{testomatio/explorbot → explorbot}/explorbot-plan/SKILL.md +0 -0
  155. /package/skills/{testomatio/explorbot → explorbot}/explorbot-setup/SKILL.md +0 -0
  156. /package/skills/{testomatio/explorbot → explorbot}/prima/SKILL.md +0 -0
  157. /package/skills/{testomatio/qa-process → qa-process}/qa-lead-strategy-advisor/SKILL.md +0 -0
  158. /package/skills/{testomatio/qa-process → qa-process}/qa-lead-strategy-advisor/references/output-format.md +0 -0
  159. /package/skills/{testomatio/qa-process → qa-process}/qa-review-pr/SKILL.md +0 -0
  160. /package/skills/{testomatio/qa-process → qa-process}/testing-workflow/SKILL.md +0 -0
  161. /package/skills/{testomatio/requirements → requirements}/catalog-features/SKILL.md +0 -0
  162. /package/skills/{testomatio/requirements → requirements}/catalog-features/references/layout.md +0 -0
  163. /package/skills/{testomatio/requirements → requirements}/detect-product-mismatches/SKILL.md +0 -0
  164. /package/skills/{testomatio/requirements → requirements}/detect-product-mismatches/references/features.md +0 -0
  165. /package/skills/{testomatio/requirements → requirements}/detect-product-mismatches/references/layout.md +0 -0
  166. /package/skills/{testomatio/requirements → requirements}/pull-request-diff-analyzer/SKILL.md +0 -0
  167. /package/skills/{testomatio/requirements → requirements}/qa-explain-behavior/SKILL.md +0 -0
  168. /package/skills/{testomatio/requirements → requirements}/qa-explain-behavior/references/answer-shapes.md +0 -0
  169. /package/skills/{testomatio/requirements → requirements}/qa-explain-behavior/references/examples.md +0 -0
  170. /package/skills/{testomatio/requirements → requirements}/qa-pr-requirements-analyzer/SKILL.md +0 -0
  171. /package/skills/{testomatio/requirements → requirements}/qa-pr-requirements-analyzer/references/summary-example.md +0 -0
  172. /package/skills/{testomatio/requirements → requirements}/qa-requirement-reviewer/SKILL.md +0 -0
  173. /package/skills/{testomatio/requirements → requirements}/qa-requirement-reviewer/references/requirements_reviewer_examples.md +0 -0
  174. /package/skills/{testomatio/requirements → requirements}/qa-thinking/SKILL.md +0 -0
  175. /package/skills/{testomatio/requirements → requirements}/wiki-from-code/SKILL.md +0 -0
  176. /package/skills/{testomatio/requirements → requirements}/wiki-from-code/references/behaviors.md +0 -0
  177. /package/skills/{testomatio/requirements → requirements}/wiki-from-code/references/layout.md +0 -0
  178. /package/skills/{testomatio/requirements → requirements}/write-user-story/SKILL.md +0 -0
  179. /package/skills/{testomatio/test-automation → test-automation}/automate-manual-test-cases/CLAUDE.md +0 -0
  180. /package/skills/{testomatio/test-automation → test-automation}/automate-manual-test-cases/SKILL.md +0 -0
  181. /package/skills/{testomatio/test-automation → test-automation}/automate-manual-test-cases/references/CODECEPTJS_BEST_PRACTICES.md +0 -0
  182. /package/skills/{testomatio/test-automation → test-automation}/automate-manual-test-cases/references/FINAL_SUMMARY_TEMPLATE.md +0 -0
  183. /package/skills/{testomatio/test-automation → test-automation}/automate-manual-test-cases/references/PLAYWRIGHT_BEST_PRACTICES.md +0 -0
  184. /package/skills/{testomatio/test-automation → test-automation}/automate-manual-test-cases/references/POM_BEST_PRACTICES.md +0 -0
  185. /package/skills/{testomatio/test-automation → test-automation}/automate-manual-test-cases/references/TEST_DATA_MANAGEMENT.md +0 -0
  186. /package/skills/{testomatio/test-automation → test-automation}/debug-fix-failed-flaky-autotests/SKILL.md +0 -0
  187. /package/skills/{testomatio/test-automation → test-automation}/debug-fix-failed-flaky-autotests/references/DEBUGGING_QUICK_REFERENCE.md +0 -0
  188. /package/skills/{testomatio/test-automation → test-automation}/epic-requirements-specification/SKILL.md +0 -0
  189. /package/skills/{testomatio/test-automation → test-automation}/qa-automation-test-consolidation/SKILL.md +0 -0
  190. /package/skills/{testomatio/test-automation → test-automation}/qa-data-seeder/SKILL.md +0 -0
  191. /package/skills/{testomatio/test-automation → test-automation}/run-tests-with-testomatio-reporter/SKILL.md +0 -0
  192. /package/skills/{testomatio/test-automation → test-automation}/setup-change-aware-pr-testing/SKILL.md +0 -0
  193. /package/skills/{testomatio/test-automation → test-automation}/setup-ci-automation/SKILL.md +0 -0
  194. /package/skills/{testomatio/test-automation → test-automation}/testomat-allure-adapter/SKILL.md +0 -0
  195. /package/skills/{testomatio/test-management → test-management}/detect-duplicate-test-cases/SKILL.md +0 -0
  196. /package/skills/{testomatio/test-management → test-management}/detect-duplicate-test-cases/references/DUPLICATE_INSTRUCTIONS.md +0 -0
  197. /package/skills/{testomatio/test-management → test-management}/detect-useless-tests/SKILL.md +0 -0
  198. /package/skills/{testomatio/test-management → test-management}/improve-test-cases/SKILL.md +0 -0
  199. /package/skills/{testomatio/test-management → test-management}/improve-test-cases/references/TESTOMAT_MARKDOWN_EXAMPLE.md +0 -0
  200. /package/skills/{testomatio/test-management → test-management}/migrate-to-testomatio/SKILL.md +0 -0
  201. /package/skills/{testomatio/test-management → test-management}/migrate-to-testomatio/references/CSV_MIGRATION.md +0 -0
  202. /package/skills/{testomatio/test-management → test-management}/migrate-to-testomatio/references/CUSTOM_MIGRATION.md +0 -0
  203. /package/skills/{testomatio/test-management → test-management}/migrate-to-testomatio/references/TESTMO_MIGRATION.md +0 -0
  204. /package/skills/{testomatio/test-management → test-management}/migrate-to-testomatio/references/TESTRAIL_MIGRATION.md +0 -0
  205. /package/skills/{testomatio/test-management → test-management}/migrate-to-testomatio/references/XRAY_MIGRATION.md +0 -0
  206. /package/skills/{testomatio/test-management → test-management}/qa-e2e-tests-reporting/SKILL.md +0 -0
  207. /package/skills/{testomatio/test-management → test-management}/qa-e2e-tests-reporting/references/TESTOMATIO_ARTIFACTS.md +0 -0
  208. /package/skills/{testomatio/test-management → test-management}/qa-e2e-tests-reporting/references/TESTOMATIO_HTML_REPORT.md +0 -0
  209. /package/skills/{testomatio/test-management → test-management}/qa-e2e-tests-reporting/references/TESTOMATIO_REPORTERS_CONFIG.md +0 -0
  210. /package/skills/{testomatio/test-management → test-management}/qa-split-testing-levels-pyramid/SKILL.md +0 -0
  211. /package/skills/{testomatio/test-management → test-management}/qa-sprint-report-by-testomatio/SKILL.md +0 -0
  212. /package/skills/{testomatio/test-management → test-management}/qa-sprint-report-by-testomatio/references/qa-sprint-report.md +0 -0
  213. /package/skills/{testomatio/test-management → test-management}/qa-test-code-coverage/SKILL.md +0 -0
  214. /package/skills/{testomatio/test-management → test-management}/qa-test-code-coverage/references/COVERAGE_FILE_FORMAT.md +0 -0
  215. /package/skills/{testomatio/test-management → test-management}/qa-test-code-coverage/references/E2E_FRAMEWORKS.md +0 -0
  216. /package/skills/{testomatio/test-management → test-management}/qa-test-code-coverage/scripts/check-coverage.mjs +0 -0
  217. /package/skills/{testomatio/test-management → test-management}/qa-write-test-cases/SKILL.md +0 -0
  218. /package/skills/{testomatio/test-management → test-management}/qa-write-test-cases/references/test-case-format.md +0 -0
  219. /package/skills/{testomatio/test-management → test-management}/qa-write-test-cases/references/testomat-tms-guide.md +0 -0
  220. /package/skills/{testomatio/test-management → test-management}/qa-write-test-cases/references/writing-rule.md +0 -0
  221. /package/skills/{testomatio/test-management → test-management}/scan-automation-project/SKILL.md +0 -0
  222. /package/skills/{testomatio/test-management → test-management}/sync-test-cases-with-tms/SKILL.md +0 -0
  223. /package/skills/{testomatio/test-management → test-management}/sync-test-cases-with-tms/references/TESTOMATIO_CLI.md +0 -0
  224. /package/skills/{testomatio/test-management → test-management}/testomatio-mcp/SKILL.md +0 -0
  225. /package/skills/{testomatio/test-management → test-management}/testomatio-mcp/references/MCP_SETUP.md +0 -0
@@ -1,531 +0,0 @@
1
- # React Application Testing
2
-
3
- ## Table of Contents
4
-
5
- 1. [Patterns](#patterns)
6
- 2. [Setup](#setup)
7
- 3. [Framework Tips](#framework-tips)
8
- 4. [Anti-Patterns](#anti-patterns)
9
- 5. [Related](#related)
10
-
11
- > **When to use**: Testing React apps built with Vite, Create React App, or custom bundlers. Covers E2E testing, component testing, React Router navigation, form libraries, portals, error boundaries, and context/state verification.
12
- > **Prerequisites**: [configuration.md](../core/configuration.md), [locators.md](../core/locators.md)
13
-
14
- ## Patterns
15
-
16
- ### Testing Context and Global State
17
-
18
- **Use when**: Verifying React context (theme, auth, locale) and state management (Redux, Zustand) produce correct UI changes.
19
- **Avoid when**: You want to assert on raw state objects—test the UI, not internal state.
20
-
21
- ```typescript
22
- import { test, expect } from '@playwright/test';
23
-
24
- test.describe('theme switching', () => {
25
- test('toggle applies dark mode across pages', async ({ page }) => {
26
- await page.goto('/preferences');
27
-
28
- const root = page.locator('html');
29
- await expect(root).not.toHaveClass(/dark-mode/);
30
-
31
- await page.getByRole('switch', { name: 'Enable dark theme' }).click();
32
- await expect(root).toHaveClass(/dark-mode/);
33
-
34
- await page.getByRole('link', { name: 'Dashboard' }).click();
35
- await expect(page.locator('html')).toHaveClass(/dark-mode/);
36
- });
37
- });
38
-
39
- test.describe('cart state persistence', () => {
40
- test('item count updates globally', async ({ page }) => {
41
- await page.goto('/catalog');
42
-
43
- const badge = page.getByTestId('cart-badge');
44
-
45
- await page.getByRole('listitem')
46
- .filter({ hasText: 'Wireless Headphones' })
47
- .getByRole('button', { name: 'Add' })
48
- .click();
49
- await expect(badge).toHaveText('1');
50
-
51
- await page.getByRole('link', { name: 'Contact' }).click();
52
- await expect(badge).toHaveText('1');
53
- });
54
- });
55
-
56
- test.describe('auth state', () => {
57
- test('login updates header across components', async ({ page }) => {
58
- await page.goto('/');
59
-
60
- await expect(page.getByRole('link', { name: 'Login' })).toBeVisible();
61
-
62
- await page.getByRole('link', { name: 'Login' }).click();
63
- await page.getByLabel('Username').fill('testuser');
64
- await page.getByLabel('Password').fill('secret123');
65
- await page.getByRole('button', { name: 'Submit' }).click();
66
-
67
- await expect(page.getByRole('link', { name: 'Login' })).toBeHidden();
68
- await expect(page.getByText('testuser')).toBeVisible();
69
- });
70
- });
71
- ```
72
-
73
- ### React Router Navigation
74
-
75
- **Use when**: Testing client-side routing with React Router v6+—route transitions, URL parameters, protected routes, browser history.
76
- **Avoid when**: Server-side routing (Next.js App Router—see [nextjs.md](nextjs.md)).
77
-
78
- ```typescript
79
- import { test, expect } from '@playwright/test';
80
-
81
- test.describe('client routing', () => {
82
- test('navigation preserves SPA state', async ({ page }) => {
83
- await page.goto('/');
84
-
85
- await page.evaluate(() => {
86
- (window as any).__spaMarker = 'active';
87
- });
88
-
89
- await page.getByRole('link', { name: 'Inventory' }).click();
90
- await page.waitForURL('/inventory');
91
-
92
- const marker = await page.evaluate(() => (window as any).__spaMarker);
93
- expect(marker).toBe('active');
94
- });
95
-
96
- test('query params filter content', async ({ page }) => {
97
- await page.goto('/items?type=books');
98
-
99
- await expect(page.getByRole('heading', { name: 'Books' })).toBeVisible();
100
-
101
- await page.getByRole('link', { name: 'Music' }).click();
102
- await page.waitForURL('/items?type=music');
103
-
104
- await expect(page.getByRole('heading', { name: 'Music' })).toBeVisible();
105
- });
106
-
107
- test('nested routes render layouts', async ({ page }) => {
108
- await page.goto('/account/security');
109
-
110
- await expect(page.getByRole('heading', { name: 'Account' })).toBeVisible();
111
- await expect(page.getByRole('heading', { name: 'Security', level: 2 })).toBeVisible();
112
-
113
- await page.getByRole('link', { name: 'Privacy' }).click();
114
- await page.waitForURL('/account/privacy');
115
-
116
- await expect(page.getByRole('heading', { name: 'Account' })).toBeVisible();
117
- await expect(page.getByRole('heading', { name: 'Privacy', level: 2 })).toBeVisible();
118
- });
119
-
120
- test('history navigation works', async ({ page }) => {
121
- await page.goto('/');
122
- await page.getByRole('link', { name: 'Inventory' }).click();
123
- await page.waitForURL('/inventory');
124
- await page.getByRole('link', { name: 'Help' }).click();
125
- await page.waitForURL('/help');
126
-
127
- await page.goBack();
128
- await expect(page).toHaveURL(/\/inventory/);
129
-
130
- await page.goBack();
131
- await expect(page).toHaveURL(/\/$/);
132
- });
133
-
134
- test('protected route redirects', async ({ page }) => {
135
- await page.goto('/admin/users');
136
-
137
- await expect(page).toHaveURL(/\/login/);
138
- });
139
-
140
- test('unknown route shows 404', async ({ page }) => {
141
- await page.goto('/nonexistent-path');
142
-
143
- await expect(page.getByRole('heading', { name: 'Not Found' })).toBeVisible();
144
- });
145
- });
146
- ```
147
-
148
- ### Testing Hooks Through UI
149
-
150
- **Use when**: Verifying custom hooks produce correct UI behavior—Playwright cannot call hooks directly.
151
- **Avoid when**: Hook logic is pure computation—use unit tests instead.
152
-
153
- ```typescript
154
- import { test, expect } from '@playwright/test';
155
-
156
- test.describe('useDebounce via SearchBox', () => {
157
- test('batches rapid input', async ({ page }) => {
158
- await page.goto('/search');
159
-
160
- const apiCalls: string[] = [];
161
- await page.route('**/api/query*', async (route) => {
162
- apiCalls.push(route.request().url());
163
- await route.continue();
164
- });
165
-
166
- await page.getByRole('textbox', { name: 'Search' }).pressSequentially('testing', {
167
- delay: 40,
168
- });
169
-
170
- await expect(page.getByRole('listitem')).toHaveCount(3);
171
- expect(apiCalls.length).toBeLessThanOrEqual(2);
172
- });
173
- });
174
-
175
- test.describe('usePagination via DataGrid', () => {
176
- test('page controls work', async ({ page }) => {
177
- await page.goto('/records');
178
-
179
- await expect(page.getByText('Page 1 of 10')).toBeVisible();
180
-
181
- await page.getByRole('button', { name: 'Next' }).click();
182
- await expect(page.getByText('Page 2 of 10')).toBeVisible();
183
-
184
- await page.getByRole('button', { name: 'Previous' }).click();
185
- await expect(page.getByText('Page 1 of 10')).toBeVisible();
186
- await expect(page.getByRole('button', { name: 'Previous' })).toBeDisabled();
187
- });
188
- });
189
- ```
190
-
191
- ### Form Libraries (React Hook Form, Formik)
192
-
193
- **Use when**: Testing forms built with react-hook-form or Formik—Playwright interacts with DOM, form library is transparent.
194
-
195
- ```typescript
196
- import { test, expect } from '@playwright/test';
197
-
198
- test.describe('signup form', () => {
199
- test.beforeEach(async ({ page }) => {
200
- await page.goto('/signup');
201
- });
202
-
203
- test('validation on empty submit', async ({ page }) => {
204
- await page.getByRole('button', { name: 'Register' }).click();
205
-
206
- await expect(page.getByText('Email required')).toBeVisible();
207
- await expect(page.getByText('Password required')).toBeVisible();
208
- });
209
-
210
- test('inline validation on blur', async ({ page }) => {
211
- const email = page.getByLabel('Email');
212
- await email.fill('invalid');
213
- await email.blur();
214
-
215
- await expect(page.getByText('Invalid email format')).toBeVisible();
216
- });
217
-
218
- test('password strength indicator', async ({ page }) => {
219
- const pwd = page.getByLabel('Password', { exact: true });
220
-
221
- await pwd.fill('weak');
222
- await expect(page.getByText('Minimum 8 characters')).toHaveClass(/invalid/);
223
-
224
- await pwd.fill('StrongPass1!');
225
- await expect(page.getByText('Minimum 8 characters')).toHaveClass(/valid/);
226
- });
227
-
228
- test('successful submission redirects', async ({ page }) => {
229
- await page.getByLabel('Name').fill('Alice');
230
- await page.getByLabel('Email').fill('alice@test.com');
231
- await page.getByLabel('Password', { exact: true }).fill('Secure123!');
232
- await page.getByLabel('Confirm').fill('Secure123!');
233
- await page.getByLabel('Accept terms').check();
234
-
235
- await page.getByRole('button', { name: 'Register' }).click();
236
-
237
- await page.waitForURL('/welcome');
238
- await expect(page.getByText('Hello, Alice')).toBeVisible();
239
- });
240
-
241
- test('submit button disabled during request', async ({ page }) => {
242
- await page.route('**/api/signup', async (route) => {
243
- await new Promise((r) => setTimeout(r, 800));
244
- await route.fulfill({ status: 201, json: { id: 1 } });
245
- });
246
-
247
- await page.getByLabel('Name').fill('Bob');
248
- await page.getByLabel('Email').fill('bob@test.com');
249
- await page.getByLabel('Password', { exact: true }).fill('Secure123!');
250
- await page.getByLabel('Confirm').fill('Secure123!');
251
- await page.getByLabel('Accept terms').check();
252
-
253
- await page.getByRole('button', { name: 'Register' }).click();
254
-
255
- await expect(page.getByRole('button', { name: /Registering|Loading/ })).toBeDisabled();
256
- });
257
- });
258
- ```
259
-
260
- ### Portals (Modals, Tooltips, Dropdowns)
261
-
262
- **Use when**: Testing components rendered via `ReactDOM.createPortal()`—modals, dialogs, tooltips, menus. These render outside parent DOM but Playwright sees the full document.
263
-
264
- ```typescript
265
- import { test, expect } from '@playwright/test';
266
-
267
- test.describe('portal components', () => {
268
- test('modal interaction', async ({ page }) => {
269
- await page.goto('/items');
270
-
271
- await page.getByRole('button', { name: 'Remove' }).first().click();
272
-
273
- const dialog = page.getByRole('dialog', { name: 'Confirm removal' });
274
- await expect(dialog).toBeVisible();
275
- await expect(dialog.getByRole('button', { name: 'Cancel' })).toBeFocused();
276
-
277
- await dialog.getByRole('button', { name: 'Remove' }).click();
278
- await expect(dialog).toBeHidden();
279
- });
280
-
281
- test('escape closes modal', async ({ page }) => {
282
- await page.goto('/items');
283
- await page.getByRole('button', { name: 'Remove' }).first().click();
284
-
285
- const dialog = page.getByRole('dialog');
286
- await expect(dialog).toBeVisible();
287
-
288
- await page.keyboard.press('Escape');
289
- await expect(dialog).toBeHidden();
290
- });
291
-
292
- test('tooltip on hover', async ({ page }) => {
293
- await page.goto('/panel');
294
-
295
- await page.getByRole('button', { name: 'Help' }).hover();
296
- await expect(page.getByRole('tooltip')).toBeVisible();
297
-
298
- await page.mouse.move(0, 0);
299
- await expect(page.getByRole('tooltip')).toBeHidden();
300
- });
301
-
302
- test('dropdown menu', async ({ page }) => {
303
- await page.goto('/panel');
304
-
305
- await page.getByRole('button', { name: 'Actions' }).click();
306
-
307
- const menu = page.getByRole('menu');
308
- await expect(menu).toBeVisible();
309
-
310
- await menu.getByRole('menuitem', { name: 'Rename' }).click();
311
- await expect(menu).toBeHidden();
312
- });
313
-
314
- test('toast auto-dismisses', async ({ page }) => {
315
- await page.goto('/preferences');
316
-
317
- await page.getByRole('button', { name: 'Save' }).click();
318
- await expect(page.getByText('Preferences saved')).toBeVisible();
319
-
320
- await expect(page.getByText('Preferences saved')).toBeHidden({ timeout: 8000 });
321
- });
322
- });
323
- ```
324
-
325
- ### Error Boundaries
326
-
327
- **Use when**: Verifying error boundaries catch rendering errors and show fallback UI.
328
- **Avoid when**: Testing error handling in event handlers or async code—error boundaries only catch render errors.
329
-
330
- ```typescript
331
- import { test, expect } from '@playwright/test';
332
-
333
- test.describe('error boundary', () => {
334
- test('shows fallback on crash', async ({ page }) => {
335
- await page.route('**/api/widgets', (route) => {
336
- route.fulfill({
337
- status: 200,
338
- json: { widgets: null },
339
- });
340
- });
341
-
342
- await page.goto('/panel');
343
-
344
- await expect(page.getByText('Something went wrong')).toBeVisible();
345
- await expect(page.getByRole('button', { name: 'Retry' })).toBeVisible();
346
- await expect(page.getByRole('navigation')).toBeVisible();
347
- });
348
-
349
- test('retry recovers component', async ({ page }) => {
350
- let calls = 0;
351
- await page.route('**/api/widgets', (route) => {
352
- calls++;
353
- if (calls === 1) {
354
- route.fulfill({ status: 200, json: { widgets: null } });
355
- } else {
356
- route.fulfill({ status: 200, json: { widgets: [{ id: 1, name: 'Chart' }] } });
357
- }
358
- });
359
-
360
- await page.goto('/panel');
361
-
362
- await expect(page.getByText('Something went wrong')).toBeVisible();
363
-
364
- await page.getByRole('button', { name: 'Retry' }).click();
365
-
366
- await expect(page.getByText('Something went wrong')).toBeHidden();
367
- await expect(page.getByText('Chart')).toBeVisible();
368
- });
369
- });
370
- ```
371
-
372
- ### Component Testing (Experimental)
373
-
374
- **Use when**: Testing complex interactive components in isolation—data tables, form wizards, rich editors. Needs real browser but not full app.
375
- **Avoid when**: Component depends heavily on backend data or routing—use E2E instead.
376
-
377
- ```typescript
378
- // playwright-ct.config.ts
379
- import { defineConfig, devices } from '@playwright/experimental-ct-react';
380
-
381
- export default defineConfig({
382
- testDir: './tests/components',
383
- testMatch: '**/*.ct.ts',
384
- use: {
385
- trace: 'on-first-retry',
386
- ctPort: 3100,
387
- },
388
- projects: [
389
- { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
390
- ],
391
- });
392
- ```
393
-
394
- ```typescript
395
- // tests/components/Stepper.ct.ts
396
- import { test, expect } from '@playwright/experimental-ct-react';
397
- import Stepper from '../../src/components/Stepper';
398
-
399
- test('increments on click', async ({ mount }) => {
400
- const component = await mount(<Stepper initial={0} />);
401
-
402
- await expect(component.getByText('Value: 0')).toBeVisible();
403
- await component.getByRole('button', { name: '+' }).click();
404
- await expect(component.getByText('Value: 1')).toBeVisible();
405
- });
406
-
407
- test('fires onChange callback', async ({ mount }) => {
408
- const values: number[] = [];
409
- const component = await mount(
410
- <Stepper initial={0} onChange={(v) => values.push(v)} />
411
- );
412
-
413
- await component.getByRole('button', { name: '+' }).click();
414
- await component.getByRole('button', { name: '+' }).click();
415
-
416
- expect(values).toEqual([1, 2]);
417
- });
418
-
419
- test('respects min boundary', async ({ mount }) => {
420
- const component = await mount(<Stepper initial={0} min={0} />);
421
-
422
- await expect(component.getByRole('button', { name: '-' })).toBeDisabled();
423
- });
424
- ```
425
-
426
- ## Setup
427
-
428
- ### E2E Config (Vite)
429
-
430
- ```typescript
431
- // playwright.config.ts
432
- import { defineConfig, devices } from '@playwright/test';
433
-
434
- export default defineConfig({
435
- testDir: './tests',
436
- fullyParallel: true,
437
- forbidOnly: !!process.env.CI,
438
- retries: process.env.CI ? 2 : 0,
439
- workers: process.env.CI ? '50%' : undefined,
440
-
441
- use: {
442
- baseURL: 'http://localhost:5173',
443
- trace: 'on-first-retry',
444
- screenshot: 'only-on-failure',
445
- },
446
-
447
- projects: [
448
- { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
449
- { name: 'firefox', use: { ...devices['Desktop Firefox'] } },
450
- { name: 'mobile', use: { ...devices['iPhone 14'] } },
451
- ],
452
-
453
- webServer: {
454
- command: process.env.CI ? 'npm run build && npx vite preview --port 5173' : 'npm run dev',
455
- url: 'http://localhost:5173',
456
- reuseExistingServer: !process.env.CI,
457
- timeout: 120_000,
458
- },
459
- });
460
- ```
461
-
462
- ### CRA vs Vite Differences
463
-
464
- | Aspect | Create React App | Vite |
465
- |---|---|---|
466
- | Default port | `3000` | `5173` |
467
- | Build output | `build/` | `dist/` |
468
- | Serve production | `npx serve -s build -l 3000` | `npx vite preview --port 5173` |
469
- | Env var prefix | `REACT_APP_*` | `VITE_*` |
470
-
471
- ## Framework Tips
472
-
473
- ### Strict Mode Double Effects
474
-
475
- React Strict Mode runs effects twice in development. Tests should be resilient:
476
-
477
- - Don't assert exact API call counts in dev mode
478
- - Run against production build for call count assertions, or account for double invocations
479
-
480
- ### Suspense and Lazy Components
481
-
482
- ```typescript
483
- test('lazy route loads content', async ({ page }) => {
484
- await page.goto('/');
485
-
486
- await page.getByRole('link', { name: 'Analytics' }).click();
487
-
488
- await expect(page.getByRole('heading', { name: 'Analytics' })).toBeVisible();
489
- });
490
- ```
491
-
492
- ### Detecting Memory Leaks
493
-
494
- ```typescript
495
- test('no unmounted state warnings', async ({ page }) => {
496
- const warnings: string[] = [];
497
- page.on('console', (msg) => {
498
- if (msg.type() === 'warning' && msg.text().includes('unmounted')) {
499
- warnings.push(msg.text());
500
- }
501
- });
502
-
503
- await page.goto('/panel');
504
- await page.getByRole('link', { name: 'Settings' }).click();
505
- await page.goBack();
506
- await page.getByRole('link', { name: 'Profile' }).click();
507
-
508
- expect(warnings).toEqual([]);
509
- });
510
- ```
511
-
512
- ## Anti-Patterns
513
-
514
- | Don't | Problem | Do Instead |
515
- |---|---|---|
516
- | `page.evaluate(() => store.getState())` | Couples tests to implementation | Assert on UI: `expect(badge).toHaveText('3')` |
517
- | Import components in E2E tests | E2E runs in Node, not browser | Use `@playwright/experimental-ct-react` for components |
518
- | `page.waitForTimeout(500)` after state changes | Timing varies across machines | `expect(locator).toHaveText('value')` auto-retries |
519
- | `page.locator('.MuiButton-root')` | Class names change between versions | `page.getByRole('button', { name: 'Submit' })` |
520
- | Test every component with CT | Overhead for simple components | CT for complex widgets, unit tests for logic, E2E for flows |
521
- | Skip keyboard navigation tests | Accessibility regressions common | Test Tab, Enter, Escape, Arrow interactions |
522
- | Assert on `__REACT_FIBER__` internals | Not stable across versions | Only interact with rendered DOM |
523
-
524
- ## Related
525
-
526
- - [locators.md](../core/locators.md) — locator strategies for any React component library
527
- - [assertions-waiting.md](../core/assertions-waiting.md) — auto-waiting for React state changes
528
- - [forms-validation.md](../testing-patterns/forms-validation.md) — form testing patterns
529
- - [component-testing.md](../testing-patterns/component-testing.md) — in-depth component testing
530
- - [test-architecture.md](../architecture/test-architecture.md) — E2E vs component vs unit decisions
531
- - [nextjs.md](nextjs.md) — Next.js-specific patterns for SSR