@alwaysmeticulous/cli 2.39.0 → 2.40.4

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 (119) hide show
  1. package/dist/api/test-run.api.d.ts +3 -31
  2. package/dist/api/test-run.api.js +3 -96
  3. package/dist/commands/download-replay/download-replay.command.js +4 -4
  4. package/dist/commands/download-session/download-session.command.js +4 -4
  5. package/dist/commands/record/record.command.js +8 -11
  6. package/dist/commands/replay/replay.command.d.ts +4 -20
  7. package/dist/commands/replay/replay.command.js +4 -239
  8. package/dist/commands/run-all-tests/run-all-tests.command.js +5 -6
  9. package/dist/commands/show-project/show-project.command.js +2 -3
  10. package/dist/index.d.ts +0 -7
  11. package/dist/index.js +1 -13
  12. package/dist/main.js +5 -11
  13. package/dist/utils/sentry.utils.d.ts +0 -4
  14. package/dist/utils/sentry.utils.js +3 -23
  15. package/package.json +14 -32
  16. package/dist/api/client.d.ts +0 -5
  17. package/dist/api/client.js +0 -32
  18. package/dist/api/download.d.ts +0 -1
  19. package/dist/api/download.js +0 -21
  20. package/dist/api/project.api.d.ts +0 -3
  21. package/dist/api/project.api.js +0 -22
  22. package/dist/api/replay-diff.api.d.ts +0 -13
  23. package/dist/api/replay-diff.api.js +0 -32
  24. package/dist/api/replay.api.d.ts +0 -36
  25. package/dist/api/replay.api.js +0 -89
  26. package/dist/api/session.api.d.ts +0 -6
  27. package/dist/api/session.api.js +0 -45
  28. package/dist/api/types.d.ts +0 -39
  29. package/dist/api/types.js +0 -2
  30. package/dist/api/upload.d.ts +0 -1
  31. package/dist/api/upload.js +0 -18
  32. package/dist/archive/archive.d.ts +0 -4
  33. package/dist/archive/archive.js +0 -64
  34. package/dist/command-utils/common-types.d.ts +0 -20
  35. package/dist/command-utils/common-types.js +0 -2
  36. package/dist/commands/bootstrap/bootstrap.command.d.ts +0 -2
  37. package/dist/commands/bootstrap/bootstrap.command.js +0 -33
  38. package/dist/commands/create-test/create-test.command.d.ts +0 -94
  39. package/dist/commands/create-test/create-test.command.js +0 -170
  40. package/dist/commands/replay/utils/compute-diff.d.ts +0 -13
  41. package/dist/commands/replay/utils/compute-diff.js +0 -95
  42. package/dist/commands/replay/utils/exit-early-if-skip-upload-env-var-set.d.ts +0 -1
  43. package/dist/commands/replay/utils/exit-early-if-skip-upload-env-var-set.js +0 -27
  44. package/dist/commands/screenshot-diff/screenshot-diff.command.d.ts +0 -53
  45. package/dist/commands/screenshot-diff/screenshot-diff.command.js +0 -182
  46. package/dist/commands/screenshot-diff/utils/get-screenshot-filename.d.ts +0 -2
  47. package/dist/commands/screenshot-diff/utils/get-screenshot-filename.js +0 -18
  48. package/dist/commands/screenshot-diff/utils/get-screenshot-identifier.d.ts +0 -2
  49. package/dist/commands/screenshot-diff/utils/get-screenshot-identifier.js +0 -24
  50. package/dist/commands/screenshot-diff/utils/has-notable-differences.d.ts +0 -2
  51. package/dist/commands/screenshot-diff/utils/has-notable-differences.js +0 -10
  52. package/dist/commands/serve/serve.command.d.ts +0 -10
  53. package/dist/commands/serve/serve.command.js +0 -31
  54. package/dist/commands/update-tests/update-tests.command.d.ts +0 -21
  55. package/dist/commands/update-tests/update-tests.command.js +0 -96
  56. package/dist/config/config.d.ts +0 -3
  57. package/dist/config/config.js +0 -70
  58. package/dist/config/config.types.d.ts +0 -16
  59. package/dist/config/config.types.js +0 -2
  60. package/dist/config/snippets.d.ts +0 -1
  61. package/dist/config/snippets.js +0 -18
  62. package/dist/errors/config.d.ts +0 -3
  63. package/dist/errors/config.js +0 -10
  64. package/dist/image/diff.utils.d.ts +0 -19
  65. package/dist/image/diff.utils.js +0 -25
  66. package/dist/image/io.utils.d.ts +0 -3
  67. package/dist/image/io.utils.js +0 -25
  68. package/dist/local-data/local-data.utils.d.ts +0 -20
  69. package/dist/local-data/local-data.utils.js +0 -92
  70. package/dist/local-data/replay-assets.d.ts +0 -3
  71. package/dist/local-data/replay-assets.js +0 -94
  72. package/dist/local-data/replays.d.ts +0 -18
  73. package/dist/local-data/replays.js +0 -87
  74. package/dist/local-data/screenshot-diffs.d.ts +0 -7
  75. package/dist/local-data/screenshot-diffs.js +0 -20
  76. package/dist/local-data/serve-assets-from-simulation.d.ts +0 -5
  77. package/dist/local-data/serve-assets-from-simulation.js +0 -52
  78. package/dist/local-data/sessions.d.ts +0 -10
  79. package/dist/local-data/sessions.js +0 -41
  80. package/dist/parallel-tests/__tests__/merge-test-results.spec.d.ts +0 -1
  81. package/dist/parallel-tests/__tests__/merge-test-results.spec.js +0 -104
  82. package/dist/parallel-tests/__tests__/mock-test-results.d.ts +0 -17
  83. package/dist/parallel-tests/__tests__/mock-test-results.js +0 -106
  84. package/dist/parallel-tests/__tests__/parrallel-tests.handler.spec.d.ts +0 -1
  85. package/dist/parallel-tests/__tests__/parrallel-tests.handler.spec.js +0 -205
  86. package/dist/parallel-tests/execute-test-in-child-process.d.ts +0 -3
  87. package/dist/parallel-tests/execute-test-in-child-process.js +0 -44
  88. package/dist/parallel-tests/merge-test-results.d.ts +0 -12
  89. package/dist/parallel-tests/merge-test-results.js +0 -122
  90. package/dist/parallel-tests/messages.types.d.ts +0 -17
  91. package/dist/parallel-tests/messages.types.js +0 -2
  92. package/dist/parallel-tests/parallel-replay.handler.d.ts +0 -3
  93. package/dist/parallel-tests/parallel-replay.handler.js +0 -57
  94. package/dist/parallel-tests/parallel-replay.types.d.ts +0 -16
  95. package/dist/parallel-tests/parallel-replay.types.js +0 -2
  96. package/dist/parallel-tests/parallel-tests.handler.d.ts +0 -14
  97. package/dist/parallel-tests/parallel-tests.handler.js +0 -194
  98. package/dist/parallel-tests/run-all-tests.d.ts +0 -73
  99. package/dist/parallel-tests/run-all-tests.js +0 -237
  100. package/dist/parallel-tests/run-all-tests.types.d.ts +0 -6
  101. package/dist/parallel-tests/run-all-tests.types.js +0 -2
  102. package/dist/parallel-tests/screenshot-diff-results.utils.d.ts +0 -7
  103. package/dist/parallel-tests/screenshot-diff-results.utils.js +0 -20
  104. package/dist/parallel-tests/task.handler.d.ts +0 -1
  105. package/dist/parallel-tests/task.handler.js +0 -86
  106. package/dist/utils/api-token.utils.d.ts +0 -1
  107. package/dist/utils/api-token.utils.js +0 -31
  108. package/dist/utils/commit-sha.utils.d.ts +0 -1
  109. package/dist/utils/commit-sha.utils.js +0 -42
  110. package/dist/utils/config.utils.d.ts +0 -7
  111. package/dist/utils/config.utils.js +0 -33
  112. package/dist/utils/github-summary.utils.d.ts +0 -5
  113. package/dist/utils/github-summary.utils.js +0 -38
  114. package/dist/utils/run-all-tests.utils.d.ts +0 -16
  115. package/dist/utils/run-all-tests.utils.js +0 -32
  116. package/dist/utils/test-run-environment.utils.d.ts +0 -2
  117. package/dist/utils/test-run-environment.utils.js +0 -25
  118. package/dist/utils/version.utils.d.ts +0 -1
  119. package/dist/utils/version.utils.js +0 -17
