bdy 1.18.24-dev → 1.18.24-dev-pipeline

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 (31) hide show
  1. package/distTs/package.json +1 -1
  2. package/distTs/src/api/client.js +9 -2
  3. package/distTs/src/command/crawl/validation.js +151 -0
  4. package/distTs/src/command/crawl.js +144 -0
  5. package/distTs/src/command/pipeline/run/start.js +101 -0
  6. package/distTs/src/command/pipeline/run/status.js +34 -0
  7. package/distTs/src/command/pipeline/run.js +7 -125
  8. package/distTs/src/command/project/link.js +11 -11
  9. package/distTs/src/command/tests/capture/validation.js +59 -0
  10. package/distTs/src/command/tests/capture.js +100 -0
  11. package/distTs/src/command/tests/unit/upload.js +86 -0
  12. package/distTs/src/command/tests/unit.js +11 -0
  13. package/distTs/src/command/tests/visual/session/close.js +27 -0
  14. package/distTs/src/command/tests/visual/session/create.js +82 -0
  15. package/distTs/src/command/tests/visual/session.js +13 -0
  16. package/distTs/src/command/tests/visual/setup.js +20 -0
  17. package/distTs/src/command/tests/visual/shared/validation.js +118 -0
  18. package/distTs/src/command/tests/visual/upload.js +138 -0
  19. package/distTs/src/command/tests/visual.js +15 -0
  20. package/distTs/src/command/tests.js +15 -0
  21. package/distTs/src/input.js +6 -10
  22. package/distTs/src/output/pipeline.js +915 -0
  23. package/distTs/src/output.js +81 -31
  24. package/distTs/src/texts.js +28 -36
  25. package/distTs/src/types/crawl.js +2 -0
  26. package/distTs/src/types/pipeline.js +424 -0
  27. package/package.json +1 -1
  28. package/distTs/src/command/project/get.js +0 -18
  29. package/distTs/src/command/project/set.js +0 -31
  30. package/distTs/src/command/sandbox/get/yaml.js +0 -30
  31. package/distTs/src/command/vt/scrape.js +0 -193
