codeceptjs 3.4.1 → 3.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.md +11 -9
  3. package/bin/codecept.js +1 -1
  4. package/docs/ai.md +248 -0
  5. package/docs/build/Appium.js +47 -7
  6. package/docs/build/JSONResponse.js +4 -4
  7. package/docs/build/Nightmare.js +3 -1
  8. package/docs/build/OpenAI.js +122 -0
  9. package/docs/build/Playwright.js +234 -54
  10. package/docs/build/Protractor.js +3 -1
  11. package/docs/build/Puppeteer.js +101 -12
  12. package/docs/build/REST.js +15 -5
  13. package/docs/build/TestCafe.js +61 -2
  14. package/docs/build/WebDriver.js +85 -5
  15. package/docs/changelog.md +85 -0
  16. package/docs/helpers/Appium.md +152 -147
  17. package/docs/helpers/JSONResponse.md +4 -4
  18. package/docs/helpers/Nightmare.md +2 -0
  19. package/docs/helpers/OpenAI.md +70 -0
  20. package/docs/helpers/Playwright.md +228 -151
  21. package/docs/helpers/Puppeteer.md +153 -101
  22. package/docs/helpers/REST.md +6 -5
  23. package/docs/helpers/TestCafe.md +97 -49
  24. package/docs/helpers/WebDriver.md +159 -107
  25. package/docs/mobile.md +49 -2
  26. package/docs/parallel.md +56 -0
  27. package/docs/plugins.md +87 -33
  28. package/docs/secrets.md +6 -0
  29. package/docs/tutorial.md +2 -2
  30. package/docs/webapi/appendField.mustache +2 -0
  31. package/docs/webapi/blur.mustache +17 -0
  32. package/docs/webapi/focus.mustache +12 -0
  33. package/docs/webapi/type.mustache +3 -0
  34. package/lib/ai.js +171 -0
  35. package/lib/cli.js +10 -2
  36. package/lib/codecept.js +4 -0
  37. package/lib/command/dryRun.js +9 -1
  38. package/lib/command/generate.js +46 -3
  39. package/lib/command/init.js +23 -1
  40. package/lib/command/interactive.js +15 -1
  41. package/lib/command/run-workers.js +2 -1
  42. package/lib/container.js +13 -3
  43. package/lib/event.js +2 -0
  44. package/lib/helper/Appium.js +45 -7
  45. package/lib/helper/JSONResponse.js +4 -4
  46. package/lib/helper/Nightmare.js +1 -1
  47. package/lib/helper/OpenAI.js +122 -0
  48. package/lib/helper/Playwright.js +200 -45
  49. package/lib/helper/Protractor.js +1 -1
  50. package/lib/helper/Puppeteer.js +67 -12
  51. package/lib/helper/REST.js +15 -5
  52. package/lib/helper/TestCafe.js +30 -2
  53. package/lib/helper/WebDriver.js +51 -5
  54. package/lib/helper/scripts/blurElement.js +17 -0
  55. package/lib/helper/scripts/focusElement.js +17 -0
  56. package/lib/helper/scripts/highlightElement.js +20 -0
  57. package/lib/html.js +258 -0
  58. package/lib/interfaces/gherkin.js +8 -0
  59. package/lib/listener/retry.js +2 -1
  60. package/lib/pause.js +73 -17
  61. package/lib/plugin/debugErrors.js +67 -0
  62. package/lib/plugin/fakerTransform.js +4 -6
  63. package/lib/plugin/heal.js +177 -0
  64. package/lib/plugin/screenshotOnFail.js +11 -2
  65. package/lib/recorder.js +11 -8
  66. package/lib/secret.js +5 -4
  67. package/lib/step.js +6 -1
  68. package/lib/ui.js +4 -3
  69. package/lib/utils.js +17 -0
  70. package/lib/workers.js +57 -9
  71. package/package.json +25 -16
  72. package/translations/ja-JP.js +9 -9
  73. package/typings/index.d.ts +43 -9
  74. package/typings/promiseBasedTypes.d.ts +242 -25
  75. package/typings/types.d.ts +260 -35
package/lib/workers.js CHANGED
@@ -10,12 +10,14 @@ const MochaFactory = require('./mochaFactory');
10
10
  const Container = require('./container');
11
11
  const { getTestRoot } = require('./command/utils');
12
12
  const { isFunction, fileExists } = require('./utils');
