codeceptjs 4.0.0-rc.17 → 4.0.0-rc.19

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 (240) hide show
  1. package/bin/codecept.js +15 -2
  2. package/bin/codeceptq.js +49 -0
  3. package/bin/mcp-server.js +733 -196
  4. package/docs/advanced.md +201 -0
  5. package/docs/agents.md +159 -0
  6. package/docs/ai.md +537 -0
  7. package/docs/aitrace.md +266 -0
  8. package/docs/api.md +332 -0
  9. package/docs/assertions.md +415 -0
  10. package/docs/auth.md +318 -0
  11. package/docs/basics.md +424 -0
  12. package/docs/bdd.md +539 -0
  13. package/docs/best.md +240 -0
  14. package/docs/bootstrap.md +132 -0
  15. package/docs/commands.md +352 -0
  16. package/docs/community-helpers.md +63 -0
  17. package/docs/configuration.md +230 -0
  18. package/docs/continuous-integration.md +497 -0
  19. package/docs/custom-helpers.md +297 -0
  20. package/docs/data.md +448 -0
  21. package/docs/debugging.md +332 -0
  22. package/docs/detox.md +235 -0
  23. package/docs/docker.md +136 -0
  24. package/docs/effects.md +179 -0
  25. package/docs/element-based-testing.md +295 -0
  26. package/docs/element-selection.md +125 -0
  27. package/docs/els.md +328 -0
  28. package/docs/examples.md +161 -0
  29. package/docs/heal.md +213 -0
  30. package/docs/helpers/ApiDataFactory.md +267 -0
  31. package/docs/helpers/Appium.md +1405 -0
  32. package/docs/helpers/Detox.md +665 -0
  33. package/docs/helpers/ExpectHelper.md +275 -0
  34. package/docs/helpers/FileSystem.md +152 -0
  35. package/docs/helpers/GraphQL.md +152 -0
  36. package/docs/helpers/GraphQLDataFactory.md +226 -0
  37. package/docs/helpers/JSONResponse.md +255 -0
  38. package/docs/helpers/Mochawesome.md +8 -0
  39. package/docs/helpers/MockRequest.md +377 -0
  40. package/docs/helpers/MockServer.md +212 -0
  41. package/docs/helpers/Playwright.md +2969 -0
  42. package/docs/helpers/Polly.md +44 -0
  43. package/docs/helpers/Protractor.md +1769 -0
  44. package/docs/helpers/Puppeteer-firefox.md +86 -0
  45. package/docs/helpers/Puppeteer.md +2690 -0
  46. package/docs/helpers/REST.md +289 -0
  47. package/docs/helpers/SoftExpectHelper.md +352 -0
  48. package/docs/helpers/WebDriver.md +2682 -0
  49. package/docs/hooks.md +339 -0
  50. package/docs/index.md +111 -0
  51. package/docs/installation.md +83 -0
  52. package/docs/internal-api.md +265 -0
  53. package/docs/internal-test-server.md +89 -0
  54. package/docs/locators.md +355 -0
  55. package/docs/mcp.md +485 -0
  56. package/docs/migration-4.md +556 -0
  57. package/docs/mobile.md +338 -0
  58. package/docs/pageobjects.md +399 -0
  59. package/docs/parallel.md +585 -0
  60. package/docs/playwright.md +714 -0
  61. package/docs/plugins.md +866 -0
  62. package/docs/puppeteer.md +314 -0
  63. package/docs/quickstart.md +120 -0
  64. package/docs/react.md +70 -0
  65. package/docs/reports.md +483 -0
  66. package/docs/retry.md +274 -0
  67. package/docs/secrets.md +150 -0
  68. package/docs/sessions.md +80 -0
  69. package/docs/shadow.md +68 -0
  70. package/docs/test-structure.md +275 -0
  71. package/docs/timeouts.md +183 -0
  72. package/docs/translation.md +247 -0
  73. package/docs/tutorial.md +271 -0
  74. package/docs/typescript.md +374 -0
  75. package/docs/web-element.md +251 -0
  76. package/docs/webdriver.md +708 -0
  77. package/docs/within.md +55 -0
  78. package/lib/aria.js +260 -0
  79. package/lib/command/dryRun.js +23 -3
  80. package/lib/command/init.js +247 -266
  81. package/lib/command/list.js +150 -10
  82. package/lib/command/query.js +218 -0
  83. package/lib/config.js +77 -4
  84. package/lib/container.js +34 -2
  85. package/lib/element/WebElement.js +37 -0
  86. package/lib/globals.js +11 -10
  87. package/lib/helper/Playwright.js +5 -6
  88. package/lib/helper/extras/PlaywrightReactVueLocator.js +45 -36
  89. package/lib/html.js +90 -16
  90. package/lib/index.js +9 -1
  91. package/lib/locator.js +2 -2
  92. package/lib/mocha/factory.js +5 -1
  93. package/lib/mocha/inject.js +1 -1
  94. package/lib/parser.js +2 -2
  95. package/lib/pause.js +38 -4
  96. package/lib/plugin/aiTrace.js +72 -84
  97. package/lib/plugin/browser.js +77 -0
  98. package/lib/plugin/expose.js +159 -0
  99. package/lib/plugin/heal.js +44 -1
  100. package/lib/plugin/pageInfo.js +51 -48
  101. package/lib/plugin/pause.js +131 -0
  102. package/lib/plugin/pauseOnFail.js +10 -34
  103. package/lib/plugin/screencast.js +287 -0
  104. package/lib/plugin/screenshot.js +563 -0
  105. package/lib/plugin/screenshotOnFail.js +8 -170
  106. package/lib/utils/pluginParser.js +151 -0
  107. package/lib/utils/trace.js +297 -0
  108. package/lib/utils.js +25 -0
  109. package/lib/workers.js +1 -15
  110. package/package.json +12 -10
  111. package/typings/index.d.ts +0 -5
  112. package/docs/webapi/amOnPage.mustache +0 -11
  113. package/docs/webapi/appendField.mustache +0 -16
  114. package/docs/webapi/attachFile.mustache +0 -24
  115. package/docs/webapi/blur.mustache +0 -18
  116. package/docs/webapi/checkOption.mustache +0 -13
  117. package/docs/webapi/clearCookie.mustache +0 -9
  118. package/docs/webapi/clearField.mustache +0 -14
  119. package/docs/webapi/click.mustache +0 -29
  120. package/docs/webapi/clickLink.mustache +0 -8
  121. package/docs/webapi/closeCurrentTab.mustache +0 -7
  122. package/docs/webapi/closeOtherTabs.mustache +0 -8
  123. package/docs/webapi/dontSee.mustache +0 -11
  124. package/docs/webapi/dontSeeCheckboxIsChecked.mustache +0 -10
  125. package/docs/webapi/dontSeeCookie.mustache +0 -8
  126. package/docs/webapi/dontSeeCurrentPathEquals.mustache +0 -10
  127. package/docs/webapi/dontSeeCurrentUrlEquals.mustache +0 -10
  128. package/docs/webapi/dontSeeElement.mustache +0 -12
  129. package/docs/webapi/dontSeeElementInDOM.mustache +0 -8
  130. package/docs/webapi/dontSeeInCurrentUrl.mustache +0 -4
  131. package/docs/webapi/dontSeeInField.mustache +0 -16
  132. package/docs/webapi/dontSeeInSource.mustache +0 -8
  133. package/docs/webapi/dontSeeInTitle.mustache +0 -8
  134. package/docs/webapi/dontSeeTraffic.mustache +0 -13
  135. package/docs/webapi/doubleClick.mustache +0 -13
  136. package/docs/webapi/downloadFile.mustache +0 -12
  137. package/docs/webapi/dragAndDrop.mustache +0 -9
  138. package/docs/webapi/dragSlider.mustache +0 -11
  139. package/docs/webapi/executeAsyncScript.mustache +0 -24
  140. package/docs/webapi/executeScript.mustache +0 -26
  141. package/docs/webapi/fillField.mustache +0 -21
  142. package/docs/webapi/flushNetworkTraffics.mustache +0 -5
  143. package/docs/webapi/focus.mustache +0 -13
  144. package/docs/webapi/forceClick.mustache +0 -28
  145. package/docs/webapi/forceRightClick.mustache +0 -18
  146. package/docs/webapi/grabAllWindowHandles.mustache +0 -7
  147. package/docs/webapi/grabAttributeFrom.mustache +0 -10
  148. package/docs/webapi/grabAttributeFromAll.mustache +0 -9
  149. package/docs/webapi/grabBrowserLogs.mustache +0 -9
  150. package/docs/webapi/grabCookie.mustache +0 -11
  151. package/docs/webapi/grabCssPropertyFrom.mustache +0 -11
  152. package/docs/webapi/grabCssPropertyFromAll.mustache +0 -10
  153. package/docs/webapi/grabCurrentUrl.mustache +0 -9
  154. package/docs/webapi/grabCurrentWindowHandle.mustache +0 -6
  155. package/docs/webapi/grabDataFromPerformanceTiming.mustache +0 -20
  156. package/docs/webapi/grabElementBoundingRect.mustache +0 -20
  157. package/docs/webapi/grabGeoLocation.mustache +0 -8
  158. package/docs/webapi/grabHTMLFrom.mustache +0 -10
  159. package/docs/webapi/grabHTMLFromAll.mustache +0 -9
  160. package/docs/webapi/grabNumberOfOpenTabs.mustache +0 -8
  161. package/docs/webapi/grabNumberOfVisibleElements.mustache +0 -9
  162. package/docs/webapi/grabPageScrollPosition.mustache +0 -8
  163. package/docs/webapi/grabPopupText.mustache +0 -5
  164. package/docs/webapi/grabRecordedNetworkTraffics.mustache +0 -10
  165. package/docs/webapi/grabSource.mustache +0 -8
  166. package/docs/webapi/grabTextFrom.mustache +0 -10
  167. package/docs/webapi/grabTextFromAll.mustache +0 -9
  168. package/docs/webapi/grabTitle.mustache +0 -8
  169. package/docs/webapi/grabValueFrom.mustache +0 -9
  170. package/docs/webapi/grabValueFromAll.mustache +0 -8
  171. package/docs/webapi/grabWebElement.mustache +0 -9
  172. package/docs/webapi/grabWebElements.mustache +0 -9
  173. package/docs/webapi/moveCursorTo.mustache +0 -16
  174. package/docs/webapi/openNewTab.mustache +0 -7
  175. package/docs/webapi/pressKey.mustache +0 -12
  176. package/docs/webapi/pressKeyDown.mustache +0 -12
  177. package/docs/webapi/pressKeyUp.mustache +0 -12
  178. package/docs/webapi/pressKeyWithKeyNormalization.mustache +0 -60
  179. package/docs/webapi/refreshPage.mustache +0 -6
  180. package/docs/webapi/resizeWindow.mustache +0 -6
  181. package/docs/webapi/rightClick.mustache +0 -14
  182. package/docs/webapi/saveElementScreenshot.mustache +0 -10
  183. package/docs/webapi/saveScreenshot.mustache +0 -12
  184. package/docs/webapi/say.mustache +0 -10
  185. package/docs/webapi/scrollIntoView.mustache +0 -11
  186. package/docs/webapi/scrollPageToBottom.mustache +0 -6
  187. package/docs/webapi/scrollPageToTop.mustache +0 -6
  188. package/docs/webapi/scrollTo.mustache +0 -12
  189. package/docs/webapi/see.mustache +0 -11
  190. package/docs/webapi/seeAttributesOnElements.mustache +0 -9
  191. package/docs/webapi/seeCheckboxIsChecked.mustache +0 -10
  192. package/docs/webapi/seeCookie.mustache +0 -8
  193. package/docs/webapi/seeCssPropertiesOnElements.mustache +0 -9
  194. package/docs/webapi/seeCurrentPathEquals.mustache +0 -10
  195. package/docs/webapi/seeCurrentUrlEquals.mustache +0 -11
  196. package/docs/webapi/seeElement.mustache +0 -12
  197. package/docs/webapi/seeElementInDOM.mustache +0 -8
  198. package/docs/webapi/seeInCurrentUrl.mustache +0 -8
  199. package/docs/webapi/seeInField.mustache +0 -17
  200. package/docs/webapi/seeInPopup.mustache +0 -8
  201. package/docs/webapi/seeInSource.mustache +0 -7
  202. package/docs/webapi/seeInTitle.mustache +0 -8
  203. package/docs/webapi/seeNumberOfElements.mustache +0 -11
  204. package/docs/webapi/seeNumberOfVisibleElements.mustache +0 -10
  205. package/docs/webapi/seeTextEquals.mustache +0 -9
  206. package/docs/webapi/seeTitleEquals.mustache +0 -8
  207. package/docs/webapi/seeTraffic.mustache +0 -36
  208. package/docs/webapi/selectOption.mustache +0 -26
  209. package/docs/webapi/setCookie.mustache +0 -16
  210. package/docs/webapi/setGeoLocation.mustache +0 -12
  211. package/docs/webapi/startRecordingTraffic.mustache +0 -8
  212. package/docs/webapi/startRecordingWebSocketMessages.mustache +0 -8
  213. package/docs/webapi/stopRecordingTraffic.mustache +0 -5
  214. package/docs/webapi/stopRecordingWebSocketMessages.mustache +0 -7
  215. package/docs/webapi/switchTo.mustache +0 -9
  216. package/docs/webapi/switchToNextTab.mustache +0 -10
  217. package/docs/webapi/switchToPreviousTab.mustache +0 -10
  218. package/docs/webapi/type.mustache +0 -21
  219. package/docs/webapi/uncheckOption.mustache +0 -13
  220. package/docs/webapi/wait.mustache +0 -8
  221. package/docs/webapi/waitForClickable.mustache +0 -11
  222. package/docs/webapi/waitForCookie.mustache +0 -9
  223. package/docs/webapi/waitForDetached.mustache +0 -10
  224. package/docs/webapi/waitForDisabled.mustache +0 -6
  225. package/docs/webapi/waitForElement.mustache +0 -11
  226. package/docs/webapi/waitForEnabled.mustache +0 -6
  227. package/docs/webapi/waitForFunction.mustache +0 -17
  228. package/docs/webapi/waitForInvisible.mustache +0 -10
  229. package/docs/webapi/waitForNumberOfTabs.mustache +0 -9
  230. package/docs/webapi/waitForText.mustache +0 -13
  231. package/docs/webapi/waitForValue.mustache +0 -10
  232. package/docs/webapi/waitForVisible.mustache +0 -10
  233. package/docs/webapi/waitInUrl.mustache +0 -9
  234. package/docs/webapi/waitNumberOfVisibleElements.mustache +0 -10
  235. package/docs/webapi/waitToHide.mustache +0 -10
  236. package/docs/webapi/waitUrlEquals.mustache +0 -10
  237. package/lib/helper/AI.js +0 -214
  238. package/lib/plugin/pauseOn.js +0 -167
  239. package/lib/plugin/stepByStepReport.js +0 -432
  240. package/lib/plugin/subtitles.js +0 -89
