codeceptjs 3.5.5 â 3.5.6
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/docs/build/FileSystem.js +1 -1
- package/docs/build/Playwright.js +51 -40
- package/docs/build/Puppeteer.js +4 -4
- package/docs/build/WebDriver.js +4 -4
- package/docs/changelog.md +1 -325
- package/docs/community-helpers.md +4 -8
- package/docs/examples.md +2 -8
- package/docs/helpers/FileSystem.md +1 -1
- package/docs/helpers/Playwright.md +1 -1
- package/docs/helpers/Puppeteer.md +1 -1
- package/docs/helpers/WebDriver.md +1 -1
- package/lib/codecept.js +3 -0
- package/lib/command/info.js +24 -0
- package/lib/command/run-workers.js +3 -2
- package/lib/command/run.js +3 -2
- package/lib/data/context.js +14 -6
- package/lib/helper/FileSystem.js +1 -1
- package/lib/helper/Playwright.js +51 -40
- package/lib/helper/Puppeteer.js +4 -4
- package/lib/helper/WebDriver.js +4 -4
- package/lib/helper/scripts/highlightElement.js +1 -1
- package/lib/pause.js +0 -2
- package/lib/plugin/autoLogin.js +0 -5
- package/lib/plugin/retryTo.js +0 -2
- package/lib/plugin/tryTo.js +0 -3
- package/lib/session.js +1 -1
- package/package.json +13 -13
- package/translations/fr-FR.js +13 -1
- package/typings/promiseBasedTypes.d.ts +1 -1
- package/typings/types.d.ts +5 -5
- package/CHANGELOG.md +0 -2887
package/docs/build/FileSystem.js
CHANGED
package/docs/build/Playwright.js
CHANGED
|
@@ -47,7 +47,6 @@ const {
|
|
|
47
47
|
setRestartStrategy, restartsSession, restartsContext, restartsBrowser,
|
|
48
48
|
} = require('./extras/PlaywrightRestartOpts');
|
|
49
49
|
const { createValueEngine, createDisabledEngine } = require('./extras/PlaywrightPropEngine');
|
|
50
|
-
const { highlightElement } = require('./scripts/highlightElement');
|
|
51
50
|
|
|
52
51
|
const pathSeparator = path.sep;
|
|
53
52
|
|
|
@@ -94,7 +93,7 @@ const pathSeparator = path.sep;
|
|
|
94
93
|
* @prop {string[]} [ignoreLog] - An array with console message types that are not logged to debug log. Default value is `['warning', 'log']`. E.g. you can set `[]` to log all messages. See all possible [values](https://playwright.dev/docs/api/class-consolemessage#console-message-type).
|
|
95
94
|
* @prop {boolean} [ignoreHTTPSErrors] - Allows access to untrustworthy pages, e.g. to a page with an expired certificate. Default value is `false`
|
|
96
95
|
* @prop {boolean} [bypassCSP] - bypass Content Security Policy or CSP
|
|
97
|
-
* @prop {boolean} [highlightElement] - highlight the interacting elements. Default: false
|
|
96
|
+
* @prop {boolean} [highlightElement] - highlight the interacting elements. Default: false. Note: only activate under verbose mode (--verbose).
|
|
98
97
|
*/
|
|
99
98
|
const config = {};
|
|
100
99
|
|
|
@@ -835,8 +834,9 @@ class Playwright extends Helper {
|
|
|
835
834
|
|
|
836
835
|
async _stopBrowser() {
|
|
837
836
|
this.withinLocator = null;
|
|
838
|
-
this._setPage(null);
|
|
837
|
+
await this._setPage(null);
|
|
839
838
|
this.context = null;
|
|
839
|
+
this.frame = null;
|
|
840
840
|
popupStore.clear();
|
|
841
841
|
await this.browser.close();
|
|
842
842
|
}
|
|
@@ -875,6 +875,7 @@ class Playwright extends Helper {
|
|
|
875
875
|
this.withinLocator = null;
|
|
876
876
|
this.context = await this.page;
|
|
877
877
|
this.contextLocator = null;
|
|
878
|
+
this.frame = null;
|
|
878
879
|
}
|
|
879
880
|
|
|
880
881
|
_extractDataFromPerformanceTiming(timing, ...dataNames) {
|
|
@@ -1299,6 +1300,9 @@ class Playwright extends Helper {
|
|
|
1299
1300
|
*/
|
|
1300
1301
|
async _locate(locator) {
|
|
1301
1302
|
const context = await this.context || await this._getContext();
|
|
1303
|
+
|
|
1304
|
+
if (this.frame) return findElements(this.frame, locator);
|
|
1305
|
+
|
|
1302
1306
|
return findElements(context, locator);
|
|
1303
1307
|
}
|
|
1304
1308
|
|
|
@@ -2009,7 +2013,7 @@ class Playwright extends Helper {
|
|
|
2009
2013
|
|
|
2010
2014
|
await el.clear();
|
|
2011
2015
|
|
|
2012
|
-
highlightActiveElement.call(this, el
|
|
2016
|
+
await highlightActiveElement.call(this, el);
|
|
2013
2017
|
|
|
2014
2018
|
await el.type(value.toString(), { delay: this.options.pressKeyDelay });
|
|
2015
2019
|
|
|
@@ -2039,7 +2043,7 @@ class Playwright extends Helper {
|
|
|
2039
2043
|
|
|
2040
2044
|
const el = els[0];
|
|
2041
2045
|
|
|
2042
|
-
highlightActiveElement.call(this, el
|
|
2046
|
+
await highlightActiveElement.call(this, el);
|
|
2043
2047
|
|
|
2044
2048
|
await el.clear();
|
|
2045
2049
|
|
|
@@ -2065,7 +2069,7 @@ class Playwright extends Helper {
|
|
|
2065
2069
|
async appendField(field, value) {
|
|
2066
2070
|
const els = await findFields.call(this, field);
|
|
2067
2071
|
assertElementExists(els, field, 'Field');
|
|
2068
|
-
highlightActiveElement.call(this, els[0]
|
|
2072
|
+
await highlightActiveElement.call(this, els[0]);
|
|
2069
2073
|
await els[0].press('End');
|
|
2070
2074
|
await els[0].type(value.toString(), { delay: this.options.pressKeyDelay });
|
|
2071
2075
|
return this._waitForAction();
|
|
@@ -2167,7 +2171,7 @@ class Playwright extends Helper {
|
|
|
2167
2171
|
assertElementExists(els, select, 'Selectable field');
|
|
2168
2172
|
const el = els[0];
|
|
2169
2173
|
|
|
2170
|
-
highlightActiveElement.call(this, el
|
|
2174
|
+
await highlightActiveElement.call(this, el);
|
|
2171
2175
|
|
|
2172
2176
|
if (!Array.isArray(option)) option = [option];
|
|
2173
2177
|
|
|
@@ -2555,11 +2559,11 @@ class Playwright extends Helper {
|
|
|
2555
2559
|
* @returns {Promise<any>}
|
|
2556
2560
|
*/
|
|
2557
2561
|
async executeScript(fn, arg) {
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2562
|
+
if (this.context && this.context.constructor.name === 'FrameLocator') {
|
|
2563
|
+
// switching to iframe context
|
|
2564
|
+
return this.context.locator(':root').evaluate(fn, arg);
|
|
2561
2565
|
}
|
|
2562
|
-
return
|
|
2566
|
+
return this.page.evaluate.apply(this.page, [fn, arg]);
|
|
2563
2567
|
}
|
|
2564
2568
|
|
|
2565
2569
|
/**
|
|
@@ -3313,7 +3317,7 @@ class Playwright extends Helper {
|
|
|
3313
3317
|
}
|
|
3314
3318
|
|
|
3315
3319
|
async _getContext() {
|
|
3316
|
-
if (this.context && this.context.constructor.name === '
|
|
3320
|
+
if (this.context && this.context.constructor.name === 'FrameLocator') {
|
|
3317
3321
|
return this.context;
|
|
3318
3322
|
}
|
|
3319
3323
|
return this.page;
|
|
@@ -3418,6 +3422,14 @@ class Playwright extends Helper {
|
|
|
3418
3422
|
}, [locator.value, text, $XPath.toString()], { timeout: waitTimeout });
|
|
3419
3423
|
}
|
|
3420
3424
|
} else {
|
|
3425
|
+
// we have this as https://github.com/microsoft/playwright/issues/26829 is not yet implemented
|
|
3426
|
+
if (this.frame) {
|
|
3427
|
+
const { setTimeout } = require('timers/promises');
|
|
3428
|
+
await setTimeout(waitTimeout);
|
|
3429
|
+
waiter = await this.frame.locator(`:has-text('${text}')`).first().isVisible();
|
|
3430
|
+
if (!waiter) throw new Error(`Text "${text}" was not found on page after ${waitTimeout / 1000} sec`);
|
|
3431
|
+
return;
|
|
3432
|
+
}
|
|
3421
3433
|
waiter = contextObject.waitForFunction(text => document.body && document.body.innerText.indexOf(text) > -1, text, { timeout: waitTimeout });
|
|
3422
3434
|
}
|
|
3423
3435
|
return waiter.catch((err) => {
|
|
@@ -3481,37 +3493,37 @@ class Playwright extends Helper {
|
|
|
3481
3493
|
}
|
|
3482
3494
|
|
|
3483
3495
|
if (locator >= 0 && locator < childFrames.length) {
|
|
3484
|
-
this.context =
|
|
3496
|
+
this.context = await this.page.frameLocator('iframe').nth(locator);
|
|
3485
3497
|
this.contextLocator = locator;
|
|
3486
3498
|
} else {
|
|
3487
3499
|
throw new Error('Element #invalidIframeSelector was not found by text|CSS|XPath');
|
|
3488
3500
|
}
|
|
3489
3501
|
return;
|
|
3490
3502
|
}
|
|
3491
|
-
let contentFrame;
|
|
3492
3503
|
|
|
3493
3504
|
if (!locator) {
|
|
3494
|
-
this.context =
|
|
3505
|
+
this.context = this.page;
|
|
3495
3506
|
this.contextLocator = null;
|
|
3507
|
+
this.frame = null;
|
|
3496
3508
|
return;
|
|
3497
3509
|
}
|
|
3498
3510
|
|
|
3499
3511
|
// iframe by selector
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3512
|
+
locator = buildLocatorString(new Locator(locator, 'css'));
|
|
3513
|
+
const frame = await this._locateElement(locator);
|
|
3514
|
+
|
|
3515
|
+
if (!frame) {
|
|
3516
|
+
throw new Error(`Frame ${JSON.stringify(locator)} was not found by text|CSS|XPath`);
|
|
3503
3517
|
}
|
|
3504
3518
|
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
// get content of the iframe using its name
|
|
3510
|
-
} else if (locator.value.toLowerCase().includes('name=')) {
|
|
3511
|
-
const frameName = locator.value.split('=')[1].replace(/"/g, '').replaceAll(/]/g, '');
|
|
3512
|
-
contentFrame = await this.page.frame(frameName);
|
|
3519
|
+
if (this.frame) {
|
|
3520
|
+
this.frame = await this.frame.frameLocator(locator);
|
|
3521
|
+
} else {
|
|
3522
|
+
this.frame = await this.page.frameLocator(locator);
|
|
3513
3523
|
}
|
|
3514
3524
|
|
|
3525
|
+
const contentFrame = this.frame;
|
|
3526
|
+
|
|
3515
3527
|
if (contentFrame) {
|
|
3516
3528
|
this.context = contentFrame;
|
|
3517
3529
|
this.contextLocator = null;
|
|
@@ -4272,7 +4284,7 @@ async function findElement(matcher, locator) {
|
|
|
4272
4284
|
if (locator.react) return findReact(matcher, locator);
|
|
4273
4285
|
locator = new Locator(locator, 'css');
|
|
4274
4286
|
|
|
4275
|
-
return matcher.locator(buildLocatorString(locator));
|
|
4287
|
+
return matcher.locator(buildLocatorString(locator)).first();
|
|
4276
4288
|
}
|
|
4277
4289
|
|
|
4278
4290
|
async function getVisibleElements(elements) {
|
|
@@ -4302,7 +4314,7 @@ async function proceedClick(locator, context = null, options = {}) {
|
|
|
4302
4314
|
assertElementExists(els, locator, 'Clickable element');
|
|
4303
4315
|
}
|
|
4304
4316
|
|
|
4305
|
-
highlightActiveElement.call(this, els[0]
|
|
4317
|
+
await highlightActiveElement.call(this, els[0]);
|
|
4306
4318
|
|
|
4307
4319
|
/*
|
|
4308
4320
|
using the force true options itself but instead dispatching a click
|
|
@@ -4352,13 +4364,9 @@ async function proceedSee(assertType, text, context, strict = false) {
|
|
|
4352
4364
|
let allText;
|
|
4353
4365
|
|
|
4354
4366
|
if (!context) {
|
|
4355
|
-
|
|
4356
|
-
if (el && !el.getProperty) {
|
|
4357
|
-
// Fallback to body
|
|
4358
|
-
el = await this.page.$('body');
|
|
4359
|
-
}
|
|
4367
|
+
const el = await this.context;
|
|
4360
4368
|
|
|
4361
|
-
allText = [await el.innerText()];
|
|
4369
|
+
allText = [await el.locator('body').innerText()];
|
|
4362
4370
|
description = 'web application';
|
|
4363
4371
|
} else {
|
|
4364
4372
|
const locator = new Locator(context, 'css');
|
|
@@ -4531,8 +4539,7 @@ async function elementSelected(element) {
|
|
|
4531
4539
|
function isFrameLocator(locator) {
|
|
4532
4540
|
locator = new Locator(locator);
|
|
4533
4541
|
if (locator.isFrame()) {
|
|
4534
|
-
|
|
4535
|
-
return _locator.value;
|
|
4542
|
+
return locator.value;
|
|
4536
4543
|
}
|
|
4537
4544
|
return false;
|
|
4538
4545
|
}
|
|
@@ -4728,10 +4735,14 @@ async function saveTraceForContext(context, name) {
|
|
|
4728
4735
|
return fileName;
|
|
4729
4736
|
}
|
|
4730
4737
|
|
|
4731
|
-
function highlightActiveElement(element
|
|
4732
|
-
if (
|
|
4733
|
-
|
|
4734
|
-
|
|
4738
|
+
async function highlightActiveElement(element) {
|
|
4739
|
+
if (this.options.highlightElement && global.debugMode) {
|
|
4740
|
+
await element.evaluate(el => {
|
|
4741
|
+
const prevStyle = el.style.boxShadow;
|
|
4742
|
+
el.style.boxShadow = '0px 0px 4px 3px rgba(255, 0, 0, 0.7)';
|
|
4743
|
+
setTimeout(() => el.style.boxShadow = prevStyle, 2000);
|
|
4744
|
+
});
|
|
4745
|
+
}
|
|
4735
4746
|
}
|
|
4736
4747
|
|
|
4737
4748
|
const createAdvancedTestResults = (url, dataToCheck, requests) => {
|
package/docs/build/Puppeteer.js
CHANGED
|
@@ -69,7 +69,7 @@ const consoleLogStore = new Console();
|
|
|
69
69
|
* @prop {boolean} [manualStart=false] - do not start browser before a test, start it manually inside a helper with `this.helpers["Puppeteer"]._startBrowser()`.
|
|
70
70
|
* @prop {string} [browser=chrome] - can be changed to `firefox` when using [puppeteer-firefox](https://codecept.io/helpers/Puppeteer-firefox).
|
|
71
71
|
* @prop {object} [chrome] - pass additional [Puppeteer run options](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions).
|
|
72
|
-
* @prop {boolean} [highlightElement] - highlight the interacting elements. Default: false
|
|
72
|
+
* @prop {boolean} [highlightElement] - highlight the interacting elements. Default: false. Note: only activate under verbose mode (--verbose).
|
|
73
73
|
*/
|
|
74
74
|
const config = {};
|
|
75
75
|
|
|
@@ -3810,7 +3810,7 @@ function getNormalizedKey(key) {
|
|
|
3810
3810
|
}
|
|
3811
3811
|
|
|
3812
3812
|
function highlightActiveElement(element, context) {
|
|
3813
|
-
if (
|
|
3814
|
-
|
|
3815
|
-
|
|
3813
|
+
if (this.options.highlightElement && global.debugMode) {
|
|
3814
|
+
highlightElement(element, context);
|
|
3815
|
+
}
|
|
3816
3816
|
}
|
package/docs/build/WebDriver.js
CHANGED
|
@@ -62,7 +62,7 @@ const webRoot = 'body';
|
|
|
62
62
|
* @prop {object} [desiredCapabilities] Selenium's [desired capabilities](https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities).
|
|
63
63
|
* @prop {boolean} [manualStart=false] - do not start browser before a test, start it manually inside a helper with `this.helpers["WebDriver"]._startBrowser()`.
|
|
64
64
|
* @prop {object} [timeouts] [WebDriver timeouts](http://webdriver.io/docs/timeouts.html) defined as hash.
|
|
65
|
-
* @prop {boolean} [highlightElement] - highlight the interacting elements. Default: false
|
|
65
|
+
* @prop {boolean} [highlightElement] - highlight the interacting elements. Default: false. Note: only activate under verbose mode (--verbose).
|
|
66
66
|
*/
|
|
67
67
|
const config = {};
|
|
68
68
|
|
|
@@ -4083,9 +4083,9 @@ function isModifierKey(key) {
|
|
|
4083
4083
|
}
|
|
4084
4084
|
|
|
4085
4085
|
function highlightActiveElement(element) {
|
|
4086
|
-
if (
|
|
4087
|
-
|
|
4088
|
-
|
|
4086
|
+
if (this.options.highlightElement && global.debugMode) {
|
|
4087
|
+
highlightElement(element, this.browser);
|
|
4088
|
+
}
|
|
4089
4089
|
}
|
|
4090
4090
|
|
|
4091
4091
|
function prepareLocateFn(context) {
|
package/docs/changelog.md
CHANGED
|
@@ -7,335 +7,11 @@ layout: Section
|
|
|
7
7
|
|
|
8
8
|
# Releases
|
|
9
9
|
|
|
10
|
-
## 3.5.5
|
|
11
|
-
|
|
12
|
-
đ Bug Fixes
|
|
13
|
-
* fix(browserstack): issue with vendor prefix ([#3845](https://github.com/codeceptjs/CodeceptJS/issues/3845)) - by **[KobeNguyenT](https://github.com/KobeNguyenT)**
|
|
14
|
-
```
|
|
15
|
-
export const caps = {
|
|
16
|
-
androidCaps: {
|
|
17
|
-
appiumV2: true,
|
|
18
|
-
host: "hub-cloud.browserstack.com",
|
|
19
|
-
port: 4444,
|
|
20
|
-
user: process.env.BROWSERSTACK_USER,
|
|
21
|
-
key: process.env.BROWSERSTACK_KEY,
|
|
22
|
-
'app': `bs://c700ce60cf13ae8ed97705a55b8e022f1hjhkjh3c5827c`,
|
|
23
|
-
browser: '',
|
|
24
|
-
desiredCapabilities: {
|
|
25
|
-
'appPackage': data.packageName,
|
|
26
|
-
'deviceName': process.env.DEVICE || 'Google Pixel 3',
|
|
27
|
-
'platformName': process.env.PLATFORM || 'android',
|
|
28
|
-
'platformVersion': process.env.OS_VERSION || '10.0',
|
|
29
|
-
'automationName': process.env.ENGINE || 'UIAutomator2',
|
|
30
|
-
'newCommandTimeout': 300000,
|
|
31
|
-
'androidDeviceReadyTimeout': 300000,
|
|
32
|
-
'androidInstallTimeout': 90000,
|
|
33
|
-
'appWaitDuration': 300000,
|
|
34
|
-
'autoGrantPermissions': true,
|
|
35
|
-
'gpsEnabled': true,
|
|
36
|
-
'isHeadless': false,
|
|
37
|
-
'noReset': false,
|
|
38
|
-
'noSign': true,
|
|
39
|
-
'bstack:options' : {
|
|
40
|
-
"appiumVersion" : "2.0.1",
|
|
41
|
-
},
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
}
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
* switchTo/within now supports strict locator ([#3847](https://github.com/codeceptjs/CodeceptJS/issues/3847)) - by **[KobeNguyenT](https://github.com/KobeNguyenT)**
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
I.switchTo({ css: 'iframe[id^=number-frame]' }) // support the strict locator
|
|
51
|
-
|
|
52
|
-
I.amOnPage('/iframe');
|
|
53
|
-
within({
|
|
54
|
-
frame: { css: '#number-frame-1234' }, // support the strict locator
|
|
55
|
-
}, () => {
|
|
56
|
-
I.fillField('user[login]', 'User');
|
|
57
|
-
I.fillField('user[email]', 'user@user.com');
|
|
58
|
-
I.fillField('user[password]', 'user@user.com');
|
|
59
|
-
I.click('button');
|
|
60
|
-
});
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
* Improve the IntelliSense when using other languages ([#3848](https://github.com/codeceptjs/CodeceptJS/issues/3848)) - by **[andonary](https://github.com/andonary)**
|
|
64
|
-
```
|
|
65
|
-
include: {
|
|
66
|
-
Je: './steps_file.js'
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
* bypassCSP support for Playwright helper ([#3865](https://github.com/codeceptjs/CodeceptJS/issues/3865)) - by **[sammeel](https://github.com/sammeel)**
|
|
71
|
-
```
|
|
72
|
-
helpers: {
|
|
73
|
-
Playwright: {
|
|
74
|
-
bypassCSP: true
|
|
75
|
-
}
|
|
76
|
-
```
|
|
77
|
-
* fix: missing requests when recording network ([#3834](https://github.com/codeceptjs/CodeceptJS/issues/3834)) - by **[KobeNguyenT](https://github.com/KobeNguyenT)**
|
|
78
|
-
|
|
79
|
-
đŠī¸ Features and Improvements
|
|
80
|
-
* Show environment info in verbose mode ([#3858](https://github.com/codeceptjs/CodeceptJS/issues/3858)) - by **[KobeNguyenT](https://github.com/KobeNguyenT)**
|
|
81
|
-
|
|
82
|
-
```
|
|
83
|
-
Environment information:-
|
|
84
|
-
|
|
85
|
-
codeceptVersion: "3.5.4"
|
|
86
|
-
nodeInfo: 18.16.0
|
|
87
|
-
osInfo: macOS 13.5
|
|
88
|
-
cpuInfo: (8) arm64 Apple M1 Pro
|
|
89
|
-
chromeInfo: 116.0.5845.179
|
|
90
|
-
edgeInfo: 116.0.1938.69
|
|
91
|
-
firefoxInfo: Not Found
|
|
92
|
-
safariInfo: 16.6
|
|
93
|
-
helpers: {
|
|
94
|
-
"Playwright": {
|
|
95
|
-
"url": "https://github.com",
|
|
96
|
-
"show": false,
|
|
97
|
-
"browser": "chromium",
|
|
98
|
-
"waitForNavigation": "load",
|
|
99
|
-
"waitForTimeout": 30000,
|
|
100
|
-
"trace": false,
|
|
101
|
-
"keepTraceForPassedTests": true
|
|
102
|
-
},
|
|
103
|
-
"CDPHelper": {
|
|
104
|
-
"require": "./helpers/CDPHelper.ts"
|
|
105
|
-
},
|
|
106
|
-
"OpenAI": {
|
|
107
|
-
"chunkSize": 8000
|
|
108
|
-
},
|
|
109
|
-
"ExpectHelper": {
|
|
110
|
-
"require": "codeceptjs-expect"
|
|
111
|
-
},
|
|
112
|
-
"REST": {
|
|
113
|
-
"endpoint": "https://reqres.in",
|
|
114
|
-
"timeout": 20000
|
|
115
|
-
},
|
|
116
|
-
"AllureHelper": {
|
|
117
|
-
"require": "./helpers/AllureHelper.ts"
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
plugins: {
|
|
121
|
-
"screenshotOnFail": {
|
|
122
|
-
"enabled": true
|
|
123
|
-
},
|
|
124
|
-
"tryTo": {
|
|
125
|
-
"enabled": true
|
|
126
|
-
},
|
|
127
|
-
"retryFailedStep": {
|
|
128
|
-
"enabled": true
|
|
129
|
-
},
|
|
130
|
-
"retryTo": {
|
|
131
|
-
"enabled": true
|
|
132
|
-
},
|
|
133
|
-
"eachElement": {
|
|
134
|
-
"enabled": true
|
|
135
|
-
},
|
|
136
|
-
"pauseOnFail": {}
|
|
137
|
-
}
|
|
138
|
-
***************************************
|
|
139
|
-
If you have questions ask them in our Slack: http://bit.ly/chat-codeceptjs
|
|
140
|
-
Or ask them on our discussion board: https://codecept.discourse.group/
|
|
141
|
-
Please copy environment info when you report issues on GitHub: https://github.com/Codeception/CodeceptJS/issues
|
|
142
|
-
***************************************
|
|
143
|
-
CodeceptJS v3.5.4 #StandWithUkraine
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
* some typings improvements ([#3855](https://github.com/codeceptjs/CodeceptJS/issues/3855)) - by **[nikzupancic](https://github.com/nikzupancic)**
|
|
147
|
-
* support the puppeteer 21.1.1 ([#3856](https://github.com/codeceptjs/CodeceptJS/issues/3856)) - by **[KobeNguyenT](https://github.com/KobeNguyenT)**
|
|
148
|
-
* fix: support secret value for some methods ([#3837](https://github.com/codeceptjs/CodeceptJS/issues/3837)) - by **[KobeNguyenT](https://github.com/KobeNguyenT)**
|
|
149
|
-
|
|
150
|
-
```
|
|
151
|
-
await I.amOnPage('/form/field_values');
|
|
152
|
-
await I.dontSeeInField('checkbox[]', secret('not seen one'));
|
|
153
|
-
await I.seeInField('checkbox[]', secret('see test one'));
|
|
154
|
-
await I.dontSeeInField('checkbox[]', secret('not seen two'));
|
|
155
|
-
await I.seeInField('checkbox[]', secret('see test two'));
|
|
156
|
-
await I.dontSeeInField('checkbox[]', secret('not seen three'));
|
|
157
|
-
await I.seeInField('checkbox[]', secret('see test three'));
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
đŠī¸ **Several bugfixes and improvements for Codecept-UI**
|
|
161
|
-
* Mask the secret value in UI
|
|
162
|
-
* Improve UX/UI
|
|
163
|
-
* PageObjects are now showing in UI
|
|
164
|
-
|
|
165
|
-
## 3.5.4
|
|
166
|
-
|
|
167
|
-
đ Bug Fixes:
|
|
168
|
-
* **[Playwright]** When passing `userDataDir`, it throws error after test execution ([#3814](https://github.com/codeceptjs/CodeceptJS/issues/3814)) - by **[KobeNguyenT](https://github.com/KobeNguyenT)**
|
|
169
|
-
* [CodeceptJS-CLI] Improve command to generate types ([#3788](https://github.com/codeceptjs/CodeceptJS/issues/3788)) - by **[KobeNguyenT](https://github.com/KobeNguyenT)**
|
|
170
|
-
* Heal plugin fix ([#3820](https://github.com/codeceptjs/CodeceptJS/issues/3820)) - by **[davert](https://github.com/davert)**
|
|
171
|
-
* Fix for error in using `all` with `run-workers` ([#3805](https://github.com/codeceptjs/CodeceptJS/issues/3805)) - by **[KobeNguyenT](https://github.com/KobeNguyenT)**
|
|
172
|
-
```js
|
|
173
|
-
helpers: {
|
|
174
|
-
Playwright: {
|
|
175
|
-
url: 'https://github.com',
|
|
176
|
-
show: false,
|
|
177
|
-
browser: 'chromium',
|
|
178
|
-
waitForNavigation: 'load',
|
|
179
|
-
waitForTimeout: 30_000,
|
|
180
|
-
trace: true,
|
|
181
|
-
keepTraceForPassedTests: true
|
|
182
|
-
},
|
|
183
|
-
},
|
|
184
|
-
multiple: {
|
|
185
|
-
profile1: {
|
|
186
|
-
browsers: [
|
|
187
|
-
{
|
|
188
|
-
browser: "chromium",
|
|
189
|
-
}
|
|
190
|
-
]
|
|
191
|
-
},
|
|
192
|
-
},
|
|
193
|
-
```
|
|
194
|
-
* Highlight elements issues ([#3779](https://github.com/codeceptjs/CodeceptJS/issues/3779)) ([#3778](https://github.com/codeceptjs/CodeceptJS/issues/3778)) - by **[philkas](https://github.com/philkas)**
|
|
195
|
-
* Support ` ` symbol in `I.see` method ([#3815](https://github.com/codeceptjs/CodeceptJS/issues/3815)) - by **[KobeNguyenT](https://github.com/KobeNguyenT)**
|
|
196
|
-
|
|
197
|
-
```js
|
|
198
|
-
// HTML code uses instead of space
|
|
199
|
-
<div class="dJHe_" style="color: rgb(255, 255, 255);">My Text!</div>
|
|
200
|
-
|
|
201
|
-
I.see("My Text!") // this test would work with both and space
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
đ Documentation
|
|
205
|
-
* Improve the configuration of electron testing when the app is build with electron-forge ([#3802](https://github.com/codeceptjs/CodeceptJS/issues/3802)) - by **[KobeNguyenT](https://github.com/KobeNguyenT)**
|
|
206
|
-
|
|
207
|
-
```js
|
|
208
|
-
const path = require("path");
|
|
209
|
-
|
|
210
|
-
exports.config = {
|
|
211
|
-
helpers: {
|
|
212
|
-
Playwright: {
|
|
213
|
-
browser: "electron",
|
|
214
|
-
electron: {
|
|
215
|
-
executablePath: require("electron"),
|
|
216
|
-
args: [path.join(__dirname, ".webpack/main/index.js")],
|
|
217
|
-
},
|
|
218
|
-
},
|
|
219
|
-
},
|
|
220
|
-
// rest of config
|
|
221
|
-
}
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
đŠī¸ Features
|
|
225
|
-
|
|
226
|
-
#### **[Playwright]** new features and improvements
|
|
227
|
-
* Parse the response in recording network steps ([#3771](https://github.com/codeceptjs/CodeceptJS/issues/3771)) - by **[KobeNguyenT](https://github.com/KobeNguyenT)**
|
|
228
|
-
|
|
229
|
-
```js
|
|
230
|
-
const traffics = await I.grabRecordedNetworkTraffics();
|
|
231
|
-
expect(traffics[0].url).to.equal('https://reqres.in/api/comments/1');
|
|
232
|
-
expect(traffics[0].response.status).to.equal(200);
|
|
233
|
-
expect(traffics[0].response.body).to.contain({ name: 'this was mocked' });
|
|
234
|
-
|
|
235
|
-
expect(traffics[1].url).to.equal('https://reqres.in/api/comments/1');
|
|
236
|
-
expect(traffics[1].response.status).to.equal(200);
|
|
237
|
-
expect(traffics[1].response.body).to.contain({ name: 'this was another mocked' });
|
|
238
|
-
```
|
|
239
|
-
* Grab metrics ([#3809](https://github.com/codeceptjs/CodeceptJS/issues/3809)) - by **[KobeNguyenT](https://github.com/KobeNguyenT)**
|
|
240
|
-
|
|
241
|
-
```js
|
|
242
|
-
const metrics = await I.grabMetrics();
|
|
243
|
-
|
|
244
|
-
// returned metrics
|
|
245
|
-
|
|
246
|
-
[
|
|
247
|
-
{ name: 'Timestamp', value: 1584904.203473 },
|
|
248
|
-
{ name: 'AudioHandlers', value: 0 },
|
|
249
|
-
{ name: 'AudioWorkletProcessors', value: 0 },
|
|
250
|
-
{ name: 'Documents', value: 22 },
|
|
251
|
-
{ name: 'Frames', value: 10 },
|
|
252
|
-
{ name: 'JSEventListeners', value: 366 },
|
|
253
|
-
{ name: 'LayoutObjects', value: 1240 },
|
|
254
|
-
{ name: 'MediaKeySessions', value: 0 },
|
|
255
|
-
{ name: 'MediaKeys', value: 0 },
|
|
256
|
-
{ name: 'Nodes', value: 4505 },
|
|
257
|
-
{ name: 'Resources', value: 141 },
|
|
258
|
-
{ name: 'ContextLifecycleStateObservers', value: 34 },
|
|
259
|
-
{ name: 'V8PerContextDatas', value: 4 },
|
|
260
|
-
{ name: 'WorkerGlobalScopes', value: 0 },
|
|
261
|
-
{ name: 'UACSSResources', value: 0 },
|
|
262
|
-
{ name: 'RTCPeerConnections', value: 0 },
|
|
263
|
-
{ name: 'ResourceFetchers', value: 22 },
|
|
264
|
-
{ name: 'AdSubframes', value: 0 },
|
|
265
|
-
{ name: 'DetachedScriptStates', value: 2 },
|
|
266
|
-
{ name: 'ArrayBufferContents', value: 1 },
|
|
267
|
-
{ name: 'LayoutCount', value: 0 },
|
|
268
|
-
{ name: 'RecalcStyleCount', value: 0 },
|
|
269
|
-
{ name: 'LayoutDuration', value: 0 },
|
|
270
|
-
{ name: 'RecalcStyleDuration', value: 0 },
|
|
271
|
-
{ name: 'DevToolsCommandDuration', value: 0.000013 },
|
|
272
|
-
{ name: 'ScriptDuration', value: 0 },
|
|
273
|
-
{ name: 'V8CompileDuration', value: 0 },
|
|
274
|
-
{ name: 'TaskDuration', value: 0.000014 },
|
|
275
|
-
{ name: 'TaskOtherDuration', value: 0.000001 },
|
|
276
|
-
{ name: 'ThreadTime', value: 0.000046 },
|
|
277
|
-
{ name: 'ProcessTime', value: 0.616852 },
|
|
278
|
-
{ name: 'JSHeapUsedSize', value: 19004908 },
|
|
279
|
-
{ name: 'JSHeapTotalSize', value: 26820608 },
|
|
280
|
-
{ name: 'FirstMeaningfulPaint', value: 0 },
|
|
281
|
-
{ name: 'DomContentLoaded', value: 1584903.690491 },
|
|
282
|
-
{ name: 'NavigationStart', value: 1584902.841845 }
|
|
283
|
-
]
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
* Grab WebSocket (WS) messages ([#3789](https://github.com/codeceptjs/CodeceptJS/issues/3789)) - by **[KobeNguyenT](https://github.com/KobeNguyenT)**
|
|
287
|
-
* `flushWebSocketMessages`
|
|
288
|
-
* `grabWebSocketMessages`
|
|
289
|
-
* `startRecordingWebSocketMessages`
|
|
290
|
-
* `stopRecordingWebSocketMessages`
|
|
291
|
-
|
|
292
|
-
```js
|
|
293
|
-
await I.startRecordingWebSocketMessages();
|
|
294
|
-
I.amOnPage('https://websocketstest.com/');
|
|
295
|
-
I.waitForText('Work for You!');
|
|
296
|
-
I.flushNetworkTraffics();
|
|
297
|
-
const wsMessages = I.grabWebSocketMessages();
|
|
298
|
-
expect(wsMessages.length).to.equal(0);
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
```js
|
|
302
|
-
await I.startRecordingWebSocketMessages();
|
|
303
|
-
await I.amOnPage('https://websocketstest.com/');
|
|
304
|
-
I.waitForText('Work for You!');
|
|
305
|
-
const wsMessages = I.grabWebSocketMessages();
|
|
306
|
-
expect(wsMessages.length).to.greaterThan(0);
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
```js
|
|
310
|
-
await I.startRecordingWebSocketMessages();
|
|
311
|
-
await I.amOnPage('https://websocketstest.com/');
|
|
312
|
-
I.waitForText('Work for You!');
|
|
313
|
-
const wsMessages = I.grabWebSocketMessages();
|
|
314
|
-
await I.stopRecordingWebSocketMessages();
|
|
315
|
-
await I.amOnPage('https://websocketstest.com/');
|
|
316
|
-
I.waitForText('Work for You!');
|
|
317
|
-
const afterWsMessages = I.grabWebSocketMessages();
|
|
318
|
-
expect(wsMessages.length).to.equal(afterWsMessages.length);
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
* Move from `ElementHandle` to `Locator`. This change is quite major, but it happened under hood, so should not affect your code. ([#3738](https://github.com/codeceptjs/CodeceptJS/issues/3738)) - by **[KobeNguyenT](https://github.com/KobeNguyenT)**
|
|
322
|
-
|
|
323
10
|
## 3.5.3
|
|
324
11
|
|
|
325
12
|
đŠī¸ Features
|
|
326
13
|
|
|
327
|
-
* **[Playwright]**
|
|
328
|
-
* `startRecordingTraffic`
|
|
329
|
-
* `grabRecordedNetworkTraffics`
|
|
330
|
-
* `blockTraffic`
|
|
331
|
-
* `mockTraffic`
|
|
332
|
-
* `flushNetworkTraffics`
|
|
333
|
-
* `stopRecordingTraffic`
|
|
334
|
-
* `seeTraffic`
|
|
335
|
-
* `grabTrafficUrl`
|
|
336
|
-
* `dontSeeTraffic`
|
|
337
|
-
|
|
338
|
-
Examples:
|
|
14
|
+
* **[Playwright]** Provide new steps to check network traffic [#3748](https://github.com/codeceptjs/CodeceptJS/issues/3748) - by **[ngraf](https://github.com/ngraf)** **[KobeNguyenT](https://github.com/KobeNguyenT)**
|
|
339
15
|
|
|
340
16
|
```js
|
|
341
17
|
// recording traffics and verify the traffic
|
|
@@ -31,6 +31,9 @@ Please **add your own** by editing this page.
|
|
|
31
31
|
* [codeceptjs-bshelper](https://github.com/PeterNgTr/codeceptjs-bshelper) - a helper which updates `Test Names` & `Test Results` on Browserstack
|
|
32
32
|
* [codeceptjs-tbhelper](https://github.com/testingbot/codeceptjs-tbhelper) - a helper which updates `Test Names` & `Test Results` on TestingBot
|
|
33
33
|
|
|
34
|
+
## Integrations
|
|
35
|
+
* [codeceptjs-testrail](https://github.com/PeterNgTr/codeceptjs-testrail) - a plugin to integrate with [Testrail](https://www.gurock.com/testrail)
|
|
36
|
+
|
|
34
37
|
## Visual-Testing
|
|
35
38
|
* [codeceptjs-resemblehelper](https://github.com/puneet0191/codeceptjs-resemblehelper) - a helper which helps with visual testing using resemble.js.
|
|
36
39
|
* [codeceptjs-applitoolshelper](https://www.npmjs.com/package/codeceptjs-applitoolshelper) - a helper which helps interaction with [Applitools](https://applitools.com)
|
|
@@ -39,10 +42,8 @@ Please **add your own** by editing this page.
|
|
|
39
42
|
## Reporters
|
|
40
43
|
* [codeceptjs-rphelper](https://github.com/reportportal/agent-js-codecept) is a CodeceptJS helper which can publish tests results on ReportPortal after execution.
|
|
41
44
|
* [codeceptjs-xray-helper](https://www.npmjs.com/package/codeceptjs-xray-helper) is a CodeceptJS helper which can publish tests results on [XRAY](https://confluence.xpand-it.com/display/XRAYCLOUD/Import+Execution+Results+-+REST).
|
|
42
|
-
* [codeceptjs-xray-cloud-helper](https://www.npmjs.com/package/codeceptjs-xray-cloud-helper) is a helper that automatically retrieves the result of CodeceptJS tests and sends them to XRAY/JIRA(cloud version) via [XRAY Cloud API](https://docs.getxray.app/display/XRAYCLOUD/Import+Execution+Results+-+REST+v2#ImportExecutionResultsRESTv2-XrayJSONresults).
|
|
43
45
|
* [codeceptjs-slack-reporter](https://www.npmjs.com/package/codeceptjs-slack-reporter) Get a Slack notification when one or more scenarios fail.
|
|
44
46
|
* [codeceptjs-browserlogs-plugin](https://github.com/pavkam/codeceptjs-browserlogs-plugin) Record the browser logs for failed tests.
|
|
45
|
-
* [codeceptjs-testrail](https://github.com/PeterNgTr/codeceptjs-testrail) - a plugin to integrate with [Testrail](https://www.gurock.com/testrail)
|
|
46
47
|
|
|
47
48
|
## Browser request control
|
|
48
49
|
* [codeceptjs-resources-check](https://github.com/luarmr/codeceptjs-resources-check) Load a URL with Puppeteer and listen to the requests while the page is loading. Enabling count the number or check the sizes of the requests.
|
|
@@ -54,9 +55,4 @@ Please **add your own** by editing this page.
|
|
|
54
55
|
## Other
|
|
55
56
|
|
|
56
57
|
* [codeceptjs-cmdhelper](https://github.com/thiagodp/codeceptjs-cmdhelper) allows you to run commands in the terminal/console
|
|
57
|
-
* [eslint-plugin-codeceptjs](https://www.npmjs.com/package/eslint-plugin-codeceptjs) Eslint rules for CodeceptJS.
|
|
58
|
-
* [codeceptjs-datalayer-helper](https://github.com/kobenguyent/codeceptjs-datalayer-helper) CodeceptJS DataLayer helper helps you to get the datalayer JavaScript array that is used to store information and send this data to the tag manager.
|
|
59
|
-
* [codeceptjs-a11y-helper](https://github.com/kobenguyent/codeceptjs-a11y-helper) accessibility tests integrated with CodeceptJS - Playwright-axe
|
|
60
|
-
* [codeceptjs-lighthouse-helper](https://github.com/kobenguyent/codeceptjs-lighthouse-helper) lighthouse audit integrated with CodeceptJS - Playwright
|
|
61
|
-
* [Snowplow Data analytics](https://www.npmjs.com/package/@viasat/codeceptjs-snowplow-helper) - Test your Snowplow events implementations with CodeceptJS and Snowplow Micro.
|
|
62
|
-
* [codeceptjs-failure-logger](https://github.com/kobenguyent/codeceptjs-failure-logger) - Log failed CodeceptJS tests to file
|
|
58
|
+
* [eslint-plugin-codeceptjs](https://www.npmjs.com/package/eslint-plugin-codeceptjs) Eslint rules for CodeceptJS.
|