codeceptjs 3.1.1 → 3.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 (70) hide show
  1. package/CHANGELOG.md +120 -0
  2. package/README.md +2 -3
  3. package/bin/codecept.js +1 -0
  4. package/docs/advanced.md +94 -60
  5. package/docs/basics.md +1 -1
  6. package/docs/bdd.md +55 -1
  7. package/docs/build/Appium.js +22 -4
  8. package/docs/build/FileSystem.js +1 -0
  9. package/docs/build/Playwright.js +40 -42
  10. package/docs/build/Protractor.js +9 -24
  11. package/docs/build/Puppeteer.js +28 -30
  12. package/docs/build/REST.js +1 -0
  13. package/docs/build/WebDriver.js +2 -24
  14. package/docs/changelog.md +120 -0
  15. package/docs/commands.md +21 -7
  16. package/docs/configuration.md +15 -2
  17. package/docs/custom-helpers.md +1 -36
  18. package/docs/helpers/Appium.md +49 -50
  19. package/docs/helpers/FileSystem.md +1 -1
  20. package/docs/helpers/Playwright.md +16 -18
  21. package/docs/helpers/Puppeteer.md +18 -18
  22. package/docs/helpers/REST.md +3 -1
  23. package/docs/helpers/WebDriver.md +1 -17
  24. package/docs/mobile-react-native-locators.md +3 -0
  25. package/docs/playwright.md +40 -0
  26. package/docs/plugins.md +187 -70
  27. package/docs/reports.md +23 -5
  28. package/lib/actor.js +20 -2
  29. package/lib/codecept.js +15 -2
  30. package/lib/command/info.js +1 -1
  31. package/lib/config.js +13 -1
  32. package/lib/container.js +3 -1
  33. package/lib/data/dataTableArgument.js +35 -0
  34. package/lib/helper/Appium.js +22 -4
  35. package/lib/helper/FileSystem.js +1 -0
  36. package/lib/helper/Playwright.js +40 -32
  37. package/lib/helper/Protractor.js +2 -14
  38. package/lib/helper/Puppeteer.js +21 -20
  39. package/lib/helper/REST.js +1 -0
  40. package/lib/helper/WebDriver.js +2 -14
  41. package/lib/index.js +2 -0
  42. package/lib/interfaces/featureConfig.js +3 -0
  43. package/lib/interfaces/gherkin.js +7 -1
  44. package/lib/interfaces/scenarioConfig.js +4 -0
  45. package/lib/listener/helpers.js +1 -0
  46. package/lib/listener/steps.js +21 -3
  47. package/lib/listener/timeout.js +71 -0
  48. package/lib/locator.js +3 -0
  49. package/lib/mochaFactory.js +13 -9
  50. package/lib/plugin/allure.js +6 -1
  51. package/lib/plugin/{puppeteerCoverage.js → coverage.js} +10 -22
  52. package/lib/plugin/customLocator.js +2 -2
  53. package/lib/plugin/retryFailedStep.js +4 -3
  54. package/lib/plugin/retryTo.js +130 -0
  55. package/lib/plugin/screenshotOnFail.js +1 -0
  56. package/lib/plugin/stepByStepReport.js +7 -0
  57. package/lib/plugin/stepTimeout.js +90 -0
  58. package/lib/plugin/subtitles.js +88 -0
  59. package/lib/plugin/tryTo.js +1 -1
  60. package/lib/recorder.js +21 -8
  61. package/lib/step.js +7 -2
  62. package/lib/store.js +2 -0
  63. package/lib/ui.js +2 -2
  64. package/package.json +6 -7
  65. package/typings/index.d.ts +8 -1
  66. package/typings/types.d.ts +104 -71
  67. package/docs/angular.md +0 -325
  68. package/docs/helpers/Protractor.md +0 -1658
  69. package/docs/webapi/waitUntil.mustache +0 -11
  70. package/typings/Protractor.d.ts +0 -16
@@ -1181,11 +1181,14 @@ class Protractor extends Helper {
1181
1181
  }
1182
1182
 
1183
1183
  /**
1184
- * Checks that title is equal to provided one.
1185
- *
1186
- * ```js
1187
- * I.seeTitleEquals('Test title.');
1188
- * ```
1184
+ * Checks that title is equal to provided one.
1185
+ *
1186
+ * ```js
1187
+ * I.seeTitleEquals('Test title.');
1188
+ * ```
1189
+ *
1190
+ * @param {string} text value to check.
1191
+ *
1189
1192
  */
