codeceptjs 3.0.3 → 3.0.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.
Files changed (64) hide show
  1. package/CHANGELOG.md +114 -18
  2. package/bin/codecept.js +1 -0
  3. package/docs/basics.md +2 -2
  4. package/docs/bdd.md +12 -1
  5. package/docs/build/Appium.js +2 -1
  6. package/docs/build/GraphQL.js +9 -10
  7. package/docs/build/Nightmare.js +4 -5
  8. package/docs/build/Playwright.js +164 -37
  9. package/docs/build/Protractor.js +1 -1
  10. package/docs/build/Puppeteer.js +1 -1
  11. package/docs/build/REST.js +24 -4
  12. package/docs/build/TestCafe.js +1 -1
  13. package/docs/build/WebDriver.js +85 -17
  14. package/docs/changelog.md +114 -18
  15. package/docs/data.md +5 -5
  16. package/docs/detox.md +2 -2
  17. package/docs/docker.md +11 -11
  18. package/docs/email.md +8 -8
  19. package/docs/helpers/Appium.md +1 -1
  20. package/docs/helpers/Nightmare.md +4 -5
  21. package/docs/helpers/Playwright.md +94 -64
  22. package/docs/helpers/Protractor.md +1 -1
  23. package/docs/helpers/Puppeteer.md +1 -1
  24. package/docs/helpers/REST.md +9 -0
  25. package/docs/helpers/TestCafe.md +1 -1
  26. package/docs/helpers/WebDriver.md +2 -1
  27. package/docs/locators.md +29 -2
  28. package/docs/mobile-react-native-locators.md +2 -2
  29. package/docs/mobile.md +3 -3
  30. package/docs/nightmare.md +0 -5
  31. package/docs/pageobjects.md +3 -1
  32. package/docs/parallel.md +35 -10
  33. package/docs/playwright.md +55 -8
  34. package/docs/plugins.md +73 -29
  35. package/docs/reports.md +8 -7
  36. package/docs/typescript.md +47 -5
  37. package/docs/webapi/fillField.mustache +1 -1
  38. package/lib/cli.js +25 -10
  39. package/lib/codecept.js +9 -1
  40. package/lib/command/interactive.js +10 -9
  41. package/lib/command/run.js +1 -1
  42. package/lib/command/workers/runTests.js +11 -6
  43. package/lib/config.js +8 -3
  44. package/lib/event.js +2 -0
  45. package/lib/helper/Appium.js +1 -0
  46. package/lib/helper/GraphQL.js +9 -10
  47. package/lib/helper/Nightmare.js +1 -1
  48. package/lib/helper/Playwright.js +131 -38
  49. package/lib/helper/REST.js +24 -4
  50. package/lib/helper/WebDriver.js +84 -16
  51. package/lib/interfaces/gherkin.js +11 -4
  52. package/lib/output.js +7 -4
  53. package/lib/plugin/allure.js +3 -7
  54. package/lib/plugin/fakerTransform.js +51 -0
  55. package/lib/plugin/screenshotOnFail.js +6 -2
  56. package/lib/recorder.js +9 -0
  57. package/lib/step.js +2 -1
  58. package/lib/transform.js +26 -0
  59. package/lib/ui.js +6 -2
  60. package/lib/within.js +1 -1
  61. package/lib/workers.js +39 -25
  62. package/package.json +14 -9
  63. package/typings/index.d.ts +49 -21
  64. package/typings/types.d.ts +72 -26
@@ -35,9 +35,10 @@ let defaultSelectorEnginesInitialized = false;
35
35
 
36
36
  const popupStore = new Popup();
37
37
  const consoleLogStore = new Console();
38
- const availableBrowsers = ['chromium', 'webkit', 'firefox'];
38
+ const availableBrowsers = ['chromium', 'webkit', 'firefox', 'electron'];
39
39
 
40
40
  const { createValueEngine, createDisabledEngine } = require('./extras/PlaywrightPropEngine');
