@alwaysmeticulous/cli 2.39.0 → 2.40.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/dist/commands/create-test/create-test.command.d.ts +0 -4
- package/dist/commands/create-test/create-test.command.js +1 -6
- package/dist/commands/replay/replay.command.d.ts +1 -6
- package/dist/commands/replay/replay.command.js +1 -6
- package/dist/commands/run-all-tests/run-all-tests.command.js +0 -1
- package/dist/commands/screenshot-diff/utils/__tests__/get-screenshot-identifier.spec.d.ts +1 -0
- package/dist/commands/screenshot-diff/utils/__tests__/get-screenshot-identifier.spec.js +25 -0
- package/dist/commands/screenshot-diff/utils/get-screenshot-filename.js +6 -2
- package/dist/commands/screenshot-diff/utils/get-screenshot-identifier.js +16 -1
- package/dist/config/config.js +1 -2
- package/dist/parallel-tests/merge-test-results.js +1 -17
- package/dist/parallel-tests/parallel-replay.handler.js +1 -2
- package/package.json +4 -4
|
@@ -78,10 +78,6 @@ export declare const createTestCommand: import("yargs").CommandModule<unknown, i
|
|
|
78
78
|
boolean: true;
|
|
79
79
|
description: string;
|
|
80
80
|
};
|
|
81
|
-
screenshotSelector: {
|
|
82
|
-
string: true;
|
|
83
|
-
description: string;
|
|
84
|
-
};
|
|
85
81
|
moveBeforeClick: {
|
|
86
82
|
readonly boolean: true;
|
|
87
83
|
readonly description: "Simulate mouse movement before clicking";
|
|
@@ -59,7 +59,7 @@ apiToken, commitSha, devTools, bypassCSP,
|
|
|
59
59
|
// Record options
|
|
60
60
|
width, height, uploadIntervalMs, incognito, trace,
|
|
61
61
|
// Replay options
|
|
62
|
-
headless,
|
|
62
|
+
headless, shiftTime, networkStubbing, moveBeforeClick, cookiesFile, disableRemoteFonts, noSandbox, skipPauses, }) => {
|
|
63
63
|
const logger = loglevel_1.default.getLogger(common_1.METICULOUS_LOGGER_NAME);
|
|
64
64
|
logger.info("Creating a new Meticulous test");
|
|
65
65
|
logger.info("Step 1: record a new test");
|
|
@@ -95,7 +95,6 @@ headless, screenshotSelector, shiftTime, networkStubbing, moveBeforeClick, cooki
|
|
|
95
95
|
devTools,
|
|
96
96
|
bypassCSP,
|
|
97
97
|
screenshot: true,
|
|
98
|
-
screenshotSelector,
|
|
99
98
|
shiftTime,
|
|
100
99
|
disableRemoteFonts,
|
|
101
100
|
noSandbox,
|
|
@@ -148,10 +147,6 @@ exports.createTestCommand = (0, command_builder_1.buildCommand)("create-test")
|
|
|
148
147
|
description: "Enable verbose logging",
|
|
149
148
|
},
|
|
150
149
|
// Replay options
|
|
151
|
-
screenshotSelector: {
|
|
152
|
-
string: true,
|
|
153
|
-
description: "Query selector to screenshot a specific DOM element instead of the whole page",
|
|
154
|
-
},
|
|
155
150
|
moveBeforeClick: common_options_1.OPTIONS.moveBeforeClick,
|
|
156
151
|
cookiesFile: {
|
|
157
152
|
string: true,
|
|
@@ -23,7 +23,6 @@ export interface RawReplayCommandHandlerOptions extends ScreenshotDiffOptions, O
|
|
|
23
23
|
screenshot: boolean;
|
|
24
24
|
appUrl: string | null | undefined;
|
|
25
25
|
simulationIdForAssets: string | null | undefined;
|
|
26
|
-
screenshotSelector: string | null | undefined;
|
|
27
26
|
maxDurationMs: number | null | undefined;
|
|
28
27
|
maxEventCount: number | null | undefined;
|
|
29
28
|
storyboard: boolean;
|
|
@@ -36,7 +35,7 @@ interface AdditionalReplayOptions {
|
|
|
36
35
|
cookiesFile: string | null | undefined;
|
|
37
36
|
debugger: boolean;
|
|
38
37
|
}
|
|
39
|
-
export declare const rawReplayCommandHandler: ({ apiToken, commitSha, sessionId, appUrl, simulationIdForAssets, headless, devTools, bypassCSP, screenshot,
|
|
38
|
+
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
39
|
export declare const getReplayTarget: ({ appUrl, simulationIdForAssets, }: {
|
|
41
40
|
appUrl: string | null;
|
|
42
41
|
simulationIdForAssets: string | null;
|
|
@@ -134,10 +133,6 @@ export declare const replayCommand: import("yargs").CommandModule<unknown, impor
|
|
|
134
133
|
description: string;
|
|
135
134
|
default: boolean;
|
|
136
135
|
};
|
|
137
|
-
screenshotSelector: {
|
|
138
|
-
string: true;
|
|
139
|
-
description: string;
|
|
140
|
-
};
|
|
141
136
|
debugger: {
|
|
142
137
|
boolean: true;
|
|
143
138
|
description: string;
|
|
@@ -232,7 +232,7 @@ const serveOrGetAppUrl = async (client, replayTarget) => {
|
|
|
232
232
|
const unknownReplayTargetType = (replayTarget) => {
|
|
233
233
|
throw new Error(`Unknown type of replay target: ${JSON.stringify(replayTarget)}`);
|
|
234
234
|
};
|
|
235
|
-
const rawReplayCommandHandler = async ({ apiToken, commitSha, sessionId, appUrl, simulationIdForAssets, headless, devTools, bypassCSP, screenshot,
|
|
235
|
+
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
236
|
const executionOptions = {
|
|
237
237
|
headless,
|
|
238
238
|
devTools,
|
|
@@ -254,7 +254,6 @@ const rawReplayCommandHandler = async ({ apiToken, commitSha, sessionId, appUrl,
|
|
|
254
254
|
const screenshottingOptions = screenshot
|
|
255
255
|
? {
|
|
256
256
|
enabled: true,
|
|
257
|
-
screenshotSelector: screenshotSelector !== null && screenshotSelector !== void 0 ? screenshotSelector : null,
|
|
258
257
|
diffOptions: { diffPixelThreshold, diffThreshold },
|
|
259
258
|
storyboardOptions,
|
|
260
259
|
}
|
|
@@ -317,10 +316,6 @@ exports.replayCommand = (0, command_builder_1.buildCommand)("simulate")
|
|
|
317
316
|
description: "Take a screenshot at the end of simulation",
|
|
318
317
|
default: true,
|
|
319
318
|
},
|
|
320
|
-
screenshotSelector: {
|
|
321
|
-
string: true,
|
|
322
|
-
description: "Query selector to screenshot a specific DOM element instead of the whole page",
|
|
323
|
-
},
|
|
324
319
|
debugger: {
|
|
325
320
|
boolean: true,
|
|
326
321
|
description: "Opens a step through debugger to advance through the replay event by event",
|
|
@@ -27,7 +27,6 @@ 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
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const get_screenshot_identifier_1 = require("../get-screenshot-identifier");
|
|
4
|
+
describe("get-screenshot-identifier", () => {
|
|
5
|
+
it("can parse identifiers without version numbers", () => {
|
|
6
|
+
expect((0, get_screenshot_identifier_1.getScreenshotIdentifier)("final-state.png")).toEqual({
|
|
7
|
+
type: "end-state",
|
|
8
|
+
});
|
|
9
|
+
expect((0, get_screenshot_identifier_1.getScreenshotIdentifier)("screenshot-after-event-7.png")).toEqual({
|
|
10
|
+
type: "after-event",
|
|
11
|
+
eventNumber: 7,
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
it("can parse identifiers with version numbers", () => {
|
|
15
|
+
expect((0, get_screenshot_identifier_1.getScreenshotIdentifier)("final-state-v2.png")).toEqual({
|
|
16
|
+
type: "end-state",
|
|
17
|
+
logicVersion: 2,
|
|
18
|
+
});
|
|
19
|
+
expect((0, get_screenshot_identifier_1.getScreenshotIdentifier)("screenshot-after-event-7-v2.png")).toEqual({
|
|
20
|
+
type: "after-event",
|
|
21
|
+
eventNumber: 7,
|
|
22
|
+
logicVersion: 2,
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -5,11 +5,15 @@ exports.getScreenshotFilename = void 0;
|
|
|
5
5
|
// in replay-node, and in https://github.com/alwaysmeticulous/meticulous-sdk/blob/395af4394dc51d9b51ba1136fc26b23fcbba5604/packages/replayer/src/screenshot.utils.ts#L42
|
|
6
6
|
const getScreenshotFilename = (identifier) => {
|
|
7
7
|
if (identifier.type === "end-state") {
|
|
8
|
-
return
|
|
8
|
+
return identifier.logicVersion == null
|
|
9
|
+
? "final-state.png"
|
|
10
|
+
: `final-state-v${identifier.logicVersion}.png`;
|
|
9
11
|
}
|
|
10
12
|
else if (identifier.type === "after-event") {
|
|
11
13
|
const eventIndexStr = identifier.eventNumber.toString().padStart(5, "0");
|
|
12
|
-
return
|
|
14
|
+
return identifier.logicVersion == null
|
|
15
|
+
? `screenshot-after-event-${eventIndexStr}.png`
|
|
16
|
+
: `screenshot-after-event-${eventIndexStr}-v${identifier.logicVersion}.png`;
|
|
13
17
|
}
|
|
14
18
|
else {
|
|
15
19
|
throw new Error("Unexpected screenshot identifier: " + JSON.stringify(identifier));
|
|
@@ -3,19 +3,34 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getScreenshotIdentifier = void 0;
|
|
4
4
|
const path_1 = require("path");
|
|
5
5
|
const getScreenshotIdentifier = (filename) => {
|
|
6
|
+
var _a;
|
|
6
7
|
const name = (0, path_1.basename)(filename);
|
|
7
8
|
if (name === "final-state.png") {
|
|
8
9
|
return {
|
|
9
10
|
type: "end-state",
|
|
10
11
|
};
|
|
11
12
|
}
|
|
13
|
+
if (name.startsWith("final-state-v")) {
|
|
14
|
+
const match = name.match(/^final-state-v(\d+)[.]png$/);
|
|
15
|
+
const logicVersionNumber = match ? parseInt(match[1], 10) : undefined;
|
|
16
|
+
if (match && logicVersionNumber != null && !isNaN(logicVersionNumber)) {
|
|
17
|
+
return {
|
|
18
|
+
type: "end-state",
|
|
19
|
+
logicVersion: logicVersionNumber,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
12
23
|
if (name.startsWith("screenshot-after-event")) {
|
|
13
|
-
const match = name.match(/^(?:.*)-(\d+)[.]png$/);
|
|
24
|
+
const match = (_a = name.match(/^(?:.*)-(\d+)-v(\d+)?[.]png$/)) !== null && _a !== void 0 ? _a : name.match(/^(?:.*)-(\d+)[.]png$/);
|
|
14
25
|
const eventNumber = match ? parseInt(match[1], 10) : undefined;
|
|
26
|
+
const logicVersionNumber = match ? parseInt(match[2], 10) : undefined;
|
|
15
27
|
if (match && eventNumber != null && !isNaN(eventNumber)) {
|
|
16
28
|
return {
|
|
17
29
|
type: "after-event",
|
|
18
30
|
eventNumber,
|
|
31
|
+
...(logicVersionNumber != null && !isNaN(logicVersionNumber)
|
|
32
|
+
? { logicVersion: logicVersionNumber }
|
|
33
|
+
: {}),
|
|
19
34
|
};
|
|
20
35
|
}
|
|
21
36
|
}
|
package/dist/config/config.js
CHANGED
|
@@ -22,10 +22,9 @@ const getConfigFilePath = async () => {
|
|
|
22
22
|
return configFilePath;
|
|
23
23
|
};
|
|
24
24
|
const validateReplayOptions = (prevOptions) => {
|
|
25
|
-
const { appUrl,
|
|
25
|
+
const { appUrl, diffThreshold, diffPixelThreshold, moveBeforeClick, simulationIdForAssets, } = prevOptions;
|
|
26
26
|
return {
|
|
27
27
|
...(appUrl != null ? { appUrl } : {}),
|
|
28
|
-
...(screenshotSelector != null ? { screenshotSelector } : {}),
|
|
29
28
|
...(diffThreshold != null ? { diffThreshold } : {}),
|
|
30
29
|
...(diffPixelThreshold != null ? { diffPixelThreshold } : {}),
|
|
31
30
|
...(moveBeforeClick != null ? { moveBeforeClick } : {}),
|
|
@@ -4,7 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.testRunOutcomeFromDiffResults = exports.mergeResults = void 0;
|
|
7
|
-
const utils_1 = require("@sentry/utils");
|
|
8
7
|
const fast_json_stable_stringify_1 = __importDefault(require("fast-json-stable-stringify"));
|
|
9
8
|
const has_notable_differences_1 = require("../commands/screenshot-diff/utils/has-notable-differences");
|
|
10
9
|
const screenshot_diff_results_utils_1 = require("./screenshot-diff-results.utils");
|
|
@@ -86,22 +85,7 @@ identifier: _identifier,
|
|
|
86
85
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
87
86
|
baseReplayId: _baseReplayId, ...rest }) => rest;
|
|
88
87
|
const hashScreenshotIdentifier = (identifier) => {
|
|
89
|
-
|
|
90
|
-
return "end-state";
|
|
91
|
-
}
|
|
92
|
-
else if (identifier.type === "after-event") {
|
|
93
|
-
return `after-event-${identifier.eventNumber}`;
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
unknownScreenshotIdentifierType(identifier);
|
|
97
|
-
// The identifier is probably from a newer version of the bundle script
|
|
98
|
-
// and we're on an old version of the CLI. Our best bet is to stringify it
|
|
99
|
-
// and use that as a hash.
|
|
100
|
-
return (0, fast_json_stable_stringify_1.default)(identifier);
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
const unknownScreenshotIdentifierType = (identifier) => {
|
|
104
|
-
utils_1.logger.error(`Unknown type of screenshot identifier: ${JSON.stringify(identifier)}`);
|
|
88
|
+
return (0, fast_json_stable_stringify_1.default)(identifier);
|
|
105
89
|
};
|
|
106
90
|
const testRunOutcomeFromDiffResults = (currentResult, newScreenshotDiffResults) => {
|
|
107
91
|
// If a test run is already flakey, we don't want to overwrite that with a 'fail' result.
|
|
@@ -41,7 +41,7 @@ const applyTestCaseExecutionOptionOverrides = (executionOptionsFromCliFlags, ove
|
|
|
41
41
|
};
|
|
42
42
|
};
|
|
43
43
|
const applyTestCaseScreenshottingOptionsOverrides = (screenshottingOptionsFromCliFlags, overridesFromTestCase) => {
|
|
44
|
-
var _a, _b
|
|
44
|
+
var _a, _b;
|
|
45
45
|
// Options specified in the test case override those passed as CLI flags
|
|
46
46
|
// (CLI flags set the defaults)
|
|
47
47
|
const diffOptions = {
|
|
@@ -50,7 +50,6 @@ const applyTestCaseScreenshottingOptionsOverrides = (screenshottingOptionsFromCl
|
|
|
50
50
|
};
|
|
51
51
|
return {
|
|
52
52
|
enabled: true,
|
|
53
|
-
screenshotSelector: (_c = overridesFromTestCase.screenshotSelector) !== null && _c !== void 0 ? _c : screenshottingOptionsFromCliFlags.screenshotSelector,
|
|
54
53
|
diffOptions,
|
|
55
54
|
storyboardOptions: screenshottingOptionsFromCliFlags.storyboardOptions,
|
|
56
55
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alwaysmeticulous/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.40.0",
|
|
4
4
|
"description": "The Meticulous CLI",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"test": "jest"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@alwaysmeticulous/common": "^2.
|
|
29
|
+
"@alwaysmeticulous/common": "^2.40.0",
|
|
30
30
|
"@sentry/node": "^7.36.0",
|
|
31
31
|
"@sentry/tracing": "^7.36.0",
|
|
32
32
|
"adm-zip": "^0.5.9",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"yargs": "^17.5.1"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@alwaysmeticulous/api": "^2.
|
|
48
|
+
"@alwaysmeticulous/api": "^2.40.0",
|
|
49
49
|
"@types/express": "^4.17.14",
|
|
50
50
|
"@types/proper-lockfile": "^4.1.2"
|
|
51
51
|
},
|
|
@@ -95,5 +95,5 @@
|
|
|
95
95
|
"coverageDirectory": "../coverage",
|
|
96
96
|
"testEnvironment": "node"
|
|
97
97
|
},
|
|
98
|
-
"gitHead": "
|
|
98
|
+
"gitHead": "46c8a774b634b1e43ca8e792a6ed573adba296ef"
|
|
99
99
|
}
|