@@ -0,0 +1,201 @@
1
+ ---
2
+ permalink: /advanced
3
+ title: Advanced Usage
4
+ ---
5
+
6
+ # Advanced Usage
7
+
8
+ ## Data Driven Tests
9
+
10
+ Execute the same scenario on a different data set.
11
+
12
+ Let's say you want to test login for different user accounts.
13
+ In this case, you need to create a datatable and fill it in with credentials.
14
+ Then use `Data().Scenario` to include this data and generate multiple scenarios:
15
+
16
+ ```js
17
+ // Define data table inside a test or load from another module
18
+ let accounts = new DataTable(['login', 'password']); //
19
+ accounts.add(['davert', '123456']); // adding records to a table
20
+ accounts.add(['admin', '123456']);
21
+
22
+ // You can skip some data. But add them to report as skipped (just like with usual scenarios):
23
+ accounts.xadd(['admin', '23456'])
24
+
25
+ // Pass dataTable to Data()
26
+ // Use special param `current` to get current data set
27
+ Data(accounts).Scenario('Test Login', ({ I, current }) => {
28
+ I.fillField('Username', current.login); // current is reserved!
29
+ I.fillField('Password', current.password);
30
+ I.click('Sign In');
31
+ I.see('Welcome '+ current.login);
32
+ });
33
+
34
+
35
+ // Also you can set only for Data tests. It will launch executes only the current test but with all data options
36
+ Data(accounts).only.Scenario('Test Login', ({ I, current }) => {
37
+ I.fillField('Username', current.login); // current is reserved!
38
+ I.fillField('Password', current.password);
39
+ I.click('Sign In');
40
+ I.see('Welcome '+ current.login);
41
+ });
42
+ ```
43
+
44
+ *Important: you can't use name `current` for pageObjects or helpers in data scenarios*
45
+
46
+ This will produce 2 tests with different data sets.
47
+ Current data set is appended to a test name in output:
48
+
49
+ ```sh
50
+ ✓ Test Login | {"login":"davert","password":"123456"}
51
+ ✓ Test Login | {"login":"admin","password":"123456"}
52
+ S Test Login | {"login":"admin","password":"23456"}
53
+ ```
54
+
55
+ ```js
56
+ // You can filter your data table
57
+ Data(accounts.filter(account => account.login == 'admin')
58
+ .Scenario('Test Login', ({ I, current }) => {
59
+ I.fillField('Username', current.login);
60
+ I.fillField('Password', current.password);
61
+ I.click('Sign In');
62
+ I.see('Welcome '+ current.login);
63
+ });
64
+ ```
65
+
66
+ This will limit data sets accoring passed function:
67
+
68
+ ```sh
69
+ ✓ Test Login | {"login":"admin","password":"123456"}
70
+ S Test Login | {"login":"admin","password":"23456"}
71
+ ```
72
+
73
+ Data sets can also be defined with array, generator, or a function.
74
+
75
+ ```js
76
+ Data(function*() {
77
+ yield { user: 'davert'};
78
+ yield { user: 'andrey'};
79
+ }).Scenario() // ...
80
+ ```
81
+
82
+ *HINT: If you don't use DataTable. add `toString()` method to each object added to data set, so the data could be pretty printed in a test name*
83
+
84
+
85
+ ## Debug
86
+
87
+ CodeceptJS provides a debug mode in which additional information is printed.
88
+ It can be turned on with `--debug` flag.
89
+
90
+ ```sh
91
+ npx codeceptjs run --debug
92
+ ```
93
+
94
+ to receive even more information turn on `--verbose` flag:
95
+
96
+ ```sh
97
+ npx codeceptjs run --verbose
98
+ ```
99
+
100
+ > You can pause execution and enter **interactive console** mode by calling `pause()` inside your test.
101
+
102
+ To see a complete internal debug of CodeceptJS use `DEBUG` env variable:
103
+
104
+ ```sh
105
+ DEBUG=codeceptjs:* npx codeceptjs run
106
+ ```
107
+
108
+ For an interactive debugging use NodeJS debugger. In **WebStorm**:
109
+
110
+ ```sh
111
+ node $NODE_DEBUG_OPTION ./node_modules/.bin/codeceptjs run
112
+ ```
113
+
114
+ For **Visual Studio Code**, add the following configuration in launch.json:
115
+
116
+ ```json
117
+ {
118
+ "type": "node",
119
+ "request": "launch",
120
+ "name": "codeceptjs",
121
+ "args": ["run", "--grep", "@your_test_tag"],
122
+ "program": "${workspaceFolder}/node_modules/codeceptjs/bin/codecept.js"
123
+ }
124
+ ```
125
+
126
+
127
+ ## Test Options
128
+
129
+ Features and Scenarios have their options that can be set by passing a hash after their names:
130
+
131
+ ```js
132
+ Feature('My feature', {key: val});
133
+
134
+ Scenario('My scenario', {key: val},({ I }) => {});
135
+ ```
136
+
137
+ You can use this options for build your own [plugins](https://codecept.io/hooks/#plugins) with [event listners](https://codecept.io/hooks/#api). Example:
138
+
139
+ ```js
140
+ // for test
141
+ event.dispatcher.on(event.test.before, (test) => {
142
+ ...
143
+ if (test.opts.key) {
144
+ ...
145
+ }
146
+ ...
147
+ });
148
+ // or for suite
149
+ event.dispatcher.on(event.suite.before, (suite) => {
150
+ ...
151
+ if (suite.opts.key) {
152
+ ...
153
+ }
154
+ ...
155
+ });
156
+ ```
157
+
158
+ ## Direct Helper Access
159
+
160
+ Some scenarios need the underlying SDK directly — a raw `page.evaluate`, a `page.on('request')` listener, an experimental Playwright API, or a wdio command the `WebDriver` helper doesn't expose. The `expose` plugin injects helper internals as scenario arguments so you can call them inline.
161
+
162
+ ```js
163
+ Scenario('intercept network', async ({ I, page }) => {
164
+ page.on('request', req => console.log(req.method(), req.url()))
165
+ I.amOnPage('/')
166
+ const title = await page.evaluate(() => document.title)
167
+ I.see(title)
168
+ })
169
+ ```
170
+ Enable `expose` plugin in config and use public properties from a corresponding helper.
171
+ Map each injection name to `HelperName.propertyName`:
172
+
173
+ ```js
174
+ plugins: {
175
+ expose: {
176
+ enabled: true,
177
+ inject: {
178
+ page: 'Playwright.page',
179
+ browser: 'Playwright.browser',
180
+ browserContext: 'Playwright.browserContext',
181
+ wdio: 'WebDriver.browser',
182
+ }
183
+ }
184
+ }
185
+ ```
186
+
187
+ There is a shorthand mode:
188
+
189
+ ```js
190
+ plugins: {
191
+ expose: {
192
+ enabled: true,
193
+ inject: { page: 'page' } // resolves Playwright.page or Puppeteer.page
194
+ }
195
+ }
196
+ ```
197
+ A value with no dot is shorthand for "the first configured browser helper that exposes this property". Allowed properties: `page`, `browser`, `browserContext`, `context`.
198
+
199
+ The injected value is a live proxy. Every property access reads the current helper property at that moment, so tab switches (`I.openNewTab`, `I.switchToNextTab`) propagate automatically — the next call through `page` targets the new tab.
200
+
201
+ Calls pass straight to the underlying SDK. They aren't wrapped as CodeceptJS steps and don't appear in step output, so `await page.evaluate(...)` behaves as native Playwright.
package/docs/agents.md ADDED
@@ -0,0 +1,159 @@
1
+ ---
2
+ permalink: /agents
3
+ title: Agentic Testing
4
+ ---
5
+
6
+ # Agentic Testing
7
+
8
+ CodeceptJS ships an **MCP server and a skillset** that lets an AI agent (Claude Code, Cursor, Codex, others) write and fix tests by driving the real browser. The agent runs the same `I.*` commands the test does, reads how the page responds, and only commits the lines that succeeded.
9
+
10
+ ## Why MCP
11
+
12
+ The traditional agent testing loop is test/fix/retry, where the agent executes a test, watches it fail, reads artifacts, performs code fixes, and reruns the test. The agent applies fixes by intelligent guess — looking at the ARIA tree, HTML, and screenshot — then assumes the fix is enough and reruns the test hoping it will pass. If the guess is wrong and the test runs for over a minute, it may take dozens of minutes of iteration and a lot of wasted tokens.
13
+
14
+ To improve that flow, the agent can spawn a browser and open the page the way the test does. This lets it interact with the page more freely and perform multi-step actions. But putting that experience back into test code is not efficient either: actions executed in the browser may not be relevant in test context, so the agent ends up in another guess-and-try loop.
15
+
16
+ The problem is that **the test runs in a different context than the agent**.
17
+
18
+ The agent can launch a test but can't control it while it's running. It can't access the browser. It can't set a breakpoint.
19
+
20
+ This is where CodeceptJS MCP steps in. Connected to the agent, it can:
21
+
22
+ - run a test and pause it on failure
23
+ - interact with the browser in a test context
24
+ - test locators and perform actions live while the test is running
25
+ - write successful actions to the test file
26
+
27
+ This lets the agent get a test working in one iteration. The agent can live-write the test before your eyes by exploring the page and performing actions that eventually land in the CodeceptJS test file.
28
+
29
+ **Live debugging of tests** is what CodeceptJS MCP provides. The agent receives feedback faster — not from a whole test execution but from specific actions on a specific page — so it can adjust and react faster, trying different approaches.
30
+
31
+ The MCP server is the agent-facing equivalent of the `pause()` REPL — same access, driven by tool calls instead of keystrokes. Full tool reference at [/mcp](/mcp).
32
+
33
+ ## The loop
34
+
35
+ Whether the agent is writing a new test or fixing an old one, it follows the same cycle.
36
+
37
+ 1. **Open the page.** Run a stub test (new work) or set a breakpoint at the failing step (fix). The browser lands at the right starting point and yields control to the agent.
38
+ 2. **Read the page.** MCP saves HTML, ARIA, and screenshot of the page to files (and the agent can call the `snapshot` tool to refresh them). The agent reads those files before deciding what to try next, controlling its token usage.
39
+ 3. **Run a CodeceptJS command.** The agent tries `I.*` commands like `I.click('Add to cart')`, `I.fillField('Email', secret(process.env.EMAIL))`, `I.see('Confirmed')`. On success, that line goes into the test — same syntax.
40
+ 4. **Check the result.** The response after each command shows the new page state. If the URL changed and the modal opened, the line goes into the verified sequence. If not, the agent reads the page again and tries a different locator or a wait.
41
+ 5. **Move forward.** The agent looks at the new state and chooses the next command. Steps 2–4 repeat until the scenario is whole.
42
+ 6. **Commit to the file.** The agent edits the test — replaces `pause()` (new tests) or the broken line (fixes) with the verified sequence — then reruns end-to-end and reads the trace to confirm.
43
+
44
+ ## How the agent reads the page
45
+
46
+ MCP commands are token efficient — they don't stream large HTML pages back to the model. MCP writes artifacts to disk under `output/trace_*/` and returns file paths. The agent reads each artifact with its own bash tools — `cat`, `grep`, `jq`.
47
+
48
+ A `run_code` response, for example, looks like this:
49
+
50
+ ```json
51
+ {
52
+ "status": "success",
53
+ "artifacts": {
54
+ "url": "http://localhost:8000/",
55
+ "html": "file:///output/trace_run_code_.../mcp_page.html",
56
+ "aria": "file:///output/trace_run_code_.../mcp_aria.txt",
57
+ "screenshot": "file:///output/trace_run_code_.../mcp_screenshot.png",
58
+ "console": "file:///output/trace_run_code_.../mcp_console.json",
59
+ "storage": "file:///output/trace_run_code_.../mcp_storage.json"
60
+ }
61
+ }
62
+ ```
63
+
64
+ Only `url` is inline. The rest are paths the agent opens with the right tool:
65
+
66
+ | Artifact | How the agent reads it |
67
+ |----------|------------------------|
68
+ | `*_screenshot.png` | As an image — most agents are multimodal |
69
+ | `*_aria.txt` | Whole — small and structured |
70
+ | `*_page.html` | With `grep` — too large for context, searchable for specific elements/attributes |
71
+ | `*_console.json` | With `jq` — filter for errors, 4xx/5xx, deprecation warnings |
72
+ | `*_storage.json` | Whole — cookies and `localStorage` snapshot |
73
+ | `trace.md` | Whole — markdown index linking every step to its artifacts |
74
+
75
+ Saved HTML is formatted, with non-semantic elements stripped out: `<style>`, `<script>`, Tailwind-style trash classes, and inline `style=""` attributes. `grep` can then effectively find the correct tree branch in raw page source. ARIA snapshots are smaller and more structured than HTML, which is why the agent prefers them when picking locators.
76
+
77
+ ## Setup
78
+
79
+ When CodeceptJS is installed, the MCP server can be launched with this command:
80
+
81
+ ```bash
82
+ npx codeceptjs-mcp
83
+ ```
84
+
85
+ > See [/mcp](/mcp) for detailed client setup.
86
+
87
+ We recommend pairing CodeceptJS MCP with the skills bundle.
88
+
89
+ Install for any agent:
90
+
91
+ ```bash
92
+ npx skills add codeceptjs/skills
93
+ ```
94
+
95
+ Or, in Claude Code:
96
+
97
+ ```text
98
+ /plugin marketplace add codeceptjs/skills
99
+ /plugin install codeceptjs@codeceptjs-skills
100
+ ```
101
+
102
+ ## Usage Examples
103
+
104
+ When MCP and skills are connected, the agent receives predefined workflows and can act effectively for testing purposes. Common scenarios it handles:
105
+
106
+ ### Writing a new test
107
+
108
+ You ask: "Add a test for the checkout flow."
109
+
110
+ The agent writes a stub:
111
+
112
+ ```javascript
113
+ Scenario('checkout', ({ I }) => {
114
+ I.amOnPage('/cart')
115
+ pause()
116
+ })
117
+ ```
118
+
119
+ It runs the stub. The browser opens at `/cart` and yields control at `pause()`. The agent reads the ARIA tree, runs `I.click('Add to cart')`, sees the cart total update — that line goes into the verified sequence. It runs `I.fillField('Email', '...')`, sees the field accept the value, records it. Through `I.click('Continue to payment')`, `I.see('Payment')`, `I.fillField('Card', secret(process.env.TEST_CARD))`, `I.click('Pay')`, `I.see('Order confirmed')` — each command commits only after the response confirms it worked.
120
+
121
+ When the scenario is whole, the agent edits the test file: replaces `pause()` with the verified sequence, renames the scenario, wraps credentials with `secret()`. It reruns the file end-to-end with `aiTrace` on and hands you the diff.
122
+
123
+ ### Fixing a failing test
124
+
125
+ A test fails. You point the agent at the scenario.
126
+
127
+ It opens `output/trace_<TestName>_*/trace.md` from the last run, reads the steps, and finds the one marked failed. Most of the time the screenshot and ARIA from that step explain the cause — "Save" is now "Save changes," or a spinner is gating the next action. The agent patches the line and reruns.
128
+
129
+ When the trace doesn't say enough, the agent passes a step number to `run_test` so the test pauses right before the failing step. From the live page, it tries `I.click({ role: 'button', name: 'Save changes' })`, sees the modal close. Or `I.waitForInvisible('.spinner', 10)` followed by the original click — watches it pass. Whatever holds goes into the test.
130
+
131
+ The fix lands with a one-line note explaining what changed.
132
+
133
+ ### Auto-fixing on CI
134
+
135
+ After a failed run, the agent reads every trace under `output/`, clusters failures by signature, and patches what fits a small set of safe fixes (locator drift, missing waits, raw `I.wait(N)` replacement). It reruns only the failing scenarios, compares against the baseline, and writes a markdown report at `output/ci-fix.md`.
136
+
137
+ If the fix held, the PR goes green. If it didn't, every edit is rolled back with `git checkout` and the report says which patterns the agent couldn't safely handle. No half-applied fixes left behind, no `retries: 3` masking the problem.
138
+
139
+ ## Skills bundle
140
+
141
+ Skills teach the agent best practices for using CodeceptJS. Plug them in when you develop tests with agents, and update them regularly to ensure you use CodeceptJS in the most effective way.
142
+
143
+ | Skill | Use case |
144
+ |-------|----------|
145
+ | `writing-codeceptjs-tests` | Author or extend a scenario. Runs the loop above with a stub-and-pause flow for greenfield work, incremental `run_code` for known flows. |
146
+ | `debugging-codeceptjs-tests` | A test is failing or flaky. Reads the trace, decides whether to patch from the trace alone or set a breakpoint on the live page. |
147
+ | `ci-fix-tests` | Conservative auto-repair on CI |
148
+ | `refactoring-codeceptjs-tests` | Extract page objects, tame long locators, move raw browser code into helpers. Proposes in batches. |
149
+ | `codeceptjs-fundamentals` | Obtain actual CodeceptJS knowledge. |
150
+ | `codeceptjs-exploration` | Pick a stable locator from messy markup. |
151
+ | `codeceptjs-run-analysis` | Read trace artifacts, cluster CI failures into root causes, verify a fix held across many traces. |
152
+ | `codeceptjs-auth` | Authorize efficiently with `auth` plugin. |
153
+
154
+ ## Pointers
155
+
156
+ - [/mcp](/mcp) — full MCP tool reference, client setup
157
+ - [/aitrace](/aitrace) — trace plugin configuration and capture options
158
+ - [/debugging](/debugging) — pause modes, IDE setup, the `pause` plugin
159
+ - [skills repo](https://github.com/codeceptjs/skills) — source and install for non-Claude clients