codeceptjs 3.3.6 → 3.3.7
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/basics.md +2 -3
- package/docs/bdd.md +33 -0
- package/docs/best.md +8 -8
- package/docs/build/Appium.js +60 -22
- package/docs/build/GraphQL.js +6 -6
- package/docs/build/Nightmare.js +4 -4
- package/docs/build/Playwright.js +102 -39
- package/docs/build/Polly.js +0 -0
- package/docs/build/Protractor.js +25 -25
- package/docs/build/Puppeteer.js +7 -7
- package/docs/build/SeleniumWebdriver.js +0 -0
- package/docs/build/TestCafe.js +12 -12
- package/docs/build/WebDriver.js +32 -32
- package/docs/changelog.md +36 -1
- package/docs/helpers/Appium.md +103 -79
- package/docs/helpers/GraphQL.md +6 -6
- package/docs/helpers/Playwright.md +280 -245
- package/docs/helpers/Puppeteer.md +1 -1
- package/docs/helpers/REST.md +1 -1
- package/docs/helpers/WebDriver.md +2 -2
- package/docs/playwright.md +14 -0
- package/docs/quickstart.md +40 -13
- package/docs/translation.md +83 -56
- package/docs/typescript.md +49 -3
- package/docs/wiki/Books-&-Posts.md +0 -0
- package/docs/wiki/Community-Helpers-&-Plugins.md +0 -0
- package/docs/wiki/Converting-Playwright-to-Istanbul-Coverage.md +0 -0
- package/docs/wiki/Examples.md +0 -0
- package/docs/wiki/Google-Summer-of-Code-(GSoC)-2020.md +0 -0
- package/docs/wiki/Home.md +0 -0
- package/docs/wiki/Release-Process.md +0 -0
- package/docs/wiki/Roadmap.md +0 -0
- package/docs/wiki/Tests.md +0 -0
- package/docs/wiki/Upgrading-to-CodeceptJS-3.md +0 -0
- package/docs/wiki/Videos.md +0 -0
- package/lib/codecept.js +3 -1
- package/lib/command/definitions.js +26 -2
- package/lib/command/generate.js +23 -9
- package/lib/command/init.js +32 -7
- package/lib/command/run.js +5 -1
- package/lib/container.js +15 -15
- package/lib/helper/Appium.js +60 -22
- package/lib/helper/GraphQL.js +6 -6
- package/lib/helper/Nightmare.js +4 -4
- package/lib/helper/Playwright.js +102 -39
- package/lib/helper/Protractor.js +25 -25
- package/lib/helper/Puppeteer.js +7 -7
- package/lib/helper/TestCafe.js +12 -12
- package/lib/helper/WebDriver.js +32 -32
- package/lib/helper/errors/ElementNotFound.js +1 -1
- package/lib/helper/extras/PlaywrightRestartOpts.js +0 -2
- package/lib/interfaces/bdd.js +26 -1
- package/lib/listener/artifacts.js +19 -0
- package/lib/rerun.js +12 -13
- package/lib/step.js +5 -5
- package/lib/translation.js +32 -0
- package/package.json +11 -17
- package/translations/ru-RU.js +1 -0
- package/typings/index.d.ts +29 -1
- package/typings/promiseBasedTypes.d.ts +10466 -0
- package/typings/types.d.ts +62 -12
- package/CHANGELOG.md +0 -2340
package/docs/build/Playwright.js
CHANGED
|
@@ -44,6 +44,8 @@ const {
|
|
|
44
44
|
} = require('./extras/PlaywrightRestartOpts');
|
|
45
45
|
const { createValueEngine, createDisabledEngine } = require('./extras/PlaywrightPropEngine');
|
|
46
46
|
|
|
47
|
+
const pathSeparator = path.sep;
|
|
48
|
+
|
|
47
49
|
/**
|
|
48
50
|
* ## Configuration
|
|
49
51
|
*
|
|
@@ -52,7 +54,7 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
|
|
|
52
54
|
* @typedef PlaywrightConfig
|
|
53
55
|
* @type {object}
|
|
54
56
|
* @prop {string} url - base url of website to be tested
|
|
55
|
-
* @prop {string} browser - a browser to test on, either: `chromium`, `firefox`, `webkit`, `electron`. Default: chromium.
|
|
57
|
+
* @prop {string} [browser] - a browser to test on, either: `chromium`, `firefox`, `webkit`, `electron`. Default: chromium.
|
|
56
58
|
* @prop {boolean} [show=false] - show browser window.
|
|
57
59
|
* @prop {string|boolean} [restart=false] - restart strategy between tests. Possible values:
|
|
58
60
|
* * 'context' or **false** - restarts [browser context](https://playwright.dev/docs/api/class-browsercontext) but keeps running browser. Recommended by Playwright team to keep tests isolated.
|
|
@@ -80,8 +82,11 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
|
|
|
80
82
|
* @prop {string} [locale] - locale string. Example: 'en-GB', 'de-DE', 'fr-FR', ...
|
|
81
83
|
* @prop {boolean} [manualStart] - do not start browser before a test, start it manually inside a helper with `this.helpers["Playwright"]._startBrowser()`.
|
|
82
84
|
* @prop {object} [chromium] - pass additional chromium options
|
|
85
|
+
* @prop {object} [firefox] - pass additional firefox options
|
|
83
86
|
* @prop {object} [electron] - (pass additional electron options
|
|
84
87
|
* @prop {any} [channel] - (While Playwright can operate against the stock Google Chrome and Microsoft Edge browsers available on the machine. In particular, current Playwright version will support Stable and Beta channels of these browsers. See [Google Chrome & Microsoft Edge](https://playwright.dev/docs/browsers/#google-chrome--microsoft-edge).
|
|
88
|
+
* @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).
|
|
89
|
+
* @prop {boolean} [ignoreHTTPSErrors] - Allows access to untrustworthy pages, e.g. to a page with an expired certificate. Default value is `false`
|
|
85
90
|
*/
|
|
86
91
|
const config = {};
|
|
87
92
|
|
|
@@ -448,7 +453,7 @@ class Playwright extends Helper {
|
|
|
448
453
|
const existingPages = await this.browserContext.pages();
|
|
449
454
|
mainPage = existingPages[0] || await this.browserContext.newPage();
|
|
450
455
|
}
|
|
451
|
-
targetCreatedHandler.call(this, mainPage);
|
|
456
|
+
await targetCreatedHandler.call(this, mainPage);
|
|
452
457
|
|
|
453
458
|
await this._setPage(mainPage);
|
|
454
459
|
|
|
@@ -513,12 +518,13 @@ class Playwright extends Helper {
|
|
|
513
518
|
browserContext = browser.context();
|
|
514
519
|
page = await browser.firstWindow();
|
|
515
520
|
} else {
|
|
516
|
-
browserContext = await this.browser.newContext(config);
|
|
521
|
+
browserContext = await this.browser.newContext(Object.assign(this.options, config));
|
|
517
522
|
page = await browserContext.newPage();
|
|
518
523
|
}
|
|
519
524
|
|
|
520
|
-
|
|
521
|
-
|
|
525
|
+
if (this.options.trace) await browserContext.tracing.start({ screenshots: true, snapshots: true });
|
|
526
|
+
await targetCreatedHandler.call(this, page);
|
|
527
|
+
await this._setPage(page);
|
|
522
528
|
// Create a new page inside context.
|
|
523
529
|
return browserContext;
|
|
524
530
|
},
|
|
@@ -740,6 +746,19 @@ class Playwright extends Helper {
|
|
|
740
746
|
});
|
|
741
747
|
|
|
742
748
|
this.isRunning = true;
|
|
749
|
+
return this.browser;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* Create a new browser context with a page. \
|
|
754
|
+
* Usually it should be run from a custom helper after call of `_startBrowser()`
|
|
755
|
+
* @param {object} [contextOptions] See https://playwright.dev/docs/api/class-browser#browser-new-context
|
|
756
|
+
*/
|
|
757
|
+
async _createContextPage(contextOptions) {
|
|
758
|
+
this.browserContext = await this.browser.newContext(contextOptions);
|
|
759
|
+
const page = await this.browserContext.newPage();
|
|
760
|
+
targetCreatedHandler.call(this, page);
|
|
761
|
+
await this._setPage(page);
|
|
743
762
|
}
|
|
744
763
|
|
|
745
764
|
_getType() {
|
|
@@ -818,8 +837,8 @@ class Playwright extends Helper {
|
|
|
818
837
|
if (this.isElectron) {
|
|
819
838
|
throw new Error('Cannot open pages inside an Electron container');
|
|
820
839
|
}
|
|
821
|
-
if (!(/^\w
|
|
822
|
-
url = this.options.url + url;
|
|
840
|
+
if (!(/^\w+\:(\/\/|.+)/.test(url))) {
|
|
841
|
+
url = this.options.url + (url.startsWith('/') ? url : `/${url}`);
|
|
823
842
|
}
|
|
824
843
|
|
|
825
844
|
if (this.options.basicAuth && (this.isAuthenticated !== true)) {
|
|
@@ -910,7 +929,7 @@ class Playwright extends Helper {
|
|
|
910
929
|
*/
|
|
911
930
|
async moveCursorTo(locator, offsetX = 0, offsetY = 0) {
|
|
912
931
|
const els = await this._locate(locator);
|
|
913
|
-
assertElementExists(els);
|
|
932
|
+
assertElementExists(els, locator);
|
|
914
933
|
|
|
915
934
|
// Use manual mouse.move instead of .hover() so the offset can be added to the coordinates
|
|
916
935
|
const { x, y } = await clickablePoint(els[0]);
|
|
@@ -946,6 +965,26 @@ class Playwright extends Helper {
|
|
|
946
965
|
return this.page.dragAndDrop(buildLocatorString(src), buildLocatorString(dst), options);
|
|
947
966
|
}
|
|
948
967
|
|
|
968
|
+
/**
|
|
969
|
+
* Restart browser with a new context and a new page
|
|
970
|
+
*
|
|
971
|
+
* ```js
|
|
972
|
+
* // Restart browser and use a new timezone
|
|
973
|
+
* I.restartBrowser({ timezoneId: 'America/Phoenix' });
|
|
974
|
+
* // Open URL in a new page in changed timezone
|
|
975
|
+
* I.amOnPage('/');
|
|
976
|
+
* // Restart browser, allow reading/copying of text from/into clipboard in Chrome
|
|
977
|
+
* I.restartBrowser({ permissions: ['clipboard-read', 'clipboard-write'] });
|
|
978
|
+
* ```
|
|
979
|
+
*
|
|
980
|
+
* @param {object} [contextOptions] [Options for browser context](https://playwright.dev/docs/api/class-browser#browser-new-context) when starting new browser
|
|
981
|
+
*/
|
|
982
|
+
async restartBrowser(contextOptions) {
|
|
983
|
+
await this._stopBrowser();
|
|
984
|
+
await this._startBrowser();
|
|
985
|
+
await this._createContextPage(contextOptions);
|
|
986
|
+
}
|
|
987
|
+
|
|
949
988
|
/**
|
|
950
989
|
* Reload the current page.
|
|
951
990
|
*
|
|
@@ -1187,7 +1226,7 @@ class Playwright extends Helper {
|
|
|
1187
1226
|
if (!page) {
|
|
1188
1227
|
throw new Error(`There is no ability to switch to next tab with offset ${num}`);
|
|
1189
1228
|
}
|
|
1190
|
-
targetCreatedHandler.call(this, page);
|
|
1229
|
+
await targetCreatedHandler.call(this, page);
|
|
1191
1230
|
await this._setPage(page);
|
|
1192
1231
|
return this._waitForAction();
|
|
1193
1232
|
}
|
|
@@ -1271,7 +1310,7 @@ class Playwright extends Helper {
|
|
|
1271
1310
|
throw new Error('Cannot open new tabs inside an Electron container');
|
|
1272
1311
|
}
|
|
1273
1312
|
const page = await this.browserContext.newPage(options);
|
|
1274
|
-
targetCreatedHandler.call(this, page);
|
|
1313
|
+
await targetCreatedHandler.call(this, page);
|
|
1275
1314
|
await this._setPage(page);
|
|
1276
1315
|
return this._waitForAction();
|
|
1277
1316
|
}
|
|
@@ -1361,7 +1400,7 @@ class Playwright extends Helper {
|
|
|
1361
1400
|
}
|
|
1362
1401
|
|
|
1363
1402
|
/**
|
|
1364
|
-
* Handles a file download.
|
|
1403
|
+
* Handles a file download. A file name is required to save the file on disk.
|
|
1365
1404
|
* Files are saved to "output" directory.
|
|
1366
1405
|
*
|
|
1367
1406
|
* Should be used with [FileSystem helper](https://codecept.io/helpers/FileSystem) to check that file were downloaded correctly.
|
|
@@ -1370,17 +1409,19 @@ class Playwright extends Helper {
|
|
|
1370
1409
|
* I.handleDownloads('downloads/avatar.jpg');
|
|
1371
1410
|
* I.click('Download Avatar');
|
|
1372
1411
|
* I.amInPath('output/downloads');
|
|
1373
|
-
* I.waitForFile('
|
|
1412
|
+
* I.waitForFile('avatar.jpg', 5);
|
|
1374
1413
|
*
|
|
1375
1414
|
* ```
|
|
1376
1415
|
*
|
|
1377
1416
|
* @param {string} [fileName] set filename for downloaded file
|
|
1378
1417
|
* @return {Promise<void>}
|
|
1379
1418
|
*/
|
|
1380
|
-
async handleDownloads(fileName
|
|
1419
|
+
async handleDownloads(fileName) {
|
|
1381
1420
|
this.page.waitForEvent('download').then(async (download) => {
|
|
1382
1421
|
const filePath = await download.path();
|
|
1383
|
-
|
|
1422
|
+
fileName = fileName || `downloads/${path.basename(filePath)}`;
|
|
1423
|
+
|
|
1424
|
+
const downloadPath = path.join(global.output_dir, fileName);
|
|
1384
1425
|
if (!fs.existsSync(path.dirname(downloadPath))) {
|
|
1385
1426
|
fs.mkdirSync(path.dirname(downloadPath), '0777');
|
|
1386
1427
|
}
|
|
@@ -1920,7 +1961,7 @@ class Playwright extends Helper {
|
|
|
1920
1961
|
throw new Error(`File at ${file} can not be found on local system`);
|
|
1921
1962
|
}
|
|
1922
1963
|
const els = await findFields.call(this, locator);
|
|
1923
|
-
assertElementExists(els, 'Field');
|
|
1964
|
+
assertElementExists(els, locator, 'Field');
|
|
1924
1965
|
await els[0].setInputFiles(file);
|
|
1925
1966
|
return this._waitForAction();
|
|
1926
1967
|
}
|
|
@@ -2208,7 +2249,7 @@ class Playwright extends Helper {
|
|
|
2208
2249
|
*/
|
|
2209
2250
|
async seeNumberOfElements(locator, num) {
|
|
2210
2251
|
const elements = await this._locate(locator);
|
|
2211
|
-
return equals(`expected number of elements (${locator}) is ${num}, but found ${elements.length}`).assert(elements.length, num);
|
|
2252
|
+
return equals(`expected number of elements (${(new Locator(locator))}) is ${num}, but found ${elements.length}`).assert(elements.length, num);
|
|
2212
2253
|
}
|
|
2213
2254
|
|
|
2214
2255
|
/**
|
|
@@ -2228,7 +2269,7 @@ class Playwright extends Helper {
|
|
|
2228
2269
|
*/
|
|
2229
2270
|
async seeNumberOfVisibleElements(locator, num) {
|
|
2230
2271
|
const res = await this.grabNumberOfVisibleElements(locator);
|
|
2231
|
-
return equals(`expected number of visible elements (${locator}) is ${num}, but found ${res}`).assert(res, num);
|
|
2272
|
+
return equals(`expected number of visible elements (${(new Locator(locator))}) is ${num}, but found ${res}`).assert(res, num);
|
|
2232
2273
|
}
|
|
2233
2274
|
|
|
2234
2275
|
/**
|
|
@@ -2355,6 +2396,7 @@ class Playwright extends Helper {
|
|
|
2355
2396
|
*
|
|
2356
2397
|
* @param {string|function} fn function to be executed in browser context.
|
|
2357
2398
|
* @param {any} [arg] optional argument to pass to the function
|
|
2399
|
+
* @returns {Promise<any>}
|
|
2358
2400
|
*/
|
|
2359
2401
|
async executeScript(fn, arg) {
|
|
2360
2402
|
let context = this.page;
|
|
@@ -2587,7 +2629,7 @@ class Playwright extends Helper {
|
|
|
2587
2629
|
}
|
|
2588
2630
|
return true;
|
|
2589
2631
|
});
|
|
2590
|
-
return equals(`all elements (${locator}) to have CSS property ${JSON.stringify(cssProperties)}`).assert(chunked.length, elemAmount);
|
|
2632
|
+
return equals(`all elements (${(new Locator(locator))}) to have CSS property ${JSON.stringify(cssProperties)}`).assert(chunked.length, elemAmount);
|
|
2591
2633
|
}
|
|
2592
2634
|
|
|
2593
2635
|
/**
|
|
@@ -2625,7 +2667,7 @@ class Playwright extends Helper {
|
|
|
2625
2667
|
}
|
|
2626
2668
|
return true;
|
|
2627
2669
|
});
|
|
2628
|
-
return equals(`all elements (${locator}) to have attributes ${JSON.stringify(attributes)}`).assert(chunked.length, elemAmount);
|
|
2670
|
+
return equals(`all elements (${(new Locator(locator))}) to have attributes ${JSON.stringify(attributes)}`).assert(chunked.length, elemAmount);
|
|
2629
2671
|
}
|
|
2630
2672
|
|
|
2631
2673
|
/**
|
|
@@ -2729,7 +2771,7 @@ class Playwright extends Helper {
|
|
|
2729
2771
|
assertElementExists(res, locator);
|
|
2730
2772
|
if (res.length > 1) this.debug(`[Elements] Using first element out of ${res.length}`);
|
|
2731
2773
|
const elem = res[0];
|
|
2732
|
-
this.debug(`Screenshot of ${locator} element has been saved to ${outputFile}`);
|
|
2774
|
+
this.debug(`Screenshot of ${(new Locator(locator))} element has been saved to ${outputFile}`);
|
|
2733
2775
|
return elem.screenshot({ path: outputFile, type: 'png' });
|
|
2734
2776
|
}
|
|
2735
2777
|
|
|
@@ -2824,29 +2866,28 @@ class Playwright extends Helper {
|
|
|
2824
2866
|
}
|
|
2825
2867
|
|
|
2826
2868
|
if (this.options.recordVideo && this.page && this.page.video()) {
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
}));
|
|
2869
|
+
test.artifacts.video = await saveVideoForPage(this.page, `${test.title}.failed`);
|
|
2870
|
+
for (const sessionName in this.sessionPages) {
|
|
2871
|
+
test.artifacts[`video_${sessionName}`] = await saveVideoForPage(this.sessionPages[sessionName], `${test.title}_${sessionName}.failed`);
|
|
2872
|
+
}
|
|
2832
2873
|
}
|
|
2833
2874
|
|
|
2834
2875
|
if (this.options.trace) {
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2876
|
+
test.artifacts.trace = await saveTraceForContext(this.browserContext, `${test.title}.failed`);
|
|
2877
|
+
for (const sessionName in this.sessionPages) {
|
|
2878
|
+
if (!this.sessionPages[sessionName].context) continue;
|
|
2879
|
+
test.artifacts[`trace_${sessionName}`] = await saveTraceForContext(this.sessionPages[sessionName].context(), `${test.title}_${sessionName}.failed`);
|
|
2880
|
+
}
|
|
2838
2881
|
}
|
|
2839
2882
|
}
|
|
2840
2883
|
|
|
2841
2884
|
async _passed(test) {
|
|
2842
2885
|
if (this.options.recordVideo && this.page && this.page.video()) {
|
|
2843
|
-
const videoPath = `${global.output_dir}/videos/${clearString(test.title)}.passed.webm`;
|
|
2844
|
-
|
|
2845
2886
|
if (this.options.keepVideoForPassedTests) {
|
|
2846
|
-
test.artifacts.video = await this.page.
|
|
2847
|
-
|
|
2848
|
-
test.artifacts
|
|
2849
|
-
}
|
|
2887
|
+
test.artifacts.video = await saveVideoForPage(this.page, `${test.title}.passed`);
|
|
2888
|
+
for (const sessionName of Object.keys(this.sessionPages)) {
|
|
2889
|
+
test.artifacts[`video_${sessionName}`] = await saveVideoForPage(this.sessionPages[sessionName], `${test.title}_${sessionName}.passed`);
|
|
2890
|
+
}
|
|
2850
2891
|
} else {
|
|
2851
2892
|
this.page.video().delete().catch(e => {});
|
|
2852
2893
|
}
|
|
@@ -2854,9 +2895,13 @@ class Playwright extends Helper {
|
|
|
2854
2895
|
|
|
2855
2896
|
if (this.options.trace) {
|
|
2856
2897
|
if (this.options.keepTraceForPassedTests) {
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2898
|
+
if (this.options.trace) {
|
|
2899
|
+
test.artifacts.trace = await saveTraceForContext(this.browserContext, `${test.title}.passed`);
|
|
2900
|
+
for (const sessionName in this.sessionPages) {
|
|
2901
|
+
if (!this.sessionPages[sessionName].context) continue;
|
|
2902
|
+
test.artifacts[`trace_${sessionName}`] = await saveTraceForContext(this.sessionPages[sessionName].context(), `${test.title}_${sessionName}.passed`);
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2860
2905
|
} else {
|
|
2861
2906
|
await this.browserContext.tracing.stop();
|
|
2862
2907
|
}
|
|
@@ -3770,7 +3815,7 @@ async function targetCreatedHandler(page) {
|
|
|
3770
3815
|
page.on('load', () => {
|
|
3771
3816
|
page.$('body')
|
|
3772
3817
|
.catch(() => null)
|
|
3773
|
-
.then(async
|
|
3818
|
+
.then(async () => {
|
|
3774
3819
|
if (this.context && this.context._type === 'Frame') {
|
|
3775
3820
|
// we are inside iframe?
|
|
3776
3821
|
const frameEl = await this.context.frameElement();
|
|
@@ -3795,7 +3840,7 @@ async function targetCreatedHandler(page) {
|
|
|
3795
3840
|
try {
|
|
3796
3841
|
await page.setViewportSize(parseWindowSize(this.options.windowSize));
|
|
3797
3842
|
} catch (err) {
|
|
3798
|
-
|
|
3843
|
+
this.debug('Target can be already closed, ignoring...');
|
|
3799
3844
|
}
|
|
3800
3845
|
}
|
|
3801
3846
|
}
|
|
@@ -3920,3 +3965,21 @@ async function refreshContextSession() {
|
|
|
3920
3965
|
});
|
|
3921
3966
|
}
|
|
3922
3967
|
}
|
|
3968
|
+
|
|
3969
|
+
async function saveVideoForPage(page, name) {
|
|
3970
|
+
if (!page.video()) return null;
|
|
3971
|
+
const fileName = `${global.output_dir}${pathSeparator}videos${pathSeparator}${Date.now()}_${clearString(name).slice(0, 245)}.webm`;
|
|
3972
|
+
page.video().saveAs(fileName).then(() => {
|
|
3973
|
+
if (!page) return;
|
|
3974
|
+
page.video().delete().catch(e => {});
|
|
3975
|
+
});
|
|
3976
|
+
return fileName;
|
|
3977
|
+
}
|
|
3978
|
+
|
|
3979
|
+
async function saveTraceForContext(context, name) {
|
|
3980
|
+
if (!context) return;
|
|
3981
|
+
if (!context.tracing) return;
|
|
3982
|
+
const fileName = `${`${global.output_dir}${pathSeparator}trace${pathSeparator}${Date.now()}_${clearString(name)}`.slice(0, 245)}.zip`;
|
|
3983
|
+
await context.tracing.stop({ path: fileName });
|
|
3984
|
+
return fileName;
|
|
3985
|
+
}
|
package/docs/build/Polly.js
CHANGED
|
File without changes
|
package/docs/build/Protractor.js
CHANGED
|
@@ -153,7 +153,7 @@ class Protractor extends Helper {
|
|
|
153
153
|
if (config.proxy) config.capabilities.proxy = config.proxy;
|
|
154
154
|
if (config.browser) config.capabilities.browserName = config.browser;
|
|
155
155
|
|
|
156
|
-
config.waitForTimeout
|
|
156
|
+
config.waitForTimeoutInSeconds = config.waitForTimeout / 1000; // convert to seconds
|
|
157
157
|
return config;
|
|
158
158
|
}
|
|
159
159
|
|
|
@@ -1011,7 +1011,7 @@ class Protractor extends Helper {
|
|
|
1011
1011
|
*/
|
|
1012
1012
|
async grabTextFrom(locator) {
|
|
1013
1013
|
const texts = await this.grabTextFromAll(locator);
|
|
1014
|
-
assertElementExists(texts);
|
|
1014
|
+
assertElementExists(texts, locator);
|
|
1015
1015
|
if (texts.length > 1) {
|
|
1016
1016
|
this.debugSection('GrabText', `Using first element out of ${texts.length}`);
|
|
1017
1017
|
}
|
|
@@ -1056,7 +1056,7 @@ class Protractor extends Helper {
|
|
|
1056
1056
|
*/
|
|
1057
1057
|
async grabHTMLFrom(locator) {
|
|
1058
1058
|
const html = await this.grabHTMLFromAll(locator);
|
|
1059
|
-
assertElementExists(html);
|
|
1059
|
+
assertElementExists(html, locator);
|
|
1060
1060
|
if (html.length > 1) {
|
|
1061
1061
|
this.debugSection('GrabHTMl', `Using first element out of ${html.length}`);
|
|
1062
1062
|
}
|
|
@@ -1381,7 +1381,7 @@ class Protractor extends Helper {
|
|
|
1381
1381
|
*/
|
|
1382
1382
|
async seeNumberOfElements(locator, num) {
|
|
1383
1383
|
const elements = await this._locate(locator);
|
|
1384
|
-
return equals(`expected number of elements (${locator}) is ${num}, but found ${elements.length}`).assert(elements.length, num);
|
|
1384
|
+
return equals(`expected number of elements (${(new Locator(locator))}) is ${num}, but found ${elements.length}`).assert(elements.length, num);
|
|
1385
1385
|
}
|
|
1386
1386
|
|
|
1387
1387
|
/**
|
|
@@ -1399,7 +1399,7 @@ class Protractor extends Helper {
|
|
|
1399
1399
|
*/
|
|
1400
1400
|
async seeNumberOfVisibleElements(locator, num) {
|
|
1401
1401
|
const res = await this.grabNumberOfVisibleElements(locator);
|
|
1402
|
-
return equals(`expected number of visible elements (${locator}) is ${num}, but found ${res}`).assert(res, num);
|
|
1402
|
+
return equals(`expected number of visible elements (${(new Locator(locator))}) is ${num}, but found ${res}`).assert(res, num);
|
|
1403
1403
|
}
|
|
1404
1404
|
|
|
1405
1405
|
/**
|
|
@@ -1456,7 +1456,7 @@ class Protractor extends Helper {
|
|
|
1456
1456
|
missingAttributes.push(...missing);
|
|
1457
1457
|
}
|
|
1458
1458
|
}
|
|
1459
|
-
return equals(`all elements (${locator}) to have CSS property ${JSON.stringify(cssProperties)}`).assert(missingAttributes.length, 0);
|
|
1459
|
+
return equals(`all elements (${(new Locator(locator))}) to have CSS property ${JSON.stringify(cssProperties)}`).assert(missingAttributes.length, 0);
|
|
1460
1460
|
}
|
|
1461
1461
|
|
|
1462
1462
|
/**
|
|
@@ -1492,7 +1492,7 @@ class Protractor extends Helper {
|
|
|
1492
1492
|
}
|
|
1493
1493
|
}
|
|
1494
1494
|
|
|
1495
|
-
return equals(`all elements (${locator}) to have attributes ${JSON.stringify(attributes)}`).assert(missingAttributes.length, 0);
|
|
1495
|
+
return equals(`all elements (${(new Locator(locator))}) to have attributes ${JSON.stringify(attributes)}`).assert(missingAttributes.length, 0);
|
|
1496
1496
|
}
|
|
1497
1497
|
|
|
1498
1498
|
/**
|
|
@@ -1650,7 +1650,7 @@ class Protractor extends Helper {
|
|
|
1650
1650
|
assertElementExists(res, locator);
|
|
1651
1651
|
if (res.length > 1) this.debug(`[Elements] Using first element out of ${res.length}`);
|
|
1652
1652
|
const elem = res[0];
|
|
1653
|
-
this.debug(`Screenshot of ${locator} element has been saved to ${outputFile}`);
|
|
1653
|
+
this.debug(`Screenshot of ${(new Locator(locator))} element has been saved to ${outputFile}`);
|
|
1654
1654
|
const png = await elem.takeScreenshot();
|
|
1655
1655
|
return writeFile(png, outputFile);
|
|
1656
1656
|
}
|
|
@@ -1862,8 +1862,8 @@ class Protractor extends Helper {
|
|
|
1862
1862
|
async dragAndDrop(srcElement, destElement) {
|
|
1863
1863
|
const srcEl = await this._locate(srcElement, true);
|
|
1864
1864
|
const destEl = await this._locate(destElement, true);
|
|
1865
|
-
assertElementExists(srcEl);
|
|
1866
|
-
assertElementExists(destEl);
|
|
1865
|
+
assertElementExists(srcEl, srcElement);
|
|
1866
|
+
assertElementExists(destEl, destElement);
|
|
1867
1867
|
return this.browser
|
|
1868
1868
|
.actions()
|
|
1869
1869
|
.dragAndDrop(srcEl[0], destEl[0])
|
|
@@ -2046,7 +2046,7 @@ class Protractor extends Helper {
|
|
|
2046
2046
|
*
|
|
2047
2047
|
*/
|
|
2048
2048
|
async waitForElement(locator, sec = null) {
|
|
2049
|
-
const aSec = sec || this.options.
|
|
2049
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds;
|
|
2050
2050
|
const el = global.element(guessLocator(locator) || global.by.css(locator));
|
|
2051
2051
|
return this.browser.wait(EC.presenceOf(el), aSec * 1000);
|
|
2052
2052
|
}
|
|
@@ -2072,7 +2072,7 @@ class Protractor extends Helper {
|
|
|
2072
2072
|
*
|
|
2073
2073
|
*/
|
|
2074
2074
|
async waitForDetached(locator, sec = null) {
|
|
2075
|
-
const aSec = sec || this.options.
|
|
2075
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds;
|
|
2076
2076
|
const el = global.element(guessLocator(locator) || global.by.css(locator));
|
|
2077
2077
|
return this.browser.wait(EC.not(EC.presenceOf(el)), aSec * 1000).catch((err) => {
|
|
2078
2078
|
if (err.message && err.message.indexOf('Wait timed out after') > -1) {
|
|
@@ -2089,7 +2089,7 @@ class Protractor extends Helper {
|
|
|
2089
2089
|
* ```
|
|
2090
2090
|
*/
|
|
2091
2091
|
async waitForClickable(locator, sec = null) {
|
|
2092
|
-
const aSec = sec || this.options.
|
|
2092
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds;
|
|
2093
2093
|
const el = global.element(guessLocator(locator) || global.by.css(locator));
|
|
2094
2094
|
return this.browser.wait(EC.elementToBeClickable(el), aSec * 1000);
|
|
2095
2095
|
}
|
|
@@ -2108,7 +2108,7 @@ class Protractor extends Helper {
|
|
|
2108
2108
|
*
|
|
2109
2109
|
*/
|
|
2110
2110
|
async waitForVisible(locator, sec = null) {
|
|
2111
|
-
const aSec = sec || this.options.
|
|
2111
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds;
|
|
2112
2112
|
const el = global.element(guessLocator(locator) || global.by.css(locator));
|
|
2113
2113
|
return this.browser.wait(EC.visibilityOf(el), aSec * 1000);
|
|
2114
2114
|
}
|
|
@@ -2144,7 +2144,7 @@ class Protractor extends Helper {
|
|
|
2144
2144
|
*
|
|
2145
2145
|
*/
|
|
2146
2146
|
async waitForInvisible(locator, sec = null) {
|
|
2147
|
-
const aSec = sec || this.options.
|
|
2147
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds;
|
|
2148
2148
|
const el = global.element(guessLocator(locator) || global.by.css(locator));
|
|
2149
2149
|
return this.browser.wait(EC.invisibilityOf(el), aSec * 1000);
|
|
2150
2150
|
}
|
|
@@ -2179,12 +2179,12 @@ class Protractor extends Helper {
|
|
|
2179
2179
|
};
|
|
2180
2180
|
}
|
|
2181
2181
|
|
|
2182
|
-
const aSec = sec || this.options.
|
|
2182
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds;
|
|
2183
2183
|
const guessLoc = guessLocator(locator) || global.by.css(locator);
|
|
2184
2184
|
|
|
2185
2185
|
return this.browser.wait(visibilityCountOf(guessLoc, num), aSec * 1000)
|
|
2186
2186
|
.catch(() => {
|
|
2187
|
-
throw Error(`The number of elements (${locator}) is not ${num} after ${aSec} sec`);
|
|
2187
|
+
throw Error(`The number of elements (${(new Locator(locator))}) is not ${num} after ${aSec} sec`);
|
|
2188
2188
|
});
|
|
2189
2189
|
}
|
|
2190
2190
|
|
|
@@ -2198,12 +2198,12 @@ class Protractor extends Helper {
|
|
|
2198
2198
|
*
|
|
2199
2199
|
*/
|
|
2200
2200
|
async waitForEnabled(locator, sec = null) {
|
|
2201
|
-
const aSec = sec || this.options.
|
|
2201
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds;
|
|
2202
2202
|
const el = global.element(guessLocator(locator) || global.by.css(locator));
|
|
2203
2203
|
|
|
2204
2204
|
return this.browser.wait(EC.elementToBeClickable(el), aSec * 1000)
|
|
2205
2205
|
.catch(() => {
|
|
2206
|
-
throw Error(`element (${locator}) still not enabled after ${aSec} sec`);
|
|
2206
|
+
throw Error(`element (${(new Locator(locator))}) still not enabled after ${aSec} sec`);
|
|
2207
2207
|
});
|
|
2208
2208
|
}
|
|
2209
2209
|
|
|
@@ -2221,7 +2221,7 @@ class Protractor extends Helper {
|
|
|
2221
2221
|
*
|
|
2222
2222
|
*/
|
|
2223
2223
|
async waitForValue(field, value, sec = null) {
|
|
2224
|
-
const aSec = sec || this.options.
|
|
2224
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds;
|
|
2225
2225
|
|
|
2226
2226
|
const valueToBeInElementValue = (loc) => {
|
|
2227
2227
|
return async () => {
|
|
@@ -2271,7 +2271,7 @@ class Protractor extends Helper {
|
|
|
2271
2271
|
}
|
|
2272
2272
|
}
|
|
2273
2273
|
|
|
2274
|
-
const aSec = sec || this.options.
|
|
2274
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds;
|
|
2275
2275
|
return this.browser.wait(() => this.browser.executeScript.call(this.browser, fn, ...args), aSec * 1000);
|
|
2276
2276
|
}
|
|
2277
2277
|
|
|
@@ -2288,7 +2288,7 @@ class Protractor extends Helper {
|
|
|
2288
2288
|
*
|
|
2289
2289
|
*/
|
|
2290
2290
|
async waitInUrl(urlPart, sec = null) {
|
|
2291
|
-
const aSec = sec || this.options.
|
|
2291
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds;
|
|
2292
2292
|
const waitTimeout = aSec * 1000;
|
|
2293
2293
|
|
|
2294
2294
|
return this.browser.wait(EC.urlContains(urlPart), waitTimeout)
|
|
@@ -2316,7 +2316,7 @@ class Protractor extends Helper {
|
|
|
2316
2316
|
*
|
|
2317
2317
|
*/
|
|
2318
2318
|
async waitUrlEquals(urlPart, sec = null) {
|
|
2319
|
-
const aSec = sec || this.options.
|
|
2319
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds;
|
|
2320
2320
|
const waitTimeout = aSec * 1000;
|
|
2321
2321
|
const baseUrl = this.options.url;
|
|
2322
2322
|
if (urlPart.indexOf('http') < 0) {
|
|
@@ -2355,7 +2355,7 @@ class Protractor extends Helper {
|
|
|
2355
2355
|
context = this.context;
|
|
2356
2356
|
}
|
|
2357
2357
|
const el = global.element(guessLocator(context) || global.by.css(context));
|
|
2358
|
-
const aSec = sec || this.options.
|
|
2358
|
+
const aSec = sec || this.options.waitForTimeoutInSeconds;
|
|
2359
2359
|
return this.browser.wait(EC.textToBePresentInElement(el, text), aSec * 1000);
|
|
2360
2360
|
}
|
|
2361
2361
|
|
|
@@ -2414,7 +2414,7 @@ class Protractor extends Helper {
|
|
|
2414
2414
|
if (locator) {
|
|
2415
2415
|
const res = await this._locate(locator, true);
|
|
2416
2416
|
if (!res || res.length === 0) {
|
|
2417
|
-
return truth(`elements of ${locator}`, 'to be seen').assert(false);
|
|
2417
|
+
return truth(`elements of ${(new Locator(locator))}`, 'to be seen').assert(false);
|
|
2418
2418
|
}
|
|
2419
2419
|
const elem = res[0];
|
|
2420
2420
|
const location = await elem.getLocation();
|
package/docs/build/Puppeteer.js
CHANGED
|
@@ -732,7 +732,7 @@ class Puppeteer extends Helper {
|
|
|
732
732
|
*/
|
|
733
733
|
async moveCursorTo(locator, offsetX = 0, offsetY = 0) {
|
|
734
734
|
const els = await this._locate(locator);
|
|
735
|
-
assertElementExists(els);
|
|
735
|
+
assertElementExists(els, locator);
|
|
736
736
|
|
|
737
737
|
// Use manual mouse.move instead of .hover() so the offset can be added to the coordinates
|
|
738
738
|
const { x, y } = await getClickablePoint(els[0]);
|
|
@@ -1795,7 +1795,7 @@ class Puppeteer extends Helper {
|
|
|
1795
1795
|
throw new Error(`File at ${file} can not be found on local system`);
|
|
1796
1796
|
}
|
|
1797
1797
|
const els = await findFields.call(this, locator);
|
|
1798
|
-
assertElementExists(els, 'Field');
|
|
1798
|
+
assertElementExists(els, locator, 'Field');
|
|
1799
1799
|
await els[0].uploadFile(file);
|
|
1800
1800
|
return this._waitForAction();
|
|
1801
1801
|
}
|
|
@@ -2084,7 +2084,7 @@ class Puppeteer extends Helper {
|
|
|
2084
2084
|
*/
|
|
2085
2085
|
async seeNumberOfElements(locator, num) {
|
|
2086
2086
|
const elements = await this._locate(locator);
|
|
2087
|
-
return equals(`expected number of elements (${locator}) is ${num}, but found ${elements.length}`).assert(elements.length, num);
|
|
2087
|
+
return equals(`expected number of elements (${(new Locator(locator))}) is ${num}, but found ${elements.length}`).assert(elements.length, num);
|
|
2088
2088
|
}
|
|
2089
2089
|
|
|
2090
2090
|
/**
|
|
@@ -2104,7 +2104,7 @@ class Puppeteer extends Helper {
|
|
|
2104
2104
|
*/
|
|
2105
2105
|
async seeNumberOfVisibleElements(locator, num) {
|
|
2106
2106
|
const res = await this.grabNumberOfVisibleElements(locator);
|
|
2107
|
-
return equals(`expected number of visible elements (${locator}) is ${num}, but found ${res}`).assert(res, num);
|
|
2107
|
+
return equals(`expected number of visible elements (${(new Locator(locator))}) is ${num}, but found ${res}`).assert(res, num);
|
|
2108
2108
|
}
|
|
2109
2109
|
|
|
2110
2110
|
/**
|
|
@@ -2516,7 +2516,7 @@ class Puppeteer extends Helper {
|
|
|
2516
2516
|
}
|
|
2517
2517
|
return true;
|
|
2518
2518
|
});
|
|
2519
|
-
return equals(`all elements (${locator}) to have CSS property ${JSON.stringify(cssProperties)}`).assert(chunked.length, elemAmount);
|
|
2519
|
+
return equals(`all elements (${(new Locator(locator))}) to have CSS property ${JSON.stringify(cssProperties)}`).assert(chunked.length, elemAmount);
|
|
2520
2520
|
}
|
|
2521
2521
|
|
|
2522
2522
|
/**
|
|
@@ -2556,7 +2556,7 @@ class Puppeteer extends Helper {
|
|
|
2556
2556
|
}
|
|
2557
2557
|
return true;
|
|
2558
2558
|
});
|
|
2559
|
-
return equals(`all elements (${locator}) to have attributes ${JSON.stringify(attributes)}`).assert(chunked.length, elemAmount);
|
|
2559
|
+
return equals(`all elements (${(new Locator(locator))}) to have attributes ${JSON.stringify(attributes)}`).assert(chunked.length, elemAmount);
|
|
2560
2560
|
}
|
|
2561
2561
|
|
|
2562
2562
|
/**
|
|
@@ -2659,7 +2659,7 @@ class Puppeteer extends Helper {
|
|
|
2659
2659
|
assertElementExists(res, locator);
|
|
2660
2660
|
if (res.length > 1) this.debug(`[Elements] Using first element out of ${res.length}`);
|
|
2661
2661
|
const elem = res[0];
|
|
2662
|
-
this.debug(`Screenshot of ${locator} element has been saved to ${outputFile}`);
|
|
2662
|
+
this.debug(`Screenshot of ${(new Locator(locator))} element has been saved to ${outputFile}`);
|
|
2663
2663
|
return elem.screenshot({ path: outputFile, type: 'png' });
|
|
2664
2664
|
}
|
|
2665
2665
|
|
|
File without changes
|