13
+ const { replaceValueDeep, deepClone } = require('./utils');
13
14
  const mainConfig = require('./config');
14
15
  const output = require('./output');
15
16
  const event = require('./event');
16
17
  const recorder = require('./recorder');
17
18
  const runHook = require('./hooks');
18
19
  const WorkerStorage = require('./workerStorage');
20
+ const collection = require('./command/run-multiple/collection');
19
21
 
20
22
  const pathToWorker = path.join(__dirname, 'command', 'workers', 'runTests.js');
21
23
 
@@ -79,15 +81,39 @@ const repackTest = (test) => {
79
81
  return test;
80
82
  };
81
83
 
82
- const createWorkerObjects = (testGroups, config, testRoot, options) => {
83
- return testGroups.map((tests, index) => {
84
- const workerObj = new WorkerObject(index);
85
- workerObj.addConfig(config);
86
- workerObj.addTests(tests);
87
- workerObj.setTestRoot(testRoot);
88
- workerObj.addOptions(options);
89
- return workerObj;
84
+ const createWorkerObjects = (testGroups, config, testRoot, options, selectedRuns) => {
85
+ selectedRuns = options && options.all && config.multiple ? Object.keys(config.multiple) : selectedRuns;
86
+ if (selectedRuns === undefined || !selectedRuns.length || config.multiple === undefined) {
87
+ return testGroups.map((tests, index) => {
88
+ const workerObj = new WorkerObject(index);
89
+ workerObj.addConfig(config);
90
+ workerObj.addTests(tests);
91
+ workerObj.setTestRoot(testRoot);
92
+ workerObj.addOptions(options);
93
+ return workerObj;
94
+ });
95
+ }
96
+ const workersToExecute = [];
97
+ collection.createRuns(selectedRuns, config).forEach((worker) => {
98
+ const workerName = worker.getOriginalName() || worker.getName();
99
+ const workerConfig = worker.getConfig();
100
+ workersToExecute.push(getOverridenConfig(workerName, workerConfig, config));
101
+ });
102
+ const workers = [];
103
+ let index = 0;
104
+ testGroups.forEach((tests) => {
105
+ const testWorkerArray = [];
106
+ workersToExecute.forEach((finalConfig) => {
107
+ const workerObj = new WorkerObject(index++);
108
+ workerObj.addConfig(finalConfig);
109
+ workerObj.addTests(tests);
110
+ workerObj.setTestRoot(testRoot);
111
+ workerObj.addOptions(options);
112
+ testWorkerArray.push(workerObj);
113
+ });
114
+ workers.push(...testWorkerArray);
90
115
  });
116
+ return workers;
91
117
  };
92
118
 
93
119
  const indexOfSmallestElement = (groups) => {
@@ -115,6 +141,28 @@ const convertToMochaTests = (testGroup) => {
115
141
  return group;
116
142
  };
117
143
 
144
+ const getOverridenConfig = (workerName, workerConfig, config) => {
145
+ // clone config
146
+ const overriddenConfig = deepClone(config);
147
+
148
+ // get configuration
149
+ const browserConfig = workerConfig.browser;
150
+
151
+ for (const key in browserConfig) {
152
+ overriddenConfig.helpers = replaceValueDeep(overriddenConfig.helpers, key, browserConfig[key]);
153
+ }
154
+
155
+ // override tests configuration
156
+ if (overriddenConfig.tests) {
157
+ overriddenConfig.tests = workerConfig.tests;
158
+ }
159
+
160
+ if (overriddenConfig.gherkin && workerConfig.gherkin && workerConfig.gherkin.features) {
161
+ overriddenConfig.gherkin.features = workerConfig.gherkin.features;
162
+ }
163
+ return overriddenConfig;
164
+ };
165
+
118
166
  class WorkerObject {
119
167
  /**
120
168
  * @param {Number} workerIndex - Unique ID for worker
@@ -183,7 +231,7 @@ class Workers extends EventEmitter {
183
231
 
184
232
  _initWorkers(numberOfWorkers, config) {
185
233
  this.splitTestsByGroups(numberOfWorkers, config);
186
- this.workers = createWorkerObjects(this.testGroups, this.codecept.config, config.testConfig, config.options);
234
+ this.workers = createWorkerObjects(this.testGroups, this.codecept.config, config.testConfig, config.options, config.selectedRuns);
187
235
  this.numberOfWorkers = this.workers.length;
188
236
  }
189
237
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeceptjs",
3
- "version": "3.4.1",
3
+ "version": "3.5.1",
4
4
  "description": "Supercharged End 2 End Testing Framework for NodeJS",
5
5
  "keywords": [
6
6
  "acceptance",
@@ -45,8 +45,14 @@
45
45
  "test": "npm run test:unit && npm run test:runner",
46
46
  "test:appium-quick": "mocha test/helper/Appium_test.js --grep 'quick'",
47
47
  "test:appium-other": "mocha test/helper/Appium_test.js --grep 'second'",
48
+ "test-app:start": "php -S 127.0.0.1:8000 -t test/data/app",
49
+ "test-app:stop": "kill -9 $(lsof -t -i:8000)",
50
+ "test:unit:webbapi:playwright": "mocha test/helper/Playwright_test.js",
51
+ "test:unit:webbapi:puppeteer": "mocha test/helper/Puppeteer_test.js",
52
+ "test:unit:webbapi:webDriver": "mocha test/helper/WebDriver_test.js",
53
+ "test:unit:webbapi:testCafe": "mocha test/helper/TestCafe_test.js",
48
54
  "def": "./runok.js def",
49
- "dev:graphql": "nodemon test/data/graphql/index.js",
55
+ "dev:graphql": "node test/data/graphql/index.js",
50
56
  "publish:site": "./runok.js publish:site",
51
57
  "update-contributor-faces": "contributor-faces .",
52
58
  "dtslint": "dtslint typings --localTs './node_modules/typescript/lib'",
@@ -58,13 +64,14 @@
58
64
  "@cucumber/cucumber-expressions": "^16",
59
65
  "@cucumber/gherkin": "^26",
60
66
  "@cucumber/messages": "^21.0.1",
67
+ "@xmldom/xmldom": "^0.7.9",
61
68
  "acorn": "^7.4.1",
62
69
  "arrify": "^2.0.1",
63
70
  "axios": "^1.3.3",
64
71
  "chai": "^4.3.6",
65
72
  "chai-deep-match": "^1.2.1",
66
73
  "chalk": "^4.1.2",
67
- "commander": "^2.20.3",
74
+ "commander": "^11.0.0",
68
75
  "cross-spawn": "^7.0.3",
69
76
  "css-to-xpath": "^0.1.0",
70
77
  "envinfo": "^7.8.1",
@@ -73,6 +80,7 @@
73
80
  "fn-args": "^4.0.0",
74
81
  "fs-extra": "^8.1.0",
75
82
  "glob": "^6.0.1",
83
+ "html-minifier": "^4.0.0",
76
84
  "inquirer": "^6.5.2",
77
85
  "joi": "^17.6.0",
78
86
  "js-beautify": "^1.14.0",
@@ -80,9 +88,11 @@
80
88
  "lodash.merge": "^4.6.2",
81
89
  "mkdirp": "^1.0.4",
82
90
  "mocha": "^10.2.0",
83
- "mocha-junit-reporter": "^1.23.3",
84
91
  "ms": "^2.1.3",
92
+ "openai": "^3.2.1",
93
+ "ora-classic": "^5.4.2",
85
94
  "parse-function": "^5.6.4",
95
+ "parse5": "^7.1.2",
86
96
  "promise-retry": "^1.1.1",
87
97
  "resq": "^1.10.2",
88
98
  "sprintf-js": "^1.1.1",
@@ -92,14 +102,14 @@
92
102
  "@codeceptjs/detox-helper": "^1.0.2",
93
103
  "@codeceptjs/mock-request": "^0.3.1",
94
104
  "@faker-js/faker": "^7.6.0",
95
- "@pollyjs/adapter-puppeteer": "^5.1.0",
105
+ "@pollyjs/adapter-puppeteer": "^6.0.5",
96
106
  "@pollyjs/core": "^5.1.0",
97
107
  "@types/inquirer": "^0.0.35",
98
108
  "@types/node": "^8.10.66",
99
- "@wdio/sauce-service": "^5.22.5",
100
- "@wdio/selenium-standalone-service": "^5.16.10",
101
- "@wdio/utils": "^5.23.0",
102
- "apollo-server-express": "^2.25.3",
109
+ "@wdio/sauce-service": "^8.3.8",
110
+ "@wdio/selenium-standalone-service": "^8.3.2",
111
+ "@wdio/utils": "^8.3.0",
112
+ "apollo-server-express": "2.25.3",
103
113
  "chai-as-promised": "^7.1.1",
104
114
  "chai-subset": "^1.6.0",
105
115
  "contributor-faces": "^1.0.3",
@@ -107,7 +117,7 @@
107
117
  "dtslint": "^4.1.6",
108
118
  "electron": "^12.2.3",
109
119
  "eslint": "^6.8.0",
110
- "eslint-config-airbnb-base": "^14.2.1",
120
+ "eslint-config-airbnb-base": "^15.0.0",
111
121
  "eslint-plugin-import": "^2.25.4",
112
122
  "eslint-plugin-mocha": "^6.3.0",
113
123
  "expect": "^26.6.2",
@@ -120,11 +130,10 @@
120
130
  "jsdoc-typeof-plugin": "^1.0.0",
121
131
  "json-server": "^0.10.1",
122
132
  "nightmare": "^3.0.2",
123
- "nodemon": "^1.19.4",
124
- "playwright": "^1.23.2",
133
+ "playwright": "^1.35.1",
125
134
  "puppeteer": "^10.4.0",
126
135
  "qrcode-terminal": "^0.12.0",
127
- "rosie": "^1.6.0",
136
+ "rosie": "^2.1.0",
128
137
  "runok": "^0.9.2",
129
138
  "sinon": "^9.2.4",
130
139
  "sinon-chai": "^3.7.0",
@@ -137,12 +146,12 @@
137
146
  "typescript": "^4.8.4",
138
147
  "wdio-docker-service": "^1.5.0",
139
148
  "webdriverio": "^8.3.8",
140
- "xml2js": "^0.4.23",
141
- "xmldom": "^0.1.31",
149
+ "xml2js": "^0.6.0",
150
+ "xmldom": "^0.5.0",
142
151
  "xpath": "0.0.27"
143
152
  },
144
153
  "engines": {
145
- "node": ">=8.9.1",
154
+ "node": ">=16.0",
146
155
  "npm": ">=5.6.0"
147
156
  },
148
157
  "es6": true
@@ -14,34 +14,34 @@ module.exports = {
14
14
  amOnPage: 'ページを移動する',
15
15
  click: 'クリックする',
16
16
  doubleClick: 'ダブルクリックする',
17
- see: 'テキストがあるか確認する',
17
+ see: 'テキストがあることを確認する',
18
18
  dontSee: 'テキストがないことを確認する',
19
19
  selectOption: 'オプションを選ぶ',
20
20
  fillField: 'フィールドに入力する',
21
21
  pressKey: 'キー入力する',
22
22
  triggerMouseEvent: 'マウスイベントを発火させる',
23
23
  attachFile: 'ファイルを添付する',
24
- seeInField: 'フィールドに文字が入っているか確認する',
25
- dontSeeInField: 'フィールドに文字が入っていないか確認する',
24
+ seeInField: 'フィールドに文字が入っていることを確認する',
25
+ dontSeeInField: 'フィールドに文字が入っていないことを確認する',
26
26
  appendField: 'フィールドに文字を追加する',
27
27
  checkOption: 'オプションをチェックする',
28
- seeCheckboxIsChecked: 'チェックされているか確認する',
28
+ seeCheckboxIsChecked: 'チェックされていることを確認する',
29
29
  dontSeeCheckboxIsChecked: 'チェックされていないことを確認する',
30
30
  grabTextFrom: 'テキストを取得する',
31
31
  grabValueFrom: '入力値を取得する',
32
32
  grabAttributeFrom: '要素を取得する',
33
- seeInTitle: 'タイトルに文字が含まれるか確認する',
33
+ seeInTitle: 'タイトルに文字が含まれていることを確認する',
34
34
  dontSeeInTitle: 'タイトルに文字が含まれないことを確認する',
35
35
  grabTitle: 'タイトルを取得する',
36
- seeElement: '要素があるか確認する',
36
+ seeElement: '要素があることを確認する',
37
37
  dontSeeElement: '要素がないことを確認する',
38
- seeInSource: 'ソースにあるか確認する',
38
+ seeInSource: 'ソースにあることを確認する',
39
39
  dontSeeInSource: 'ソースにないことを確認する',
40
40
  executeScript: 'スクリプトを実行する',
41
41
  executeAsyncScript: '非同期スクリプトを実行する',
42
- seeInCurrentUrl: 'URLに含まれるか確認する',
42
+ seeInCurrentUrl: 'URLに含まれることを確認する',
43
43
  dontSeeInCurrentUrl: 'URLに含まれないことを確認する',
44
- seeCurrentUrlEquals: 'URLが等しいか確認する',
44
+ seeCurrentUrlEquals: 'URLが等しいことを確認する',
45
45
  dontSeeCurrentUrlEquals: 'URLが等しくないことを確認する',
46
46
  saveScreenshot: 'スクリーンショットを保存する',
47
47
  setCookie: 'Cookieをセットする',
@@ -12,26 +12,26 @@ declare namespace CodeceptJS {
12
12
 
13
13
  type Cookie = {
14
14
  name: string;
15
- value: string;
15
+ value: string | boolean;
16
16
  domain?: string,
17
17
  path?: string,
18
18
  };
19
19
 
20
20
  type RetryConfig = {
21
21
  /** Filter tests by string or regexp pattern */
22
- grep: string | RegExp;
22
+ grep?: string | RegExp;
23
23
  /** Number of times to repeat scenarios of a Feature */
24
- Feature: number;
24
+ Feature?: number;
25
25
  /** Number of times to repeat scenarios */
26
- Scenario: number;
26
+ Scenario?: number;
27
27
  /** Number of times to repeat Before hook */
28
- Before: number;
28
+ Before?: number;
29
29
  /** Number of times to repeat After hook */
30
- After: number;
30
+ After?: number;
31
31
  /** Number of times to repeat BeforeSuite hook */
32
- BeforeSuite: number;
32
+ BeforeSuite?: number;
33
33
  /** Number of times to repeat AfterSuite hook */
34
- AfterSuite: number;
34
+ AfterSuite?: number;
35
35
  };
36
36
 
37
37
  type TimeoutConfig = {
@@ -67,6 +67,14 @@ declare namespace CodeceptJS {
67
67
  * ```
68
68
  */
69
69
  output: string;
70
+ /**
71
+ * empty output folder for next run
72
+ *
73
+ * ```js
74
+ * emptyOutputFolder: true
75
+ * ```
76
+ */
77
+ emptyOutputFolder?: boolean;
70
78
  /**
71
79
  * Pattern to filter tests by name.
72
80
  * This option is useful if you plan to use multiple configs for different environments.
@@ -341,6 +349,29 @@ declare namespace CodeceptJS {
341
349
  steps: string | Array<string>
342
350
  };
343
351
 
352
+ /**
353
+ * [AI](https://codecept.io/ai/) features configuration.
354
+ */
355
+ ai?: {
356
+ /** OpenAI model to use */
357
+ model?: string,
358
+ /** temperature, measure of randomness. Lower is better. */
359
+ temperature?: number,
360
+ /** configuration for processing HTML for GPT */
361
+ html?: {
362
+ /** max size of HTML to be sent to OpenAI to avoid token limit */
363
+ maxLength?: number,
364
+ /** should HTML be changed by removing non-interactive elements */
365
+ simplify?: boolean,
366
+ /** should HTML be minified before sending */
367
+ minify?: boolean,
368
+ interactiveElements?: Array<string>,
369
+ textElements?: Array<string>,
370
+ allowedAttrs?: Array<string>,
371
+ allowedRoles?: Array<string>,
372
+ }
373
+ },
374
+
344
375
  /**
345
376
  * Enable full promise-based helper methods for [TypeScript](https://codecept.io/typescript/) project.
346
377
  * If true, all helper methods are typed as asynchronous;
@@ -392,7 +423,7 @@ declare namespace CodeceptJS {
392
423
  | { ios: string }
393
424
  | { android: string; ios: string }
394
425
  | { react: string }
395
- | { shadow: string }
426
+ | { shadow: string[] }
396
427
  | { custom: string };
397
428
 
398
429
  interface CustomLocators {}
@@ -489,6 +520,9 @@ declare const Background: CodeceptJS.IHook;
489
520
  declare const Before: CodeceptJS.IHook;
490
521
  declare const After: CodeceptJS.IHook;
491
522
 
523
+ // Plugins
524
+ declare const __: any
525
+
492
526
  interface Window {
493
527
  codeceptjs: typeof CodeceptJS.browserCodecept;
494
528
  resq: any;