dceky 1.1.12 → 1.2.0
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/README.md +9 -2
- package/lib/start/constants/ALL_E2E_TESTS_LABEL.d.ts +6 -0
- package/lib/start/constants/ALL_E2E_TESTS_LABEL.js +9 -0
- package/lib/start/constants/ALL_E2E_TESTS_LABEL.js.map +1 -0
- package/lib/start/constants/ALL_E2E_TESTS_SPEC_PATTERN.d.ts +6 -0
- package/lib/start/constants/ALL_E2E_TESTS_SPEC_PATTERN.js +9 -0
- package/lib/start/constants/ALL_E2E_TESTS_SPEC_PATTERN.js.map +1 -0
- package/lib/start/helpers/executeAllHeadlessCombinations.d.ts +4 -2
- package/lib/start/helpers/executeAllHeadlessCombinations.js +4 -2
- package/lib/start/helpers/executeAllHeadlessCombinations.js.map +1 -1
- package/lib/start/helpers/executeCypress.d.ts +6 -2
- package/lib/start/helpers/executeCypress.js +7 -5
- package/lib/start/helpers/executeCypress.js.map +1 -1
- package/lib/start/helpers/findE2ETestFolderByName.d.ts +10 -0
- package/lib/start/helpers/findE2ETestFolderByName.js +46 -0
- package/lib/start/helpers/findE2ETestFolderByName.js.map +1 -0
- package/lib/start/helpers/getE2ETestFoldersForChooser.d.ts +8 -0
- package/lib/start/helpers/getE2ETestFoldersForChooser.js +82 -0
- package/lib/start/helpers/getE2ETestFoldersForChooser.js.map +1 -0
- package/lib/start/helpers/runCypressHeadless.d.ts +4 -2
- package/lib/start/helpers/runCypressHeadless.js +4 -5
- package/lib/start/helpers/runCypressHeadless.js.map +1 -1
- package/lib/start/index.js +57 -7
- package/lib/start/index.js.map +1 -1
- package/lib/start/types/E2ETestFolderChoice.d.ts +11 -0
- package/lib/start/types/E2ETestFolderChoice.js +3 -0
- package/lib/start/types/E2ETestFolderChoice.js.map +1 -0
- package/package.json +1 -1
- package/start/constants/ALL_E2E_TESTS_LABEL.ts +7 -0
- package/start/constants/ALL_E2E_TESTS_SPEC_PATTERN.ts +7 -0
- package/start/helpers/executeAllHeadlessCombinations.ts +11 -3
- package/start/helpers/executeCypress.ts +11 -6
- package/start/helpers/findE2ETestFolderByName.ts +55 -0
- package/start/helpers/getE2ETestFoldersForChooser.ts +95 -0
- package/start/helpers/runCypressHeadless.ts +7 -7
- package/start/index.ts +58 -8
- package/start/types/E2ETestFolderChoice.ts +16 -0
package/README.md
CHANGED
|
@@ -38,11 +38,11 @@ You'll have a bunch of changes to commit and push. Do that now.
|
|
|
38
38
|
|
|
39
39
|
To start running ky tests, use `npm run ky:start` and follow instructions.
|
|
40
40
|
|
|
41
|
-
You'll be automatically guided through a launch process where you'll choose whether tests will run visibly or headless, which profile(s) you'll use,
|
|
41
|
+
You'll be automatically guided through a launch process where you'll choose whether tests will run visibly or headless, which profile(s) you'll use, which browser(s) you'll use, and which e2e test folder to run. You can also set these through environment variables or arguments. See the examples below:
|
|
42
42
|
|
|
43
43
|
```ts
|
|
44
44
|
// Arguments:
|
|
45
|
-
npm run ky:start --headless --browser=chrome,webkit --profile=Stage
|
|
45
|
+
npm run ky:start --headless --browser=chrome,webkit --profile=Stage --e2eFolder=Activities
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
```ts
|
|
@@ -50,6 +50,7 @@ npm run ky:start --headless --browser=chrome,webkit --profile=Stage
|
|
|
50
50
|
HEADLESS=true
|
|
51
51
|
BROWSER=chrome,webkit
|
|
52
52
|
PROFILE=Stage
|
|
53
|
+
E2E_TEST_FOLDER=Activities
|
|
53
54
|
```
|
|
54
55
|
|
|
55
56
|
### Setup Ky: `npm run ky:setup`
|
|
@@ -64,6 +65,12 @@ QA people and CI systems should start tests using `npm run ky:start` because tha
|
|
|
64
65
|
|
|
65
66
|
But, developers should run tests using `npm run ky:dev` because each time the tests are run, ky is automatically set up again, ensuring that ky files are up-to-date and running smoothly.
|
|
66
67
|
|
|
68
|
+
## Customizing Ky
|
|
69
|
+
|
|
70
|
+
### Adding globals
|
|
71
|
+
|
|
72
|
+
There are three types of globals: `/cypress/globals/GlobalCredentials` (secure values must go here), `/cypress/globals/GlobalResources` (videos, links, resources), and `/cypress/globals/GlobalValues` (everything else).
|
|
73
|
+
|
|
67
74
|
### Writing Your Own Custom Commands
|
|
68
75
|
|
|
69
76
|
Custom commands are called using Ky (e.g. `ky.myCustomCommand()`), and you define them in the `commands` folder generated when you first setup Ky.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* Display label used when all e2e tests should run
|
|
5
|
+
* @author Yuen Ler Chow
|
|
6
|
+
*/
|
|
7
|
+
const ALL_E2E_TESTS_LABEL = 'All tests';
|
|
8
|
+
exports.default = ALL_E2E_TESTS_LABEL;
|
|
9
|
+
//# sourceMappingURL=ALL_E2E_TESTS_LABEL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ALL_E2E_TESTS_LABEL.js","sourceRoot":"","sources":["../../../start/constants/ALL_E2E_TESTS_LABEL.ts"],"names":[],"mappings":";;AAAA;;;GAGG;AACH,MAAM,mBAAmB,GAAG,WAAW,CAAC;AAExC,kBAAe,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* Spec glob used when all e2e tests should run
|
|
5
|
+
* @author Yuen Ler Chow
|
|
6
|
+
*/
|
|
7
|
+
const ALL_E2E_TESTS_SPEC_PATTERN = 'cypress/e2e/**/*.ky.ts';
|
|
8
|
+
exports.default = ALL_E2E_TESTS_SPEC_PATTERN;
|
|
9
|
+
//# sourceMappingURL=ALL_E2E_TESTS_SPEC_PATTERN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ALL_E2E_TESTS_SPEC_PATTERN.js","sourceRoot":"","sources":["../../../start/constants/ALL_E2E_TESTS_SPEC_PATTERN.ts"],"names":[],"mappings":";;AAAA;;;GAGG;AACH,MAAM,0BAA0B,GAAG,wBAAwB,CAAC;AAE5D,kBAAe,0BAA0B,CAAC"}
|
|
@@ -5,11 +5,13 @@ import Profile from '../types/Profile';
|
|
|
5
5
|
* @param opts - object of arguments
|
|
6
6
|
* @param opts.selectedProfiles - Array of selected profiles
|
|
7
7
|
* @param opts.selectedBrowsers - Array of selected browsers
|
|
8
|
-
* @param
|
|
8
|
+
* @param opts.threadsPerCombo - Number of parallel threads per combo
|
|
9
|
+
* @param opts.e2eSpecPattern - E2E test spec glob
|
|
9
10
|
*/
|
|
10
11
|
declare const executeAllHeadlessCombinations: (opts: {
|
|
11
12
|
selectedProfiles: Profile[];
|
|
12
13
|
selectedBrowsers: string[];
|
|
13
|
-
threadsPerCombo
|
|
14
|
+
threadsPerCombo: number;
|
|
15
|
+
e2eSpecPattern: string;
|
|
14
16
|
}) => Promise<void>;
|
|
15
17
|
export default executeAllHeadlessCombinations;
|
|
@@ -28,10 +28,11 @@ const print_1 = __importDefault(require("./print"));
|
|
|
28
28
|
* @param opts - object of arguments
|
|
29
29
|
* @param opts.selectedProfiles - Array of selected profiles
|
|
30
30
|
* @param opts.selectedBrowsers - Array of selected browsers
|
|
31
|
-
* @param
|
|
31
|
+
* @param opts.threadsPerCombo - Number of parallel threads per combo
|
|
32
|
+
* @param opts.e2eSpecPattern - E2E test spec glob
|
|
32
33
|
*/
|
|
33
34
|
const executeAllHeadlessCombinations = (opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
34
|
-
const { selectedProfiles, selectedBrowsers, threadsPerCombo } = opts;
|
|
35
|
+
const { selectedProfiles, selectedBrowsers, threadsPerCombo, e2eSpecPattern, } = opts;
|
|
35
36
|
// Create date-labeled output directory
|
|
36
37
|
const outputDir = (0, getDateLabeledDir_1.default)();
|
|
37
38
|
if (!fs_1.default.existsSync(outputDir)) {
|
|
@@ -56,6 +57,7 @@ const executeAllHeadlessCombinations = (opts) => __awaiter(void 0, void 0, void
|
|
|
56
57
|
browser: combo.browser,
|
|
57
58
|
outputDir,
|
|
58
59
|
numThreads: threadsPerCombo,
|
|
60
|
+
e2eSpecPattern,
|
|
59
61
|
});
|
|
60
62
|
});
|
|
61
63
|
const results = yield Promise.all(runPromises);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executeAllHeadlessCombinations.js","sourceRoot":"","sources":["../../../start/helpers/executeAllHeadlessCombinations.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,+BAA+B;AAC/B,4CAAoB;AACpB,gDAAwB;AACxB,kDAA0B;AAE1B,iBAAiB;AACjB,8EAAsD;AACtD,4EAAoD;AACpD,sFAA8D;AAC9D,sGAA8E;AAC9E,oDAA4B;AAK5B
|
|
1
|
+
{"version":3,"file":"executeAllHeadlessCombinations.js","sourceRoot":"","sources":["../../../start/helpers/executeAllHeadlessCombinations.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,12 +6,16 @@ import Profile from '../types/Profile';
|
|
|
6
6
|
* @param opts.selectedProfiles - Array of selected profiles
|
|
7
7
|
* @param opts.selectedBrowsers - Array of selected browsers
|
|
8
8
|
* @param opts.isHeadless - Whether to run in headless mode
|
|
9
|
-
* @param
|
|
9
|
+
* @param opts.threadsPerCombo - Number of parallel threads per combo
|
|
10
|
+
* @param opts.e2eTestFolder - E2E test folder label
|
|
11
|
+
* @param opts.e2eSpecPattern - E2E test spec glob
|
|
10
12
|
*/
|
|
11
13
|
declare const executeCypress: (opts: {
|
|
12
14
|
selectedProfiles: Profile[];
|
|
13
15
|
selectedBrowsers: string[];
|
|
14
16
|
isHeadless: boolean;
|
|
15
|
-
threadsPerCombo
|
|
17
|
+
threadsPerCombo: number;
|
|
18
|
+
e2eTestFolder: string;
|
|
19
|
+
e2eSpecPattern: string;
|
|
16
20
|
}) => Promise<void>;
|
|
17
21
|
export default executeCypress;
|
|
@@ -16,8 +16,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
16
16
|
// Import helpers
|
|
17
17
|
const runCypressVisible_1 = __importDefault(require("./runCypressVisible"));
|
|
18
18
|
const executeAllHeadlessCombinations_1 = __importDefault(require("./executeAllHeadlessCombinations"));
|
|
19
|
-
// Import constants
|
|
20
|
-
const DEFAULT_THREADS_PER_COMBO_1 = __importDefault(require("../constants/DEFAULT_THREADS_PER_COMBO"));
|
|
21
19
|
/**
|
|
22
20
|
* Execute Cypress tests in either headless or visible mode
|
|
23
21
|
* @author Yuen Ler Chow
|
|
@@ -25,17 +23,20 @@ const DEFAULT_THREADS_PER_COMBO_1 = __importDefault(require("../constants/DEFAUL
|
|
|
25
23
|
* @param opts.selectedProfiles - Array of selected profiles
|
|
26
24
|
* @param opts.selectedBrowsers - Array of selected browsers
|
|
27
25
|
* @param opts.isHeadless - Whether to run in headless mode
|
|
28
|
-
* @param
|
|
26
|
+
* @param opts.threadsPerCombo - Number of parallel threads per combo
|
|
27
|
+
* @param opts.e2eTestFolder - E2E test folder label
|
|
28
|
+
* @param opts.e2eSpecPattern - E2E test spec glob
|
|
29
29
|
*/
|
|
30
30
|
const executeCypress = (opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
31
|
-
const { selectedProfiles, selectedBrowsers, isHeadless, threadsPerCombo, } = opts;
|
|
31
|
+
const { selectedProfiles, selectedBrowsers, isHeadless, threadsPerCombo, e2eTestFolder, e2eSpecPattern, } = opts;
|
|
32
32
|
console.log('\n═══════════════════════════════════════════════════════════');
|
|
33
33
|
console.log('Starting Cypress with the following configuration:');
|
|
34
34
|
console.log(`Profile(s): ${selectedProfiles.map((p) => { return p.profileName; }).join(', ')}`);
|
|
35
35
|
console.log(`Browser(s): ${selectedBrowsers.join(', ')}`);
|
|
36
36
|
console.log(`Headless: ${isHeadless}`);
|
|
37
37
|
if (isHeadless) {
|
|
38
|
-
console.log(`
|
|
38
|
+
console.log(`E2E test folder: ${e2eTestFolder}`);
|
|
39
|
+
console.log(`Threads per combo: ${threadsPerCombo}`);
|
|
39
40
|
}
|
|
40
41
|
console.log('═══════════════════════════════════════════════════════════\n');
|
|
41
42
|
try {
|
|
@@ -50,6 +51,7 @@ const executeCypress = (opts) => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
50
51
|
selectedProfiles,
|
|
51
52
|
selectedBrowsers,
|
|
52
53
|
threadsPerCombo,
|
|
54
|
+
e2eSpecPattern,
|
|
53
55
|
});
|
|
54
56
|
}
|
|
55
57
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executeCypress.js","sourceRoot":"","sources":["../../../start/helpers/executeCypress.ts"],"names":[],"mappings":";AAAA,+BAA+B;;;;;;;;;;;;;;AAK/B,iBAAiB;AACjB,4EAAoD;AACpD,sGAA8E;AAE9E
|
|
1
|
+
{"version":3,"file":"executeCypress.js","sourceRoot":"","sources":["../../../start/helpers/executeCypress.ts"],"names":[],"mappings":";AAAA,+BAA+B;;;;;;;;;;;;;;AAK/B,iBAAiB;AACjB,4EAAoD;AACpD,sGAA8E;AAE9E;;;;;;;;;;GAUG;AACH,MAAM,cAAc,GAAG,CACrB,IAOC,EACc,EAAE;IACjB,MAAM,EACJ,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,aAAa,EACb,cAAc,GACf,GAAG,IAAI,CAAC;IAET,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,eAAe,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChG,OAAO,CAAC,GAAG,CAAC,eAAe,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,aAAa,UAAU,EAAE,CAAC,CAAC;IACvC,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,oBAAoB,aAAa,EAAE,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,sBAAsB,eAAe,EAAE,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;IAE7E,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,wCAAwC;YACxC,MAAM,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM,IAAA,2BAAiB,EAAC,WAAW,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,6EAA6E;YAC7E,MAAM,IAAA,wCAA8B,EAAC;gBACnC,gBAAgB;gBAChB,gBAAgB;gBAChB,eAAe;gBACf,cAAc;aACf,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAA,CAAC;AAEF,kBAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import E2ETestFolderChoice from '../types/E2ETestFolderChoice';
|
|
2
|
+
/**
|
|
3
|
+
* Find an e2e test folder by name
|
|
4
|
+
* @author Yuen Ler Chow
|
|
5
|
+
* @param name e2e test folder name to find
|
|
6
|
+
* @param folders array of available e2e test folders
|
|
7
|
+
* @returns selected e2e test folder choice
|
|
8
|
+
*/
|
|
9
|
+
declare const findE2ETestFolderByName: (name: string, folders: E2ETestFolderChoice[]) => E2ETestFolderChoice;
|
|
10
|
+
export default findE2ETestFolderByName;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable no-console */
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
// Import constants
|
|
8
|
+
const ALL_E2E_TESTS_LABEL_1 = __importDefault(require("../constants/ALL_E2E_TESTS_LABEL"));
|
|
9
|
+
const ALL_E2E_TESTS_SPEC_PATTERN_1 = __importDefault(require("../constants/ALL_E2E_TESTS_SPEC_PATTERN"));
|
|
10
|
+
/**
|
|
11
|
+
* Find an e2e test folder by name
|
|
12
|
+
* @author Yuen Ler Chow
|
|
13
|
+
* @param name e2e test folder name to find
|
|
14
|
+
* @param folders array of available e2e test folders
|
|
15
|
+
* @returns selected e2e test folder choice
|
|
16
|
+
*/
|
|
17
|
+
const findE2ETestFolderByName = (name, folders) => {
|
|
18
|
+
// Convert inputs like "cypress/e2e/login/" to "login" before matching folder names
|
|
19
|
+
const normalizedName = (name
|
|
20
|
+
.trim()
|
|
21
|
+
.replace(/\\/g, '/')
|
|
22
|
+
.replace(/^cypress\/e2e\/?/i, '')
|
|
23
|
+
.replace(/^\/+/, '')
|
|
24
|
+
.replace(/\/+$/, ''));
|
|
25
|
+
if (['all', '*', '.'].includes(normalizedName.toLowerCase())) {
|
|
26
|
+
return {
|
|
27
|
+
tag: 'A',
|
|
28
|
+
description: ALL_E2E_TESTS_LABEL_1.default,
|
|
29
|
+
relativePath: '',
|
|
30
|
+
specPattern: ALL_E2E_TESTS_SPEC_PATTERN_1.default,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const selectedFolder = folders.find((folder) => {
|
|
34
|
+
return folder.relativePath.toLowerCase() === normalizedName.toLowerCase();
|
|
35
|
+
});
|
|
36
|
+
if (!selectedFolder) {
|
|
37
|
+
const validFolders = folders.map((folder) => {
|
|
38
|
+
return folder.relativePath;
|
|
39
|
+
});
|
|
40
|
+
console.error(`E2E test folder invalid: ${name}. Available folders: all, ${validFolders.join(', ')}`);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
return selectedFolder;
|
|
44
|
+
};
|
|
45
|
+
exports.default = findE2ETestFolderByName;
|
|
46
|
+
//# sourceMappingURL=findE2ETestFolderByName.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findE2ETestFolderByName.js","sourceRoot":"","sources":["../../../start/helpers/findE2ETestFolderByName.ts"],"names":[],"mappings":";AAAA,+BAA+B;;;;;AAE/B,mBAAmB;AACnB,2FAAmE;AACnE,yGAAiF;AAKjF;;;;;;GAMG;AACH,MAAM,uBAAuB,GAAG,CAC9B,IAAY,EACZ,OAA8B,EACT,EAAE;IACvB,mFAAmF;IACnF,MAAM,cAAc,GAAG,CACrB,IAAI;SACD,IAAI,EAAE;SACN,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC;SAChC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;SACnB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CACvB,CAAC;IAEF,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;QAC7D,OAAO;YACL,GAAG,EAAE,GAAG;YACR,WAAW,EAAE,6BAAmB;YAChC,YAAY,EAAE,EAAE;YAChB,WAAW,EAAE,oCAA0B;SACxC,CAAC;IACJ,CAAC;IAED,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QAC7C,OAAO,MAAM,CAAC,YAAY,CAAC,WAAW,EAAE,KAAK,cAAc,CAAC,WAAW,EAAE,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YAC1C,OAAO,MAAM,CAAC,YAAY,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,KAAK,CAAC,4BAA4B,IAAI,6BAA6B,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,cAAc,CAAC;AACxB,CAAC,CAAC;AAEF,kBAAe,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import E2ETestFolderChoice from '../types/E2ETestFolderChoice';
|
|
2
|
+
/**
|
|
3
|
+
* Get e2e test folders that contain .ky.ts tests.
|
|
4
|
+
* @author Yuen Ler Chow
|
|
5
|
+
* @returns e2e test folder options for the chooser
|
|
6
|
+
*/
|
|
7
|
+
declare const getE2ETestFoldersForChooser: () => E2ETestFolderChoice[];
|
|
8
|
+
export default getE2ETestFoldersForChooser;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const fs_1 = __importDefault(require("fs"));
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
// Import helpers
|
|
9
|
+
const getRootPath_1 = __importDefault(require("./getRootPath"));
|
|
10
|
+
/**
|
|
11
|
+
* Check whether a directory contains any .ky.ts tests, including nested folders.
|
|
12
|
+
* @author Yuen Ler Chow
|
|
13
|
+
* @param dir directory to search
|
|
14
|
+
* @returns true if the directory contains at least one .ky.ts test
|
|
15
|
+
*/
|
|
16
|
+
const hasKyTests = (dir) => {
|
|
17
|
+
const entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
|
|
18
|
+
return entries.some((entry) => {
|
|
19
|
+
const entryPath = path_1.default.join(dir, entry.name);
|
|
20
|
+
if (entry.isDirectory()) {
|
|
21
|
+
return hasKyTests(entryPath);
|
|
22
|
+
}
|
|
23
|
+
return entry.isFile() && entry.name.endsWith('.ky.ts');
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Collect e2e folders that contain .ky.ts tests.
|
|
28
|
+
* @author Yuen Ler Chow
|
|
29
|
+
* @param opts object of arguments
|
|
30
|
+
* @param opts.dir directory to search
|
|
31
|
+
* @param opts.e2eDir root e2e directory used for relative paths
|
|
32
|
+
* @param opts.folders mutable list of relative folder paths
|
|
33
|
+
*/
|
|
34
|
+
const collectTestFolders = (opts) => {
|
|
35
|
+
const { dir, e2eDir, folders } = opts;
|
|
36
|
+
const entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
|
|
37
|
+
entries.forEach((entry) => {
|
|
38
|
+
if (!entry.isDirectory()) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const entryPath = path_1.default.join(dir, entry.name);
|
|
42
|
+
if (hasKyTests(entryPath)) {
|
|
43
|
+
folders.push(path_1.default
|
|
44
|
+
.relative(e2eDir, entryPath)
|
|
45
|
+
.split(path_1.default.sep)
|
|
46
|
+
.join('/'));
|
|
47
|
+
}
|
|
48
|
+
collectTestFolders({
|
|
49
|
+
dir: entryPath,
|
|
50
|
+
e2eDir,
|
|
51
|
+
folders,
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Get e2e test folders that contain .ky.ts tests.
|
|
57
|
+
* @author Yuen Ler Chow
|
|
58
|
+
* @returns e2e test folder options for the chooser
|
|
59
|
+
*/
|
|
60
|
+
const getE2ETestFoldersForChooser = () => {
|
|
61
|
+
const root = (0, getRootPath_1.default)();
|
|
62
|
+
const e2eDir = path_1.default.join(root, 'cypress/e2e');
|
|
63
|
+
if (!fs_1.default.existsSync(e2eDir)) {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
const folders = [];
|
|
67
|
+
collectTestFolders({
|
|
68
|
+
dir: e2eDir,
|
|
69
|
+
e2eDir,
|
|
70
|
+
folders,
|
|
71
|
+
});
|
|
72
|
+
return folders.sort().map((relativePath, index) => {
|
|
73
|
+
return {
|
|
74
|
+
tag: String(index + 1),
|
|
75
|
+
description: relativePath,
|
|
76
|
+
relativePath,
|
|
77
|
+
specPattern: `cypress/e2e/${relativePath}/**/*.ky.ts`,
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
exports.default = getE2ETestFoldersForChooser;
|
|
82
|
+
//# sourceMappingURL=getE2ETestFoldersForChooser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getE2ETestFoldersForChooser.js","sourceRoot":"","sources":["../../../start/helpers/getE2ETestFoldersForChooser.ts"],"names":[],"mappings":";;;;;AAAA,4CAAoB;AACpB,gDAAwB;AAExB,iBAAiB;AACjB,gEAAwC;AAKxC;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,GAAW,EAAW,EAAE;IAC1C,MAAM,OAAO,GAAG,YAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QAC5B,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,OAAO,UAAU,CAAC,SAAS,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,kBAAkB,GAAG,CAAC,IAI3B,EAAQ,EAAE;IACT,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACtC,MAAM,OAAO,GAAG,YAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7D,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QACxB,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACzB,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CACV,cAAI;iBACD,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;iBAC3B,KAAK,CAAC,cAAI,CAAC,GAAG,CAAC;iBACf,IAAI,CAAC,GAAG,CAAC,CACb,CAAC;QACJ,CAAC;QAED,kBAAkB,CAAC;YACjB,GAAG,EAAE,SAAS;YACd,MAAM;YACN,OAAO;SACR,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,2BAA2B,GAAG,GAA0B,EAAE;IAC9D,MAAM,IAAI,GAAG,IAAA,qBAAW,GAAE,CAAC;IAC3B,MAAM,MAAM,GAAG,cAAI,CAAC,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IAE9C,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,kBAAkB,CAAC;QACjB,GAAG,EAAE,MAAM;QACX,MAAM;QACN,OAAO;KACR,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,KAAK,EAAE,EAAE;QAChD,OAAO;YACL,GAAG,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;YACtB,WAAW,EAAE,YAAY;YACzB,YAAY;YACZ,WAAW,EAAE,eAAe,YAAY,aAAa;SACtD,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AACF,kBAAe,2BAA2B,CAAC"}
|
|
@@ -6,13 +6,15 @@ import RunResult from '../types/RunResult';
|
|
|
6
6
|
* @param opts.profileName - The profile name to use
|
|
7
7
|
* @param opts.browser - The browser to use
|
|
8
8
|
* @param opts.outputDir - The output directory for results
|
|
9
|
-
* @param
|
|
9
|
+
* @param opts.numThreads - The number of parallel threads to use
|
|
10
|
+
* @param opts.e2eSpecPattern - The spec glob to run
|
|
10
11
|
* @returns Promise that resolves with run result
|
|
11
12
|
*/
|
|
12
13
|
declare const runCypressHeadless: (opts: {
|
|
13
14
|
profileName: string;
|
|
14
15
|
browser: string;
|
|
15
16
|
outputDir: string;
|
|
16
|
-
numThreads
|
|
17
|
+
numThreads: number;
|
|
18
|
+
e2eSpecPattern: string;
|
|
17
19
|
}) => Promise<RunResult>;
|
|
18
20
|
export default runCypressHeadless;
|
|
@@ -13,8 +13,6 @@ const getRootPath_1 = __importDefault(require("./getRootPath"));
|
|
|
13
13
|
const generateReporterConfig_1 = __importDefault(require("./generateReporterConfig"));
|
|
14
14
|
const mergeReports_1 = __importDefault(require("./mergeReports"));
|
|
15
15
|
const generateHtmlReport_1 = __importDefault(require("./generateHtmlReport"));
|
|
16
|
-
// Import constants
|
|
17
|
-
const DEFAULT_THREADS_PER_COMBO_1 = __importDefault(require("../constants/DEFAULT_THREADS_PER_COMBO"));
|
|
18
16
|
/**
|
|
19
17
|
* Run Cypress in headless mode for a single profile and browser using cypress-parallel
|
|
20
18
|
* @author Yuen Ler Chow
|
|
@@ -22,11 +20,12 @@ const DEFAULT_THREADS_PER_COMBO_1 = __importDefault(require("../constants/DEFAUL
|
|
|
22
20
|
* @param opts.profileName - The profile name to use
|
|
23
21
|
* @param opts.browser - The browser to use
|
|
24
22
|
* @param opts.outputDir - The output directory for results
|
|
25
|
-
* @param
|
|
23
|
+
* @param opts.numThreads - The number of parallel threads to use
|
|
24
|
+
* @param opts.e2eSpecPattern - The spec glob to run
|
|
26
25
|
* @returns Promise that resolves with run result
|
|
27
26
|
*/
|
|
28
27
|
const runCypressHeadless = (opts) => {
|
|
29
|
-
const { profileName, browser, outputDir, numThreads
|
|
28
|
+
const { profileName, browser, outputDir, numThreads, e2eSpecPattern, } = opts;
|
|
30
29
|
return new Promise((resolve, reject) => {
|
|
31
30
|
const root = (0, getRootPath_1.default)();
|
|
32
31
|
// Ensure output directory exists
|
|
@@ -65,7 +64,7 @@ const runCypressHeadless = (opts) => {
|
|
|
65
64
|
'--threads',
|
|
66
65
|
numThreads.toString(),
|
|
67
66
|
'-d',
|
|
68
|
-
|
|
67
|
+
`'${e2eSpecPattern}'`,
|
|
69
68
|
'-m',
|
|
70
69
|
'false',
|
|
71
70
|
'-a',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runCypressHeadless.js","sourceRoot":"","sources":["../../../start/helpers/runCypressHeadless.ts"],"names":[],"mappings":";AAAA,+BAA+B;;;;;AAE/B,cAAc;AACd,iDAAsC;AACtC,gDAAwB;AACxB,4CAAoB;AAEpB,iBAAiB;AACjB,gEAAwC;AACxC,sFAA8D;AAC9D,kEAA0C;AAC1C,8EAAsD;AAKtD
|
|
1
|
+
{"version":3,"file":"runCypressHeadless.js","sourceRoot":"","sources":["../../../start/helpers/runCypressHeadless.ts"],"names":[],"mappings":"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"}
|
package/lib/start/index.js
CHANGED
|
@@ -22,8 +22,12 @@ const extractArgValue_1 = __importDefault(require("./helpers/extractArgValue"));
|
|
|
22
22
|
const getRootPath_1 = __importDefault(require("./helpers/getRootPath"));
|
|
23
23
|
const executeCypress_1 = __importDefault(require("./helpers/executeCypress"));
|
|
24
24
|
const getCypressDetectedBrowsersForChooser_1 = __importDefault(require("./helpers/getCypressDetectedBrowsersForChooser"));
|
|
25
|
+
const getE2ETestFoldersForChooser_1 = __importDefault(require("./helpers/getE2ETestFoldersForChooser"));
|
|
26
|
+
const findE2ETestFolderByName_1 = __importDefault(require("./helpers/findE2ETestFolderByName"));
|
|
25
27
|
// Import constants
|
|
26
28
|
const DEFAULT_THREADS_PER_COMBO_1 = __importDefault(require("./constants/DEFAULT_THREADS_PER_COMBO"));
|
|
29
|
+
const ALL_E2E_TESTS_LABEL_1 = __importDefault(require("./constants/ALL_E2E_TESTS_LABEL"));
|
|
30
|
+
const ALL_E2E_TESTS_SPEC_PATTERN_1 = __importDefault(require("./constants/ALL_E2E_TESTS_SPEC_PATTERN"));
|
|
27
31
|
// Get the project directory
|
|
28
32
|
const pwd = (0, getRootPath_1.default)();
|
|
29
33
|
// Find available profiles under /cypress/profiles
|
|
@@ -54,6 +58,8 @@ const args = process.argv.slice(2);
|
|
|
54
58
|
let selectedProfiles = [];
|
|
55
59
|
let selectedBrowsers = [];
|
|
56
60
|
let isHeadless = false;
|
|
61
|
+
let selectedE2ETestFolder = ALL_E2E_TESTS_LABEL_1.default;
|
|
62
|
+
let selectedE2ESpecPattern = ALL_E2E_TESTS_SPEC_PATTERN_1.default;
|
|
57
63
|
// Check for PROFILE (env var or CLI arg)
|
|
58
64
|
const envProfileRaw = process.env.PROFILE;
|
|
59
65
|
const argProfileRaw = (0, extractArgValue_1.default)(args, '--profile');
|
|
@@ -70,6 +76,10 @@ if (browserRaw) {
|
|
|
70
76
|
const browserNames = (0, parseCommaSeparated_1.default)(browserRaw);
|
|
71
77
|
selectedBrowsers = (0, validateBrowsers_1.default)(browserNames);
|
|
72
78
|
}
|
|
79
|
+
// Check for E2E_TEST_FOLDER (env var or CLI arg)
|
|
80
|
+
const envE2ETestFolderRaw = process.env.E2E_TEST_FOLDER;
|
|
81
|
+
const argE2ETestFolderRaw = (0, extractArgValue_1.default)(args, '--e2eFolder');
|
|
82
|
+
const e2eTestFolderRaw = envE2ETestFolderRaw || argE2ETestFolderRaw;
|
|
73
83
|
// Check for HEADLESS (env var or CLI flag)
|
|
74
84
|
const envHeadlessRaw = process.env.HEADLESS;
|
|
75
85
|
const headlessFlagValue = (0, extractArgValue_1.default)(args, '--headless');
|
|
@@ -79,7 +89,7 @@ isHeadless = !!(envHeadlessRaw && envHeadlessRaw.toLowerCase() !== 'false') || h
|
|
|
79
89
|
const envThreadsRaw = process.env.THREADS_PER_COMBO;
|
|
80
90
|
const argThreadsRaw = (0, extractArgValue_1.default)(args, '--threadsPerCombo');
|
|
81
91
|
const threadsRaw = envThreadsRaw || argThreadsRaw;
|
|
82
|
-
let threadsPerCombo;
|
|
92
|
+
let threadsPerCombo = DEFAULT_THREADS_PER_COMBO_1.default;
|
|
83
93
|
if (threadsRaw) {
|
|
84
94
|
const parsed = Number.parseInt(threadsRaw, 10);
|
|
85
95
|
if (!Number.isNaN(parsed) && parsed > 0) {
|
|
@@ -102,6 +112,41 @@ if (!envHeadlessRaw && !hasHeadlessFlag) {
|
|
|
102
112
|
});
|
|
103
113
|
isHeadless = choices[0].tag === 'Y';
|
|
104
114
|
}
|
|
115
|
+
// If running headless, optionally narrow tests to one e2e folder
|
|
116
|
+
if (isHeadless) {
|
|
117
|
+
const choosableE2ETestFolders = (0, getE2ETestFoldersForChooser_1.default)();
|
|
118
|
+
if (e2eTestFolderRaw) {
|
|
119
|
+
const e2eSelection = (0, findE2ETestFolderByName_1.default)(e2eTestFolderRaw, choosableE2ETestFolders);
|
|
120
|
+
selectedE2ETestFolder = e2eSelection.description;
|
|
121
|
+
selectedE2ESpecPattern = e2eSelection.specPattern;
|
|
122
|
+
}
|
|
123
|
+
else if (choosableE2ETestFolders.length > 0) {
|
|
124
|
+
const choices = (0, showChooser_1.default)({
|
|
125
|
+
question: 'Choose e2e test folder:',
|
|
126
|
+
options: [
|
|
127
|
+
{
|
|
128
|
+
tag: 'A',
|
|
129
|
+
description: ALL_E2E_TESTS_LABEL_1.default,
|
|
130
|
+
},
|
|
131
|
+
...choosableE2ETestFolders,
|
|
132
|
+
],
|
|
133
|
+
title: 'Select E2E Tests',
|
|
134
|
+
allowMulti: false,
|
|
135
|
+
});
|
|
136
|
+
const allTestsChosen = choices.some((choice) => {
|
|
137
|
+
return choice.tag === 'A';
|
|
138
|
+
});
|
|
139
|
+
if (!allTestsChosen) {
|
|
140
|
+
const selectedFolder = choosableE2ETestFolders.find((folder) => {
|
|
141
|
+
return folder.tag === choices[0].tag;
|
|
142
|
+
});
|
|
143
|
+
if (selectedFolder) {
|
|
144
|
+
selectedE2ETestFolder = selectedFolder.relativePath;
|
|
145
|
+
selectedE2ESpecPattern = selectedFolder.specPattern;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
105
150
|
// If running headless and no browsers were selected, ask the user to choose
|
|
106
151
|
if (isHeadless && selectedBrowsers.length === 0) {
|
|
107
152
|
const choosableBrowsers = (0, getCypressDetectedBrowsersForChooser_1.default)();
|
|
@@ -139,10 +184,11 @@ if (isHeadless && selectedBrowsers.length === 0) {
|
|
|
139
184
|
else {
|
|
140
185
|
selectedBrowsers = (choices
|
|
141
186
|
.map((choice) => {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
187
|
+
var _a;
|
|
188
|
+
const selectedBrowser = choosableBrowsers.find((browser) => {
|
|
189
|
+
return browser.tag.toLowerCase() === choice.tag.toLowerCase();
|
|
190
|
+
});
|
|
191
|
+
return (_a = selectedBrowser === null || selectedBrowser === void 0 ? void 0 : selectedBrowser.name) !== null && _a !== void 0 ? _a : null;
|
|
146
192
|
})
|
|
147
193
|
.filter((name) => {
|
|
148
194
|
return name !== null;
|
|
@@ -189,10 +235,12 @@ if (selectedProfiles.length === 0
|
|
|
189
235
|
else {
|
|
190
236
|
selectedProfiles = (choices
|
|
191
237
|
.map((choice) => {
|
|
192
|
-
|
|
238
|
+
var _a;
|
|
239
|
+
const profileIndex = Number.parseInt(choice.tag, 10) - 1;
|
|
240
|
+
if (Number.isNaN(profileIndex)) {
|
|
193
241
|
return null;
|
|
194
242
|
}
|
|
195
|
-
return choosableProfiles[
|
|
243
|
+
return (_a = choosableProfiles[profileIndex]) !== null && _a !== void 0 ? _a : null;
|
|
196
244
|
})
|
|
197
245
|
.filter((profile) => {
|
|
198
246
|
return profile !== null;
|
|
@@ -205,5 +253,7 @@ if (selectedProfiles.length === 0
|
|
|
205
253
|
selectedBrowsers,
|
|
206
254
|
isHeadless,
|
|
207
255
|
threadsPerCombo,
|
|
256
|
+
e2eTestFolder: selectedE2ETestFolder,
|
|
257
|
+
e2eSpecPattern: selectedE2ESpecPattern,
|
|
208
258
|
});
|
|
209
259
|
//# sourceMappingURL=index.js.map
|
package/lib/start/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../start/index.ts"],"names":[],"mappings":";AAAA,+BAA+B;AAC/B;;;;;GAKG;;;;;AAEH,cAAc;AACd,4CAAoB;AACpB,gDAAwB;AAExB,iBAAiB;AACjB,wEAAgD;AAChD,wFAAgE;AAChE,wFAAgE;AAChE,kFAA0D;AAC1D,gFAAwD;AACxD,wEAAgD;AAChD,8EAAsD;AACtD,0HAAkG;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../start/index.ts"],"names":[],"mappings":";AAAA,+BAA+B;AAC/B;;;;;GAKG;;;;;AAEH,cAAc;AACd,4CAAoB;AACpB,gDAAwB;AAExB,iBAAiB;AACjB,wEAAgD;AAChD,wFAAgE;AAChE,wFAAgE;AAChE,kFAA0D;AAC1D,gFAAwD;AACxD,wEAAgD;AAChD,8EAAsD;AACtD,0HAAkG;AAClG,wGAAgF;AAChF,gGAAwE;AAExE,mBAAmB;AACnB,sGAA8E;AAC9E,0FAAkE;AAClE,wGAAgF;AAEhF,4BAA4B;AAC5B,MAAM,GAAG,GAAG,IAAA,qBAAW,GAAE,CAAC;AAE1B,kDAAkD;AAClD,MAAM,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;AACvD,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;IAChC,OAAO,CAAC,IAAI,CAAC,4CAA4C,WAAW,GAAG,CAAC,CAAC;IACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,gEAAgE;AAChE,MAAM,YAAY,GAAG,CACnB,YAAE;KACC,WAAW,CAAC,WAAW,CAAC;KACxB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;IACZ,OAAO,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;AACnC,CAAC,CAAC,CACL,CAAC;AAEF,8CAA8C;AAC9C,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;IACzC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IACpD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;AAC/B,CAAC,CAAC,CAAC;AAEH,4BAA4B;AAC5B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IAC1B,OAAO,CAAC,KAAK,CAAC,yBAAyB,WAAW,GAAG,CAAC,CAAC;IACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,sBAAsB;AACtB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,6DAA6D;AAC7D,IAAI,gBAAgB,GAA4C,EAAE,CAAC;AACnE,IAAI,gBAAgB,GAAa,EAAE,CAAC;AACpC,IAAI,UAAU,GAAG,KAAK,CAAC;AACvB,IAAI,qBAAqB,GAAG,6BAAmB,CAAC;AAChD,IAAI,sBAAsB,GAAG,oCAA0B,CAAC;AAExD,yCAAyC;AACzC,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;AAC1C,MAAM,aAAa,GAAG,IAAA,yBAAe,EAAC,IAAI,EAAE,WAAW,CAAC,CAAC;AACzD,MAAM,UAAU,GAAG,aAAa,IAAI,aAAa,CAAC;AAElD,IAAI,UAAU,EAAE,CAAC;IACf,MAAM,YAAY,GAAG,IAAA,6BAAmB,EAAC,UAAU,CAAC,CAAC;IACrD,gBAAgB,GAAG,IAAA,6BAAmB,EAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;AACjE,CAAC;AAED,yCAAyC;AACzC,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;AAC1C,MAAM,aAAa,GAAG,IAAA,yBAAe,EAAC,IAAI,EAAE,WAAW,CAAC,CAAC;AACzD,MAAM,UAAU,GAAG,aAAa,IAAI,aAAa,CAAC;AAElD,IAAI,UAAU,EAAE,CAAC;IACf,MAAM,YAAY,GAAG,IAAA,6BAAmB,EAAC,UAAU,CAAC,CAAC;IACrD,gBAAgB,GAAG,IAAA,0BAAgB,EAAC,YAAY,CAAC,CAAC;AACpD,CAAC;AAED,iDAAiD;AACjD,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;AACxD,MAAM,mBAAmB,GAAG,IAAA,yBAAe,EAAC,IAAI,EAAE,aAAa,CAAC,CAAC;AACjE,MAAM,gBAAgB,GAAG,mBAAmB,IAAI,mBAAmB,CAAC;AAEpE,2CAA2C;AAC3C,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC5C,MAAM,iBAAiB,GAAG,IAAA,yBAAe,EAAC,IAAI,EAAE,YAAY,CAAC,CAAC;AAC9D,MAAM,eAAe,GAAG,iBAAiB,KAAK,SAAS,CAAC;AACxD,UAAU,GAAG,CAAC,CAAC,CAAC,cAAc,IAAI,cAAc,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,IAAI,eAAe,CAAC;AAE/F,mDAAmD;AACnD,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;AACpD,MAAM,aAAa,GAAG,IAAA,yBAAe,EAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;AACjE,MAAM,UAAU,GAAG,aAAa,IAAI,aAAa,CAAC;AAClD,IAAI,eAAe,GAAG,mCAAyB,CAAC;AAChD,IAAI,UAAU,EAAE,CAAC;IACf,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC/C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACxC,eAAe,GAAG,MAAM,CAAC;IAC3B,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CAAC,wCAAwC,UAAU,qBAAqB,mCAAyB,IAAI,CAAC,CAAC;IACrH,CAAC;AACH,CAAC;AAED,uDAAuD;AACvD,IAAI,CAAC,cAAc,IAAI,CAAC,eAAe,EAAE,CAAC;IACxC,MAAM,OAAO,GAAG,IAAA,qBAAW,EAAC;QAC1B,QAAQ,EAAE,uBAAuB;QACjC,OAAO,EAAE;YACP,EAAE,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,gBAAgB,EAAE;YAC3C,EAAE,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,kBAAkB,EAAE;SAC9C;QACD,KAAK,EAAE,aAAa;QACpB,UAAU,EAAE,KAAK;KAClB,CAAC,CAAC;IAEH,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC;AACtC,CAAC;AAED,iEAAiE;AACjE,IAAI,UAAU,EAAE,CAAC;IACf,MAAM,uBAAuB,GAAG,IAAA,qCAA2B,GAAE,CAAC;IAE9D,IAAI,gBAAgB,EAAE,CAAC;QACrB,MAAM,YAAY,GAAG,IAAA,iCAAuB,EAAC,gBAAgB,EAAE,uBAAuB,CAAC,CAAC;QACxF,qBAAqB,GAAG,YAAY,CAAC,WAAW,CAAC;QACjD,sBAAsB,GAAG,YAAY,CAAC,WAAW,CAAC;IACpD,CAAC;SAAM,IAAI,uBAAuB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,IAAA,qBAAW,EAAC;YAC1B,QAAQ,EAAE,yBAAyB;YACnC,OAAO,EAAE;gBACP;oBACE,GAAG,EAAE,GAAG;oBACR,WAAW,EAAE,6BAAmB;iBACjC;gBACD,GAAG,uBAAuB;aAC3B;YACD,KAAK,EAAE,kBAAkB;YACzB,UAAU,EAAE,KAAK;SAClB,CAAC,CAAC;QAEH,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;YAC7C,OAAO,MAAM,CAAC,GAAG,KAAK,GAAG,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,cAAc,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;gBAC7D,OAAO,MAAM,CAAC,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YACvC,CAAC,CAAC,CAAC;YACH,IAAI,cAAc,EAAE,CAAC;gBACnB,qBAAqB,GAAG,cAAc,CAAC,YAAY,CAAC;gBACpD,sBAAsB,GAAG,cAAc,CAAC,WAAW,CAAC;YACtD,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,IAAI,UAAU,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IAChD,MAAM,iBAAiB,GAAG,IAAA,8CAAoC,GAAE,CAAC;IACjE,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO,CAAC,KAAK,CAAC,2FAA2F,CAAC,CAAC;QAC3G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE;QACtD,OAAO;YACL,GAAG;YACH,WAAW,EAAE,IAAI;SAClB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,kDAAkD;IAClD,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,OAAO,CAAC;YACd,GAAG,EAAE,GAAG;YACR,WAAW,EAAE,cAAc;SAC5B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,IAAA,qBAAW,EAAC;QAC1B,QAAQ,EAAE,8CAA8C;QACxD,OAAO;QACP,KAAK,EAAE,mBAAmB;QAC1B,UAAU,EAAE,IAAI;KACjB,CAAC,CAAC;IAEH,MAAM,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QAChD,OAAO,MAAM,CAAC,GAAG,KAAK,GAAG,CAAC;IAC5B,CAAC,CAAC,CAAC;IACH,IAAI,iBAAiB,EAAE,CAAC;QACtB,gBAAgB,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAC7C,OAAO,CAAC,CAAC,IAAI,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,gBAAgB,GAAG,CACjB,OAAO;aACJ,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;;YACd,MAAM,eAAe,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;gBACzD,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;YAChE,CAAC,CAAC,CAAC;YACH,OAAO,MAAA,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,IAAI,mCAAI,IAAI,CAAC;QACvC,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;YACf,OAAO,IAAI,KAAK,IAAI,CAAC;QACvB,CAAC,CAAC,CACL,CAAC;IACJ,CAAC;AACH,CAAC;AAED,uDAAuD;AACvD,wDAAwD;AACxD,2DAA2D;AAC3D,qHAAqH;AACrH,IACE,gBAAgB,CAAC,MAAM,KAAK,CAAC;OAC1B,CAAC,CAAC,UAAU,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,EAC/C,CAAC;IACD,wDAAwD;IACxD,MAAM,iBAAiB,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC9C,OAAO,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,KAAK,SAAS,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;QAC/C,OAAO;YACL,GAAG,EAAE,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;YACpB,WAAW,EAAE,CAAC,CAAC,WAAW;SAC3B,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,wEAAwE;IACxE,IAAI,UAAU,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/C,OAAO,CAAC,OAAO,CAAC;YACd,GAAG,EAAE,GAAG;YACR,WAAW,EAAE,cAAc;SAC5B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,IAAA,qBAAW,EAAC;QAC1B,QAAQ,EAAE,CACR,UAAU;YACR,CAAC,CAAC,+CAA+C;YACjD,CAAC,CAAC,iBAAiB,CACtB;QACD,OAAO;QACP,KAAK,EAAE,iBAAiB,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC/C,UAAU,EAAE,UAAU;KACvB,CAAC,CAAC;IAEH,MAAM,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QAChD,OAAO,MAAM,CAAC,GAAG,KAAK,GAAG,CAAC;IAC5B,CAAC,CAAC,CAAC;IACH,IAAI,iBAAiB,EAAE,CAAC;QACtB,gBAAgB,GAAG,iBAAiB,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,gBAAgB,GAAG,CACjB,OAAO;aACJ,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;;YACd,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;YACzD,IAAI,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC/B,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,MAAA,iBAAiB,CAAC,YAAY,CAAC,mCAAI,IAAI,CAAC;QACjD,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;YAClB,OAAO,OAAO,KAAK,IAAI,CAAC;QAC1B,CAAC,CAAC,CACL,CAAC;IACJ,CAAC;AACH,CAAC;AAED,8CAA8C;AAC9C,IAAA,wBAAc,EAAC;IACb,gBAAgB;IAChB,gBAAgB;IAChB,UAAU;IACV,eAAe;IACf,aAAa,EAAE,qBAAqB;IACpC,cAAc,EAAE,sBAAsB;CACvC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"E2ETestFolderChoice.js","sourceRoot":"","sources":["../../../start/types/E2ETestFolderChoice.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -19,16 +19,23 @@ import Profile from '../types/Profile';
|
|
|
19
19
|
* @param opts - object of arguments
|
|
20
20
|
* @param opts.selectedProfiles - Array of selected profiles
|
|
21
21
|
* @param opts.selectedBrowsers - Array of selected browsers
|
|
22
|
-
* @param
|
|
22
|
+
* @param opts.threadsPerCombo - Number of parallel threads per combo
|
|
23
|
+
* @param opts.e2eSpecPattern - E2E test spec glob
|
|
23
24
|
*/
|
|
24
25
|
const executeAllHeadlessCombinations = async (
|
|
25
26
|
opts: {
|
|
26
27
|
selectedProfiles: Profile[],
|
|
27
28
|
selectedBrowsers: string[],
|
|
28
|
-
threadsPerCombo
|
|
29
|
+
threadsPerCombo: number,
|
|
30
|
+
e2eSpecPattern: string,
|
|
29
31
|
},
|
|
30
32
|
): Promise<void> => {
|
|
31
|
-
const {
|
|
33
|
+
const {
|
|
34
|
+
selectedProfiles,
|
|
35
|
+
selectedBrowsers,
|
|
36
|
+
threadsPerCombo,
|
|
37
|
+
e2eSpecPattern,
|
|
38
|
+
} = opts;
|
|
32
39
|
|
|
33
40
|
// Create date-labeled output directory
|
|
34
41
|
const outputDir = getDateLabeledDir();
|
|
@@ -58,6 +65,7 @@ const executeAllHeadlessCombinations = async (
|
|
|
58
65
|
browser: combo.browser,
|
|
59
66
|
outputDir,
|
|
60
67
|
numThreads: threadsPerCombo,
|
|
68
|
+
e2eSpecPattern,
|
|
61
69
|
});
|
|
62
70
|
});
|
|
63
71
|
const results = await Promise.all(runPromises);
|
|
@@ -7,9 +7,6 @@ import Profile from '../types/Profile';
|
|
|
7
7
|
import runCypressVisible from './runCypressVisible';
|
|
8
8
|
import executeAllHeadlessCombinations from './executeAllHeadlessCombinations';
|
|
9
9
|
|
|
10
|
-
// Import constants
|
|
11
|
-
import DEFAULT_THREADS_PER_COMBO from '../constants/DEFAULT_THREADS_PER_COMBO';
|
|
12
|
-
|
|
13
10
|
/**
|
|
14
11
|
* Execute Cypress tests in either headless or visible mode
|
|
15
12
|
* @author Yuen Ler Chow
|
|
@@ -17,14 +14,18 @@ import DEFAULT_THREADS_PER_COMBO from '../constants/DEFAULT_THREADS_PER_COMBO';
|
|
|
17
14
|
* @param opts.selectedProfiles - Array of selected profiles
|
|
18
15
|
* @param opts.selectedBrowsers - Array of selected browsers
|
|
19
16
|
* @param opts.isHeadless - Whether to run in headless mode
|
|
20
|
-
* @param
|
|
17
|
+
* @param opts.threadsPerCombo - Number of parallel threads per combo
|
|
18
|
+
* @param opts.e2eTestFolder - E2E test folder label
|
|
19
|
+
* @param opts.e2eSpecPattern - E2E test spec glob
|
|
21
20
|
*/
|
|
22
21
|
const executeCypress = async (
|
|
23
22
|
opts: {
|
|
24
23
|
selectedProfiles: Profile[],
|
|
25
24
|
selectedBrowsers: string[],
|
|
26
25
|
isHeadless: boolean,
|
|
27
|
-
threadsPerCombo
|
|
26
|
+
threadsPerCombo: number,
|
|
27
|
+
e2eTestFolder: string,
|
|
28
|
+
e2eSpecPattern: string,
|
|
28
29
|
},
|
|
29
30
|
): Promise<void> => {
|
|
30
31
|
const {
|
|
@@ -32,6 +33,8 @@ const executeCypress = async (
|
|
|
32
33
|
selectedBrowsers,
|
|
33
34
|
isHeadless,
|
|
34
35
|
threadsPerCombo,
|
|
36
|
+
e2eTestFolder,
|
|
37
|
+
e2eSpecPattern,
|
|
35
38
|
} = opts;
|
|
36
39
|
|
|
37
40
|
console.log('\n═══════════════════════════════════════════════════════════');
|
|
@@ -40,7 +43,8 @@ const executeCypress = async (
|
|
|
40
43
|
console.log(`Browser(s): ${selectedBrowsers.join(', ')}`);
|
|
41
44
|
console.log(`Headless: ${isHeadless}`);
|
|
42
45
|
if (isHeadless) {
|
|
43
|
-
console.log(`
|
|
46
|
+
console.log(`E2E test folder: ${e2eTestFolder}`);
|
|
47
|
+
console.log(`Threads per combo: ${threadsPerCombo}`);
|
|
44
48
|
}
|
|
45
49
|
console.log('═══════════════════════════════════════════════════════════\n');
|
|
46
50
|
|
|
@@ -55,6 +59,7 @@ const executeCypress = async (
|
|
|
55
59
|
selectedProfiles,
|
|
56
60
|
selectedBrowsers,
|
|
57
61
|
threadsPerCombo,
|
|
62
|
+
e2eSpecPattern,
|
|
58
63
|
});
|
|
59
64
|
}
|
|
60
65
|
} catch (error) {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
|
|
3
|
+
// Import constants
|
|
4
|
+
import ALL_E2E_TESTS_LABEL from '../constants/ALL_E2E_TESTS_LABEL';
|
|
5
|
+
import ALL_E2E_TESTS_SPEC_PATTERN from '../constants/ALL_E2E_TESTS_SPEC_PATTERN';
|
|
6
|
+
|
|
7
|
+
// Import types
|
|
8
|
+
import E2ETestFolderChoice from '../types/E2ETestFolderChoice';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Find an e2e test folder by name
|
|
12
|
+
* @author Yuen Ler Chow
|
|
13
|
+
* @param name e2e test folder name to find
|
|
14
|
+
* @param folders array of available e2e test folders
|
|
15
|
+
* @returns selected e2e test folder choice
|
|
16
|
+
*/
|
|
17
|
+
const findE2ETestFolderByName = (
|
|
18
|
+
name: string,
|
|
19
|
+
folders: E2ETestFolderChoice[],
|
|
20
|
+
): E2ETestFolderChoice => {
|
|
21
|
+
// Convert inputs like "cypress/e2e/login/" to "login" before matching folder names
|
|
22
|
+
const normalizedName = (
|
|
23
|
+
name
|
|
24
|
+
.trim()
|
|
25
|
+
.replace(/\\/g, '/')
|
|
26
|
+
.replace(/^cypress\/e2e\/?/i, '')
|
|
27
|
+
.replace(/^\/+/, '')
|
|
28
|
+
.replace(/\/+$/, '')
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
if (['all', '*', '.'].includes(normalizedName.toLowerCase())) {
|
|
32
|
+
return {
|
|
33
|
+
tag: 'A',
|
|
34
|
+
description: ALL_E2E_TESTS_LABEL,
|
|
35
|
+
relativePath: '',
|
|
36
|
+
specPattern: ALL_E2E_TESTS_SPEC_PATTERN,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const selectedFolder = folders.find((folder) => {
|
|
41
|
+
return folder.relativePath.toLowerCase() === normalizedName.toLowerCase();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
if (!selectedFolder) {
|
|
45
|
+
const validFolders = folders.map((folder) => {
|
|
46
|
+
return folder.relativePath;
|
|
47
|
+
});
|
|
48
|
+
console.error(`E2E test folder invalid: ${name}. Available folders: all, ${validFolders.join(', ')}`);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return selectedFolder;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export default findE2ETestFolderByName;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
|
|
4
|
+
// Import helpers
|
|
5
|
+
import getRootPath from './getRootPath';
|
|
6
|
+
|
|
7
|
+
// Import shared types
|
|
8
|
+
import E2ETestFolderChoice from '../types/E2ETestFolderChoice';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Check whether a directory contains any .ky.ts tests, including nested folders.
|
|
12
|
+
* @author Yuen Ler Chow
|
|
13
|
+
* @param dir directory to search
|
|
14
|
+
* @returns true if the directory contains at least one .ky.ts test
|
|
15
|
+
*/
|
|
16
|
+
const hasKyTests = (dir: string): boolean => {
|
|
17
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
18
|
+
return entries.some((entry) => {
|
|
19
|
+
const entryPath = path.join(dir, entry.name);
|
|
20
|
+
if (entry.isDirectory()) {
|
|
21
|
+
return hasKyTests(entryPath);
|
|
22
|
+
}
|
|
23
|
+
return entry.isFile() && entry.name.endsWith('.ky.ts');
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Collect e2e folders that contain .ky.ts tests.
|
|
29
|
+
* @author Yuen Ler Chow
|
|
30
|
+
* @param opts object of arguments
|
|
31
|
+
* @param opts.dir directory to search
|
|
32
|
+
* @param opts.e2eDir root e2e directory used for relative paths
|
|
33
|
+
* @param opts.folders mutable list of relative folder paths
|
|
34
|
+
*/
|
|
35
|
+
const collectTestFolders = (opts: {
|
|
36
|
+
dir: string,
|
|
37
|
+
e2eDir: string,
|
|
38
|
+
folders: string[],
|
|
39
|
+
}): void => {
|
|
40
|
+
const { dir, e2eDir, folders } = opts;
|
|
41
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
42
|
+
|
|
43
|
+
entries.forEach((entry) => {
|
|
44
|
+
if (!entry.isDirectory()) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const entryPath = path.join(dir, entry.name);
|
|
49
|
+
if (hasKyTests(entryPath)) {
|
|
50
|
+
folders.push(
|
|
51
|
+
path
|
|
52
|
+
.relative(e2eDir, entryPath)
|
|
53
|
+
.split(path.sep)
|
|
54
|
+
.join('/'),
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
collectTestFolders({
|
|
59
|
+
dir: entryPath,
|
|
60
|
+
e2eDir,
|
|
61
|
+
folders,
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get e2e test folders that contain .ky.ts tests.
|
|
68
|
+
* @author Yuen Ler Chow
|
|
69
|
+
* @returns e2e test folder options for the chooser
|
|
70
|
+
*/
|
|
71
|
+
const getE2ETestFoldersForChooser = (): E2ETestFolderChoice[] => {
|
|
72
|
+
const root = getRootPath();
|
|
73
|
+
const e2eDir = path.join(root, 'cypress/e2e');
|
|
74
|
+
|
|
75
|
+
if (!fs.existsSync(e2eDir)) {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const folders: string[] = [];
|
|
80
|
+
collectTestFolders({
|
|
81
|
+
dir: e2eDir,
|
|
82
|
+
e2eDir,
|
|
83
|
+
folders,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
return folders.sort().map((relativePath, index) => {
|
|
87
|
+
return {
|
|
88
|
+
tag: String(index + 1),
|
|
89
|
+
description: relativePath,
|
|
90
|
+
relativePath,
|
|
91
|
+
specPattern: `cypress/e2e/${relativePath}/**/*.ky.ts`,
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
export default getE2ETestFoldersForChooser;
|
|
@@ -14,9 +14,6 @@ import generateHtmlReport from './generateHtmlReport';
|
|
|
14
14
|
// Import shared types
|
|
15
15
|
import RunResult from '../types/RunResult';
|
|
16
16
|
|
|
17
|
-
// Import constants
|
|
18
|
-
import DEFAULT_THREADS_PER_COMBO from '../constants/DEFAULT_THREADS_PER_COMBO';
|
|
19
|
-
|
|
20
17
|
/**
|
|
21
18
|
* Run Cypress in headless mode for a single profile and browser using cypress-parallel
|
|
22
19
|
* @author Yuen Ler Chow
|
|
@@ -24,20 +21,23 @@ import DEFAULT_THREADS_PER_COMBO from '../constants/DEFAULT_THREADS_PER_COMBO';
|
|
|
24
21
|
* @param opts.profileName - The profile name to use
|
|
25
22
|
* @param opts.browser - The browser to use
|
|
26
23
|
* @param opts.outputDir - The output directory for results
|
|
27
|
-
* @param
|
|
24
|
+
* @param opts.numThreads - The number of parallel threads to use
|
|
25
|
+
* @param opts.e2eSpecPattern - The spec glob to run
|
|
28
26
|
* @returns Promise that resolves with run result
|
|
29
27
|
*/
|
|
30
28
|
const runCypressHeadless = (opts: {
|
|
31
29
|
profileName: string,
|
|
32
30
|
browser: string,
|
|
33
31
|
outputDir: string,
|
|
34
|
-
numThreads
|
|
32
|
+
numThreads: number,
|
|
33
|
+
e2eSpecPattern: string,
|
|
35
34
|
}): Promise<RunResult> => {
|
|
36
35
|
const {
|
|
37
36
|
profileName,
|
|
38
37
|
browser,
|
|
39
38
|
outputDir,
|
|
40
|
-
numThreads
|
|
39
|
+
numThreads,
|
|
40
|
+
e2eSpecPattern,
|
|
41
41
|
} = opts;
|
|
42
42
|
|
|
43
43
|
return new Promise((resolve, reject) => {
|
|
@@ -91,7 +91,7 @@ const runCypressHeadless = (opts: {
|
|
|
91
91
|
'--threads',
|
|
92
92
|
numThreads.toString(),
|
|
93
93
|
'-d',
|
|
94
|
-
|
|
94
|
+
`'${e2eSpecPattern}'`,
|
|
95
95
|
'-m',
|
|
96
96
|
'false',
|
|
97
97
|
'-a',
|
package/start/index.ts
CHANGED
|
@@ -19,9 +19,13 @@ import extractArgValue from './helpers/extractArgValue';
|
|
|
19
19
|
import getRootPath from './helpers/getRootPath';
|
|
20
20
|
import executeCypress from './helpers/executeCypress';
|
|
21
21
|
import getCypressDetectedBrowsersForChooser from './helpers/getCypressDetectedBrowsersForChooser';
|
|
22
|
+
import getE2ETestFoldersForChooser from './helpers/getE2ETestFoldersForChooser';
|
|
23
|
+
import findE2ETestFolderByName from './helpers/findE2ETestFolderByName';
|
|
22
24
|
|
|
23
25
|
// Import constants
|
|
24
26
|
import DEFAULT_THREADS_PER_COMBO from './constants/DEFAULT_THREADS_PER_COMBO';
|
|
27
|
+
import ALL_E2E_TESTS_LABEL from './constants/ALL_E2E_TESTS_LABEL';
|
|
28
|
+
import ALL_E2E_TESTS_SPEC_PATTERN from './constants/ALL_E2E_TESTS_SPEC_PATTERN';
|
|
25
29
|
|
|
26
30
|
// Get the project directory
|
|
27
31
|
const pwd = getRootPath();
|
|
@@ -61,6 +65,8 @@ const args = process.argv.slice(2);
|
|
|
61
65
|
let selectedProfiles: { file: string; profileName: string }[] = [];
|
|
62
66
|
let selectedBrowsers: string[] = [];
|
|
63
67
|
let isHeadless = false;
|
|
68
|
+
let selectedE2ETestFolder = ALL_E2E_TESTS_LABEL;
|
|
69
|
+
let selectedE2ESpecPattern = ALL_E2E_TESTS_SPEC_PATTERN;
|
|
64
70
|
|
|
65
71
|
// Check for PROFILE (env var or CLI arg)
|
|
66
72
|
const envProfileRaw = process.env.PROFILE;
|
|
@@ -82,6 +88,11 @@ if (browserRaw) {
|
|
|
82
88
|
selectedBrowsers = validateBrowsers(browserNames);
|
|
83
89
|
}
|
|
84
90
|
|
|
91
|
+
// Check for E2E_TEST_FOLDER (env var or CLI arg)
|
|
92
|
+
const envE2ETestFolderRaw = process.env.E2E_TEST_FOLDER;
|
|
93
|
+
const argE2ETestFolderRaw = extractArgValue(args, '--e2eFolder');
|
|
94
|
+
const e2eTestFolderRaw = envE2ETestFolderRaw || argE2ETestFolderRaw;
|
|
95
|
+
|
|
85
96
|
// Check for HEADLESS (env var or CLI flag)
|
|
86
97
|
const envHeadlessRaw = process.env.HEADLESS;
|
|
87
98
|
const headlessFlagValue = extractArgValue(args, '--headless');
|
|
@@ -92,7 +103,7 @@ isHeadless = !!(envHeadlessRaw && envHeadlessRaw.toLowerCase() !== 'false') || h
|
|
|
92
103
|
const envThreadsRaw = process.env.THREADS_PER_COMBO;
|
|
93
104
|
const argThreadsRaw = extractArgValue(args, '--threadsPerCombo');
|
|
94
105
|
const threadsRaw = envThreadsRaw || argThreadsRaw;
|
|
95
|
-
let threadsPerCombo
|
|
106
|
+
let threadsPerCombo = DEFAULT_THREADS_PER_COMBO;
|
|
96
107
|
if (threadsRaw) {
|
|
97
108
|
const parsed = Number.parseInt(threadsRaw, 10);
|
|
98
109
|
if (!Number.isNaN(parsed) && parsed > 0) {
|
|
@@ -117,6 +128,43 @@ if (!envHeadlessRaw && !hasHeadlessFlag) {
|
|
|
117
128
|
isHeadless = choices[0].tag === 'Y';
|
|
118
129
|
}
|
|
119
130
|
|
|
131
|
+
// If running headless, optionally narrow tests to one e2e folder
|
|
132
|
+
if (isHeadless) {
|
|
133
|
+
const choosableE2ETestFolders = getE2ETestFoldersForChooser();
|
|
134
|
+
|
|
135
|
+
if (e2eTestFolderRaw) {
|
|
136
|
+
const e2eSelection = findE2ETestFolderByName(e2eTestFolderRaw, choosableE2ETestFolders);
|
|
137
|
+
selectedE2ETestFolder = e2eSelection.description;
|
|
138
|
+
selectedE2ESpecPattern = e2eSelection.specPattern;
|
|
139
|
+
} else if (choosableE2ETestFolders.length > 0) {
|
|
140
|
+
const choices = showChooser({
|
|
141
|
+
question: 'Choose e2e test folder:',
|
|
142
|
+
options: [
|
|
143
|
+
{
|
|
144
|
+
tag: 'A',
|
|
145
|
+
description: ALL_E2E_TESTS_LABEL,
|
|
146
|
+
},
|
|
147
|
+
...choosableE2ETestFolders,
|
|
148
|
+
],
|
|
149
|
+
title: 'Select E2E Tests',
|
|
150
|
+
allowMulti: false,
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
const allTestsChosen = choices.some((choice) => {
|
|
154
|
+
return choice.tag === 'A';
|
|
155
|
+
});
|
|
156
|
+
if (!allTestsChosen) {
|
|
157
|
+
const selectedFolder = choosableE2ETestFolders.find((folder) => {
|
|
158
|
+
return folder.tag === choices[0].tag;
|
|
159
|
+
});
|
|
160
|
+
if (selectedFolder) {
|
|
161
|
+
selectedE2ETestFolder = selectedFolder.relativePath;
|
|
162
|
+
selectedE2ESpecPattern = selectedFolder.specPattern;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
120
168
|
// If running headless and no browsers were selected, ask the user to choose
|
|
121
169
|
if (isHeadless && selectedBrowsers.length === 0) {
|
|
122
170
|
const choosableBrowsers = getCypressDetectedBrowsersForChooser();
|
|
@@ -157,11 +205,10 @@ if (isHeadless && selectedBrowsers.length === 0) {
|
|
|
157
205
|
selectedBrowsers = (
|
|
158
206
|
choices
|
|
159
207
|
.map((choice) => {
|
|
160
|
-
|
|
161
|
-
return
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return choosableBrowsers[choice.index].name;
|
|
208
|
+
const selectedBrowser = choosableBrowsers.find((browser) => {
|
|
209
|
+
return browser.tag.toLowerCase() === choice.tag.toLowerCase();
|
|
210
|
+
});
|
|
211
|
+
return selectedBrowser?.name ?? null;
|
|
165
212
|
})
|
|
166
213
|
.filter((name) => {
|
|
167
214
|
return name !== null;
|
|
@@ -218,10 +265,11 @@ if (
|
|
|
218
265
|
selectedProfiles = (
|
|
219
266
|
choices
|
|
220
267
|
.map((choice) => {
|
|
221
|
-
|
|
268
|
+
const profileIndex = Number.parseInt(choice.tag, 10) - 1;
|
|
269
|
+
if (Number.isNaN(profileIndex)) {
|
|
222
270
|
return null;
|
|
223
271
|
}
|
|
224
|
-
return choosableProfiles[
|
|
272
|
+
return choosableProfiles[profileIndex] ?? null;
|
|
225
273
|
})
|
|
226
274
|
.filter((profile) => {
|
|
227
275
|
return profile !== null;
|
|
@@ -236,4 +284,6 @@ executeCypress({
|
|
|
236
284
|
selectedBrowsers,
|
|
237
285
|
isHeadless,
|
|
238
286
|
threadsPerCombo,
|
|
287
|
+
e2eTestFolder: selectedE2ETestFolder,
|
|
288
|
+
e2eSpecPattern: selectedE2ESpecPattern,
|
|
239
289
|
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An e2e test folder that can be put into a chooser
|
|
3
|
+
* @author Yuen Ler Chow
|
|
4
|
+
*/
|
|
5
|
+
type E2ETestFolderChoice = {
|
|
6
|
+
// The chooser tag users type to select this folder
|
|
7
|
+
tag: string,
|
|
8
|
+
// The text shown in the chooser
|
|
9
|
+
description: string,
|
|
10
|
+
// The folder path relative to cypress/e2e
|
|
11
|
+
relativePath: string,
|
|
12
|
+
// The Cypress spec glob for this folder
|
|
13
|
+
specPattern: string,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default E2ETestFolderChoice;
|