fix(expect): produce "waiting for selector" log, corner cases (#9140)
This commit is contained in:
parent
45b365d958
commit
f4aaebfba0
|
|
@ -1248,6 +1248,7 @@ export class Frame extends SdkObject {
|
|||
const data = this._contextData.get(options.mainWorld ? 'main' : info.world)!;
|
||||
|
||||
return controller.run(async progress => {
|
||||
progress.log(`waiting for selector "${selector}"`);
|
||||
const rerunnableTask = new RerunnableTask(data, progress, injectedScript => {
|
||||
return injectedScript.evaluateHandle((injected, { info, taskData, callbackText, querySelectorAll, logScale }) => {
|
||||
const callback = injected.eval(callbackText) as DomTaskBody<T, R>;
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ export async function toMatchText(
|
|||
|
||||
const { pass, received, log } = await query(this.isNot, timeout);
|
||||
const stringSubstring = options.matchSubstring ? 'substring' : 'string';
|
||||
const receivedString = received || '';
|
||||
const message = pass
|
||||
? () =>
|
||||
typeof expected === 'string'
|
||||
|
|
@ -72,17 +73,17 @@ export async function toMatchText(
|
|||
'\n\n' +
|
||||
`Expected ${stringSubstring}: not ${this.utils.printExpected(expected)}\n` +
|
||||
`Received string: ${printReceivedStringContainExpectedSubstring(
|
||||
received!,
|
||||
received!.indexOf(expected),
|
||||
receivedString,
|
||||
receivedString.indexOf(expected),
|
||||
expected.length,
|
||||
)}`
|
||||
)}` + callLogText(log)
|
||||
: this.utils.matcherHint(matcherName, undefined, undefined, matcherOptions) +
|
||||
'\n\n' +
|
||||
`Expected pattern: not ${this.utils.printExpected(expected)}\n` +
|
||||
`Received string: ${printReceivedStringContainExpectedResult(
|
||||
received!,
|
||||
receivedString,
|
||||
typeof expected.exec === 'function'
|
||||
? expected.exec(received!)
|
||||
? expected.exec(receivedString)
|
||||
: null,
|
||||
)}` + callLogText(log)
|
||||
: () => {
|
||||
|
|
@ -95,7 +96,7 @@ export async function toMatchText(
|
|||
'\n\n' +
|
||||
this.utils.printDiffOrStringify(
|
||||
expected,
|
||||
received,
|
||||
receivedString,
|
||||
labelExpected,
|
||||
labelReceived,
|
||||
this.expand !== false,
|
||||
|
|
@ -105,10 +106,6 @@ export async function toMatchText(
|
|||
return { message, pass };
|
||||
}
|
||||
|
||||
export function normalizeWhiteSpace(s: string) {
|
||||
return s.trim().replace(/\s+/g, ' ');
|
||||
}
|
||||
|
||||
export function toExpectedTextValues(items: (string | RegExp)[], options: { matchSubstring?: boolean, normalizeWhiteSpace?: boolean } = {}): ExpectedTextValue[] {
|
||||
return items.map(i => ({
|
||||
string: isString(i) ? i : undefined,
|
||||
|
|
|
|||
|
|
@ -225,6 +225,7 @@ it.describe('pause', () => {
|
|||
expect(await sanitizeLog(recorderPage)).toEqual([
|
||||
'page.pause- XXms',
|
||||
'page.isChecked(button)- XXms',
|
||||
'waiting for selector "button"',
|
||||
'selector resolved to <button onclick=\"console.log(1)\">Submit</button>',
|
||||
'error: Not a checkbox or radio button',
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -81,6 +81,13 @@ it('innerText should throw', async ({ page, server }) => {
|
|||
expect(error2.message).toContain('Not an HTMLElement');
|
||||
});
|
||||
|
||||
it('innerText should produce log', async ({ page, server }) => {
|
||||
await page.setContent(`<div>Hello</div>`);
|
||||
const locator = page.locator('span');
|
||||
const error = await locator.innerText({ timeout: 1000 }).catch(e => e);
|
||||
expect(error.message).toContain('waiting for selector "span"');
|
||||
});
|
||||
|
||||
it('textContent should work', async ({ page, server }) => {
|
||||
await page.goto(`${server.PREFIX}/dom.html`);
|
||||
const locator = page.locator('#inner');
|
||||
|
|
|
|||
|
|
@ -312,5 +312,49 @@ test('should print nice error for toHaveText', async ({ runInlineTest }) => {
|
|||
expect(output).toContain('Pending operations:');
|
||||
expect(output).toContain('Error: expect(received).toHaveText(expected)');
|
||||
expect(output).toContain('Expected string: "Text"');
|
||||
expect(output).toContain('Received string: undefined');
|
||||
expect(output).toContain('Received string: ""');
|
||||
expect(output).toContain('waiting for selector "no-such-thing"');
|
||||
});
|
||||
|
||||
test('should print expected/received on Ctrl+C', async ({ runInlineTest }) => {
|
||||
test.skip(process.platform === 'win32', 'No sending SIGINT on Windows');
|
||||
|
||||
const result = await runInlineTest({
|
||||
'a.test.ts': `
|
||||
const { test } = pwt;
|
||||
|
||||
test('times out waiting for text', async ({ page }) => {
|
||||
await page.setContent('<div id=node>Text content</div>');
|
||||
const promise = expect(page.locator('#node')).toHaveText('Text 2');
|
||||
await new Promise(f => setTimeout(f, 500));
|
||||
console.log('\\n%%SEND-SIGINT%%');
|
||||
await promise;
|
||||
});
|
||||
`,
|
||||
}, { workers: 1 }, {}, { sendSIGINTAfter: 1 });
|
||||
expect(result.exitCode).toBe(130);
|
||||
expect(result.passed).toBe(0);
|
||||
expect(result.skipped).toBe(1);
|
||||
expect(stripAscii(result.output)).toContain('Expected string: "Text 2"');
|
||||
expect(stripAscii(result.output)).toContain('Received string: "Text content"');
|
||||
});
|
||||
|
||||
test('should support not.toHaveText when selector does not match', async ({ runInlineTest }) => {
|
||||
const result = await runInlineTest({
|
||||
'a.test.ts': `
|
||||
const { test } = pwt;
|
||||
|
||||
test('fails', async ({ page }) => {
|
||||
await page.setContent('<div>hello</div>');
|
||||
await expect(page.locator('span')).not.toHaveText('hello', { timeout: 1000 });
|
||||
});
|
||||
`,
|
||||
}, { workers: 1 });
|
||||
expect(result.exitCode).toBe(1);
|
||||
expect(result.passed).toBe(0);
|
||||
expect(result.failed).toBe(1);
|
||||
const output = stripAscii(result.output);
|
||||
expect(output).toContain('Expected string: not "hello"');
|
||||
expect(output).toContain('Received string: ""');
|
||||
expect(output).toContain('waiting for selector "span"');
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue