codeceptjs 4.0.0-rc.2 → 4.0.0-rc.20
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 +39 -27
- package/bin/codecept.js +15 -2
- package/bin/codeceptq.js +49 -0
- package/bin/mcp-server.js +1187 -0
- package/docs/advanced.md +201 -0
- package/docs/agents.md +159 -0
- package/docs/ai.md +537 -0
- package/docs/aitrace.md +266 -0
- package/docs/api.md +332 -0
- package/docs/assertions.md +415 -0
- package/docs/auth.md +318 -0
- package/docs/basics.md +424 -0
- package/docs/bdd.md +539 -0
- package/docs/best.md +240 -0
- package/docs/bootstrap.md +132 -0
- package/docs/commands.md +352 -0
- package/docs/community-helpers.md +63 -0
- package/docs/configuration.md +230 -0
- package/docs/continuous-integration.md +497 -0
- package/docs/custom-helpers.md +297 -0
- package/docs/data.md +448 -0
- package/docs/debugging.md +332 -0
- package/docs/detox.md +235 -0
- package/docs/docker.md +136 -0
- package/docs/effects.md +179 -0
- package/docs/element-based-testing.md +295 -0
- package/docs/element-selection.md +125 -0
- package/docs/els.md +328 -0
- package/docs/examples.md +161 -0
- package/docs/heal.md +213 -0
- package/docs/helpers/ApiDataFactory.md +267 -0
- package/docs/helpers/Appium.md +1405 -0
- package/docs/helpers/Detox.md +665 -0
- package/docs/helpers/ExpectHelper.md +275 -0
- package/docs/helpers/FileSystem.md +152 -0
- package/docs/helpers/GraphQL.md +152 -0
- package/docs/helpers/GraphQLDataFactory.md +226 -0
- package/docs/helpers/JSONResponse.md +255 -0
- package/docs/helpers/Mochawesome.md +8 -0
- package/docs/helpers/MockRequest.md +377 -0
- package/docs/helpers/MockServer.md +212 -0
- package/docs/helpers/Playwright.md +2969 -0
- package/docs/helpers/Polly.md +44 -0
- package/docs/helpers/Protractor.md +1769 -0
- package/docs/helpers/Puppeteer-firefox.md +86 -0
- package/docs/helpers/Puppeteer.md +2690 -0
- package/docs/helpers/REST.md +289 -0
- package/docs/helpers/SoftExpectHelper.md +352 -0
- package/docs/helpers/WebDriver.md +2682 -0
- package/docs/hooks.md +339 -0
- package/docs/index.md +111 -0
- package/docs/installation.md +83 -0
- package/docs/internal-api.md +265 -0
- package/docs/internal-test-server.md +89 -0
- package/docs/locators.md +355 -0
- package/docs/mcp.md +485 -0
- package/docs/migration-4.md +556 -0
- package/docs/mobile.md +338 -0
- package/docs/pageobjects.md +399 -0
- package/docs/parallel.md +585 -0
- package/docs/playwright.md +714 -0
- package/docs/plugins.md +866 -0
- package/docs/puppeteer.md +314 -0
- package/docs/quickstart.md +120 -0
- package/docs/react.md +70 -0
- package/docs/reports.md +483 -0
- package/docs/retry.md +274 -0
- package/docs/secrets.md +150 -0
- package/docs/sessions.md +80 -0
- package/docs/shadow.md +68 -0
- package/docs/test-structure.md +275 -0
- package/docs/timeouts.md +183 -0
- package/docs/translation.md +247 -0
- package/docs/tutorial.md +271 -0
- package/docs/typescript.md +374 -0
- package/docs/web-element.md +251 -0
- package/docs/webdriver.md +708 -0
- package/docs/within.md +55 -0
- package/lib/ai.js +3 -2
- package/lib/aria.js +260 -0
- package/lib/assertions.js +18 -0
- package/lib/codecept.js +26 -23
- package/lib/command/check.js +2 -1
- package/lib/command/dryRun.js +24 -5
- package/lib/command/generate.js +2 -0
- package/lib/command/gherkin/snippets.js +5 -4
- package/lib/command/init.js +248 -269
- package/lib/command/list.js +150 -10
- package/lib/command/query.js +218 -0
- package/lib/command/run-multiple.js +2 -0
- package/lib/command/run-workers.js +2 -0
- package/lib/command/run.js +1 -1
- package/lib/command/workers/runTests.js +10 -10
- package/lib/config.js +77 -4
- package/lib/container.js +114 -17
- package/lib/effects.js +17 -0
- package/lib/element/WebElement.js +246 -2
- package/lib/els.js +12 -6
- package/lib/globals.js +32 -19
- package/lib/heal.js +4 -3
- package/lib/helper/ApiDataFactory.js +2 -1
- package/lib/helper/Appium.js +8 -8
- package/lib/helper/FileSystem.js +3 -2
- package/lib/helper/GraphQLDataFactory.js +2 -1
- package/lib/helper/Playwright.js +228 -162
- package/lib/helper/Puppeteer.js +208 -76
- package/lib/helper/WebDriver.js +173 -68
- package/lib/helper/errors/MultipleElementsFound.js +27 -110
- package/lib/helper/errors/NonFocusedType.js +8 -0
- package/lib/helper/extras/Download.js +45 -0
- package/lib/helper/extras/PlaywrightReactVueLocator.js +45 -36
- package/lib/helper/extras/elementSelection.js +58 -0
- package/lib/helper/extras/focusCheck.js +43 -0
- package/lib/helper/extras/richTextEditor.js +178 -0
- package/lib/helper/scripts/dropFile.js +11 -0
- package/lib/history.js +3 -2
- package/lib/html.js +103 -16
- package/lib/index.js +9 -1
- package/lib/listener/config.js +6 -4
- package/lib/listener/emptyRun.js +2 -1
- package/lib/listener/globalRetry.js +32 -6
- package/lib/listener/helpers.js +4 -1
- package/lib/listener/mocha.js +2 -1
- package/lib/listener/pageobjects.js +43 -0
- package/lib/listener/result.js +3 -2
- package/lib/locator.js +126 -3
- package/lib/mocha/cli.js +14 -2
- package/lib/mocha/factory.js +7 -2
- package/lib/mocha/inject.js +1 -1
- package/lib/mocha/scenarioConfig.js +2 -1
- package/lib/mocha/ui.js +5 -6
- package/lib/parser.js +2 -2
- package/lib/pause.js +38 -4
- package/lib/plugin/aiTrace.js +453 -0
- package/lib/plugin/analyze.js +1 -1
- package/lib/plugin/auth.js +3 -3
- package/lib/plugin/browser.js +77 -0
- package/lib/plugin/expose.js +159 -0
- package/lib/plugin/heal.js +44 -1
- package/lib/plugin/pageInfo.js +53 -49
- package/lib/plugin/pause.js +131 -0
- package/lib/plugin/pauseOnFail.js +10 -34
- package/lib/plugin/retryFailedStep.js +28 -19
- package/lib/plugin/screencast.js +287 -0
- package/lib/plugin/screenshot.js +563 -0
- package/lib/plugin/screenshotOnFail.js +8 -171
- package/lib/rerun.js +2 -1
- package/lib/result.js +2 -1
- package/lib/step/base.js +3 -2
- package/lib/step/config.js +15 -2
- package/lib/step/record.js +2 -2
- package/lib/store.js +72 -3
- package/lib/translation.js +2 -1
- package/lib/utils/mask_data.js +2 -1
- package/lib/utils/pluginParser.js +151 -0
- package/lib/utils/trace.js +297 -0
- package/lib/utils.js +77 -3
- package/lib/workers.js +52 -22
- package/package.json +19 -13
- package/typings/index.d.ts +19 -5
- package/docs/webapi/amOnPage.mustache +0 -11
- package/docs/webapi/appendField.mustache +0 -11
- package/docs/webapi/attachFile.mustache +0 -12
- package/docs/webapi/blur.mustache +0 -18
- package/docs/webapi/checkOption.mustache +0 -13
- package/docs/webapi/clearCookie.mustache +0 -9
- package/docs/webapi/clearField.mustache +0 -9
- package/docs/webapi/click.mustache +0 -29
- package/docs/webapi/clickLink.mustache +0 -8
- package/docs/webapi/closeCurrentTab.mustache +0 -7
- package/docs/webapi/closeOtherTabs.mustache +0 -8
- package/docs/webapi/dontSee.mustache +0 -11
- package/docs/webapi/dontSeeCheckboxIsChecked.mustache +0 -10
- package/docs/webapi/dontSeeCookie.mustache +0 -8
- package/docs/webapi/dontSeeCurrentPathEquals.mustache +0 -10
- package/docs/webapi/dontSeeCurrentUrlEquals.mustache +0 -10
- package/docs/webapi/dontSeeElement.mustache +0 -8
- package/docs/webapi/dontSeeElementInDOM.mustache +0 -8
- package/docs/webapi/dontSeeInCurrentUrl.mustache +0 -4
- package/docs/webapi/dontSeeInField.mustache +0 -11
- package/docs/webapi/dontSeeInSource.mustache +0 -8
- package/docs/webapi/dontSeeInTitle.mustache +0 -8
- package/docs/webapi/dontSeeTraffic.mustache +0 -13
- package/docs/webapi/doubleClick.mustache +0 -13
- package/docs/webapi/downloadFile.mustache +0 -12
- package/docs/webapi/dragAndDrop.mustache +0 -9
- package/docs/webapi/dragSlider.mustache +0 -11
- package/docs/webapi/executeAsyncScript.mustache +0 -24
- package/docs/webapi/executeScript.mustache +0 -26
- package/docs/webapi/fillField.mustache +0 -16
- package/docs/webapi/flushNetworkTraffics.mustache +0 -5
- package/docs/webapi/focus.mustache +0 -13
- package/docs/webapi/forceClick.mustache +0 -28
- package/docs/webapi/forceRightClick.mustache +0 -18
- package/docs/webapi/grabAllWindowHandles.mustache +0 -7
- package/docs/webapi/grabAttributeFrom.mustache +0 -10
- package/docs/webapi/grabAttributeFromAll.mustache +0 -9
- package/docs/webapi/grabBrowserLogs.mustache +0 -9
- package/docs/webapi/grabCookie.mustache +0 -11
- package/docs/webapi/grabCssPropertyFrom.mustache +0 -11
- package/docs/webapi/grabCssPropertyFromAll.mustache +0 -10
- package/docs/webapi/grabCurrentUrl.mustache +0 -9
- package/docs/webapi/grabCurrentWindowHandle.mustache +0 -6
- package/docs/webapi/grabDataFromPerformanceTiming.mustache +0 -20
- package/docs/webapi/grabElementBoundingRect.mustache +0 -20
- package/docs/webapi/grabGeoLocation.mustache +0 -8
- package/docs/webapi/grabHTMLFrom.mustache +0 -10
- package/docs/webapi/grabHTMLFromAll.mustache +0 -9
- package/docs/webapi/grabNumberOfOpenTabs.mustache +0 -8
- package/docs/webapi/grabNumberOfVisibleElements.mustache +0 -9
- package/docs/webapi/grabPageScrollPosition.mustache +0 -8
- package/docs/webapi/grabPopupText.mustache +0 -5
- package/docs/webapi/grabRecordedNetworkTraffics.mustache +0 -10
- package/docs/webapi/grabSource.mustache +0 -8
- package/docs/webapi/grabTextFrom.mustache +0 -10
- package/docs/webapi/grabTextFromAll.mustache +0 -9
- package/docs/webapi/grabTitle.mustache +0 -8
- package/docs/webapi/grabValueFrom.mustache +0 -9
- package/docs/webapi/grabValueFromAll.mustache +0 -8
- package/docs/webapi/grabWebElement.mustache +0 -9
- package/docs/webapi/grabWebElements.mustache +0 -9
- package/docs/webapi/moveCursorTo.mustache +0 -12
- package/docs/webapi/openNewTab.mustache +0 -7
- package/docs/webapi/pressKey.mustache +0 -12
- package/docs/webapi/pressKeyDown.mustache +0 -12
- package/docs/webapi/pressKeyUp.mustache +0 -12
- package/docs/webapi/pressKeyWithKeyNormalization.mustache +0 -60
- package/docs/webapi/refreshPage.mustache +0 -6
- package/docs/webapi/resizeWindow.mustache +0 -6
- package/docs/webapi/rightClick.mustache +0 -14
- package/docs/webapi/saveElementScreenshot.mustache +0 -10
- package/docs/webapi/saveScreenshot.mustache +0 -12
- package/docs/webapi/say.mustache +0 -10
- package/docs/webapi/scrollIntoView.mustache +0 -11
- package/docs/webapi/scrollPageToBottom.mustache +0 -6
- package/docs/webapi/scrollPageToTop.mustache +0 -6
- package/docs/webapi/scrollTo.mustache +0 -12
- package/docs/webapi/see.mustache +0 -11
- package/docs/webapi/seeAttributesOnElements.mustache +0 -9
- package/docs/webapi/seeCheckboxIsChecked.mustache +0 -10
- package/docs/webapi/seeCookie.mustache +0 -8
- package/docs/webapi/seeCssPropertiesOnElements.mustache +0 -9
- package/docs/webapi/seeCurrentPathEquals.mustache +0 -10
- package/docs/webapi/seeCurrentUrlEquals.mustache +0 -11
- package/docs/webapi/seeElement.mustache +0 -8
- package/docs/webapi/seeElementInDOM.mustache +0 -8
- package/docs/webapi/seeInCurrentUrl.mustache +0 -8
- package/docs/webapi/seeInField.mustache +0 -12
- package/docs/webapi/seeInPopup.mustache +0 -8
- package/docs/webapi/seeInSource.mustache +0 -7
- package/docs/webapi/seeInTitle.mustache +0 -8
- package/docs/webapi/seeNumberOfElements.mustache +0 -11
- package/docs/webapi/seeNumberOfVisibleElements.mustache +0 -10
- package/docs/webapi/seeTextEquals.mustache +0 -9
- package/docs/webapi/seeTitleEquals.mustache +0 -8
- package/docs/webapi/seeTraffic.mustache +0 -36
- package/docs/webapi/selectOption.mustache +0 -21
- package/docs/webapi/setCookie.mustache +0 -16
- package/docs/webapi/setGeoLocation.mustache +0 -12
- package/docs/webapi/startRecordingTraffic.mustache +0 -8
- package/docs/webapi/startRecordingWebSocketMessages.mustache +0 -8
- package/docs/webapi/stopRecordingTraffic.mustache +0 -5
- package/docs/webapi/stopRecordingWebSocketMessages.mustache +0 -7
- package/docs/webapi/switchTo.mustache +0 -9
- package/docs/webapi/switchToNextTab.mustache +0 -10
- package/docs/webapi/switchToPreviousTab.mustache +0 -10
- package/docs/webapi/type.mustache +0 -21
- package/docs/webapi/uncheckOption.mustache +0 -13
- package/docs/webapi/wait.mustache +0 -8
- package/docs/webapi/waitForClickable.mustache +0 -11
- package/docs/webapi/waitForCookie.mustache +0 -9
- package/docs/webapi/waitForDetached.mustache +0 -10
- package/docs/webapi/waitForDisabled.mustache +0 -6
- package/docs/webapi/waitForElement.mustache +0 -11
- package/docs/webapi/waitForEnabled.mustache +0 -6
- package/docs/webapi/waitForFunction.mustache +0 -17
- package/docs/webapi/waitForInvisible.mustache +0 -10
- package/docs/webapi/waitForNumberOfTabs.mustache +0 -9
- package/docs/webapi/waitForText.mustache +0 -13
- package/docs/webapi/waitForValue.mustache +0 -10
- package/docs/webapi/waitForVisible.mustache +0 -10
- package/docs/webapi/waitInUrl.mustache +0 -9
- package/docs/webapi/waitNumberOfVisibleElements.mustache +0 -10
- package/docs/webapi/waitToHide.mustache +0 -10
- package/docs/webapi/waitUrlEquals.mustache +0 -10
- package/lib/helper/AI.js +0 -214
- package/lib/listener/enhancedGlobalRetry.js +0 -110
- package/lib/plugin/enhancedRetryFailedStep.js +0 -99
- package/lib/plugin/htmlReporter.js +0 -3648
- package/lib/plugin/stepByStepReport.js +0 -427
- package/lib/plugin/subtitles.js +0 -89
- package/lib/retryCoordinator.js +0 -207
- package/typings/promiseBasedTypes.d.ts +0 -9469
- package/typings/types.d.ts +0 -11402
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
---
|
|
2
|
+
permalink: /test-structure
|
|
3
|
+
title: Test Structure
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Test Structure
|
|
7
|
+
|
|
8
|
+
A CodeceptJS test file contains one **Feature** (suite) and one or more **Scenarios** (tests).
|
|
9
|
+
|
|
10
|
+
```js
|
|
11
|
+
Feature('User Authentication')
|
|
12
|
+
|
|
13
|
+
Scenario('user logs in', ({ I }) => {
|
|
14
|
+
I.amOnPage('/login')
|
|
15
|
+
I.fillField('Email', 'user@example.com')
|
|
16
|
+
I.fillField('Password', secret('123456'))
|
|
17
|
+
I.click('Sign In')
|
|
18
|
+
I.see('Welcome')
|
|
19
|
+
})
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Feature
|
|
23
|
+
|
|
24
|
+
`Feature(title, config?)` declares a suite. Each test file contains exactly one Feature.
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
Feature('User Authentication')
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
An optional config object sets defaults for all scenarios:
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
Feature('Payment Processing', {
|
|
34
|
+
retries: 2,
|
|
35
|
+
timeout: 30000
|
|
36
|
+
})
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Available options:
|
|
40
|
+
|
|
41
|
+
- `retries` — number of times to retry failed scenarios before marking as failed (see [Retry Mechanisms](/retry))
|
|
42
|
+
- `timeout` — maximum time in milliseconds for each scenario to complete (see [Timeouts](/advanced#timeout))
|
|
43
|
+
- `retryBefore` — number of times to retry the Before hook if it fails
|
|
44
|
+
- `retryAfter` — number of times to retry the After hook if it fails
|
|
45
|
+
- `retryBeforeSuite` — number of times to retry the BeforeSuite hook if it fails
|
|
46
|
+
- `retryAfterSuite` — number of times to retry the AfterSuite hook if it fails
|
|
47
|
+
|
|
48
|
+
> Unlike Mocha/Jest, nesting suites is not allowed — each file maps to exactly one feature.
|
|
49
|
+
|
|
50
|
+
## Scenario
|
|
51
|
+
|
|
52
|
+
`Scenario(title, config?, fn)` declares a test. The function receives an object with `I` (the actor), `test` object, and any page objects declared in `include` config:
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
Scenario('guest checkout', ({ I, checkoutPage }) => {
|
|
56
|
+
checkoutPage.open()
|
|
57
|
+
I.see('Order Summary')
|
|
58
|
+
})
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Access the `test` object to store metadata and artifacts for custom reporting:
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
Scenario('payment processing', ({ I, test }) => {
|
|
65
|
+
test.meta.transactionId = '12345'
|
|
66
|
+
test.artifacts.receipt = 'receipts/order-12345.pdf'
|
|
67
|
+
I.amOnPage('/checkout')
|
|
68
|
+
})
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Available properties:
|
|
72
|
+
|
|
73
|
+
- `test.title` — test name
|
|
74
|
+
- `test.tags` — extracted tags from test name (e.g., `@smoke`, `@critical`)
|
|
75
|
+
- `test.steps` — array of executed steps
|
|
76
|
+
- `test.artifacts` — store screenshots, videos, logs, or files
|
|
77
|
+
- `test.meta` — custom metadata for reporters
|
|
78
|
+
- `test.notes` — array for adding notes or annotations
|
|
79
|
+
- `test.file` — path to test file
|
|
80
|
+
- `test.state` — current state (pending, passed, failed)
|
|
81
|
+
- `test.duration` — execution time in milliseconds
|
|
82
|
+
- `test.fullTitle()` — full title including suite name
|
|
83
|
+
|
|
84
|
+
An optional config object can customize the scenario:
|
|
85
|
+
|
|
86
|
+
```js
|
|
87
|
+
Scenario('slow test', {
|
|
88
|
+
timeout: 60000,
|
|
89
|
+
retries: 3
|
|
90
|
+
}, ({ I }) => {
|
|
91
|
+
// ...
|
|
92
|
+
})
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Available options:
|
|
96
|
+
|
|
97
|
+
- `timeout` — maximum time in milliseconds for scenario to complete (see [Timeouts](/timeouts))
|
|
98
|
+
- `retries` — number of times to retry the scenario if it fails (see [Retry Mechanisms](/retry))
|
|
99
|
+
- `meta` — metadata object with key-value pairs for reporting or filtering
|
|
100
|
+
- `[helperName]` — helper-specific configuration (e.g., `Playwright: { headless: false }`)
|
|
101
|
+
- `cookies` — pre-loaded cookies for authentication (used by auth plugin)
|
|
102
|
+
- `user` — user identifier for session management (used by auth plugin)
|
|
103
|
+
- `disableRetryFailedStep` — disable automatic step retries for this scenario
|
|
104
|
+
|
|
105
|
+
### Dynamic Configuration
|
|
106
|
+
|
|
107
|
+
Override helper config for a single scenario using `.config()`:
|
|
108
|
+
|
|
109
|
+
```js
|
|
110
|
+
Scenario('run in firefox', ({ I }) => {
|
|
111
|
+
// ...
|
|
112
|
+
}).config({ browser: 'firefox' })
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
To target a specific helper, pass its name as the first argument:
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
Scenario('use v2 API', ({ I }) => {
|
|
119
|
+
// ...
|
|
120
|
+
}).config('REST', { endpoint: 'https://api.mysite.com/v2' })
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Pass a function to derive config from the test object — useful for cloud providers:
|
|
124
|
+
|
|
125
|
+
```js
|
|
126
|
+
Scenario('report to BrowserStack', ({ I }) => {
|
|
127
|
+
// ...
|
|
128
|
+
}).config((test) => ({
|
|
129
|
+
desiredCapabilities: {
|
|
130
|
+
project: test.suite.title,
|
|
131
|
+
name: test.title,
|
|
132
|
+
}
|
|
133
|
+
}))
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Apply config to all scenarios in a suite via `Feature`:
|
|
137
|
+
|
|
138
|
+
```js
|
|
139
|
+
Feature('Admin Panel').config({ url: 'https://mysite.com/admin' })
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Config changes are reverted after the test or suite completes. Some options — such as `browser` when `restart: false` — cannot be changed after the browser has started.
|
|
143
|
+
|
|
144
|
+
### Data-Driven Scenarios
|
|
145
|
+
|
|
146
|
+
Use `Data().Scenario` to run the same scenario with multiple datasets:
|
|
147
|
+
|
|
148
|
+
```js
|
|
149
|
+
const users = new DataTable(['role', 'email'])
|
|
150
|
+
users.add(['admin', 'admin@example.com'])
|
|
151
|
+
users.add(['user', 'user@example.com'])
|
|
152
|
+
|
|
153
|
+
Data(users).Scenario('user can log in', ({ I, current }) => {
|
|
154
|
+
I.fillField('Email', current.email)
|
|
155
|
+
I.click('Login')
|
|
156
|
+
I.see(`Logged in as ${current.role}`)
|
|
157
|
+
})
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
> ▶ See [Data Driven Tests](/data) for more details.
|
|
161
|
+
|
|
162
|
+
### Tags
|
|
163
|
+
|
|
164
|
+
Append a tag to the scenario title:
|
|
165
|
+
|
|
166
|
+
```js
|
|
167
|
+
Scenario('update user profile @slow', ...)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Or use the `tag()` method:
|
|
171
|
+
|
|
172
|
+
```js
|
|
173
|
+
Scenario('update user profile', ({ I }) => {
|
|
174
|
+
// ...
|
|
175
|
+
}).tag('@slow').tag('important')
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Run tagged tests with `--grep`:
|
|
179
|
+
|
|
180
|
+
```sh
|
|
181
|
+
npx codeceptjs run --grep '@slow'
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Use regex for complex filtering:
|
|
185
|
+
|
|
186
|
+
```sh
|
|
187
|
+
# both @smoke2 and @smoke3
|
|
188
|
+
npx codeceptjs run --grep '(?=.*@smoke2)(?=.*@smoke3)'
|
|
189
|
+
# @smoke2 or @smoke3
|
|
190
|
+
npx codeceptjs run --grep '@smoke2|@smoke3'
|
|
191
|
+
# all except @smoke4
|
|
192
|
+
npx codeceptjs run --grep '(?=.*)^(?!.*@smoke4)'
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Skipping & Focusing
|
|
196
|
+
|
|
197
|
+
```js
|
|
198
|
+
xScenario('skipped test', ...) // skip
|
|
199
|
+
Scenario.skip('skipped test', ...) // skip
|
|
200
|
+
Scenario.only('focused test', ...) // run only this test
|
|
201
|
+
|
|
202
|
+
xFeature('Skipped Suite') // skip entire file
|
|
203
|
+
Feature.skip('Skipped Suite') // skip entire file
|
|
204
|
+
Feature.only('Run Only This Suite') // focus entire file
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Todo Scenarios
|
|
208
|
+
|
|
209
|
+
Mark scenarios as planned but not yet implemented:
|
|
210
|
+
|
|
211
|
+
```js
|
|
212
|
+
Scenario.todo('user can reset password')
|
|
213
|
+
|
|
214
|
+
Scenario.todo('user can change avatar', ({ I }) => {
|
|
215
|
+
/**
|
|
216
|
+
* 1. Open profile settings
|
|
217
|
+
* 2. Upload new avatar
|
|
218
|
+
* Result: avatar is updated
|
|
219
|
+
*/
|
|
220
|
+
})
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Hooks
|
|
224
|
+
|
|
225
|
+
### Before / After
|
|
226
|
+
|
|
227
|
+
Run code before or after **each scenario** in the file:
|
|
228
|
+
|
|
229
|
+
```js
|
|
230
|
+
Before(({ I }) => {
|
|
231
|
+
I.amOnPage('/')
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
After(({ I }) => {
|
|
235
|
+
I.clearCookie()
|
|
236
|
+
})
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
These are equivalent to `beforeEach` / `afterEach` in Mocha/Jest.
|
|
240
|
+
|
|
241
|
+
Hooks can be retried on failure:
|
|
242
|
+
|
|
243
|
+
```js
|
|
244
|
+
Before(({ I }) => {
|
|
245
|
+
I.amOnPage('/dashboard')
|
|
246
|
+
}).retry(3)
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### BeforeSuite / AfterSuite
|
|
250
|
+
|
|
251
|
+
Run code once before or after **all scenarios** in the file — equivalent to `beforeAll` / `afterAll`:
|
|
252
|
+
|
|
253
|
+
```js
|
|
254
|
+
BeforeSuite(async ({ I }) => {
|
|
255
|
+
// seed test data before any scenario runs
|
|
256
|
+
await I.executeScript(() => window.resetDatabase())
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
AfterSuite(async ({ I }) => {
|
|
260
|
+
await I.executeScript(() => window.cleanupDatabase())
|
|
261
|
+
})
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
> **Note:** The browser is available in `BeforeSuite` when using Playwright or Puppeteer helpers.
|
|
265
|
+
|
|
266
|
+
Hooks can also be configured at Feature level:
|
|
267
|
+
|
|
268
|
+
```js
|
|
269
|
+
Feature('My Suite', {
|
|
270
|
+
retryBefore: 3,
|
|
271
|
+
retryBeforeSuite: 2,
|
|
272
|
+
retryAfter: 1,
|
|
273
|
+
retryAfterSuite: 3,
|
|
274
|
+
})
|
|
275
|
+
```
|
package/docs/timeouts.md
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
---
|
|
2
|
+
permalink: /timeouts
|
|
3
|
+
title: Timeouts
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Timeouts
|
|
7
|
+
|
|
8
|
+
CodeceptJS provides multiple timeout configurations to control test execution time at different levels.
|
|
9
|
+
|
|
10
|
+
## Step Timeout
|
|
11
|
+
|
|
12
|
+
Set timeout for individual steps using `step.timeout()`:
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
import step from 'codeceptjs/steps'
|
|
16
|
+
|
|
17
|
+
Scenario('test with step timeouts', ({ I }) => {
|
|
18
|
+
I.amOnPage('/')
|
|
19
|
+
I.click('Slow Button', step.timeout(30))
|
|
20
|
+
I.fillField('Email', 'user@example.com', step.timeout(10))
|
|
21
|
+
})
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Scenario Timeout
|
|
25
|
+
|
|
26
|
+
Override timeout for specific scenarios:
|
|
27
|
+
|
|
28
|
+
```js
|
|
29
|
+
Scenario('quick test', { timeout: 5 }, ({ I }) => {
|
|
30
|
+
I.amOnPage('/')
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
Scenario('slow test', { timeout: 120 }, ({ I }) => {
|
|
34
|
+
I.amOnPage('/dashboard')
|
|
35
|
+
})
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Feature Timeout
|
|
39
|
+
|
|
40
|
+
Set timeout for all scenarios in a feature:
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
Feature('Slow Operations', { timeout: 60 })
|
|
44
|
+
|
|
45
|
+
Scenario('first test', ({ I }) => {
|
|
46
|
+
// has 60 second timeout
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
Scenario('second test', ({ I }) => {
|
|
50
|
+
// has 60 second timeout
|
|
51
|
+
})
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Global Timeout
|
|
55
|
+
|
|
56
|
+
Set default timeout for all tests in `codecept.conf.js`:
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
export const config = {
|
|
60
|
+
timeout: 10 // 10 seconds for all tests
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Use advanced configuration with grep patterns for conditional timeouts:
|
|
65
|
+
|
|
66
|
+
```js
|
|
67
|
+
export const config = {
|
|
68
|
+
timeout: [
|
|
69
|
+
10, // default timeout
|
|
70
|
+
{
|
|
71
|
+
grep: '@slow',
|
|
72
|
+
Feature: 60 // 60 seconds for features tagged @slow
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
grep: /critical/,
|
|
76
|
+
Scenario: 30 // 30 seconds for scenarios matching pattern
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Helper Timeouts
|
|
83
|
+
|
|
84
|
+
Each helper (Playwright, Puppeteer, WebDriver, Appium, REST) has its own timeout settings for browser actions, API requests, and element interactions. These are configured separately from test timeouts and are measured in milliseconds.
|
|
85
|
+
|
|
86
|
+
Refer to helper-specific documentation for timeout configuration:
|
|
87
|
+
|
|
88
|
+
- [Playwright Helper](/helpers/Playwright) — `timeout`, `waitForTimeout`, `getPageTimeout`
|
|
89
|
+
- [Puppeteer Helper](/helpers/Puppeteer) — `waitForTimeout`, `getPageTimeout`
|
|
90
|
+
- [WebDriver Helper](/helpers/WebDriver) — `waitForTimeout`, `smartWait`, `timeouts` object
|
|
91
|
+
- [Appium Helper](/helpers/Appium) — `timeouts` object
|
|
92
|
+
- [REST Helper](/helpers/REST) — `timeout`
|
|
93
|
+
|
|
94
|
+
## stepTimeout Plugin
|
|
95
|
+
|
|
96
|
+
Automatically apply timeouts to all steps:
|
|
97
|
+
|
|
98
|
+
```js
|
|
99
|
+
plugins: {
|
|
100
|
+
stepTimeout: {
|
|
101
|
+
enabled: true,
|
|
102
|
+
timeout: 150, // default step timeout in seconds
|
|
103
|
+
overrideStepLimits: false, // override step.timeout() if true
|
|
104
|
+
noTimeoutSteps: [
|
|
105
|
+
'amOnPage',
|
|
106
|
+
'wait*' // wildcard patterns supported
|
|
107
|
+
],
|
|
108
|
+
customTimeoutSteps: [
|
|
109
|
+
['slowAction*', 30], // 30 seconds for matching steps
|
|
110
|
+
[/critical.*/, 60] // regex patterns supported
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Timeout Priority
|
|
117
|
+
|
|
118
|
+
When multiple timeouts are configured, CodeceptJS applies them in priority order:
|
|
119
|
+
|
|
120
|
+
1. **stepTimeoutHard** — plugin with `overrideStepLimits: true`
|
|
121
|
+
2. **codeLimitTime** — `step.timeout()` or `I.limitTime()`
|
|
122
|
+
3. **stepTimeoutSoft** — plugin with `overrideStepLimits: false`
|
|
123
|
+
4. **testOrSuite** — global test/suite timeout
|
|
124
|
+
|
|
125
|
+
Higher priority timeouts override lower priority ones.
|
|
126
|
+
|
|
127
|
+
## Disabling Timeouts
|
|
128
|
+
|
|
129
|
+
Disable all timeouts for debugging:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
npx codeceptjs run --no-timeouts
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Complete Example
|
|
136
|
+
|
|
137
|
+
```js
|
|
138
|
+
// codecept.conf.js
|
|
139
|
+
export const config = {
|
|
140
|
+
timeout: [
|
|
141
|
+
10,
|
|
142
|
+
{ grep: '@slow', Feature: 60 },
|
|
143
|
+
{ grep: '@critical', Scenario: 30 }
|
|
144
|
+
],
|
|
145
|
+
|
|
146
|
+
helpers: {
|
|
147
|
+
Playwright: {
|
|
148
|
+
timeout: 5000,
|
|
149
|
+
waitForTimeout: 1000,
|
|
150
|
+
getPageTimeout: 30000
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
plugins: {
|
|
155
|
+
stepTimeout: {
|
|
156
|
+
enabled: true,
|
|
157
|
+
timeout: 150,
|
|
158
|
+
noTimeoutSteps: ['amOnPage', 'wait*'],
|
|
159
|
+
customTimeoutSteps: [
|
|
160
|
+
['slowAction*', 30]
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
```js
|
|
168
|
+
// test file
|
|
169
|
+
import step from 'codeceptjs/steps'
|
|
170
|
+
|
|
171
|
+
Feature('User Management @slow', { timeout: 60 })
|
|
172
|
+
|
|
173
|
+
Scenario('create user', { timeout: 20 }, ({ I }) => {
|
|
174
|
+
I.amOnPage('/users')
|
|
175
|
+
I.click('Create', step.timeout(10))
|
|
176
|
+
I.fillField('Name', 'John', step.timeout(5).retry(2))
|
|
177
|
+
})
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Timeout Units
|
|
181
|
+
|
|
182
|
+
- **Global, Feature, Scenario, Step, stepTimeout plugin** — seconds
|
|
183
|
+
- **Helper timeouts** — milliseconds
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
---
|
|
2
|
+
permalink: /translation
|
|
3
|
+
title: Translation
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Translation
|
|
7
|
+
|
|
8
|
+
*Unique feature of CodeceptJS: write tests in your language!*
|
|
9
|
+
|
|
10
|
+
🇩🇪🇯🇵🇫🇷🇹🇼🇨🇳🇵🇱🇧🇷🇮🇹
|
|
11
|
+
|
|
12
|
+
Test output and the way tests are written can be localized. This way scenarios can be written in almost native language using UTF support of JavaScript.
|
|
13
|
+
|
|
14
|
+
If you have non-English team and you work on non-English project consider enabling translation
|
|
15
|
+
by setting translation to [one of available languages](https://github.com/codeceptjs/CodeceptJS/blob/3.x/translations) or writing vocabulary for your language.
|
|
16
|
+
|
|
17
|
+
## How it works
|
|
18
|
+
|
|
19
|
+
CodceptJS provides a high-level domain specific language (DSL) for writing end-to-end tests.
|
|
20
|
+
As CodeceptJS API is designed to provide a minimal set of methods to write test cases of any kind of complexity.
|
|
21
|
+
|
|
22
|
+
It is possible to add aliases for all CodeceptJS keywords and methods. So if all keywords and methods are translated to a specific language it is possible to write tests in that language. Sure, this is not perfect, as CSS/XPath locators as well as REST API speific words are used as is. However, writing tests in your native language may improve the team's understanding of the test behavior.
|
|
23
|
+
|
|
24
|
+
You can enable translation if your team is not from English-speaking country developing non-English product.
|
|
25
|
+
|
|
26
|
+
> ⚠️ It's important to note that default translations are far from being complete. So there are still lots of methods and keywords not translated to your language yet. We recommend to [extend a vocabulary](#extending-vocabulary) to add aliases for non-translated methods and submit a pull request with improvements to a [corresponding language file](https://github.com/codeceptjs/CodeceptJS/blob/3.x/translations).
|
|
27
|
+
|
|
28
|
+
To enable translition create a new project with
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
npx codeceptjs init
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
And select a language of your choice from a list:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
? Do you want localization for tests? (See https://codecept.io/translation/)
|
|
38
|
+
❯ English (no localization)
|
|
39
|
+
de-DE
|
|
40
|
+
it-IT
|
|
41
|
+
fr-FR
|
|
42
|
+
ja-JP
|
|
43
|
+
pl-PL
|
|
44
|
+
pt-BR
|
|
45
|
+
(Move up and down to reveal more choices)
|
|
46
|
+
```
|
|
47
|
+
> 💡 If you don't see your language in the list but still want to use localized tests, select 'English (no localization)' and create [custom translation](#custom-translation).
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
## Languages
|
|
51
|
+
|
|
52
|
+
### Portuguese 🇧🇷
|
|
53
|
+
|
|
54
|
+
To write your tests in portuguese you can enable the portuguese translation in config file like:
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
translation: "pt-BR"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Now you can write test like this:
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
Cenário('Efetuar login', ({ Eu }) => {
|
|
64
|
+
Eu.estouNaPagina('http://minhaAplicacao.com.br');
|
|
65
|
+
Eu.preenchoOCampo("login", "usuario@minhaAplicacao.com.br");
|
|
66
|
+
Eu.preenchoOCampo("senha", "123456");
|
|
67
|
+
Eu.clico("Entrar");
|
|
68
|
+
Eu.vejo("Seja bem vindo usuário!");
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### French 🇫🇷
|
|
73
|
+
|
|
74
|
+
To write your tests in French you can enable the French translation by adding to config:
|
|
75
|
+
|
|
76
|
+
```js
|
|
77
|
+
translation: "fr-FR"
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Now you can write tests like this:
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
Scenario('Se connecter sur GitHub', (Je) => {
|
|
84
|
+
Je.suisSurLaPage('https://github.com/login');
|
|
85
|
+
Je.remplisLeChamp("Username or email address", "jean-dupond");
|
|
86
|
+
Je.remplisLeChamp("Password", "*********");
|
|
87
|
+
Je.cliqueSur("Sign in");
|
|
88
|
+
Je.vois("Learn Git and GitHub without any code!");
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Italian 🇮🇹
|
|
93
|
+
|
|
94
|
+
Add to `codeceptjs.conf.js` or `codeceptjs.conf.ts` config file:
|
|
95
|
+
|
|
96
|
+
```js
|
|
97
|
+
translation: "it-IT"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Now you can write test like this:
|
|
101
|
+
|
|
102
|
+
```js
|
|
103
|
+
Caratteristica('Effettuare il Login su GitHub', (io) => {
|
|
104
|
+
io.sono_sulla_pagina('https://github.com/login');
|
|
105
|
+
io.compilo_il_campo("Username or email address", "giuseppe-santoro");
|
|
106
|
+
io.compilo_il_campo("Password", "*********");
|
|
107
|
+
io.faccio_click_su("Sign in");
|
|
108
|
+
io.vedo("Learn Git and GitHub without any code!");
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Polish 🇵🇱
|
|
113
|
+
|
|
114
|
+
Add to `codeceptjs.conf.js` or `codeceptjs.conf.ts` config file:
|
|
115
|
+
|
|
116
|
+
```js
|
|
117
|
+
translation: "pl-PL"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Now you can write test like this:
|
|
121
|
+
|
|
122
|
+
```js
|
|
123
|
+
Scenario('Zakładanie konta free trial na stronie głównej GetResponse', ({ Ja }) => {
|
|
124
|
+
Ja.jestem_na_stronie('https://getresponse.com');
|
|
125
|
+
Ja.wypełniam_pole("Email address", "sjakubowski@getresponse.com");
|
|
126
|
+
Ja.wypełniam_pole("Password", "digital-marketing-systems");
|
|
127
|
+
Ja.klikam('Sign up');
|
|
128
|
+
Ja.czekam(1);
|
|
129
|
+
Ja.widzę_w_adresie_url('/account_free_created.html');
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Chinese 🇹🇼🇨🇳
|
|
134
|
+
|
|
135
|
+
Add to `codeceptjs.conf.js` or `codeceptjs.conf.ts` config: file:
|
|
136
|
+
|
|
137
|
+
```JS
|
|
138
|
+
translation: "zh-CN"
|
|
139
|
+
```
|
|
140
|
+
or
|
|
141
|
+
```JS
|
|
142
|
+
translation: "zh-TW"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
This way tests can be written in Chinese language while it is still JavaScript:
|
|
146
|
+
|
|
147
|
+
```JavaScript
|
|
148
|
+
Feature('CodeceptJS 演示');
|
|
149
|
+
|
|
150
|
+
Scenario('成功提交表单', ({ 我 }) => {
|
|
151
|
+
我.在页面('/documentation')
|
|
152
|
+
我.填写字段('电邮', 'hello@world.com')
|
|
153
|
+
我.填写字段('密码', '123456')
|
|
154
|
+
我.勾选选项('激活')
|
|
155
|
+
我.勾选选项('男');
|
|
156
|
+
我.单击('创建用户')
|
|
157
|
+
我.看到('用户名可用')
|
|
158
|
+
我.在当前网址中看不到('/documentation')
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
or
|
|
162
|
+
|
|
163
|
+
```JavaScript
|
|
164
|
+
Feature('CodeceptJS 演示');
|
|
165
|
+
|
|
166
|
+
Scenario('成功提交表單', ({ 我 }) => {
|
|
167
|
+
我.在頁面('/documentation')
|
|
168
|
+
我.填寫欄位('電郵', 'hello@world.com')
|
|
169
|
+
我.填寫欄位('密碼', '123456')
|
|
170
|
+
我.勾選選項('活化')
|
|
171
|
+
我.勾選選項('男');
|
|
172
|
+
我.單擊('建立用戶')
|
|
173
|
+
我.看到('用戶名可用')
|
|
174
|
+
我.在當前網址中看不到('/documentation')
|
|
175
|
+
});
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Japanese 🇯🇵
|
|
179
|
+
|
|
180
|
+
Add to `codeceptjs.conf.js` or `codeceptjs.conf.ts` config file:
|
|
181
|
+
|
|
182
|
+
```js
|
|
183
|
+
translation: "ja-JP"
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Now you can write test like this:
|
|
187
|
+
|
|
188
|
+
```js
|
|
189
|
+
Scenario('ログインできる', ({ 私は }) => {
|
|
190
|
+
私は.ページを移動する('/login');
|
|
191
|
+
私は.フィールドに入力する("Eメール", "foo@example.com");
|
|
192
|
+
私は.フィールドに入力する("パスワード", "p@ssword");
|
|
193
|
+
私は.クリックする('ログイン');
|
|
194
|
+
私は.待つ(1);
|
|
195
|
+
私は.URLに含まれるか確認する('/home');
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Extending Vocabulary
|
|
200
|
+
|
|
201
|
+
To add localized aliases to more actions create a new JSON or JavaScript file returning an object with following fields:
|
|
202
|
+
|
|
203
|
+
```js
|
|
204
|
+
export default {
|
|
205
|
+
actions: {
|
|
206
|
+
// add action aliases, translating method name to your language
|
|
207
|
+
rightClick: 'Rechtsklick'
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Then enable this vocabulary file in codecept conf:
|
|
213
|
+
|
|
214
|
+
```js
|
|
215
|
+
// inside codecept.conf.js or codecept.conf.ts
|
|
216
|
+
// ...
|
|
217
|
+
translation: 'de_DE',
|
|
218
|
+
vocabularies: ['my_translation_file.js'],
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Custom Translation
|
|
222
|
+
|
|
223
|
+
Create translation file like this:
|
|
224
|
+
|
|
225
|
+
```js
|
|
226
|
+
export default {
|
|
227
|
+
I: 'Ya',
|
|
228
|
+
contexts: {
|
|
229
|
+
Feature: 'Feature',
|
|
230
|
+
Scenario: 'Szenario',
|
|
231
|
+
Before: 'Vor',
|
|
232
|
+
After: 'Nach',
|
|
233
|
+
BeforeSuite: 'vor_der_suite',
|
|
234
|
+
AfterSuite: 'nach_der_suite',
|
|
235
|
+
},
|
|
236
|
+
actions: {
|
|
237
|
+
click: 'Klicken',
|
|
238
|
+
wait: 'Wartenn',
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
And add the file path to your config
|
|
243
|
+
|
|
244
|
+
```js
|
|
245
|
+
translation: "MyLang",
|
|
246
|
+
vocabularies: ["./relative/path/to/your/translation.js"]
|
|
247
|
+
```
|