41
+
41
42
  /**
42
43
  * Uses [Playwright](https://github.com/microsoft/playwright) library to run tests inside:
43
44
  *
@@ -58,7 +59,7 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
58
59
  * This helper should be configured in codecept.json or codecept.conf.js
59
60
  *
60
61
  * * `url`: base url of website to be tested
61
- * * `browser`: a browser to test on, either: `chromium`, `firefox`, `webkit`. Default: chromium.
62
+ * * `browser`: a browser to test on, either: `chromium`, `firefox`, `webkit`, `electron`. Default: chromium.
62
63
  * * `show`: (optional, default: false) - show browser window.
63
64
  * * `restart`: (optional, default: true) - restart browser between tests.
64
65
  * * `disableScreenshots`: (optional, default: false) - don't save screenshot on failure.
@@ -77,6 +78,7 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
77
78
  * * `userAgent`: (optional) user-agent string.
78
79
  * * `manualStart`: (optional, default: false) - do not start browser before a test, start it manually inside a helper with `this.helpers["Playwright"]._startBrowser()`.
79
80
  * * `chromium`: (optional) pass additional chromium options
81
+ * * `electron`: (optional) pass additional electron options
80
82
  *
81
83
  * #### Example #1: Wait for 0 network connections.
82
84
  *
@@ -121,7 +123,7 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
121
123
  * }
122
124
  * ```
123
125
  *
124
- * #### Example #4: Connect to remote browser by specifying [websocket endpoint](https://chromedevtools.github.io/devtools-protocol/#how-do-i-access-the-browser-target)
126
+ * #### Example #4: Connect to remote browser by specifying [websocket endpoint](https://playwright.dev/docs/api/class-browsertype#browsertypeconnectparams)
125
127
  *
126
128
  * ```js
127
129
  * {
@@ -129,7 +131,7 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
129
131
  * Playwright: {
130
132
  * url: "http://localhost",
131
133
  * chromium: {
132
- * browserWSEndpoint: "ws://localhost:9222/devtools/browser/c5aa6160-b5bc-4d53-bb49-6ecb36cd2e0a"
134
+ * browserWSEndpoint: { wsEndpoint: 'ws://localhost:9222/devtools/browser/c5aa6160-b5bc-4d53-bb49-6ecb36cd2e0a' }
133
135
  * }
134
136
  * }
135
137
  * }
@@ -147,6 +149,7 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
147
149
  * url: "http://localhost",
148
150
  * show: true // headless mode not supported for extensions
149
151
  * chromium: {
152
+ * userDataDir: '/tmp/playwright-tmp', // necessary to launch the browser in normal mode instead of incognito,
150
153
  * args: [
151
154
  * `--disable-extensions-except=${pathToExtension}`,
152
155
  * `--load-extension=${pathToExtension}`
@@ -206,6 +209,8 @@ class Playwright extends Helper {
206
209
  this.isAuthenticated = false;
207
210
  this.sessionPages = {};
208
211
  this.activeSessionName = '';
212
+ this.isElectron = false;
213
+ this.electronSessions = [];
209
214
 
210
215
  // override defaults with config
211
216
  this._setConfig(config);
@@ -257,6 +262,8 @@ class Playwright extends Helper {
257
262
  ...this._getOptionsForBrowser(config),
258
263
  };
259
264
  this.isRemoteBrowser = !!this.playwrightOptions.browserWSEndpoint;
265
+ this.isElectron = this.options.browser === 'electron';
266
+ this.userDataDir = this.playwrightOptions.userDataDir;
260
267
  popupStore.defaultAction = this.options.defaultPopupAction;
261
268
  }
262
269
 
@@ -268,7 +275,7 @@ class Playwright extends Helper {
268
275
  },
269
276
  {
270
277
  name: 'browser',
271
- message: 'Browser in which testing will be performed. Possible options: chromium, firefox or webkit',
278
+ message: 'Browser in which testing will be performed. Possible options: chromium, firefox, webkit or electron',
272
279
  default: 'chromium',
273
280
  },
274
281
  ];
@@ -320,11 +327,21 @@ class Playwright extends Helper {
320
327
  async _after() {
321
328
  if (!this.isRunning) return;
322
329
 
330
+ if (this.isElectron) {
331
+ this.browser.close();
332
+ this.electronSessions.forEach(session => session.close());
333
+ return;
334
+ }
335
+
323
336
  // close other sessions
324
- const contexts = await this.browser.contexts();
325
- contexts.shift();
337
+ try {
338
+ const contexts = await this.browser.contexts();
339
+ contexts.shift();
326
340
 
327
- await Promise.all(contexts.map(c => c.close()));
341
+ await Promise.all(contexts.map(c => c.close()));
342
+ } catch (e) {
343
+ console.log(e);
344
+ }
328
345
 
329
346
  if (this.options.restart) {
330
347
  this.isRunning = false;
@@ -371,12 +388,22 @@ class Playwright extends Helper {
371
388
  this.debugSection('New Context', config ? JSON.stringify(config) : 'opened');
372
389
  this.activeSessionName = sessionName;
373
390
 
374
- const bc = await this.browser.newContext(config);
375
- const page = await bc.newPage();
391
+ let browserContext;
392
+ let page;
393
+ if (this.isElectron) {
394
+ const browser = await playwright._electron.launch(this.playwrightOptions);
395
+ this.electronSessions.push(browser);
396
+ browserContext = browser.context();
397
+ page = await browser.firstWindow();
398
+ } else {
399
+ browserContext = await this.browser.newContext(config);
400
+ page = await browserContext.newPage();
401
+ }
402
+
376
403
  targetCreatedHandler.call(this, page);
377
404
  this._setPage(page);
378
405
  // Create a new page inside context.
379
- return bc;
406
+ return browserContext;
380
407
  },
381
408
  stop: async () => {
382
409
  // is closed by _after
@@ -489,6 +516,7 @@ class Playwright extends Helper {
489
516
  if (!page) return;
490
517
  page.setDefaultNavigationTimeout(this.options.getPageTimeout);
491
518
  this.context = await this.page;
519
+ this.contextLocator = null;
492
520
  if (this.config.browser === 'chrome') {
493
521
  await page.bringToFront();
494
522
  }
@@ -547,15 +575,19 @@ class Playwright extends Helper {
547
575
  }
548
576
 
549
577
  async _startBrowser() {
550
- if (this.isRemoteBrowser) {
578
+ if (this.isElectron) {
579
+ this.browser = await playwright._electron.launch(this.playwrightOptions);
580
+ } else if (this.isRemoteBrowser) {
551
581
  try {
552
- this.browser = await playwright[this.options.browser].connect(this.playwrightOptions);
582
+ this.browser = await playwright[this.options.browser].connect(this.playwrightOptions.browserWSEndpoint);
553
583
  } catch (err) {
554
584
  if (err.toString().indexOf('ECONNREFUSED')) {
555
585
  throw new RemoteBrowserConnectionRefused(err);
556
586
  }
557
587
  throw err;
558
588
  }
589
+ } else if (this.userDataDir) {
590
+ this.browser = await playwright[this.options.browser].launchPersistentContext(this.userDataDir, this.playwrightOptions);
559
591
  } else {
560
592
  this.browser = await playwright[this.options.browser].launch(this.playwrightOptions);
561
593
  }
@@ -564,11 +596,22 @@ class Playwright extends Helper {
564
596
  this.browser.on('targetchanged', (target) => {
565
597
  this.debugSection('Url', target.url());
566
598
  });
567
- this.browserContext = await this.browser.newContext({ ignoreHTTPSErrors: this.options.ignoreHTTPSErrors, acceptDownloads: true, ...this.options.emulate });// Adding the HTTPSError ignore in the context so that we can ignore those errors
568
599
 
569
- const existingPages = await this.browserContext.pages();
600
+ if (this.isElectron) {
601
+ this.browserContext = this.browser.context();
602
+ } else if (this.userDataDir) {
603
+ this.browserContext = this.browser;
604
+ } else {
605
+ this.browserContext = await this.browser.newContext({ ignoreHTTPSErrors: this.options.ignoreHTTPSErrors, acceptDownloads: true, ...this.options.emulate });// Adding the HTTPSError ignore in the context so that we can ignore those errors
606
+ }
570
607
 
571
- const mainPage = existingPages[0] || await this.browserContext.newPage();
608
+ let mainPage;
609
+ if (this.isElectron) {
610
+ mainPage = await this.browser.firstWindow();
611
+ } else {
612
+ const existingPages = await this.browserContext.pages();
613
+ mainPage = existingPages[0] || await this.browserContext.newPage();
614
+ }
572
615
  targetCreatedHandler.call(this, mainPage);
573
616
 
574
617
  await this._setPage(mainPage);
@@ -577,6 +620,10 @@ class Playwright extends Helper {
577
620
  this.isRunning = true;
578
621
  }
579
622
 
623
+ _getType() {
624
+ return this.browser._type;
625
+ }
626
+
580
627
  async _stopBrowser() {
581
628
  this.withinLocator = null;
582
629
  this._setPage(null);
@@ -611,6 +658,7 @@ class Playwright extends Helper {
611
658
  const els = await this._locate(locator);
612
659
  assertElementExists(els, locator);
613
660
  this.context = els[0];
661
+ this.contextLocator = locator;
614
662
 
615
663
  this.withinLocator = new Locator(locator);
616
664
  }
@@ -618,6 +666,7 @@ class Playwright extends Helper {
618
666
  async _withinEnd() {
619
667
  this.withinLocator = null;
620
668
  this.context = await this.page;
669
+ this.contextLocator = null;
621
670
  }
622
671
 
623
672
  _extractDataFromPerformanceTiming(timing, ...dataNames) {
@@ -635,6 +684,9 @@ class Playwright extends Helper {
635
684
  * {{> amOnPage }}
636
685
  */
