playwright 1.54.1 → 1.56.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/ThirdPartyNotices.txt +2727 -434
- package/lib/agents/generateAgents.js +263 -0
- package/lib/agents/generator.md +102 -0
- package/lib/agents/healer.md +78 -0
- package/lib/agents/planner.md +135 -0
- package/lib/common/config.js +3 -1
- package/lib/common/configLoader.js +2 -1
- package/lib/common/expectBundle.js +3 -0
- package/lib/common/expectBundleImpl.js +51 -51
- package/lib/common/fixtures.js +1 -1
- package/lib/common/suiteUtils.js +0 -9
- package/lib/index.js +127 -115
- package/lib/isomorphic/testTree.js +35 -8
- package/lib/matchers/expect.js +6 -7
- package/lib/matchers/matcherHint.js +43 -15
- package/lib/matchers/matchers.js +10 -4
- package/lib/matchers/toBeTruthy.js +16 -14
- package/lib/matchers/toEqual.js +18 -13
- package/lib/matchers/toHaveURL.js +12 -27
- package/lib/matchers/toMatchAriaSnapshot.js +26 -31
- package/lib/matchers/toMatchSnapshot.js +15 -12
- package/lib/matchers/toMatchText.js +29 -35
- package/lib/mcp/browser/actions.d.js +16 -0
- package/lib/mcp/browser/browserContextFactory.js +296 -0
- package/lib/mcp/browser/browserServerBackend.js +76 -0
- package/lib/mcp/browser/codegen.js +66 -0
- package/lib/mcp/browser/config.js +383 -0
- package/lib/mcp/browser/context.js +284 -0
- package/lib/mcp/browser/response.js +228 -0
- package/lib/mcp/browser/sessionLog.js +160 -0
- package/lib/mcp/browser/tab.js +277 -0
- package/lib/mcp/browser/tools/common.js +63 -0
- package/lib/mcp/browser/tools/console.js +44 -0
- package/lib/mcp/browser/tools/dialogs.js +60 -0
- package/lib/mcp/browser/tools/evaluate.js +70 -0
- package/lib/mcp/browser/tools/files.js +58 -0
- package/lib/mcp/browser/tools/form.js +74 -0
- package/lib/mcp/browser/tools/install.js +69 -0
- package/lib/mcp/browser/tools/keyboard.js +85 -0
- package/lib/mcp/browser/tools/mouse.js +107 -0
- package/lib/mcp/browser/tools/navigate.js +62 -0
- package/lib/mcp/browser/tools/network.js +54 -0
- package/lib/mcp/browser/tools/pdf.js +59 -0
- package/lib/mcp/browser/tools/screenshot.js +88 -0
- package/lib/mcp/browser/tools/snapshot.js +182 -0
- package/lib/mcp/browser/tools/tabs.js +67 -0
- package/lib/mcp/browser/tools/tool.js +49 -0
- package/lib/mcp/browser/tools/tracing.js +74 -0
- package/lib/mcp/browser/tools/utils.js +100 -0
- package/lib/mcp/browser/tools/verify.js +154 -0
- package/lib/mcp/browser/tools/wait.js +63 -0
- package/lib/mcp/browser/tools.js +80 -0
- package/lib/mcp/browser/watchdog.js +44 -0
- package/lib/mcp/config.d.js +16 -0
- package/lib/mcp/extension/cdpRelay.js +351 -0
- package/lib/mcp/extension/extensionContextFactory.js +75 -0
- package/lib/mcp/extension/protocol.js +28 -0
- package/lib/mcp/index.js +61 -0
- package/lib/mcp/log.js +35 -0
- package/lib/mcp/program.js +96 -0
- package/lib/mcp/sdk/bundle.js +81 -0
- package/lib/mcp/sdk/exports.js +32 -0
- package/lib/mcp/sdk/http.js +180 -0
- package/lib/mcp/sdk/inProcessTransport.js +71 -0
- package/lib/mcp/sdk/mdb.js +208 -0
- package/lib/mcp/sdk/proxyBackend.js +128 -0
- package/lib/mcp/sdk/server.js +190 -0
- package/lib/mcp/sdk/tool.js +51 -0
- package/lib/mcp/test/browserBackend.js +98 -0
- package/lib/mcp/test/generatorTools.js +122 -0
- package/lib/mcp/test/plannerTools.js +46 -0
- package/lib/mcp/test/seed.js +72 -0
- package/lib/mcp/test/streams.js +39 -0
- package/lib/mcp/test/testBackend.js +97 -0
- package/lib/mcp/test/testContext.js +176 -0
- package/lib/mcp/test/testTool.js +30 -0
- package/lib/mcp/test/testTools.js +115 -0
- package/lib/mcpBundleImpl.js +41 -0
- package/lib/plugins/webServerPlugin.js +2 -0
- package/lib/program.js +77 -57
- package/lib/reporters/base.js +34 -29
- package/lib/reporters/dot.js +11 -11
- package/lib/reporters/github.js +2 -1
- package/lib/reporters/html.js +58 -41
- package/lib/reporters/internalReporter.js +2 -1
- package/lib/reporters/line.js +15 -15
- package/lib/reporters/list.js +24 -19
- package/lib/reporters/listModeReporter.js +69 -0
- package/lib/reporters/markdown.js +3 -3
- package/lib/reporters/merge.js +3 -1
- package/lib/reporters/teleEmitter.js +3 -1
- package/lib/runner/dispatcher.js +9 -2
- package/lib/runner/failureTracker.js +12 -2
- package/lib/runner/lastRun.js +7 -4
- package/lib/runner/loadUtils.js +46 -12
- package/lib/runner/projectUtils.js +8 -2
- package/lib/runner/reporters.js +7 -32
- package/lib/runner/tasks.js +20 -10
- package/lib/runner/testRunner.js +390 -0
- package/lib/runner/testServer.js +57 -276
- package/lib/runner/watchMode.js +5 -1
- package/lib/runner/workerHost.js +8 -6
- package/lib/transform/babelBundleImpl.js +179 -195
- package/lib/transform/compilationCache.js +22 -5
- package/lib/transform/transform.js +1 -1
- package/lib/util.js +12 -35
- package/lib/utilsBundleImpl.js +1 -1
- package/lib/worker/fixtureRunner.js +7 -2
- package/lib/worker/testInfo.js +76 -45
- package/lib/worker/testTracing.js +8 -7
- package/lib/worker/workerMain.js +12 -3
- package/package.json +10 -2
- package/types/test.d.ts +63 -44
- package/types/testReporter.d.ts +1 -1
- package/lib/runner/runner.js +0 -110
package/lib/matchers/matchers.js
CHANGED
|
@@ -59,6 +59,7 @@ var import_toMatchText = require("./toMatchText");
|
|
|
59
59
|
var import_config = require("../common/config");
|
|
60
60
|
var import_globals = require("../common/globals");
|
|
61
61
|
var import_testInfo = require("../worker/testInfo");
|
|
62
|
+
var import_matcherHint = require("./matcherHint");
|
|
62
63
|
function toBeAttached(locator, options) {
|
|
63
64
|
const attached = !options || options.attached === void 0 || options.attached;
|
|
64
65
|
const expected = attached ? "attached" : "detached";
|
|
@@ -146,7 +147,7 @@ function toContainText(locator, expected, options = {}) {
|
|
|
146
147
|
return import_toMatchText.toMatchText.call(this, "toContainText", locator, "Locator", async (isNot, timeout) => {
|
|
147
148
|
const expectedText = (0, import_utils.serializeExpectedTextValues)([expected], { matchSubstring: true, normalizeWhiteSpace: true, ignoreCase: options.ignoreCase });
|
|
148
149
|
return await locator._expect("to.have.text", { expectedText, isNot, useInnerText: options.useInnerText, timeout });
|
|
149
|
-
}, expected, options);
|
|
150
|
+
}, expected, { ...options, matchSubstring: true });
|
|
150
151
|
}
|
|
151
152
|
}
|
|
152
153
|
function toHaveAccessibleDescription(locator, expected, options) {
|
|
@@ -273,7 +274,7 @@ function toHaveTitle(page, expected, options = {}) {
|
|
|
273
274
|
return import_toMatchText.toMatchText.call(this, "toHaveTitle", page, "Page", async (isNot, timeout) => {
|
|
274
275
|
const expectedText = (0, import_utils.serializeExpectedTextValues)([expected], { normalizeWhiteSpace: true });
|
|
275
276
|
return await page.mainFrame()._expect("to.have.title", { expectedText, isNot, timeout });
|
|
276
|
-
}, expected,
|
|
277
|
+
}, expected, options);
|
|
277
278
|
}
|
|
278
279
|
function toHaveURL(page, expected, options) {
|
|
279
280
|
if (typeof expected === "function")
|
|
@@ -283,7 +284,7 @@ function toHaveURL(page, expected, options) {
|
|
|
283
284
|
return import_toMatchText.toMatchText.call(this, "toHaveURL", page, "Page", async (isNot, timeout) => {
|
|
284
285
|
const expectedText = (0, import_utils.serializeExpectedTextValues)([expected], { ignoreCase: options?.ignoreCase });
|
|
285
286
|
return await page.mainFrame()._expect("to.have.url", { expectedText, isNot, timeout });
|
|
286
|
-
}, expected,
|
|
287
|
+
}, expected, options);
|
|
287
288
|
}
|
|
288
289
|
async function toBeOK(response) {
|
|
289
290
|
const matcherName = "toBeOK";
|
|
@@ -294,7 +295,12 @@ async function toBeOK(response) {
|
|
|
294
295
|
response._fetchLog(),
|
|
295
296
|
isTextEncoding ? response.text() : null
|
|
296
297
|
]) : [];
|
|
297
|
-
const message = () =>
|
|
298
|
+
const message = () => (0, import_matcherHint.formatMatcherMessage)(this, {
|
|
299
|
+
matcherName,
|
|
300
|
+
receiver: "response",
|
|
301
|
+
expectation: "",
|
|
302
|
+
log
|
|
303
|
+
}) + (text === null ? "" : `
|
|
298
304
|
Response text:
|
|
299
305
|
${import_utils2.colors.dim(text?.substring(0, 1e3) || "")}`);
|
|
300
306
|
const pass = response.ok();
|
|
@@ -23,14 +23,10 @@ __export(toBeTruthy_exports, {
|
|
|
23
23
|
module.exports = __toCommonJS(toBeTruthy_exports);
|
|
24
24
|
var import_util = require("../util");
|
|
25
25
|
var import_matcherHint = require("./matcherHint");
|
|
26
|
-
async function toBeTruthy(matcherName,
|
|
27
|
-
(0, import_util.expectTypes)(
|
|
28
|
-
const matcherOptions = {
|
|
29
|
-
isNot: this.isNot,
|
|
30
|
-
promise: this.promise
|
|
31
|
-
};
|
|
26
|
+
async function toBeTruthy(matcherName, locator, receiverType, expected, arg, query, options = {}) {
|
|
27
|
+
(0, import_util.expectTypes)(locator, [receiverType], matcherName);
|
|
32
28
|
const timeout = options.timeout ?? this.timeout;
|
|
33
|
-
const { matches: pass, log, timedOut, received } = await query(!!this.isNot, timeout);
|
|
29
|
+
const { matches: pass, log, timedOut, received, errorMessage } = await query(!!this.isNot, timeout);
|
|
34
30
|
if (pass === !this.isNot) {
|
|
35
31
|
return {
|
|
36
32
|
name: matcherName,
|
|
@@ -39,21 +35,27 @@ async function toBeTruthy(matcherName, receiver, receiverType, expected, arg, qu
|
|
|
39
35
|
expected
|
|
40
36
|
};
|
|
41
37
|
}
|
|
42
|
-
const notFound = received === import_matcherHint.kNoElementsFoundError ? received : void 0;
|
|
43
38
|
let printedReceived;
|
|
44
39
|
let printedExpected;
|
|
45
40
|
if (pass) {
|
|
46
41
|
printedExpected = `Expected: not ${expected}`;
|
|
47
|
-
printedReceived = `Received: ${
|
|
42
|
+
printedReceived = errorMessage ? "" : `Received: ${expected}`;
|
|
48
43
|
} else {
|
|
49
44
|
printedExpected = `Expected: ${expected}`;
|
|
50
|
-
printedReceived = `Received: ${
|
|
45
|
+
printedReceived = errorMessage ? "" : `Received: ${received}`;
|
|
51
46
|
}
|
|
52
47
|
const message = () => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
48
|
+
return (0, import_matcherHint.formatMatcherMessage)(this, {
|
|
49
|
+
matcherName,
|
|
50
|
+
expectation: arg,
|
|
51
|
+
locator,
|
|
52
|
+
timeout,
|
|
53
|
+
timedOut,
|
|
54
|
+
printedExpected,
|
|
55
|
+
printedReceived,
|
|
56
|
+
errorMessage,
|
|
57
|
+
log
|
|
58
|
+
});
|
|
57
59
|
};
|
|
58
60
|
return {
|
|
59
61
|
message,
|
package/lib/matchers/toEqual.js
CHANGED
|
@@ -26,15 +26,10 @@ var import_util = require("../util");
|
|
|
26
26
|
var import_matcherHint = require("./matcherHint");
|
|
27
27
|
const EXPECTED_LABEL = "Expected";
|
|
28
28
|
const RECEIVED_LABEL = "Received";
|
|
29
|
-
async function toEqual(matcherName,
|
|
30
|
-
(0, import_util.expectTypes)(
|
|
31
|
-
const matcherOptions = {
|
|
32
|
-
comment: options.contains ? "" : "deep equality",
|
|
33
|
-
isNot: this.isNot,
|
|
34
|
-
promise: this.promise
|
|
35
|
-
};
|
|
29
|
+
async function toEqual(matcherName, locator, receiverType, query, expected, options = {}) {
|
|
30
|
+
(0, import_util.expectTypes)(locator, [receiverType], matcherName);
|
|
36
31
|
const timeout = options.timeout ?? this.timeout;
|
|
37
|
-
const { matches: pass, received, log, timedOut } = await query(!!this.isNot, timeout);
|
|
32
|
+
const { matches: pass, received, log, timedOut, errorMessage } = await query(!!this.isNot, timeout);
|
|
38
33
|
if (pass === !this.isNot) {
|
|
39
34
|
return {
|
|
40
35
|
name: matcherName,
|
|
@@ -48,7 +43,9 @@ async function toEqual(matcherName, receiver, receiverType, query, expected, opt
|
|
|
48
43
|
let printedDiff;
|
|
49
44
|
if (pass) {
|
|
50
45
|
printedExpected = `Expected: not ${this.utils.printExpected(expected)}`;
|
|
51
|
-
printedReceived = `Received: ${this.utils.printReceived(received)}`;
|
|
46
|
+
printedReceived = errorMessage ? "" : `Received: ${this.utils.printReceived(received)}`;
|
|
47
|
+
} else if (errorMessage) {
|
|
48
|
+
printedExpected = `Expected: ${this.utils.printExpected(expected)}`;
|
|
52
49
|
} else if (Array.isArray(expected) && Array.isArray(received)) {
|
|
53
50
|
const normalizedExpected = expected.map((exp, index) => {
|
|
54
51
|
const rec = received[index];
|
|
@@ -73,10 +70,18 @@ async function toEqual(matcherName, receiver, receiverType, query, expected, opt
|
|
|
73
70
|
);
|
|
74
71
|
}
|
|
75
72
|
const message = () => {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
73
|
+
return (0, import_matcherHint.formatMatcherMessage)(this, {
|
|
74
|
+
matcherName,
|
|
75
|
+
expectation: "expected",
|
|
76
|
+
locator,
|
|
77
|
+
timeout,
|
|
78
|
+
timedOut,
|
|
79
|
+
printedExpected,
|
|
80
|
+
printedReceived,
|
|
81
|
+
printedDiff,
|
|
82
|
+
errorMessage,
|
|
83
|
+
log
|
|
84
|
+
});
|
|
80
85
|
};
|
|
81
86
|
return {
|
|
82
87
|
actual: received,
|
|
@@ -22,27 +22,11 @@ __export(toHaveURL_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(toHaveURL_exports);
|
|
24
24
|
var import_utils = require("playwright-core/lib/utils");
|
|
25
|
-
var import_utils2 = require("playwright-core/lib/utils");
|
|
26
25
|
var import_expect = require("./expect");
|
|
27
26
|
var import_matcherHint = require("./matcherHint");
|
|
28
27
|
var import_expectBundle = require("../common/expectBundle");
|
|
29
28
|
async function toHaveURLWithPredicate(page, expected, options) {
|
|
30
29
|
const matcherName = "toHaveURL";
|
|
31
|
-
const expression = "page";
|
|
32
|
-
const matcherOptions = {
|
|
33
|
-
isNot: this.isNot,
|
|
34
|
-
promise: this.promise
|
|
35
|
-
};
|
|
36
|
-
if (typeof expected !== "function") {
|
|
37
|
-
throw new Error(
|
|
38
|
-
[
|
|
39
|
-
// Always display `expected` in expectation place
|
|
40
|
-
(0, import_matcherHint.matcherHint)(this, void 0, matcherName, expression, void 0, matcherOptions),
|
|
41
|
-
`${import_utils2.colors.bold("Matcher error")}: ${(0, import_expectBundle.EXPECTED_COLOR)("expected")} value must be a string, regular expression, or predicate`,
|
|
42
|
-
this.utils.printWithType("Expected", expected, this.utils.printExpected)
|
|
43
|
-
].join("\n\n")
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
30
|
const timeout = options?.timeout ?? this.timeout;
|
|
47
31
|
const baseURL = page.context()._options.baseURL;
|
|
48
32
|
let conditionSucceeded = false;
|
|
@@ -74,7 +58,6 @@ async function toHaveURLWithPredicate(page, expected, options) {
|
|
|
74
58
|
message: () => toHaveURLMessage(
|
|
75
59
|
this,
|
|
76
60
|
matcherName,
|
|
77
|
-
expression,
|
|
78
61
|
expected,
|
|
79
62
|
lastCheckedURLString,
|
|
80
63
|
this.isNot,
|
|
@@ -85,19 +68,14 @@ async function toHaveURLWithPredicate(page, expected, options) {
|
|
|
85
68
|
timeout
|
|
86
69
|
};
|
|
87
70
|
}
|
|
88
|
-
function toHaveURLMessage(state, matcherName,
|
|
89
|
-
const matcherOptions = {
|
|
90
|
-
isNot: state.isNot,
|
|
91
|
-
promise: state.promise
|
|
92
|
-
};
|
|
71
|
+
function toHaveURLMessage(state, matcherName, expected, received, pass, timedOut, timeout) {
|
|
93
72
|
const receivedString = received || "";
|
|
94
|
-
const messagePrefix = (0, import_matcherHint.matcherHint)(state, void 0, matcherName, expression, void 0, matcherOptions, didTimeout ? timeout : void 0);
|
|
95
73
|
let printedReceived;
|
|
96
74
|
let printedExpected;
|
|
97
75
|
let printedDiff;
|
|
98
76
|
if (typeof expected === "function") {
|
|
99
|
-
printedExpected = `Expected predicate to ${!state.isNot ? "succeed" : "fail"}`;
|
|
100
|
-
printedReceived = `Received
|
|
77
|
+
printedExpected = `Expected: predicate to ${!state.isNot ? "succeed" : "fail"}`;
|
|
78
|
+
printedReceived = `Received: ${(0, import_expectBundle.printReceived)(receivedString)}`;
|
|
101
79
|
} else {
|
|
102
80
|
if (pass) {
|
|
103
81
|
printedExpected = `Expected pattern: not ${state.utils.printExpected(expected)}`;
|
|
@@ -108,8 +86,15 @@ function toHaveURLMessage(state, matcherName, expression, expected, received, pa
|
|
|
108
86
|
printedDiff = state.utils.printDiffOrStringify(expected, receivedString, labelExpected, "Received string", false);
|
|
109
87
|
}
|
|
110
88
|
}
|
|
111
|
-
|
|
112
|
-
|
|
89
|
+
return (0, import_matcherHint.formatMatcherMessage)(state, {
|
|
90
|
+
matcherName,
|
|
91
|
+
expectation: "expected",
|
|
92
|
+
timeout,
|
|
93
|
+
timedOut,
|
|
94
|
+
printedExpected,
|
|
95
|
+
printedReceived,
|
|
96
|
+
printedDiff
|
|
97
|
+
});
|
|
113
98
|
}
|
|
114
99
|
// Annotate the CommonJS export names for ESM import in node:
|
|
115
100
|
0 && (module.exports = {
|
|
@@ -35,11 +35,10 @@ var import_fs = __toESM(require("fs"));
|
|
|
35
35
|
var import_path = __toESM(require("path"));
|
|
36
36
|
var import_utils = require("playwright-core/lib/utils");
|
|
37
37
|
var import_matcherHint = require("./matcherHint");
|
|
38
|
-
var import_expectBundle = require("../common/expectBundle");
|
|
39
38
|
var import_util = require("../util");
|
|
40
39
|
var import_expect = require("./expect");
|
|
41
40
|
var import_globals = require("../common/globals");
|
|
42
|
-
async function toMatchAriaSnapshot(
|
|
41
|
+
async function toMatchAriaSnapshot(locator, expectedParam, options = {}) {
|
|
43
42
|
const matcherName = "toMatchAriaSnapshot";
|
|
44
43
|
const testInfo = (0, import_globals.currentTestInfo)();
|
|
45
44
|
if (!testInfo)
|
|
@@ -47,10 +46,6 @@ async function toMatchAriaSnapshot(receiver, expectedParam, options = {}) {
|
|
|
47
46
|
if (testInfo._projectInternal.ignoreSnapshots)
|
|
48
47
|
return { pass: !this.isNot, message: () => "", name: "toMatchAriaSnapshot", expected: "" };
|
|
49
48
|
const updateSnapshots = testInfo.config.updateSnapshots;
|
|
50
|
-
const matcherOptions = {
|
|
51
|
-
isNot: this.isNot,
|
|
52
|
-
promise: this.promise
|
|
53
|
-
};
|
|
54
49
|
let expected;
|
|
55
50
|
let timeout;
|
|
56
51
|
let expectedPath;
|
|
@@ -75,36 +70,36 @@ async function toMatchAriaSnapshot(receiver, expectedParam, options = {}) {
|
|
|
75
70
|
}
|
|
76
71
|
}
|
|
77
72
|
expected = unshift(expected);
|
|
78
|
-
const { matches: pass, received, log, timedOut } = await
|
|
73
|
+
const { matches: pass, received, log, timedOut, errorMessage } = await locator._expect("to.match.aria", { expectedValue: expected, isNot: this.isNot, timeout });
|
|
79
74
|
const typedReceived = received;
|
|
80
|
-
const messagePrefix = (0, import_matcherHint.matcherHint)(this, receiver, matcherName, "locator", void 0, matcherOptions, timedOut ? timeout : void 0);
|
|
81
|
-
const notFound = typedReceived === import_matcherHint.kNoElementsFoundError;
|
|
82
|
-
if (notFound) {
|
|
83
|
-
return {
|
|
84
|
-
pass: this.isNot,
|
|
85
|
-
message: () => messagePrefix + `Expected: ${this.utils.printExpected(expected)}
|
|
86
|
-
Received: ${(0, import_expectBundle.EXPECTED_COLOR)("<element not found>")}` + (0, import_util.callLogText)(log),
|
|
87
|
-
name: "toMatchAriaSnapshot",
|
|
88
|
-
expected
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
const receivedText = typedReceived.raw;
|
|
92
75
|
const message = () => {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
76
|
+
let printedExpected;
|
|
77
|
+
let printedReceived;
|
|
78
|
+
let printedDiff;
|
|
79
|
+
if (errorMessage) {
|
|
80
|
+
printedExpected = `Expected: ${this.isNot ? "not " : ""}${this.utils.printExpected(expected)}`;
|
|
81
|
+
} else if (pass) {
|
|
82
|
+
const receivedString = (0, import_expect.printReceivedStringContainExpectedSubstring)(typedReceived.raw, typedReceived.raw.indexOf(expected), expected.length);
|
|
83
|
+
printedExpected = `Expected: not ${this.utils.printExpected(expected)}`;
|
|
84
|
+
printedReceived = `Received: ${receivedString}`;
|
|
100
85
|
} else {
|
|
101
|
-
|
|
102
|
-
if (notFound)
|
|
103
|
-
return messagePrefix + `${labelExpected}: ${this.utils.printExpected(expected)}
|
|
104
|
-
Received: ${receivedText}` + (0, import_util.callLogText)(log);
|
|
105
|
-
return messagePrefix + this.utils.printDiffOrStringify(expected, receivedText, labelExpected, "Received", false) + (0, import_util.callLogText)(log);
|
|
86
|
+
printedDiff = this.utils.printDiffOrStringify(expected, typedReceived.raw, "Expected", "Received", false);
|
|
106
87
|
}
|
|
88
|
+
return (0, import_matcherHint.formatMatcherMessage)(this, {
|
|
89
|
+
matcherName,
|
|
90
|
+
expectation: "expected",
|
|
91
|
+
locator,
|
|
92
|
+
timeout,
|
|
93
|
+
timedOut,
|
|
94
|
+
printedExpected,
|
|
95
|
+
printedReceived,
|
|
96
|
+
printedDiff,
|
|
97
|
+
errorMessage,
|
|
98
|
+
log
|
|
99
|
+
});
|
|
107
100
|
};
|
|
101
|
+
if (errorMessage)
|
|
102
|
+
return { pass: this.isNot, message, name: "toMatchAriaSnapshot", expected };
|
|
108
103
|
if (!this.isNot) {
|
|
109
104
|
if (updateSnapshots === "all" || updateSnapshots === "changed" && pass === this.isNot || generateMissingBaseline) {
|
|
110
105
|
if (expectedPath) {
|
|
@@ -162,7 +162,7 @@ class SnapshotHelper {
|
|
|
162
162
|
step?._attachToStep({ name: (0, import_util.addSuffixToFilePath)(this.attachmentBaseName, "-diff"), contentType: this.mimeType, path: this.diffPath });
|
|
163
163
|
}
|
|
164
164
|
if (log?.length)
|
|
165
|
-
output.push((0,
|
|
165
|
+
output.push((0, import_matcherHint.callLogText)(log));
|
|
166
166
|
else
|
|
167
167
|
output.push("");
|
|
168
168
|
return this.createMatcherResult(output.join("\n"), false, log);
|
|
@@ -216,8 +216,7 @@ function toMatchSnapshot(received, nameOrOptions = {}, optOptions = {}) {
|
|
|
216
216
|
const result = helper.comparator(received, expected, helper.options);
|
|
217
217
|
if (!result)
|
|
218
218
|
return helper.handleMatching();
|
|
219
|
-
const
|
|
220
|
-
const header = (0, import_matcherHint.matcherHint)(this, void 0, "toMatchSnapshot", receiver, void 0, void 0);
|
|
219
|
+
const header = (0, import_matcherHint.formatMatcherMessage)(this, { matcherName: "toMatchSnapshot", receiver: (0, import_utils.isString)(received) ? "string" : "Buffer", expectation: "expected" });
|
|
221
220
|
return helper.handleDifferent(received, expected, void 0, result.diff, header, result.errorMessage, void 0, this._stepInfo);
|
|
222
221
|
}
|
|
223
222
|
function toHaveScreenshotStepTitle(nameOrOptions = {}, optOptions = {}) {
|
|
@@ -271,11 +270,10 @@ async function toHaveScreenshot(pageOrLocator, nameOrOptions = {}, optOptions =
|
|
|
271
270
|
}
|
|
272
271
|
if (helper.updateSnapshots === "none" && !hasSnapshot)
|
|
273
272
|
return helper.createMatcherResult(`A snapshot doesn't exist at ${helper.expectedPath}.`, false);
|
|
274
|
-
const receiver = locator ? "locator" : "page";
|
|
275
273
|
if (!hasSnapshot) {
|
|
276
274
|
const { actual: actual2, previous: previous2, diff: diff2, errorMessage: errorMessage2, log: log2, timedOut: timedOut2 } = await page._expectScreenshot(expectScreenshotOptions);
|
|
277
275
|
if (errorMessage2) {
|
|
278
|
-
const header2 = (0, import_matcherHint.
|
|
276
|
+
const header2 = (0, import_matcherHint.formatMatcherMessage)(this, { matcherName: "toHaveScreenshot", locator, expectation: "expected", timeout, timedOut: timedOut2 });
|
|
279
277
|
return helper.handleDifferent(actual2, void 0, previous2, diff2, header2, errorMessage2, log2, this._stepInfo);
|
|
280
278
|
}
|
|
281
279
|
return helper.handleMissing(actual2, this._stepInfo);
|
|
@@ -283,22 +281,27 @@ async function toHaveScreenshot(pageOrLocator, nameOrOptions = {}, optOptions =
|
|
|
283
281
|
const expected = await import_fs.default.promises.readFile(helper.expectedPath);
|
|
284
282
|
expectScreenshotOptions.expected = helper.updateSnapshots === "all" ? void 0 : expected;
|
|
285
283
|
const { actual, previous, diff, errorMessage, log, timedOut } = await page._expectScreenshot(expectScreenshotOptions);
|
|
286
|
-
const writeFiles = () => {
|
|
287
|
-
writeFileSync(helper.expectedPath,
|
|
288
|
-
writeFileSync(helper.actualPath,
|
|
284
|
+
const writeFiles = (actualBuffer) => {
|
|
285
|
+
writeFileSync(helper.expectedPath, actualBuffer);
|
|
286
|
+
writeFileSync(helper.actualPath, actualBuffer);
|
|
289
287
|
console.log(helper.expectedPath + " is re-generated, writing actual.");
|
|
290
288
|
return helper.createMatcherResult(helper.expectedPath + " running with --update-snapshots, writing actual.", true);
|
|
291
289
|
};
|
|
292
290
|
if (!errorMessage) {
|
|
293
291
|
if (helper.updateSnapshots === "all" && actual && (0, import_utils.compareBuffersOrStrings)(actual, expected)) {
|
|
294
292
|
console.log(helper.expectedPath + " is re-generated, writing actual.");
|
|
295
|
-
return writeFiles();
|
|
293
|
+
return writeFiles(actual);
|
|
296
294
|
}
|
|
297
295
|
return helper.handleMatching();
|
|
298
296
|
}
|
|
299
|
-
if (helper.updateSnapshots === "changed" || helper.updateSnapshots === "all")
|
|
300
|
-
|
|
301
|
-
|
|
297
|
+
if (helper.updateSnapshots === "changed" || helper.updateSnapshots === "all") {
|
|
298
|
+
if (actual)
|
|
299
|
+
return writeFiles(actual);
|
|
300
|
+
let header2 = (0, import_matcherHint.formatMatcherMessage)(this, { matcherName: "toHaveScreenshot", locator, expectation: "expected", timeout, timedOut });
|
|
301
|
+
header2 += " Failed to re-generate expected.\n";
|
|
302
|
+
return helper.handleDifferent(actual, expectScreenshotOptions.expected, previous, diff, header2, errorMessage, log, this._stepInfo);
|
|
303
|
+
}
|
|
304
|
+
const header = (0, import_matcherHint.formatMatcherMessage)(this, { matcherName: "toHaveScreenshot", locator, expectation: "expected", timeout, timedOut });
|
|
302
305
|
return helper.handleDifferent(actual, expectScreenshotOptions.expected, previous, diff, header, errorMessage, log, this._stepInfo);
|
|
303
306
|
}
|
|
304
307
|
function writeFileSync(aPath, content) {
|
|
@@ -21,26 +21,20 @@ __export(toMatchText_exports, {
|
|
|
21
21
|
toMatchText: () => toMatchText
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(toMatchText_exports);
|
|
24
|
-
var import_utils = require("playwright-core/lib/utils");
|
|
25
24
|
var import_util = require("../util");
|
|
26
25
|
var import_expect = require("./expect");
|
|
27
26
|
var import_matcherHint = require("./matcherHint");
|
|
28
27
|
var import_expectBundle = require("../common/expectBundle");
|
|
29
28
|
async function toMatchText(matcherName, receiver, receiverType, query, expected, options = {}) {
|
|
30
29
|
(0, import_util.expectTypes)(receiver, [receiverType], matcherName);
|
|
31
|
-
const
|
|
32
|
-
isNot: this.isNot,
|
|
33
|
-
promise: this.promise
|
|
34
|
-
};
|
|
30
|
+
const locator = receiverType === "Locator" ? receiver : void 0;
|
|
35
31
|
if (!(typeof expected === "string") && !(expected && typeof expected.test === "function")) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
this.utils.printWithType("Expected", expected, this.utils.printExpected)
|
|
40
|
-
].join("\n\n"));
|
|
32
|
+
const errorMessage2 = `Error: ${(0, import_expectBundle.EXPECTED_COLOR)("expected")} value must be a string or regular expression
|
|
33
|
+
${this.utils.printWithType("Expected", expected, this.utils.printExpected)}`;
|
|
34
|
+
throw new Error((0, import_matcherHint.formatMatcherMessage)(this, { locator, matcherName, expectation: "expected", errorMessage: errorMessage2 }));
|
|
41
35
|
}
|
|
42
36
|
const timeout = options.timeout ?? this.timeout;
|
|
43
|
-
const { matches: pass, received, log, timedOut } = await query(!!this.isNot, timeout);
|
|
37
|
+
const { matches: pass, received, log, timedOut, errorMessage } = await query(!!this.isNot, timeout);
|
|
44
38
|
if (pass === !this.isNot) {
|
|
45
39
|
return {
|
|
46
40
|
name: matcherName,
|
|
@@ -49,45 +43,45 @@ async function toMatchText(matcherName, receiver, receiverType, query, expected,
|
|
|
49
43
|
expected
|
|
50
44
|
};
|
|
51
45
|
}
|
|
52
|
-
const
|
|
46
|
+
const expectedSuffix = typeof expected === "string" ? options.matchSubstring ? " substring" : "" : " pattern";
|
|
47
|
+
const receivedSuffix = typeof expected === "string" ? options.matchSubstring ? " string" : "" : " string";
|
|
53
48
|
const receivedString = received || "";
|
|
54
|
-
const messagePrefix = (0, import_matcherHint.matcherHint)(this, receiverType === "Locator" ? receiver : void 0, matcherName, options.receiverLabel ?? "locator", void 0, matcherOptions, timedOut ? timeout : void 0);
|
|
55
|
-
const notFound = received === import_matcherHint.kNoElementsFoundError;
|
|
56
49
|
let printedReceived;
|
|
57
50
|
let printedExpected;
|
|
58
51
|
let printedDiff;
|
|
59
52
|
if (pass) {
|
|
60
53
|
if (typeof expected === "string") {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
printedReceived = `Received: ${received}`;
|
|
64
|
-
} else {
|
|
65
|
-
printedExpected = `Expected ${stringSubstring}: not ${this.utils.printExpected(expected)}`;
|
|
54
|
+
printedExpected = `Expected${expectedSuffix}: not ${this.utils.printExpected(expected)}`;
|
|
55
|
+
if (!errorMessage) {
|
|
66
56
|
const formattedReceived = (0, import_expect.printReceivedStringContainExpectedSubstring)(receivedString, receivedString.indexOf(expected), expected.length);
|
|
67
|
-
printedReceived = `Received
|
|
57
|
+
printedReceived = `Received${receivedSuffix}: ${formattedReceived}`;
|
|
68
58
|
}
|
|
69
59
|
} else {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
printedReceived = `Received: ${received}`;
|
|
73
|
-
} else {
|
|
74
|
-
printedExpected = `Expected pattern: not ${this.utils.printExpected(expected)}`;
|
|
60
|
+
printedExpected = `Expected${expectedSuffix}: not ${this.utils.printExpected(expected)}`;
|
|
61
|
+
if (!errorMessage) {
|
|
75
62
|
const formattedReceived = (0, import_expect.printReceivedStringContainExpectedResult)(receivedString, typeof expected.exec === "function" ? expected.exec(receivedString) : null);
|
|
76
|
-
printedReceived = `Received
|
|
63
|
+
printedReceived = `Received${receivedSuffix}: ${formattedReceived}`;
|
|
77
64
|
}
|
|
78
65
|
}
|
|
79
66
|
} else {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
} else {
|
|
85
|
-
printedDiff = this.utils.printDiffOrStringify(expected, receivedString, labelExpected, "Received string", false);
|
|
86
|
-
}
|
|
67
|
+
if (errorMessage)
|
|
68
|
+
printedExpected = `Expected${expectedSuffix}: ${this.utils.printExpected(expected)}`;
|
|
69
|
+
else
|
|
70
|
+
printedDiff = this.utils.printDiffOrStringify(expected, receivedString, `Expected${expectedSuffix}`, `Received${receivedSuffix}`, false);
|
|
87
71
|
}
|
|
88
72
|
const message = () => {
|
|
89
|
-
|
|
90
|
-
|
|
73
|
+
return (0, import_matcherHint.formatMatcherMessage)(this, {
|
|
74
|
+
matcherName,
|
|
75
|
+
expectation: "expected",
|
|
76
|
+
locator,
|
|
77
|
+
timeout,
|
|
78
|
+
timedOut,
|
|
79
|
+
printedExpected,
|
|
80
|
+
printedReceived,
|
|
81
|
+
printedDiff,
|
|
82
|
+
log,
|
|
83
|
+
errorMessage
|
|
84
|
+
});
|
|
91
85
|
};
|
|
92
86
|
return {
|
|
93
87
|
name: matcherName,
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
var actions_d_exports = {};
|
|
16
|
+
module.exports = __toCommonJS(actions_d_exports);
|