@@ -23,7 +23,7 @@ commandProjectLink.action(async (dir, options) => {
23
23
  ProjectCfg.init(path, workspace, project);
24
24
  output_1.default.okSign();
25
25
  output_1.default.normal(texts_1.TXT_COMMAND_PROJECT_LINK_TO, false);
26
- output_1.default.light(` ${url}`);
26
+ output_1.default.cyan(` ${url}`);
27
27
  await initRepo(workspace, project, path, git, options);
28
28
  tryNow();
29
29
  output_1.default.exitNormal();
@@ -54,13 +54,13 @@ const tryNow = () => {
54
54
  output_1.default.arrowSign();
55
55
  output_1.default.label(texts_1.OPT_COMMAND_PROJECT_LINK_TRY_NOW);
56
56
  output_1.default.dim('$ ', false);
57
- output_1.default.light('bdy tunnel http 3000 ', false);
57
+ output_1.default.cyan('bdy tunnel http 3000 ', false);
58
58
  output_1.default.muted(' Expose localhost:3000 to the internet');
59
59
  output_1.default.dim('$ ', false);
60
- output_1.default.light('bdy package publish . ', false);
60
+ output_1.default.cyan('bdy package publish . ', false);
61
61
  output_1.default.muted(' Publish a package from the current project');
62
62
  output_1.default.dim('$ ', false);
63
- output_1.default.light('bdy sandbox create --run "npm start" ', false);
63
+ output_1.default.cyan('bdy sandbox create --run "npm start" ', false);
64
64
  output_1.default.muted(' Spin up a cloud sandbox and run your app');
65
65
  };
66
66
  const initRepo = async (workspace, project, path, git, options) => {
@@ -89,16 +89,16 @@ const initRepo = async (workspace, project, path, git, options) => {
89
89
  });
90
90
  output_1.default.okSign();
91
91
  output_1.default.normal('Remote ', false);
92
- output_1.default.light('origin ', false);
92
+ output_1.default.cyan('origin ', false);
93
93
  output_1.default.normal('set to ', false);
94
- output_1.default.light(remote);
94
+ output_1.default.cyan(remote);
95
95
  }
96
96
  else if (remotes.origin !== remote) {
97
97
  output_1.default.yellow(texts_1.OPT_COMMAND_PROJECT_LINK_HAS_REMOTE);
98
98
  output_1.default.normal('Current origin: ', false);
99
- output_1.default.light(remotes.origin);
99
+ output_1.default.cyan(remotes.origin);
100
100
  output_1.default.normal('Buddy project: ', false);
101
- output_1.default.light(remote);
101
+ output_1.default.cyan(remote);
102
102
  const opt = await output_1.default.inputMenuAdv(texts_1.OPT_COMMAND_PROJECT_LINK_SET_GIT_REMOTE, [
103
103
  {
104
104
  name: 'Add buddy remote',
@@ -127,9 +127,9 @@ const initRepo = async (workspace, project, path, git, options) => {
127
127
  });
128
128
  output_1.default.okSign();
129
129
  output_1.default.normal('Remote ', false);
130
- output_1.default.light('buddy ', false);
130
+ output_1.default.cyan('buddy ', false);
131
131
  output_1.default.normal('set to ', false);
132
- output_1.default.light(remote);
132
+ output_1.default.cyan(remote);
133
133
  }
134
134
  else if (opt === 'origin') {
135
135
  await (0, utils_1.execLocally)(`git remote rm origin`, {
@@ -140,7 +140,7 @@ const initRepo = async (workspace, project, path, git, options) => {
140
140
  });
141
141
  output_1.default.okSign();
142
142
  output_1.default.normal('Origin replaced with ', false);
143
- output_1.default.light(remote);
143
+ output_1.default.cyan(remote);
144
144
  }
145
145
  else {
146
146
  return;
@@ -0,0 +1,59 @@
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
+ exports.validateOptions = validateOptions;
7
+ exports.checkIfMinimalOptionsAreProvided = checkIfMinimalOptionsAreProvided;
8
+ const zod_1 = require("zod");
9
+ const output_1 = __importDefault(require("../../../output"));
10
+ const validation_1 = require("../visual/shared/validation");
11
+ const optionsSchema = zod_1.z.object({
12
+ urls: zod_1.z.string().optional(),
13
+ sitemap: zod_1.z.string().optional(),
14
+ urlsFile: zod_1.z.string().optional(),
15
+ follow: zod_1.z.boolean(),
16
+ respectRobots: zod_1.z.boolean(),
17
+ ignore: zod_1.z
18
+ .array(zod_1.z.string().regex(/^(?:([^:]+)::)?(?:(CSS|XPATH))=(.+)$/, {
19
+ message: "Ignore option must follow pattern '[scope::]type=value' where type must be CSS or XPATH (scope is optional)",
20
+ }))
21
+ .optional()
22
+ .transform(validation_1.parseScopedSelector),
23
+ cookie: validation_1.cookieSchema,
24
+ header: validation_1.headerSchema,
25
+ delay: zod_1.z
26
+ .array(zod_1.z.string().regex(/^(?:([^:]+)::)?(\d+)$/, {
27
+ message: "Delay option must follow pattern '[scope::]milliseconds' (scope is optional)",
28
+ }))
29
+ .optional()
30
+ .transform((value) => value?.map((v) => {
31
+ if (v.includes('::')) {
32
+ const [scope, milliseconds] = v.split('::');
33
+ return { scope: scope.trim(), value: Number(milliseconds) };
34
+ }
35
+ else {
36
+ return { scope: validation_1.DEFAULT_SCOPE, value: Number(v) };
37
+ }
38
+ })),
39
+ waitFor: validation_1.waitForSchema,
40
+ ignoreUrls: zod_1.z.array(zod_1.z.string()).optional(),
41
+ dryRun: zod_1.z.boolean().optional(),
42
+ });
43
+ function validateOptions(options) {
44
+ try {
45
+ const validatedOptions = optionsSchema.parse(options);
46
+ return validatedOptions;
47
+ }
48
+ catch (error) {
49
+ if (error instanceof zod_1.ZodError) {
50
+ output_1.default.exitError(error.errors.map((e) => e.message).join(', '));
51
+ }
52
+ else {
53
+ throw error;
54
+ }
55
+ }
56
+ }
57
+ function checkIfMinimalOptionsAreProvided(options) {
58
+ return !!options.urls || !!options.sitemap || !!options.urlsFile;
59
+ }
@@ -0,0 +1,100 @@
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 utils_1 = require("../../utils");
7
+ const texts_1 = require("../../texts");
8
+ const output_1 = __importDefault(require("../../output"));
9
+ const node_fs_1 = require("node:fs");
10
+ const commandCapture = (0, utils_1.newCommand)('capture', texts_1.DESC_COMMAND_CAPTURE);
11
+ commandCapture.option('--urls <urls>', texts_1.OPTION_COMPARE_URLS);
12
+ commandCapture.option('--sitemap <sitemap>', texts_1.OPTION_COMPARE_SITEMAP);
13
+ commandCapture.option('--urlsFile <urlsFile>', texts_1.OPTION_COMPARE_URLS_FILE);
14
+ commandCapture.option('--dryRun', texts_1.OPTION_COMPARE_DRY_RUN);
15
+ commandCapture.option('--follow', texts_1.OPTION_COMPARE_FOLLOW, false);
16
+ commandCapture.option('--respectRobots', texts_1.OPTION_COMPARE_RESPECT_ROBOTS, false);
17
+ commandCapture.option('--ignoreUrls <ignoreUrls...>', texts_1.OPTION_COMPARE_IGNORE_URLS);
18
+ commandCapture.option('--ignore <ignores...>', texts_1.OPTION_COMPARE_IGNORE);
19
+ commandCapture.option('--cookie <cookies...>', texts_1.OPTION_COMPARE_COOKIE);
20
+ commandCapture.option('--header <headers...>', texts_1.OPTION_COMPARE_HEADER);
21
+ commandCapture.option('--delay <delays...>', texts_1.OPTION_COMPARE_DELAY);
22
+ commandCapture.option('--waitFor <waitFors...>', texts_1.OPTION_COMPARE_WAIT_FOR);
23
+ commandCapture.action(async (options) => {
24
+ const { getCiAndGitInfo, formattedCiInfo } = require('@buddy-works/ci-info');
25
+ const { checkToken } = require('../../visualTest/validation');
26
+ const { addProtocolIfMissing } = require('../../visualTest/linkUtils');
27
+ const { sendCompareLinks } = require('../../visualTest/requests');
28
+ const { checkIfMinimalOptionsAreProvided, validateOptions } = require('./capture/validation');
29
+ const { setCiAndCommitInfo } = require('../../visualTest/context');
30
+ const validatedOptions = validateOptions(options);
31
+ if (!checkToken('vt')) {
32
+ output_1.default.exitError(texts_1.ERR_MISSING_VT_TOKEN);
33
+ }
34
+ if (!checkIfMinimalOptionsAreProvided(validatedOptions)) {
35
+ output_1.default.exitError(texts_1.ERR_MISSING_URLS);
36
+ }
37
+ let urls = [];
38
+ let sitemapSource;
39
+ if (validatedOptions.urls) {
40
+ const urlsList = getUrlsFromUrlOption(validatedOptions.urls);
41
+ urls = urls.concat(urlsList);
42
+ }
43
+ if (validatedOptions.urlsFile) {
44
+ const urlsList = getUrlsFromUrlFile(validatedOptions.urlsFile);
45
+ urls = urls.concat(urlsList);
46
+ }
47
+ if (validatedOptions.sitemap) {
48
+ sitemapSource = addProtocolIfMissing(validatedOptions.sitemap);
49
+ }
50
+ const { filteredUrls, duplicates } = filterDuplicates(urls);
51
+ if (duplicates.length > 0) {
52
+ output_1.default.normal(`Detected ${duplicates.length} duplicated urls:`);
53
+ output_1.default.normal(duplicates.join('\n'));
54
+ }
55
+ if (validatedOptions.dryRun) {
56
+ output_1.default.exitSuccess(`List of urls:\n${filteredUrls.join('\n')}`);
57
+ }
58
+ else if (filteredUrls.length > 1) {
59
+ output_1.default.normal(`List of urls:\n${filteredUrls.join('\n')}`);
60
+ }
61
+ const ciAndGitInfo = await getCiAndGitInfo({});
62
+ output_1.default.normal(formattedCiInfo(ciAndGitInfo));
63
+ setCiAndCommitInfo(ciAndGitInfo);
64
+ try {
65
+ const { message } = await sendCompareLinks(filteredUrls, validatedOptions, sitemapSource);
66
+ output_1.default.exitSuccess(message);
67
+ }
68
+ catch (error) {
69
+ output_1.default.exitError(`${error}`);
70
+ }
71
+ });
72
+ function getUrlsFromUrlOption(urls) {
73
+ const { addProtocolIfMissing } = require('../../visualTest/linkUtils');
74
+ return urls.split(',').map((url) => addProtocolIfMissing(url).trim());
75
+ }
76
+ function getUrlsFromUrlFile(urlsFile) {
77
+ const { addProtocolIfMissing } = require('../../visualTest/linkUtils');
78
+ const urlsFromFile = (0, node_fs_1.readFileSync)(urlsFile, 'utf-8');
79
+ return urlsFromFile
80
+ .split('\n')
81
+ .filter((url) => url.trim().length > 0)
82
+ .map((url) => addProtocolIfMissing(url).trim());
83
+ }
84
+ function filterDuplicates(urls) {
85
+ const seen = new Set();
86
+ const duplicates = new Set();
87
+ for (const url of urls) {
88
+ if (seen.has(url)) {
89
+ duplicates.add(url);
90
+ }
91
+ else {
92
+ seen.add(url);
93
+ }
94
+ }
95
+ return {
96
+ filteredUrls: Array.from(seen),
97
+ duplicates: Array.from(duplicates),
98
+ };
99
+ }
100
+ exports.default = commandCapture;
@@ -0,0 +1,86 @@
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 utils_1 = require("../../../utils");
7
+ const texts_1 = require("../../../texts");
8
+ const output_1 = __importDefault(require("../../../output"));
9
+ const commander_1 = require("commander");
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const token = process.env.BUDDY_UT_TOKEN || '';
12
+ const commandUtUpload = (0, utils_1.newCommand)('upload', texts_1.DESC_COMMAND_UT_UPLOAD);
13
+ commandUtUpload.argument('<glob>', texts_1.OPTION_UPLOAD_REPORT_GLOB);
14
+ commandUtUpload.addOption(new commander_1.Option('--format <format>', texts_1.OPTION_UPLOAD_REPORT_FORMAT)
15
+ .choices(['junit-xml'])
16
+ .makeOptionMandatory());
17
+ commandUtUpload.option('--dryRun', texts_1.OPTION_UPLOAD_DRY_RUN);
18
+ commandUtUpload.action(async (input, options) => {
19
+ const { getCiInfo } = require('../../../unitTest/ci');
20
+ const { sendUploadRequest } = require('../../../unitTest/requests');
21
+ if (!token) {
22
+ output_1.default.exitError(texts_1.ERR_MISSING_UT_TOKEN);
23
+ }
24
+ const { glob, dryRun } = validateInputAndOptions(input, options);
25
+ const ciInfo = await getCiInfo();
26
+ const { absolutePattern, files } = findFilesByGlob(glob);
27
+ if (files.length === 0) {
28
+ output_1.default.exitError(`No files matched the provided glob: ${absolutePattern}`);
29
+ }
30
+ if (dryRun) {
31
+ output_1.default.normal(`Found ${files.length} report file(s) using pattern: ${absolutePattern}`);
32
+ files.forEach((file) => {
33
+ output_1.default.normal(file);
34
+ });
35
+ output_1.default.exitSuccess('Dry run completed');
36
+ }
37
+ await sendUploadRequest(files, ciInfo);
38
+ output_1.default.exitSuccess('Upload completed');
39
+ });
40
+ exports.default = commandUtUpload;
41
+ function validateInputAndOptions(input, options) {
42
+ const z = require('zod');
43
+ const { ZodError } = require('zod');
44
+ const globSchema = z.string();
45
+ const optionsSchema = z.object({
46
+ format: z.enum(['junit-xml']),
47
+ dryRun: z.boolean().optional(),
48
+ });
49
+ try {
50
+ const glob = globSchema.parse(input);
51
+ const { format, dryRun } = optionsSchema.parse(options);
52
+ return {
53
+ glob,
54
+ format,
55
+ dryRun,
56
+ };
57
+ }
58
+ catch (error) {
59
+ if (error instanceof ZodError) {
60
+ output_1.default.exitError(error.errors.map((e) => `${e.path}: ${e.message}`).join(', '));
61
+ }
62
+ else {
63
+ throw error;
64
+ }
65
+ }
66
+ }
67
+ function findFilesByGlob(pattern) {
68
+ const { fdir } = require('fdir');
69
+ const picomatch = require('picomatch');
70
+ const cwd = process.cwd();
71
+ const scan = picomatch.scan(pattern);
72
+ if (!scan.isGlob) {
73
+ return {
74
+ absolutePattern: pattern,
75
+ files: (0, utils_1.isFile)(pattern) ? [pattern] : [],
76
+ };
77
+ }
78
+ if (node_path_1.default.isAbsolute(pattern)) {
79
+ const root = scan.base;
80
+ const files = new fdir().withFullPaths().glob(pattern).crawl(root).sync();
81
+ return { absolutePattern: pattern, files };
82
+ }
83
+ const preparedPattern = node_path_1.default.resolve(cwd, pattern);
84
+ const files = new fdir().withFullPaths().glob(preparedPattern).crawl().sync();
85
+ return { absolutePattern: preparedPattern, files };
86
+ }
@@ -0,0 +1,11 @@
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 utils_1 = require("../../utils");
7
+ const texts_1 = require("../../texts");
8
+ const upload_1 = __importDefault(require("./unit/upload"));
9
+ const commandUnit = (0, utils_1.newCommand)('unit', texts_1.DESC_COMMAND_UNIT);
10
+ commandUnit.addCommand(upload_1.default);
11
+ exports.default = commandUnit;
@@ -0,0 +1,27 @@
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 utils_1 = require("../../../../utils");
7
+ const texts_1 = require("../../../../texts");
8
+ const output_1 = __importDefault(require("../../../../output"));
9
+ const commandSessionClose = (0, utils_1.newCommand)('close', texts_1.DESC_COMMAND_SESSION_CLOSE);
10
+ commandSessionClose.action(async () => {
11
+ const { checkBuildId, checkToken } = require('../../../../visualTest/validation');
12
+ const { closeSession } = require('../../../../visualTest/requests');
13
+ if (!checkToken('vt')) {
14
+ output_1.default.exitError(texts_1.ERR_MISSING_VT_TOKEN);
15
+ }
16
+ if (!checkBuildId()) {
17
+ output_1.default.exitError(texts_1.ERR_MISSING_BUILD_ID);
18
+ }
19
+ try {
20
+ const { message } = await closeSession();
21
+ output_1.default.exitNormal(message);
22
+ }
23
+ catch (error) {
24
+ output_1.default.exitError(`${error}`);
25
+ }
26
+ });
27
+ exports.default = commandSessionClose;
@@ -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 utils_1 = require("../../../../utils");
7
+ const texts_1 = require("../../../../texts");
8
+ const output_1 = __importDefault(require("../../../../output"));
9
+ const commandSessionCreate = (0, utils_1.newCommand)('create', texts_1.DESC_COMMAND_SESSION_CREATE);
10
+ commandSessionCreate.argument('<command>', texts_1.OPTION_EXEC_COMMAND);
11
+ commandSessionCreate.option('--skipDiscovery', texts_1.OPTION_EXEC_SKIP_DISCOVERY);
12
+ commandSessionCreate.option('--oneByOne', texts_1.OPTION_EXEC_ONE_BY_ONE);
13
+ commandSessionCreate.option('--parallel', texts_1.OPTION_EXEC_PARALLEL);
14
+ commandSessionCreate.action(async (command, options) => {
15
+ const which = require('which');
16
+ const { getCiAndGitInfo, formattedCiInfo } = require('@buddy-works/ci-info');
17
+ const { checkParallel, checkToken } = require('../../../../visualTest/validation');
18
+ const { getDefaultSettings } = require('../../../../visualTest/requests');
19
+ const { debug, setBrowserPath, setCiAndCommitInfo, setExecOptions } = require('../../../../visualTest/context');
20
+ const { createServer } = require('../../../../visualTest/server');
21
+ const { finishProcessingSnapshots, setDefaultSettings, showSessionLink } = require('../../../../visualTest/snapshots');
22
+ const { testExec } = require('../../../../visualTest/exec');
23
+ const { getBrowserPath } = require('../../../../visualTest/browser');
24
+ setExecOptions(options);
25
+ try {
26
+ const browserPath = await getBrowserPath();
27
+ setBrowserPath(browserPath);
28
+ }
29
+ catch (error) {
30
+ output_1.default.exitError(`${error}`);
31
+ }
32
+ if (!checkToken('vt')) {
33
+ output_1.default.exitError(texts_1.ERR_MISSING_VT_TOKEN);
34
+ }
35
+ if (!checkParallel()) {
36
+ output_1.default.exitError(texts_1.ERR_MISSING_BUILD_ID);
37
+ }
38
+ const app = await createServer();
39
+ const [mainCommand, ...mainCommandArguments] = command.split(' ');
40
+ output_1.default.normal((0, texts_1.LOG_RUNNING_EXEC_COMMAND)(`${mainCommand} ${[...mainCommandArguments].join(' ')}`));
41
+ const resolved = await which(mainCommand, { nothrow: true });
42
+ if (!resolved) {
43
+ output_1.default.exitError((0, texts_1.ERR_MISSING_EXEC_COMMAND)(`${mainCommand} ${[...mainCommandArguments].join(' ')}`));
44
+ }
45
+ try {
46
+ let t1, t11;
47
+ if (debug) {
48
+ t1 = performance.now();
49
+ }
50
+ const defaultSettings = await getDefaultSettings();
51
+ setDefaultSettings(defaultSettings);
52
+ const ciAndGitInfo = await getCiAndGitInfo({
53
+ baseBranch: defaultSettings.baseBranch,
54
+ logger: output_1.default.warning,
55
+ });
56
+ setCiAndCommitInfo(ciAndGitInfo);
57
+ output_1.default.normal(formattedCiInfo(ciAndGitInfo));
58
+ if (debug) {
59
+ t11 = performance.now();
60
+ }
61
+ const spawnedProcessExitCode = await testExec(mainCommand, [
62
+ ...mainCommandArguments,
63
+ ]);
64
+ if (debug && t11) {
65
+ const t22 = performance.now();
66
+ output_1.default.normal((0, texts_1.DEBUG_EXEC_TEST_COMMAND)(t22 - t11));
67
+ }
68
+ await app.close();
69
+ await finishProcessingSnapshots(spawnedProcessExitCode);
70
+ showSessionLink();
71
+ if (debug && t1) {
72
+ const t2 = performance.now();
73
+ output_1.default.normal((0, texts_1.DEBUG_EXEC_COMMAND)(t2 - t1));
74
+ }
75
+ process.exit(spawnedProcessExitCode);
76
+ }
77
+ catch (error) {
78
+ await app.close();
79
+ output_1.default.exitError(`${error}`);
80
+ }
81
+ });
82
+ exports.default = commandSessionCreate;
@@ -0,0 +1,13 @@
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 utils_1 = require("../../../utils");
7
+ const texts_1 = require("../../../texts");
8
+ const create_1 = __importDefault(require("./session/create"));
9
+ const close_1 = __importDefault(require("./session/close"));
10
+ const commandSession = (0, utils_1.newCommand)('session', texts_1.DESC_COMMAND_SESSION);
11
+ commandSession.addCommand(create_1.default);
12
+ commandSession.addCommand(close_1.default);
13
+ exports.default = commandSession;
@@ -0,0 +1,20 @@
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 utils_1 = require("../../../utils");
7
+ const texts_1 = require("../../../texts");
8
+ const output_1 = __importDefault(require("../../../output"));
9
+ const commandVisualSetup = (0, utils_1.newCommand)('setup', texts_1.DESC_COMMAND_VISUAL_SETUP);
10
+ commandVisualSetup.action(async () => {
11
+ try {
12
+ const { installBrowser } = require('../../../visualTest/browser');
13
+ await installBrowser();
14
+ output_1.default.exitNormal('');
15
+ }
16
+ catch (error) {
17
+ output_1.default.exitError(`${error}`);
18
+ }
19
+ });
20
+ exports.default = commandVisualSetup;
@@ -0,0 +1,118 @@
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
+ exports.waitForSchema = exports.headerSchema = exports.cookieSchema = exports.DEFAULT_SCOPE = void 0;
7
+ exports.parseScopedSelector = parseScopedSelector;
8
+ exports.parseScopedKeyValue = parseScopedKeyValue;
9
+ const zod_1 = require("zod");
10
+ const output_1 = __importDefault(require("../../../../output"));
11
+ exports.DEFAULT_SCOPE = '**';
12
+ function parseScopedSelector(value) {
13
+ return value?.map((v) => {
14
+ let scope, type, selectorValue;
15
+ if (v.includes('::CSS=') || v.includes('::XPATH=')) {
16
+ const [scopePart, ...rest] = v.split('::');
17
+ const [typePart, ...valuePart] = rest.join('::').split('=');
18
+ type = typePart;
19
+ selectorValue = valuePart.join('=');
20
+ scope = scopePart;
21
+ }
22
+ else {
23
+ const [typePart, ...valuePart] = v.split('=');
24
+ type = typePart;
25
+ selectorValue = valuePart.join('=');
26
+ scope = exports.DEFAULT_SCOPE;
27
+ }
28
+ return { scope, type, value: selectorValue };
29
+ });
30
+ }
31
+ function parseScopedKeyValue(rawValue) {
32
+ let scope = exports.DEFAULT_SCOPE;
33
+ let keyValue = rawValue;
34
+ const scopeSeparatorIndex = rawValue.indexOf('::');
35
+ if (scopeSeparatorIndex >= 0) {
36
+ scope = rawValue.slice(0, scopeSeparatorIndex).trim();
37
+ keyValue = rawValue.slice(scopeSeparatorIndex + 2).trim();
38
+ }
39
+ const equalSignIndex = keyValue.indexOf('=');
40
+ if (equalSignIndex <= 0) {
41
+ output_1.default.exitError("Option value must follow pattern '[scope::]key=value' (scope is optional)");
42
+ }
43
+ const key = keyValue.slice(0, equalSignIndex).trim();
44
+ const value = keyValue.slice(equalSignIndex + 1).trim();
45
+ if (!key) {
46
+ output_1.default.exitError('Option key cannot be empty');
47
+ }
48
+ return { scope, key, value };
49
+ }
50
+ exports.cookieSchema = zod_1.z
51
+ .array(zod_1.z
52
+ .string()
53
+ .max(4096, {
54
+ message: 'Cookie must be less than 4096 characters',
55
+ })
56
+ .regex(/^(?:([^:]+)::)?([^=]+)=(.*)$/, {
57
+ message: "Cookie option must follow pattern '[scope::]key=value[;attribute]' (scope is optional)",
58
+ }))
59
+ .optional()
60
+ .transform((value) => value?.map((v) => {
61
+ let scope = exports.DEFAULT_SCOPE;
62
+ let cookieValue = v;
63
+ if (v.includes('::')) {
64
+ const [scopePart, valuePart] = v.split('::');
65
+ scope = scopePart.trim();
66
+ cookieValue = valuePart.trim();
67
+ }
68
+ const cookieParts = cookieValue.split(';').map((part) => part.trim());
69
+ const mainPart = cookieParts[0];
70
+ const firstEqualSignIndex = mainPart.indexOf('=');
71
+ const key = mainPart.slice(0, firstEqualSignIndex).trim();
72
+ const value = mainPart.slice(firstEqualSignIndex + 1).trim();
73
+ const cookie = {
74
+ scope,
75
+ key,
76
+ value,
77
+ httpOnly: false,
78
+ secure: false,
79
+ };
80
+ for (let i = 1; i < cookieParts.length; i++) {
81
+ const part = cookieParts[i].toLowerCase();
82
+ if (part === 'httponly') {
83
+ cookie.httpOnly = true;
84
+ }
85
+ else if (part === 'secure') {
86
+ cookie.secure = true;
87
+ }
88
+ else if (part.startsWith('domain=')) {
89
+ cookie.domain = part.substring(7);
90
+ }
91
+ else if (part.startsWith('path=')) {
92
+ cookie.path = part.substring(5);
93
+ }
94
+ else if (part.startsWith('samesite=')) {
95
+ const sameSiteValue = part.substring(9);
96
+ if (['strict', 'lax', 'none'].includes(sameSiteValue)) {
97
+ cookie.sameSite = (sameSiteValue.charAt(0).toUpperCase() +
98
+ sameSiteValue.slice(1));
99
+ }
100
+ }
101
+ }
102
+ return cookie;
103
+ }));
104
+ exports.headerSchema = zod_1.z
105
+ .array(zod_1.z.string().regex(/^(?:([^:]+)::)?([^=]+)=(.*)$/, {
106
+ message: "Header option must follow pattern '[scope::]key=value' (scope is optional)",
107
+ }))
108
+ .optional()
109
+ .transform((value) => value?.map((v) => {
110
+ const { scope, key, value } = parseScopedKeyValue(v);
111
+ return { scope, key, value };
112
+ }));
113
+ exports.waitForSchema = zod_1.z
114
+ .array(zod_1.z.string().regex(/^(?:([^:]+)::)?(?:(CSS|XPATH))=(.+)$/, {
115
+ message: "WaitFor option must follow pattern '[scope::]type=value' where type must be CSS or XPATH (scope is optional)",
116
+ }))
117
+ .optional()
118
+ .transform(parseScopedSelector);