codeceptjs 2.2.0 → 2.2.1

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 (44) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/README.md +15 -22
  3. package/bin/codecept.js +3 -1
  4. package/docs/advanced.md +1 -1
  5. package/docs/angular.md +6 -9
  6. package/docs/basics.md +388 -86
  7. package/docs/bdd.md +4 -3
  8. package/docs/build/Nightmare.js +3 -0
  9. package/docs/build/Polly.js +26 -12
  10. package/docs/build/Puppeteer.js +14 -13
  11. package/docs/build/TestCafe.js +101 -2
  12. package/docs/build/WebDriver.js +53 -52
  13. package/docs/changelog.md +86 -57
  14. package/docs/detox.md +235 -0
  15. package/docs/helpers/Detox.md +579 -0
  16. package/docs/helpers/Polly.md +13 -3
  17. package/docs/helpers/Puppeteer.md +155 -156
  18. package/docs/helpers/TestCafe.md +53 -0
  19. package/docs/helpers/WebDriver.md +209 -204
  20. package/docs/locators.md +2 -0
  21. package/docs/mobile.md +5 -1
  22. package/docs/puppeteer.md +59 -13
  23. package/docs/quickstart.md +47 -12
  24. package/docs/testcafe.md +157 -0
  25. package/docs/webdriver.md +453 -0
  26. package/lib/command/definitions.js +152 -7
  27. package/lib/command/gherkin/snippets.js +19 -8
  28. package/lib/command/init.js +30 -22
  29. package/lib/command/utils.js +1 -1
  30. package/lib/container.js +36 -10
  31. package/lib/data/dataScenarioConfig.js +18 -0
  32. package/lib/helper/Nightmare.js +3 -0
  33. package/lib/helper/Polly.js +26 -12
  34. package/lib/helper/Puppeteer.js +14 -13
  35. package/lib/helper/TestCafe.js +72 -2
  36. package/lib/helper/WebDriver.js +53 -52
  37. package/lib/helper/testcafe/testcafe-utils.js +3 -2
  38. package/lib/interfaces/scenarioConfig.js +2 -2
  39. package/lib/listener/config.js +2 -2
  40. package/lib/plugin/allure.js +3 -0
  41. package/lib/step.js +5 -2
  42. package/lib/ui.js +1 -1
  43. package/lib/utils.js +13 -21
  44. package/package.json +14 -12
package/docs/locators.md CHANGED
@@ -64,6 +64,8 @@ I.seeElement({ css: 'button' });
64
64
  I.seeElement({ xpath: 'descendant::table/tr' });
65
65
  ```
66
66
 
67
+ > ℹ Use [Locator Advicer](https://davertmik.github.io/locator/) to check quality of your locators.
68
+
67
69
  ## Semantic Locators
68
70
 
69
71
  CodeceptJS can guess an element's locator from context.
package/docs/mobile.md CHANGED
@@ -173,6 +173,8 @@ In both Android and iPhone elements are defined in XML format and can be searche
173
173
  I.seeElement('//android.widget.ScrollView/android.widget.LinearLayout')'
174
174
  ```
175
175
 
176
+ > Despite showing XPath in this guide we **do not recommend using XPath for testing iOS native apps. XPath runs very slow on iOS. Consider using ID or Accessibility ID locators instead.
177
+
176
178
  CSS locators are not supported in native mobile apps, you need to switch to web context to use them.
177
179
 
178
180
  Elements can also be located by their accessability id, available both at Android and iOS.
