chore: add a test for the log scale polling (#9136)
This commit is contained in:
parent
1db41c330a
commit
db6c55af51
|
|
@ -1241,7 +1241,7 @@ export class Frame extends SdkObject {
|
||||||
selector: string,
|
selector: string,
|
||||||
body: DomTaskBody<T, R>,
|
body: DomTaskBody<T, R>,
|
||||||
taskData: T,
|
taskData: T,
|
||||||
options: types.TimeoutOptions & types.StrictOptions & { mainWorld?: boolean } & { querySelectorAll?: boolean } & { logScale?: boolean } = {}): Promise<R> {
|
options: types.TimeoutOptions & types.StrictOptions & { mainWorld?: boolean, querySelectorAll?: boolean, logScale?: boolean } = {}): Promise<R> {
|
||||||
|
|
||||||
const info = this._page.parseSelector(selector, options);
|
const info = this._page.parseSelector(selector, options);
|
||||||
const callbackText = body.toString();
|
const callbackText = body.toString();
|
||||||
|
|
|
||||||
|
|
@ -800,8 +800,11 @@ export class InjectedScript {
|
||||||
throw injected.createStacklessError('Element is not a checkbox');
|
throw injected.createStacklessError('Element is not a checkbox');
|
||||||
if (elementState === 'error:notconnected')
|
if (elementState === 'error:notconnected')
|
||||||
throw injected.createStacklessError('Element is not connected');
|
throw injected.createStacklessError('Element is not connected');
|
||||||
if (elementState === options.isNot)
|
if (elementState === options.isNot) {
|
||||||
|
progress.setIntermediateResult(elementState);
|
||||||
|
progress.log(` unexpected value "${elementState}"`);
|
||||||
return continuePolling;
|
return continuePolling;
|
||||||
|
}
|
||||||
return { pass: !options.isNot };
|
return { pass: !options.isNot };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -811,8 +814,11 @@ export class InjectedScript {
|
||||||
if (expression === 'to.have.count') {
|
if (expression === 'to.have.count') {
|
||||||
const received = elements.length;
|
const received = elements.length;
|
||||||
const matches = received === options.expectedNumber;
|
const matches = received === options.expectedNumber;
|
||||||
if (matches === options.isNot)
|
if (matches === options.isNot) {
|
||||||
|
progress.setIntermediateResult(received);
|
||||||
|
progress.log(` unexpected value "${received}"`);
|
||||||
return continuePolling;
|
return continuePolling;
|
||||||
|
}
|
||||||
return { pass: !options.isNot, received };
|
return { pass: !options.isNot, received };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -824,6 +830,7 @@ export class InjectedScript {
|
||||||
const matches = deepEquals(received, options.expectedValue);
|
const matches = deepEquals(received, options.expectedValue);
|
||||||
if (matches === options.isNot) {
|
if (matches === options.isNot) {
|
||||||
progress.setIntermediateResult(received);
|
progress.setIntermediateResult(received);
|
||||||
|
progress.log(` unexpected value "${received}"`);
|
||||||
return continuePolling;
|
return continuePolling;
|
||||||
}
|
}
|
||||||
return { received, pass: !options.isNot };
|
return { received, pass: !options.isNot };
|
||||||
|
|
@ -857,6 +864,7 @@ export class InjectedScript {
|
||||||
const matcher = new ExpectedTextMatcher(options.expectedText[0]);
|
const matcher = new ExpectedTextMatcher(options.expectedText[0]);
|
||||||
if (matcher.matches(received) === options.isNot) {
|
if (matcher.matches(received) === options.isNot) {
|
||||||
progress.setIntermediateResult(received);
|
progress.setIntermediateResult(received);
|
||||||
|
progress.log(` unexpected value "${received}"`);
|
||||||
return continuePolling;
|
return continuePolling;
|
||||||
}
|
}
|
||||||
return { received, pass: !options.isNot };
|
return { received, pass: !options.isNot };
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import { toEqual } from './toEqual';
|
||||||
import { toExpectedTextValues, toMatchText } from './toMatchText';
|
import { toExpectedTextValues, toMatchText } from './toMatchText';
|
||||||
|
|
||||||
interface LocatorEx extends Locator {
|
interface LocatorEx extends Locator {
|
||||||
_expect(expression: string, options: channels.FrameExpectOptions): Promise<{ pass: boolean, received?: string, log?: string[] }>;
|
_expect(expression: string, options: channels.FrameExpectOptions): Promise<{ pass: boolean, received?: any, log?: string[] }>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function toBeChecked(
|
export function toBeChecked(
|
||||||
|
|
@ -115,7 +115,7 @@ export function toContainText(
|
||||||
return toMatchText.call(this, 'toContainText', locator, 'Locator', async (isNot, timeout) => {
|
return toMatchText.call(this, 'toContainText', locator, 'Locator', async (isNot, timeout) => {
|
||||||
const expectedText = toExpectedTextValues([expected], { matchSubstring: true, normalizeWhiteSpace: true });
|
const expectedText = toExpectedTextValues([expected], { matchSubstring: true, normalizeWhiteSpace: true });
|
||||||
return await locator._expect('to.have.text', { expectedText, isNot, useInnerText: options?.useInnerText, timeout });
|
return await locator._expect('to.have.text', { expectedText, isNot, useInnerText: options?.useInnerText, timeout });
|
||||||
}, expected, { ...options, matchSubstring: true });
|
}, expected, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function toHaveAttribute(
|
export function toHaveAttribute(
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,14 @@
|
||||||
import { currentTestInfo } from '../globals';
|
import { currentTestInfo } from '../globals';
|
||||||
import type { Expect } from '../types';
|
import type { Expect } from '../types';
|
||||||
import { expectType } from '../util';
|
import { expectType } from '../util';
|
||||||
|
import { callLogText } from './toMatchText';
|
||||||
|
|
||||||
export async function toBeTruthy(
|
export async function toBeTruthy(
|
||||||
this: ReturnType<Expect['getState']>,
|
this: ReturnType<Expect['getState']>,
|
||||||
matcherName: string,
|
matcherName: string,
|
||||||
receiver: any,
|
receiver: any,
|
||||||
receiverType: string,
|
receiverType: string,
|
||||||
query: (isNot: boolean, timeout: number) => Promise<{ pass: boolean }>,
|
query: (isNot: boolean, timeout: number) => Promise<{ pass: boolean, log?: string[] }>,
|
||||||
options: { timeout?: number } = {},
|
options: { timeout?: number } = {},
|
||||||
) {
|
) {
|
||||||
const testInfo = currentTestInfo();
|
const testInfo = currentTestInfo();
|
||||||
|
|
@ -41,10 +42,10 @@ export async function toBeTruthy(
|
||||||
defaultExpectTimeout = 5000;
|
defaultExpectTimeout = 5000;
|
||||||
const timeout = options.timeout === 0 ? 0 : options.timeout || defaultExpectTimeout;
|
const timeout = options.timeout === 0 ? 0 : options.timeout || defaultExpectTimeout;
|
||||||
|
|
||||||
const { pass } = await query(this.isNot, timeout);
|
const { pass, log } = await query(this.isNot, timeout);
|
||||||
|
|
||||||
const message = () => {
|
const message = () => {
|
||||||
return this.utils.matcherHint(matcherName, undefined, '', matcherOptions);
|
return this.utils.matcherHint(matcherName, undefined, '', matcherOptions) + callLogText(log);
|
||||||
};
|
};
|
||||||
|
|
||||||
return { message, pass };
|
return { message, pass };
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
import { currentTestInfo } from '../globals';
|
import { currentTestInfo } from '../globals';
|
||||||
import type { Expect } from '../types';
|
import type { Expect } from '../types';
|
||||||
import { expectType } from '../util';
|
import { expectType } from '../util';
|
||||||
|
import { callLogText } from './toMatchText';
|
||||||
|
|
||||||
// Omit colon and one or more spaces, so can call getLabelPrinter.
|
// Omit colon and one or more spaces, so can call getLabelPrinter.
|
||||||
const EXPECTED_LABEL = 'Expected';
|
const EXPECTED_LABEL = 'Expected';
|
||||||
|
|
@ -30,7 +31,7 @@ export async function toEqual<T>(
|
||||||
matcherName: string,
|
matcherName: string,
|
||||||
receiver: any,
|
receiver: any,
|
||||||
receiverType: string,
|
receiverType: string,
|
||||||
query: (isNot: boolean, timeout: number) => Promise<{ pass: boolean, received?: any }>,
|
query: (isNot: boolean, timeout: number) => Promise<{ pass: boolean, received?: any, log?: string[] }>,
|
||||||
expected: T,
|
expected: T,
|
||||||
options: { timeout?: number } = {},
|
options: { timeout?: number } = {},
|
||||||
) {
|
) {
|
||||||
|
|
@ -50,7 +51,7 @@ export async function toEqual<T>(
|
||||||
defaultExpectTimeout = 5000;
|
defaultExpectTimeout = 5000;
|
||||||
const timeout = options.timeout === 0 ? 0 : options.timeout || defaultExpectTimeout;
|
const timeout = options.timeout === 0 ? 0 : options.timeout || defaultExpectTimeout;
|
||||||
|
|
||||||
const { pass, received } = await query(this.isNot, timeout);
|
const { pass, received, log } = await query(this.isNot, timeout);
|
||||||
|
|
||||||
const message = pass
|
const message = pass
|
||||||
? () =>
|
? () =>
|
||||||
|
|
@ -59,7 +60,7 @@ export async function toEqual<T>(
|
||||||
`Expected: not ${this.utils.printExpected(expected)}\n` +
|
`Expected: not ${this.utils.printExpected(expected)}\n` +
|
||||||
(this.utils.stringify(expected) !== this.utils.stringify(received)
|
(this.utils.stringify(expected) !== this.utils.stringify(received)
|
||||||
? `Received: ${this.utils.printReceived(received)}`
|
? `Received: ${this.utils.printReceived(received)}`
|
||||||
: '')
|
: '') + callLogText(log)
|
||||||
: () =>
|
: () =>
|
||||||
this.utils.matcherHint(matcherName, undefined, undefined, matcherOptions) +
|
this.utils.matcherHint(matcherName, undefined, undefined, matcherOptions) +
|
||||||
'\n\n' +
|
'\n\n' +
|
||||||
|
|
@ -69,7 +70,7 @@ export async function toEqual<T>(
|
||||||
EXPECTED_LABEL,
|
EXPECTED_LABEL,
|
||||||
RECEIVED_LABEL,
|
RECEIVED_LABEL,
|
||||||
isExpand(this.expand),
|
isExpand(this.expand),
|
||||||
);
|
) + callLogText(log);
|
||||||
|
|
||||||
// Passing the actual and expected objects so that a custom reporter
|
// Passing the actual and expected objects so that a custom reporter
|
||||||
// could access them, for example in order to display a custom visual diff,
|
// could access them, for example in order to display a custom visual diff,
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ export async function toMatchText(
|
||||||
matcherName: string,
|
matcherName: string,
|
||||||
receiver: any,
|
receiver: any,
|
||||||
receiverType: string,
|
receiverType: string,
|
||||||
query: (isNot: boolean, timeout: number) => Promise<{ pass: boolean, received?: string }>,
|
query: (isNot: boolean, timeout: number) => Promise<{ pass: boolean, received?: string, log?: string[] }>,
|
||||||
expected: string | RegExp,
|
expected: string | RegExp,
|
||||||
options: { timeout?: number, matchSubstring?: boolean } = {},
|
options: { timeout?: number, matchSubstring?: boolean } = {},
|
||||||
) {
|
) {
|
||||||
|
|
@ -63,7 +63,7 @@ export async function toMatchText(
|
||||||
defaultExpectTimeout = 5000;
|
defaultExpectTimeout = 5000;
|
||||||
const timeout = options.timeout === 0 ? 0 : options.timeout || defaultExpectTimeout;
|
const timeout = options.timeout === 0 ? 0 : options.timeout || defaultExpectTimeout;
|
||||||
|
|
||||||
const { pass, received } = await query(this.isNot, timeout);
|
const { pass, received, log } = await query(this.isNot, timeout);
|
||||||
const stringSubstring = options.matchSubstring ? 'substring' : 'string';
|
const stringSubstring = options.matchSubstring ? 'substring' : 'string';
|
||||||
const message = pass
|
const message = pass
|
||||||
? () =>
|
? () =>
|
||||||
|
|
@ -84,7 +84,7 @@ export async function toMatchText(
|
||||||
typeof expected.exec === 'function'
|
typeof expected.exec === 'function'
|
||||||
? expected.exec(received!)
|
? expected.exec(received!)
|
||||||
: null,
|
: null,
|
||||||
)}`
|
)}` + callLogText(log)
|
||||||
: () => {
|
: () => {
|
||||||
const labelExpected = `Expected ${typeof expected === 'string' ? stringSubstring : 'pattern'
|
const labelExpected = `Expected ${typeof expected === 'string' ? stringSubstring : 'pattern'
|
||||||
}`;
|
}`;
|
||||||
|
|
@ -99,7 +99,7 @@ export async function toMatchText(
|
||||||
labelExpected,
|
labelExpected,
|
||||||
labelReceived,
|
labelReceived,
|
||||||
this.expand !== false,
|
this.expand !== false,
|
||||||
));
|
)) + callLogText(log);
|
||||||
};
|
};
|
||||||
|
|
||||||
return { message, pass };
|
return { message, pass };
|
||||||
|
|
@ -118,3 +118,13 @@ export function toExpectedTextValues(items: (string | RegExp)[], options: { matc
|
||||||
normalizeWhiteSpace: options.normalizeWhiteSpace,
|
normalizeWhiteSpace: options.normalizeWhiteSpace,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function callLogText(log: string[] | undefined): string {
|
||||||
|
if (!log)
|
||||||
|
return '';
|
||||||
|
return `
|
||||||
|
|
||||||
|
Call log:
|
||||||
|
${(log || []).join('\n')}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -220,3 +220,23 @@ test('should support respect expect.timeout', async ({ runInlineTest }) => {
|
||||||
expect(result.failed).toBe(1);
|
expect(result.failed).toBe(1);
|
||||||
expect(result.exitCode).toBe(1);
|
expect(result.exitCode).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should log scale the time', async ({ runInlineTest }) => {
|
||||||
|
const result = await runInlineTest({
|
||||||
|
'a.test.ts': `
|
||||||
|
const { test } = pwt;
|
||||||
|
|
||||||
|
test('pass', async ({ page }) => {
|
||||||
|
await page.setContent('<div id=div>Wrong</div>');
|
||||||
|
await expect(page.locator('div')).toHaveText('Text', { timeout: 2000 });
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
}, { workers: 1 });
|
||||||
|
const output = stripAscii(result.output);
|
||||||
|
const tokens = output.split('unexpected value');
|
||||||
|
// Log scale: 0, 100, 250, 500, 1000, 1000, should be less than 8.
|
||||||
|
expect(tokens.length).toBeGreaterThan(1);
|
||||||
|
expect(tokens.length).toBeLessThan(8);
|
||||||
|
expect(result.passed).toBe(0);
|
||||||
|
expect(result.exitCode).toBe(1);
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue