test: misc test improvements (#10371)

This commit is contained in:
Alex Rudenko 2023-06-13 15:05:01 +02:00 committed by GitHub
parent 3e3911acdb
commit 2961449391
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 96 additions and 30 deletions

View File

@ -99,8 +99,9 @@ export class Browser extends BrowserBase {
this.#browserName = opts.browserName; this.#browserName = opts.browserName;
this.#browserVersion = opts.browserVersion; this.#browserVersion = opts.browserVersion;
this.#process?.on('close', () => { this.#process?.once('close', () => {
return this.emit(BrowserEmittedEvents.Disconnected); this.#connection.dispose();
this.emit(BrowserEmittedEvents.Disconnected);
}); });
} }
@ -109,6 +110,9 @@ export class Browser extends BrowserBase {
} }
override async close(): Promise<void> { override async close(): Promise<void> {
if (this.#connection.closed) {
return;
}
this.#connection.dispose(); this.#connection.dispose();
await this.#closeCallback?.call(null); await this.#closeCallback?.call(null);
} }

View File

@ -427,6 +427,9 @@ describe('AriaQueryHandler', () => {
.waitForSelector('aria/inner', {visible: true}) .waitForSelector('aria/inner', {visible: true})
.then(() => { .then(() => {
return (divVisible = true); return (divVisible = true);
})
.catch(() => {
return (divVisible = false);
}); });
await page.setContent( await page.setContent(
`<div style='display: none; visibility: hidden;'><div aria-label="inner">hi</div></div>` `<div style='display: none; visibility: hidden;'><div aria-label="inner">hi</div></div>`
@ -456,6 +459,9 @@ describe('AriaQueryHandler', () => {
.waitForSelector('aria/[role="button"]', {hidden: true}) .waitForSelector('aria/[role="button"]', {hidden: true})
.then(() => { .then(() => {
return (divHidden = true); return (divHidden = true);
})
.catch(() => {
return (divHidden = false);
}); });
await page.waitForSelector('aria/[role="button"]'); // do a round trip await page.waitForSelector('aria/[role="button"]'); // do a round trip
expect(divHidden).toBe(false); expect(divHidden).toBe(false);
@ -479,6 +485,9 @@ describe('AriaQueryHandler', () => {
.waitForSelector('aria/[role="main"]', {hidden: true}) .waitForSelector('aria/[role="main"]', {hidden: true})
.then(() => { .then(() => {
return (divHidden = true); return (divHidden = true);
})
.catch(() => {
return (divHidden = false);
}); });
await page.waitForSelector('aria/[role="main"]'); // do a round trip await page.waitForSelector('aria/[role="main"]'); // do a round trip
expect(divHidden).toBe(false); expect(divHidden).toBe(false);
@ -500,6 +509,9 @@ describe('AriaQueryHandler', () => {
.waitForSelector('aria/[role="main"]', {hidden: true}) .waitForSelector('aria/[role="main"]', {hidden: true})
.then(() => { .then(() => {
return (divRemoved = true); return (divRemoved = true);
})
.catch(() => {
return (divRemoved = false);
}); });
await page.waitForSelector('aria/[role="main"]'); // do a round trip await page.waitForSelector('aria/[role="main"]'); // do a round trip
expect(divRemoved).toBe(false); expect(divRemoved).toBe(false);
@ -553,8 +565,13 @@ describe('AriaQueryHandler', () => {
const {page} = getTestState(); const {page} = getTestState();
let divFound = false; let divFound = false;
const waitForSelector = page.waitForSelector('aria/zombo').then(() => { const waitForSelector = page
.waitForSelector('aria/zombo')
.then(() => {
return (divFound = true); return (divFound = true);
})
.catch(() => {
return (divFound = false);
}); });
await page.setContent(`<div aria-label='notZombo'></div>`); await page.setContent(`<div aria-label='notZombo'></div>`);
expect(divFound).toBe(false); expect(divFound).toBe(false);
@ -569,7 +586,9 @@ describe('AriaQueryHandler', () => {
it('should return the element handle', async () => { it('should return the element handle', async () => {
const {page} = getTestState(); const {page} = getTestState();
const waitForSelector = page.waitForSelector('aria/zombo'); const waitForSelector = page.waitForSelector('aria/zombo').catch(err => {
return err;
});
await page.setContent(`<div aria-label='zombo'>anything</div>`); await page.setContent(`<div aria-label='zombo'>anything</div>`);
expect( expect(
await page.evaluate(x => { await page.evaluate(x => {

View File

@ -389,23 +389,29 @@ describe('ElementHandle specs', function () {
describe('Element.waitForSelector', () => { describe('Element.waitForSelector', () => {
it('should wait correctly with waitForSelector on an element', async () => { it('should wait correctly with waitForSelector on an element', async () => {
const {page} = getTestState(); const {page} = getTestState();
const waitFor = page.waitForSelector('.foo') as Promise< const waitFor = page.waitForSelector('.foo').catch(err => {
ElementHandle<HTMLDivElement> return err;
>; }) as Promise<ElementHandle<HTMLDivElement>>;
// Set the page content after the waitFor has been started. // Set the page content after the waitFor has been started.
await page.setContent( await page.setContent(
'<div id="not-foo"></div><div class="bar">bar2</div><div class="foo">Foo1</div>' '<div id="not-foo"></div><div class="bar">bar2</div><div class="foo">Foo1</div>'
); );
let element = (await waitFor)!; let element = (await waitFor)!;
if (element instanceof Error) {
throw element;
}
expect(element).toBeDefined(); expect(element).toBeDefined();
const innerWaitFor = element.waitForSelector('.bar') as Promise< const innerWaitFor = element.waitForSelector('.bar').catch(err => {
ElementHandle<HTMLDivElement> return err;
>; }) as Promise<ElementHandle<HTMLDivElement>>;
await element.evaluate(el => { await element.evaluate(el => {
el.innerHTML = '<div class="bar">bar1</div>'; el.innerHTML = '<div class="bar">bar1</div>';
}); });
element = (await innerWaitFor)!; element = (await innerWaitFor)!;
if (element instanceof Error) {
throw element;
}
expect(element).toBeDefined(); expect(element).toBeDefined();
expect( expect(
await element.evaluate(el => { await element.evaluate(el => {
@ -683,7 +689,9 @@ describe('ElementHandle specs', function () {
return (element as Element).querySelector(`.${selector}`); return (element as Element).querySelector(`.${selector}`);
}, },
}); });
const waitFor = page.waitForSelector('getByClass/foo'); const waitFor = page.waitForSelector('getByClass/foo').catch(err => {
return err;
});
// Set the page content after the waitFor has been started. // Set the page content after the waitFor has been started.
await page.setContent( await page.setContent(
@ -691,6 +699,10 @@ describe('ElementHandle specs', function () {
); );
const element = await waitFor; const element = await waitFor;
if (element instanceof Error) {
throw element;
}
expect(element).toBeDefined(); expect(element).toBeDefined();
}); });
@ -701,26 +713,34 @@ describe('ElementHandle specs', function () {
return (element as Element).querySelector(`.${selector}`); return (element as Element).querySelector(`.${selector}`);
}, },
}); });
const waitFor = page.waitForSelector('getByClass/foo') as Promise< const waitFor = page.waitForSelector('getByClass/foo').catch(err => {
ElementHandle<HTMLElement> return err;
>; }) as Promise<ElementHandle<HTMLElement>>;
// Set the page content after the waitFor has been started. // Set the page content after the waitFor has been started.
await page.setContent( await page.setContent(
'<div id="not-foo"></div><div class="bar">bar2</div><div class="foo">Foo1</div>' '<div id="not-foo"></div><div class="bar">bar2</div><div class="foo">Foo1</div>'
); );
let element = (await waitFor)!; let element = (await waitFor)!;
if (element instanceof Error) {
throw element;
}
expect(element).toBeDefined(); expect(element).toBeDefined();
const innerWaitFor = element.waitForSelector('getByClass/bar') as Promise< const innerWaitFor = element
ElementHandle<HTMLElement> .waitForSelector('getByClass/bar')
>; .catch(err => {
return err;
}) as Promise<ElementHandle<HTMLElement>>;
await element.evaluate(el => { await element.evaluate(el => {
el.innerHTML = '<div class="bar">bar1</div>'; el.innerHTML = '<div class="bar">bar1</div>';
}); });
element = (await innerWaitFor)!; element = (await innerWaitFor)!;
if (element instanceof Error) {
throw element;
}
expect(element).toBeDefined(); expect(element).toBeDefined();
expect( expect(
await element.evaluate(el => { await element.evaluate(el => {
@ -738,7 +758,9 @@ describe('ElementHandle specs', function () {
return (element as Element).querySelector(`.${selector}`); return (element as Element).querySelector(`.${selector}`);
}, },
}); });
const waitFor = page.waitForSelector('getByClass/foo'); const waitFor = page.waitForSelector('getByClass/foo').catch(err => {
return err;
});
// Set the page content after the waitFor has been started. // Set the page content after the waitFor has been started.
await page.setContent( await page.setContent(
@ -746,6 +768,10 @@ describe('ElementHandle specs', function () {
); );
const element = await waitFor; const element = await waitFor;
if (element instanceof Error) {
throw element;
}
expect(element).toBeDefined(); expect(element).toBeDefined();
}); });
it('should work when both queryOne and queryAll are registered', async () => { it('should work when both queryOne and queryAll are registered', async () => {

View File

@ -150,7 +150,12 @@ describe('Locator', function () {
<button style="display: none;" onclick="this.innerText = 'clicked';">test</button> <button style="display: none;" onclick="this.innerText = 'clicked';">test</button>
`); `);
const button = await page.$('button'); const button = await page.$('button');
const result = page.locator('button').click(); const result = page
.locator('button')
.click()
.catch(err => {
return err;
});
expect( expect(
await button?.evaluate(el => { await button?.evaluate(el => {
return el.innerText; return el.innerText;
@ -159,7 +164,10 @@ describe('Locator', function () {
await button?.evaluate(el => { await button?.evaluate(el => {
el.style.display = 'block'; el.style.display = 'block';
}); });
await result; const maybeError = await result;
if (maybeError instanceof Error) {
throw maybeError;
}
expect( expect(
await button?.evaluate(el => { await button?.evaluate(el => {
return el.innerText; return el.innerText;

View File

@ -20,6 +20,7 @@ import expect from 'expect';
import {Frame} from 'puppeteer-core/internal/api/Frame.js'; import {Frame} from 'puppeteer-core/internal/api/Frame.js';
import {Page} from 'puppeteer-core/internal/api/Page.js'; import {Page} from 'puppeteer-core/internal/api/Page.js';
import {EventEmitter} from 'puppeteer-core/internal/common/EventEmitter.js'; import {EventEmitter} from 'puppeteer-core/internal/common/EventEmitter.js';
import {Deferred} from 'puppeteer-core/internal/util/Deferred.js';
import {compare} from './golden-utils.js'; import {compare} from './golden-utils.js';
@ -132,19 +133,27 @@ export const dumpFrames = (frame: Frame, indentation?: string): string[] => {
return result; return result;
}; };
export const waitEvent = <T = any>( export const waitEvent = async <T = any>(
emitter: EventEmitter, emitter: EventEmitter,
eventName: string, eventName: string,
predicate: (event: T) => boolean = () => { predicate: (event: T) => boolean = () => {
return true; return true;
} }
): Promise<T> => { ): Promise<T> => {
return new Promise(fulfill => { const deferred = Deferred.create<T>({
emitter.on(eventName, (event: T) => { timeout: 5000,
message: 'Waiting for test event timed out.',
});
const handler = (event: T) => {
if (!predicate(event)) { if (!predicate(event)) {
return; return;
} }
fulfill(event); deferred.resolve(event);
}); };
}); emitter.on(eventName, handler);
try {
return await deferred.valueOrThrow();
} finally {
emitter.off(eventName, handler);
}
}; };