1190
1193
  async seeTitleEquals(text) {
1191
1194
  const title = await this.browser.getTitle();
@@ -1509,7 +1512,7 @@ class Protractor extends Helper {
1509
1512
  }
1510
1513
 
1511
1514
  /**
1512
- * Checks that current url contains a provided fragment.
1515
+ * Checks that current url contains a provided fragment.
1513
1516
  *
1514
1517
  * ```js
1515
1518
  * I.seeInCurrentUrl('/register'); // we are on registration page
@@ -2184,24 +2187,6 @@ class Protractor extends Helper {
2184
2187
  return this.browser.wait(() => this.browser.executeScript.call(this.browser, fn, ...args), aSec * 1000);
2185
2188
  }
2186
2189
 
2187
- /**
2188
- * Waits for a function to return true (waits for 1sec by default).
2189
- *
2190
- * ```js
2191
- * I.waitUntil(() => window.requests == 0);
2192
- * I.waitUntil(() => window.requests == 0, 5);
2193
- * ```
2194
- *
2195
- * @param {function|string} fn function which is executed in browser context.
2196
- * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
2197
- * @param {string} [timeoutMsg=''] message to show in case of timeout fail.
2198
- * @param {?number} [interval=null]
2199
- */
2200
- async waitUntil(fn, sec = null, timeoutMsg = null) {
2201
- const aSec = sec || this.options.waitForTimeout;
2202
- return this.browser.wait(fn, aSec * 1000, timeoutMsg);
2203
- }
2204
-
2205
2190
  /**
2206
2191
  * Waiting for the part of the URL to match the expected. Useful for SPA to understand that page was changed.
2207
2192
  *
@@ -129,8 +129,9 @@ const consoleLogStore = new Console();
129
129
  * }
130
130
  * }
131
131
  * ```
132
+ * > Note: When connecting to remote browser `show` and specific `chrome` options (e.g. `headless` or `devtools`) are ignored.
132
133
  *
133
- * #### Example #5: Target URL with provided basic authentication
134
+ * #### Example #5: Target URL with provided basic authentication
134
135
  *
135
136
  * ```js
136
137
  * {
@@ -143,10 +144,25 @@ const consoleLogStore = new Console();
143
144
  * }
144
145
  * }
145
146
  * ```
147
+ * #### Troubleshooting
146
148
  *
149
+ * Error Message: `No usable sandbox!`
150
+ *
151
+ * When running Puppeteer on CI try to disable sandbox if you see that message
152
+ *
153
+ * ```
154
+ * helpers: {
155
+ * Puppeteer: {
156
+ * url: 'http://localhost',
157
+ * show: false,
158
+ * chrome: {
159
+ * args: ['--no-sandbox', '--disable-setuid-sandbox']
160
+ * }
161
+ * },
162
+ * }
163
+ * ```
147
164
  *
148
165
  *
149
- * Note: When connecting to remote browser `show` and specific `chrome` options (e.g. `headless` or `devtools`) are ignored.
150
166
  *
151
167
  * ## Access From Helpers
152
168
  *
@@ -248,7 +264,7 @@ class Puppeteer extends Helper {
248
264
  async _before() {
249
265
  this.sessionPages = {};
250
266
  recorder.retry({
251
- retries: 5,
267
+ retries: 3,
252
268
  when: err => {
253
269
  if (!err || typeof (err.message) !== 'string') {
254
270
  return false;
@@ -545,10 +561,9 @@ class Puppeteer extends Helper {
545
561
  this.context = null;
546
562
  popupStore.clear();
547
563
  this.isAuthenticated = false;
564
+ await this.browser.close();
548
565
  if (this.isRemoteBrowser) {
549
566
  await this.browser.disconnect();
550
- } else {
551
- await this.browser.close();
552
567
  }
553
568
  }
554
569
 
@@ -836,11 +851,14 @@ class Puppeteer extends Helper {
836
851
  }
837
852
 
838
853
  /**
839
- * Checks that title is equal to provided one.
840
- *
841
- * ```js
842
- * I.seeTitleEquals('Test title.');
843
- * ```
854
+ * Checks that title is equal to provided one.
855
+ *
856
+ * ```js
857
+ * I.seeTitleEquals('Test title.');
858
+ * ```
859
+ *
860
+ * @param {string} text value to check.
861
+ *
844
862
  */
845
863
  async seeTitleEquals(text) {
846
864
  const title = await this.page.title();
@@ -3086,26 +3104,6 @@ class Puppeteer extends Helper {
3086
3104
  return this.page.waitForNavigation(opts);
3087
3105
  }
3088
3106
 
3089
- /**
3090
- * Waits for a function to return true (waits for 1sec by default).
3091
- *
3092
- * ```js
3093
- * I.waitUntil(() => window.requests == 0);
3094
- * I.waitUntil(() => window.requests == 0, 5);
3095
- * ```
3096
- *
3097
- * @param {function|string} fn function which is executed in browser context.
3098
- * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
3099
- * @param {string} [timeoutMsg=''] message to show in case of timeout fail.
3100
- * @param {?number} [interval=null]
3101
- */
3102
- async waitUntil(fn, sec = null) {
3103
- console.log('This method will remove in CodeceptJS 1.4; use `waitForFunction` instead!');
3104
- const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
3105
- const context = await this._getContext();
3106
- return context.waitForFunction(fn, { timeout: waitTimeout });
3107
- }
3108
-
3109
3107
  async waitUntilExists(locator, sec) {
3110
3108
  console.log(`waitUntilExists deprecated:
3111
3109
  * use 'waitForElement' to wait for element to be attached
@@ -131,6 +131,7 @@ class REST extends Helper {
131
131
  * I.setRequestTimeout(10000); // In milliseconds
132
132
  * ```
133
133
  *
134
+ * @param {number} newTimeout - timeout in milliseconds
134
135
  */
135
136
  setRequestTimeout(newTimeout) {
136
137
  this.options.timeout = newTimeout;
@@ -481,7 +481,7 @@ class WebDriver extends Helper {
481
481
  try {
482
482
  require('webdriverio');
483
483
  } catch (e) {
484
- return ['webdriverio@^5.2.2'];
484
+ return ['webdriverio@^6.12.1'];
485
485
  }
486
486
  }
487
487
 
@@ -875,7 +875,7 @@ class WebDriver extends Helper {
875
875
  * I.defineTimeout({ implicit: 10000, pageLoad: 10000, script: 5000 });
876
876
  * ```
877
877
  *
878
- * @param {WebdriverIO.Timeouts} timeouts WebDriver timeouts object.
878
+ * @param {*} timeouts WebDriver timeouts object.
879
879
  */
880
880
  defineTimeout(timeouts) {
881
881
  return this._defineBrowserTimeout(this.browser, timeouts);
@@ -3259,28 +3259,6 @@ class WebDriver extends Helper {
3259
3259
  return this.browser.waitUntil(async () => this.browser.execute(fn, ...args), { timeout: aSec * 1000, timeoutMsg: '' });
3260
3260
  }
3261
3261
 
3262
- /**
3263
- * Waits for a function to return true (waits for 1sec by default).
3264
- *
3265
- * ```js
3266
- * I.waitUntil(() => window.requests == 0);
3267
- * I.waitUntil(() => window.requests == 0, 5);
3268
- * ```
3269
- *
3270
- * @param {function|string} fn function which is executed in browser context.
3271
- * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
3272
- * @param {string} [timeoutMsg=''] message to show in case of timeout fail.
3273
- * @param {?number} [interval=null]
3274
- */
3275
- async waitUntil(fn, sec = null, timeoutMsg = null, interval = null) {
3276
- const aSec = sec || this.options.waitForTimeout;
3277
- const _interval = typeof interval === 'number' ? interval * 1000 : null;
3278
- if (isWebDriver5()) {
3279
- return this.browser.waitUntil(fn, aSec * 1000, timeoutMsg, _interval);
3280
- }
3281
- return this.browser.waitUntil(fn, { timeout: aSec * 1000, timeoutMsg, interval: _interval });
3282
- }
3283
-
3284
3262
  /**
3285
3263
  * Switches frame or in case of null locator reverts to parent.
3286
3264
  *
package/docs/changelog.md CHANGED
@@ -7,6 +7,126 @@ layout: Section
7
7
 
8
8
  # Releases
9
9
 
10
+ ## 3.2.1
11
+
12
+ > ♻️ This release fixes hanging of tests by reducing timeouts for automatic retries on failures.
13
+
14
+ * [retryFailedStep plugin] **New Defaults**: retries steps up to 3 times with factor of 1.5 (previously 5 with factor 2)
15
+ * **[Playwright]** - disabled retry on failed context actions (not needed anymore)
16
+ * **[Puppeteer]** - reduced retries on context failures to 3 times.
17
+ * **[Playwright]** Handling `crash` event to automatically close crashed pages.
18
+
19
+ ## 3.2.0
20
+
21
+ 🛩️ Features:
22
+
23
+ **[Timeouts](https://codecept.io/advanced/#timeout) implemented**
24
+ * global timeouts (via `timeout` config option).
25
+ * _Breaking change:_ timeout option expects **timeout in seconds**, not in milliseconds as it was previously.
26
+ * test timeouts (via `Scenario` and `Feature` options)
27
+ * _Breaking change:_ `Feature().timeout()` and `Scenario().timeout()` calls has no effect and are deprecated
28
+
29
+ ```js
30
+ // set timeout for every test in suite to 10 secs
31
+ Feature('tests with timeout', { timeout: 10 });
32
+
33
+ // set timeout for this test to 20 secs
34
+ Scenario('a test with timeout', { timeout: 20 }, ({ I }) => {});
35
+ ```
36
+
37
+ * step timeouts (See [#3059](https://github.com/codeceptjs/CodeceptJS/issues/3059) by **[nikocanvacom](https://github.com/nikocanvacom)**)
38
+
39
+ ```js
40
+ // set step timeout to 5 secs
41
+ I.limitTime(5).click('Link');
42
+ ```
43
+ * `stepTimeout` plugin introduced to automatically add timeouts for each step ([#3059](https://github.com/codeceptjs/CodeceptJS/issues/3059) by **[nikocanvacom](https://github.com/nikocanvacom)**).
44
+
45
+ [**retryTo**](/plugins/#retryto) plugin introduced to rerun a set of steps on failure:
46
+
47
+ ```js
48
+ // editing in text in iframe
49
+ // if iframe was not loaded - retry 5 times
50
+ await retryTo(() => {
51
+ I.switchTo('#editor frame');
52
+ I.fillField('textarea', 'value');
53
+ }, 5);
54
+ ```
55
+
56
+ * **[Playwright]** added `locale` configuration
57
+ * **[WebDriver]** upgraded to webdriverio v7
58
+
59
+ 🐛 Bugfixes:
60
+
61
+ * Fixed allure plugin "Unexpected endStep()" error in [#3098](https://github.com/codeceptjs/CodeceptJS/issues/3098) by **[abhimanyupandian](https://github.com/abhimanyupandian)**
62
+ * **[Puppeteer]** always close remote browser on test end. See [#3054](https://github.com/codeceptjs/CodeceptJS/issues/3054) by **[mattonem](https://github.com/mattonem)**
63
+ * stepbyStepReport Plugin: Disabled screenshots after test has failed. See [#3119](https://github.com/codeceptjs/CodeceptJS/issues/3119) by **[ioannisChalkias](https://github.com/ioannisChalkias)**
64
+
65
+
66
+ ## 3.1.3
67
+
68
+ 🛩️ Features:
69
+
70
+ * BDD Improvement. Added `DataTableArgument` class to work with table data structures.
71
+
72
+ ```js
73
+ const { DataTableArgument } = require('codeceptjs');
74
+ //...
75
+ Given('I have an employee card', (table) => {
76
+ const dataTableArgument = new DataTableArgument(table);
77
+ const hashes = dataTableArgument.hashes();
78
+ // hashes = [{ name: 'Harry', surname: 'Potter', position: 'Seeker' }];
79
+ const rows = dataTableArgument.rows();
80
+ // rows = [['Harry', 'Potter', Seeker]];
81
+ }
82
+ ```
83
+ See updated [BDD section](https://codecept.io/bdd/) for more API options. Thanks to **[EgorBodnar](https://github.com/EgorBodnar)**
84
+
85
+ * Support `cjs` file extensions for config file: `codecept.conf.cjs`. See [#3052](https://github.com/codeceptjs/CodeceptJS/issues/3052) by **[kalvenschraut](https://github.com/kalvenschraut)**
86
+ * API updates: Added `test.file` and `suite.file` properties to `test` and `suite` objects to use in helpers and plugins.
87
+
88
+ 🐛 Bugfixes:
89
+
90
+ * **[Playwright]** Fixed resetting `test.artifacts` for failing tests. See [#3033](https://github.com/codeceptjs/CodeceptJS/issues/3033) by **[jancorvus](https://github.com/jancorvus)**. Fixes [#3032](https://github.com/codeceptjs/CodeceptJS/issues/3032)
91
+ * **[Playwright]** Apply `basicAuth` credentials to all opened browser contexts. See [#3036](https://github.com/codeceptjs/CodeceptJS/issues/3036) by **[nikocanvacom](https://github.com/nikocanvacom)**. Fixes [#3035](https://github.com/codeceptjs/CodeceptJS/issues/3035)
92
+ * **[WebDriver]** Updated `webdriverio` default version to `^6.12.1`. See [#3043](https://github.com/codeceptjs/CodeceptJS/issues/3043) by **[sridhareaswaran](https://github.com/sridhareaswaran)**
93
+ * **[Playwright]** `I.haveRequestHeaders` affects all tabs. See [#3049](https://github.com/codeceptjs/CodeceptJS/issues/3049) by **[jancorvus](https://github.com/jancorvus)**
94
+ * BDD: Fixed unhandled empty feature files. Fix [#3046](https://github.com/codeceptjs/CodeceptJS/issues/3046) by **[abhimanyupandian](https://github.com/abhimanyupandian)**
95
+ * Fixed `RangeError: Invalid string length` in `recorder.js` when running huge amount of tests.
96
+ * **[Appium]** Fixed definitions for `touchPerform`, `hideDeviceKeyboard`, `removeApp` by **[mirao](https://github.com/mirao)**
97
+
98
+ 📖 Documentation:
99
+
100
+ * Added Testrail reporter [Reports Docs](https://codecept.io/reports/#testrail)
101
+
102
+
103
+ ## 3.1.2
104
+
105
+ 🛩️ Features:
106
+
107
+ * Added `coverage` plugin to generate code coverage for Playwright & Puppeteer. By **[anirudh-modi](https://github.com/anirudh-modi)**
108
+ * Added `subtitle` plugin to generate subtitles for videos recorded with Playwright. By **[anirudh-modi](https://github.com/anirudh-modi)**
109
+ * Configuration: `config.tests` to accept array of file patterns. See [#2994](https://github.com/codeceptjs/CodeceptJS/issues/2994) by **[monsteramba](https://github.com/monsteramba)**
110
+
111
+ ```js
112
+ exports.config = {
113
+ tests: ['./*_test.js','./sampleTest.js'],
114
+ // ...
115
+ }
116
+ ```
117
+ * Notification is shown for test files without `Feature()`. See [#3011](https://github.com/codeceptjs/CodeceptJS/issues/3011) by **[PeterNgTr](https://github.com/PeterNgTr)**
118
+
119
+ 🐛 Bugfixes:
120
+
121
+ * **[Playwright]** Fixed [#2986](https://github.com/codeceptjs/CodeceptJS/issues/2986) error is thrown when deleting a missing video. Fix by **[hatufacci](https://github.com/hatufacci)**
122
+ * Fixed false positive result when invalid function is called in a helper. See [#2997](https://github.com/codeceptjs/CodeceptJS/issues/2997) by **[abhimanyupandian](https://github.com/abhimanyupandian)**
123
+ * **[Appium]** Removed full page mode for `saveScreenshot`. See [#3002](https://github.com/codeceptjs/CodeceptJS/issues/3002) by **[nlespiaucq](https://github.com/nlespiaucq)**
124
+ * **[Playwright]** Fixed [#3003](https://github.com/codeceptjs/CodeceptJS/issues/3003) saving trace for a test with a long name. Fix by **[hatufacci](https://github.com/hatufacci)**
125
+
126
+ 🎱 Other:
127
+
128
+ * Deprecated `puppeteerCoverage` plugin in favor of `coverage` plugin.
129
+
10
130
  ## 3.1.1
11
131
 
12
132
  * **[Appium]** Fixed [#2759](https://github.com/codeceptjs/CodeceptJS/issues/2759)
package/docs/commands.md CHANGED
@@ -47,18 +47,12 @@ Run single test with steps printed
47
47
  npx codeceptjs run github_test.js --steps
48
48
  ```
49
49
 
50
- Run single test in debug mode
50
+ Run single test in debug mode (see more in [debugging](#Debugging) section)
51
51
 
52
52
  ```sh
53
53
  npx codeceptjs run github_test.js --debug
54
54
  ```
55
55
 
56
- Run test with internal logs printed (global promises, and events).
57
-
58
- ```sh
59
- npx codeceptjs run github_test.js --verbose
60
- ```
61
-
62
56
  Select config file manually (`-c` or `--config` option)
63
57
 
64
58
  ```sh
@@ -80,6 +74,26 @@ npx codeceptjs run --reporter xunit
80
74
 
81
75
  Use any of [Mocha reporters](https://github.com/mochajs/mocha/tree/master/lib/reporters) used.
82
76
 
77
+ #### Debugging
78
+
79
+ Run single test in debug mode
80
+
81
+ ```sh
82
+ npx codeceptjs run --debug
83
+ ```
84
+
85
+ Run test with internal logs printed.
86
+
87
+ ```sh
88
+ npx codeceptjs run --verbose
89
+ ```
90
+
91
+ Display complete debug output including scheduled promises
92
+
93
+ ```
94
+ DEBUG=codeceptjs:* npx codeceptjs run
95
+ ```
96
+
83
97
  ## Run Workers
84
98
 
85
99
  Run tests in parallel threads.
@@ -11,7 +11,7 @@ After running `codeceptjs init` it should be saved in test root.
11
11
 
12
12
  Here is an overview of available options with their defaults:
13
13
 
14
- * **tests**: `"./*_test.js"` - pattern to locate tests. Allows to enter [glob pattern](https://github.com/isaacs/node-glob).
14
+ * **tests**: `"./*_test.js"` - pattern to locate tests. Allows to enter [glob pattern](https://github.com/isaacs/node-glob), Can either be a pattern to locate tests or an array of patterns to locate tests / test file names.
15
15
  * **grep**: - pattern to filter tests by name
16
16
  * **include**: `{}` - actors and page objects to be registered in DI container and included in tests. Accepts objects and module `require` paths
17
17
  * **timeout**: `10000` - default tests timeout
@@ -47,7 +47,20 @@ exports.config = {
47
47
  require: ["ts-node/register", "should"]
48
48
  }
49
49
  ```
50
-
50
+ For array of test pattern
51
+ ```js
52
+ exports.config = {
53
+ tests: ['./*_test.js','./sampleTest.js'],
54
+ timeout: 10000,
55
+ output: '',
56
+ helpers: {},
57
+ include: {},
58
+ bootstrap: false,
59
+ mocha: {},
60
+ // require modules
61
+ require: ["ts-node/register", "should"]
62
+ }
63
+ ```
51
64
  ## Dynamic Configuration
52
65
 
53
66
  By default `codecept.json` is used for configuration. You can override its values in runtime by using `--override` or `-o` option in command line, passing valid JSON as a value:
@@ -108,7 +108,7 @@ If you need to get access to web elements, it is recommended to implement operat
108
108
 
109
109
  To get access for elements, connect to a corresponding helper and use `_locate` function to match web elements by CSS or XPath, like you usually do:
110
110
 
111
- ### Acessing Elements in WebDriver
111
+ ### Accessing Elements in WebDriver
112
112
 
113
113
  ```js
114
114
  // inside a custom helper
@@ -304,38 +304,3 @@ class MyHelper extends Helper {
304
304
 
305
305
  module.exports = MyHelper;
306
306
  ```
307
-
308
- ### Protractor Example
309
-
310
- Protractor example demonstrates usage of global `element` and `by` objects.
311
- However `browser` should be accessed from a helper instance via `this.helpers['Protractor']`;
312
- We also use `chai-as-promised` library to have nice assertions with promises.
313
-
314
- ```js
315
- const Helper = require('@codeceptjs/helper');
316
-
317
- // use any assertion library you like
318
- const chai = require('chai');
319
- const chaiAsPromised = require('chai-as-promised');
320
- chai.use(chaiAsPromised);
321
- const expect = chai.expect;
322
-
323
- class MyHelper extends Helper {
324
- /**
325
- * checks that authentication cookie is set
326
- */
327
- seeInHistory(historyPosition, value) {
328
- // access browser instance from Protractor helper
329
- this.helpers['Protractor'].browser.refresh();
330
-
331
- // you can use `element` as well as in protractor
332
- const history = element.all(by.repeater('result in memory'));
333
-
334
- // use chai as promised for better assertions
335
- // end your method with `return` to handle promises
336
- return expect(history.get(historyPosition).getText()).to.eventually.equal(value);
337
- }
338
- }
339
-
340
- module.exports = MyHelper;
341
- ```