@@ -1,35 +1,7 @@
1
- import { TestRunConfigData } from "@alwaysmeticulous/api";
1
+ import { TestCaseResult } from "@alwaysmeticulous/api";
2
2
  import { AxiosInstance } from "axios";
3
- import { TestCaseResult } from "../config/config.types";
4
- import { ScreenshotLocator, TestRun, TestRunStatus } from "./types";
5
- export declare const getTestRun: (options: {
6
- client: AxiosInstance;
7
- testRunId: string;
8
- }) => Promise<TestRun | null>;
9
- export declare const createTestRun: (options: {
10
- client: AxiosInstance;
11
- commitSha: string;
12
- meticulousSha: string;
13
- configData: TestRunConfigData;
14
- }) => Promise<TestRun>;
15
- export declare const putTestRunResults: (options: {
16
- client: AxiosInstance;
17
- testRunId: string;
18
- status: TestRunStatus;
19
- resultData: {
20
- [key: string]: any;
21
- };
22
- }) => Promise<TestRun>;
23
- export declare const getTestRunUrl: (testRun: TestRun) => string;
24
- export interface GetLatestTestRunResultsOptions {
3
+ export interface GetCachedTestRunResultsOptions {
25
4
  client: AxiosInstance;
26
5
  commitSha: string;
27
6
  }
28
- export declare const getCachedTestRunResults: ({ client, commitSha, }: GetLatestTestRunResultsOptions) => Promise<TestCaseResult[]>;
29
- export declare const getLatestTestRunId: (opts: GetLatestTestRunResultsOptions) => Promise<string | null>;
30
- export interface GetBaseScreenshotLocatorsOptions {
31
- client: AxiosInstance;
32
- testRunId: string;
33
- sessionId: string;
34
- }
35
- export declare const getBaseScreenshots: ({ client, testRunId, sessionId, }: GetBaseScreenshotLocatorsOptions) => Promise<ScreenshotLocator[]>;
7
+ export declare const getCachedTestRunResults: ({ client, commitSha, }: GetCachedTestRunResultsOptions) => Promise<TestCaseResult[]>;
@@ -1,73 +1,12 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
4
  };
28
5
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.getBaseScreenshots = exports.getLatestTestRunId = exports.getCachedTestRunResults = exports.getTestRunUrl = exports.putTestRunResults = exports.createTestRun = exports.getTestRun = void 0;
6
+ exports.getCachedTestRunResults = void 0;
7
+ const client_1 = require("@alwaysmeticulous/client");
30
8
  const common_1 = require("@alwaysmeticulous/common");
31
- const axios_1 = __importStar(require("axios"));
32
9
  const loglevel_1 = __importDefault(require("loglevel"));