637
686
  async amOnPage(url) {
687
+ if (this.isElectron) {
688
+ throw new Error('Cannot open pages inside an Electron container');
689
+ }
638
690
  if (!(/^\w+\:\/\//.test(url))) {
639
691
  url = this.options.url + url;
640
692
  }
@@ -800,11 +852,7 @@ class Playwright extends Helper {
800
852
  }
801
853
 
802
854
  /**
803
- * Checks that title is equal to provided one.
804
- *
805
- * ```js
806
- * I.seeTitleEquals('Test title.');
807
- * ```
855
+ * {{> seeTitleEquals }}
808
856
  */
809
857
  async seeTitleEquals(text) {
810
858
  const title = await this.page.title();
@@ -890,6 +938,9 @@ class Playwright extends Helper {
890
938
  * @param {number} [num=1]
891
939
  */
892
940
  async switchToNextTab(num = 1) {
941
+ if (this.isElectron) {
942
+ throw new Error('Cannot switch tabs inside an Electron container');
943
+ }
893
944
  const pages = await this.browserContext.pages();
894
945
 
895
946
  const index = pages.indexOf(this.page);
@@ -913,6 +964,9 @@ class Playwright extends Helper {
913
964
  * @param {number} [num=1]
914
965
  */
915
966
  async switchToPreviousTab(num = 1) {
967
+ if (this.isElectron) {
968
+ throw new Error('Cannot switch tabs inside an Electron container');
969
+ }
916
970
  const pages = await this.browserContext.pages();
917
971
  const index = pages.indexOf(this.page);
918
972
  this.withinLocator = null;
@@ -934,6 +988,9 @@ class Playwright extends Helper {
934
988
  * ```
935
989
  */
936
990
  async closeCurrentTab() {
991
+ if (this.isElectron) {
992
+ throw new Error('Cannot close current tab inside an Electron container');
993
+ }
937
994
  const oldPage = this.page;
938
995
  await this.switchToPreviousTab();
939
996
  await oldPage.close();
@@ -972,6 +1029,9 @@ class Playwright extends Helper {
972
1029
  * ```
973
1030
  */
974
1031
  async openNewTab(options) {
1032
+ if (this.isElectron) {
1033
+ throw new Error('Cannot open new tabs inside an Electron container');
1034
+ }
975
1035
  await this._setPage(await this.browserContext.newPage(options));
976
1036
  return this._waitForAction();
977
1037
  }
@@ -1069,14 +1129,7 @@ class Playwright extends Helper {
1069
1129
  }
1070
1130
 
1071
1131
  /**
1072
- *
1073
- * Force clicks an element without waiting for it to become visible and not animating.
1074
- *
1075
- * ```js
1076
- * I.forceClick('#hiddenButton');
1077
- * I.forceClick('Click me', '#hidden');
1078
- * ```
1079
- *
1132
+ * {{> forceClick }}
1080
1133
  */
1081
1134
  async forceClick(locator, context = null) {
1082
1135
  return proceedClick.call(this, locator, context, { force: true });
@@ -1500,6 +1553,10 @@ class Playwright extends Helper {
1500
1553
  * I.executeScript(([x, y]) => x + y, [x, y]);
1501
1554
  * ```
1502
1555
  * If a function returns a Promise it will wait for its resolution.
1556
+ *
1557
+ * @param {string|function} fn function to be executed in browser context.
1558
+ * @param {any} [arg] optional argument to pass to the function
1559
+ * @return {Promise<any>}
1503
1560
  */
1504
1561
  async executeScript(fn, arg) {
1505
1562
  let context = this.page;
@@ -1509,15 +1566,32 @@ class Playwright extends Helper {
1509
1566
  return context.evaluate.apply(context, [fn, arg]);
1510
1567
  }
1511
1568
 
1569
+ /**
1570
+ * Grab Locator if called within Context
1571
+ *
1572
+ * @param {*} locator
1573
+ */
1574
+ _contextLocator(locator) {
1575
+ locator = buildLocatorString(new Locator(locator, 'css'));
1576
+
1577
+ if (this.contextLocator) {
1578
+ const contextLocator = buildLocatorString(new Locator(this.contextLocator, 'css'));
1579
+ locator = `${contextLocator} >> ${locator}`;
1580
+ }
1581
+
1582
+ return locator;
1583
+ }
1584
+
1512
1585
  /**
1513
1586
  * {{> grabTextFrom }}
1514
1587
  *
1515
1588
  */
1516
1589
  async grabTextFrom(locator) {
1517
- const texts = await this.grabTextFromAll(locator);
1518
- assertElementExists(texts, locator);
1519
- this.debugSection('Text', texts[0]);
1520
- return texts[0];
1590
+ locator = this._contextLocator(locator);
1591
+ const text = await this.page.textContent(locator);
1592
+ assertElementExists(text, locator);
1593
+ this.debugSection('Text', text);
1594
+ return text;
1521
1595
  }
1522
1596
 
1523
1597
  /**
@@ -1590,8 +1664,7 @@ class Playwright extends Helper {
1590
1664
  async grabCssPropertyFromAll(locator, cssProperty) {
1591
1665
  const els = await this._locate(locator);
1592
1666
  this.debug(`Matched ${els.length} elements`);
1593
- const res = await Promise.all(els.map(el => el.$eval('xpath=.', el => JSON.parse(JSON.stringify(getComputedStyle(el))), el)));
1594
- const cssValues = res.map(props => props[toCamelCase(cssProperty)]);
1667
+ const cssValues = await Promise.all(els.map(el => el.$eval('xpath=.', (el, cssProperty) => getComputedStyle(el).getPropertyValue(cssProperty), cssProperty)));
1595
1668
 
1596
1669
  return cssValues;
1597
1670
  }
@@ -2041,6 +2114,7 @@ class Playwright extends Helper {
2041
2114
 
2042
2115
  if (locator >= 0 && locator < childFrames.length) {
2043
2116
  this.context = childFrames[locator];
2117
+ this.contextLocator = locator;
2044
2118
  } else {
2045
2119
  throw new Error('Element #invalidIframeSelector was not found by text|CSS|XPath');
2046
2120
  }
@@ -2048,6 +2122,7 @@ class Playwright extends Helper {
2048
2122
  }
2049
2123
  if (!locator) {
2050
2124
  this.context = this.page;
2125
+ this.contextLocator = null;
2051
2126
  return;
2052
2127
  }
2053
2128
 
@@ -2058,8 +2133,10 @@ class Playwright extends Helper {
2058
2133
 
2059
2134
  if (contentFrame) {
2060
2135
  this.context = contentFrame;
2136
+ this.contextLocator = null;
2061
2137
  } else {
2062
2138
  this.context = els[0];
2139
+ this.contextLocator = locator;
2063
2140
  }
2064
2141
  }
2065
2142
 
@@ -2083,7 +2160,7 @@ class Playwright extends Helper {
2083
2160
  /**
2084
2161
  * Waits for navigation to finish. By default takes configured `waitForNavigation` option.
2085
2162
  *
2086
- * See [Pupeteer's reference](https://github.com/microsoft/Playwright/blob/master/docs/api.md#pagewaitfornavigationoptions)
2163
+ * See [Playwright's reference](https://playwright.dev/docs/api/class-page?_highlight=waitfornavi#pagewaitfornavigationoptions)
2087
2164
  *
2088
2165
  * @param {*} opts
2089
2166
  */
@@ -2176,6 +2253,19 @@ async function findElements(matcher, locator) {
2176
2253
  return matcher.$$(buildLocatorString(locator));
2177
2254
  }
2178
2255
 
2256
+ async function getVisibleElements(elements) {
2257
+ const visibleElements = [];
2258
+ for (const element of elements) {
2259
+ if (await element.isVisible()) {
2260
+ visibleElements.push(element);
2261
+ }
2262
+ }
2263
+ if (visibleElements.length === 0) {
2264
+ return elements;
2265
+ }
2266
+ return visibleElements;
2267
+ }
2268
+
2179
2269
  async function proceedClick(locator, context = null, options = {}) {
2180
2270
  let matcher = await this._getContext();
2181
2271
  if (context) {
@@ -2195,7 +2285,8 @@ async function proceedClick(locator, context = null, options = {}) {
2195
2285
  if (options.force) {
2196
2286
  await els[0].dispatchEvent('click');
2197
2287
  } else {
2198
- await els[0].click(options);
2288
+ const element = els.length > 1 ? (await getVisibleElements(els))[0] : els[0];
2289
+ await element.click(options);
2199
2290
  }
2200
2291
  const promises = [];
2201
2292
  if (options.waitForNavigation) {
@@ -2453,11 +2544,13 @@ async function targetCreatedHandler(page) {
2453
2544
  // we are inside iframe?
2454
2545
  const frameEl = await this.context.frameElement();
2455
2546
  this.context = await frameEl.contentFrame();
2547
+ this.contextLocator = null;
2456
2548
  return;
2457
2549
  }
2458
2550
  // if context element was in iframe - keep it
2459
2551
  // if (await this.context.ownerFrame()) return;
2460
2552
  this.context = page;
2553
+ this.contextLocator = null;
2461
2554
  });
2462
2555
  });
2463
2556
  page.on('console', (msg) => {
@@ -2468,7 +2561,7 @@ async function targetCreatedHandler(page) {
2468
2561
  if (this.options.userAgent) {
2469
2562
  await page.setUserAgent(this.options.userAgent);
2470
2563
  }
2471
- if (this.options.windowSize && this.options.windowSize.indexOf('x') > 0) {
2564
+ if (this.options.windowSize && this.options.windowSize.indexOf('x') > 0 && this._getType() === 'Browser') {
2472
2565
  const dimensions = this.options.windowSize.split('x');
2473
2566
  const width = parseInt(dimensions[0], 10);
2474
2567
  const height = parseInt(dimensions[1], 10);
@@ -1,4 +1,5 @@
1
1
  const axios = require('axios').default;
2
+ const Secret = require('../secret');
2
3
 
3
4
  const Helper = require('../helper');
4
5
 
@@ -58,7 +59,8 @@ class REST extends Helper {
58
59
 
59
60
  this.options = { ...this.options, ...config };
60
61
  this.headers = { ...this.options.defaultHeaders };
61
- axios.defaults.headers = this.options.defaultHeaders;
62
+ this.axios = axios.create();
63
+ this.axios.defaults.headers = this.options.defaultHeaders;
62
64
  }
63
65
 
64
66
  static _checkRequirements() {
@@ -75,12 +77,18 @@ class REST extends Helper {
75
77
  * @param {*} request
76
78
  */
77
79
  async _executeRequest(request) {
78
- axios.defaults.timeout = request.timeout || this.options.timeout;
80
+ const _debugRequest = { ...request };
81
+ this.axios.defaults.timeout = request.timeout || this.options.timeout;
79
82
 
80
83
  if (this.headers && this.headers.auth) {
81
84
  request.auth = this.headers.auth;
82
85
  }
83
86
 
87
+ if (request.data instanceof Secret) {
88
+ _debugRequest.data = '*****';
89
+ request.data = typeof request.data === 'object' ? { ...request.data.toString() } : request.data.toString();
90
+ }
91
+
84
92
  if ((typeof request.data) === 'string') {
85
93
  if (!request.headers || !request.headers['Content-Type']) {
86
94
  request.headers = { ...request.headers, ...{ 'Content-Type': 'application/x-www-form-urlencoded' } };
@@ -91,11 +99,11 @@ class REST extends Helper {
91
99
  await this.config.onRequest(request);
92
100
  }
93
101
 
94
- this.debugSection('Request', JSON.stringify(request));
102
+ this.debugSection('Request', JSON.stringify(_debugRequest));
95
103
 
96
104
  let response;
97
105
  try {
98
- response = await axios(request);
106
+ response = await this.axios(request);
99
107
  } catch (err) {
100
108
  if (!err.response) throw err;
101
109
  this.debugSection('Response', `Response error. Status code: ${err.response.status}`);
@@ -149,6 +157,10 @@ class REST extends Helper {
149
157
  *
150
158
  * ```js
151
159
  * I.sendPostRequest('/api/users.json', { "email": "user@user.com" });
160
+ *
161
+ * // To mask the payload in logs
162
+ * I.sendPostRequest('/api/users.json', secret({ "email": "user@user.com" }));
163
+ *
152
164
  * ```
153
165
  *
154
166
  * @param {*} url
@@ -176,6 +188,10 @@ class REST extends Helper {
176
188
  *
177
189
  * ```js
178
190
  * I.sendPatchRequest('/api/users.json', { "email": "user@user.com" });
191
+ *
192
+ * // To mask the payload in logs
193
+ * I.sendPatchRequest('/api/users.json', secret({ "email": "user@user.com" }));
194
+ *
179
195
  * ```
180
196
  *
181
197
  * @param {string} url
@@ -203,6 +219,10 @@ class REST extends Helper {
203
219
  *
204
220
  * ```js
205
221
  * I.sendPutRequest('/api/users.json', { "email": "user@user.com" });
222
+ *
223
+ * // To mask the payload in logs
224
+ * I.sendPutRequest('/api/users.json', secret({ "email": "user@user.com" }));
225
+ *
206
226
  * ```
207
227
  *
208
228
  * @param {string} url