@@ -181,7 +183,9 @@ Accessibility id is recommended to use for locating element, as it rarely change
181
183
  * iOS uses [UIAccessibilityIdentification](https://developer.apple.com/documentation/uikit/uiaccessibilityidentification)
182
184
  * Android `accessibility id` matches the content-description
183
185
  * Web view uses `[aria-label]` attribute as accessibility id
184
- * ReactNative for Android has some caveats you could find more [here](mobile-react-native-locators.md)
186
+ * For [React Native for Android see our special guide](mobile-react-native-locators.md).
187
+
188
+ > If you test React Native application, consider using [Detox helper](/detox) for faster tests.
185
189
 
186
190
  Add `~` prefix to search for element by its accessibility id:
187
191
 
package/docs/puppeteer.md CHANGED
@@ -36,7 +36,7 @@ Or see [alternative installation options](http://codecept.io/installation/)
36
36
  And a basic project initialized
37
37
 
38
38
  ```sh
39
- codeceptjs init
39
+ npx codeceptjs init
40
40
  ```
41
41
 
42
42
  You will be asked for a Helper to use, you should select Puppeteer and provide url of a website you are testing.
@@ -52,14 +52,14 @@ Make sure `Puppeteer` helper is enabled in `codecept.conf.js` config:
52
52
  helpers: {
53
53
  Puppeteer: {
54
54
  url: "http://localhost",
55
- show: false
55
+ show: true
56
56
  }
57
57
  }
58
58
  // ..
59
59
  }
60
60
  ```
61
61
 
62
- Turn on the `show` option if you want to follow test progress in a window. This is very useful for debugging.
62
+ > Turn off the `show` option if you want to run test in headless mode.
63
63
 
64
64
  Puppeteer uses different strategies to detect if a page is loaded. In configuration use `waitForNavigation` option for that:
65
65
 
@@ -69,6 +69,7 @@ By default it is set to `domcontentloaded` which waits for `DOMContentLoaded` ev
69
69
  helpers: {
70
70
  Puppeteer: {
71
71
  url: "http://localhost",
72
+ show: true,
72
73
  waitForNavigation: "networkidle0"
73
74
  }
74
75
  }
@@ -77,14 +78,14 @@ By default it is set to `domcontentloaded` which waits for `DOMContentLoaded` ev
77
78
  When a test runs faster than application it is recommended to increase `waitForAction` config value.
78
79
  It will wait for a small amount of time (100ms) by default after each user action is taken.
79
80
 
80
- > More options are listed in [helper reference](http://codecept.io/helpers/Puppeteer/).
81
+ > More options are listed in [helper reference](http://codecept.io/helpers/Puppeteer/).
81
82
 
82
83
  ## Writing Tests
83
84
 
84
85
  CodeceptJS test should be created with `gt` command:
85
86
 
86
87
  ```sh
87
- codeceptjs gt
88
+ npx codeceptjs gt
88
89
  ```
89
90
 
90
91
  As an example we will use `ToDoMvc` app for testing.
@@ -102,7 +103,7 @@ Tests consist with a scenario of user's action taken on a page. The most widely
102
103
  * `see`, `dontSee` - to check for a text on a page
103
104
  * `seeElement`, `dontSeeElement` - to check for elements on a page
104
105
 
105
- *All actions are listed in [helper reference](http://codecept.io/helpers/Puppeteer/).*
106
+ > ℹ All actions are listed in [Puppeteer helper reference](http://codecept.io/helpers/Puppeteer/).*
106
107
 
107
108
  All actions which interact with elements **support CSS and XPath locators**. Actions like `click` or `fillField` by locate elements by their name or value on a page:
108
109
 
@@ -155,7 +156,7 @@ Scenario('get value of current tasks', async (I) => {
155
156
 
156
157
  ### Within
157
158
 
158
- In case some actions should be taken inside one element (a container or modal window) you can use `within` block to narrow the scope.
159
+ In case some actions should be taken inside one element (a container or modal window or iframe) you can use `within` block to narrow the scope.
159
160
  Please take a note that you can't use within inside another within in Puppeteer helper:
160
161
 
161
162
  ```js
@@ -167,15 +168,58 @@ within('.todoapp', () => {
167
168
  I.see('0 items left', '.todo-count');
168
169
  ```
169
170
 
171
+ > [▶ Learn more about basic commands](https://codecept.io/basics#writing-tests)
172
+
170
173
  CodeceptJS allows you to implement custom actions like `I.createTodo` or use **PageObjects**. Learn how to improve your tests in [PageObjects](http://codecept.io/pageobjects/) guide.
171
174
 
172
- `within` can also work with [iframes](/acceptance/#iframes)
175
+ > [▶ Demo project is available on GitHub](https://github.com/DavertMik/codeceptjs-todomvc-puppeteer)
176
+
177
+ ## Mocking Requests
178
+
179
+ Web application sends various requests to local services (Rest API, GraphQL) or to 3rd party services (CDNS, Google Analytics, etc).
180
+ When you run tests with Puppeteer you can control those requests by mocking them. For instance, you can speed up your tests by blocking trackers, Google Analytics, and other services you don't control.
173
181
 
174
- When running steps inside a within block will be shown with a shift.
182
+ Also you can replace real request with a one explicitly defined. This is useful when you want to isolate application testing from a backend. For instance, if you don't want to save data to database, and you know the request which performs save, you can mock the request, so application will treat this as valid response, but no data will be actually saved.
175
183
 
176
- ![within](https://codecept.io/img/within.png)
184
+ To mock requests enable additional helper [Polly](https://codecept.io/helpers/Polly) (which is based on Polly.js).
185
+
186
+ ```js
187
+ helpers: {
188
+ Puppeteer: {
189
+ // regular Puppeteer config here
190
+ },
191
+ Polly: {}
192
+ }
193
+ ```
194
+
195
+ And install additional packages:
196
+
197
+ ```
198
+ npm i @pollyjs/core @pollyjs/adapter-puppeteer --save-dev
199
+ ```
177
200
 
178
- > [Demo project is available on GitHub](https://github.com/DavertMik/codeceptjs-todomvc-puppeteer)
201
+ After an installation function `mockRequest` will be added to `I` object. You can use it to explicitly define which requests to block and which response they should return instead:
202
+
203
+ ```js
204
+ // block all Google Analytics calls
205
+ I.mockRequest('/google-analytics/*path', 200);
206
+ // return an empty successful response
207
+ I.mockRequest('GET', '/api/users', 200);
208
+ // block post requests to /api/users and return predefined object
209
+ I.mockRequest('POST', '/api/users', { user: 'davert' });
210
+ // return error request with body
211
+ I.mockRequest('GET', '/api/users/1', 404, { error: 'User not found' });
212
+ ```
213
+
214
+ > See [`mockRequest` API](https://codecept.io/helpers/Polly#mockrequest)
215
+
216
+ To see `mockRequest` method in intellisense auto completion don't forget to run `codeceptjs def` command:
217
+
218
+ ```
219
+ npx codeceptjs def
220
+ ```
221
+
222
+ Mocking rules will be kept while a test is running. To stop mocking use `I.stopMocking()` command
179
223
 
180
224
  ## Extending
181
225
 
@@ -184,7 +228,7 @@ Puppeteer has a very [rich and flexible API](https://github.com/GoogleChrome/pup
184
228
  Start with creating an `MyPuppeteer` helper using `generate:helper` or `gh` command:
185
229
 
186
230
  ```sh
187
- codeceptjs gh
231
+ npx codeceptjs gh
188
232
  ```
189
233
 
190
234
  Then inside a Helper you can access `Puppeteer` helper of CodeceptJS.
@@ -199,5 +243,7 @@ async renderPageToPdf() {
199
243
  }
200
244
  ```
201
245
 
202
- The same way you can also access `browser` object to implement more actions or handle events. [Learn more about Helpers](http://codecept.io/helpers/) in the corresponding guide.
246
+ The same way you can also access `browser` object to implement more actions or handle events.
247
+
248
+ > [▶ Learn more about Helpers](http://codecept.io/helpers/)
203
249
 
@@ -4,18 +4,42 @@ title: Quickstart
4
4
  ---
5
5
 
6
6
  **NodeJS v 8.9** and higher required to start.
7
- CodeceptJS is multi-backend testing framework. It can execute tests using different libraries like webdriverio, Puppeteer, Protractor, etc.
7
+ CodeceptJS is an end 2 end testing framework which supports multiple browser drivers like WebDriver, Puppeteer, Protractor, TestCafe etc.
8
8
 
9
- * In this guide we will use [Google Chrome **Puppeteer**](https://github.com/GoogleChrome/puppeteer) as a driver for browsers. This allows us to start in a minutes with no extra tools installed.
10
- * If you are familiar with Selenium, you can choose classical [**Selenium WebDriver** setup](#using-selenium-webdriver).
11
- * Also, look at [complete installation reference](https://codecept.io/installation/).
9
+ > **⬇️ TLDR [Fastest and simplest setup with Puppeteer and CodeceptJS](#using-puppeteer) ⬇️**
12
10
 
11
+ How to choose the right driver for your web application?
12
+ Here is a brief comparison of all tools you can use with CodeceptJS.
13
+
14
+
15
+ | Driver | Cross-Browser | Limitations | Headless | Selenuim | Speed |
16
+ |---|---|---|--|--|--|
17
+ | WebDriver | ✔️ | headers, downloads | ⁉ | ✔️ | normal |
18
+ | Puppeteer | chrome | cross-browser support | ✔️ | | fast |
19
+ | Protractor | ✔️ | headers, downloads | ⁉ | ✔️ | normal |
20
+ | TestCafe | ✔️ | multiple tabs | ✔️ | | fast |
21
+ | Nightmare | electron (chromium) | multiple tabs, cross-browser | ✔️ | | fast |
22
+
23
+ ⁉ - headless mode requires additional tools and configuration.
24
+
25
+ #### How to choose browser driver
26
+
27
+ * **[Choose Puppeteer](#Using-Puppeteer)** for simplest setup, fast tests, full browser control. Limited to Chrome and Firefox only. Cloud browsers via browserless.io.
28
+ * **[Choose WebDriver](#Using-WebDriver)** or Protractor for classical Selenium. Rich ecosystem and cross browser support with cloud browsers via Sauce Labs, BrowserStack, TestingBot. **Selenium server requried** for local start.
29
+ * **[Choose TestCafe](#Using-TestCafe)** for cheap and fast cross-browser tests. Has stability and feature limitation comparing to WebDriver.
30
+
31
+ Each driver has its own pros and cons which can't be described in this paragraph. However, in CodeceptJS it is easy to switch between them. In most cases you just need to update a config to run tests differently.
13
32
 
14
33
  ## Using Puppeteer
15
34
 
16
35
 
17
36
  <video onclick="this.paused ? this.play() : this.pause();" src="/img/codeceptjs-install.mp4" style="width: 100%" controls></video>
18
37
 
38
+ 0) If you start an empty project, initialize npm first:
39
+
40
+ ```
41
+ npm init -y
42
+ ```
19
43
 
20
44
  1) Install CodeceptJS with Puppeteer
21
45
 
@@ -102,17 +126,24 @@ Puppeteer starts a browser without showing its window. To see the browser, edit
102
126
 
103
127
  Rerun the test to see the browser.
104
128
 
105
- > Next: [CodeceptJS with Puppeteer >>>](https://codecept.io/puppeteer/)
129
+ > [▶ Next: CodeceptJS Basics](https://codecept.io/basics/)
130
+
131
+ > [▶ Next: CodeceptJS with Puppeteer](https://codecept.io/puppeteer/)
106
132
 
107
- > Next: [CodeceptJS Basics >>>](https://codecept.io/basics/)
108
133
 
109
- > Next: [Demo Project](https://github.com/DavertMik/codeceptjs-todomvc-puppeteer)
110
134
 
111
135
 
112
136
  ---
113
137
 
114
138
  ## Using Selenium WebDriver
115
139
 
140
+ 0) If you start an empty project, initialize npm first:
141
+
142
+ ```
143
+ npm init -y
144
+ ```
145
+
146
+
116
147
  1) Install CodeceptJS with webdriverio library
117
148
 
118
149
  ```
@@ -209,19 +240,23 @@ My First Test --
209
240
  ```
210
241
 
211
242
 
212
- > Next: [CodeceptJS Basics >>>](https://codecept.io/basics/)
243
+ > [▶ Next: CodeceptJS Basics](https://codecept.io/basics/)
213
244
 
214
- > Next: [Acceptance Testing in CodeceptJS >>>](https://codecept.io/acceptance/)
245
+ > [▶ Next: WebDriver Testing](https://codecept.io/webdriver/)
215
246
 
216
247
 
217
248
  ## Using Protractor
218
249
 
219
- > [**Follow corresponding guide >>**](https://codecept.io/angular/)
250
+ > [Follow corresponding guide](https://codecept.io/angular/)
220
251
 
221
252
  ## Using Appium
222
253
 
223
- > [**Follow corresponding guide >>**](https://codecept.io/mobile/)
254
+ > [Follow corresponding guide](https://codecept.io/mobile/)
224
255
 
225
256
  ## Using NightmareJS
226
257
 
227
- > [**Follow corresponding guide >>**](https://codecept.io/nightmare/)
258
+ > [Follow corresponding guide](https://codecept.io/nightmare/)
259
+
260
+ ## Using TestCafe
261
+
262
+ > [▶ Follow corresponding guide](https://codecept.io/testcafe/)
@@ -0,0 +1,157 @@
1
+ ---
2
+ id: testcafe
3
+ title: Testing with TestCafe
4
+ ---
5
+
6
+ [TestCafe](https://devexpress.github.io/testcafe/) is another alternative engine for driving browsers. It is driven by unique technology which provides fast and simple cross browser testing for desktop and mobile browsers. Unlike WebDriver or Puppeteer, TestCafe doesn't control a browser at all. It is not a browser itself, like [Nightmare](https://codecept.io/nightmare) or Cypress. **TestCafe core is a proxy server** that runs behind the scene, and transforms all HTML and JS to include code that is needed for test automation.
7
+
8
+ ![](/img/testcafe.png)
9
+
10
+ This is very smart idea. But to use TestCafe on daily basis you need to clearly understand its benefits and limitations:
11
+
12
+ ### Pros
13
+
14
+ * **Fast**. Browser is controlled from inside a web page. This makes test run inside a browser as fast as your browser can render page with no extra network requests.
15
+ * **Simple Cross-Browser Support.** Because TestCafe only launches browsers, it can **automate browser** on desktop or mobile. Unlike WebDriver, you don't need special version of browser and driver to prepare to run tests. Setup simplified. All you need is just a browser installed, and you are ready to go.
16
+ * **Stable to Execution.** Because a test is executed inside a browser, the network latency effects are reduced. Unlike WebDriver you won't hit stale element exceptions, or element not interactable exceptions, as from within a web browser all DOM elements are accessible.
17
+
18
+ ## Cons
19
+
20
+ * **Magic.** Browsers executed in TestCafe are not aware that they run in test mode. So at some edges automation control can be broken. It's also quite hard to debug possible issues, as you don't know how actually a web page is parsed to inject automation scripts.
21
+ * **No Browser Control.** Because TestCafe do not control browser, you can't actually automate all users actions. For instance, TestCafe can't open new tabs or open a new browser window in incognito mode. There can be also some issues running tests on 3rd party servers or inside iframes.
22
+ * **Simulated Events.** Events like `click` or `doubleClick` are simulated by JavaScript internally. Inside WebDriver or Puppeteer, where those events are dispatched by a browser, called native events. Native events are closer to real user experience. So in some cases simulated events wouldn't represent actual user experience, which can lead to false positive results. For instance, a button which can't be physically clicked by a user, would be clickable inside TestCafe.
23
+
24
+ Anyway, TestCafe is a good option to start if you need cross browser testing. And here is the **reason to use TestCafe with CodeceptJS: if you hit an edge case or issue, you can easily switch your tests to WebDriver**. As all helpers in CodeceptJS share the same syntax.
25
+
26
+ CodeceptJS is a rich testing frameworks which also provides features missing in original TestCafe:
27
+
28
+ * [Cucumber integration](https://codecept.io/bdd)
29
+ * [Real Page Objects](https://codecept.io/pageobjects)
30
+ * [Data Management via API](https://codecept.io/data)
31
+ * and others
32
+
33
+ ## Writing Tests
34
+
35
+ To start using TestCafe with CodeceptJS install both via NPM
36
+
37
+ > If you don't have `package.json` in your project, create it with `npm init -y`.
38
+
39
+ ```
40
+ npm i codeceptjs testcafe --save-dev
41
+ ```
42
+
43
+ Then you need to initialize a project, selecting TestCafe when asked:
44
+
45
+ ```
46
+ npx codeceptjs init
47
+ ```
48
+
49
+ A first test should be created with `codeceptjs gt` command
50
+
51
+ ```
52
+ npx codeceptjs gt
53
+ ```
54
+
55
+ In the next example we will [TodoMVC application](http://todomvc.com/examples/angularjs/#/). So let's create a test which will fill in todo list:
56
+
57
+ ```js
58
+ Feature('TodoMVC');
59
+
60
+ Scenario('create todo item', (I) => {
61
+ I.amOnPage('http://todomvc.com/examples/angularjs/#/');
62
+ I.fillField('.new-todo', todo)
63
+ I.pressKey('Enter');
64
+ I.seeNumberOfVisibleElements('.todo-list li', 1);
65
+ I.see('1 item left', '.todo-count');
66
+ });
67
+ ```
68
+
69
+ Same syntax is the same for all helpers in CodeceptJS so to learn more about available commands learn [CodeceptJS Basics](https://codecept.io/basics).
70
+
71
+ > [▶ Complete list of TestCafe actions](https://codecept.io/helpers/TestCafe)
72
+
73
+ ## Page Objects
74
+
75
+ Multiple tests can be refactored to share some logic and locators. It is recommended to use PageObjects for this. For instance, in example above, we could create special actions for creating todos and checking them. If we move such methods in a corresponding object a test would look even clearer:
76
+
77
+ ```js
78
+ Scenario('Create a new todo item', async (I, TodosPage) => {
79
+ I.say('Given I have an empty todo list')
80
+
81
+ I.say('When I create a todo "foo"')
82
+ TodosPage.enterTodo('foo')
83
+
84
+ I.say('Then I see the new todo on my list')
85
+ TodosPage.seeNumberOfTodos(1)
86
+
87
+ I.saveScreenshot('create-todo-item.png')
88
+ })
89
+
90
+ Scenario('Create multiple todo items', async (I, TodosPage) => {
91
+ I.say('Given I have an empty todo list')
92
+
93
+ I.say('When I create todos "foo", "bar" and "baz"')
94
+ TodosPage.enterTodo('foo')
95
+ TodosPage.enterTodo('bar')
96
+ TodosPage.enterTodo('baz')
97
+
98
+ I.say('Then I have these 3 todos on my list')
99
+ TodosPage.seeNumberOfTodos(3)
100
+
101
+ I.saveScreenshot('create-multiple-todo-items.png')
102
+ })
103
+ ```
104
+
105
+ > ℹ [Source code of this example](https://github.com/hubidu/codeceptjs-testcafe-todomvc) is available on GitHub.
106
+
107
+ A PageObject can be injected into a test by its name. Here is how TodosPage looks like:
108
+
109
+ ```js
110
+ // inside todos_page.js
111
+ const { I } = inject();
112
+
113
+ module.exports = {
114
+ goto() {
115
+ I.amOnPage('http://todomvc.com/examples/angularjs/#/')
116
+ },
117
+
118
+ enterTodo(todo) {
119
+ I.fillField('.new-todo', todo)
120
+ I.pressKey('Enter')
121
+ },
122
+
123
+ seeNumberOfTodos(numberOfTodos) {
124
+ I.seeNumberOfVisibleElements('.todo-list li', numberOfTodos)
125
+ },
126
+ }
127
+ ```
128
+
129
+ > [▶ Read more about PageObjects in CodeceptJS](https://codecept.io/pageobjects)
130
+
131
+ ## Extending
132
+
133
+ If you want to use TestCafe API inside your tests you can put them into actions of `I` object. To do so you can generate a new helper, access TestCafe helper, and get the test controller.
134
+
135
+ Create a helper using `codecepjs gh` command.
136
+
137
+ ```
138
+ npx codeceptjs gh
139
+ ```
140
+
141
+ All methods of newly created class will be added to `I` object.
142
+
143
+ ```js
144
+ const Helper = codeceptjs.helper;
145
+
146
+ class MyTestCafe extends Helper {
147
+
148
+ slowlyFillField(field, text) {
149
+ // import test controller from TestCafe helper
150
+ const { t } = this.helpers.TestCafe;
151
+ // use TestCafe API here
152
+ return t.setTestSpeed(0.1)
153
+ .typeText(field, text);
154
+ }
155
+
156
+ }
157
+ ```