33
- const getTestRun = async ({ client, testRunId }) => {
34
- const { data } = await client.get(`test-runs/${testRunId}`).catch((error) => {
35
- var _a;
36
- if (axios_1.default.isAxiosError(error)) {
37
- if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
38
- return { data: null };
39
- }
40
- }
41
- throw error;
42
- });
43
- return data;
44
- };
45
- exports.getTestRun = getTestRun;
46
- const createTestRun = async ({ client, commitSha, meticulousSha, configData, }) => {
47
- const { data } = await client.post("test-runs", {
48
- commitSha,
49
- meticulousSha,
50
- configData,
51
- });
52
- return data;
53
- };
54
- exports.createTestRun = createTestRun;
55
- const putTestRunResults = async ({ client, testRunId, status, resultData }) => {
56
- const { data } = await client.put(`test-runs/${testRunId}/results`, {
57
- status,
58
- resultData,
59
- });
60
- return data;
61
- };
62
- exports.putTestRunResults = putTestRunResults;
63
- const getTestRunUrl = (testRun) => {
64
- const { project } = testRun;
65
- const organizationName = encodeURIComponent(project.organization.name);
66
- const projectName = encodeURIComponent(project.name);
67
- const testRunUrl = `https://app.meticulous.ai/projects/${organizationName}/${projectName}/test-runs/${testRun.id}`;
68
- return testRunUrl;
69
- };
70
- exports.getTestRunUrl = getTestRunUrl;
71
10
  const getCachedTestRunResults = async ({ client, commitSha, }) => {
72
11
  var _a, _b, _c;
73
12
  const logger = loglevel_1.default.getLogger(common_1.METICULOUS_LOGGER_NAME);
@@ -75,40 +14,8 @@ const getCachedTestRunResults = async ({ client, commitSha, }) => {
75
14
  logger.warn("Test run cache not supported: no commit hash");
76
15
  return [];
77
16
  }
78
- const results = (_c = (_b = (_a = (await getLatestTestRunResults({ client, commitSha }))) === null || _a === void 0 ? void 0 : _a.resultData) === null || _b === void 0 ? void 0 : _b.results) !== null && _c !== void 0 ? _c : [];
17
+ const results = (_c = (_b = (_a = (await (0, client_1.getLatestTestRunResults)({ client, commitSha }))) === null || _a === void 0 ? void 0 : _a.resultData) === null || _b === void 0 ? void 0 : _b.results) !== null && _c !== void 0 ? _c : [];
79
18
  // Only return passing tests
80
19
  return results.filter(({ result }) => result === "pass");
81
20
  };
82
21
  exports.getCachedTestRunResults = getCachedTestRunResults;
