codeceptjs 3.1.2 â 3.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +103 -0
- package/README.md +2 -3
- package/bin/codecept.js +1 -0
- package/docs/advanced.md +94 -60
- package/docs/basics.md +27 -2
- package/docs/bdd.md +57 -3
- package/docs/build/Appium.js +8 -4
- package/docs/build/FileSystem.js +1 -0
- package/docs/build/Playwright.js +39 -30
- package/docs/build/Protractor.js +9 -24
- package/docs/build/Puppeteer.js +10 -28
- package/docs/build/REST.js +1 -0
- package/docs/build/WebDriver.js +3 -25
- package/docs/changelog.md +103 -0
- package/docs/commands.md +21 -7
- package/docs/custom-helpers.md +1 -36
- package/docs/helpers/Appium.md +34 -30
- package/docs/helpers/FileSystem.md +1 -1
- package/docs/helpers/Playwright.md +16 -18
- package/docs/helpers/Puppeteer.md +1 -17
- package/docs/helpers/REST.md +3 -1
- package/docs/helpers/WebDriver.md +1 -17
- package/docs/mobile-react-native-locators.md +3 -0
- package/docs/pageobjects.md +2 -0
- package/docs/playwright.md +16 -33
- package/docs/plugins.md +128 -3
- package/docs/reports.md +23 -5
- package/lib/actor.js +20 -2
- package/lib/codecept.js +2 -0
- package/lib/command/info.js +1 -1
- package/lib/config.js +13 -1
- package/lib/container.js +3 -1
- package/lib/data/dataTableArgument.js +35 -0
- package/lib/helper/Appium.js +8 -4
- package/lib/helper/FileSystem.js +1 -0
- package/lib/helper/Playwright.js +39 -20
- package/lib/helper/Protractor.js +2 -14
- package/lib/helper/Puppeteer.js +3 -18
- package/lib/helper/REST.js +1 -0
- package/lib/helper/WebDriver.js +3 -15
- package/lib/index.js +2 -0
- package/lib/interfaces/featureConfig.js +3 -0
- package/lib/interfaces/gherkin.js +7 -1
- package/lib/interfaces/scenarioConfig.js +4 -0
- package/lib/listener/helpers.js +1 -0
- package/lib/listener/steps.js +21 -3
- package/lib/listener/timeout.js +72 -0
- package/lib/locator.js +3 -0
- package/lib/mochaFactory.js +2 -3
- package/lib/plugin/allure.js +6 -1
- package/lib/plugin/coverage.js +1 -1
- package/lib/plugin/retryFailedStep.js +4 -3
- package/lib/plugin/retryTo.js +130 -0
- package/lib/plugin/screenshotOnFail.js +1 -0
- package/lib/plugin/stepByStepReport.js +7 -0
- package/lib/plugin/stepTimeout.js +91 -0
- package/lib/recorder.js +23 -9
- package/lib/step.js +58 -0
- package/lib/store.js +2 -0
- package/lib/ui.js +2 -2
- package/package.json +4 -6
- package/typings/index.d.ts +8 -1
- package/typings/types.d.ts +103 -70
- package/docs/angular.md +0 -325
- package/docs/helpers/Protractor.md +0 -1658
- package/docs/webapi/waitUntil.mustache +0 -11
- package/typings/Protractor.d.ts +0 -16
package/docs/build/Playwright.js
CHANGED
|
@@ -80,6 +80,7 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
|
|
|
80
80
|
* * `basicAuth`: (optional) the basic authentication to pass to base url. Example: {username: 'username', password: 'password'}
|
|
81
81
|
* * `windowSize`: (optional) default window size. Set a dimension like `640x480`.
|
|
82
82
|
* * `userAgent`: (optional) user-agent string.
|
|
83
|
+
* * `locale`: (optional) locale string. Example: 'en-GB', 'de-DE', 'fr-FR', ...
|
|
83
84
|
* * `manualStart`: (optional, default: false) - do not start browser before a test, start it manually inside a helper with `this.helpers["Playwright"]._startBrowser()`.
|
|
84
85
|
* * `chromium`: (optional) pass additional chromium options
|
|
85
86
|
* * `electron`: (optional) pass additional electron options
|
|
@@ -197,6 +198,19 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
|
|
|
197
198
|
* }
|
|
198
199
|
* ```
|
|
199
200
|
*
|
|
201
|
+
* #### Example #7: Launch test with a specifc user locale
|
|
202
|
+
*
|
|
203
|
+
* ```js
|
|
204
|
+
* {
|
|
205
|
+
* helpers: {
|
|
206
|
+
* Playwright : {
|
|
207
|
+
* url: "http://localhost",
|
|
208
|
+
* locale: "fr-FR",
|
|
209
|
+
* }
|
|
210
|
+
* }
|
|
211
|
+
* }
|
|
212
|
+
* ```
|
|
213
|
+
*
|
|
200
214
|
* Note: When connecting to remote browser `show` and specific `chrome` options (e.g. `headless` or `devtools`) are ignored.
|
|
201
215
|
*
|
|
202
216
|
* ## Access From Helpers
|
|
@@ -351,9 +365,11 @@ class Playwright extends Helper {
|
|
|
351
365
|
return err.message.includes('context');
|
|
352
366
|
},
|
|
353
367
|
});
|
|
368
|
+
|
|
354
369
|
if (this.options.restart && !this.options.manualStart) await this._startBrowser();
|
|
355
370
|
if (!this.isRunning && !this.options.manualStart) await this._startBrowser();
|
|
356
371
|
|
|
372
|
+
this.isAuthenticated = false;
|
|
357
373
|
if (this.isElectron) {
|
|
358
374
|
this.browserContext = this.browser.context();
|
|
359
375
|
} else if (this.userDataDir) {
|
|
@@ -364,8 +380,14 @@ class Playwright extends Helper {
|
|
|
364
380
|
acceptDownloads: true,
|
|
365
381
|
...this.options.emulate,
|
|
366
382
|
};
|
|
383
|
+
if (this.options.basicAuth) {
|
|
384
|
+
contextOptions.httpCredentials = this.options.basicAuth;
|
|
385
|
+
this.isAuthenticated = true;
|
|
386
|
+
}
|
|
367
387
|
if (this.options.recordVideo) contextOptions.recordVideo = this.options.recordVideo;
|
|
368
388
|
if (this.storageState) contextOptions.storageState = this.storageState;
|
|
389
|
+
if (this.options.userAgent) contextOptions.userAgent = this.options.userAgent;
|
|
390
|
+
if (this.options.locale) contextOptions.locale = this.options.locale;
|
|
369
391
|
this.browserContext = await this.browser.newContext(contextOptions); // Adding the HTTPSError ignore in the context so that we can ignore those errors
|
|
370
392
|
}
|
|
371
393
|
|
|
@@ -564,9 +586,14 @@ class Playwright extends Helper {
|
|
|
564
586
|
this.page = page;
|
|
565
587
|
if (!page) return;
|
|
566
588
|
page.setDefaultNavigationTimeout(this.options.getPageTimeout);
|
|
589
|
+
|
|
590
|
+
page.on('crash', async () => {
|
|
591
|
+
console.log('ERROR: Page has crashed, closing page!');
|
|
592
|
+
await page.close();
|
|
593
|
+
});
|
|
567
594
|
this.context = await this.page;
|
|
568
595
|
this.contextLocator = null;
|
|
569
|
-
if (this.
|
|
596
|
+
if (this.options.browser === 'chrome') {
|
|
570
597
|
await page.bringToFront();
|
|
571
598
|
}
|
|
572
599
|
}
|
|
@@ -730,9 +757,9 @@ class Playwright extends Helper {
|
|
|
730
757
|
url = this.options.url + url;
|
|
731
758
|
}
|
|
732
759
|
|
|
733
|
-
if (this.
|
|
760
|
+
if (this.options.basicAuth && (this.isAuthenticated !== true)) {
|
|
734
761
|
if (url.includes(this.options.url)) {
|
|
735
|
-
await this.browserContext.setHTTPCredentials(this.
|
|
762
|
+
await this.browserContext.setHTTPCredentials(this.options.basicAuth);
|
|
736
763
|
this.isAuthenticated = true;
|
|
737
764
|
}
|
|
738
765
|
}
|
|
@@ -795,7 +822,7 @@ class Playwright extends Helper {
|
|
|
795
822
|
if (!customHeaders) {
|
|
796
823
|
throw new Error('Cannot send empty headers.');
|
|
797
824
|
}
|
|
798
|
-
return this.
|
|
825
|
+
return this.browserContext.setExtraHTTPHeaders(customHeaders);
|
|
799
826
|
}
|
|
800
827
|
|
|
801
828
|
/**
|
|
@@ -2565,6 +2592,11 @@ class Playwright extends Helper {
|
|
|
2565
2592
|
|
|
2566
2593
|
async _failed(test) {
|
|
2567
2594
|
await this._withinEnd();
|
|
2595
|
+
|
|
2596
|
+
if (!test.artifacts) {
|
|
2597
|
+
test.artifacts = {};
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2568
2600
|
if (this.options.recordVideo && this.page.video()) {
|
|
2569
2601
|
test.artifacts.video = await this.page.video().path();
|
|
2570
2602
|
}
|
|
@@ -2946,11 +2978,11 @@ class Playwright extends Helper {
|
|
|
2946
2978
|
}
|
|
2947
2979
|
|
|
2948
2980
|
/**
|
|
2949
|
-
* Waits for a network
|
|
2981
|
+
* Waits for a network response.
|
|
2950
2982
|
*
|
|
2951
2983
|
* ```js
|
|
2952
2984
|
* I.waitForResponse('http://example.com/resource');
|
|
2953
|
-
* I.waitForResponse(
|
|
2985
|
+
* I.waitForResponse(response => response.url() === 'https://example.com' && response.status() === 200);
|
|
2954
2986
|
* ```
|
|
2955
2987
|
*
|
|
2956
2988
|
* @param {string|function} urlOrPredicate
|
|
@@ -3059,26 +3091,6 @@ class Playwright extends Helper {
|
|
|
3059
3091
|
return this.page.waitForNavigation(opts);
|
|
3060
3092
|
}
|
|
3061
3093
|
|
|
3062
|
-
/**
|
|
3063
|
-
* Waits for a function to return true (waits for 1sec by default).
|
|
3064
|
-
*
|
|
3065
|
-
* ```js
|
|
3066
|
-
* I.waitUntil(() => window.requests == 0);
|
|
3067
|
-
* I.waitUntil(() => window.requests == 0, 5);
|
|
3068
|
-
* ```
|
|
3069
|
-
*
|
|
3070
|
-
* @param {function|string} fn function which is executed in browser context.
|
|
3071
|
-
* @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
|
|
3072
|
-
* @param {string} [timeoutMsg=''] message to show in case of timeout fail.
|
|
3073
|
-
* @param {?number} [interval=null]
|
|
3074
|
-
*/
|
|
3075
|
-
async waitUntil(fn, sec = null) {
|
|
3076
|
-
console.log('This method will remove in CodeceptJS 1.4; use `waitForFunction` instead!');
|
|
3077
|
-
const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
|
|
3078
|
-
const context = await this._getContext();
|
|
3079
|
-
return context.waitForFunction(fn, { timeout: waitTimeout });
|
|
3080
|
-
}
|
|
3081
|
-
|
|
3082
3094
|
async waitUntilExists(locator, sec) {
|
|
3083
3095
|
console.log(`waitUntilExists deprecated:
|
|
3084
3096
|
* use 'waitForElement' to wait for element to be attached
|
|
@@ -3541,13 +3553,10 @@ async function targetCreatedHandler(page) {
|
|
|
3541
3553
|
});
|
|
3542
3554
|
});
|
|
3543
3555
|
page.on('console', (msg) => {
|
|
3544
|
-
this.debugSection(`Browser:${ucfirst(msg.type())}`, (msg._text || '') + msg.args().join(' '));
|
|
3556
|
+
this.debugSection(`Browser:${ucfirst(msg.type())}`, (msg.text && msg.text() || msg._text || '') + msg.args().join(' '));
|
|
3545
3557
|
consoleLogStore.add(msg);
|
|
3546
3558
|
});
|
|
3547
3559
|
|
|
3548
|
-
if (this.options.userAgent) {
|
|
3549
|
-
await page.setUserAgent(this.options.userAgent);
|
|
3550
|
-
}
|
|
3551
3560
|
if (this.options.windowSize && this.options.windowSize.indexOf('x') > 0 && this._getType() === 'Browser') {
|
|
3552
3561
|
await page.setViewportSize(parseWindowSize(this.options.windowSize));
|
|
3553
3562
|
}
|
package/docs/build/Protractor.js
CHANGED
|
@@ -1181,11 +1181,14 @@ class Protractor extends Helper {
|
|
|
1181
1181
|
}
|
|
1182
1182
|
|
|
1183
1183
|
/**
|
|
1184
|
-
*
|
|
1185
|
-
*
|
|
1186
|
-
*
|
|
1187
|
-
*
|
|
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
|
-
|
|
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
|
*
|
package/docs/build/Puppeteer.js
CHANGED
|
@@ -264,7 +264,7 @@ class Puppeteer extends Helper {
|
|
|
264
264
|
async _before() {
|
|
265
265
|
this.sessionPages = {};
|
|
266
266
|
recorder.retry({
|
|
267
|
-
retries:
|
|
267
|
+
retries: 3,
|
|
268
268
|
when: err => {
|
|
269
269
|
if (!err || typeof (err.message) !== 'string') {
|
|
270
270
|
return false;
|
|
@@ -561,10 +561,9 @@ class Puppeteer extends Helper {
|
|
|
561
561
|
this.context = null;
|
|
562
562
|
popupStore.clear();
|
|
563
563
|
this.isAuthenticated = false;
|
|
564
|
+
await this.browser.close();
|
|
564
565
|
if (this.isRemoteBrowser) {
|
|
565
566
|
await this.browser.disconnect();
|
|
566
|
-
} else {
|
|
567
|
-
await this.browser.close();
|
|
568
567
|
}
|
|
569
568
|
}
|
|
570
569
|
|
|
@@ -852,11 +851,14 @@ class Puppeteer extends Helper {
|
|
|
852
851
|
}
|
|
853
852
|
|
|
854
853
|
/**
|
|
855
|
-
*
|
|
856
|
-
*
|
|
857
|
-
*
|
|
858
|
-
*
|
|
859
|
-
*
|
|
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
|
+
*
|
|
860
862
|
*/
|
|
861
863
|
async seeTitleEquals(text) {
|
|
862
864
|
const title = await this.page.title();
|
|
@@ -3102,26 +3104,6 @@ class Puppeteer extends Helper {
|
|
|
3102
3104
|
return this.page.waitForNavigation(opts);
|
|
3103
3105
|
}
|
|
3104
3106
|
|
|
3105
|
-
/**
|
|
3106
|
-
* Waits for a function to return true (waits for 1sec by default).
|
|
3107
|
-
*
|
|
3108
|
-
* ```js
|
|
3109
|
-
* I.waitUntil(() => window.requests == 0);
|
|
3110
|
-
* I.waitUntil(() => window.requests == 0, 5);
|
|
3111
|
-
* ```
|
|
3112
|
-
*
|
|
3113
|
-
* @param {function|string} fn function which is executed in browser context.
|
|
3114
|
-
* @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
|
|
3115
|
-
* @param {string} [timeoutMsg=''] message to show in case of timeout fail.
|
|
3116
|
-
* @param {?number} [interval=null]
|
|
3117
|
-
*/
|
|
3118
|
-
async waitUntil(fn, sec = null) {
|
|
3119
|
-
console.log('This method will remove in CodeceptJS 1.4; use `waitForFunction` instead!');
|
|
3120
|
-
const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
|
|
3121
|
-
const context = await this._getContext();
|
|
3122
|
-
return context.waitForFunction(fn, { timeout: waitTimeout });
|
|
3123
|
-
}
|
|
3124
|
-
|
|
3125
3107
|
async waitUntilExists(locator, sec) {
|
|
3126
3108
|
console.log(`waitUntilExists deprecated:
|
|
3127
3109
|
* use 'waitForElement' to wait for element to be attached
|
package/docs/build/REST.js
CHANGED
package/docs/build/WebDriver.js
CHANGED
|
@@ -481,7 +481,7 @@ class WebDriver extends Helper {
|
|
|
481
481
|
try {
|
|
482
482
|
require('webdriverio');
|
|
483
483
|
} catch (e) {
|
|
484
|
-
return ['webdriverio@^
|
|
484
|
+
return ['webdriverio@^6.12.1'];
|
|
485
485
|
}
|
|
486
486
|
}
|
|
487
487
|
|
|
@@ -582,7 +582,7 @@ class WebDriver extends Helper {
|
|
|
582
582
|
this.context = this.root;
|
|
583
583
|
if (this.options.restart && !this.options.manualStart) return this._startBrowser();
|
|
584
584
|
if (!this.isRunning && !this.options.manualStart) return this._startBrowser();
|
|
585
|
-
this.$$ = this.browser.$$.bind(this.browser);
|
|
585
|
+
if (this.browser) this.$$ = this.browser.$$.bind(this.browser);
|
|
586
586
|
return this.browser;
|
|
587
587
|
}
|
|
588
588
|
|
|
@@ -875,7 +875,7 @@ class WebDriver extends Helper {
|
|
|
875
875
|
* I.defineTimeout({ implicit: 10000, pageLoad: 10000, script: 5000 });
|
|
876
876
|
* ```
|
|
877
877
|
*
|
|
878
|
-
* @param {
|
|
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,109 @@ layout: Section
|
|
|
7
7
|
|
|
8
8
|
# Releases
|
|
9
9
|
|
|
10
|
+
## 3.2.2
|
|
11
|
+
|
|
12
|
+
* **[Playwright]** Reverted removal of retry on context errors. Fixes [#3130](https://github.com/codeceptjs/CodeceptJS/issues/3130)
|
|
13
|
+
* Timeout improvements by **[nikocanvacom](https://github.com/nikocanvacom)**:
|
|
14
|
+
* Added priorites to timeouts
|
|
15
|
+
* Added `overrideStepLimits` to [stepTimeout plugin](https://codecept.io/plugins/#steptimeout) to override steps timeouts set by `limitTime`.
|
|
16
|
+
* Fixed step timeout not working due to override by NaN by test timeout [#3126](https://github.com/codeceptjs/CodeceptJS/issues/3126)
|
|
17
|
+
* **[Appium]** Fixed logging error when `manualStart` is true. See [#3140](https://github.com/codeceptjs/CodeceptJS/issues/3140) by **[nikocanvacom](https://github.com/nikocanvacom)**
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## 3.2.1
|
|
21
|
+
|
|
22
|
+
> âģī¸ This release fixes hanging of tests by reducing timeouts for automatic retries on failures.
|
|
23
|
+
|
|
24
|
+
* [retryFailedStep plugin] **New Defaults**: retries steps up to 3 times with factor of 1.5 (previously 5 with factor 2)
|
|
25
|
+
* **[Playwright]** - disabled retry on failed context actions (not needed anymore)
|
|
26
|
+
* **[Puppeteer]** - reduced retries on context failures to 3 times.
|
|
27
|
+
* **[Playwright]** Handling `crash` event to automatically close crashed pages.
|
|
28
|
+
|
|
29
|
+
## 3.2.0
|
|
30
|
+
|
|
31
|
+
đŠī¸ Features:
|
|
32
|
+
|
|
33
|
+
**[Timeouts](https://codecept.io/advanced/#timeout) implemented**
|
|
34
|
+
* global timeouts (via `timeout` config option).
|
|
35
|
+
* _Breaking change:_ timeout option expects **timeout in seconds**, not in milliseconds as it was previously.
|
|
36
|
+
* test timeouts (via `Scenario` and `Feature` options)
|
|
37
|
+
* _Breaking change:_ `Feature().timeout()` and `Scenario().timeout()` calls has no effect and are deprecated
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
// set timeout for every test in suite to 10 secs
|
|
41
|
+
Feature('tests with timeout', { timeout: 10 });
|
|
42
|
+
|
|
43
|
+
// set timeout for this test to 20 secs
|
|
44
|
+
Scenario('a test with timeout', { timeout: 20 }, ({ I }) => {});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
* step timeouts (See [#3059](https://github.com/codeceptjs/CodeceptJS/issues/3059) by **[nikocanvacom](https://github.com/nikocanvacom)**)
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
// set step timeout to 5 secs
|
|
51
|
+
I.limitTime(5).click('Link');
|
|
52
|
+
```
|
|
53
|
+
* `stepTimeout` plugin introduced to automatically add timeouts for each step ([#3059](https://github.com/codeceptjs/CodeceptJS/issues/3059) by **[nikocanvacom](https://github.com/nikocanvacom)**).
|
|
54
|
+
|
|
55
|
+
[**retryTo**](/plugins/#retryto) plugin introduced to rerun a set of steps on failure:
|
|
56
|
+
|
|
57
|
+
```js
|
|
58
|
+
// editing in text in iframe
|
|
59
|
+
// if iframe was not loaded - retry 5 times
|
|
60
|
+
await retryTo(() => {
|
|
61
|
+
I.switchTo('#editor frame');
|
|
62
|
+
I.fillField('textarea', 'value');
|
|
63
|
+
}, 5);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
* **[Playwright]** added `locale` configuration
|
|
67
|
+
* **[WebDriver]** upgraded to webdriverio v7
|
|
68
|
+
|
|
69
|
+
đ Bugfixes:
|
|
70
|
+
|
|
71
|
+
* Fixed allure plugin "Unexpected endStep()" error in [#3098](https://github.com/codeceptjs/CodeceptJS/issues/3098) by **[abhimanyupandian](https://github.com/abhimanyupandian)**
|
|
72
|
+
* **[Puppeteer]** always close remote browser on test end. See [#3054](https://github.com/codeceptjs/CodeceptJS/issues/3054) by **[mattonem](https://github.com/mattonem)**
|
|
73
|
+
* stepbyStepReport Plugin: Disabled screenshots after test has failed. See [#3119](https://github.com/codeceptjs/CodeceptJS/issues/3119) by **[ioannisChalkias](https://github.com/ioannisChalkias)**
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
## 3.1.3
|
|
77
|
+
|
|
78
|
+
đŠī¸ Features:
|
|
79
|
+
|
|
80
|
+
* BDD Improvement. Added `DataTableArgument` class to work with table data structures.
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
const { DataTableArgument } = require('codeceptjs');
|
|
84
|
+
//...
|
|
85
|
+
Given('I have an employee card', (table) => {
|
|
86
|
+
const dataTableArgument = new DataTableArgument(table);
|
|
87
|
+
const hashes = dataTableArgument.hashes();
|
|
88
|
+
// hashes = [{ name: 'Harry', surname: 'Potter', position: 'Seeker' }];
|
|
89
|
+
const rows = dataTableArgument.rows();
|
|
90
|
+
// rows = [['Harry', 'Potter', Seeker]];
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
See updated [BDD section](https://codecept.io/bdd/) for more API options. Thanks to **[EgorBodnar](https://github.com/EgorBodnar)**
|
|
94
|
+
|
|
95
|
+
* 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)**
|
|
96
|
+
* API updates: Added `test.file` and `suite.file` properties to `test` and `suite` objects to use in helpers and plugins.
|
|
97
|
+
|
|
98
|
+
đ Bugfixes:
|
|
99
|
+
|
|
100
|
+
* **[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)
|
|
101
|
+
* **[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)
|
|
102
|
+
* **[WebDriver]** Updated `webdriverio` default version to `^6.12.1`. See [#3043](https://github.com/codeceptjs/CodeceptJS/issues/3043) by **[sridhareaswaran](https://github.com/sridhareaswaran)**
|
|
103
|
+
* **[Playwright]** `I.haveRequestHeaders` affects all tabs. See [#3049](https://github.com/codeceptjs/CodeceptJS/issues/3049) by **[jancorvus](https://github.com/jancorvus)**
|
|
104
|
+
* BDD: Fixed unhandled empty feature files. Fix [#3046](https://github.com/codeceptjs/CodeceptJS/issues/3046) by **[abhimanyupandian](https://github.com/abhimanyupandian)**
|
|
105
|
+
* Fixed `RangeError: Invalid string length` in `recorder.js` when running huge amount of tests.
|
|
106
|
+
* **[Appium]** Fixed definitions for `touchPerform`, `hideDeviceKeyboard`, `removeApp` by **[mirao](https://github.com/mirao)**
|
|
107
|
+
|
|
108
|
+
đ Documentation:
|
|
109
|
+
|
|
110
|
+
* Added Testrail reporter [Reports Docs](https://codecept.io/reports/#testrail)
|
|
111
|
+
|
|
112
|
+
|
|
10
113
|
## 3.1.2
|
|
11
114
|
|
|
12
115
|
đŠī¸ Features:
|
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.
|
package/docs/custom-helpers.md
CHANGED
|
@@ -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
|
-
###
|
|
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
|
-
```
|