screenshot/test_1

This commit is contained in:
ramkumarp
2025-03-27 11:21:02 +00:00
commit 616d466383
470 changed files with 144705 additions and 0 deletions

371
node_modules/playwright/lib/matchers/expect.js generated vendored Normal file
View File

@@ -0,0 +1,371 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.expect = void 0;
exports.mergeExpects = mergeExpects;
exports.printReceivedStringContainExpectedSubstring = exports.printReceivedStringContainExpectedResult = void 0;
var _utils = require("playwright-core/lib/utils");
var _matcherHint = require("./matcherHint");
var _matchers = require("./matchers");
var _toMatchAriaSnapshot = require("./toMatchAriaSnapshot");
var _toMatchSnapshot = require("./toMatchSnapshot");
var _expectBundle = require("../common/expectBundle");
var _globals = require("../common/globals");
var _util = require("../util");
var _testInfo = require("../worker/testInfo");
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// #region
// Mirrored from https://github.com/facebook/jest/blob/f13abff8df9a0e1148baf3584bcde6d1b479edc7/packages/expect/src/print.ts
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found here
* https://github.com/facebook/jest/blob/1547740bbc26400d69f4576bf35645163e942829/LICENSE
*/
// Format substring but do not enclose in double quote marks.
// The replacement is compatible with pretty-format package.
const printSubstring = val => val.replace(/"|\\/g, '\\$&');
const printReceivedStringContainExpectedSubstring = (received, start, length // not end
) => (0, _expectBundle.RECEIVED_COLOR)('"' + printSubstring(received.slice(0, start)) + (0, _expectBundle.INVERTED_COLOR)(printSubstring(received.slice(start, start + length))) + printSubstring(received.slice(start + length)) + '"');
exports.printReceivedStringContainExpectedSubstring = printReceivedStringContainExpectedSubstring;
const printReceivedStringContainExpectedResult = (received, result) => result === null ? (0, _expectBundle.printReceived)(received) : printReceivedStringContainExpectedSubstring(received, result.index, result[0].length);
// #endregion
exports.printReceivedStringContainExpectedResult = printReceivedStringContainExpectedResult;
function createMatchers(actual, info, prefix) {
return new Proxy((0, _expectBundle.expect)(actual), new ExpectMetaInfoProxyHandler(info, prefix));
}
const userMatchersSymbol = Symbol('userMatchers');
function qualifiedMatcherName(qualifier, matcherName) {
return qualifier.join(':') + '$' + matcherName;
}
function createExpect(info, prefix, userMatchers) {
const expectInstance = new Proxy(_expectBundle.expect, {
apply: function (target, thisArg, argumentsList) {
const [actual, messageOrOptions] = argumentsList;
const message = (0, _utils.isString)(messageOrOptions) ? messageOrOptions : (messageOrOptions === null || messageOrOptions === void 0 ? void 0 : messageOrOptions.message) || info.message;
const newInfo = {
...info,
message
};
if (newInfo.poll) {
if (typeof actual !== 'function') throw new Error('`expect.poll()` accepts only function as a first argument');
newInfo.poll.generator = actual;
}
return createMatchers(actual, newInfo, prefix);
},
get: function (target, property) {
if (property === 'configure') return configure;
if (property === 'extend') {
return matchers => {
const qualifier = [...prefix, (0, _utils.createGuid)()];
const wrappedMatchers = {};
for (const [name, matcher] of Object.entries(matchers)) {
wrappedMatchers[name] = wrapPlaywrightMatcherToPassNiceThis(matcher);
const key = qualifiedMatcherName(qualifier, name);
wrappedMatchers[key] = wrappedMatchers[name];
Object.defineProperty(wrappedMatchers[key], 'name', {
value: name
});
}
_expectBundle.expect.extend(wrappedMatchers);
return createExpect(info, qualifier, {
...userMatchers,
...matchers
});
};
}
if (property === 'soft') {
return (actual, messageOrOptions) => {
return configure({
soft: true
})(actual, messageOrOptions);
};
}
if (property === userMatchersSymbol) return userMatchers;
if (property === 'poll') {
return (actual, messageOrOptions) => {
const poll = (0, _utils.isString)(messageOrOptions) ? {} : messageOrOptions || {};
return configure({
_poll: poll
})(actual, messageOrOptions);
};
}
return _expectBundle.expect[property];
}
});
const configure = configuration => {
const newInfo = {
...info
};
if ('message' in configuration) newInfo.message = configuration.message;
if ('timeout' in configuration) newInfo.timeout = configuration.timeout;
if ('soft' in configuration) newInfo.isSoft = configuration.soft;
if ('_poll' in configuration) {
newInfo.poll = configuration._poll ? {
...info.poll,
generator: () => {}
} : undefined;
if (typeof configuration._poll === 'object') {
var _configuration$_poll$, _configuration$_poll$2;
newInfo.poll.timeout = (_configuration$_poll$ = configuration._poll.timeout) !== null && _configuration$_poll$ !== void 0 ? _configuration$_poll$ : newInfo.poll.timeout;
newInfo.poll.intervals = (_configuration$_poll$2 = configuration._poll.intervals) !== null && _configuration$_poll$2 !== void 0 ? _configuration$_poll$2 : newInfo.poll.intervals;
}
}
return createExpect(newInfo, prefix, userMatchers);
};
return expectInstance;
}
// Expect wraps matchers, so there is no way to pass this information to the raw Playwright matcher.
// Rely on sync call sequence to seed each matcher call with the context.
let matcherCallContext;
function setMatcherCallContext(context) {
matcherCallContext = context;
}
function takeMatcherCallContext() {
try {
return matcherCallContext;
} finally {
// Any subsequent matcher following the first is assumed to be an unsupported legacy asymmetric matcher.
// Lacking call context in these scenarios is not particularly important.
matcherCallContext = undefined;
}
}
const defaultExpectTimeout = 5000;
function wrapPlaywrightMatcherToPassNiceThis(matcher) {
return function (...args) {
var _ref, _context$expectInfo$t, _context$testInfo;
const {
isNot,
promise,
utils
} = this;
const context = takeMatcherCallContext();
const timeout = (_ref = (_context$expectInfo$t = context === null || context === void 0 ? void 0 : context.expectInfo.timeout) !== null && _context$expectInfo$t !== void 0 ? _context$expectInfo$t : context === null || context === void 0 || (_context$testInfo = context.testInfo) === null || _context$testInfo === void 0 || (_context$testInfo = _context$testInfo._projectInternal) === null || _context$testInfo === void 0 || (_context$testInfo = _context$testInfo.expect) === null || _context$testInfo === void 0 ? void 0 : _context$testInfo.timeout) !== null && _ref !== void 0 ? _ref : defaultExpectTimeout;
const newThis = {
isNot,
promise,
utils,
timeout,
_stepInfo: context === null || context === void 0 ? void 0 : context.step
};
newThis.equals = throwUnsupportedExpectMatcherError;
return matcher.call(newThis, ...args);
};
}
function throwUnsupportedExpectMatcherError() {
throw new Error('It looks like you are using custom expect matchers that are not compatible with Playwright. See https://aka.ms/playwright/expect-compatibility');
}
_expectBundle.expect.setState({
expand: false
});
const customAsyncMatchers = {
toBeAttached: _matchers.toBeAttached,
toBeChecked: _matchers.toBeChecked,
toBeDisabled: _matchers.toBeDisabled,
toBeEditable: _matchers.toBeEditable,
toBeEmpty: _matchers.toBeEmpty,
toBeEnabled: _matchers.toBeEnabled,
toBeFocused: _matchers.toBeFocused,
toBeHidden: _matchers.toBeHidden,
toBeInViewport: _matchers.toBeInViewport,
toBeOK: _matchers.toBeOK,
toBeVisible: _matchers.toBeVisible,
toContainText: _matchers.toContainText,
toHaveAccessibleDescription: _matchers.toHaveAccessibleDescription,
toHaveAccessibleName: _matchers.toHaveAccessibleName,
toHaveAccessibleErrorMessage: _matchers.toHaveAccessibleErrorMessage,
toHaveAttribute: _matchers.toHaveAttribute,
toHaveClass: _matchers.toHaveClass,
toHaveCount: _matchers.toHaveCount,
toHaveCSS: _matchers.toHaveCSS,
toHaveId: _matchers.toHaveId,
toHaveJSProperty: _matchers.toHaveJSProperty,
toHaveRole: _matchers.toHaveRole,
toHaveText: _matchers.toHaveText,
toHaveTitle: _matchers.toHaveTitle,
toHaveURL: _matchers.toHaveURL,
toHaveValue: _matchers.toHaveValue,
toHaveValues: _matchers.toHaveValues,
toHaveScreenshot: _toMatchSnapshot.toHaveScreenshot,
toMatchAriaSnapshot: _toMatchAriaSnapshot.toMatchAriaSnapshot,
toPass: _matchers.toPass
};
const customMatchers = {
...customAsyncMatchers,
toMatchSnapshot: _toMatchSnapshot.toMatchSnapshot
};
class ExpectMetaInfoProxyHandler {
constructor(info, prefix) {
this._info = void 0;
this._prefix = void 0;
this._info = {
...info
};
this._prefix = prefix;
}
get(target, matcherName, receiver) {
let matcher = Reflect.get(target, matcherName, receiver);
if (typeof matcherName !== 'string') return matcher;
let resolvedMatcherName = matcherName;
for (let i = this._prefix.length; i > 0; i--) {
const qualifiedName = qualifiedMatcherName(this._prefix.slice(0, i), matcherName);
if (Reflect.has(target, qualifiedName)) {
matcher = Reflect.get(target, qualifiedName, receiver);
resolvedMatcherName = qualifiedName;
break;
}
}
if (matcher === undefined) throw new Error(`expect: Property '${matcherName}' not found.`);
if (typeof matcher !== 'function') {
if (matcherName === 'not') this._info.isNot = !this._info.isNot;
return new Proxy(matcher, this);
}
if (this._info.poll) {
if (customAsyncMatchers[matcherName] || matcherName === 'resolves' || matcherName === 'rejects') throw new Error(`\`expect.poll()\` does not support "${matcherName}" matcher.`);
matcher = (...args) => pollMatcher(resolvedMatcherName, this._info, this._prefix, ...args);
}
return (...args) => {
const testInfo = (0, _globals.currentTestInfo)();
setMatcherCallContext({
expectInfo: this._info,
testInfo
});
if (!testInfo) return matcher.call(target, ...args);
const customMessage = this._info.message || '';
const argsSuffix = computeArgsSuffix(matcherName, args);
const defaultTitle = `expect${this._info.poll ? '.poll' : ''}${this._info.isSoft ? '.soft' : ''}${this._info.isNot ? '.not' : ''}.${matcherName}${argsSuffix}`;
const title = customMessage || defaultTitle;
// This looks like it is unnecessary, but it isn't - we need to filter
// out all the frames that belong to the test runner from caught runtime errors.
const stackFrames = (0, _util.filteredStackTrace)((0, _utils.captureRawStack)());
// toPass and poll matchers can contain other steps, expects and API calls,
// so they behave like a retriable step.
const stepInfo = {
category: matcherName === 'toPass' || this._info.poll ? 'step' : 'expect',
title: (0, _util.trimLongString)(title, 1024),
params: args[0] ? {
expected: args[0]
} : undefined,
infectParentStepsWithError: this._info.isSoft
};
const step = testInfo._addStep(stepInfo);
const reportStepError = e => {
const jestError = (0, _matcherHint.isJestError)(e) ? e : null;
const error = jestError ? new _matcherHint.ExpectError(jestError, customMessage, stackFrames) : e;
if (jestError !== null && jestError !== void 0 && jestError.matcherResult.suggestedRebaseline) {
// NOTE: this is a workaround for the fact that we can't pass the suggested rebaseline
// for passing matchers. See toMatchAriaSnapshot for a counterpart.
step.complete({
suggestedRebaseline: jestError === null || jestError === void 0 ? void 0 : jestError.matcherResult.suggestedRebaseline
});
return;
}
step.complete({
error
});
if (this._info.isSoft) testInfo._failWithError(error);else throw error;
};
const finalizer = () => {
step.complete({});
};
try {
setMatcherCallContext({
expectInfo: this._info,
testInfo,
step: step.info
});
const callback = () => matcher.call(target, ...args);
const result = (0, _utils.currentZone)().with('stepZone', step).run(callback);
if (result instanceof Promise) {
const promise = result.then(finalizer).catch(reportStepError);
return testInfo._floatingPromiseScope.wrapPromiseAPIResult(promise);
}
finalizer();
return result;
} catch (e) {
reportStepError(e);
}
};
}
}
async function pollMatcher(qualifiedMatcherName, info, prefix, ...args) {
var _ref2, _ref3, _poll$timeout, _testInfo$_projectInt, _poll$intervals;
const testInfo = (0, _globals.currentTestInfo)();
const poll = info.poll;
const timeout = (_ref2 = (_ref3 = (_poll$timeout = poll.timeout) !== null && _poll$timeout !== void 0 ? _poll$timeout : info.timeout) !== null && _ref3 !== void 0 ? _ref3 : testInfo === null || testInfo === void 0 || (_testInfo$_projectInt = testInfo._projectInternal) === null || _testInfo$_projectInt === void 0 || (_testInfo$_projectInt = _testInfo$_projectInt.expect) === null || _testInfo$_projectInt === void 0 ? void 0 : _testInfo$_projectInt.timeout) !== null && _ref2 !== void 0 ? _ref2 : defaultExpectTimeout;
const {
deadline,
timeoutMessage
} = testInfo ? testInfo._deadlineForMatcher(timeout) : _testInfo.TestInfoImpl._defaultDeadlineForMatcher(timeout);
const result = await (0, _utils.pollAgainstDeadline)(async () => {
if (testInfo && (0, _globals.currentTestInfo)() !== testInfo) return {
continuePolling: false,
result: undefined
};
const innerInfo = {
...info,
isSoft: false,
// soft is outside of poll, not inside
poll: undefined
};
const value = await poll.generator();
try {
let matchers = createMatchers(value, innerInfo, prefix);
if (info.isNot) matchers = matchers.not;
matchers[qualifiedMatcherName](...args);
return {
continuePolling: false,
result: undefined
};
} catch (error) {
return {
continuePolling: true,
result: error
};
}
}, deadline, (_poll$intervals = poll.intervals) !== null && _poll$intervals !== void 0 ? _poll$intervals : [100, 250, 500, 1000]);
if (result.timedOut) {
const message = result.result ? [result.result.message, '', `Call Log:`, `- ${timeoutMessage}`].join('\n') : timeoutMessage;
throw new Error(message);
}
}
function computeArgsSuffix(matcherName, args) {
let value = '';
if (matcherName === 'toHaveScreenshot') value = (0, _toMatchSnapshot.toHaveScreenshotStepTitle)(...args);
return value ? `(${value})` : '';
}
const expect = exports.expect = createExpect({}, [], {}).extend(customMatchers);
function mergeExpects(...expects) {
let merged = expect;
for (const e of expects) {
const internals = e[userMatchersSymbol];
if (!internals)
// non-playwright expects mutate the global expect, so we don't need to do anything special
continue;
merged = merged.extend(internals);
}
return merged;
}

49
node_modules/playwright/lib/matchers/matcherHint.js generated vendored Normal file
View File

@@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ExpectError = void 0;
exports.isJestError = isJestError;
exports.kNoElementsFoundError = void 0;
exports.matcherHint = matcherHint;
var _utils = require("playwright-core/lib/utils");
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const kNoElementsFoundError = exports.kNoElementsFoundError = '<element(s) not found>';
function matcherHint(state, locator, matcherName, expression, actual, matcherOptions, timeout) {
let header = state.utils.matcherHint(matcherName, expression, actual, matcherOptions).replace(/ \/\/ deep equality/, '') + '\n\n';
if (timeout) header = _utils.colors.red(`Timed out ${timeout}ms waiting for `) + header;
if (locator) header += `Locator: ${String(locator)}\n`;
return header;
}
class ExpectError extends Error {
constructor(jestError, customMessage, stackFrames) {
super('');
// Copy to erase the JestMatcherError constructor name from the console.log(error).
this.matcherResult = void 0;
this.name = jestError.name;
this.message = jestError.message;
this.matcherResult = jestError.matcherResult;
if (customMessage) this.message = customMessage + '\n\n' + this.message;
this.stack = this.name + ': ' + this.message + '\n' + (0, _utils.stringifyStackFrames)(stackFrames).join('\n');
}
}
exports.ExpectError = ExpectError;
function isJestError(e) {
return e instanceof Error && 'matcherResult' in e;
}

475
node_modules/playwright/lib/matchers/matchers.js generated vendored Normal file
View File

@@ -0,0 +1,475 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.toBeAttached = toBeAttached;
exports.toBeChecked = toBeChecked;
exports.toBeDisabled = toBeDisabled;
exports.toBeEditable = toBeEditable;
exports.toBeEmpty = toBeEmpty;
exports.toBeEnabled = toBeEnabled;
exports.toBeFocused = toBeFocused;
exports.toBeHidden = toBeHidden;
exports.toBeInViewport = toBeInViewport;
exports.toBeOK = toBeOK;
exports.toBeVisible = toBeVisible;
exports.toContainText = toContainText;
exports.toHaveAccessibleDescription = toHaveAccessibleDescription;
exports.toHaveAccessibleErrorMessage = toHaveAccessibleErrorMessage;
exports.toHaveAccessibleName = toHaveAccessibleName;
exports.toHaveAttribute = toHaveAttribute;
exports.toHaveCSS = toHaveCSS;
exports.toHaveClass = toHaveClass;
exports.toHaveCount = toHaveCount;
exports.toHaveId = toHaveId;
exports.toHaveJSProperty = toHaveJSProperty;
exports.toHaveRole = toHaveRole;
exports.toHaveText = toHaveText;
exports.toHaveTitle = toHaveTitle;
exports.toHaveURL = toHaveURL;
exports.toHaveValue = toHaveValue;
exports.toHaveValues = toHaveValues;
exports.toPass = toPass;
var _utils = require("playwright-core/lib/utils");
var _util = require("../util");
var _toBeTruthy = require("./toBeTruthy");
var _toEqual = require("./toEqual");
var _toHaveURL = require("./toHaveURL");
var _toMatchText = require("./toMatchText");
var _config = require("../common/config");
var _globals = require("../common/globals");
var _testInfo = require("../worker/testInfo");
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function toBeAttached(locator, options) {
const attached = !options || options.attached === undefined || options.attached;
const expected = attached ? 'attached' : 'detached';
const arg = attached ? '' : '{ attached: false }';
return _toBeTruthy.toBeTruthy.call(this, 'toBeAttached', locator, 'Locator', expected, arg, async (isNot, timeout) => {
return await locator._expect(attached ? 'to.be.attached' : 'to.be.detached', {
isNot,
timeout
});
}, options);
}
function toBeChecked(locator, options) {
const checked = options === null || options === void 0 ? void 0 : options.checked;
const indeterminate = options === null || options === void 0 ? void 0 : options.indeterminate;
const expectedValue = {
checked,
indeterminate
};
let expected;
let arg;
if (options !== null && options !== void 0 && options.indeterminate) {
expected = 'indeterminate';
arg = `{ indeterminate: true }`;
} else {
expected = (options === null || options === void 0 ? void 0 : options.checked) === false ? 'unchecked' : 'checked';
arg = (options === null || options === void 0 ? void 0 : options.checked) === false ? `{ checked: false }` : '';
}
return _toBeTruthy.toBeTruthy.call(this, 'toBeChecked', locator, 'Locator', expected, arg, async (isNot, timeout) => {
return await locator._expect('to.be.checked', {
isNot,
timeout,
expectedValue
});
}, options);
}
function toBeDisabled(locator, options) {
return _toBeTruthy.toBeTruthy.call(this, 'toBeDisabled', locator, 'Locator', 'disabled', '', async (isNot, timeout) => {
return await locator._expect('to.be.disabled', {
isNot,
timeout
});
}, options);
}
function toBeEditable(locator, options) {
const editable = !options || options.editable === undefined || options.editable;
const expected = editable ? 'editable' : 'readOnly';
const arg = editable ? '' : '{ editable: false }';
return _toBeTruthy.toBeTruthy.call(this, 'toBeEditable', locator, 'Locator', expected, arg, async (isNot, timeout) => {
return await locator._expect(editable ? 'to.be.editable' : 'to.be.readonly', {
isNot,
timeout
});
}, options);
}
function toBeEmpty(locator, options) {
return _toBeTruthy.toBeTruthy.call(this, 'toBeEmpty', locator, 'Locator', 'empty', '', async (isNot, timeout) => {
return await locator._expect('to.be.empty', {
isNot,
timeout
});
}, options);
}
function toBeEnabled(locator, options) {
const enabled = !options || options.enabled === undefined || options.enabled;
const expected = enabled ? 'enabled' : 'disabled';
const arg = enabled ? '' : '{ enabled: false }';
return _toBeTruthy.toBeTruthy.call(this, 'toBeEnabled', locator, 'Locator', expected, arg, async (isNot, timeout) => {
return await locator._expect(enabled ? 'to.be.enabled' : 'to.be.disabled', {
isNot,
timeout
});
}, options);
}
function toBeFocused(locator, options) {
return _toBeTruthy.toBeTruthy.call(this, 'toBeFocused', locator, 'Locator', 'focused', '', async (isNot, timeout) => {
return await locator._expect('to.be.focused', {
isNot,
timeout
});
}, options);
}
function toBeHidden(locator, options) {
return _toBeTruthy.toBeTruthy.call(this, 'toBeHidden', locator, 'Locator', 'hidden', '', async (isNot, timeout) => {
return await locator._expect('to.be.hidden', {
isNot,
timeout
});
}, options);
}
function toBeVisible(locator, options) {
const visible = !options || options.visible === undefined || options.visible;
const expected = visible ? 'visible' : 'hidden';
const arg = visible ? '' : '{ visible: false }';
return _toBeTruthy.toBeTruthy.call(this, 'toBeVisible', locator, 'Locator', expected, arg, async (isNot, timeout) => {
return await locator._expect(visible ? 'to.be.visible' : 'to.be.hidden', {
isNot,
timeout
});
}, options);
}
function toBeInViewport(locator, options) {
return _toBeTruthy.toBeTruthy.call(this, 'toBeInViewport', locator, 'Locator', 'in viewport', '', async (isNot, timeout) => {
return await locator._expect('to.be.in.viewport', {
isNot,
expectedNumber: options === null || options === void 0 ? void 0 : options.ratio,
timeout
});
}, options);
}
function toContainText(locator, expected, options = {}) {
if (Array.isArray(expected)) {
return _toEqual.toEqual.call(this, 'toContainText', locator, 'Locator', async (isNot, timeout) => {
const expectedText = (0, _utils.serializeExpectedTextValues)(expected, {
matchSubstring: true,
normalizeWhiteSpace: true,
ignoreCase: options.ignoreCase
});
return await locator._expect('to.contain.text.array', {
expectedText,
isNot,
useInnerText: options.useInnerText,
timeout
});
}, expected, {
...options,
contains: true
});
} else {
return _toMatchText.toMatchText.call(this, 'toContainText', locator, 'Locator', async (isNot, timeout) => {
const expectedText = (0, _utils.serializeExpectedTextValues)([expected], {
matchSubstring: true,
normalizeWhiteSpace: true,
ignoreCase: options.ignoreCase
});
return await locator._expect('to.have.text', {
expectedText,
isNot,
useInnerText: options.useInnerText,
timeout
});
}, expected, options);
}
}
function toHaveAccessibleDescription(locator, expected, options) {
return _toMatchText.toMatchText.call(this, 'toHaveAccessibleDescription', locator, 'Locator', async (isNot, timeout) => {
const expectedText = (0, _utils.serializeExpectedTextValues)([expected], {
ignoreCase: options === null || options === void 0 ? void 0 : options.ignoreCase,
normalizeWhiteSpace: true
});
return await locator._expect('to.have.accessible.description', {
expectedText,
isNot,
timeout
});
}, expected, options);
}
function toHaveAccessibleName(locator, expected, options) {
return _toMatchText.toMatchText.call(this, 'toHaveAccessibleName', locator, 'Locator', async (isNot, timeout) => {
const expectedText = (0, _utils.serializeExpectedTextValues)([expected], {
ignoreCase: options === null || options === void 0 ? void 0 : options.ignoreCase,
normalizeWhiteSpace: true
});
return await locator._expect('to.have.accessible.name', {
expectedText,
isNot,
timeout
});
}, expected, options);
}
function toHaveAccessibleErrorMessage(locator, expected, options) {
return _toMatchText.toMatchText.call(this, 'toHaveAccessibleErrorMessage', locator, 'Locator', async (isNot, timeout) => {
const expectedText = (0, _utils.serializeExpectedTextValues)([expected], {
ignoreCase: options === null || options === void 0 ? void 0 : options.ignoreCase,
normalizeWhiteSpace: true
});
return await locator._expect('to.have.accessible.error.message', {
expectedText: expectedText,
isNot,
timeout
});
}, expected, options);
}
function toHaveAttribute(locator, name, expected, options) {
if (!options) {
// Update params for the case toHaveAttribute(name, options);
if (typeof expected === 'object' && !(0, _utils.isRegExp)(expected)) {
options = expected;
expected = undefined;
}
}
if (expected === undefined) {
return _toBeTruthy.toBeTruthy.call(this, 'toHaveAttribute', locator, 'Locator', 'have attribute', '', async (isNot, timeout) => {
return await locator._expect('to.have.attribute', {
expressionArg: name,
isNot,
timeout
});
}, options);
}
return _toMatchText.toMatchText.call(this, 'toHaveAttribute', locator, 'Locator', async (isNot, timeout) => {
var _options;
const expectedText = (0, _utils.serializeExpectedTextValues)([expected], {
ignoreCase: (_options = options) === null || _options === void 0 ? void 0 : _options.ignoreCase
});
return await locator._expect('to.have.attribute.value', {
expressionArg: name,
expectedText,
isNot,
timeout
});
}, expected, options);
}
function toHaveClass(locator, expected, options) {
if (Array.isArray(expected)) {
return _toEqual.toEqual.call(this, 'toHaveClass', locator, 'Locator', async (isNot, timeout) => {
const expectedText = (0, _utils.serializeExpectedTextValues)(expected);
return await locator._expect('to.have.class.array', {
expectedText,
isNot,
timeout
});
}, expected, options);
} else {
return _toMatchText.toMatchText.call(this, 'toHaveClass', locator, 'Locator', async (isNot, timeout) => {
const expectedText = (0, _utils.serializeExpectedTextValues)([expected]);
return await locator._expect('to.have.class', {
expectedText,
isNot,
timeout
});
}, expected, options);
}
}
function toHaveCount(locator, expected, options) {
return _toEqual.toEqual.call(this, 'toHaveCount', locator, 'Locator', async (isNot, timeout) => {
return await locator._expect('to.have.count', {
expectedNumber: expected,
isNot,
timeout
});
}, expected, options);
}
function toHaveCSS(locator, name, expected, options) {
return _toMatchText.toMatchText.call(this, 'toHaveCSS', locator, 'Locator', async (isNot, timeout) => {
const expectedText = (0, _utils.serializeExpectedTextValues)([expected]);
return await locator._expect('to.have.css', {
expressionArg: name,
expectedText,
isNot,
timeout
});
}, expected, options);
}
function toHaveId(locator, expected, options) {
return _toMatchText.toMatchText.call(this, 'toHaveId', locator, 'Locator', async (isNot, timeout) => {
const expectedText = (0, _utils.serializeExpectedTextValues)([expected]);
return await locator._expect('to.have.id', {
expectedText,
isNot,
timeout
});
}, expected, options);
}
function toHaveJSProperty(locator, name, expected, options) {
return _toEqual.toEqual.call(this, 'toHaveJSProperty', locator, 'Locator', async (isNot, timeout) => {
return await locator._expect('to.have.property', {
expressionArg: name,
expectedValue: expected,
isNot,
timeout
});
}, expected, options);
}
function toHaveRole(locator, expected, options) {
if (!(0, _utils.isString)(expected)) throw new Error(`"role" argument in toHaveRole must be a string`);
return _toMatchText.toMatchText.call(this, 'toHaveRole', locator, 'Locator', async (isNot, timeout) => {
const expectedText = (0, _utils.serializeExpectedTextValues)([expected]);
return await locator._expect('to.have.role', {
expectedText,
isNot,
timeout
});
}, expected, options);
}
function toHaveText(locator, expected, options = {}) {
if (Array.isArray(expected)) {
return _toEqual.toEqual.call(this, 'toHaveText', locator, 'Locator', async (isNot, timeout) => {
const expectedText = (0, _utils.serializeExpectedTextValues)(expected, {
normalizeWhiteSpace: true,
ignoreCase: options.ignoreCase
});
return await locator._expect('to.have.text.array', {
expectedText,
isNot,
useInnerText: options === null || options === void 0 ? void 0 : options.useInnerText,
timeout
});
}, expected, options);
} else {
return _toMatchText.toMatchText.call(this, 'toHaveText', locator, 'Locator', async (isNot, timeout) => {
const expectedText = (0, _utils.serializeExpectedTextValues)([expected], {
normalizeWhiteSpace: true,
ignoreCase: options.ignoreCase
});
return await locator._expect('to.have.text', {
expectedText,
isNot,
useInnerText: options === null || options === void 0 ? void 0 : options.useInnerText,
timeout
});
}, expected, options);
}
}
function toHaveValue(locator, expected, options) {
return _toMatchText.toMatchText.call(this, 'toHaveValue', locator, 'Locator', async (isNot, timeout) => {
const expectedText = (0, _utils.serializeExpectedTextValues)([expected]);
return await locator._expect('to.have.value', {
expectedText,
isNot,
timeout
});
}, expected, options);
}
function toHaveValues(locator, expected, options) {
return _toEqual.toEqual.call(this, 'toHaveValues', locator, 'Locator', async (isNot, timeout) => {
const expectedText = (0, _utils.serializeExpectedTextValues)(expected);
return await locator._expect('to.have.values', {
expectedText,
isNot,
timeout
});
}, expected, options);
}
function toHaveTitle(page, expected, options = {}) {
const locator = page.locator(':root');
return _toMatchText.toMatchText.call(this, 'toHaveTitle', locator, 'Locator', async (isNot, timeout) => {
const expectedText = (0, _utils.serializeExpectedTextValues)([expected], {
normalizeWhiteSpace: true
});
return await locator._expect('to.have.title', {
expectedText,
isNot,
timeout
});
}, expected, options);
}
function toHaveURL(page, expected, options) {
// Ports don't support predicates. Keep separate server and client codepaths
if (typeof expected === 'function') return _toHaveURL.toHaveURLWithPredicate.call(this, page, expected, options);
const baseURL = page.context()._options.baseURL;
expected = typeof expected === 'string' ? (0, _utils.constructURLBasedOnBaseURL)(baseURL, expected) : expected;
const locator = page.locator(':root');
return _toMatchText.toMatchText.call(this, 'toHaveURL', locator, 'Locator', async (isNot, timeout) => {
const expectedText = (0, _utils.serializeExpectedTextValues)([expected], {
ignoreCase: options === null || options === void 0 ? void 0 : options.ignoreCase
});
return await locator._expect('to.have.url', {
expectedText,
isNot,
timeout
});
}, expected, options);
}
async function toBeOK(response) {
const matcherName = 'toBeOK';
(0, _util.expectTypes)(response, ['APIResponse'], matcherName);
const contentType = response.headers()['content-type'];
const isTextEncoding = contentType && (0, _utils.isTextualMimeType)(contentType);
const [log, text] = this.isNot === response.ok() ? await Promise.all([response._fetchLog(), isTextEncoding ? response.text() : null]) : [];
const message = () => this.utils.matcherHint(matcherName, undefined, '', {
isNot: this.isNot
}) + (0, _util.callLogText)(log) + (text === null ? '' : `\nResponse text:\n${_utils.colors.dim((text === null || text === void 0 ? void 0 : text.substring(0, 1000)) || '')}`);
const pass = response.ok();
return {
message,
pass
};
}
async function toPass(callback, options = {}) {
var _testInfo$_projectInt, _testInfo$_projectInt2;
const testInfo = (0, _globals.currentTestInfo)();
const timeout = (0, _config.takeFirst)(options.timeout, testInfo === null || testInfo === void 0 || (_testInfo$_projectInt = testInfo._projectInternal.expect) === null || _testInfo$_projectInt === void 0 || (_testInfo$_projectInt = _testInfo$_projectInt.toPass) === null || _testInfo$_projectInt === void 0 ? void 0 : _testInfo$_projectInt.timeout, 0);
const intervals = (0, _config.takeFirst)(options.intervals, testInfo === null || testInfo === void 0 || (_testInfo$_projectInt2 = testInfo._projectInternal.expect) === null || _testInfo$_projectInt2 === void 0 || (_testInfo$_projectInt2 = _testInfo$_projectInt2.toPass) === null || _testInfo$_projectInt2 === void 0 ? void 0 : _testInfo$_projectInt2.intervals, [100, 250, 500, 1000]);
const {
deadline,
timeoutMessage
} = testInfo ? testInfo._deadlineForMatcher(timeout) : _testInfo.TestInfoImpl._defaultDeadlineForMatcher(timeout);
const result = await (0, _utils.pollAgainstDeadline)(async () => {
if (testInfo && (0, _globals.currentTestInfo)() !== testInfo) return {
continuePolling: false,
result: undefined
};
try {
await callback();
return {
continuePolling: !!this.isNot,
result: undefined
};
} catch (e) {
return {
continuePolling: !this.isNot,
result: e
};
}
}, deadline, intervals);
if (result.timedOut) {
const message = result.result ? [result.result.message, '', `Call Log:`, `- ${timeoutMessage}`].join('\n') : timeoutMessage;
return {
message: () => message,
pass: !!this.isNot
};
}
return {
pass: !this.isNot,
message: () => ''
};
}

71
node_modules/playwright/lib/matchers/toBeTruthy.js generated vendored Normal file
View File

@@ -0,0 +1,71 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.toBeTruthy = toBeTruthy;
var _util = require("../util");
var _matcherHint = require("./matcherHint");
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
async function toBeTruthy(matcherName, receiver, receiverType, expected, arg, query, options = {}) {
var _options$timeout;
(0, _util.expectTypes)(receiver, [receiverType], matcherName);
const matcherOptions = {
isNot: this.isNot,
promise: this.promise
};
const timeout = (_options$timeout = options.timeout) !== null && _options$timeout !== void 0 ? _options$timeout : this.timeout;
const {
matches: pass,
log,
timedOut,
received
} = await query(!!this.isNot, timeout);
if (pass === !this.isNot) {
return {
name: matcherName,
message: () => '',
pass,
expected
};
}
const notFound = received === _matcherHint.kNoElementsFoundError ? received : undefined;
let printedReceived;
let printedExpected;
if (pass) {
printedExpected = `Expected: not ${expected}`;
printedReceived = `Received: ${notFound ? _matcherHint.kNoElementsFoundError : expected}`;
} else {
printedExpected = `Expected: ${expected}`;
printedReceived = `Received: ${notFound ? _matcherHint.kNoElementsFoundError : received}`;
}
const message = () => {
const header = (0, _matcherHint.matcherHint)(this, receiver, matcherName, 'locator', arg, matcherOptions, timedOut ? timeout : undefined);
const logText = (0, _util.callLogText)(log);
return `${header}${printedExpected}\n${printedReceived}${logText}`;
};
return {
message,
pass,
actual: received,
name: matcherName,
expected,
log,
timeout: timedOut ? timeout : undefined
};
}

85
node_modules/playwright/lib/matchers/toEqual.js generated vendored Normal file
View File

@@ -0,0 +1,85 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.toEqual = toEqual;
var _utils = require("playwright-core/lib/utils");
var _util = require("../util");
var _matcherHint = require("./matcherHint");
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Omit colon and one or more spaces, so can call getLabelPrinter.
const EXPECTED_LABEL = 'Expected';
const RECEIVED_LABEL = 'Received';
async function toEqual(matcherName, receiver, receiverType, query, expected, options = {}) {
var _options$timeout;
(0, _util.expectTypes)(receiver, [receiverType], matcherName);
const matcherOptions = {
comment: options.contains ? '' : 'deep equality',
isNot: this.isNot,
promise: this.promise
};
const timeout = (_options$timeout = options.timeout) !== null && _options$timeout !== void 0 ? _options$timeout : this.timeout;
const {
matches: pass,
received,
log,
timedOut
} = await query(!!this.isNot, timeout);
if (pass === !this.isNot) {
return {
name: matcherName,
message: () => '',
pass,
expected
};
}
let printedReceived;
let printedExpected;
let printedDiff;
if (pass) {
printedExpected = `Expected: not ${this.utils.printExpected(expected)}`;
printedReceived = `Received: ${this.utils.printReceived(received)}`;
} else if (Array.isArray(expected) && Array.isArray(received)) {
const normalizedExpected = expected.map((exp, index) => {
const rec = received[index];
if ((0, _utils.isRegExp)(exp)) return exp.test(rec) ? rec : exp;
return exp;
});
printedDiff = this.utils.printDiffOrStringify(normalizedExpected, received, EXPECTED_LABEL, RECEIVED_LABEL, false);
} else {
printedDiff = this.utils.printDiffOrStringify(expected, received, EXPECTED_LABEL, RECEIVED_LABEL, false);
}
const message = () => {
const header = (0, _matcherHint.matcherHint)(this, receiver, matcherName, 'locator', undefined, matcherOptions, timedOut ? timeout : undefined);
const details = printedDiff || `${printedExpected}\n${printedReceived}`;
return `${header}${details}${(0, _util.callLogText)(log)}`;
};
// Passing the actual and expected objects so that a custom reporter
// could access them, for example in order to display a custom visual diff,
// or create a different error message
return {
actual: received,
expected,
message,
name: matcherName,
pass,
log,
timeout: timedOut ? timeout : undefined
};
}

96
node_modules/playwright/lib/matchers/toHaveURL.js generated vendored Normal file
View File

@@ -0,0 +1,96 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.toHaveURLWithPredicate = toHaveURLWithPredicate;
var _utils = require("playwright-core/lib/utils");
var _expect = require("./expect");
var _matcherHint = require("./matcherHint");
var _expectBundle = require("../common/expectBundle");
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
async function toHaveURLWithPredicate(page, expected, options) {
var _options$timeout;
const matcherName = 'toHaveURL';
const expression = 'page';
const matcherOptions = {
isNot: this.isNot,
promise: this.promise
};
if (typeof expected !== 'function') {
throw new Error([
// Always display `expected` in expectation place
(0, _matcherHint.matcherHint)(this, undefined, matcherName, expression, undefined, matcherOptions), `${_utils.colors.bold('Matcher error')}: ${(0, _expectBundle.EXPECTED_COLOR)('expected')} value must be a string, regular expression, or predicate`, this.utils.printWithType('Expected', expected, this.utils.printExpected)].join('\n\n'));
}
const timeout = (_options$timeout = options === null || options === void 0 ? void 0 : options.timeout) !== null && _options$timeout !== void 0 ? _options$timeout : this.timeout;
const baseURL = page.context()._options.baseURL;
let conditionSucceeded = false;
let lastCheckedURLString = undefined;
try {
await page.mainFrame().waitForURL(url => {
lastCheckedURLString = url.toString();
if (options !== null && options !== void 0 && options.ignoreCase) {
return !this.isNot === (0, _utils.urlMatches)(baseURL === null || baseURL === void 0 ? void 0 : baseURL.toLocaleLowerCase(), lastCheckedURLString.toLocaleLowerCase(), expected);
}
return !this.isNot === (0, _utils.urlMatches)(baseURL, lastCheckedURLString, expected);
}, {
timeout
});
conditionSucceeded = true;
} catch (e) {
conditionSucceeded = false;
}
if (conditionSucceeded) return {
name: matcherName,
pass: !this.isNot,
message: () => ''
};
return {
name: matcherName,
pass: this.isNot,
message: () => toHaveURLMessage(this, matcherName, expression, expected, lastCheckedURLString, this.isNot, true, timeout),
actual: lastCheckedURLString,
timeout
};
}
function toHaveURLMessage(state, matcherName, expression, expected, received, pass, didTimeout, timeout) {
const matcherOptions = {
isNot: state.isNot,
promise: state.promise
};
const receivedString = received || '';
const messagePrefix = (0, _matcherHint.matcherHint)(state, undefined, matcherName, expression, undefined, matcherOptions, didTimeout ? timeout : undefined);
let printedReceived;
let printedExpected;
let printedDiff;
if (typeof expected === 'function') {
printedExpected = `Expected predicate to ${!state.isNot ? 'succeed' : 'fail'}`;
printedReceived = `Received string: ${(0, _expectBundle.printReceived)(receivedString)}`;
} else {
if (pass) {
printedExpected = `Expected pattern: not ${state.utils.printExpected(expected)}`;
const formattedReceived = (0, _expect.printReceivedStringContainExpectedResult)(receivedString, null);
printedReceived = `Received string: ${formattedReceived}`;
} else {
const labelExpected = `Expected ${typeof expected === 'string' ? 'string' : 'pattern'}`;
printedDiff = state.utils.printDiffOrStringify(expected, receivedString, labelExpected, 'Received string', false);
}
}
const resultDetails = printedDiff ? printedDiff : printedExpected + '\n' + printedReceived;
return messagePrefix + resultDetails;
}

View File

@@ -0,0 +1,194 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.toMatchAriaSnapshot = toMatchAriaSnapshot;
var _fs = _interopRequireDefault(require("fs"));
var _path = _interopRequireDefault(require("path"));
var _utils = require("playwright-core/lib/utils");
var _matcherHint = require("./matcherHint");
var _expectBundle = require("../common/expectBundle");
var _util = require("../util");
var _expect = require("./expect");
var _globals = require("../common/globals");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
async function toMatchAriaSnapshot(receiver, expectedParam, options = {}) {
var _testInfo$_projectInt;
const matcherName = 'toMatchAriaSnapshot';
const testInfo = (0, _globals.currentTestInfo)();
if (!testInfo) throw new Error(`toMatchAriaSnapshot() must be called during the test`);
if (testInfo._projectInternal.ignoreSnapshots) return {
pass: !this.isNot,
message: () => '',
name: 'toMatchAriaSnapshot',
expected: ''
};
const updateSnapshots = testInfo.config.updateSnapshots;
const pathTemplate = (_testInfo$_projectInt = testInfo._projectInternal.expect) === null || _testInfo$_projectInt === void 0 || (_testInfo$_projectInt = _testInfo$_projectInt.toMatchAriaSnapshot) === null || _testInfo$_projectInt === void 0 ? void 0 : _testInfo$_projectInt.pathTemplate;
const defaultTemplate = '{snapshotDir}/{testFileDir}/{testFileName}-snapshots/{arg}{ext}';
const matcherOptions = {
isNot: this.isNot,
promise: this.promise
};
let expected;
let timeout;
let expectedPath;
if ((0, _utils.isString)(expectedParam)) {
var _options$timeout;
expected = expectedParam;
timeout = (_options$timeout = options.timeout) !== null && _options$timeout !== void 0 ? _options$timeout : this.timeout;
} else {
var _expectedParam$timeou;
if (expectedParam !== null && expectedParam !== void 0 && expectedParam.name) {
const ext = expectedParam.name.endsWith('.aria.yml') ? '.aria.yml' : undefined;
expectedPath = testInfo._resolveSnapshotPath(pathTemplate, defaultTemplate, [(0, _util.sanitizeFilePathBeforeExtension)(expectedParam.name, ext)]);
} else {
let snapshotNames = testInfo[snapshotNamesSymbol];
if (!snapshotNames) {
snapshotNames = {
anonymousSnapshotIndex: 0
};
testInfo[snapshotNamesSymbol] = snapshotNames;
}
const fullTitleWithoutSpec = [...testInfo.titlePath.slice(1), ++snapshotNames.anonymousSnapshotIndex].join(' ');
expectedPath = testInfo._resolveSnapshotPath(pathTemplate, defaultTemplate, [(0, _utils.sanitizeForFilePath)((0, _util.trimLongString)(fullTitleWithoutSpec))], '.aria.yml');
// in 1.51, we changed the default template to use .aria.yml extension
// for backwards compatibility, we check for the legacy .yml extension
if (!(await (0, _util.fileExistsAsync)(expectedPath))) {
const legacyPath = testInfo._resolveSnapshotPath(pathTemplate, defaultTemplate, [(0, _utils.sanitizeForFilePath)((0, _util.trimLongString)(fullTitleWithoutSpec))], '.yml');
if (await (0, _util.fileExistsAsync)(legacyPath)) expectedPath = legacyPath;
}
}
expected = await _fs.default.promises.readFile(expectedPath, 'utf8').catch(() => '');
timeout = (_expectedParam$timeou = expectedParam === null || expectedParam === void 0 ? void 0 : expectedParam.timeout) !== null && _expectedParam$timeou !== void 0 ? _expectedParam$timeou : this.timeout;
}
const generateMissingBaseline = updateSnapshots === 'missing' && !expected;
if (generateMissingBaseline) {
if (this.isNot) {
const message = `Matchers using ".not" can't generate new baselines`;
return {
pass: this.isNot,
message: () => message,
name: 'toMatchAriaSnapshot'
};
} else {
// When generating new baseline, run entire pipeline against impossible match.
expected = `- none "Generating new baseline"`;
}
}
expected = unshift(expected);
const {
matches: pass,
received,
log,
timedOut
} = await receiver._expect('to.match.aria', {
expectedValue: expected,
isNot: this.isNot,
timeout
});
const typedReceived = received;
const messagePrefix = (0, _matcherHint.matcherHint)(this, receiver, matcherName, 'locator', undefined, matcherOptions, timedOut ? timeout : undefined);
const notFound = typedReceived === _matcherHint.kNoElementsFoundError;
if (notFound) {
return {
pass: this.isNot,
message: () => messagePrefix + `Expected: ${this.utils.printExpected(expected)}\nReceived: ${(0, _expectBundle.EXPECTED_COLOR)('<element not found>')}` + (0, _util.callLogText)(log),
name: 'toMatchAriaSnapshot',
expected
};
}
const receivedText = typedReceived.raw;
const message = () => {
if (pass) {
if (notFound) return messagePrefix + `Expected: not ${this.utils.printExpected(expected)}\nReceived: ${receivedText}` + (0, _util.callLogText)(log);
const printedReceived = (0, _expect.printReceivedStringContainExpectedSubstring)(receivedText, receivedText.indexOf(expected), expected.length);
return messagePrefix + `Expected: not ${this.utils.printExpected(expected)}\nReceived: ${printedReceived}` + (0, _util.callLogText)(log);
} else {
const labelExpected = `Expected`;
if (notFound) return messagePrefix + `${labelExpected}: ${this.utils.printExpected(expected)}\nReceived: ${receivedText}` + (0, _util.callLogText)(log);
return messagePrefix + this.utils.printDiffOrStringify(expected, receivedText, labelExpected, 'Received', false) + (0, _util.callLogText)(log);
}
};
if (!this.isNot) {
if (updateSnapshots === 'all' || updateSnapshots === 'changed' && pass === this.isNot || generateMissingBaseline) {
if (expectedPath) {
await _fs.default.promises.mkdir(_path.default.dirname(expectedPath), {
recursive: true
});
await _fs.default.promises.writeFile(expectedPath, typedReceived.regex, 'utf8');
const relativePath = _path.default.relative(process.cwd(), expectedPath);
if (updateSnapshots === 'missing') {
const message = `A snapshot doesn't exist at ${relativePath}, writing actual.`;
testInfo._hasNonRetriableError = true;
testInfo._failWithError(new Error(message));
} else {
const message = `A snapshot is generated at ${relativePath}.`;
/* eslint-disable no-console */
console.log(message);
}
return {
pass: true,
message: () => '',
name: 'toMatchAriaSnapshot'
};
} else {
const suggestedRebaseline = `\`\n${(0, _utils.escapeTemplateString)(indent(typedReceived.regex, '{indent} '))}\n{indent}\``;
if (updateSnapshots === 'missing') {
const message = 'A snapshot is not provided, generating new baseline.';
testInfo._hasNonRetriableError = true;
testInfo._failWithError(new Error(message));
}
// TODO: ideally, we should return "pass: true" here because this matcher passes
// when regenerating baselines. However, we can only access suggestedRebaseline in case
// of an error, so we fail here and workaround it in the expect implementation.
return {
pass: false,
message: () => '',
name: 'toMatchAriaSnapshot',
suggestedRebaseline
};
}
}
}
return {
name: matcherName,
expected,
message,
pass,
actual: received,
log,
timeout: timedOut ? timeout : undefined
};
}
function unshift(snapshot) {
const lines = snapshot.split('\n');
let whitespacePrefixLength = 100;
for (const line of lines) {
if (!line.trim()) continue;
const match = line.match(/^(\s*)/);
if (match && match[1].length < whitespacePrefixLength) whitespacePrefixLength = match[1].length;
}
return lines.filter(t => t.trim()).map(line => line.substring(whitespacePrefixLength)).join('\n');
}
function indent(snapshot, indent) {
return snapshot.split('\n').map(line => indent + line).join('\n');
}
const snapshotNamesSymbol = Symbol('snapshotNames');

412
node_modules/playwright/lib/matchers/toMatchSnapshot.js generated vendored Normal file
View File

@@ -0,0 +1,412 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.toHaveScreenshot = toHaveScreenshot;
exports.toHaveScreenshotStepTitle = toHaveScreenshotStepTitle;
exports.toMatchSnapshot = toMatchSnapshot;
var _fs = _interopRequireDefault(require("fs"));
var _path = _interopRequireDefault(require("path"));
var _utils = require("playwright-core/lib/utils");
var _utilsBundle = require("playwright-core/lib/utilsBundle");
var _util = require("../util");
var _matcherHint = require("./matcherHint");
var _globals = require("../common/globals");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const snapshotNamesSymbol = Symbol('snapshotNames');
// Keep in sync with above (begin).
const NonConfigProperties = ['clip', 'fullPage', 'mask', 'maskColor', 'omitBackground', 'timeout'];
// Keep in sync with above (end).
class SnapshotHelper {
constructor(testInfo, matcherName, locator, anonymousSnapshotExtension, configOptions, nameOrOptions, optOptions) {
var _mime$getType;
this.testInfo = void 0;
this.attachmentBaseName = void 0;
this.legacyExpectedPath = void 0;
this.previousPath = void 0;
this.expectedPath = void 0;
this.actualPath = void 0;
this.diffPath = void 0;
this.mimeType = void 0;
this.kind = void 0;
this.updateSnapshots = void 0;
this.comparator = void 0;
this.options = void 0;
this.matcherName = void 0;
this.locator = void 0;
let name;
if (Array.isArray(nameOrOptions) || typeof nameOrOptions === 'string') {
name = nameOrOptions;
this.options = {
...optOptions
};
} else {
const {
name: nameFromOptions,
...options
} = nameOrOptions;
this.options = options;
name = nameFromOptions;
}
let snapshotNames = testInfo[snapshotNamesSymbol];
if (!testInfo[snapshotNamesSymbol]) {
snapshotNames = {
anonymousSnapshotIndex: 0,
namedSnapshotIndex: {}
};
testInfo[snapshotNamesSymbol] = snapshotNames;
}
let expectedPathSegments;
let outputBasePath;
if (!name) {
// Consider the use case below. We should save actual to different paths.
// Therefore we auto-increment |anonymousSnapshotIndex|.
//
// expect.toMatchSnapshot('a.png')
// // noop
// expect.toMatchSnapshot('a.png')
const fullTitleWithoutSpec = [...testInfo.titlePath.slice(1), ++snapshotNames.anonymousSnapshotIndex].join(' ');
// Note: expected path must not ever change for backwards compatibility.
expectedPathSegments = [(0, _utils.sanitizeForFilePath)((0, _util.trimLongString)(fullTitleWithoutSpec)) + '.' + anonymousSnapshotExtension];
// Trim the output file paths more aggressively to avoid hitting Windows filesystem limits.
const sanitizedName = (0, _utils.sanitizeForFilePath)((0, _util.trimLongString)(fullTitleWithoutSpec, _util.windowsFilesystemFriendlyLength)) + '.' + anonymousSnapshotExtension;
outputBasePath = testInfo._getOutputPath(sanitizedName);
this.attachmentBaseName = sanitizedName;
} else {
// We intentionally do not sanitize user-provided array of segments, assuming
// it is a file system path. See https://github.com/microsoft/playwright/pull/9156.
// Note: expected path must not ever change for backwards compatibility.
expectedPathSegments = Array.isArray(name) ? name : [(0, _util.sanitizeFilePathBeforeExtension)(name)];
const joinedName = Array.isArray(name) ? name.join(_path.default.sep) : (0, _util.sanitizeFilePathBeforeExtension)((0, _util.trimLongString)(name, _util.windowsFilesystemFriendlyLength));
snapshotNames.namedSnapshotIndex[joinedName] = (snapshotNames.namedSnapshotIndex[joinedName] || 0) + 1;
const index = snapshotNames.namedSnapshotIndex[joinedName];
const sanitizedName = index > 1 ? (0, _util.addSuffixToFilePath)(joinedName, `-${index - 1}`) : joinedName;
outputBasePath = testInfo._getOutputPath(sanitizedName);
this.attachmentBaseName = sanitizedName;
}
const defaultTemplate = '{snapshotDir}/{testFileDir}/{testFileName}-snapshots/{arg}{-projectName}{-snapshotSuffix}{ext}';
this.expectedPath = testInfo._resolveSnapshotPath(configOptions.pathTemplate, defaultTemplate, expectedPathSegments);
this.legacyExpectedPath = (0, _util.addSuffixToFilePath)(outputBasePath, '-expected');
this.previousPath = (0, _util.addSuffixToFilePath)(outputBasePath, '-previous');
this.actualPath = (0, _util.addSuffixToFilePath)(outputBasePath, '-actual');
this.diffPath = (0, _util.addSuffixToFilePath)(outputBasePath, '-diff');
const filteredConfigOptions = {
...configOptions
};
for (const prop of NonConfigProperties) delete filteredConfigOptions[prop];
this.options = {
...filteredConfigOptions,
...this.options
};
// While comparator is not a part of the public API, it is translated here.
if (this.options._comparator) {
this.options.comparator = this.options._comparator;
delete this.options._comparator;
}
if (this.options.maxDiffPixels !== undefined && this.options.maxDiffPixels < 0) throw new Error('`maxDiffPixels` option value must be non-negative integer');
if (this.options.maxDiffPixelRatio !== undefined && (this.options.maxDiffPixelRatio < 0 || this.options.maxDiffPixelRatio > 1)) throw new Error('`maxDiffPixelRatio` option value must be between 0 and 1');
this.matcherName = matcherName;
this.locator = locator;
this.updateSnapshots = testInfo.config.updateSnapshots;
this.mimeType = (_mime$getType = _utilsBundle.mime.getType(_path.default.basename(this.expectedPath))) !== null && _mime$getType !== void 0 ? _mime$getType : 'application/octet-string';
this.comparator = (0, _utils.getComparator)(this.mimeType);
this.testInfo = testInfo;
this.kind = this.mimeType.startsWith('image/') ? 'Screenshot' : 'Snapshot';
}
createMatcherResult(message, pass, log) {
const unfiltered = {
name: this.matcherName,
expected: this.expectedPath,
actual: this.actualPath,
diff: this.diffPath,
pass,
message: () => message,
log
};
return Object.fromEntries(Object.entries(unfiltered).filter(([_, v]) => v !== undefined));
}
handleMissingNegated() {
const isWriteMissingMode = this.updateSnapshots !== 'none';
const message = `A snapshot doesn't exist at ${this.expectedPath}${isWriteMissingMode ? ', matchers using ".not" won\'t write them automatically.' : '.'}`;
// NOTE: 'isNot' matcher implies inversed value.
return this.createMatcherResult(message, true);
}
handleDifferentNegated() {
// NOTE: 'isNot' matcher implies inversed value.
return this.createMatcherResult('', false);
}
handleMatchingNegated() {
const message = [_utils.colors.red(`${this.kind} comparison failed:`), '', indent('Expected result should be different from the actual one.', ' ')].join('\n');
// NOTE: 'isNot' matcher implies inversed value.
return this.createMatcherResult(message, true);
}
handleMissing(actual, step) {
const isWriteMissingMode = this.updateSnapshots !== 'none';
if (isWriteMissingMode) writeFileSync(this.expectedPath, actual);
step === null || step === void 0 || step._attachToStep({
name: (0, _util.addSuffixToFilePath)(this.attachmentBaseName, '-expected'),
contentType: this.mimeType,
path: this.expectedPath
});
writeFileSync(this.actualPath, actual);
step === null || step === void 0 || step._attachToStep({
name: (0, _util.addSuffixToFilePath)(this.attachmentBaseName, '-actual'),
contentType: this.mimeType,
path: this.actualPath
});
const message = `A snapshot doesn't exist at ${this.expectedPath}${isWriteMissingMode ? ', writing actual.' : '.'}`;
if (this.updateSnapshots === 'all' || this.updateSnapshots === 'changed') {
/* eslint-disable no-console */
console.log(message);
return this.createMatcherResult(message, true);
}
if (this.updateSnapshots === 'missing') {
this.testInfo._hasNonRetriableError = true;
this.testInfo._failWithError(new Error(message));
return this.createMatcherResult('', true);
}
return this.createMatcherResult(message, false);
}
handleDifferent(actual, expected, previous, diff, header, diffError, log, step) {
const output = [`${header}${indent(diffError, ' ')}`];
if (expected !== undefined) {
// Copy the expectation inside the `test-results/` folder for backwards compatibility,
// so that one can upload `test-results/` directory and have all the data inside.
writeFileSync(this.legacyExpectedPath, expected);
step === null || step === void 0 || step._attachToStep({
name: (0, _util.addSuffixToFilePath)(this.attachmentBaseName, '-expected'),
contentType: this.mimeType,
path: this.expectedPath
});
output.push(`\nExpected: ${_utils.colors.yellow(this.expectedPath)}`);
}
if (previous !== undefined) {
writeFileSync(this.previousPath, previous);
step === null || step === void 0 || step._attachToStep({
name: (0, _util.addSuffixToFilePath)(this.attachmentBaseName, '-previous'),
contentType: this.mimeType,
path: this.previousPath
});
output.push(`Previous: ${_utils.colors.yellow(this.previousPath)}`);
}
if (actual !== undefined) {
writeFileSync(this.actualPath, actual);
step === null || step === void 0 || step._attachToStep({
name: (0, _util.addSuffixToFilePath)(this.attachmentBaseName, '-actual'),
contentType: this.mimeType,
path: this.actualPath
});
output.push(`Received: ${_utils.colors.yellow(this.actualPath)}`);
}
if (diff !== undefined) {
writeFileSync(this.diffPath, diff);
step === null || step === void 0 || step._attachToStep({
name: (0, _util.addSuffixToFilePath)(this.attachmentBaseName, '-diff'),
contentType: this.mimeType,
path: this.diffPath
});
output.push(` Diff: ${_utils.colors.yellow(this.diffPath)}`);
}
if (log !== null && log !== void 0 && log.length) output.push((0, _util.callLogText)(log));else output.push('');
return this.createMatcherResult(output.join('\n'), false, log);
}
handleMatching() {
return this.createMatcherResult('', true);
}
}
function toMatchSnapshot(received, nameOrOptions = {}, optOptions = {}) {
var _testInfo$_projectInt;
const testInfo = (0, _globals.currentTestInfo)();
if (!testInfo) throw new Error(`toMatchSnapshot() must be called during the test`);
if (received instanceof Promise) throw new Error('An unresolved Promise was passed to toMatchSnapshot(), make sure to resolve it by adding await to it.');
if (testInfo._projectInternal.ignoreSnapshots) return {
pass: !this.isNot,
message: () => '',
name: 'toMatchSnapshot',
expected: nameOrOptions
};
const configOptions = ((_testInfo$_projectInt = testInfo._projectInternal.expect) === null || _testInfo$_projectInt === void 0 ? void 0 : _testInfo$_projectInt.toMatchSnapshot) || {};
const helper = new SnapshotHelper(testInfo, 'toMatchSnapshot', undefined, determineFileExtension(received), configOptions, nameOrOptions, optOptions);
if (this.isNot) {
if (!_fs.default.existsSync(helper.expectedPath)) return helper.handleMissingNegated();
const isDifferent = !!helper.comparator(received, _fs.default.readFileSync(helper.expectedPath), helper.options);
return isDifferent ? helper.handleDifferentNegated() : helper.handleMatchingNegated();
}
if (!_fs.default.existsSync(helper.expectedPath)) return helper.handleMissing(received, this._stepInfo);
const expected = _fs.default.readFileSync(helper.expectedPath);
if (helper.updateSnapshots === 'all') {
if (!(0, _utils.compareBuffersOrStrings)(received, expected)) return helper.handleMatching();
writeFileSync(helper.expectedPath, received);
/* eslint-disable no-console */
console.log(helper.expectedPath + ' is not the same, writing actual.');
return helper.createMatcherResult(helper.expectedPath + ' running with --update-snapshots, writing actual.', true);
}
if (helper.updateSnapshots === 'changed') {
const result = helper.comparator(received, expected, helper.options);
if (!result) return helper.handleMatching();
writeFileSync(helper.expectedPath, received);
/* eslint-disable no-console */
console.log(helper.expectedPath + ' does not match, writing actual.');
return helper.createMatcherResult(helper.expectedPath + ' running with --update-snapshots, writing actual.', true);
}
const result = helper.comparator(received, expected, helper.options);
if (!result) return helper.handleMatching();
const receiver = (0, _utils.isString)(received) ? 'string' : 'Buffer';
const header = (0, _matcherHint.matcherHint)(this, undefined, 'toMatchSnapshot', receiver, undefined, undefined);
return helper.handleDifferent(received, expected, undefined, result.diff, header, result.errorMessage, undefined, this._stepInfo);
}
function toHaveScreenshotStepTitle(nameOrOptions = {}, optOptions = {}) {
let name;
if (typeof nameOrOptions === 'object' && !Array.isArray(nameOrOptions)) name = nameOrOptions.name;else name = nameOrOptions;
return Array.isArray(name) ? name.join(_path.default.sep) : name || '';
}
async function toHaveScreenshot(pageOrLocator, nameOrOptions = {}, optOptions = {}) {
var _testInfo$_projectInt2, _helper$options$timeo, _helper$options$anima, _helper$options$caret, _helper$options$scale;
const testInfo = (0, _globals.currentTestInfo)();
if (!testInfo) throw new Error(`toHaveScreenshot() must be called during the test`);
if (testInfo._projectInternal.ignoreSnapshots) return {
pass: !this.isNot,
message: () => '',
name: 'toHaveScreenshot',
expected: nameOrOptions
};
(0, _util.expectTypes)(pageOrLocator, ['Page', 'Locator'], 'toHaveScreenshot');
const [page, locator] = pageOrLocator.constructor.name === 'Page' ? [pageOrLocator, undefined] : [pageOrLocator.page(), pageOrLocator];
const configOptions = ((_testInfo$_projectInt2 = testInfo._projectInternal.expect) === null || _testInfo$_projectInt2 === void 0 ? void 0 : _testInfo$_projectInt2.toHaveScreenshot) || {};
const helper = new SnapshotHelper(testInfo, 'toHaveScreenshot', locator, 'png', configOptions, nameOrOptions, optOptions);
if (!helper.expectedPath.toLowerCase().endsWith('.png')) throw new Error(`Screenshot name "${_path.default.basename(helper.expectedPath)}" must have '.png' extension`);
(0, _util.expectTypes)(pageOrLocator, ['Page', 'Locator'], 'toHaveScreenshot');
const style = await loadScreenshotStyles(helper.options.stylePath);
const timeout = (_helper$options$timeo = helper.options.timeout) !== null && _helper$options$timeo !== void 0 ? _helper$options$timeo : this.timeout;
const expectScreenshotOptions = {
locator,
animations: (_helper$options$anima = helper.options.animations) !== null && _helper$options$anima !== void 0 ? _helper$options$anima : 'disabled',
caret: (_helper$options$caret = helper.options.caret) !== null && _helper$options$caret !== void 0 ? _helper$options$caret : 'hide',
clip: helper.options.clip,
fullPage: helper.options.fullPage,
mask: helper.options.mask,
maskColor: helper.options.maskColor,
omitBackground: helper.options.omitBackground,
scale: (_helper$options$scale = helper.options.scale) !== null && _helper$options$scale !== void 0 ? _helper$options$scale : 'css',
style,
isNot: !!this.isNot,
timeout,
comparator: helper.options.comparator,
maxDiffPixels: helper.options.maxDiffPixels,
maxDiffPixelRatio: helper.options.maxDiffPixelRatio,
threshold: helper.options.threshold
};
const hasSnapshot = _fs.default.existsSync(helper.expectedPath);
if (this.isNot) {
if (!hasSnapshot) return helper.handleMissingNegated();
// Having `errorMessage` means we timed out while waiting
// for screenshots not to match, so screenshots
// are actually the same in the end.
expectScreenshotOptions.expected = await _fs.default.promises.readFile(helper.expectedPath);
const isDifferent = !(await page._expectScreenshot(expectScreenshotOptions)).errorMessage;
return isDifferent ? helper.handleDifferentNegated() : helper.handleMatchingNegated();
}
// Fast path: there's no screenshot and we don't intend to update it.
if (helper.updateSnapshots === 'none' && !hasSnapshot) return helper.createMatcherResult(`A snapshot doesn't exist at ${helper.expectedPath}.`, false);
const receiver = locator ? 'locator' : 'page';
if (!hasSnapshot) {
// Regenerate a new screenshot by waiting until two screenshots are the same.
const {
actual,
previous,
diff,
errorMessage,
log,
timedOut
} = await page._expectScreenshot(expectScreenshotOptions);
// We tried re-generating new snapshot but failed.
// This can be due to e.g. spinning animation, so we want to show it as a diff.
if (errorMessage) {
const header = (0, _matcherHint.matcherHint)(this, locator, 'toHaveScreenshot', receiver, undefined, undefined, timedOut ? timeout : undefined);
return helper.handleDifferent(actual, undefined, previous, diff, header, errorMessage, log, this._stepInfo);
}
// We successfully generated new screenshot.
return helper.handleMissing(actual, this._stepInfo);
}
// General case:
// - snapshot exists
// - regular matcher (i.e. not a `.not`)
const expected = await _fs.default.promises.readFile(helper.expectedPath);
expectScreenshotOptions.expected = helper.updateSnapshots === 'all' ? undefined : expected;
const {
actual,
previous,
diff,
errorMessage,
log,
timedOut
} = await page._expectScreenshot(expectScreenshotOptions);
const writeFiles = () => {
writeFileSync(helper.expectedPath, actual);
writeFileSync(helper.actualPath, actual);
/* eslint-disable no-console */
console.log(helper.expectedPath + ' is re-generated, writing actual.');
return helper.createMatcherResult(helper.expectedPath + ' running with --update-snapshots, writing actual.', true);
};
if (!errorMessage) {
// Screenshot is matching, but is not necessarily the same as the expected.
if (helper.updateSnapshots === 'all' && actual && (0, _utils.compareBuffersOrStrings)(actual, expected)) {
console.log(helper.expectedPath + ' is re-generated, writing actual.');
return writeFiles();
}
return helper.handleMatching();
}
if (helper.updateSnapshots === 'changed' || helper.updateSnapshots === 'all') return writeFiles();
const header = (0, _matcherHint.matcherHint)(this, undefined, 'toHaveScreenshot', receiver, undefined, undefined, timedOut ? timeout : undefined);
return helper.handleDifferent(actual, expectScreenshotOptions.expected, previous, diff, header, errorMessage, log, this._stepInfo);
}
function writeFileSync(aPath, content) {
_fs.default.mkdirSync(_path.default.dirname(aPath), {
recursive: true
});
_fs.default.writeFileSync(aPath, content);
}
function indent(lines, tab) {
return lines.replace(/^(?=.+$)/gm, tab);
}
function determineFileExtension(file) {
if (typeof file === 'string') return 'txt';
if (compareMagicBytes(file, [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])) return 'png';
if (compareMagicBytes(file, [0xff, 0xd8, 0xff])) return 'jpg';
return 'dat';
}
function compareMagicBytes(file, magicBytes) {
return Buffer.compare(Buffer.from(magicBytes), file.slice(0, magicBytes.length)) === 0;
}
async function loadScreenshotStyles(stylePath) {
if (!stylePath) return;
const stylePaths = Array.isArray(stylePath) ? stylePath : [stylePath];
const styles = await Promise.all(stylePaths.map(async stylePath => {
const text = await _fs.default.promises.readFile(stylePath, 'utf8');
return text.trim();
}));
return styles.join('\n').trim() || undefined;
}

103
node_modules/playwright/lib/matchers/toMatchText.js generated vendored Normal file
View File

@@ -0,0 +1,103 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.toMatchText = toMatchText;
var _utils = require("playwright-core/lib/utils");
var _util = require("../util");
var _expect = require("./expect");
var _matcherHint = require("./matcherHint");
var _expectBundle = require("../common/expectBundle");
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
async function toMatchText(matcherName, receiver, receiverType, query, expected, options = {}) {
var _options$timeout;
(0, _util.expectTypes)(receiver, [receiverType], matcherName);
const matcherOptions = {
isNot: this.isNot,
promise: this.promise
};
if (!(typeof expected === 'string') && !(expected && typeof expected.test === 'function')) {
// Same format as jest's matcherErrorMessage
throw new Error([(0, _matcherHint.matcherHint)(this, receiver, matcherName, receiver, expected, matcherOptions), `${_utils.colors.bold('Matcher error')}: ${(0, _expectBundle.EXPECTED_COLOR)('expected')} value must be a string or regular expression`, this.utils.printWithType('Expected', expected, this.utils.printExpected)].join('\n\n'));
}
const timeout = (_options$timeout = options.timeout) !== null && _options$timeout !== void 0 ? _options$timeout : this.timeout;
const {
matches: pass,
received,
log,
timedOut
} = await query(!!this.isNot, timeout);
if (pass === !this.isNot) {
return {
name: matcherName,
message: () => '',
pass,
expected
};
}
const stringSubstring = options.matchSubstring ? 'substring' : 'string';
const receivedString = received || '';
const messagePrefix = (0, _matcherHint.matcherHint)(this, receiver, matcherName, 'locator', undefined, matcherOptions, timedOut ? timeout : undefined);
const notFound = received === _matcherHint.kNoElementsFoundError;
let printedReceived;
let printedExpected;
let printedDiff;
if (pass) {
if (typeof expected === 'string') {
if (notFound) {
printedExpected = `Expected ${stringSubstring}: not ${this.utils.printExpected(expected)}`;
printedReceived = `Received: ${received}`;
} else {
printedExpected = `Expected ${stringSubstring}: not ${this.utils.printExpected(expected)}`;
const formattedReceived = (0, _expect.printReceivedStringContainExpectedSubstring)(receivedString, receivedString.indexOf(expected), expected.length);
printedReceived = `Received string: ${formattedReceived}`;
}
} else {
if (notFound) {
printedExpected = `Expected pattern: not ${this.utils.printExpected(expected)}`;
printedReceived = `Received: ${received}`;
} else {
printedExpected = `Expected pattern: not ${this.utils.printExpected(expected)}`;
const formattedReceived = (0, _expect.printReceivedStringContainExpectedResult)(receivedString, typeof expected.exec === 'function' ? expected.exec(receivedString) : null);
printedReceived = `Received string: ${formattedReceived}`;
}
}
} else {
const labelExpected = `Expected ${typeof expected === 'string' ? stringSubstring : 'pattern'}`;
if (notFound) {
printedExpected = `${labelExpected}: ${this.utils.printExpected(expected)}`;
printedReceived = `Received: ${received}`;
} else {
printedDiff = this.utils.printDiffOrStringify(expected, receivedString, labelExpected, 'Received string', false);
}
}
const message = () => {
const resultDetails = printedDiff ? printedDiff : printedExpected + '\n' + printedReceived;
return messagePrefix + resultDetails + (0, _util.callLogText)(log);
};
return {
name: matcherName,
expected,
message,
pass,
actual: received,
log,
timeout: timedOut ? timeout : undefined
};
}