83
- const getLatestTestRunResults = async ({ client, commitSha, }) => {
84
- var _a;
85
- const { data } = await client
86
- .get(`test-runs/cache?commitSha=${encodeURIComponent(commitSha)}`)
87
- .catch((error) => {
88
- var _a;
89
- if (error instanceof axios_1.AxiosError && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
90
- return { data: null };
91
- }
92
- throw error;
93
- });
94
- return (_a = data) !== null && _a !== void 0 ? _a : null;
95
- };
96
- const getLatestTestRunId = async (opts) => {
97
- var _a, _b;
98
- return (_b = (_a = (await getLatestTestRunResults(opts))) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null;
99
- };
100
- exports.getLatestTestRunId = getLatestTestRunId;
101
- const getBaseScreenshots = async ({ client, testRunId, sessionId, }) => {
102
- var _a;
103
- const { data } = await client
104
- .get(`test-runs/${encodeURIComponent(testRunId)}/base-screenshots?sessionId=${encodeURIComponent(sessionId)}`)
105
- .catch((error) => {
106
- var _a;
107
- if (error instanceof axios_1.AxiosError && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
108
- return { data: null };
109
- }
110
- throw error;
111
- });
112
- return (_a = data) !== null && _a !== void 0 ? _a : [];
113
- };
114
- exports.getBaseScreenshots = getBaseScreenshots;
@@ -4,17 +4,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.downloadReplayCommand = void 0;
7
+ const client_1 = require("@alwaysmeticulous/client");
7
8
  const common_1 = require("@alwaysmeticulous/common");
9
+ const downloading_helpers_1 = require("@alwaysmeticulous/downloading-helpers");
8
10
  const loglevel_1 = __importDefault(require("loglevel"));
9
- const client_1 = require("../../api/client");
10
11
  const command_builder_1 = require("../../command-utils/command-builder");
11
- const replays_1 = require("../../local-data/replays");
12
12
  const handler = async ({ apiToken, replayId, }) => {
13
13
  const logger = loglevel_1.default.getLogger(common_1.METICULOUS_LOGGER_NAME);
14
14
  const client = (0, client_1.createClient)({ apiToken });
15
- const { fileName: replayMetadataFileName } = await (0, replays_1.getOrFetchReplay)(client, replayId);
15
+ const { fileName: replayMetadataFileName } = await (0, downloading_helpers_1.getOrFetchReplay)(client, replayId);
16
16
  logger.info(`Downloaded replay metadata to: ${replayMetadataFileName}`);
17
- const { fileName: replayFolderFilePath } = await (0, replays_1.getOrFetchReplayArchive)(client, replayId);
17
+ const { fileName: replayFolderFilePath } = await (0, downloading_helpers_1.getOrFetchReplayArchive)(client, replayId);
18
18
  logger.info(`Downloaded replay data to: ${replayFolderFilePath}`);
19
19
  };
20
20
  exports.downloadReplayCommand = (0, command_builder_1.buildCommand)("download-simulation")
@@ -4,17 +4,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.downloadSessionCommand = void 0;
7
+ const client_1 = require("@alwaysmeticulous/client");
7
8
  const common_1 = require("@alwaysmeticulous/common");
9
+ const downloading_helpers_1 = require("@alwaysmeticulous/downloading-helpers");
8
10
  const loglevel_1 = __importDefault(require("loglevel"));
9
- const client_1 = require("../../api/client");
10
11
  const command_builder_1 = require("../../command-utils/command-builder");
11
- const sessions_1 = require("../../local-data/sessions");
12
12
  const handler = async ({ apiToken, sessionId, }) => {
13
13
  const logger = loglevel_1.default.getLogger(common_1.METICULOUS_LOGGER_NAME);
14
14
  const client = (0, client_1.createClient)({ apiToken });
15
- const { fileName: sessionMetadataFileName } = await (0, sessions_1.getOrFetchRecordedSession)(client, sessionId);
15
+ const { fileName: sessionMetadataFileName } = await (0, downloading_helpers_1.getOrFetchRecordedSession)(client, sessionId);
16
16
  logger.info(`Downloaded session metadata to: ${sessionMetadataFileName}`);
17
- const { fileName: sessionFileName } = await (0, sessions_1.getOrFetchRecordedSessionData)(client, sessionId);
17
+ const { fileName: sessionFileName } = await (0, downloading_helpers_1.getOrFetchRecordedSessionData)(client, sessionId);
18
18
  logger.info(`Downloaded session data to: ${sessionFileName}`);
19
19
  };
20
20
  exports.downloadSessionCommand = (0, command_builder_1.buildCommand)("download-session")
@@ -5,14 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.recordCommand = exports.recordCommandHandler = void 0;
7
7
  const path_1 = require("path");
8
+ const client_1 = require("@alwaysmeticulous/client");
8
9
  const common_1 = require("@alwaysmeticulous/common");
10
+ const downloading_helpers_1 = require("@alwaysmeticulous/downloading-helpers");
9
11
  const loglevel_1 = __importDefault(require("loglevel"));
10
- const client_1 = require("../../api/client");
11
- const project_api_1 = require("../../api/project.api");
12
- const session_api_1 = require("../../api/session.api");
13
12
  const command_builder_1 = require("../../command-utils/command-builder");
14
- const replay_assets_1 = require("../../local-data/replay-assets");
15
- const commit_sha_utils_1 = require("../../utils/commit-sha.utils");
16
13
  const recordCommandHandler = async ({ apiToken, commitSha: commitSha_, devTools, bypassCSP, width, height, uploadIntervalMs, incognito, trace, onDetectedSession: onDetectedSession_, }) => {
17
14
  const logger = loglevel_1.default.getLogger(common_1.METICULOUS_LOGGER_NAME);
18
15
  const debugLogger = trace ? await common_1.DebugLogger.create() : null;
@@ -30,7 +27,7 @@ const recordCommandHandler = async ({ apiToken, commitSha: commitSha_, devTools,
30
27
  logger.info("Preparing recording...");
31
28
  // 1. Fetch the recording token
32
29
  const client = (0, client_1.createClient)({ apiToken });
33
- const project = await (0, project_api_1.getProject)(client);
30
+ const project = await (0, client_1.getProject)(client);
34
31
  if (!project) {
35
32
  logger.error("Could not retrieve project data. Is the API token correct?");
36
33
  debugLogger === null || debugLogger === void 0 ? void 0 : debugLogger.log("Could not retrieve project data. Is the API token correct?");
@@ -44,11 +41,11 @@ const recordCommandHandler = async ({ apiToken, commitSha: commitSha_, devTools,
44
41
  }
45
42
  logger.debug(`Recording token: ${recordingToken}`);
46
43
  // 2. Guess commit SHA1
47
- const commitSha = (await (0, commit_sha_utils_1.getCommitSha)(commitSha_)) || "unknown";
44
+ const commitSha = (await (0, common_1.getCommitSha)(commitSha_)) || "unknown";
48
45
  logger.debug(`Commit: ${commitSha}`);
49
46
  // 3. Load recording snippets
50
- const recordingSnippet = await (0, replay_assets_1.fetchAsset)("v1/stagingMeticulousSnippet.js");
51
- const earlyNetworkRecorderSnippet = await (0, replay_assets_1.fetchAsset)("record/v1/network-recorder.bundle.js");
47
+ const recordingSnippet = await (0, downloading_helpers_1.fetchAsset)("v1/stagingMeticulousSnippet.js");
48
+ const earlyNetworkRecorderSnippet = await (0, downloading_helpers_1.fetchAsset)("record/v1/network-recorder.bundle.js");
52
49
  // 4. Load recording package
53
50
  let recordSession;
54
51
  try {
@@ -64,13 +61,13 @@ const recordCommandHandler = async ({ apiToken, commitSha: commitSha_, devTools,
64
61
  }
65
62
  const cookieDir = (0, path_1.join)((0, common_1.getMeticulousLocalDataDir)(), "cookies");
66
63
  // Report recording start
67
- const recordingCommandId = await (0, session_api_1.getRecordingCommandId)(client);
64
+ const recordingCommandId = await (0, client_1.getRecordingCommandId)(client);
68
65
  // 5. Start recording
69
66
  const onDetectedSession = (sessionId) => {
70
67
  if (onDetectedSession_) {
71
68
  onDetectedSession_(sessionId);
72
69
  }
73
- (0, session_api_1.postSessionIdNotification)(client, sessionId, recordingCommandId).catch((error) => {
70
+ (0, client_1.postSessionIdNotification)(client, sessionId, recordingCommandId).catch((error) => {
74
71
  logger.error(`Warning: error while notifying session recording ${sessionId}`);
75
72
  logger.error(error);
76
73
  debugLogger === null || debugLogger === void 0 ? void 0 : debugLogger.log(`Warning: error while notifying session recording ${sessionId}`);
@@ -1,29 +1,17 @@
1
1
  /// <reference types="yargs" />
2
- import { ScreenshotDiffResult } from "@alwaysmeticulous/api";
3
- import { GeneratedBy, Replay, ReplayEventsDependencies, ReplayExecutionOptions, ReplayTarget } from "@alwaysmeticulous/common";
4
- import { ScreenshotAssertionsOptions, ScreenshotDiffOptions } from "../../command-utils/common-types";
5
- export interface ReplayOptions extends AdditionalReplayOptions {
6
- replayTarget: ReplayTarget;
7
- executionOptions: ReplayExecutionOptions;
8
- screenshottingOptions: ScreenshotAssertionsOptions;
9
- generatedBy: GeneratedBy;
10
- testRunId: string | null;
11
- replayEventsDependencies: ReplayEventsDependencies;
12
- suppressScreenshotDiffLogging: boolean;
13
- }
14
- export interface ReplayResult {
2
+ import { ScreenshotDiffResult, Replay, ScreenshotDiffOptions } from "@alwaysmeticulous/api";
3
+ import { ReplayExecutionOptions, ReplayTarget } from "@alwaysmeticulous/sdk-bundles-api";
4
+ export interface ReplayAndStoreResultsResult {
15
5
  replay: Replay;
16
6
  /**
17
7
  * Empty if screenshottingOptions.enabled was false.
18
8
  */
19
9
  screenshotDiffResultsByBaseReplayId: Record<string, ScreenshotDiffResult[]>;
20
10
  }
21
- export declare const replayCommandHandler: ({ replayTarget, executionOptions, screenshottingOptions, apiToken, sessionId, commitSha: commitSha_, baseTestRunId, cookiesFile, generatedBy, testRunId, replayEventsDependencies, debugger: enableStepThroughDebugger, suppressScreenshotDiffLogging, }: ReplayOptions) => Promise<ReplayResult>;
22
11
  export interface RawReplayCommandHandlerOptions extends ScreenshotDiffOptions, Omit<ReplayExecutionOptions, "maxDurationMs" | "maxEventCount">, Omit<AdditionalReplayOptions, "baseTestRunId"> {
23
12
  screenshot: boolean;
24
13
  appUrl: string | null | undefined;
25
14
  simulationIdForAssets: string | null | undefined;
26
- screenshotSelector: string | null | undefined;
27
15
  maxDurationMs: number | null | undefined;
28
16
  maxEventCount: number | null | undefined;
29
17
  storyboard: boolean;
@@ -36,7 +24,7 @@ interface AdditionalReplayOptions {
36
24
  cookiesFile: string | null | undefined;
37
25
  debugger: boolean;
38
26
  }
39
- export declare const rawReplayCommandHandler: ({ apiToken, commitSha, sessionId, appUrl, simulationIdForAssets, headless, devTools, bypassCSP, screenshot, screenshotSelector, diffThreshold, diffPixelThreshold, shiftTime, networkStubbing, moveBeforeClick, cookiesFile, disableRemoteFonts, noSandbox, skipPauses, maxDurationMs, maxEventCount, storyboard, essentialFeaturesOnly, debugger: enableStepThroughDebugger, }: RawReplayCommandHandlerOptions) => Promise<Replay>;
27
+ export declare const rawReplayCommandHandler: ({ apiToken, commitSha, sessionId, appUrl, simulationIdForAssets, headless, devTools, bypassCSP, screenshot, diffThreshold, diffPixelThreshold, shiftTime, networkStubbing, moveBeforeClick, cookiesFile, disableRemoteFonts, noSandbox, skipPauses, maxDurationMs, maxEventCount, storyboard, essentialFeaturesOnly, debugger: enableStepThroughDebugger, }: RawReplayCommandHandlerOptions) => Promise<Replay>;
40
28
  export declare const getReplayTarget: ({ appUrl, simulationIdForAssets, }: {
41
29
  appUrl: string | null;
42
30
  simulationIdForAssets: string | null;
@@ -134,10 +122,6 @@ export declare const replayCommand: import("yargs").CommandModule<unknown, impor
134
122
  description: string;
135
123
  default: boolean;
136
124
  };
137
- screenshotSelector: {
138
- string: true;
139
- description: string;
140
- };
141
125
  debugger: {
142
126
  boolean: true;
143
127
  description: string;
@@ -1,238 +1,10 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
2
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.replayCommand = exports.getReplayTarget = exports.rawReplayCommandHandler = exports.replayCommandHandler = void 0;
30
- const promises_1 = require("fs/promises");
31
- const path_1 = require("path");
32
- const common_1 = require("@alwaysmeticulous/common");
33
- const Sentry = __importStar(require("@sentry/node"));
34
- const loglevel_1 = __importDefault(require("loglevel"));
35
- const luxon_1 = require("luxon");
36
- const client_1 = require("../../api/client");
37
- const replay_api_1 = require("../../api/replay.api");
38
- const upload_1 = require("../../api/upload");
39
- const archive_1 = require("../../archive/archive");
3
+ exports.replayCommand = exports.getReplayTarget = exports.rawReplayCommandHandler = void 0;
4
+ const replay_orchestrator_1 = require("@alwaysmeticulous/replay-orchestrator");
40
5
  const command_builder_1 = require("../../command-utils/command-builder");
41
6
  const common_options_1 = require("../../command-utils/common-options");
42
- const local_data_utils_1 = require("../../local-data/local-data.utils");
43
- const replay_assets_1 = require("../../local-data/replay-assets");
44
- const serve_assets_from_simulation_1 = require("../../local-data/serve-assets-from-simulation");
45
- const sessions_1 = require("../../local-data/sessions");
46
- const commit_sha_utils_1 = require("../../utils/commit-sha.utils");
47
- const version_utils_1 = require("../../utils/version.utils");
48
- const compute_diff_1 = require("./utils/compute-diff");
49
- const exit_early_if_skip_upload_env_var_set_1 = require("./utils/exit-early-if-skip-upload-env-var-set");
50
- const replayCommandHandler = async ({ replayTarget, executionOptions, screenshottingOptions, apiToken, sessionId, commitSha: commitSha_, baseTestRunId, cookiesFile, generatedBy, testRunId, replayEventsDependencies, debugger: enableStepThroughDebugger, suppressScreenshotDiffLogging, }) => {
51
- var _a;
52
- if (executionOptions.headless === true &&
53
- enableStepThroughDebugger === true) {
54
- throw new Error("Cannot run with both --debugger flag and --headless flag at the same time.");
55
- }
56
- const rootTransaction = (_a = Sentry.getCurrentHub().getScope()) === null || _a === void 0 ? void 0 : _a.getTransaction();
57
- const handlerSpanContext = {
58
- name: "replay.command_handler",
59
- description: "Handle the replay command",
60
- op: "replay.command_handler",
61
- };
62
- let transaction;
63
- if (rootTransaction) {
64
- transaction = rootTransaction.startChild(handlerSpanContext);
65
- }
66
- else {
67
- transaction = Sentry.startTransaction(handlerSpanContext);
68
- }
69
- Sentry.getCurrentHub().configureScope((scope) => scope.setSpan(transaction));
70
- const logger = loglevel_1.default.getLogger(common_1.METICULOUS_LOGGER_NAME);
71
- const client = (0, client_1.createClient)({ apiToken });
72
- // 1. Check session files
73
- const fetchSessions = transaction.startChild({ op: "fetchingSessions" });
74
- const { data: session } = await (0, sessions_1.getOrFetchRecordedSession)(client, sessionId);
75
- const { data: sessionData } = await (0, sessions_1.getOrFetchRecordedSessionData)(client, sessionId);
76
- fetchSessions.finish();
77
- // 2. Guess commit SHA1
78
- const commitSha = (await (0, commit_sha_utils_1.getCommitSha)(commitSha_)) || "unknown";
79
- logger.debug(`Commit: ${commitSha}`);
80
- const meticulousSha = await (0, version_utils_1.getMeticulousVersion)();
81
- // 3. If simulationIdForAssets specified then download assets & spin up local server
82
- const serveOrGetAppUrlSpan = transaction.startChild({
83
- op: "serveOrGetAppUrl",
84
- });
85
- const { appUrl, closeServer } = await serveOrGetAppUrl(client, replayTarget);
86
- serveOrGetAppUrlSpan.finish();
87
- // 4. Load replay package
88
- let replayEvents;
89
- try {
90
- logger.debug("Loading replayer package...");
91
- const replayer = await require("@alwaysmeticulous/replayer");
92
- replayEvents = replayer.replayEvents;
93
- }
94
- catch (error) {
95
- logger.error("Error: could not import @alwaysmeticulous/replayer");
96
- logger.error(error);
97
- process.exit(1);
98
- }
99
- // Report replay start
100
- logger.debug("Reporting replay started...");
101
- const replayCommandId = await (0, replay_api_1.getReplayCommandId)(client, sessionId);
102
- // 5. Create replay directory
103
- logger.debug("Creating directory to store replay output...");
104
- await (0, promises_1.mkdir)((0, path_1.join)((0, common_1.getMeticulousLocalDataDir)(), "replays"), {
105
- recursive: true,
106
- });
107
- const tempDirName = (0, local_data_utils_1.sanitizeFilename)(`${new Date().toISOString()}-`);
108
- const tempDir = await (0, promises_1.mkdtemp)((0, path_1.join)((0, common_1.getMeticulousLocalDataDir)(), "replays", tempDirName));
109
- // 6. Create and save replay parameters
110
- logger.debug("Snapshotting replay parameters...");
111
- const replayEventsParams = {
112
- appUrl: appUrl !== null && appUrl !== void 0 ? appUrl : null,
113
- replayExecutionOptions: executionOptions,
114
- browser: null,
115
- outputDir: tempDir,
116
- session,
117
- recordingId: "manual-replay",
118
- meticulousSha: "meticulousSha",
119
- generatedBy,
120
- testRunId,
121
- dependencies: replayEventsDependencies,
122
- enableStepThroughDebugger,
123
- screenshottingOptions,
124
- cookiesFile: cookiesFile !== null && cookiesFile !== void 0 ? cookiesFile : null,
125
- };
126
- await (0, promises_1.writeFile)((0, path_1.join)(tempDir, "replayEventsParams.json"), JSON.stringify(replayEventsParams));
127
- // 7. Perform replay
128
- logger.debug("Beggining replay...");
129
- const startTime = luxon_1.DateTime.utc();
130
- await replayEvents({
131
- ...replayEventsParams,
132
- sessionData,
133
- parentPerformanceSpan: transaction.startChild({ op: "replayEvents" }),
134
- });
135
- closeServer === null || closeServer === void 0 ? void 0 : closeServer();
136
- const endTime = luxon_1.DateTime.utc();
137
- logger.info(`Simulation time: ${endTime.diff(startTime).as("seconds")} seconds`);
138
- (0, exit_early_if_skip_upload_env_var_set_1.exitEarlyIfSkipUploadEnvVarSet)(baseTestRunId);
139
- logger.info("Sending simulation results to Meticulous");
140
- // 8. Create a Zip archive containing the replay files
141
- const createReplayArchiveSpan = transaction.startChild({
142
- op: "createArchiveAndUpload",
143
- });
144
- const archivePath = await (0, archive_1.createReplayArchive)(tempDir);
145
- createReplayArchiveSpan.finish();
146
- try {
147
- // 9. Get upload URL
148
- const getReplayPushUrlSpan = transaction.startChild({
149
- op: "getReplayPushUrl",
150
- });
151
- const replay = await (0, replay_api_1.createReplay)({
152
- client,
153
- commitSha,
154
- sessionId,
155
- meticulousSha,
156
- version: "v2",
157
- metadata: { generatedBy },
158
- });
159
- const uploadUrlData = await (0, replay_api_1.getReplayPushUrl)(client, replay.id);
160
- if (!uploadUrlData) {
161
- logger.error("Error: Could not get a push URL from the Meticulous API");
162
- process.exit(1);
163
- }
164
- const uploadUrl = uploadUrlData.pushUrl;
165
- getReplayPushUrlSpan.finish();
166
- // 10. Send archive to S3
167
- const uploadArchiveSpan = transaction.startChild({ op: "uploadArchive" });
168
- try {
169
- await (0, upload_1.uploadArchive)(uploadUrl, archivePath);
170
- }
171
- catch (error) {
172
- await (0, replay_api_1.putReplayPushedStatus)(client, replay.id, "failure", replayCommandId).catch(logger.error);
173
- logger.error(error);
174
- process.exit(1);
175
- }
176
- uploadArchiveSpan.finish();
177
- // 11. Report successful upload to Meticulous
178
- const updatedProjectBuild = await (0, replay_api_1.putReplayPushedStatus)(client, replay.id, "success", replayCommandId);
179
- logger.info("Simulation artifacts successfully sent to Meticulous");
180
- logger.debug(updatedProjectBuild);
181
- const replayUrl = (0, replay_api_1.getReplayUrl)(replay);
182
- logger.info("=======");
183
- logger.info(`View simulation at: ${replayUrl}`);
184
- logger.info("=======");
185
- // 12. Diff against base replay screenshot if one is provided
186
- const computeDiffSpan = transaction.startChild({
187
- op: "computeDiff",
188
- });
189
- const computeDiffsLogger = loglevel_1.default.getLogger(`METICULOUS_LOGGER_NAME/compute-diffs`);
190
- if (suppressScreenshotDiffLogging) {
191
- computeDiffsLogger.setLevel("ERROR", false);
192
- }
193
- else {
194
- computeDiffsLogger.setLevel(logger.getLevel(), false);
195
- }
196
- const screenshotDiffResultsByBaseReplayId = screenshottingOptions.enabled && baseTestRunId
197
- ? await (0, compute_diff_1.computeDiff)({
198
- client,
199
- baseTestRunId,
200
- sessionId,
201
- headReplayId: replay.id,
202
- tempDir,
203
- screenshottingOptions,
204
- logger: computeDiffsLogger,
205
- })
206
- : {};
207
- computeDiffSpan.finish();
208
- return { replay, screenshotDiffResultsByBaseReplayId };
209
- }
210
- finally {
211
- await (0, archive_1.deleteArchive)(archivePath);
212
- transaction.finish();
213
- }
214
- };
215
- exports.replayCommandHandler = replayCommandHandler;
216
- const serveOrGetAppUrl = async (client, replayTarget) => {
217
- if (replayTarget.type === "snapshotted-assets") {
218
- const server = await (0, serve_assets_from_simulation_1.serveAssetsFromSimulation)(client, replayTarget.simulationIdForAssets);
219
- return {
220
- appUrl: server.url,
221
- closeServer: server.closeServer,
222
- };
223
- }
224
- if (replayTarget.type === "url") {
225
- return { appUrl: replayTarget.appUrl };
226
- }
227
- if (replayTarget.type === "original-recorded-url") {
228
- return {};
229
- }
230
- return unknownReplayTargetType(replayTarget);
231
- };
232
- const unknownReplayTargetType = (replayTarget) => {
233
- throw new Error(`Unknown type of replay target: ${JSON.stringify(replayTarget)}`);
234
- };
235
- const rawReplayCommandHandler = async ({ apiToken, commitSha, sessionId, appUrl, simulationIdForAssets, headless, devTools, bypassCSP, screenshot, screenshotSelector, diffThreshold, diffPixelThreshold, shiftTime, networkStubbing, moveBeforeClick, cookiesFile, disableRemoteFonts, noSandbox, skipPauses, maxDurationMs, maxEventCount, storyboard, essentialFeaturesOnly, debugger: enableStepThroughDebugger, }) => {
7
+ const rawReplayCommandHandler = async ({ apiToken, commitSha, sessionId, appUrl, simulationIdForAssets, headless, devTools, bypassCSP, screenshot, diffThreshold, diffPixelThreshold, shiftTime, networkStubbing, moveBeforeClick, cookiesFile, disableRemoteFonts, noSandbox, skipPauses, maxDurationMs, maxEventCount, storyboard, essentialFeaturesOnly, debugger: enableStepThroughDebugger, }) => {
236
8
  const executionOptions = {
237
9
  headless,
238
10
  devTools,
@@ -254,13 +26,11 @@ const rawReplayCommandHandler = async ({ apiToken, commitSha, sessionId, appUrl,
254
26
  const screenshottingOptions = screenshot
255
27
  ? {
256
28
  enabled: true,
257
- screenshotSelector: screenshotSelector !== null && screenshotSelector !== void 0 ? screenshotSelector : null,
258
29
  diffOptions: { diffPixelThreshold, diffThreshold },
259
30
  storyboardOptions,
260
31
  }
261
32
  : { enabled: false };
262
- const replayEventsDependencies = await (0, replay_assets_1.loadReplayEventsDependencies)();
263
- const { replay } = await (0, exports.replayCommandHandler)({
33
+ const { replay } = await (0, replay_orchestrator_1.replayAndStoreResults)({
264
34
  replayTarget: (0, exports.getReplayTarget)({
265
35
  appUrl: appUrl !== null && appUrl !== void 0 ? appUrl : null,
266
36
  simulationIdForAssets: simulationIdForAssets !== null && simulationIdForAssets !== void 0 ? simulationIdForAssets : null,
@@ -274,7 +44,6 @@ const rawReplayCommandHandler = async ({ apiToken, commitSha, sessionId, appUrl,
274
44
  generatedBy: generatedByOption,
275
45
  baseTestRunId: null,
276
46
  testRunId: null,
277
- replayEventsDependencies,
278
47
  debugger: enableStepThroughDebugger,
279
48
  suppressScreenshotDiffLogging: false,
280
49
  });
@@ -317,10 +86,6 @@ exports.replayCommand = (0, command_builder_1.buildCommand)("simulate")
317
86
  description: "Take a screenshot at the end of simulation",
318
87
  default: true,
319
88
  },
320
- screenshotSelector: {
321
- string: true,
322
- description: "Query selector to screenshot a specific DOM element instead of the whole page",
323
- },
324
89
  debugger: {
325
90
  boolean: true,
326
91
  description: "Opens a step through debugger to advance through the replay event by event",
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.runAllTestsCommand = void 0;
4
- const client_1 = require("../../api/client");
4
+ const client_1 = require("@alwaysmeticulous/client");
5
+ const common_1 = require("@alwaysmeticulous/common");
6
+ const replay_orchestrator_1 = require("@alwaysmeticulous/replay-orchestrator");
5
7
  const test_run_api_1 = require("../../api/test-run.api");
6
8
  const command_builder_1 = require("../../command-utils/command-builder");
7
9
  const common_options_1 = require("../../command-utils/common-options");
8
- const run_all_tests_1 = require("../../parallel-tests/run-all-tests");
9
- const commit_sha_utils_1 = require("../../utils/commit-sha.utils");
10
10
  const handler = async ({ apiToken, commitSha: commitSha_, baseCommitSha, appUrl, headless, devTools, bypassCSP, diffThreshold, diffPixelThreshold, shiftTime, networkStubbing, githubSummary, parallelize, parallelTasks: parrelelTasks_, maxRetriesOnFailure, rerunTestsNTimes, useCache, testsFile, disableRemoteFonts, noSandbox, skipPauses, moveBeforeClick, maxDurationMs, maxEventCount, storyboard, essentialFeaturesOnly, baseTestRunId, }) => {
11
11
  const executionOptions = {
12
12
  headless,
@@ -27,17 +27,16 @@ const handler = async ({ apiToken, commitSha: commitSha_, baseCommitSha, appUrl,
27
27
  : { enabled: false };
28
28
  const screenshottingOptions = {
29
29
  enabled: true,
30
- screenshotSelector: null,
31
30
  diffOptions: { diffPixelThreshold, diffThreshold },
32
31
  storyboardOptions,
33
32
  };
34
33
  const parrelelTasks = parallelize ? parrelelTasks_ : 1;
35
- const commitSha = (await (0, commit_sha_utils_1.getCommitSha)(commitSha_)) || "unknown";
34
+ const commitSha = (await (0, common_1.getCommitSha)(commitSha_)) || "unknown";
36
35
  const client = (0, client_1.createClient)({ apiToken });
37
36
  const cachedTestRunResults = useCache
38
37
  ? await (0, test_run_api_1.getCachedTestRunResults)({ client, commitSha })
39
38
  : [];
40
- const { testRun } = await (0, run_all_tests_1.runAllTests)({
39
+ const { testRun } = await (0, replay_orchestrator_1.executeTestRun)({
41
40
  testsFile: testsFile !== null && testsFile !== void 0 ? testsFile : null,
42
41
  executionOptions,
43
42
  screenshottingOptions,
@@ -4,15 +4,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.showProjectCommand = void 0;
7
+ const client_1 = require("@alwaysmeticulous/client");
7
8
  const common_1 = require("@alwaysmeticulous/common");
8
9
  const loglevel_1 = __importDefault(require("loglevel"));
9
- const client_1 = require("../../api/client");
10
- const project_api_1 = require("../../api/project.api");
11
10
  const command_builder_1 = require("../../command-utils/command-builder");
12
11
  const handler = async ({ apiToken }) => {
13
12
  const logger = loglevel_1.default.getLogger(common_1.METICULOUS_LOGGER_NAME);
14
13
  const client = (0, client_1.createClient)({ apiToken });
15
- const project = await (0, project_api_1.getProject)(client);
14
+ const project = await (0, client_1.getProject)(client);
16
15
  if (!project) {
17
16
  logger.error("Could not retrieve project data. Is the API token correct?");
18
17
  process.exit(1);