chore(types): convert tests to typescript part 3 (#3340)
This commit is contained in:
parent
1bcbf19e86
commit
eac8aeedaf
|
|
@ -30,7 +30,7 @@ import { ProgressController } from './progress';
|
||||||
import { DebugController } from './debug/debugController';
|
import { DebugController } from './debug/debugController';
|
||||||
import { LoggerSink } from './loggerSink';
|
import { LoggerSink } from './loggerSink';
|
||||||
|
|
||||||
export interface BrowserContext {
|
export interface BrowserContext extends EventEmitter {
|
||||||
setDefaultNavigationTimeout(timeout: number): void;
|
setDefaultNavigationTimeout(timeout: number): void;
|
||||||
setDefaultTimeout(timeout: number): void;
|
setDefaultTimeout(timeout: number): void;
|
||||||
pages(): Page[];
|
pages(): Page[];
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import utils from './utils';
|
||||||
const {FFOX, CHROMIUM, WEBKIT} = testOptions;
|
const {FFOX, CHROMIUM, WEBKIT} = testOptions;
|
||||||
|
|
||||||
it.skip(CHROMIUM)('should be missing', async function({page, server}) {
|
it.skip(CHROMIUM)('should be missing', async function({page, server}) {
|
||||||
|
|
@ -13,9 +13,17 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
import { Page, Browser, BrowserContext } from '../../types/types';
|
||||||
|
|
||||||
const {FFOX, CHROMIUM, WEBKIT, CHANNEL} = testOptions;
|
const {FFOX, CHROMIUM, WEBKIT, CHANNEL} = testOptions;
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface FixtureState {
|
||||||
|
sppBrowser: Browser;
|
||||||
|
sppContext: BrowserContext;
|
||||||
|
sppPage: Page;
|
||||||
|
}
|
||||||
|
}
|
||||||
registerFixture('sppBrowser', async ({browserType, defaultBrowserOptions}, test) => {
|
registerFixture('sppBrowser', async ({browserType, defaultBrowserOptions}, test) => {
|
||||||
const browser = await browserType.launch({
|
const browser = await browserType.launch({
|
||||||
...defaultBrowserOptions,
|
...defaultBrowserOptions,
|
||||||
|
|
@ -76,13 +84,13 @@ it.skip(!CHROMIUM)('should handle remote -> local -> remote transitions', async
|
||||||
expect(await page.frames()[1].evaluate(() => '' + location.href)).toBe(server.CROSS_PROCESS_PREFIX + '/grid.html');
|
expect(await page.frames()[1].evaluate(() => '' + location.href)).toBe(server.CROSS_PROCESS_PREFIX + '/grid.html');
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.frames()[1].waitForNavigation(),
|
page.frames()[1].waitForNavigation(),
|
||||||
page.evaluate(() => goLocal()),
|
page.evaluate('goLocal()'),
|
||||||
]);
|
]);
|
||||||
expect(await page.frames()[1].evaluate(() => '' + location.href)).toBe(server.PREFIX + '/grid.html');
|
expect(await page.frames()[1].evaluate(() => '' + location.href)).toBe(server.PREFIX + '/grid.html');
|
||||||
expect(await countOOPIFs(browser)).toBe(0);
|
expect(await countOOPIFs(browser)).toBe(0);
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.frames()[1].waitForNavigation(),
|
page.frames()[1].waitForNavigation(),
|
||||||
page.evaluate(() => goRemote()),
|
page.evaluate('goRemote()'),
|
||||||
]);
|
]);
|
||||||
expect(await page.frames()[1].evaluate(() => '' + location.href)).toBe(server.CROSS_PROCESS_PREFIX + '/grid.html');
|
expect(await page.frames()[1].evaluate(() => '' + location.href)).toBe(server.CROSS_PROCESS_PREFIX + '/grid.html');
|
||||||
expect(await countOOPIFs(browser)).toBe(1);
|
expect(await countOOPIFs(browser)).toBe(1);
|
||||||
|
|
@ -118,7 +126,7 @@ it.skip(!CHROMIUM)('should expose function', async({sppBrowser, sppPage, server}
|
||||||
const oopif = page.frames()[1];
|
const oopif = page.frames()[1];
|
||||||
await page.exposeFunction('mul', (a, b) => a * b);
|
await page.exposeFunction('mul', (a, b) => a * b);
|
||||||
const result = await oopif.evaluate(async function() {
|
const result = await oopif.evaluate(async function() {
|
||||||
return await mul(9, 4);
|
return await window['mul'](9, 4);
|
||||||
});
|
});
|
||||||
expect(result).toBe(36);
|
expect(result).toBe(36);
|
||||||
});
|
});
|
||||||
|
|
@ -252,25 +260,25 @@ it.skip(!CHROMIUM)('should support exposeFunction', async function({sppBrowser,
|
||||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||||
expect(await countOOPIFs(browser)).toBe(1);
|
expect(await countOOPIFs(browser)).toBe(1);
|
||||||
expect(page.frames().length).toBe(2);
|
expect(page.frames().length).toBe(2);
|
||||||
expect(await page.frames()[0].evaluate(() => inc(3))).toBe(4);
|
expect(await page.frames()[0].evaluate(() => window['inc'](3))).toBe(4);
|
||||||
expect(await page.frames()[1].evaluate(() => inc(4))).toBe(5);
|
expect(await page.frames()[1].evaluate(() => window['inc'](4))).toBe(5);
|
||||||
expect(await page.frames()[0].evaluate(() => dec(3))).toBe(2);
|
expect(await page.frames()[0].evaluate(() => window['dec'](3))).toBe(2);
|
||||||
expect(await page.frames()[1].evaluate(() => dec(4))).toBe(3);
|
expect(await page.frames()[1].evaluate(() => window['dec'](4))).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip(!CHROMIUM)('should support addInitScript', async function({sppBrowser, sppContext, sppPage, server}) {
|
it.skip(!CHROMIUM)('should support addInitScript', async function({sppBrowser, sppContext, sppPage, server}) {
|
||||||
const browser = sppBrowser;
|
const browser = sppBrowser;
|
||||||
const context = sppContext;
|
const context = sppContext;
|
||||||
const page = sppPage;
|
const page = sppPage;
|
||||||
await context.addInitScript(() => window.bar = 17);
|
await context.addInitScript(() => window['bar'] = 17);
|
||||||
await page.addInitScript(() => window.foo = 42);
|
await page.addInitScript(() => window['foo'] = 42);
|
||||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||||
expect(await countOOPIFs(browser)).toBe(1);
|
expect(await countOOPIFs(browser)).toBe(1);
|
||||||
expect(page.frames().length).toBe(2);
|
expect(page.frames().length).toBe(2);
|
||||||
expect(await page.frames()[0].evaluate(() => window.foo)).toBe(42);
|
expect(await page.frames()[0].evaluate(() => window['foo'])).toBe(42);
|
||||||
expect(await page.frames()[1].evaluate(() => window.foo)).toBe(42);
|
expect(await page.frames()[1].evaluate(() => window['foo'])).toBe(42);
|
||||||
expect(await page.frames()[0].evaluate(() => window.bar)).toBe(17);
|
expect(await page.frames()[0].evaluate(() => window['bar'])).toBe(17);
|
||||||
expect(await page.frames()[1].evaluate(() => window.bar)).toBe(17);
|
expect(await page.frames()[1].evaluate(() => window['bar'])).toBe(17);
|
||||||
});
|
});
|
||||||
// @see https://github.com/microsoft/playwright/issues/1240
|
// @see https://github.com/microsoft/playwright/issues/1240
|
||||||
it.skip(!CHROMIUM)('should click a button when it overlays oopif', async function({sppBrowser, sppPage, server}) {
|
it.skip(!CHROMIUM)('should click a button when it overlays oopif', async function({sppBrowser, sppPage, server}) {
|
||||||
|
|
@ -279,7 +287,7 @@ it.skip(!CHROMIUM)('should click a button when it overlays oopif', async functio
|
||||||
await page.goto(server.PREFIX + '/button-overlay-oopif.html');
|
await page.goto(server.PREFIX + '/button-overlay-oopif.html');
|
||||||
expect(await countOOPIFs(browser)).toBe(1);
|
expect(await countOOPIFs(browser)).toBe(1);
|
||||||
await page.click('button');
|
await page.click('button');
|
||||||
expect(await page.evaluate(() => window.BUTTON_CLICKED)).toBe(true);
|
expect(await page.evaluate(() => window['BUTTON_CLICKED'])).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip(!CHROMIUM)('should report google.com frame with headful', async({browserType, defaultBrowserOptions, server}) => {
|
it.skip(!CHROMIUM)('should report google.com frame with headful', async({browserType, defaultBrowserOptions, server}) => {
|
||||||
|
|
@ -325,7 +333,7 @@ it.skip(!CHROMIUM)('ElementHandle.boundingBox() should work', async function({sp
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.frames()[1].waitForNavigation(),
|
page.frames()[1].waitForNavigation(),
|
||||||
page.evaluate(() => goLocal()),
|
page.evaluate('goLocal()'),
|
||||||
]);
|
]);
|
||||||
expect(await countOOPIFs(browser)).toBe(0);
|
expect(await countOOPIFs(browser)).toBe(0);
|
||||||
const handle2 = await page.frames()[1].$('.box:nth-of-type(13)');
|
const handle2 = await page.frames()[1].$('.box:nth-of-type(13)');
|
||||||
|
|
@ -346,9 +354,9 @@ it.skip(!CHROMIUM)('should click', async function({sppBrowser, sppPage, server})
|
||||||
|
|
||||||
expect(await countOOPIFs(browser)).toBe(1);
|
expect(await countOOPIFs(browser)).toBe(1);
|
||||||
const handle1 = await page.frames()[1].$('.box:nth-of-type(13)');
|
const handle1 = await page.frames()[1].$('.box:nth-of-type(13)');
|
||||||
await handle1.evaluate(div => div.addEventListener('click', () => window._clicked = true, false));
|
await handle1.evaluate(div => div.addEventListener('click', () => window['_clicked'] = true, false));
|
||||||
await handle1.click();
|
await handle1.click();
|
||||||
expect(await handle1.evaluate(() => window._clicked)).toBe(true);
|
expect(await handle1.evaluate(() => window['_clicked'])).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
async function countOOPIFs(browser) {
|
async function countOOPIFs(browser) {
|
||||||
|
|
@ -14,10 +14,15 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const fs = require('fs');
|
import fs from 'fs';
|
||||||
const path = require('path');
|
import path from 'path';
|
||||||
|
import { ChromiumBrowser } from '../..';
|
||||||
const {FFOX, CHROMIUM, WEBKIT, OUTPUT_DIR, CHANNEL} = testOptions;
|
const {FFOX, CHROMIUM, WEBKIT, OUTPUT_DIR, CHANNEL} = testOptions;
|
||||||
|
declare global {
|
||||||
|
interface FixtureState {
|
||||||
|
outputFile: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
registerFixture('outputFile', async ({parallelIndex}, test) => {
|
registerFixture('outputFile', async ({parallelIndex}, test) => {
|
||||||
const outputFile = path.join(OUTPUT_DIR, `trace-${parallelIndex}.json`);
|
const outputFile = path.join(OUTPUT_DIR, `trace-${parallelIndex}.json`);
|
||||||
await test(outputFile);
|
await test(outputFile);
|
||||||
|
|
@ -26,48 +31,48 @@ registerFixture('outputFile', async ({parallelIndex}, test) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip(!CHROMIUM)('should output a trace', async({browser, page, server, outputFile}) => {
|
it.skip(!CHROMIUM)('should output a trace', async({browser, page, server, outputFile}) => {
|
||||||
await browser.startTracing(page, {screenshots: true, path: outputFile});
|
await (browser as ChromiumBrowser).startTracing(page, {screenshots: true, path: outputFile});
|
||||||
await page.goto(server.PREFIX + '/grid.html');
|
await page.goto(server.PREFIX + '/grid.html');
|
||||||
await browser.stopTracing();
|
await (browser as ChromiumBrowser).stopTracing();
|
||||||
expect(fs.existsSync(outputFile)).toBe(true);
|
expect(fs.existsSync(outputFile)).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip(!CHROMIUM)('should run with custom categories if provided', async({browser, page, outputFile}) => {
|
it.skip(!CHROMIUM)('should run with custom categories if provided', async({browser, page, outputFile}) => {
|
||||||
await browser.startTracing(page, {path: outputFile, categories: ['disabled-by-default-v8.cpu_profiler.hires']});
|
await (browser as ChromiumBrowser).startTracing(page, {path: outputFile, categories: ['disabled-by-default-v8.cpu_profiler.hires']});
|
||||||
await browser.stopTracing();
|
await (browser as ChromiumBrowser).stopTracing();
|
||||||
|
|
||||||
const traceJson = JSON.parse(fs.readFileSync(outputFile).toString());
|
const traceJson = JSON.parse(fs.readFileSync(outputFile).toString());
|
||||||
expect(traceJson.metadata['trace-config']).toContain('disabled-by-default-v8.cpu_profiler.hires', 'Does not contain expected category');
|
expect(traceJson.metadata['trace-config']).toContain('disabled-by-default-v8.cpu_profiler.hires');
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip(!CHROMIUM)('should throw if tracing on two pages', async({browser, page, outputFile}) => {
|
it.skip(!CHROMIUM)('should throw if tracing on two pages', async({browser, page, outputFile}) => {
|
||||||
await browser.startTracing(page, {path: outputFile});
|
await (browser as ChromiumBrowser).startTracing(page, {path: outputFile});
|
||||||
const newPage = await browser.newPage();
|
const newPage = await browser.newPage();
|
||||||
let error = null;
|
let error = null;
|
||||||
await browser.startTracing(newPage, {path: outputFile}).catch(e => error = e);
|
await (browser as ChromiumBrowser).startTracing(newPage, {path: outputFile}).catch(e => error = e);
|
||||||
await newPage.close();
|
await newPage.close();
|
||||||
expect(error).toBeTruthy();
|
expect(error).toBeTruthy();
|
||||||
await browser.stopTracing();
|
await (browser as ChromiumBrowser).stopTracing();
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip(!CHROMIUM)('should return a buffer', async({browser, page, server, outputFile}) => {
|
it.skip(!CHROMIUM)('should return a buffer', async({browser, page, server, outputFile}) => {
|
||||||
await browser.startTracing(page, {screenshots: true, path: outputFile});
|
await (browser as ChromiumBrowser).startTracing(page, {screenshots: true, path: outputFile});
|
||||||
await page.goto(server.PREFIX + '/grid.html');
|
await page.goto(server.PREFIX + '/grid.html');
|
||||||
const trace = await browser.stopTracing();
|
const trace = await (browser as ChromiumBrowser).stopTracing();
|
||||||
const buf = fs.readFileSync(outputFile);
|
const buf = fs.readFileSync(outputFile);
|
||||||
expect(trace.toString()).toEqual(buf.toString(), 'Tracing buffer mismatch');
|
expect(trace.toString()).toEqual(buf.toString());
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip(!CHROMIUM)('should work without options', async({browser, page, server}) => {
|
it.skip(!CHROMIUM)('should work without options', async({browser, page, server}) => {
|
||||||
await browser.startTracing(page);
|
await (browser as ChromiumBrowser).startTracing(page);
|
||||||
await page.goto(server.PREFIX + '/grid.html');
|
await page.goto(server.PREFIX + '/grid.html');
|
||||||
const trace = await browser.stopTracing();
|
const trace = await (browser as ChromiumBrowser).stopTracing();
|
||||||
expect(trace).toBeTruthy();
|
expect(trace).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip(!CHROMIUM)('should support a buffer without a path', async({browser, page, server}) => {
|
it.skip(!CHROMIUM)('should support a buffer without a path', async({browser, page, server}) => {
|
||||||
await browser.startTracing(page, {screenshots: true});
|
await (browser as ChromiumBrowser).startTracing(page, {screenshots: true});
|
||||||
await page.goto(server.PREFIX + '/grid.html');
|
await page.goto(server.PREFIX + '/grid.html');
|
||||||
const trace = await browser.stopTracing();
|
const trace = await (browser as ChromiumBrowser).stopTracing();
|
||||||
expect(trace.toString()).toContain('screenshot', 'Does not contain screenshot');
|
expect(trace.toString()).toContain('screenshot');
|
||||||
});
|
});
|
||||||
120
test/click-react.spec.ts
Normal file
120
test/click-react.spec.ts
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2018 Google Inc. All rights reserved.
|
||||||
|
* Modifications 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.
|
||||||
|
*/
|
||||||
|
import utils from './utils';
|
||||||
|
|
||||||
|
declare const renderComponent;
|
||||||
|
declare const e;
|
||||||
|
declare const MyButton;
|
||||||
|
|
||||||
|
it.fail(true)('should report that selector does not match anymore', async ({page, server}) => {
|
||||||
|
await page.goto(server.PREFIX + '/react.html');
|
||||||
|
await page.evaluate(() => {
|
||||||
|
renderComponent(e('div', {}, [e(MyButton, { name: 'button1' }), e(MyButton, { name: 'button2' })] ));
|
||||||
|
});
|
||||||
|
const __testHookAfterStable = () => page.evaluate(() => {
|
||||||
|
window['counter'] = (window['counter'] || 0) + 1;
|
||||||
|
if (window['counter'] === 1)
|
||||||
|
renderComponent(e('div', {}, [e(MyButton, { name: 'button2' }), e(MyButton, { name: 'button1' })] ));
|
||||||
|
else
|
||||||
|
renderComponent(e('div', {}, []));
|
||||||
|
});
|
||||||
|
const error = await page.dblclick('text=button1', { __testHookAfterStable, timeout: 3000 } as any).catch(e => e);
|
||||||
|
expect(await page.evaluate('window.button1')).toBe(undefined);
|
||||||
|
expect(await page.evaluate('window.button2')).toBe(undefined);
|
||||||
|
expect(error.message).toContain('page.dblclick: Timeout 3000ms exceeded.');
|
||||||
|
expect(error.message).toContain('element does not match the selector anymore');
|
||||||
|
});
|
||||||
|
|
||||||
|
it.fail(true)('should not retarget the handle when element is recycled', async ({page, server}) => {
|
||||||
|
await page.goto(server.PREFIX + '/react.html');
|
||||||
|
await page.evaluate(() => {
|
||||||
|
renderComponent(e('div', {}, [e(MyButton, { name: 'button1' }), e(MyButton, { name: 'button2', disabled: true })] ));
|
||||||
|
});
|
||||||
|
const __testHookBeforeStable = () => page.evaluate(() => {
|
||||||
|
window['counter'] = (window['counter'] || 0) + 1;
|
||||||
|
if (window['counter'] === 1)
|
||||||
|
renderComponent(e('div', {}, [e(MyButton, { name: 'button2', disabled: true }), e(MyButton, { name: 'button1' })] ));
|
||||||
|
});
|
||||||
|
const handle = await page.$('text=button1');
|
||||||
|
const error = await handle.click({ __testHookBeforeStable, timeout: 3000 } as any).catch(e => e);
|
||||||
|
expect(await page.evaluate('window.button1')).toBe(undefined);
|
||||||
|
expect(await page.evaluate('window.button2')).toBe(undefined);
|
||||||
|
expect(error.message).toContain('elementHandle.click: Timeout 3000ms exceeded.');
|
||||||
|
expect(error.message).toContain('element is disabled - waiting');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should timeout when click opens alert', async({page, server}) => {
|
||||||
|
const dialogPromise = page.waitForEvent('dialog');
|
||||||
|
await page.setContent(`<div onclick='window.alert(123)'>Click me</div>`);
|
||||||
|
const error = await page.click('div', { timeout: 3000 }).catch(e => e);
|
||||||
|
expect(error.message).toContain('page.click: Timeout 3000ms exceeded.');
|
||||||
|
const dialog = await dialogPromise;
|
||||||
|
await dialog.dismiss();
|
||||||
|
});
|
||||||
|
|
||||||
|
it.fail(true)('should retarget when element is recycled during hit testing', async ({page, server}) => {
|
||||||
|
await page.goto(server.PREFIX + '/react.html');
|
||||||
|
await page.evaluate(() => {
|
||||||
|
renderComponent(e('div', {}, [e(MyButton, { name: 'button1' }), e(MyButton, { name: 'button2' })] ));
|
||||||
|
});
|
||||||
|
const __testHookAfterStable = () => page.evaluate(() => {
|
||||||
|
window['counter'] = (window['counter'] || 0) + 1;
|
||||||
|
if (window['counter'] === 1)
|
||||||
|
renderComponent(e('div', {}, [e(MyButton, { name: 'button2' }), e(MyButton, { name: 'button1' })] ));
|
||||||
|
});
|
||||||
|
await page.click('text=button1', { __testHookAfterStable } as any);
|
||||||
|
expect(await page.evaluate('window.button1')).toBe(true);
|
||||||
|
expect(await page.evaluate('window.button2')).toBe(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.fail(true)('should retarget when element is recycled before enabled check', async ({page, server}) => {
|
||||||
|
await page.goto(server.PREFIX + '/react.html');
|
||||||
|
await page.evaluate(() => {
|
||||||
|
renderComponent(e('div', {}, [e(MyButton, { name: 'button1' }), e(MyButton, { name: 'button2', disabled: true })] ));
|
||||||
|
});
|
||||||
|
const __testHookBeforeStable = () => page.evaluate(() => {
|
||||||
|
window['counter'] = (window['counter'] || 0) + 1;
|
||||||
|
if (window['counter'] === 1)
|
||||||
|
renderComponent(e('div', {}, [e(MyButton, { name: 'button2', disabled: true }), e(MyButton, { name: 'button1' })] ));
|
||||||
|
});
|
||||||
|
await page.click('text=button1', { __testHookBeforeStable } as any);
|
||||||
|
expect(await page.evaluate('window.button1')).toBe(true);
|
||||||
|
expect(await page.evaluate('window.button2')).toBe(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not retarget when element changes on hover', async ({page, server}) => {
|
||||||
|
await page.goto(server.PREFIX + '/react.html');
|
||||||
|
await page.evaluate(() => {
|
||||||
|
renderComponent(e('div', {}, [e(MyButton, { name: 'button1', renameOnHover: true }), e(MyButton, { name: 'button2' })] ));
|
||||||
|
});
|
||||||
|
await page.click('text=button1');
|
||||||
|
expect(await page.evaluate('window.button1')).toBe(true);
|
||||||
|
expect(await page.evaluate('window.button2')).toBe(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not retarget when element is recycled on hover', async ({page, server}) => {
|
||||||
|
await page.goto(server.PREFIX + '/react.html');
|
||||||
|
await page.evaluate(() => {
|
||||||
|
function shuffle() {
|
||||||
|
renderComponent(e('div', {}, [e(MyButton, { name: 'button2' }), e(MyButton, { name: 'button1' })] ));
|
||||||
|
}
|
||||||
|
renderComponent(e('div', {}, [e(MyButton, { name: 'button1', onHover: shuffle }), e(MyButton, { name: 'button2' })] ));
|
||||||
|
});
|
||||||
|
await page.click('text=button1');
|
||||||
|
expect(await page.evaluate('window.button1')).toBe(undefined);
|
||||||
|
expect(await page.evaluate('window.button2')).toBe(true);
|
||||||
|
});
|
||||||
|
|
@ -15,20 +15,21 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import utils from './utils';
|
||||||
const {USES_HOOKS} = testOptions;
|
const {USES_HOOKS} = testOptions;
|
||||||
|
|
||||||
it.skip(USES_HOOKS)('should avoid side effects after timeout', async({page, server}) => {
|
it.skip(USES_HOOKS)('should avoid side effects after timeout', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/button.html');
|
await page.goto(server.PREFIX + '/input/button.html');
|
||||||
const error = await page.click('button', { timeout: 2000, __testHookBeforePointerAction: () => new Promise(f => setTimeout(f, 2500))}).catch(e => e);
|
const error = await page.click('button', { timeout: 2000, __testHookBeforePointerAction: () => new Promise(f => setTimeout(f, 2500))} as any).catch(e => e);
|
||||||
await page.waitForTimeout(5000); // Give it some time to click after the test hook is done waiting.
|
await page.waitForTimeout(5000); // Give it some time to click after the test hook is done waiting.
|
||||||
expect(await page.evaluate(() => result)).toBe('Was not clicked');
|
expect(await page.evaluate('result')).toBe('Was not clicked');
|
||||||
expect(error.message).toContain('page.click: Timeout 2000ms exceeded.');
|
expect(error.message).toContain('page.click: Timeout 2000ms exceeded.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should timeout waiting for button to be enabled', async({page, server}) => {
|
it('should timeout waiting for button to be enabled', async({page, server}) => {
|
||||||
await page.setContent('<button onclick="javascript:window.__CLICKED=true;" disabled><span>Click target</span></button>');
|
await page.setContent('<button onclick="javascript:window.__CLICKED=true;" disabled><span>Click target</span></button>');
|
||||||
const error = await page.click('text=Click target', { timeout: 3000 }).catch(e => e);
|
const error = await page.click('text=Click target', { timeout: 3000 }).catch(e => e);
|
||||||
expect(await page.evaluate(() => window.__CLICKED)).toBe(undefined);
|
expect(await page.evaluate('window.__CLICKED')).toBe(undefined);
|
||||||
expect(error.message).toContain('page.click: Timeout 3000ms exceeded.');
|
expect(error.message).toContain('page.click: Timeout 3000ms exceeded.');
|
||||||
expect(error.message).toContain('element is disabled - waiting');
|
expect(error.message).toContain('element is disabled - waiting');
|
||||||
});
|
});
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import utils from './utils';
|
||||||
const {USES_HOOKS} = testOptions;
|
const {USES_HOOKS} = testOptions;
|
||||||
|
|
||||||
it('should timeout waiting for display:none to be gone', async({page, server}) => {
|
it('should timeout waiting for display:none to be gone', async({page, server}) => {
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import utils from './utils';
|
||||||
const {USES_HOOKS} = testOptions;
|
const {USES_HOOKS} = testOptions;
|
||||||
|
|
||||||
it.skip(USES_HOOKS)('should fail when element jumps during hit testing', async({page, server}) => {
|
it.skip(USES_HOOKS)('should fail when element jumps during hit testing', async({page, server}) => {
|
||||||
|
|
@ -22,13 +23,13 @@ it.skip(USES_HOOKS)('should fail when element jumps during hit testing', async({
|
||||||
let clicked = false;
|
let clicked = false;
|
||||||
const handle = await page.$('button');
|
const handle = await page.$('button');
|
||||||
const __testHookBeforeHitTarget = () => page.evaluate(() => {
|
const __testHookBeforeHitTarget = () => page.evaluate(() => {
|
||||||
const margin = parseInt(document.querySelector('button').style.marginLeft || 0) + 100;
|
const margin = parseInt(document.querySelector('button').style.marginLeft || '0') + 100;
|
||||||
document.querySelector('button').style.marginLeft = margin + 'px';
|
document.querySelector('button').style.marginLeft = margin + 'px';
|
||||||
});
|
});
|
||||||
const promise = handle.click({ timeout: 5000, __testHookBeforeHitTarget }).then(() => clicked = true).catch(e => e);
|
const promise = handle.click({ timeout: 5000, __testHookBeforeHitTarget } as any).then(() => clicked = true).catch(e => e);
|
||||||
const error = await promise;
|
const error = await promise;
|
||||||
expect(clicked).toBe(false);
|
expect(clicked).toBe(false);
|
||||||
expect(await page.evaluate(() => window.clicked)).toBe(undefined);
|
expect(await page.evaluate('window.clicked')).toBe(undefined);
|
||||||
expect(error.message).toContain('elementHandle.click: Timeout 5000ms exceeded.');
|
expect(error.message).toContain('elementHandle.click: Timeout 5000ms exceeded.');
|
||||||
expect(error.message).toContain('element does not receive pointer events');
|
expect(error.message).toContain('element does not receive pointer events');
|
||||||
expect(error.message).toContain('retrying click action');
|
expect(error.message).toContain('retrying click action');
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
import utils from './utils';
|
||||||
|
|
||||||
it('should timeout waiting for stable position', async({page, server}) => {
|
it('should timeout waiting for stable position', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/button.html');
|
await page.goto(server.PREFIX + '/input/button.html');
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright 2018 Google Inc. All rights reserved.
|
|
||||||
* Modifications 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
it.fail(true)('should report that selector does not match anymore', async ({page, server}) => {
|
|
||||||
await page.goto(server.PREFIX + '/react.html');
|
|
||||||
await page.evaluate(() => {
|
|
||||||
renderComponent(e('div', {}, [e(MyButton, { name: 'button1' }), e(MyButton, { name: 'button2' })] ));
|
|
||||||
});
|
|
||||||
const __testHookAfterStable = () => page.evaluate(() => {
|
|
||||||
window.counter = (window.counter || 0) + 1;
|
|
||||||
if (window.counter === 1)
|
|
||||||
renderComponent(e('div', {}, [e(MyButton, { name: 'button2' }), e(MyButton, { name: 'button1' })] ));
|
|
||||||
else
|
|
||||||
renderComponent(e('div', {}, []));
|
|
||||||
});
|
|
||||||
const error = await page.dblclick('text=button1', { __testHookAfterStable, timeout: 3000 }).catch(e => e);
|
|
||||||
expect(await page.evaluate(() => window.button1)).toBe(undefined);
|
|
||||||
expect(await page.evaluate(() => window.button2)).toBe(undefined);
|
|
||||||
expect(error.message).toContain('page.dblclick: Timeout 3000ms exceeded.');
|
|
||||||
expect(error.message).toContain('element does not match the selector anymore');
|
|
||||||
});
|
|
||||||
|
|
||||||
it.fail(true)('should not retarget the handle when element is recycled', async ({page, server}) => {
|
|
||||||
await page.goto(server.PREFIX + '/react.html');
|
|
||||||
await page.evaluate(() => {
|
|
||||||
renderComponent(e('div', {}, [e(MyButton, { name: 'button1' }), e(MyButton, { name: 'button2', disabled: true })] ));
|
|
||||||
});
|
|
||||||
const __testHookBeforeStable = () => page.evaluate(() => {
|
|
||||||
window.counter = (window.counter || 0) + 1;
|
|
||||||
if (window.counter === 1)
|
|
||||||
renderComponent(e('div', {}, [e(MyButton, { name: 'button2', disabled: true }), e(MyButton, { name: 'button1' })] ));
|
|
||||||
});
|
|
||||||
const handle = await page.$('text=button1');
|
|
||||||
const error = await handle.click({ __testHookBeforeStable, timeout: 3000 }).catch(e => e);
|
|
||||||
expect(await page.evaluate(() => window.button1)).toBe(undefined);
|
|
||||||
expect(await page.evaluate(() => window.button2)).toBe(undefined);
|
|
||||||
expect(error.message).toContain('elementHandle.click: Timeout 3000ms exceeded.');
|
|
||||||
expect(error.message).toContain('element is disabled - waiting');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should timeout when click opens alert', async({page, server}) => {
|
|
||||||
const dialogPromise = page.waitForEvent('dialog');
|
|
||||||
await page.setContent(`<div onclick='window.alert(123)'>Click me</div>`);
|
|
||||||
const error = await page.click('div', { timeout: 3000 }).catch(e => e);
|
|
||||||
expect(error.message).toContain('page.click: Timeout 3000ms exceeded.');
|
|
||||||
const dialog = await dialogPromise;
|
|
||||||
await dialog.dismiss();
|
|
||||||
});
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const utils = require('./utils');
|
import utils from './utils';
|
||||||
const {FFOX, CHROMIUM, WEBKIT, HEADLESS, USES_HOOKS} = testOptions;
|
const {FFOX, CHROMIUM, WEBKIT, HEADLESS, USES_HOOKS} = testOptions;
|
||||||
|
|
||||||
async function giveItAChanceToClick(page) {
|
async function giveItAChanceToClick(page) {
|
||||||
|
|
@ -26,7 +26,7 @@ async function giveItAChanceToClick(page) {
|
||||||
it('should click the button', async({page, server}) => {
|
it('should click the button', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/button.html');
|
await page.goto(server.PREFIX + '/input/button.html');
|
||||||
await page.click('button');
|
await page.click('button');
|
||||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
expect(await page.evaluate('result')).toBe('Clicked');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click svg', async({page, server}) => {
|
it('should click svg', async({page, server}) => {
|
||||||
|
|
@ -36,14 +36,14 @@ it('should click svg', async({page, server}) => {
|
||||||
</svg>
|
</svg>
|
||||||
`);
|
`);
|
||||||
await page.click('circle');
|
await page.click('circle');
|
||||||
expect(await page.evaluate(() => window.__CLICKED)).toBe(42);
|
expect(await page.evaluate('__CLICKED')).toBe(42);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click the button if window.Node is removed', async({page, server}) => {
|
it('should click the button if window.Node is removed', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/button.html');
|
await page.goto(server.PREFIX + '/input/button.html');
|
||||||
await page.evaluate(() => delete window.Node);
|
await page.evaluate(() => delete window.Node);
|
||||||
await page.click('button');
|
await page.click('button');
|
||||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
expect(await page.evaluate('result')).toBe('Clicked');
|
||||||
});
|
});
|
||||||
|
|
||||||
// @see https://github.com/GoogleChrome/puppeteer/issues/4281
|
// @see https://github.com/GoogleChrome/puppeteer/issues/4281
|
||||||
|
|
@ -57,7 +57,7 @@ it('should click on a span with an inline element inside', async({page, server})
|
||||||
<span onclick='javascript:window.CLICKED=42'></span>
|
<span onclick='javascript:window.CLICKED=42'></span>
|
||||||
`);
|
`);
|
||||||
await page.click('span');
|
await page.click('span');
|
||||||
expect(await page.evaluate(() => window.CLICKED)).toBe(42);
|
expect(await page.evaluate('CLICKED')).toBe(42);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not throw UnhandledPromiseRejection when page closes', async({browser, server}) => {
|
it('should not throw UnhandledPromiseRejection when page closes', async({browser, server}) => {
|
||||||
|
|
@ -75,7 +75,7 @@ it('should click the button after navigation ', async({page, server}) => {
|
||||||
await page.click('button');
|
await page.click('button');
|
||||||
await page.goto(server.PREFIX + '/input/button.html');
|
await page.goto(server.PREFIX + '/input/button.html');
|
||||||
await page.click('button');
|
await page.click('button');
|
||||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
expect(await page.evaluate('result')).toBe('Clicked');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click the button after a cross origin navigation ', async({page, server}) => {
|
it('should click the button after a cross origin navigation ', async({page, server}) => {
|
||||||
|
|
@ -83,7 +83,7 @@ it('should click the button after a cross origin navigation ', async({page, serv
|
||||||
await page.click('button');
|
await page.click('button');
|
||||||
await page.goto(server.CROSS_PROCESS_PREFIX + '/input/button.html');
|
await page.goto(server.CROSS_PROCESS_PREFIX + '/input/button.html');
|
||||||
await page.click('button');
|
await page.click('button');
|
||||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
expect(await page.evaluate('result')).toBe('Clicked');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click with disabled javascript', async({browser, server}) => {
|
it('should click with disabled javascript', async({browser, server}) => {
|
||||||
|
|
@ -109,7 +109,7 @@ it('should click when one of inline box children is outside of viewport', async(
|
||||||
<span onclick='javascript:window.CLICKED = 42;'><i>woof</i><b>doggo</b></span>
|
<span onclick='javascript:window.CLICKED = 42;'><i>woof</i><b>doggo</b></span>
|
||||||
`);
|
`);
|
||||||
await page.click('span');
|
await page.click('span');
|
||||||
expect(await page.evaluate(() => window.CLICKED)).toBe(42);
|
expect(await page.evaluate('CLICKED')).toBe(42);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should select the text by triple clicking', async({page, server}) => {
|
it('should select the text by triple clicking', async({page, server}) => {
|
||||||
|
|
@ -150,7 +150,7 @@ it('should click offscreen buttons', async({page, server}) => {
|
||||||
it('should waitFor visible when already visible', async({page, server}) => {
|
it('should waitFor visible when already visible', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/button.html');
|
await page.goto(server.PREFIX + '/input/button.html');
|
||||||
await page.click('button');
|
await page.click('button');
|
||||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
expect(await page.evaluate('result')).toBe('Clicked');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not wait with force', async({page, server}) => {
|
it('should not wait with force', async({page, server}) => {
|
||||||
|
|
@ -159,7 +159,7 @@ it('should not wait with force', async({page, server}) => {
|
||||||
await page.$eval('button', b => b.style.display = 'none');
|
await page.$eval('button', b => b.style.display = 'none');
|
||||||
await page.click('button', { force: true }).catch(e => error = e);
|
await page.click('button', { force: true }).catch(e => error = e);
|
||||||
expect(error.message).toContain('Element is not visible');
|
expect(error.message).toContain('Element is not visible');
|
||||||
expect(await page.evaluate(() => result)).toBe('Was not clicked');
|
expect(await page.evaluate('result')).toBe('Was not clicked');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should waitFor display:none to be gone', async({page, server}) => {
|
it('should waitFor display:none to be gone', async({page, server}) => {
|
||||||
|
|
@ -168,12 +168,12 @@ it('should waitFor display:none to be gone', async({page, server}) => {
|
||||||
await page.$eval('button', b => b.style.display = 'none');
|
await page.$eval('button', b => b.style.display = 'none');
|
||||||
const clicked = page.click('button', { timeout: 0 }).then(() => done = true);
|
const clicked = page.click('button', { timeout: 0 }).then(() => done = true);
|
||||||
await giveItAChanceToClick(page);
|
await giveItAChanceToClick(page);
|
||||||
expect(await page.evaluate(() => result)).toBe('Was not clicked');
|
expect(await page.evaluate('result')).toBe('Was not clicked');
|
||||||
expect(done).toBe(false);
|
expect(done).toBe(false);
|
||||||
await page.$eval('button', b => b.style.display = 'block');
|
await page.$eval('button', b => b.style.display = 'block');
|
||||||
await clicked;
|
await clicked;
|
||||||
expect(done).toBe(true);
|
expect(done).toBe(true);
|
||||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
expect(await page.evaluate('result')).toBe('Clicked');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should waitFor visibility:hidden to be gone', async({page, server}) => {
|
it('should waitFor visibility:hidden to be gone', async({page, server}) => {
|
||||||
|
|
@ -182,12 +182,12 @@ it('should waitFor visibility:hidden to be gone', async({page, server}) => {
|
||||||
await page.$eval('button', b => b.style.visibility = 'hidden');
|
await page.$eval('button', b => b.style.visibility = 'hidden');
|
||||||
const clicked = page.click('button', { timeout: 0 }).then(() => done = true);
|
const clicked = page.click('button', { timeout: 0 }).then(() => done = true);
|
||||||
await giveItAChanceToClick(page);
|
await giveItAChanceToClick(page);
|
||||||
expect(await page.evaluate(() => result)).toBe('Was not clicked');
|
expect(await page.evaluate('result')).toBe('Was not clicked');
|
||||||
expect(done).toBe(false);
|
expect(done).toBe(false);
|
||||||
await page.$eval('button', b => b.style.visibility = 'visible');
|
await page.$eval('button', b => b.style.visibility = 'visible');
|
||||||
await clicked;
|
await clicked;
|
||||||
expect(done).toBe(true);
|
expect(done).toBe(true);
|
||||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
expect(await page.evaluate('result')).toBe('Clicked');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should waitFor visible when parent is hidden', async({page, server}) => {
|
it('should waitFor visible when parent is hidden', async({page, server}) => {
|
||||||
|
|
@ -200,21 +200,21 @@ it('should waitFor visible when parent is hidden', async({page, server}) => {
|
||||||
await page.$eval('button', b => b.parentElement.style.display = 'block');
|
await page.$eval('button', b => b.parentElement.style.display = 'block');
|
||||||
await clicked;
|
await clicked;
|
||||||
expect(done).toBe(true);
|
expect(done).toBe(true);
|
||||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
expect(await page.evaluate('result')).toBe('Clicked');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click wrapped links', async({page, server}) => {
|
it('should click wrapped links', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/wrappedlink.html');
|
await page.goto(server.PREFIX + '/wrappedlink.html');
|
||||||
await page.click('a');
|
await page.click('a');
|
||||||
expect(await page.evaluate(() => window.__clicked)).toBe(true);
|
expect(await page.evaluate('__clicked')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click on checkbox input and toggle', async({page, server}) => {
|
it('should click on checkbox input and toggle', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/checkbox.html');
|
await page.goto(server.PREFIX + '/input/checkbox.html');
|
||||||
expect(await page.evaluate(() => result.check)).toBe(null);
|
expect(await page.evaluate(() => window['result'].check)).toBe(null);
|
||||||
await page.click('input#agree');
|
await page.click('input#agree');
|
||||||
expect(await page.evaluate(() => result.check)).toBe(true);
|
expect(await page.evaluate(() => window['result'].check)).toBe(true);
|
||||||
expect(await page.evaluate(() => result.events)).toEqual([
|
expect(await page.evaluate(() => window['result'].events)).toEqual([
|
||||||
'mouseover',
|
'mouseover',
|
||||||
'mouseenter',
|
'mouseenter',
|
||||||
'mousemove',
|
'mousemove',
|
||||||
|
|
@ -225,21 +225,21 @@ it('should click on checkbox input and toggle', async({page, server}) => {
|
||||||
'change',
|
'change',
|
||||||
]);
|
]);
|
||||||
await page.click('input#agree');
|
await page.click('input#agree');
|
||||||
expect(await page.evaluate(() => result.check)).toBe(false);
|
expect(await page.evaluate(() => window['result'].check)).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click on checkbox label and toggle', async({page, server}) => {
|
it('should click on checkbox label and toggle', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/checkbox.html');
|
await page.goto(server.PREFIX + '/input/checkbox.html');
|
||||||
expect(await page.evaluate(() => result.check)).toBe(null);
|
expect(await page.evaluate(() => window['result'].check)).toBe(null);
|
||||||
await page.click('label[for="agree"]');
|
await page.click('label[for="agree"]');
|
||||||
expect(await page.evaluate(() => result.check)).toBe(true);
|
expect(await page.evaluate(() => window['result'].check)).toBe(true);
|
||||||
expect(await page.evaluate(() => result.events)).toEqual([
|
expect(await page.evaluate(() => window['result'].events)).toEqual([
|
||||||
'click',
|
'click',
|
||||||
'input',
|
'input',
|
||||||
'change',
|
'change',
|
||||||
]);
|
]);
|
||||||
await page.click('label[for="agree"]');
|
await page.click('label[for="agree"]');
|
||||||
expect(await page.evaluate(() => result.check)).toBe(false);
|
expect(await page.evaluate(() => window['result'].check)).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not hang with touch-enabled viewports', async({browser, playwright}) => {
|
it('should not hang with touch-enabled viewports', async({browser, playwright}) => {
|
||||||
|
|
@ -264,10 +264,10 @@ it('should scroll and click the button', async({page, server}) => {
|
||||||
it('should double click the button', async({page, server}) => {
|
it('should double click the button', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/button.html');
|
await page.goto(server.PREFIX + '/input/button.html');
|
||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
window.double = false;
|
window['double'] = false;
|
||||||
const button = document.querySelector('button');
|
const button = document.querySelector('button');
|
||||||
button.addEventListener('dblclick', event => {
|
button.addEventListener('dblclick', event => {
|
||||||
window.double = true;
|
window['double'] = true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
await page.dblclick('button');
|
await page.dblclick('button');
|
||||||
|
|
@ -284,13 +284,13 @@ it('should click a partially obscured button', async({page, server}) => {
|
||||||
button.style.left = '368px';
|
button.style.left = '368px';
|
||||||
});
|
});
|
||||||
await page.click('button');
|
await page.click('button');
|
||||||
expect(await page.evaluate(() => window.result)).toBe('Clicked');
|
expect(await page.evaluate(() => window['result'])).toBe('Clicked');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click a rotated button', async({page, server}) => {
|
it('should click a rotated button', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/rotatedButton.html');
|
await page.goto(server.PREFIX + '/input/rotatedButton.html');
|
||||||
await page.click('button');
|
await page.click('button');
|
||||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
expect(await page.evaluate('result')).toBe('Clicked');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fire contextmenu event on right click', async({page, server}) => {
|
it('should fire contextmenu event on right click', async({page, server}) => {
|
||||||
|
|
@ -313,7 +313,7 @@ it('should click the button inside an iframe', async({page, server}) => {
|
||||||
const frame = page.frames()[1];
|
const frame = page.frames()[1];
|
||||||
const button = await frame.$('button');
|
const button = await frame.$('button');
|
||||||
await button.click();
|
await button.click();
|
||||||
expect(await frame.evaluate(() => window.result)).toBe('Clicked');
|
expect(await frame.evaluate(() => window['result'])).toBe('Clicked');
|
||||||
});
|
});
|
||||||
|
|
||||||
it.fail(CHROMIUM || WEBKIT)('should click the button with fixed position inside an iframe', async({page, server}) => {
|
it.fail(CHROMIUM || WEBKIT)('should click the button with fixed position inside an iframe', async({page, server}) => {
|
||||||
|
|
@ -327,7 +327,7 @@ it.fail(CHROMIUM || WEBKIT)('should click the button with fixed position inside
|
||||||
const frame = page.frames()[1];
|
const frame = page.frames()[1];
|
||||||
await frame.$eval('button', button => button.style.setProperty('position', 'fixed'));
|
await frame.$eval('button', button => button.style.setProperty('position', 'fixed'));
|
||||||
await frame.click('button');
|
await frame.click('button');
|
||||||
expect(await frame.evaluate(() => window.result)).toBe('Clicked');
|
expect(await frame.evaluate(() => window['result'])).toBe('Clicked');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click the button with deviceScaleFactor set', async({browser, server}) => {
|
it('should click the button with deviceScaleFactor set', async({browser, server}) => {
|
||||||
|
|
@ -339,7 +339,7 @@ it('should click the button with deviceScaleFactor set', async({browser, server}
|
||||||
const frame = page.frames()[1];
|
const frame = page.frames()[1];
|
||||||
const button = await frame.$('button');
|
const button = await frame.$('button');
|
||||||
await button.click();
|
await button.click();
|
||||||
expect(await frame.evaluate(() => window.result)).toBe('Clicked');
|
expect(await frame.evaluate(() => window['result'])).toBe('Clicked');
|
||||||
await context.close();
|
await context.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -347,10 +347,10 @@ it('should click the button with px border with offset', async({page, server}) =
|
||||||
await page.goto(server.PREFIX + '/input/button.html');
|
await page.goto(server.PREFIX + '/input/button.html');
|
||||||
await page.$eval('button', button => button.style.borderWidth = '8px');
|
await page.$eval('button', button => button.style.borderWidth = '8px');
|
||||||
await page.click('button', { position: { x: 20, y: 10 } });
|
await page.click('button', { position: { x: 20, y: 10 } });
|
||||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
expect(await page.evaluate('result')).toBe('Clicked');
|
||||||
// Safari reports border-relative offsetX/offsetY.
|
// Safari reports border-relative offsetX/offsetY.
|
||||||
expect(await page.evaluate(() => offsetX)).toBe(WEBKIT ? 20 + 8 : 20);
|
expect(await page.evaluate('offsetX')).toBe(WEBKIT ? 20 + 8 : 20);
|
||||||
expect(await page.evaluate(() => offsetY)).toBe(WEBKIT ? 10 + 8 : 10);
|
expect(await page.evaluate('offsetY')).toBe(WEBKIT ? 10 + 8 : 10);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click the button with em border with offset', async({page, server}) => {
|
it('should click the button with em border with offset', async({page, server}) => {
|
||||||
|
|
@ -358,10 +358,10 @@ it('should click the button with em border with offset', async({page, server}) =
|
||||||
await page.$eval('button', button => button.style.borderWidth = '2em');
|
await page.$eval('button', button => button.style.borderWidth = '2em');
|
||||||
await page.$eval('button', button => button.style.fontSize = '12px');
|
await page.$eval('button', button => button.style.fontSize = '12px');
|
||||||
await page.click('button', { position: { x: 20, y: 10 } });
|
await page.click('button', { position: { x: 20, y: 10 } });
|
||||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
expect(await page.evaluate('result')).toBe('Clicked');
|
||||||
// Safari reports border-relative offsetX/offsetY.
|
// Safari reports border-relative offsetX/offsetY.
|
||||||
expect(await page.evaluate(() => offsetX)).toBe(WEBKIT ? 12 * 2 + 20 : 20);
|
expect(await page.evaluate('offsetX')).toBe(WEBKIT ? 12 * 2 + 20 : 20);
|
||||||
expect(await page.evaluate(() => offsetY)).toBe(WEBKIT ? 12 * 2 + 10 : 10);
|
expect(await page.evaluate('offsetY')).toBe(WEBKIT ? 12 * 2 + 10 : 10);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click a very large button with offset', async({page, server}) => {
|
it('should click a very large button with offset', async({page, server}) => {
|
||||||
|
|
@ -369,10 +369,10 @@ it('should click a very large button with offset', async({page, server}) => {
|
||||||
await page.$eval('button', button => button.style.borderWidth = '8px');
|
await page.$eval('button', button => button.style.borderWidth = '8px');
|
||||||
await page.$eval('button', button => button.style.height = button.style.width = '2000px');
|
await page.$eval('button', button => button.style.height = button.style.width = '2000px');
|
||||||
await page.click('button', { position: { x: 1900, y: 1910 } });
|
await page.click('button', { position: { x: 1900, y: 1910 } });
|
||||||
expect(await page.evaluate(() => window.result)).toBe('Clicked');
|
expect(await page.evaluate(() => window['result'])).toBe('Clicked');
|
||||||
// Safari reports border-relative offsetX/offsetY.
|
// Safari reports border-relative offsetX/offsetY.
|
||||||
expect(await page.evaluate(() => offsetX)).toBe(WEBKIT ? 1900 + 8 : 1900);
|
expect(await page.evaluate('offsetX')).toBe(WEBKIT ? 1900 + 8 : 1900);
|
||||||
expect(await page.evaluate(() => offsetY)).toBe(WEBKIT ? 1910 + 8 : 1910);
|
expect(await page.evaluate('offsetY')).toBe(WEBKIT ? 1910 + 8 : 1910);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click a button in scrolling container with offset', async({page, server}) => {
|
it('should click a button in scrolling container with offset', async({page, server}) => {
|
||||||
|
|
@ -389,10 +389,10 @@ it('should click a button in scrolling container with offset', async({page, serv
|
||||||
button.style.borderWidth = '8px';
|
button.style.borderWidth = '8px';
|
||||||
});
|
});
|
||||||
await page.click('button', { position: { x: 1900, y: 1910 } });
|
await page.click('button', { position: { x: 1900, y: 1910 } });
|
||||||
expect(await page.evaluate(() => window.result)).toBe('Clicked');
|
expect(await page.evaluate(() => window['result'])).toBe('Clicked');
|
||||||
// Safari reports border-relative offsetX/offsetY.
|
// Safari reports border-relative offsetX/offsetY.
|
||||||
expect(await page.evaluate(() => offsetX)).toBe(WEBKIT ? 1900 + 8 : 1900);
|
expect(await page.evaluate('offsetX')).toBe(WEBKIT ? 1900 + 8 : 1900);
|
||||||
expect(await page.evaluate(() => offsetY)).toBe(WEBKIT ? 1910 + 8 : 1910);
|
expect(await page.evaluate('offsetY')).toBe(WEBKIT ? 1910 + 8 : 1910);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip(FFOX)('should click the button with offset with page scale', async({browser, server}) => {
|
it.skip(FFOX)('should click the button with offset with page scale', async({browser, server}) => {
|
||||||
|
|
@ -404,7 +404,7 @@ it.skip(FFOX)('should click the button with offset with page scale', async({brow
|
||||||
document.body.style.margin = '0';
|
document.body.style.margin = '0';
|
||||||
});
|
});
|
||||||
await page.click('button', { position: { x: 20, y: 10 } });
|
await page.click('button', { position: { x: 20, y: 10 } });
|
||||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
expect(await page.evaluate('result')).toBe('Clicked');
|
||||||
const round = x => Math.round(x + 0.01);
|
const round = x => Math.round(x + 0.01);
|
||||||
let expected = { x: 28, y: 18 }; // 20;10 + 8px of border in each direction
|
let expected = { x: 28, y: 18 }; // 20;10 + 8px of border in each direction
|
||||||
if (WEBKIT) {
|
if (WEBKIT) {
|
||||||
|
|
@ -414,8 +414,8 @@ it.skip(FFOX)('should click the button with offset with page scale', async({brow
|
||||||
// Headless Chromium rounds down during css -> dip -> css conversion.
|
// Headless Chromium rounds down during css -> dip -> css conversion.
|
||||||
expected = { x: 27, y: 18 };
|
expected = { x: 27, y: 18 };
|
||||||
}
|
}
|
||||||
expect(round(await page.evaluate(() => pageX))).toBe(expected.x);
|
expect(round(await page.evaluate('pageX'))).toBe(expected.x);
|
||||||
expect(round(await page.evaluate(() => pageY))).toBe(expected.y);
|
expect(round(await page.evaluate('pageY'))).toBe(expected.y);
|
||||||
await context.close();
|
await context.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -433,9 +433,9 @@ it('should wait for stable position', async({page, server}) => {
|
||||||
document.body.style.margin = '0';
|
document.body.style.margin = '0';
|
||||||
});
|
});
|
||||||
await page.click('button');
|
await page.click('button');
|
||||||
expect(await page.evaluate(() => window.result)).toBe('Clicked');
|
expect(await page.evaluate(() => window['result'])).toBe('Clicked');
|
||||||
expect(await page.evaluate(() => pageX)).toBe(300);
|
expect(await page.evaluate('pageX')).toBe(300);
|
||||||
expect(await page.evaluate(() => pageY)).toBe(10);
|
expect(await page.evaluate('pageY')).toBe(10);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should wait for becoming hit target', async({page, server}) => {
|
it('should wait for becoming hit target', async({page, server}) => {
|
||||||
|
|
@ -467,7 +467,7 @@ it('should wait for becoming hit target', async({page, server}) => {
|
||||||
await page.$eval('.flyover', flyOver => flyOver.style.left = '200px');
|
await page.$eval('.flyover', flyOver => flyOver.style.left = '200px');
|
||||||
await clickPromise;
|
await clickPromise;
|
||||||
expect(clicked).toBe(true);
|
expect(clicked).toBe(true);
|
||||||
expect(await page.evaluate(() => window.result)).toBe('Clicked');
|
expect(await page.evaluate(() => window['result'])).toBe('Clicked');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when obscured and not waiting for hit target', async({page, server}) => {
|
it('should fail when obscured and not waiting for hit target', async({page, server}) => {
|
||||||
|
|
@ -484,7 +484,7 @@ it('should fail when obscured and not waiting for hit target', async({page, serv
|
||||||
document.body.appendChild(blocker);
|
document.body.appendChild(blocker);
|
||||||
});
|
});
|
||||||
await button.click({ force: true });
|
await button.click({ force: true });
|
||||||
expect(await page.evaluate(() => window.result)).toBe('Was not clicked');
|
expect(await page.evaluate(() => window['result'])).toBe('Was not clicked');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should wait for button to be enabled', async({page, server}) => {
|
it('should wait for button to be enabled', async({page, server}) => {
|
||||||
|
|
@ -492,11 +492,11 @@ it('should wait for button to be enabled', async({page, server}) => {
|
||||||
let done = false;
|
let done = false;
|
||||||
const clickPromise = page.click('text=Click target').then(() => done = true);
|
const clickPromise = page.click('text=Click target').then(() => done = true);
|
||||||
await giveItAChanceToClick(page);
|
await giveItAChanceToClick(page);
|
||||||
expect(await page.evaluate(() => window.__CLICKED)).toBe(undefined);
|
expect(await page.evaluate('window.__CLICKED')).toBe(undefined);
|
||||||
expect(done).toBe(false);
|
expect(done).toBe(false);
|
||||||
await page.evaluate(() => document.querySelector('button').removeAttribute('disabled'));
|
await page.evaluate(() => document.querySelector('button').removeAttribute('disabled'));
|
||||||
await clickPromise;
|
await clickPromise;
|
||||||
expect(await page.evaluate(() => window.__CLICKED)).toBe(true);
|
expect(await page.evaluate('__CLICKED')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should wait for input to be enabled', async({page, server}) => {
|
it('should wait for input to be enabled', async({page, server}) => {
|
||||||
|
|
@ -504,11 +504,11 @@ it('should wait for input to be enabled', async({page, server}) => {
|
||||||
let done = false;
|
let done = false;
|
||||||
const clickPromise = page.click('input').then(() => done = true);
|
const clickPromise = page.click('input').then(() => done = true);
|
||||||
await giveItAChanceToClick(page);
|
await giveItAChanceToClick(page);
|
||||||
expect(await page.evaluate(() => window.__CLICKED)).toBe(undefined);
|
expect(await page.evaluate('window.__CLICKED')).toBe(undefined);
|
||||||
expect(done).toBe(false);
|
expect(done).toBe(false);
|
||||||
await page.evaluate(() => document.querySelector('input').removeAttribute('disabled'));
|
await page.evaluate(() => document.querySelector('input').removeAttribute('disabled'));
|
||||||
await clickPromise;
|
await clickPromise;
|
||||||
expect(await page.evaluate(() => window.__CLICKED)).toBe(true);
|
expect(await page.evaluate('__CLICKED')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should wait for select to be enabled', async({page, server}) => {
|
it('should wait for select to be enabled', async({page, server}) => {
|
||||||
|
|
@ -516,29 +516,29 @@ it('should wait for select to be enabled', async({page, server}) => {
|
||||||
let done = false;
|
let done = false;
|
||||||
const clickPromise = page.click('select').then(() => done = true);
|
const clickPromise = page.click('select').then(() => done = true);
|
||||||
await giveItAChanceToClick(page);
|
await giveItAChanceToClick(page);
|
||||||
expect(await page.evaluate(() => window.__CLICKED)).toBe(undefined);
|
expect(await page.evaluate('window.__CLICKED')).toBe(undefined);
|
||||||
expect(done).toBe(false);
|
expect(done).toBe(false);
|
||||||
await page.evaluate(() => document.querySelector('select').removeAttribute('disabled'));
|
await page.evaluate(() => document.querySelector('select').removeAttribute('disabled'));
|
||||||
await clickPromise;
|
await clickPromise;
|
||||||
expect(await page.evaluate(() => window.__CLICKED)).toBe(true);
|
expect(await page.evaluate('__CLICKED')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click disabled div', async({page, server}) => {
|
it('should click disabled div', async({page, server}) => {
|
||||||
await page.setContent('<div onclick="javascript:window.__CLICKED=true;" disabled>Click target</div>');
|
await page.setContent('<div onclick="javascript:window.__CLICKED=true;" disabled>Click target</div>');
|
||||||
await page.click('text=Click target');
|
await page.click('text=Click target');
|
||||||
expect(await page.evaluate(() => window.__CLICKED)).toBe(true);
|
expect(await page.evaluate('__CLICKED')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should climb dom for inner label with pointer-events:none', async({page, server}) => {
|
it('should climb dom for inner label with pointer-events:none', async({page, server}) => {
|
||||||
await page.setContent('<button onclick="javascript:window.__CLICKED=true;"><label style="pointer-events:none">Click target</label></button>');
|
await page.setContent('<button onclick="javascript:window.__CLICKED=true;"><label style="pointer-events:none">Click target</label></button>');
|
||||||
await page.click('text=Click target');
|
await page.click('text=Click target');
|
||||||
expect(await page.evaluate(() => window.__CLICKED)).toBe(true);
|
expect(await page.evaluate('__CLICKED')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should climb up to [role=button]', async({page, server}) => {
|
it('should climb up to [role=button]', async({page, server}) => {
|
||||||
await page.setContent('<div role=button onclick="javascript:window.__CLICKED=true;"><div style="pointer-events:none"><span><div>Click target</div></span></div>');
|
await page.setContent('<div role=button onclick="javascript:window.__CLICKED=true;"><div style="pointer-events:none"><span><div>Click target</div></span></div>');
|
||||||
await page.click('text=Click target');
|
await page.click('text=Click target');
|
||||||
expect(await page.evaluate(() => window.__CLICKED)).toBe(true);
|
expect(await page.evaluate('__CLICKED')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should wait for BUTTON to be clickable when it has pointer-events:none', async({page, server}) => {
|
it('should wait for BUTTON to be clickable when it has pointer-events:none', async({page, server}) => {
|
||||||
|
|
@ -546,11 +546,11 @@ it('should wait for BUTTON to be clickable when it has pointer-events:none', asy
|
||||||
let done = false;
|
let done = false;
|
||||||
const clickPromise = page.click('text=Click target').then(() => done = true);
|
const clickPromise = page.click('text=Click target').then(() => done = true);
|
||||||
await giveItAChanceToClick(page);
|
await giveItAChanceToClick(page);
|
||||||
expect(await page.evaluate(() => window.__CLICKED)).toBe(undefined);
|
expect(await page.evaluate('window.__CLICKED')).toBe(undefined);
|
||||||
expect(done).toBe(false);
|
expect(done).toBe(false);
|
||||||
await page.evaluate(() => document.querySelector('button').style.removeProperty('pointer-events'));
|
await page.evaluate(() => document.querySelector('button').style.removeProperty('pointer-events'));
|
||||||
await clickPromise;
|
await clickPromise;
|
||||||
expect(await page.evaluate(() => window.__CLICKED)).toBe(true);
|
expect(await page.evaluate('__CLICKED')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should wait for LABEL to be clickable when it has pointer-events:none', async({page, server}) => {
|
it('should wait for LABEL to be clickable when it has pointer-events:none', async({page, server}) => {
|
||||||
|
|
@ -558,28 +558,28 @@ it('should wait for LABEL to be clickable when it has pointer-events:none', asyn
|
||||||
const clickPromise = page.click('text=Click target');
|
const clickPromise = page.click('text=Click target');
|
||||||
// Do a few roundtrips to the page.
|
// Do a few roundtrips to the page.
|
||||||
for (let i = 0; i < 5; ++i)
|
for (let i = 0; i < 5; ++i)
|
||||||
expect(await page.evaluate(() => window.__CLICKED)).toBe(undefined);
|
expect(await page.evaluate('window.__CLICKED')).toBe(undefined);
|
||||||
// remove `pointer-events: none` css from button.
|
// remove `pointer-events: none` css from button.
|
||||||
await page.evaluate(() => document.querySelector('label').style.removeProperty('pointer-events'));
|
await page.evaluate(() => document.querySelector('label').style.removeProperty('pointer-events'));
|
||||||
await clickPromise;
|
await clickPromise;
|
||||||
expect(await page.evaluate(() => window.__CLICKED)).toBe(true);
|
expect(await page.evaluate('__CLICKED')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update modifiers correctly', async({page, server}) => {
|
it('should update modifiers correctly', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/button.html');
|
await page.goto(server.PREFIX + '/input/button.html');
|
||||||
await page.click('button', { modifiers: ['Shift'] });
|
await page.click('button', { modifiers: ['Shift'] });
|
||||||
expect(await page.evaluate(() => shiftKey)).toBe(true);
|
expect(await page.evaluate('shiftKey')).toBe(true);
|
||||||
await page.click('button', { modifiers: [] });
|
await page.click('button', { modifiers: [] });
|
||||||
expect(await page.evaluate(() => shiftKey)).toBe(false);
|
expect(await page.evaluate('shiftKey')).toBe(false);
|
||||||
|
|
||||||
await page.keyboard.down('Shift');
|
await page.keyboard.down('Shift');
|
||||||
await page.click('button', { modifiers: [] });
|
await page.click('button', { modifiers: [] });
|
||||||
expect(await page.evaluate(() => shiftKey)).toBe(false);
|
expect(await page.evaluate('shiftKey')).toBe(false);
|
||||||
await page.click('button');
|
await page.click('button');
|
||||||
expect(await page.evaluate(() => shiftKey)).toBe(true);
|
expect(await page.evaluate('shiftKey')).toBe(true);
|
||||||
await page.keyboard.up('Shift');
|
await page.keyboard.up('Shift');
|
||||||
await page.click('button');
|
await page.click('button');
|
||||||
expect(await page.evaluate(() => shiftKey)).toBe(false);
|
expect(await page.evaluate('shiftKey')).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click an offscreen element when scroll-behavior is smooth', async({page}) => {
|
it('should click an offscreen element when scroll-behavior is smooth', async({page}) => {
|
||||||
|
|
@ -594,45 +594,45 @@ it('should click an offscreen element when scroll-behavior is smooth', async({pa
|
||||||
|
|
||||||
it('should report nice error when element is detached and force-clicked', async({page, server}) => {
|
it('should report nice error when element is detached and force-clicked', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/animating-button.html');
|
await page.goto(server.PREFIX + '/input/animating-button.html');
|
||||||
await page.evaluate(() => addButton());
|
await page.evaluate('addButton()');
|
||||||
const handle = await page.$('button');
|
const handle = await page.$('button');
|
||||||
await page.evaluate(() => stopButton(true));
|
await page.evaluate('stopButton(true)');
|
||||||
const promise = handle.click({ force: true }).catch(e => e);
|
const promise = handle.click({ force: true }).catch(e => e);
|
||||||
const error = await promise;
|
const error = await promise;
|
||||||
expect(await page.evaluate(() => window.clicked)).toBe(undefined);
|
expect(await page.evaluate('window.clicked')).toBe(undefined);
|
||||||
expect(error.message).toContain('Element is not attached to the DOM');
|
expect(error.message).toContain('Element is not attached to the DOM');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when element detaches after animation', async({page, server}) => {
|
it('should fail when element detaches after animation', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/animating-button.html');
|
await page.goto(server.PREFIX + '/input/animating-button.html');
|
||||||
await page.evaluate(() => addButton());
|
await page.evaluate('addButton()');
|
||||||
const handle = await page.$('button');
|
const handle = await page.$('button');
|
||||||
const promise = handle.click().catch(e => e);
|
const promise = handle.click().catch(e => e);
|
||||||
await page.evaluate(() => stopButton(true));
|
await page.evaluate('stopButton(true)');
|
||||||
const error = await promise;
|
const error = await promise;
|
||||||
expect(await page.evaluate(() => window.clicked)).toBe(undefined);
|
expect(await page.evaluate('window.clicked')).toBe(undefined);
|
||||||
expect(error.message).toContain('Element is not attached to the DOM');
|
expect(error.message).toContain('Element is not attached to the DOM');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should retry when element detaches after animation', async({page, server}) => {
|
it('should retry when element detaches after animation', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/animating-button.html');
|
await page.goto(server.PREFIX + '/input/animating-button.html');
|
||||||
await page.evaluate(() => addButton());
|
await page.evaluate('addButton()');
|
||||||
let clicked = false;
|
let clicked = false;
|
||||||
const promise = page.click('button').then(() => clicked = true);
|
const promise = page.click('button').then(() => clicked = true);
|
||||||
expect(clicked).toBe(false);
|
expect(clicked).toBe(false);
|
||||||
expect(await page.evaluate(() => window.clicked)).toBe(undefined);
|
expect(await page.evaluate('window.clicked')).toBe(undefined);
|
||||||
await page.evaluate(() => stopButton(true));
|
await page.evaluate('stopButton(true)');
|
||||||
await page.evaluate(() => addButton());
|
await page.evaluate('addButton()');
|
||||||
expect(clicked).toBe(false);
|
expect(clicked).toBe(false);
|
||||||
expect(await page.evaluate(() => window.clicked)).toBe(undefined);
|
expect(await page.evaluate('window.clicked')).toBe(undefined);
|
||||||
await page.evaluate(() => stopButton(true));
|
await page.evaluate('stopButton(true)');
|
||||||
await page.evaluate(() => addButton());
|
await page.evaluate('addButton()');
|
||||||
expect(clicked).toBe(false);
|
expect(clicked).toBe(false);
|
||||||
expect(await page.evaluate(() => window.clicked)).toBe(undefined);
|
expect(await page.evaluate('window.clicked')).toBe(undefined);
|
||||||
await page.evaluate(() => stopButton(false));
|
await page.evaluate('stopButton(false)');
|
||||||
await promise;
|
await promise;
|
||||||
expect(clicked).toBe(true);
|
expect(clicked).toBe(true);
|
||||||
expect(await page.evaluate(() => window.clicked)).toBe(true);
|
expect(await page.evaluate('clicked')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should retry when element is animating from outside the viewport', async({page, server}) => {
|
it('should retry when element is animating from outside the viewport', async({page, server}) => {
|
||||||
|
|
@ -660,7 +660,7 @@ it('should retry when element is animating from outside the viewport', async({pa
|
||||||
const promise = handle.click();
|
const promise = handle.click();
|
||||||
await handle.evaluate(button => button.className = 'animated');
|
await handle.evaluate(button => button.className = 'animated');
|
||||||
await promise;
|
await promise;
|
||||||
expect(await page.evaluate(() => window.clicked)).toBe(true);
|
expect(await page.evaluate('clicked')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when element is animating from outside the viewport with force', async({page, server}) => {
|
it('should fail when element is animating from outside the viewport with force', async({page, server}) => {
|
||||||
|
|
@ -688,7 +688,7 @@ it('should fail when element is animating from outside the viewport with force',
|
||||||
const promise = handle.click({ force: true }).catch(e => e);
|
const promise = handle.click({ force: true }).catch(e => e);
|
||||||
await handle.evaluate(button => button.className = 'animated');
|
await handle.evaluate(button => button.className = 'animated');
|
||||||
const error = await promise;
|
const error = await promise;
|
||||||
expect(await page.evaluate(() => window.clicked)).toBe(undefined);
|
expect(await page.evaluate('window.clicked')).toBe(undefined);
|
||||||
expect(error.message).toContain('Element is outside of the viewport');
|
expect(error.message).toContain('Element is outside of the viewport');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -707,70 +707,17 @@ it('should dispatch microtasks in order', async({page, server}) => {
|
||||||
document.body.appendChild(document.createElement('div'));
|
document.body.appendChild(document.createElement('div'));
|
||||||
});
|
});
|
||||||
button.addEventListener('mouseup', () => {
|
button.addEventListener('mouseup', () => {
|
||||||
window.result = mutationCount;
|
window['result'] = mutationCount;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
`);
|
`);
|
||||||
await page.click('button');
|
await page.click('button');
|
||||||
expect(await page.evaluate(() => window.result)).toBe(1);
|
expect(await page.evaluate(() => window['result'])).toBe(1);
|
||||||
});
|
|
||||||
|
|
||||||
it.fail(true)('should retarget when element is recycled during hit testing', async ({page, server}) => {
|
|
||||||
await page.goto(server.PREFIX + '/react.html');
|
|
||||||
await page.evaluate(() => {
|
|
||||||
renderComponent(e('div', {}, [e(MyButton, { name: 'button1' }), e(MyButton, { name: 'button2' })] ));
|
|
||||||
});
|
|
||||||
const __testHookAfterStable = () => page.evaluate(() => {
|
|
||||||
window.counter = (window.counter || 0) + 1;
|
|
||||||
if (window.counter === 1)
|
|
||||||
renderComponent(e('div', {}, [e(MyButton, { name: 'button2' }), e(MyButton, { name: 'button1' })] ));
|
|
||||||
});
|
|
||||||
await page.click('text=button1', { __testHookAfterStable });
|
|
||||||
expect(await page.evaluate(() => window.button1)).toBe(true);
|
|
||||||
expect(await page.evaluate(() => window.button2)).toBe(undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
it.fail(true)('should retarget when element is recycled before enabled check', async ({page, server}) => {
|
|
||||||
await page.goto(server.PREFIX + '/react.html');
|
|
||||||
await page.evaluate(() => {
|
|
||||||
renderComponent(e('div', {}, [e(MyButton, { name: 'button1' }), e(MyButton, { name: 'button2', disabled: true })] ));
|
|
||||||
});
|
|
||||||
const __testHookBeforeStable = () => page.evaluate(() => {
|
|
||||||
window.counter = (window.counter || 0) + 1;
|
|
||||||
if (window.counter === 1)
|
|
||||||
renderComponent(e('div', {}, [e(MyButton, { name: 'button2', disabled: true }), e(MyButton, { name: 'button1' })] ));
|
|
||||||
});
|
|
||||||
await page.click('text=button1', { __testHookBeforeStable });
|
|
||||||
expect(await page.evaluate(() => window.button1)).toBe(true);
|
|
||||||
expect(await page.evaluate(() => window.button2)).toBe(undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not retarget when element changes on hover', async ({page, server}) => {
|
|
||||||
await page.goto(server.PREFIX + '/react.html');
|
|
||||||
await page.evaluate(() => {
|
|
||||||
renderComponent(e('div', {}, [e(MyButton, { name: 'button1', renameOnHover: true }), e(MyButton, { name: 'button2' })] ));
|
|
||||||
});
|
|
||||||
await page.click('text=button1');
|
|
||||||
expect(await page.evaluate(() => window.button1)).toBe(true);
|
|
||||||
expect(await page.evaluate(() => window.button2)).toBe(undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not retarget when element is recycled on hover', async ({page, server}) => {
|
|
||||||
await page.goto(server.PREFIX + '/react.html');
|
|
||||||
await page.evaluate(() => {
|
|
||||||
function shuffle() {
|
|
||||||
renderComponent(e('div', {}, [e(MyButton, { name: 'button2' }), e(MyButton, { name: 'button1' })] ));
|
|
||||||
}
|
|
||||||
renderComponent(e('div', {}, [e(MyButton, { name: 'button1', onHover: shuffle }), e(MyButton, { name: 'button2' })] ));
|
|
||||||
});
|
|
||||||
await page.click('text=button1');
|
|
||||||
expect(await page.evaluate(() => window.button1)).toBe(undefined);
|
|
||||||
expect(await page.evaluate(() => window.button2)).toBe(true);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click the button when window.innerWidth is corrupted', async({page, server}) => {
|
it('should click the button when window.innerWidth is corrupted', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/button.html');
|
await page.goto(server.PREFIX + '/input/button.html');
|
||||||
await page.evaluate(() => window.innerWidth = 0);
|
await page.evaluate(() => Object.defineProperty(window, 'innerWidth', {value: 0}));
|
||||||
await page.click('button');
|
await page.click('button');
|
||||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
expect(await page.evaluate('result')).toBe('Clicked');
|
||||||
});
|
});
|
||||||
|
|
@ -15,14 +15,20 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const fs = require('fs');
|
import fs from 'fs';
|
||||||
const path = require('path');
|
import path from 'path';
|
||||||
const utils = require('./utils');
|
import utils from './utils';
|
||||||
const os = require('os');
|
import os from 'os';
|
||||||
|
import { BrowserType, Browser, BrowserContext, Page } from '..';
|
||||||
const {mkdtempAsync, makeUserDataDir, removeUserDataDir} = utils;
|
const {removeFolderAsync, mkdtempAsync, removeUserDataDir, makeUserDataDir} = utils;
|
||||||
const {FFOX, MAC, CHROMIUM, WEBKIT, WIN, USES_HOOKS} = testOptions;
|
const {FFOX, MAC, CHROMIUM, WEBKIT, WIN, USES_HOOKS} = testOptions;
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface FixtureState {
|
||||||
|
userDataDir: string;
|
||||||
|
launchPersistent: (options?: Parameters<BrowserType<Browser>['launchPersistentContext']>[1]) => Promise<{context: BrowserContext, page: Page}>;
|
||||||
|
}
|
||||||
|
}
|
||||||
registerFixture('userDataDir', async ({}, test) => {
|
registerFixture('userDataDir', async ({}, test) => {
|
||||||
const userDataDir = await mkdtempAsync(path.join(os.tmpdir(), 'playwright_dev_profile-'));
|
const userDataDir = await mkdtempAsync(path.join(os.tmpdir(), 'playwright_dev_profile-'));
|
||||||
try {
|
try {
|
||||||
|
|
@ -173,7 +179,7 @@ it('should support bypassCSP option', async ({server, launchPersistent}) => {
|
||||||
const {page, context} = await launchPersistent({bypassCSP: true});
|
const {page, context} = await launchPersistent({bypassCSP: true});
|
||||||
await page.goto(server.PREFIX + '/csp.html');
|
await page.goto(server.PREFIX + '/csp.html');
|
||||||
await page.addScriptTag({content: 'window.__injected = 42;'});
|
await page.addScriptTag({content: 'window.__injected = 42;'});
|
||||||
expect(await page.evaluate(() => window.__injected)).toBe(42);
|
expect(await page.evaluate('__injected')).toBe(42);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support javascriptEnabled option', async ({server, launchPersistent}) => {
|
it('should support javascriptEnabled option', async ({server, launchPersistent}) => {
|
||||||
|
|
@ -14,14 +14,19 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const fs = require('fs');
|
import fs from 'fs';
|
||||||
const path = require('path');
|
import path from 'path';
|
||||||
const util = require('util');
|
import util from 'util';
|
||||||
const os = require('os');
|
import os from 'os';
|
||||||
const {mkdtempAsync, removeFolderAsync} = require('./utils');
|
import {mkdtempAsync, removeFolderAsync} from './utils';
|
||||||
|
|
||||||
const {FFOX, CHROMIUM, WEBKIT, HEADLESS} = testOptions;
|
const {FFOX, CHROMIUM, WEBKIT, HEADLESS} = testOptions;
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface FixtureState {
|
||||||
|
persistentDirectory: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
registerFixture('persistentDirectory', async ({}, test) => {
|
registerFixture('persistentDirectory', async ({}, test) => {
|
||||||
const persistentDirectory = await mkdtempAsync(path.join(os.tmpdir(), 'playwright-test-'));
|
const persistentDirectory = await mkdtempAsync(path.join(os.tmpdir(), 'playwright-test-'));
|
||||||
try {
|
try {
|
||||||
|
|
@ -203,7 +208,7 @@ it('should report non-navigation downloads', async({browser, server}) => {
|
||||||
|
|
||||||
it(`should report download path within page.on('download', …) handler for Files`, async({browser, server}) => {
|
it(`should report download path within page.on('download', …) handler for Files`, async({browser, server}) => {
|
||||||
const page = await browser.newPage({ acceptDownloads: true });
|
const page = await browser.newPage({ acceptDownloads: true });
|
||||||
const onDownloadPath = new Promise((res) => {
|
const onDownloadPath = new Promise<string>((res) => {
|
||||||
page.on('download', dl => {
|
page.on('download', dl => {
|
||||||
dl.path().then(res);
|
dl.path().then(res);
|
||||||
});
|
});
|
||||||
|
|
@ -216,7 +221,7 @@ it(`should report download path within page.on('download', …) handler for File
|
||||||
})
|
})
|
||||||
it(`should report download path within page.on('download', …) handler for Blobs`, async({browser, server}) => {
|
it(`should report download path within page.on('download', …) handler for Blobs`, async({browser, server}) => {
|
||||||
const page = await browser.newPage({ acceptDownloads: true });
|
const page = await browser.newPage({ acceptDownloads: true });
|
||||||
const onDownloadPath = new Promise((res) => {
|
const onDownloadPath = new Promise<string>((res) => {
|
||||||
page.on('download', dl => {
|
page.on('download', dl => {
|
||||||
dl.path().then(res);
|
dl.path().then(res);
|
||||||
});
|
});
|
||||||
|
|
@ -14,11 +14,19 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const path = require('path');
|
import path from 'path';
|
||||||
const fs = require('fs');
|
import fs from 'fs';
|
||||||
const os = require('os');
|
import os from 'os';
|
||||||
const {mkdtempAsync, removeFolderAsync} = require('./utils');
|
import {mkdtempAsync, removeFolderAsync} from './utils';
|
||||||
|
import { Browser, BrowserContext } from '..';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface FixtureState {
|
||||||
|
downloadsPath: string;
|
||||||
|
downloadsBrowser: Browser;
|
||||||
|
persistentDownloadsContext: BrowserContext;
|
||||||
|
}
|
||||||
|
}
|
||||||
registerFixture('downloadsPath', async ({}, test) => {
|
registerFixture('downloadsPath', async ({}, test) => {
|
||||||
const downloadsPath = await mkdtempAsync(path.join(os.tmpdir(), 'playwright-test-'));
|
const downloadsPath = await mkdtempAsync(path.join(os.tmpdir(), 'playwright-test-'));
|
||||||
try {
|
try {
|
||||||
|
|
@ -66,7 +74,6 @@ registerFixture('persistentDownloadsContext', async ({server, browserType, defau
|
||||||
await test(context);
|
await test(context);
|
||||||
} finally {
|
} finally {
|
||||||
await context.close();
|
await context.close();
|
||||||
await state.context.close();
|
|
||||||
await removeFolderAsync(userDataDir);
|
await removeFolderAsync(userDataDir);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -80,7 +87,7 @@ it('should keep downloadsPath folder', async({downloadsBrowser, downloadsPath, s
|
||||||
]);
|
]);
|
||||||
expect(download.url()).toBe(`${server.PREFIX}/download`);
|
expect(download.url()).toBe(`${server.PREFIX}/download`);
|
||||||
expect(download.suggestedFilename()).toBe(`file.txt`);
|
expect(download.suggestedFilename()).toBe(`file.txt`);
|
||||||
await download.path().catch(e => error = e);
|
await download.path().catch(e => void 0);
|
||||||
await page.close();
|
await page.close();
|
||||||
await downloadsBrowser.close();
|
await downloadsBrowser.close();
|
||||||
expect(fs.existsSync(downloadsPath)).toBeTruthy();
|
expect(fs.existsSync(downloadsPath)).toBeTruthy();
|
||||||
|
|
@ -15,14 +15,21 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const path = require('path');
|
import path from 'path';
|
||||||
const {spawn, execSync} = require('child_process');
|
import {spawn, execSync} from 'child_process';
|
||||||
|
import { BrowserType, Browser, LaunchOptions } from '..';
|
||||||
const {FFOX, CHROMIUM, WEBKIT, WIN, LINUX, HEADLESS} = testOptions;
|
const {FFOX, CHROMIUM, WEBKIT, WIN, LINUX, HEADLESS} = testOptions;
|
||||||
|
|
||||||
const playwrightPath = path.join(__dirname, '..');
|
const playwrightPath = path.join(__dirname, '..');
|
||||||
|
|
||||||
class Wrapper {
|
class Wrapper {
|
||||||
constructor(browserType, defaultBrowserOptions, extraOptions) {
|
_output: Map<any, any>;
|
||||||
|
_outputCallback: Map<any, any>;
|
||||||
|
_browserType: BrowserType<Browser>;
|
||||||
|
_child: import("child_process").ChildProcess;
|
||||||
|
_exitPromise: Promise<unknown>;
|
||||||
|
_exitAndDisconnectPromise: Promise<any>;
|
||||||
|
constructor(browserType: BrowserType<Browser>, defaultBrowserOptions: LaunchOptions, extraOptions?: { stallOnClose: boolean; }) {
|
||||||
this._output = new Map();
|
this._output = new Map();
|
||||||
this._outputCallback = new Map();
|
this._outputCallback = new Map();
|
||||||
|
|
||||||
|
|
@ -91,6 +98,12 @@ class Wrapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface FixtureState {
|
||||||
|
wrapper: Wrapper;
|
||||||
|
stallingWrapper: Wrapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
registerFixture('wrapper', async ({browserType, defaultBrowserOptions}, test) => {
|
registerFixture('wrapper', async ({browserType, defaultBrowserOptions}, test) => {
|
||||||
const wrapper = new Wrapper(browserType, defaultBrowserOptions);
|
const wrapper = new Wrapper(browserType, defaultBrowserOptions);
|
||||||
await wrapper.connect();
|
await wrapper.connect();
|
||||||
|
|
@ -8,5 +8,5 @@
|
||||||
"strictNullChecks": false,
|
"strictNullChecks": false,
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
},
|
},
|
||||||
"include": ["*.spec.js", "types.d.ts", "*.spec.ts"]
|
"include": ["**/*.spec.js", "types.d.ts", "**/*.spec.ts"]
|
||||||
}
|
}
|
||||||
75
test/types.d.ts
vendored
75
test/types.d.ts
vendored
|
|
@ -1,8 +1,6 @@
|
||||||
type ServerResponse = import('http').ServerResponse;
|
type ServerResponse = import('http').ServerResponse;
|
||||||
type IncomingMessage = import('http').IncomingMessage;
|
type IncomingMessage = import('http').IncomingMessage;
|
||||||
|
|
||||||
type Falsy = false|''|0|null|undefined;
|
|
||||||
|
|
||||||
type DescribeFunction = ((name: string, inner: () => void) => void) & {fail(condition: boolean): DescribeFunction};
|
type DescribeFunction = ((name: string, inner: () => void) => void) & {fail(condition: boolean): DescribeFunction};
|
||||||
|
|
||||||
type ItFunction<STATE> = ((name: string, inner: (state: STATE) => Promise<void>) => void) & {
|
type ItFunction<STATE> = ((name: string, inner: (state: STATE) => Promise<void>) => void) & {
|
||||||
|
|
@ -12,48 +10,20 @@ type ItFunction<STATE> = ((name: string, inner: (state: STATE) => Promise<void>)
|
||||||
repeat(n: number): ItFunction<STATE>;
|
repeat(n: number): ItFunction<STATE>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type TestRunner<STATE> = {
|
interface FixtureState {
|
||||||
describe: DescribeFunction;
|
parallelIndex: number;
|
||||||
xdescribe: DescribeFunction;
|
http_server: {server: TestServer, httpsServer: TestServer};
|
||||||
fdescribe: DescribeFunction;
|
defaultBrowserOptions: import('../index').LaunchOptions;
|
||||||
|
|
||||||
it: ItFunction<STATE>;
|
|
||||||
xit: ItFunction<STATE>;
|
|
||||||
fit: ItFunction<STATE>;
|
|
||||||
dit: ItFunction<STATE>;
|
|
||||||
|
|
||||||
beforeAll, beforeEach, afterAll, afterEach;
|
|
||||||
};
|
|
||||||
|
|
||||||
interface TestSetup<STATE> {
|
|
||||||
testRunner: TestRunner<STATE>;
|
|
||||||
product: 'Chromium'|'Firefox'|'WebKit';
|
|
||||||
selectors: import('../index').Selectors;
|
|
||||||
playwrightPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
type TestState = {
|
|
||||||
server: TestServer;
|
|
||||||
httpsServer: TestServer;
|
|
||||||
sourceServer: TestServer;
|
|
||||||
};
|
|
||||||
|
|
||||||
type BrowserState = TestState & {
|
|
||||||
playwright: typeof import('../index');
|
playwright: typeof import('../index');
|
||||||
browserType: import('../index').BrowserType<import('../index').Browser>;
|
browserType: import('../index').BrowserType<import('../index').Browser>;
|
||||||
browser: import('../index').Browser;
|
browser: import('../index').Browser;
|
||||||
browserServer: import('../index').BrowserServer;
|
toImpl: (rpcObject: any) => any;
|
||||||
defaultBrowserOptions: import('../index').LaunchOptions;
|
|
||||||
};
|
|
||||||
|
|
||||||
type PageState = BrowserState & {
|
|
||||||
context: import('../index').BrowserContext;
|
context: import('../index').BrowserContext;
|
||||||
|
server: TestServer;
|
||||||
page: import('../index').Page;
|
page: import('../index').Page;
|
||||||
};
|
httpsServer: TestServer;
|
||||||
type ChromiumPageState = PageState & {
|
browserServer: import('../index').BrowserServer;
|
||||||
browser: import('../index').ChromiumBrowser;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
interface TestServer {
|
interface TestServer {
|
||||||
enableHTTPCache(pathPrefix: string);
|
enableHTTPCache(pathPrefix: string);
|
||||||
|
|
@ -72,15 +42,32 @@ interface TestServer {
|
||||||
CROSS_PROCESS_PREFIX: string;
|
CROSS_PROCESS_PREFIX: string;
|
||||||
EMPTY_PAGE: string;
|
EMPTY_PAGE: string;
|
||||||
}
|
}
|
||||||
|
declare module '' {
|
||||||
|
module 'expect/build/types' {
|
||||||
|
interface Matchers<R> {
|
||||||
|
toBeGolden(name: string): R;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare const expect: typeof import('expect');
|
||||||
|
|
||||||
|
|
||||||
declare const describe: DescribeFunction;
|
declare const describe: DescribeFunction;
|
||||||
declare const fdescribe: DescribeFunction;
|
declare const fdescribe: DescribeFunction;
|
||||||
declare const xdescribe: DescribeFunction;
|
declare const xdescribe: DescribeFunction;
|
||||||
declare const expect: typeof import('expect');
|
declare const it: ItFunction<FixtureState>;
|
||||||
declare const it: ItFunction<PageState>;
|
declare const fit: ItFunction<FixtureState>;
|
||||||
declare const fit: ItFunction<PageState>;
|
declare const dit: ItFunction<FixtureState>;
|
||||||
declare const dit: ItFunction<PageState>;
|
declare const xit: ItFunction<FixtureState>;
|
||||||
declare const xit: ItFunction<PageState>;
|
|
||||||
|
declare const beforeEach: (inner: (state: FixtureState) => Promise<void>) => void;
|
||||||
|
declare const afterEach: (inner: (state: FixtureState) => Promise<void>) => void;
|
||||||
|
declare const beforeAll: (inner: (state: FixtureState) => Promise<void>) => void;
|
||||||
|
declare const afterAll: (inner: (state: FixtureState) => Promise<void>) => void;
|
||||||
|
|
||||||
|
declare const registerFixture: <T extends keyof FixtureState>(name: T, inner: (state: FixtureState, test: (arg: FixtureState[T]) => Promise<void>) => Promise<void>) => void;
|
||||||
|
|
||||||
declare const browserType: import('../index').BrowserType<import('../index').Browser>;
|
declare const browserType: import('../index').BrowserType<import('../index').Browser>;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue