mirror of
https://github.com/microsoft/playwright.git
synced 2024-08-17 08:00:23 +03:00
chore(test): run eslint on tests (#3638)
This commit is contained in:
parent
6ffdd4dfa1
commit
e2057fb8bb
@ -11,7 +11,7 @@ src/server/webkit/protocol.ts
|
||||
/electron-types.d.ts
|
||||
utils/generate_types/overrides.d.ts
|
||||
utils/generate_types/test/test.ts
|
||||
/test/
|
||||
node_modules/
|
||||
browser_patches/*/checkout/
|
||||
packages/**/*.d.ts
|
||||
output/
|
||||
|
@ -78,7 +78,7 @@ it('should work', async function({page}) {
|
||||
expect(await page.accessibility.snapshot()).toEqual(golden);
|
||||
});
|
||||
|
||||
it('should work with regular text', async({page}) => {
|
||||
it('should work with regular text', async ({page}) => {
|
||||
await page.setContent(`<div>Hello World</div>`);
|
||||
const snapshot = await page.accessibility.snapshot();
|
||||
expect(snapshot.children[0]).toEqual({
|
||||
@ -87,31 +87,31 @@ it('should work with regular text', async({page}) => {
|
||||
});
|
||||
});
|
||||
|
||||
it('roledescription', async({page}) => {
|
||||
it('roledescription', async ({page}) => {
|
||||
await page.setContent('<div tabIndex=-1 aria-roledescription="foo">Hi</div>');
|
||||
const snapshot = await page.accessibility.snapshot();
|
||||
expect(snapshot.children[0].roledescription).toEqual('foo');
|
||||
});
|
||||
|
||||
it('orientation', async({page}) => {
|
||||
it('orientation', async ({page}) => {
|
||||
await page.setContent('<a href="" role="slider" aria-orientation="vertical">11</a>');
|
||||
const snapshot = await page.accessibility.snapshot();
|
||||
expect(snapshot.children[0].orientation).toEqual('vertical');
|
||||
});
|
||||
|
||||
it('autocomplete', async({page}) => {
|
||||
it('autocomplete', async ({page}) => {
|
||||
await page.setContent('<div role="textbox" aria-autocomplete="list">hi</div>');
|
||||
const snapshot = await page.accessibility.snapshot();
|
||||
expect(snapshot.children[0].autocomplete).toEqual('list');
|
||||
});
|
||||
|
||||
it('multiselectable', async({page}) => {
|
||||
it('multiselectable', async ({page}) => {
|
||||
await page.setContent('<div role="grid" tabIndex=-1 aria-multiselectable=true>hey</div>');
|
||||
const snapshot = await page.accessibility.snapshot();
|
||||
expect(snapshot.children[0].multiselectable).toEqual(true);
|
||||
});
|
||||
|
||||
it('keyshortcuts', async({page}) => {
|
||||
it('keyshortcuts', async ({page}) => {
|
||||
await page.setContent('<div role="grid" tabIndex=-1 aria-keyshortcuts="foo">hey</div>');
|
||||
const snapshot = await page.accessibility.snapshot();
|
||||
expect(snapshot.children[0].keyshortcuts).toEqual('foo');
|
||||
@ -204,12 +204,12 @@ it.skip(options.FIREFOX || options.WEBKIT)('plain text field with role should no
|
||||
// WebKit rich text accessibility is iffy
|
||||
await page.setContent(`
|
||||
<div contenteditable="plaintext-only" role='textbox'>Edit this image:<img src="fakeimage.png" alt="my fake image"></div>`);
|
||||
const snapshot = await page.accessibility.snapshot();
|
||||
expect(snapshot.children[0]).toEqual({
|
||||
role: 'textbox',
|
||||
name: '',
|
||||
value: 'Edit this image:'
|
||||
});
|
||||
const snapshot = await page.accessibility.snapshot();
|
||||
expect(snapshot.children[0]).toEqual({
|
||||
role: 'textbox',
|
||||
name: '',
|
||||
value: 'Edit this image:'
|
||||
});
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX || options.WEBKIT)('plain text field without role should not have content', async function({page}) {
|
||||
@ -289,7 +289,7 @@ it('checkbox without label should not have children', async function({page}) {
|
||||
expect(snapshot.children[0]).toEqual(golden);
|
||||
});
|
||||
|
||||
it('should work a button', async({page}) => {
|
||||
it('should work a button', async ({page}) => {
|
||||
await page.setContent(`<button>My Button</button>`);
|
||||
|
||||
const button = await page.$('button');
|
||||
@ -299,7 +299,7 @@ it('should work a button', async({page}) => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should work an input', async({page}) => {
|
||||
it('should work an input', async ({page}) => {
|
||||
await page.setContent(`<input title="My Input" value="My Value">`);
|
||||
|
||||
const input = await page.$('input');
|
||||
@ -310,7 +310,7 @@ it('should work an input', async({page}) => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should work on a menu', async({page}) => {
|
||||
it('should work on a menu', async ({page}) => {
|
||||
await page.setContent(`
|
||||
<div role="menu" title="My Menu">
|
||||
<div role="menuitem">First Item</div>
|
||||
@ -331,14 +331,14 @@ it('should work on a menu', async({page}) => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should return null when the element is no longer in DOM', async({page}) => {
|
||||
it('should return null when the element is no longer in DOM', async ({page}) => {
|
||||
await page.setContent(`<button>My Button</button>`);
|
||||
const button = await page.$('button');
|
||||
await page.$eval('button', button => button.remove());
|
||||
expect(await page.accessibility.snapshot({root: button})).toEqual(null);
|
||||
});
|
||||
|
||||
it('should show uninteresting nodes', async({page}) => {
|
||||
it('should show uninteresting nodes', async ({page}) => {
|
||||
await page.setContent(`
|
||||
<div id="root" role="textbox">
|
||||
<div>
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
it('should await navigation when clicking anchor', async({page, server}) => {
|
||||
it('should await navigation when clicking anchor', async ({page, server}) => {
|
||||
const messages = [];
|
||||
server.setRoute('/empty.html', async (req, res) => {
|
||||
messages.push('route');
|
||||
@ -33,7 +33,7 @@ it('should await navigation when clicking anchor', async({page, server}) => {
|
||||
expect(messages.join('|')).toBe('route|navigated|click');
|
||||
});
|
||||
|
||||
it('should await cross-process navigation when clicking anchor', async({page, server}) => {
|
||||
it('should await cross-process navigation when clicking anchor', async ({page, server}) => {
|
||||
const messages = [];
|
||||
server.setRoute('/empty.html', async (req, res) => {
|
||||
messages.push('route');
|
||||
@ -50,7 +50,7 @@ it('should await cross-process navigation when clicking anchor', async({page, se
|
||||
expect(messages.join('|')).toBe('route|navigated|click');
|
||||
});
|
||||
|
||||
it('should await form-get on click', async({page, server}) => {
|
||||
it('should await form-get on click', async ({page, server}) => {
|
||||
const messages = [];
|
||||
server.setRoute('/empty.html?foo=bar', async (req, res) => {
|
||||
messages.push('route');
|
||||
@ -71,7 +71,7 @@ it('should await form-get on click', async({page, server}) => {
|
||||
expect(messages.join('|')).toBe('route|navigated|click');
|
||||
});
|
||||
|
||||
it('should await form-post on click', async({page, server}) => {
|
||||
it('should await form-post on click', async ({page, server}) => {
|
||||
const messages = [];
|
||||
server.setRoute('/empty.html', async (req, res) => {
|
||||
messages.push('route');
|
||||
@ -92,7 +92,7 @@ it('should await form-post on click', async({page, server}) => {
|
||||
expect(messages.join('|')).toBe('route|navigated|click');
|
||||
});
|
||||
|
||||
it('should await navigation when assigning location', async({page, server}) => {
|
||||
it('should await navigation when assigning location', async ({page, server}) => {
|
||||
const messages = [];
|
||||
server.setRoute('/empty.html', async (req, res) => {
|
||||
messages.push('route');
|
||||
@ -106,7 +106,7 @@ it('should await navigation when assigning location', async({page, server}) => {
|
||||
expect(messages.join('|')).toBe('route|navigated|evaluate');
|
||||
});
|
||||
|
||||
it('should await navigation when assigning location twice', async({page, server}) => {
|
||||
it('should await navigation when assigning location twice', async ({page, server}) => {
|
||||
const messages = [];
|
||||
server.setRoute('/empty.html?cancel', async (req, res) => { res.end('done'); });
|
||||
server.setRoute('/empty.html?override', async (req, res) => { messages.push('routeoverride'); res.end('done'); });
|
||||
@ -118,7 +118,7 @@ it('should await navigation when assigning location twice', async({page, server}
|
||||
expect(messages.join('|')).toBe('routeoverride|evaluate');
|
||||
});
|
||||
|
||||
it('should await navigation when evaluating reload', async({page, server}) => {
|
||||
it('should await navigation when evaluating reload', async ({page, server}) => {
|
||||
const messages = [];
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
server.setRoute('/empty.html', async (req, res) => {
|
||||
@ -134,7 +134,7 @@ it('should await navigation when evaluating reload', async({page, server}) => {
|
||||
expect(messages.join('|')).toBe('route|navigated|evaluate');
|
||||
});
|
||||
|
||||
it('should await navigating specified target', async({page, server}) => {
|
||||
it('should await navigating specified target', async ({page, server}) => {
|
||||
const messages = [];
|
||||
server.setRoute('/empty.html', async (req, res) => {
|
||||
messages.push('route');
|
||||
@ -155,19 +155,19 @@ it('should await navigating specified target', async({page, server}) => {
|
||||
expect(messages.join('|')).toBe('route|navigated|click');
|
||||
});
|
||||
|
||||
it('should work with noWaitAfter: true', async({page, server}) => {
|
||||
it('should work with noWaitAfter: true', async ({page, server}) => {
|
||||
server.setRoute('/empty.html', async () => {});
|
||||
await page.setContent(`<a href="${server.EMPTY_PAGE}">empty.html</a>`);
|
||||
await page.click('a', { noWaitAfter: true });
|
||||
});
|
||||
|
||||
it('should work with dblclick noWaitAfter: true', async({page, server}) => {
|
||||
it('should work with dblclick noWaitAfter: true', async ({page, server}) => {
|
||||
server.setRoute('/empty.html', async () => {});
|
||||
await page.setContent(`<a href="${server.EMPTY_PAGE}">empty.html</a>`);
|
||||
await page.dblclick('a', { noWaitAfter: true });
|
||||
});
|
||||
|
||||
it('should work with waitForLoadState(load)', async({page, server}) => {
|
||||
it('should work with waitForLoadState(load)', async ({page, server}) => {
|
||||
const messages = [];
|
||||
server.setRoute('/empty.html', async (req, res) => {
|
||||
messages.push('route');
|
||||
@ -183,7 +183,7 @@ it('should work with waitForLoadState(load)', async({page, server}) => {
|
||||
expect(messages.join('|')).toBe('route|domcontentloaded|clickload');
|
||||
});
|
||||
|
||||
it('should work with goto following click', async({page, server}) => {
|
||||
it('should work with goto following click', async ({page, server}) => {
|
||||
server.setRoute('/login.html', async (req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.end(`You are logged in`);
|
||||
@ -200,7 +200,7 @@ it('should work with goto following click', async({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
});
|
||||
|
||||
it.skip(options.WIRE)('should report navigation in the log when clicking anchor', async({page, server}) => {
|
||||
it.skip(options.WIRE)('should report navigation in the log when clicking anchor', async ({page, server}) => {
|
||||
await page.setContent(`<a href="${server.PREFIX + '/frames/one-frame.html'}">click me</a>`);
|
||||
const __testHookAfterPointerAction = () => new Promise(f => setTimeout(f, 6000));
|
||||
const error = await page.click('a', { timeout: 5000, __testHookAfterPointerAction } as any).catch(e => e);
|
||||
|
@ -16,33 +16,33 @@
|
||||
*/
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('clicking on links which do not commit navigation', async({page, server, httpsServer}) => {
|
||||
it('clicking on links which do not commit navigation', async ({page, server, httpsServer}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.setContent(`<a href='${httpsServer.EMPTY_PAGE}'>foobar</a>`);
|
||||
await page.click('a');
|
||||
});
|
||||
|
||||
it('calling window.stop async', async({page, server}) => {
|
||||
it('calling window.stop async', async ({page, server}) => {
|
||||
server.setRoute('/empty.html', async (req, res) => {});
|
||||
await page.evaluate((url) => {
|
||||
window.location.href = url;
|
||||
setTimeout(() => window.stop(), 100);
|
||||
}, server.EMPTY_PAGE);
|
||||
await page.evaluate(url => {
|
||||
window.location.href = url;
|
||||
setTimeout(() => window.stop(), 100);
|
||||
}, server.EMPTY_PAGE);
|
||||
});
|
||||
|
||||
it('calling window.stop sync', async({page, server}) => {
|
||||
await page.evaluate((url) => {
|
||||
window.location.href = url;
|
||||
window.stop();
|
||||
}, server.EMPTY_PAGE);
|
||||
it('calling window.stop sync', async ({page, server}) => {
|
||||
await page.evaluate(url => {
|
||||
window.location.href = url;
|
||||
window.stop();
|
||||
}, server.EMPTY_PAGE);
|
||||
});
|
||||
|
||||
it('assigning location to about:blank', async({page, server}) => {
|
||||
it('assigning location to about:blank', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.evaluate(`window.location.href = "about:blank";`);
|
||||
});
|
||||
|
||||
it('assigning location to about:blank after non-about:blank', async({page, server}) => {
|
||||
it('assigning location to about:blank after non-about:blank', async ({page, server}) => {
|
||||
server.setRoute('/empty.html', async (req, res) => {});
|
||||
await page.evaluate(`
|
||||
window.location.href = "${server.EMPTY_PAGE}";
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
it('should work', async({context, page, server}) => {
|
||||
it('should work', async ({context, page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await context.addCookies([{
|
||||
url: server.EMPTY_PAGE,
|
||||
@ -26,7 +26,7 @@ it('should work', async({context, page, server}) => {
|
||||
expect(await page.evaluate(() => document.cookie)).toEqual('password=123456');
|
||||
});
|
||||
|
||||
it('should roundtrip cookie', async({context, page, server}) => {
|
||||
it('should roundtrip cookie', async ({context, page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
// @see https://en.wikipedia.org/wiki/Year_2038_problem
|
||||
const date = +(new Date('1/1/2038'));
|
||||
@ -43,7 +43,7 @@ it('should roundtrip cookie', async({context, page, server}) => {
|
||||
expect(await context.cookies()).toEqual(cookies);
|
||||
});
|
||||
|
||||
it('should send cookie header', async({server, context}) => {
|
||||
it('should send cookie header', async ({server, context}) => {
|
||||
let cookie = '';
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
cookie = req.headers.cookie;
|
||||
@ -55,7 +55,7 @@ it('should send cookie header', async({server, context}) => {
|
||||
expect(cookie).toBe('cookie=value');
|
||||
});
|
||||
|
||||
it('should isolate cookies in browser contexts', async({context, server, browser}) => {
|
||||
it('should isolate cookies in browser contexts', async ({context, server, browser}) => {
|
||||
const anotherContext = await browser.newContext();
|
||||
await context.addCookies([{url: server.EMPTY_PAGE, name: 'isolatecookie', value: 'page1value'}]);
|
||||
await anotherContext.addCookies([{url: server.EMPTY_PAGE, name: 'isolatecookie', value: 'page2value'}]);
|
||||
@ -71,7 +71,7 @@ it('should isolate cookies in browser contexts', async({context, server, browser
|
||||
await anotherContext.close();
|
||||
});
|
||||
|
||||
it('should isolate session cookies', async({context, server, browser}) => {
|
||||
it('should isolate session cookies', async ({context, server, browser}) => {
|
||||
server.setRoute('/setcookie.html', (req, res) => {
|
||||
res.setHeader('Set-Cookie', 'session=value');
|
||||
res.end();
|
||||
@ -97,7 +97,7 @@ it('should isolate session cookies', async({context, server, browser}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should isolate persistent cookies', async({context, server, browser}) => {
|
||||
it('should isolate persistent cookies', async ({context, server, browser}) => {
|
||||
server.setRoute('/setcookie.html', (req, res) => {
|
||||
res.setHeader('Set-Cookie', 'persistent=persistent-value; max-age=3600');
|
||||
res.end();
|
||||
@ -117,7 +117,7 @@ it('should isolate persistent cookies', async({context, server, browser}) => {
|
||||
await context2.close();
|
||||
});
|
||||
|
||||
it('should isolate send cookie header', async({server, context, browser}) => {
|
||||
it('should isolate send cookie header', async ({server, context, browser}) => {
|
||||
let cookie = '';
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
cookie = req.headers.cookie || '';
|
||||
@ -138,7 +138,7 @@ it('should isolate send cookie header', async({server, context, browser}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it.slow()('should isolate cookies between launches', async({browserType, server, defaultBrowserOptions}) => {
|
||||
it.slow()('should isolate cookies between launches', async ({browserType, server, defaultBrowserOptions}) => {
|
||||
const browser1 = await browserType.launch(defaultBrowserOptions);
|
||||
const context1 = await browser1.newContext();
|
||||
await context1.addCookies([{url: server.EMPTY_PAGE, name: 'cookie-in-context-1', value: 'value', expires: Date.now() / 1000 + 10000}]);
|
||||
@ -151,7 +151,7 @@ it.slow()('should isolate cookies between launches', async({browserType, server,
|
||||
await browser2.close();
|
||||
});
|
||||
|
||||
it('should set multiple cookies', async({context, page, server}) => {
|
||||
it('should set multiple cookies', async ({context, page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await context.addCookies([{
|
||||
url: server.EMPTY_PAGE,
|
||||
@ -171,7 +171,7 @@ it('should set multiple cookies', async({context, page, server}) => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should have |expires| set to |-1| for session cookies', async({context, server}) => {
|
||||
it('should have |expires| set to |-1| for session cookies', async ({context, server}) => {
|
||||
await context.addCookies([{
|
||||
url: server.EMPTY_PAGE,
|
||||
name: 'expires',
|
||||
@ -181,7 +181,7 @@ it('should have |expires| set to |-1| for session cookies', async({context, serv
|
||||
expect(cookies[0].expires).toBe(-1);
|
||||
});
|
||||
|
||||
it('should set cookie with reasonable defaults', async({context, server}) => {
|
||||
it('should set cookie with reasonable defaults', async ({context, server}) => {
|
||||
await context.addCookies([{
|
||||
url: server.EMPTY_PAGE,
|
||||
name: 'defaults',
|
||||
@ -200,7 +200,7 @@ it('should set cookie with reasonable defaults', async({context, server}) => {
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should set a cookie with a path', async({context, page, server}) => {
|
||||
it('should set a cookie with a path', async ({context, page, server}) => {
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
await context.addCookies([{
|
||||
domain: 'localhost',
|
||||
@ -229,8 +229,8 @@ it('should not set a cookie with blank page URL', async function({context, serve
|
||||
let error = null;
|
||||
try {
|
||||
await context.addCookies([
|
||||
{url: server.EMPTY_PAGE, name: 'example-cookie', value: 'best'},
|
||||
{url: 'about:blank', name: 'example-cookie-blank', value: 'best'}
|
||||
{url: server.EMPTY_PAGE, name: 'example-cookie', value: 'best'},
|
||||
{url: 'about:blank', name: 'example-cookie-blank', value: 'best'}
|
||||
]);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
@ -250,7 +250,7 @@ it('should not set a cookie on a data URL page', async function({context}) {
|
||||
expect(error.message).toContain('Data URL page can not have cookie "example-cookie"');
|
||||
});
|
||||
|
||||
it('should default to setting secure cookie for HTTPS websites', async({context, page, server}) => {
|
||||
it('should default to setting secure cookie for HTTPS websites', async ({context, page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const SECURE_URL = 'https://example.com';
|
||||
await context.addCookies([{
|
||||
@ -262,7 +262,7 @@ it('should default to setting secure cookie for HTTPS websites', async({context,
|
||||
expect(cookie.secure).toBe(true);
|
||||
});
|
||||
|
||||
it('should be able to set unsecure cookie for HTTP website', async({context, page, server}) => {
|
||||
it('should be able to set unsecure cookie for HTTP website', async ({context, page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const HTTP_URL = 'http://example.com';
|
||||
await context.addCookies([{
|
||||
@ -274,7 +274,7 @@ it('should be able to set unsecure cookie for HTTP website', async({context, pag
|
||||
expect(cookie.secure).toBe(false);
|
||||
});
|
||||
|
||||
it('should set a cookie on a different domain', async({context, page, server}) => {
|
||||
it('should set a cookie on a different domain', async ({context, page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await context.addCookies([{
|
||||
url: 'https://www.example.com',
|
||||
@ -294,7 +294,7 @@ it('should set a cookie on a different domain', async({context, page, server}) =
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should set cookies for a frame', async({context, page, server}) => {
|
||||
it('should set cookies for a frame', async ({context, page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await context.addCookies([
|
||||
{url: server.PREFIX, name: 'frame-cookie', value: 'value'}
|
||||
@ -312,7 +312,7 @@ it('should set cookies for a frame', async({context, page, server}) => {
|
||||
expect(await page.frames()[1].evaluate('document.cookie')).toBe('frame-cookie=value');
|
||||
});
|
||||
|
||||
it('should(not) block third party cookies', async({context, page, server}) => {
|
||||
it('should(not) block third party cookies', async ({context, page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.evaluate(src => {
|
||||
let fulfill;
|
||||
@ -330,14 +330,14 @@ it('should(not) block third party cookies', async({context, page, server}) => {
|
||||
if (allowsThirdParty) {
|
||||
expect(cookies).toEqual([
|
||||
{
|
||||
"domain": "127.0.0.1",
|
||||
"expires": -1,
|
||||
"httpOnly": false,
|
||||
"name": "username",
|
||||
"path": "/",
|
||||
"sameSite": "None",
|
||||
"secure": false,
|
||||
"value": "John Doe"
|
||||
'domain': '127.0.0.1',
|
||||
'expires': -1,
|
||||
'httpOnly': false,
|
||||
'name': 'username',
|
||||
'path': '/',
|
||||
'sameSite': 'None',
|
||||
'secure': false,
|
||||
'value': 'John Doe'
|
||||
}
|
||||
]);
|
||||
} else {
|
||||
|
@ -84,14 +84,14 @@ it('should isolate localStorage and cookies', async function({browser, server})
|
||||
expect(browser.contexts().length).toBe(0);
|
||||
});
|
||||
|
||||
it('should propagate default viewport to the page', async({ browser }) => {
|
||||
it('should propagate default viewport to the page', async ({ browser }) => {
|
||||
const context = await browser.newContext({ viewport: { width: 456, height: 789 } });
|
||||
const page = await context.newPage();
|
||||
await utils.verifyViewport(page, 456, 789);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should make a copy of default viewport', async({ browser }) => {
|
||||
it('should make a copy of default viewport', async ({ browser }) => {
|
||||
const viewport = { width: 456, height: 789 };
|
||||
const context = await browser.newContext({ viewport });
|
||||
viewport.width = 567;
|
||||
@ -100,37 +100,37 @@ it('should make a copy of default viewport', async({ browser }) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should respect deviceScaleFactor', async({ browser }) => {
|
||||
it('should respect deviceScaleFactor', async ({ browser }) => {
|
||||
const context = await browser.newContext({ deviceScaleFactor: 3 });
|
||||
const page = await context.newPage();
|
||||
expect(await page.evaluate('window.devicePixelRatio')).toBe(3);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should not allow deviceScaleFactor with null viewport', async({ browser }) => {
|
||||
it('should not allow deviceScaleFactor with null viewport', async ({ browser }) => {
|
||||
const error = await browser.newContext({ viewport: null, deviceScaleFactor: 1 }).catch(e => e);
|
||||
expect(error.message).toContain('"deviceScaleFactor" option is not supported with null "viewport"');
|
||||
});
|
||||
|
||||
it('should not allow isMobile with null viewport', async({ browser }) => {
|
||||
it('should not allow isMobile with null viewport', async ({ browser }) => {
|
||||
const error = await browser.newContext({ viewport: null, isMobile: true }).catch(e => e);
|
||||
expect(error.message).toContain('"isMobile" option is not supported with null "viewport"');
|
||||
});
|
||||
|
||||
it('close() should work for empty context', async({ browser }) => {
|
||||
it('close() should work for empty context', async ({ browser }) => {
|
||||
const context = await browser.newContext();
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('close() should abort waitForEvent', async({ browser }) => {
|
||||
it('close() should abort waitForEvent', async ({ browser }) => {
|
||||
const context = await browser.newContext();
|
||||
const promise = context.waitForEvent('page').catch(e => e);
|
||||
await context.close();
|
||||
let error = await promise;
|
||||
const error = await promise;
|
||||
expect(error.message).toContain('Context closed');
|
||||
});
|
||||
|
||||
it('close() should be callable twice', async({browser}) => {
|
||||
it('close() should be callable twice', async ({browser}) => {
|
||||
const context = await browser.newContext();
|
||||
await Promise.all([
|
||||
context.close(),
|
||||
@ -139,7 +139,7 @@ it('close() should be callable twice', async({browser}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should not report frameless pages on error', async({browser, server}) => {
|
||||
it('should not report frameless pages on error', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
@ -157,7 +157,7 @@ it('should not report frameless pages on error', async({browser, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should return all of the pages', async({browser, server}) => {
|
||||
it('should return all of the pages', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const second = await context.newPage();
|
||||
@ -177,7 +177,7 @@ it('should close all belonging pages once closing context', async function({brow
|
||||
expect(context.pages().length).toBe(0);
|
||||
});
|
||||
|
||||
it('should disable javascript', async({browser}) => {
|
||||
it('should disable javascript', async ({browser}) => {
|
||||
{
|
||||
const context = await browser.newContext({ javaScriptEnabled: false });
|
||||
const page = await context.newPage();
|
||||
@ -200,14 +200,14 @@ it('should disable javascript', async({browser}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should be able to navigate after disabling javascript', async({browser, server}) => {
|
||||
it('should be able to navigate after disabling javascript', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ javaScriptEnabled: false });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work with offline option', async({browser, server}) => {
|
||||
it('should work with offline option', async ({browser, server}) => {
|
||||
const context = await browser.newContext({offline: true});
|
||||
const page = await context.newPage();
|
||||
let error = null;
|
||||
@ -219,7 +219,7 @@ it('should work with offline option', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should emulate navigator.onLine', async({browser, server}) => {
|
||||
it('should emulate navigator.onLine', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
expect(await page.evaluate(() => window.navigator.onLine)).toBe(true);
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should clear cookies', async({context, page, server}) => {
|
||||
it('should clear cookies', async ({context, page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await context.addCookies([{
|
||||
url: server.EMPTY_PAGE,
|
||||
@ -31,7 +31,7 @@ it('should clear cookies', async({context, page, server}) => {
|
||||
expect(await page.evaluate('document.cookie')).toBe('');
|
||||
});
|
||||
|
||||
it('should isolate cookies when clearing', async({context, server, browser}) => {
|
||||
it('should isolate cookies when clearing', async ({context, server, browser}) => {
|
||||
const anotherContext = await browser.newContext();
|
||||
await context.addCookies([{url: server.EMPTY_PAGE, name: 'page1cookie', value: 'page1value'}]);
|
||||
await anotherContext.addCookies([{url: server.EMPTY_PAGE, name: 'page2cookie', value: 'page2value'}]);
|
||||
|
@ -16,11 +16,11 @@
|
||||
*/
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
it('should return no cookies in pristine browser context', async({context, page, server}) => {
|
||||
it('should return no cookies in pristine browser context', async ({context, page, server}) => {
|
||||
expect(await context.cookies()).toEqual([]);
|
||||
});
|
||||
|
||||
it('should get a cookie', async({context, page, server}) => {
|
||||
it('should get a cookie', async ({context, page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const documentCookie = await page.evaluate(() => {
|
||||
document.cookie = 'username=John Doe';
|
||||
@ -39,7 +39,7 @@ it('should get a cookie', async({context, page, server}) => {
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should get a non-session cookie', async({context, page, server}) => {
|
||||
it('should get a non-session cookie', async ({context, page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
// @see https://en.wikipedia.org/wiki/Year_2038_problem
|
||||
const date = +(new Date('1/1/2038'));
|
||||
@ -61,7 +61,7 @@ it('should get a non-session cookie', async({context, page, server}) => {
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should properly report httpOnly cookie', async({context, page, server}) => {
|
||||
it('should properly report httpOnly cookie', async ({context, page, server}) => {
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
res.setHeader('Set-Cookie', 'name=value;HttpOnly; Path=/');
|
||||
res.end();
|
||||
@ -72,7 +72,7 @@ it('should properly report httpOnly cookie', async({context, page, server}) => {
|
||||
expect(cookies[0].httpOnly).toBe(true);
|
||||
});
|
||||
|
||||
it.fail(options.WEBKIT && WIN)('should properly report "Strict" sameSite cookie', async({context, page, server}) => {
|
||||
it.fail(options.WEBKIT && WIN)('should properly report "Strict" sameSite cookie', async ({context, page, server}) => {
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
res.setHeader('Set-Cookie', 'name=value;SameSite=Strict');
|
||||
res.end();
|
||||
@ -83,7 +83,7 @@ it.fail(options.WEBKIT && WIN)('should properly report "Strict" sameSite cookie'
|
||||
expect(cookies[0].sameSite).toBe('Strict');
|
||||
});
|
||||
|
||||
it.fail(options.WEBKIT && WIN)('should properly report "Lax" sameSite cookie', async({context, page, server}) => {
|
||||
it.fail(options.WEBKIT && WIN)('should properly report "Lax" sameSite cookie', async ({context, page, server}) => {
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
res.setHeader('Set-Cookie', 'name=value;SameSite=Lax');
|
||||
res.end();
|
||||
@ -94,7 +94,7 @@ it.fail(options.WEBKIT && WIN)('should properly report "Lax" sameSite cookie', a
|
||||
expect(cookies[0].sameSite).toBe('Lax');
|
||||
});
|
||||
|
||||
it('should get multiple cookies', async({context, page, server}) => {
|
||||
it('should get multiple cookies', async ({context, page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const documentCookie = await page.evaluate(() => {
|
||||
document.cookie = 'username=John Doe';
|
||||
@ -128,7 +128,7 @@ it('should get multiple cookies', async({context, page, server}) => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should get cookies from multiple urls', async({context}) => {
|
||||
it('should get cookies from multiple urls', async ({context}) => {
|
||||
await context.addCookies([{
|
||||
url: 'https://foo.com',
|
||||
name: 'doggo',
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
it.fail(options.CHROMIUM && !options.HEADLESS)('should fail without credentials', async({browser, server}) => {
|
||||
it.fail(options.CHROMIUM && !options.HEADLESS)('should fail without credentials', async ({browser, server}) => {
|
||||
server.setAuth('/empty.html', 'user', 'pass');
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
@ -25,7 +25,7 @@ it.fail(options.CHROMIUM && !options.HEADLESS)('should fail without credentials'
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.fail(options.CHROMIUM && !options.HEADLESS)('should work with setHTTPCredentials', async({browser, server}) => {
|
||||
it.fail(options.CHROMIUM && !options.HEADLESS)('should work with setHTTPCredentials', async ({browser, server}) => {
|
||||
server.setAuth('/empty.html', 'user', 'pass');
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
@ -37,7 +37,7 @@ it.fail(options.CHROMIUM && !options.HEADLESS)('should work with setHTTPCredenti
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work with correct credentials', async({browser, server}) => {
|
||||
it('should work with correct credentials', async ({browser, server}) => {
|
||||
server.setAuth('/empty.html', 'user', 'pass');
|
||||
const context = await browser.newContext({
|
||||
httpCredentials: { username: 'user', password: 'pass' }
|
||||
@ -48,7 +48,7 @@ it('should work with correct credentials', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should fail with wrong credentials', async({browser, server}) => {
|
||||
it('should fail with wrong credentials', async ({browser, server}) => {
|
||||
server.setAuth('/empty.html', 'user', 'pass');
|
||||
const context = await browser.newContext({
|
||||
httpCredentials: { username: 'foo', password: 'bar' }
|
||||
@ -59,7 +59,7 @@ it('should fail with wrong credentials', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should return resource body', async({browser, server}) => {
|
||||
it('should return resource body', async ({browser, server}) => {
|
||||
server.setAuth('/playground.html', 'user', 'pass');
|
||||
const context = await browser.newContext({
|
||||
httpCredentials: { username: 'user', password: 'pass' }
|
||||
@ -67,7 +67,7 @@ it('should return resource body', async({browser, server}) => {
|
||||
const page = await context.newPage();
|
||||
const response = await page.goto(server.PREFIX + '/playground.html');
|
||||
expect(response.status()).toBe(200);
|
||||
expect(await page.title()).toBe("Playground");
|
||||
expect((await response.body()).toString()).toContain("Playground");
|
||||
expect(await page.title()).toBe('Playground');
|
||||
expect((await response.body()).toString()).toContain('Playground');
|
||||
await context.close();
|
||||
});
|
||||
|
@ -18,7 +18,7 @@ import './playwright.fixtures';
|
||||
|
||||
import * as utils from './utils';
|
||||
|
||||
it('should bypass CSP meta tag', async({browser, server}) => {
|
||||
it('should bypass CSP meta tag', async ({browser, server}) => {
|
||||
// Make sure CSP prohibits addScriptTag.
|
||||
{
|
||||
const context = await browser.newContext();
|
||||
@ -40,7 +40,7 @@ it('should bypass CSP meta tag', async({browser, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should bypass CSP header', async({browser, server}) => {
|
||||
it('should bypass CSP header', async ({browser, server}) => {
|
||||
// Make sure CSP prohibits addScriptTag.
|
||||
server.setCSP('/empty.html', 'default-src "self"');
|
||||
|
||||
@ -64,7 +64,7 @@ it('should bypass CSP header', async({browser, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should bypass after cross-process navigation', async({browser, server}) => {
|
||||
it('should bypass after cross-process navigation', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ bypassCSP: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/csp.html');
|
||||
@ -77,7 +77,7 @@ it('should bypass after cross-process navigation', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should bypass CSP in iframes as well', async({browser, server}) => {
|
||||
it('should bypass CSP in iframes as well', async ({browser, server}) => {
|
||||
// Make sure CSP prohibits addScriptTag in an iframe.
|
||||
{
|
||||
const context = await browser.newContext();
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
it.skip(options.FIREFOX)('should work', async({playwright, browser, server}) => {
|
||||
it.skip(options.FIREFOX)('should work', async ({playwright, browser, server}) => {
|
||||
const iPhone = playwright.devices['iPhone 6'];
|
||||
const context = await browser.newContext({ ...iPhone });
|
||||
const page = await context.newPage();
|
||||
@ -26,7 +26,7 @@ it.skip(options.FIREFOX)('should work', async({playwright, browser, server}) =>
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('should support clicking', async({playwright, browser, server}) => {
|
||||
it.skip(options.FIREFOX)('should support clicking', async ({playwright, browser, server}) => {
|
||||
const iPhone = playwright.devices['iPhone 6'];
|
||||
const context = await browser.newContext({ ...iPhone });
|
||||
const page = await context.newPage();
|
||||
@ -38,7 +38,7 @@ it.skip(options.FIREFOX)('should support clicking', async({playwright, browser,
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('should scroll to click', async({browser, server}) => {
|
||||
it.skip(options.FIREFOX)('should scroll to click', async ({browser, server}) => {
|
||||
const context = await browser.newContext({
|
||||
viewport: {
|
||||
width: 400,
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('expose binding should work', async({browser}) => {
|
||||
it('expose binding should work', async ({browser}) => {
|
||||
const context = await browser.newContext();
|
||||
let bindingSource;
|
||||
await context.exposeBinding('add', (source, a, b) => {
|
||||
@ -32,7 +32,7 @@ it('expose binding should work', async({browser}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work', async({browser, server}) => {
|
||||
it('should work', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
await context.exposeFunction('add', (a, b) => a + b);
|
||||
const page = await context.newPage();
|
||||
@ -47,7 +47,7 @@ it('should work', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should throw for duplicate registrations', async({browser, server}) => {
|
||||
it('should throw for duplicate registrations', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
await context.exposeFunction('foo', () => {});
|
||||
await context.exposeFunction('bar', () => {});
|
||||
@ -62,7 +62,7 @@ it('should throw for duplicate registrations', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should be callable from-inside addInitScript', async({browser, server}) => {
|
||||
it('should be callable from-inside addInitScript', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
let args = [];
|
||||
await context.exposeFunction('woof', function(arg) {
|
||||
|
@ -14,9 +14,9 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { options } from './playwright.fixtures';
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should affect accept-language header', async({browser, server}) => {
|
||||
it('should affect accept-language header', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ locale: 'fr-CH' });
|
||||
const page = await context.newPage();
|
||||
const [request] = await Promise.all([
|
||||
@ -27,14 +27,14 @@ it('should affect accept-language header', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should affect navigator.language', async({browser, server}) => {
|
||||
it('should affect navigator.language', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ locale: 'fr-CH' });
|
||||
const page = await context.newPage();
|
||||
expect(await page.evaluate(() => navigator.language)).toBe('fr-CH');
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should format number', async({browser, server}) => {
|
||||
it('should format number', async ({browser, server}) => {
|
||||
{
|
||||
const context = await browser.newContext({ locale: 'en-US' });
|
||||
const page = await context.newPage();
|
||||
@ -51,7 +51,7 @@ it('should format number', async({browser, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should format date', async({browser, server}) => {
|
||||
it('should format date', async ({browser, server}) => {
|
||||
{
|
||||
const context = await browser.newContext({ locale: 'en-US', timezoneId: 'America/Los_Angeles' });
|
||||
const page = await context.newPage();
|
||||
@ -70,7 +70,7 @@ it('should format date', async({browser, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should format number in popups', async({browser, server}) => {
|
||||
it('should format number in popups', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ locale: 'fr-CH' });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -85,7 +85,7 @@ it('should format number in popups', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should affect navigator.language in popups', async({browser, server}) => {
|
||||
it('should affect navigator.language in popups', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ locale: 'fr-CH' });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -99,7 +99,7 @@ it('should affect navigator.language in popups', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work for multiple pages sharing same process', async({browser, server}) => {
|
||||
it('should work for multiple pages sharing same process', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ locale: 'ru-RU' });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -114,11 +114,11 @@ it('should work for multiple pages sharing same process', async({browser, server
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should be isolated between contexts', async({browser, server}) => {
|
||||
it('should be isolated between contexts', async ({browser, server}) => {
|
||||
const context1 = await browser.newContext({ locale: 'en-US' });
|
||||
const promises = [];
|
||||
// By default firefox limits number of child web processes to 8.
|
||||
for (let i = 0; i< 8; i++)
|
||||
for (let i = 0; i < 8; i++)
|
||||
promises.push(context1.newPage());
|
||||
await Promise.all(promises);
|
||||
|
||||
@ -137,7 +137,7 @@ it('should be isolated between contexts', async({browser, server}) => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not change default locale in another context', async({browser, server}) => {
|
||||
it('should not change default locale in another context', async ({browser, server}) => {
|
||||
async function getContextLocale(context) {
|
||||
const page = await context.newPage();
|
||||
return await page.evaluate(() => (new Intl.NumberFormat()).resolvedOptions().locale);
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
it('should have url', async({browser, server}) => {
|
||||
it('should have url', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const [otherPage] = await Promise.all([
|
||||
@ -27,7 +27,7 @@ it('should have url', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should have url after domcontentloaded', async({browser, server}) => {
|
||||
it('should have url after domcontentloaded', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const [otherPage] = await Promise.all([
|
||||
@ -39,7 +39,7 @@ it('should have url after domcontentloaded', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should have about:blank url with domcontentloaded', async({browser, server}) => {
|
||||
it('should have about:blank url with domcontentloaded', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const [otherPage] = await Promise.all([
|
||||
@ -51,7 +51,7 @@ it('should have about:blank url with domcontentloaded', async({browser, server})
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should have about:blank for empty url with domcontentloaded', async({browser, server}) => {
|
||||
it('should have about:blank for empty url with domcontentloaded', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const [otherPage] = await Promise.all([
|
||||
@ -63,7 +63,7 @@ it('should have about:blank for empty url with domcontentloaded', async({browser
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should report when a new page is created and closed', async({browser, server}) => {
|
||||
it('should report when a new page is created and closed', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const [otherPage] = await Promise.all([
|
||||
@ -90,7 +90,7 @@ it('should report when a new page is created and closed', async({browser, server
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should report initialized pages', async({browser, server}) => {
|
||||
it('should report initialized pages', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const pagePromise = context.waitForEvent('page');
|
||||
context.newPage();
|
||||
@ -105,7 +105,7 @@ it('should report initialized pages', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should not crash while redirecting of original request was missed', async({browser, server}) => {
|
||||
it('should not crash while redirecting of original request was missed', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
let serverResponse = null;
|
||||
@ -125,7 +125,7 @@ it('should not crash while redirecting of original request was missed', async({b
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should have an opener', async({browser, server}) => {
|
||||
it('should have an opener', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -156,7 +156,7 @@ it('should fire page lifecycle events', async function({browser, server}) {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.fixme(options.WEBKIT)('should work with Shift-clicking', async({browser, server}) => {
|
||||
it.fixme(options.WEBKIT)('should work with Shift-clicking', async ({browser, server}) => {
|
||||
// WebKit: Shift+Click does not open a new window.
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
@ -170,7 +170,7 @@ it.fixme(options.WEBKIT)('should work with Shift-clicking', async({browser, serv
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.fixme(options.WEBKIT || options.FIREFOX)('should work with Ctrl-clicking', async({browser, server}) => {
|
||||
it.fixme(options.WEBKIT || options.FIREFOX)('should work with Ctrl-clicking', async ({browser, server}) => {
|
||||
// Firefox: reports an opener in this case.
|
||||
// WebKit: Ctrl+Click does not open a new tab.
|
||||
const context = await browser.newContext();
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should intercept', async({browser, server}) => {
|
||||
it('should intercept', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
let intercepted = false;
|
||||
await context.route('**/empty.html', route => {
|
||||
@ -39,7 +39,7 @@ it('should intercept', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should unroute', async({browser, server}) => {
|
||||
it('should unroute', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
|
||||
@ -77,7 +77,7 @@ it('should unroute', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should yield to page.route', async({browser, server}) => {
|
||||
it('should yield to page.route', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
await context.route('**/empty.html', route => {
|
||||
route.fulfill({ status: 200, body: 'context' });
|
||||
@ -92,7 +92,7 @@ it('should yield to page.route', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should fall back to context.route', async({browser, server}) => {
|
||||
it('should fall back to context.route', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
await context.route('**/empty.html', route => {
|
||||
route.fulfill({ status: 200, body: 'context' });
|
||||
|
@ -14,7 +14,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { options } from './playwright.fixtures';
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should work', async ({ browser }) => {
|
||||
const func = () => new Date(1479579154987).toString();
|
||||
@ -44,17 +44,17 @@ it('should work', async ({ browser }) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw for invalid timezone IDs when creating pages', async({browser}) => {
|
||||
it('should throw for invalid timezone IDs when creating pages', async ({browser}) => {
|
||||
for (const timezoneId of ['Foo/Bar', 'Baz/Qux']) {
|
||||
let error = null;
|
||||
const context = await browser.newContext({ timezoneId });
|
||||
const page = await context.newPage().catch(e => error = e);
|
||||
await context.newPage().catch(e => error = e);
|
||||
expect(error.message).toContain(`Invalid timezone ID: ${timezoneId}`);
|
||||
await context.close();
|
||||
}
|
||||
});
|
||||
|
||||
it('should work for multiple pages sharing same process', async({browser, server}) => {
|
||||
it('should work for multiple pages sharing same process', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ timezoneId: 'Europe/Moscow' });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -69,7 +69,7 @@ it('should work for multiple pages sharing same process', async({browser, server
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should not change default timezone in another context', async({browser, server}) => {
|
||||
it('should not change default timezone in another context', async ({browser, server}) => {
|
||||
async function getContextTimezone(context) {
|
||||
const page = await context.newPage();
|
||||
return await page.evaluate(() => Intl.DateTimeFormat().resolvedOptions().timeZone);
|
||||
|
@ -18,7 +18,7 @@ import './playwright.fixtures';
|
||||
|
||||
import utils from './utils';
|
||||
|
||||
it('should work', async({browser, server}) => {
|
||||
it('should work', async ({browser, server}) => {
|
||||
{
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
@ -37,7 +37,7 @@ it('should work', async({browser, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should work for subframes', async({browser, server}) => {
|
||||
it('should work for subframes', async ({browser, server}) => {
|
||||
{
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
@ -56,7 +56,7 @@ it('should work for subframes', async({browser, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should emulate device user-agent', async({browser, server, playwright}) => {
|
||||
it('should emulate device user-agent', async ({browser, server, playwright}) => {
|
||||
{
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
@ -73,7 +73,7 @@ it('should emulate device user-agent', async({browser, server, playwright}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should make a copy of default options', async({browser, server}) => {
|
||||
it('should make a copy of default options', async ({browser, server}) => {
|
||||
const options = { userAgent: 'foobar' };
|
||||
const context = await browser.newContext(options);
|
||||
options.userAgent = 'wrong';
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
it.skip(options.FIREFOX)('should support mobile emulation', async({playwright, browser, server}) => {
|
||||
it.skip(options.FIREFOX)('should support mobile emulation', async ({playwright, browser, server}) => {
|
||||
const iPhone = playwright.devices['iPhone 6'];
|
||||
const context = await browser.newContext({ ...iPhone });
|
||||
const page = await context.newPage();
|
||||
@ -28,7 +28,7 @@ it.skip(options.FIREFOX)('should support mobile emulation', async({playwright, b
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('should support touch emulation', async({playwright, browser, server}) => {
|
||||
it.skip(options.FIREFOX)('should support touch emulation', async ({playwright, browser, server}) => {
|
||||
const iPhone = playwright.devices['iPhone 6'];
|
||||
const context = await browser.newContext({ ...iPhone });
|
||||
const page = await context.newPage();
|
||||
@ -51,7 +51,7 @@ it.skip(options.FIREFOX)('should support touch emulation', async({playwright, br
|
||||
}
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('should be detectable by Modernizr', async({playwright, browser, server}) => {
|
||||
it.skip(options.FIREFOX)('should be detectable by Modernizr', async ({playwright, browser, server}) => {
|
||||
const iPhone = playwright.devices['iPhone 6'];
|
||||
const context = await browser.newContext({ ...iPhone });
|
||||
const page = await context.newPage();
|
||||
@ -60,7 +60,7 @@ it.skip(options.FIREFOX)('should be detectable by Modernizr', async({playwright,
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('should detect touch when applying viewport with touches', async({browser, server}) => {
|
||||
it.skip(options.FIREFOX)('should detect touch when applying viewport with touches', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ viewport: { width: 800, height: 600 }, hasTouch: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -69,7 +69,7 @@ it.skip(options.FIREFOX)('should detect touch when applying viewport with touche
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('should support landscape emulation', async({playwright, browser, server}) => {
|
||||
it.skip(options.FIREFOX)('should support landscape emulation', async ({playwright, browser, server}) => {
|
||||
const iPhone = playwright.devices['iPhone 6'];
|
||||
const iPhoneLandscape = playwright.devices['iPhone 6 landscape'];
|
||||
const context1 = await browser.newContext({ ...iPhone });
|
||||
@ -83,7 +83,7 @@ it.skip(options.FIREFOX)('should support landscape emulation', async({playwright
|
||||
await context2.close();
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('should support window.orientation emulation', async({browser, server}) => {
|
||||
it.skip(options.FIREFOX)('should support window.orientation emulation', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ viewport: { width: 300, height: 400 }, isMobile: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/mobile.html');
|
||||
@ -93,7 +93,7 @@ it.skip(options.FIREFOX)('should support window.orientation emulation', async({b
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('should fire orientationchange event', async({browser, server}) => {
|
||||
it.skip(options.FIREFOX)('should fire orientationchange event', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ viewport: { width: 300, height: 400 }, isMobile: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/mobile.html');
|
||||
@ -112,7 +112,7 @@ it.skip(options.FIREFOX)('should fire orientationchange event', async({browser,
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('default mobile viewports to 980 width', async({browser, server}) => {
|
||||
it.skip(options.FIREFOX)('default mobile viewports to 980 width', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ viewport: {width: 320, height: 480 }, isMobile: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/empty.html');
|
||||
@ -120,7 +120,7 @@ it.skip(options.FIREFOX)('default mobile viewports to 980 width', async({browser
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('respect meta viewport tag', async({browser, server}) => {
|
||||
it.skip(options.FIREFOX)('respect meta viewport tag', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ viewport: {width: 320, height: 480 }, isMobile: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/mobile.html');
|
||||
|
@ -18,17 +18,17 @@ import './playwright.fixtures';
|
||||
|
||||
import utils from './utils';
|
||||
|
||||
it('should get the proper default viewport size', async({page, server}) => {
|
||||
it('should get the proper default viewport size', async ({page, server}) => {
|
||||
await utils.verifyViewport(page, 1280, 720);
|
||||
});
|
||||
|
||||
it('should set the proper viewport size', async({page, server}) => {
|
||||
it('should set the proper viewport size', async ({page, server}) => {
|
||||
await utils.verifyViewport(page, 1280, 720);
|
||||
await page.setViewportSize({width: 123, height: 456});
|
||||
await utils.verifyViewport(page, 123, 456);
|
||||
});
|
||||
|
||||
it('should return correct outerWidth and outerHeight', async({page}) => {
|
||||
it('should return correct outerWidth and outerHeight', async ({page}) => {
|
||||
const size = await page.evaluate(() => {
|
||||
return {
|
||||
innerWidth: window.innerWidth,
|
||||
@ -43,7 +43,7 @@ it('should return correct outerWidth and outerHeight', async({page}) => {
|
||||
expect(size.outerHeight >= size.innerHeight).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should emulate device width', async({page, server}) => {
|
||||
it('should emulate device width', async ({page, server}) => {
|
||||
expect(page.viewportSize()).toEqual({width: 1280, height: 720});
|
||||
await page.setViewportSize({width: 200, height: 200});
|
||||
expect(await page.evaluate(() => window.screen.width)).toBe(200);
|
||||
@ -63,7 +63,7 @@ it('should emulate device width', async({page, server}) => {
|
||||
expect(await page.evaluate(() => matchMedia('(device-width: 500px)').matches)).toBe(true);
|
||||
});
|
||||
|
||||
it('should emulate device height', async({page, server}) => {
|
||||
it('should emulate device height', async ({page, server}) => {
|
||||
expect(page.viewportSize()).toEqual({width: 1280, height: 720});
|
||||
await page.setViewportSize({width: 200, height: 200});
|
||||
expect(await page.evaluate(() => window.screen.height)).toBe(200);
|
||||
@ -83,14 +83,14 @@ it('should emulate device height', async({page, server}) => {
|
||||
expect(await page.evaluate(() => matchMedia('(device-height: 500px)').matches)).toBe(true);
|
||||
});
|
||||
|
||||
it('should not have touch by default', async({page, server}) => {
|
||||
it('should not have touch by default', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/mobile.html');
|
||||
expect(await page.evaluate(() => 'ontouchstart' in window)).toBe(false);
|
||||
await page.goto(server.PREFIX + '/detect-touch.html');
|
||||
expect(await page.evaluate(() => document.body.textContent.trim())).toBe('NO');
|
||||
});
|
||||
|
||||
it('should support touch with null viewport', async({browser, server}) => {
|
||||
it('should support touch with null viewport', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ viewport: null, hasTouch: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/mobile.html');
|
||||
@ -98,7 +98,7 @@ it('should support touch with null viewport', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should report null viewportSize when given null viewport', async({browser, server}) => {
|
||||
it('should report null viewportSize when given null viewport', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ viewport: null });
|
||||
const page = await context.newPage();
|
||||
expect(page.viewportSize()).toBe(null);
|
||||
|
@ -18,13 +18,13 @@
|
||||
import fs from 'fs';
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
it.skip(Boolean(process.env.CRPATH || process.env.FFPATH || process.env.WKPATH))('browserType.executablePath should work', async({browserType}) => {
|
||||
it.skip(Boolean(process.env.CRPATH || process.env.FFPATH || process.env.WKPATH))('browserType.executablePath should work', async ({browserType}) => {
|
||||
const executablePath = browserType.executablePath();
|
||||
expect(fs.existsSync(executablePath)).toBe(true);
|
||||
expect(fs.realpathSync(executablePath)).toBe(executablePath);
|
||||
});
|
||||
|
||||
it('browserType.name should work', async({browserType}) => {
|
||||
it('browserType.name should work', async ({browserType}) => {
|
||||
if (options.WEBKIT)
|
||||
expect(browserType.name()).toBe('webkit');
|
||||
else if (options.FIREFOX)
|
||||
|
@ -19,7 +19,7 @@ import { options } from './playwright.fixtures';
|
||||
import utils from './utils';
|
||||
import './remoteServer.fixture';
|
||||
|
||||
it.skip(options.WIRE).slow()('should be able to reconnect to a browser', async({browserType, remoteServer, server}) => {
|
||||
it.skip(options.WIRE).slow()('should be able to reconnect to a browser', async ({browserType, remoteServer, server}) => {
|
||||
{
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const browserContext = await browser.newContext();
|
||||
@ -81,8 +81,8 @@ it.skip(options.WIRE).slow()('disconnected event should be emitted when browser
|
||||
expect(disconnected2).toBe(1);
|
||||
});
|
||||
|
||||
it.skip(options.WIRE).slow()('should handle exceptions during connect', async({browserType, remoteServer}) => {
|
||||
const __testHookBeforeCreateBrowser = () => { throw new Error('Dummy') };
|
||||
it.skip(options.WIRE).slow()('should handle exceptions during connect', async ({browserType, remoteServer}) => {
|
||||
const __testHookBeforeCreateBrowser = () => { throw new Error('Dummy'); };
|
||||
const error = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint(), __testHookBeforeCreateBrowser } as any).catch(e => e);
|
||||
expect(error.message).toContain('Dummy');
|
||||
});
|
||||
@ -94,7 +94,7 @@ it.skip(options.WIRE).slow()('should set the browser connected state', async ({b
|
||||
expect(remote.isConnected()).toBe(false);
|
||||
});
|
||||
|
||||
it.skip(options.WIRE).slow()('should throw when used after isConnected returns false', async({browserType, remoteServer}) => {
|
||||
it.skip(options.WIRE).slow()('should throw when used after isConnected returns false', async ({browserType, remoteServer}) => {
|
||||
const remote = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const page = await remote.newPage();
|
||||
await Promise.all([
|
||||
@ -106,7 +106,7 @@ it.skip(options.WIRE).slow()('should throw when used after isConnected returns f
|
||||
expect(error.message).toContain('has been closed');
|
||||
});
|
||||
|
||||
it.skip(options.WIRE).slow()('should reject navigation when browser closes', async({browserType, remoteServer, server}) => {
|
||||
it.skip(options.WIRE).slow()('should reject navigation when browser closes', async ({browserType, remoteServer, server}) => {
|
||||
server.setRoute('/one-style.css', () => {});
|
||||
const remote = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const page = await remote.newPage();
|
||||
@ -117,7 +117,7 @@ it.skip(options.WIRE).slow()('should reject navigation when browser closes', asy
|
||||
expect(error.message).toContain('Navigation failed because page was closed!');
|
||||
});
|
||||
|
||||
it.skip(options.WIRE).slow()('should reject waitForSelector when browser closes', async({browserType, remoteServer, server}) => {
|
||||
it.skip(options.WIRE).slow()('should reject waitForSelector when browser closes', async ({browserType, remoteServer, server}) => {
|
||||
server.setRoute('/empty.html', () => {});
|
||||
const remote = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const page = await remote.newPage();
|
||||
@ -131,7 +131,7 @@ it.skip(options.WIRE).slow()('should reject waitForSelector when browser closes'
|
||||
expect(error.message).toContain('Protocol error');
|
||||
});
|
||||
|
||||
it.skip(options.WIRE).slow()('should emit close events on pages and contexts', async({browserType, remoteServer}) => {
|
||||
it.skip(options.WIRE).slow()('should emit close events on pages and contexts', async ({browserType, remoteServer}) => {
|
||||
const remote = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const context = await remote.newContext();
|
||||
const page = await context.newPage();
|
||||
@ -144,7 +144,7 @@ it.skip(options.WIRE).slow()('should emit close events on pages and contexts', a
|
||||
expect(pageClosed).toBeTruthy();
|
||||
});
|
||||
|
||||
it.skip(options.WIRE).slow()('should terminate network waiters', async({browserType, remoteServer, server}) => {
|
||||
it.skip(options.WIRE).slow()('should terminate network waiters', async ({browserType, remoteServer, server}) => {
|
||||
const remote = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const newPage = await remote.newPage();
|
||||
const results = await Promise.all([
|
||||
@ -159,7 +159,7 @@ it.skip(options.WIRE).slow()('should terminate network waiters', async({browserT
|
||||
}
|
||||
});
|
||||
|
||||
it.skip(options.WIRE).fail(true).slow()('should respect selectors', async({ playwright, browserType, remoteServer }) => {
|
||||
it.skip(options.WIRE).fail(true).slow()('should respect selectors', async ({ playwright, browserType, remoteServer }) => {
|
||||
const mycss = () => ({
|
||||
create(root, target) {},
|
||||
query(root, selector) {
|
||||
|
@ -17,13 +17,13 @@
|
||||
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
it.skip(options.WIRE)('should work', async({browserType, defaultBrowserOptions}) => {
|
||||
it.skip(options.WIRE)('should work', async ({browserType, defaultBrowserOptions}) => {
|
||||
const browserServer = await browserType.launchServer(defaultBrowserOptions);
|
||||
expect(browserServer.wsEndpoint()).not.toBe(null);
|
||||
await browserServer.close();
|
||||
});
|
||||
|
||||
it.skip(options.WIRE)('should fire "close" event during kill', async({browserType, defaultBrowserOptions}) => {
|
||||
it.skip(options.WIRE)('should fire "close" event during kill', async ({browserType, defaultBrowserOptions}) => {
|
||||
const order = [];
|
||||
const browserServer = await browserType.launchServer(defaultBrowserOptions);
|
||||
const closedPromise = new Promise(f => browserServer.on('close', () => {
|
||||
|
@ -18,7 +18,7 @@
|
||||
import path from 'path';
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
it('should reject all promises when browser is closed', async({browserType, defaultBrowserOptions}) => {
|
||||
it('should reject all promises when browser is closed', async ({browserType, defaultBrowserOptions}) => {
|
||||
const browser = await browserType.launch(defaultBrowserOptions);
|
||||
const page = await (await browser.newContext()).newPage();
|
||||
let error = null;
|
||||
@ -29,21 +29,21 @@ it('should reject all promises when browser is closed', async({browserType, defa
|
||||
expect(error.message).toContain('Protocol error');
|
||||
});
|
||||
|
||||
it('should throw if userDataDir option is passed', async({browserType, defaultBrowserOptions}) => {
|
||||
it('should throw if userDataDir option is passed', async ({browserType, defaultBrowserOptions}) => {
|
||||
let waitError = null;
|
||||
const options = Object.assign({}, defaultBrowserOptions, {userDataDir: 'random-path'});
|
||||
await browserType.launch(options).catch(e => waitError = e);
|
||||
expect(waitError.message).toContain('launchPersistentContext');
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('should throw if page argument is passed', async({browserType, defaultBrowserOptions}) => {
|
||||
it.skip(options.FIREFOX)('should throw if page argument is passed', async ({browserType, defaultBrowserOptions}) => {
|
||||
let waitError = null;
|
||||
const options = Object.assign({}, defaultBrowserOptions, { args: ['http://example.com'] });
|
||||
await browserType.launch(options).catch(e => waitError = e);
|
||||
expect(waitError.message).toContain('can not specify page');
|
||||
});
|
||||
|
||||
it.fixme(true)('should reject if launched browser fails immediately', async({browserType, defaultBrowserOptions}) => {
|
||||
it.fixme(true)('should reject if launched browser fails immediately', async ({browserType, defaultBrowserOptions}) => {
|
||||
// I'm getting ENCONRESET on this one.
|
||||
const options = Object.assign({}, defaultBrowserOptions, {executablePath: path.join(__dirname, 'assets', 'dummy_bad_browser_executable.js')});
|
||||
let waitError = null;
|
||||
@ -51,14 +51,14 @@ it.fixme(true)('should reject if launched browser fails immediately', async({bro
|
||||
expect(waitError.message).toContain('== logs ==');
|
||||
});
|
||||
|
||||
it('should reject if executable path is invalid', async({browserType, defaultBrowserOptions}) => {
|
||||
it('should reject if executable path is invalid', async ({browserType, defaultBrowserOptions}) => {
|
||||
let waitError = null;
|
||||
const options = Object.assign({}, defaultBrowserOptions, {executablePath: 'random-invalid-path'});
|
||||
await browserType.launch(options).catch(e => waitError = e);
|
||||
expect(waitError.message).toContain('Failed to launch');
|
||||
});
|
||||
|
||||
it.skip(options.WIRE)('should handle timeout', async({browserType, defaultBrowserOptions}) => {
|
||||
it.skip(options.WIRE)('should handle timeout', async ({browserType, defaultBrowserOptions}) => {
|
||||
const options = { ...defaultBrowserOptions, timeout: 5000, __testHookBeforeCreateBrowser: () => new Promise(f => setTimeout(f, 6000)) };
|
||||
const error = await browserType.launch(options).catch(e => e);
|
||||
expect(error.message).toContain(`browserType.launch: Timeout 5000ms exceeded.`);
|
||||
@ -66,26 +66,26 @@ it.skip(options.WIRE)('should handle timeout', async({browserType, defaultBrowse
|
||||
expect(error.message).toContain(`<launched> pid=`);
|
||||
});
|
||||
|
||||
it.skip(options.WIRE)('should handle exception', async({browserType, defaultBrowserOptions}) => {
|
||||
it.skip(options.WIRE)('should handle exception', async ({browserType, defaultBrowserOptions}) => {
|
||||
const e = new Error('Dummy');
|
||||
const options = { ...defaultBrowserOptions, __testHookBeforeCreateBrowser: () => { throw e; }, timeout: 9000 };
|
||||
const error = await browserType.launch(options).catch(e => e);
|
||||
expect(error.message).toContain('Dummy');
|
||||
});
|
||||
|
||||
it.skip(options.WIRE)('should report launch log', async({browserType, defaultBrowserOptions}) => {
|
||||
it.skip(options.WIRE)('should report launch log', async ({browserType, defaultBrowserOptions}) => {
|
||||
const e = new Error('Dummy');
|
||||
const options = { ...defaultBrowserOptions, __testHookBeforeCreateBrowser: () => { throw e; }, timeout: 9000 };
|
||||
const error = await browserType.launch(options).catch(e => e);
|
||||
expect(error.message).toContain('<launching>');
|
||||
});
|
||||
|
||||
it.slow()('should accept objects as options', async({browserType, defaultBrowserOptions}) => {
|
||||
it.slow()('should accept objects as options', async ({browserType, defaultBrowserOptions}) => {
|
||||
const browser = await browserType.launch({ ...defaultBrowserOptions, process } as any);
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should fire close event for all contexts', async({browserType, defaultBrowserOptions}) => {
|
||||
it('should fire close event for all contexts', async ({browserType, defaultBrowserOptions}) => {
|
||||
const browser = await browserType.launch(defaultBrowserOptions);
|
||||
const context = await browser.newContext();
|
||||
let closed = false;
|
||||
@ -94,7 +94,7 @@ it('should fire close event for all contexts', async({browserType, defaultBrowse
|
||||
expect(closed).toBe(true);
|
||||
});
|
||||
|
||||
it('should be callable twice', async({browserType, defaultBrowserOptions}) => {
|
||||
it('should be callable twice', async ({browserType, defaultBrowserOptions}) => {
|
||||
const browser = await browserType.launch(defaultBrowserOptions);
|
||||
await Promise.all([
|
||||
browser.close(),
|
||||
|
@ -22,8 +22,8 @@ it.fail(options.WEBKIT && WIN)('Web Assembly should work', async function({page,
|
||||
expect(await page.evaluate('loadTable()')).toBe('42, 83');
|
||||
});
|
||||
|
||||
it('WebSocket should work', async({page, server}) => {
|
||||
const value = await page.evaluate((port) => {
|
||||
it('WebSocket should work', async ({page, server}) => {
|
||||
const value = await page.evaluate(port => {
|
||||
let cb;
|
||||
const result = new Promise(f => cb = f);
|
||||
const ws = new WebSocket('ws://localhost:' + port + '/ws');
|
||||
@ -34,7 +34,7 @@ it('WebSocket should work', async({page, server}) => {
|
||||
expect(value).toBe('incoming');
|
||||
});
|
||||
|
||||
it('should respect CSP', async({page, server}) => {
|
||||
it('should respect CSP', async ({page, server}) => {
|
||||
server.setRoute('/empty.html', async (req, res) => {
|
||||
res.setHeader('Content-Security-Policy', `script-src 'unsafe-inline';`);
|
||||
res.end(`
|
||||
@ -48,7 +48,7 @@ it('should respect CSP', async({page, server}) => {
|
||||
expect(await page.evaluate(() => window['testStatus'])).toBe('SUCCESS');
|
||||
});
|
||||
|
||||
it.fixme(options.WEBKIT && (WIN || LINUX))('should play video', async({page, asset}) => {
|
||||
it.fixme(options.WEBKIT && (WIN || LINUX))('should play video', async ({page, asset}) => {
|
||||
// TODO: the test passes on Windows locally but fails on GitHub Action bot,
|
||||
// apparently due to a Media Pack issue in the Windows Server.
|
||||
// Also the test is very flaky on Linux WebKit.
|
||||
|
@ -17,11 +17,11 @@
|
||||
import { options } from './playwright.fixtures';
|
||||
import type { ChromiumBrowser } from '..';
|
||||
|
||||
it('should work', async({browser}) => {
|
||||
it('should work', async ({browser}) => {
|
||||
expect(!!browser['_connection']).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should scope context handles', async({browserType, browser, server}) => {
|
||||
it('should scope context handles', async ({browserType, browser, server}) => {
|
||||
const GOLDEN_PRECONDITION = {
|
||||
_guid: '',
|
||||
objects: [
|
||||
@ -65,7 +65,7 @@ it('should scope context handles', async({browserType, browser, server}) => {
|
||||
await expectScopeState(browser, GOLDEN_PRECONDITION);
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should scope CDPSession handles', async({browserType, browser, server}) => {
|
||||
it.skip(!options.CHROMIUM)('should scope CDPSession handles', async ({browserType, browser, server}) => {
|
||||
const GOLDEN_PRECONDITION = {
|
||||
_guid: '',
|
||||
objects: [
|
||||
@ -102,7 +102,7 @@ it.skip(!options.CHROMIUM)('should scope CDPSession handles', async({browserType
|
||||
await expectScopeState(browserType, GOLDEN_PRECONDITION);
|
||||
});
|
||||
|
||||
it('should scope browser handles', async({browserType, defaultBrowserOptions}) => {
|
||||
it('should scope browser handles', async ({browserType, defaultBrowserOptions}) => {
|
||||
const GOLDEN_PRECONDITION = {
|
||||
_guid: '',
|
||||
objects: [
|
||||
|
@ -16,49 +16,49 @@
|
||||
*/
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should check the box', async({page}) => {
|
||||
it('should check the box', async ({page}) => {
|
||||
await page.setContent(`<input id='checkbox' type='checkbox'></input>`);
|
||||
await page.check('input');
|
||||
expect(await page.evaluate(() => window['checkbox'].checked)).toBe(true);
|
||||
});
|
||||
|
||||
it('should not check the checked box', async({page}) => {
|
||||
it('should not check the checked box', async ({page}) => {
|
||||
await page.setContent(`<input id='checkbox' type='checkbox' checked></input>`);
|
||||
await page.check('input');
|
||||
expect(await page.evaluate(() => window['checkbox'].checked)).toBe(true);
|
||||
});
|
||||
|
||||
it('should uncheck the box', async({page}) => {
|
||||
it('should uncheck the box', async ({page}) => {
|
||||
await page.setContent(`<input id='checkbox' type='checkbox' checked></input>`);
|
||||
await page.uncheck('input');
|
||||
expect(await page.evaluate(() => window['checkbox'].checked)).toBe(false);
|
||||
});
|
||||
|
||||
it('should not uncheck the unchecked box', async({page}) => {
|
||||
it('should not uncheck the unchecked box', async ({page}) => {
|
||||
await page.setContent(`<input id='checkbox' type='checkbox'></input>`);
|
||||
await page.uncheck('input');
|
||||
expect(await page.evaluate(() => window['checkbox'].checked)).toBe(false);
|
||||
});
|
||||
|
||||
it('should check the box by label', async({page}) => {
|
||||
it('should check the box by label', async ({page}) => {
|
||||
await page.setContent(`<label for='checkbox'><input id='checkbox' type='checkbox'></input></label>`);
|
||||
await page.check('label');
|
||||
expect(await page.evaluate(() => window['checkbox'].checked)).toBe(true);
|
||||
});
|
||||
|
||||
it('should check the box outside label', async({page}) => {
|
||||
it('should check the box outside label', async ({page}) => {
|
||||
await page.setContent(`<label for='checkbox'>Text</label><div><input id='checkbox' type='checkbox'></input></div>`);
|
||||
await page.check('label');
|
||||
expect(await page.evaluate(() => window['checkbox'].checked)).toBe(true);
|
||||
});
|
||||
|
||||
it('should check the box inside label w/o id', async({page}) => {
|
||||
it('should check the box inside label w/o id', async ({page}) => {
|
||||
await page.setContent(`<label>Text<span><input id='checkbox' type='checkbox'></input></span></label>`);
|
||||
await page.check('label');
|
||||
expect(await page.evaluate(() => window['checkbox'].checked)).toBe(true);
|
||||
});
|
||||
|
||||
it('should check radio', async({page}) => {
|
||||
it('should check radio', async ({page}) => {
|
||||
await page.setContent(`
|
||||
<input type='radio'>one</input>
|
||||
<input id='two' type='radio'>two</input>
|
||||
@ -67,7 +67,7 @@ it('should check radio', async({page}) => {
|
||||
expect(await page.evaluate(() => window['two'].checked)).toBe(true);
|
||||
});
|
||||
|
||||
it('should check the box by aria role', async({page}) => {
|
||||
it('should check the box by aria role', async ({page}) => {
|
||||
await page.setContent(`<div role='checkbox' id='checkbox'>CHECKBOX</div>
|
||||
<script>
|
||||
checkbox.addEventListener('click', () => checkbox.setAttribute('aria-checked', 'true'));
|
||||
|
@ -73,20 +73,20 @@ it.skip(!options.CHROMIUM)('should work with complicated usecases', async functi
|
||||
delete coverage[0].text;
|
||||
delete coverage[0].url;
|
||||
expect(coverage).toEqual(
|
||||
[
|
||||
{
|
||||
"ranges": [
|
||||
{
|
||||
"start": 149,
|
||||
"end": 297
|
||||
},
|
||||
{
|
||||
"start": 327,
|
||||
"end": 433
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
[
|
||||
{
|
||||
'ranges': [
|
||||
{
|
||||
'start': 149,
|
||||
'end': 297
|
||||
},
|
||||
{
|
||||
'start': 327,
|
||||
'end': 433
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
import { options } from '../playwright.fixtures';
|
||||
import type { ChromiumBrowserContext } from '../..';
|
||||
|
||||
it.skip(!options.CHROMIUM)('should create a worker from a service worker', async({page, server, context}) => {
|
||||
it.skip(!options.CHROMIUM)('should create a worker from a service worker', async ({page, server, context}) => {
|
||||
const [worker] = await Promise.all([
|
||||
(context as ChromiumBrowserContext).waitForEvent('serviceworker'),
|
||||
page.goto(server.PREFIX + '/serviceworkers/empty/sw.html')
|
||||
@ -24,7 +24,7 @@ it.skip(!options.CHROMIUM)('should create a worker from a service worker', async
|
||||
expect(await worker.evaluate(() => self.toString())).toBe('[object ServiceWorkerGlobalScope]');
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('serviceWorkers() should return current workers', async({page, server, context}) => {
|
||||
it.skip(!options.CHROMIUM)('serviceWorkers() should return current workers', async ({page, server, context}) => {
|
||||
const [worker1] = await Promise.all([
|
||||
(context as ChromiumBrowserContext).waitForEvent('serviceworker'),
|
||||
page.goto(server.PREFIX + '/serviceworkers/empty/sw.html')
|
||||
@ -42,7 +42,7 @@ it.skip(!options.CHROMIUM)('serviceWorkers() should return current workers', asy
|
||||
expect(workers).toContain(worker2);
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should not create a worker from a shared worker', async({page, server, context}) => {
|
||||
it.skip(!options.CHROMIUM)('should not create a worker from a shared worker', async ({page, server, context}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
let serviceWorkerCreated;
|
||||
(context as ChromiumBrowserContext).once('serviceworker', () => serviceWorkerCreated = true);
|
||||
@ -52,7 +52,7 @@ it.skip(!options.CHROMIUM)('should not create a worker from a shared worker', as
|
||||
expect(serviceWorkerCreated).not.toBeTruthy();
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should close service worker together with the context', async({browser, server}) => {
|
||||
it.skip(!options.CHROMIUM)('should close service worker together with the context', async ({browser, server}) => {
|
||||
const context = await browser.newContext() as ChromiumBrowserContext;
|
||||
const page = await context.newPage();
|
||||
const [worker] = await Promise.all([
|
||||
@ -66,7 +66,7 @@ it.skip(!options.CHROMIUM)('should close service worker together with the contex
|
||||
expect(messages.join('|')).toBe('worker|context');
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('Page.route should work with intervention headers', async({server, page}) => {
|
||||
it.skip(!options.CHROMIUM)('Page.route should work with intervention headers', async ({server, page}) => {
|
||||
server.setRoute('/intervention', (req, res) => res.end(`
|
||||
<script>
|
||||
document.write('<script src="${server.CROSS_PROCESS_PREFIX}/intervention.js">' + '</scr' + 'ipt>');
|
||||
|
@ -20,21 +20,21 @@ import utils from '../utils';
|
||||
import type { ChromiumBrowser, ChromiumBrowserContext } from '../..';
|
||||
const { makeUserDataDir, removeUserDataDir } = utils;
|
||||
|
||||
it.skip(options.WIRE || !options.CHROMIUM)('should throw with remote-debugging-pipe argument', async({browserType, defaultBrowserOptions}) => {
|
||||
it.skip(options.WIRE || !options.CHROMIUM)('should throw with remote-debugging-pipe argument', async ({browserType, defaultBrowserOptions}) => {
|
||||
const options = Object.assign({}, defaultBrowserOptions);
|
||||
options.args = ['--remote-debugging-pipe'].concat(options.args || []);
|
||||
const error = await browserType.launchServer(options).catch(e => e);
|
||||
expect(error.message).toContain('Playwright manages remote debugging connection itself');
|
||||
});
|
||||
|
||||
it.skip(options.WIRE || !options.CHROMIUM)('should not throw with remote-debugging-port argument', async({browserType, defaultBrowserOptions}) => {
|
||||
it.skip(options.WIRE || !options.CHROMIUM)('should not throw with remote-debugging-port argument', async ({browserType, defaultBrowserOptions}) => {
|
||||
const options = Object.assign({}, defaultBrowserOptions);
|
||||
options.args = ['--remote-debugging-port=0'].concat(options.args || []);
|
||||
const browser = await browserType.launchServer(options);
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM || options.WIRE || WIN)('should open devtools when "devtools: true" option is given', async({browserType, defaultBrowserOptions}) => {
|
||||
it.skip(!options.CHROMIUM || options.WIRE || WIN)('should open devtools when "devtools: true" option is given', async ({browserType, defaultBrowserOptions}) => {
|
||||
let devtoolsCallback;
|
||||
const devtoolsPromise = new Promise(f => devtoolsCallback = f);
|
||||
const __testHookForDevTools = devtools => devtools.__testHookOnBinding = parsed => {
|
||||
@ -50,7 +50,7 @@ it.skip(!options.CHROMIUM || options.WIRE || WIN)('should open devtools when "de
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should return background pages', async({browserType, defaultBrowserOptions}) => {
|
||||
it.skip(!options.CHROMIUM)('should return background pages', async ({browserType, defaultBrowserOptions}) => {
|
||||
const userDataDir = await makeUserDataDir();
|
||||
const extensionPath = path.join(__dirname, '..', 'assets', 'simple-extension');
|
||||
const extensionOptions = {...defaultBrowserOptions,
|
||||
@ -62,9 +62,9 @@ it.skip(!options.CHROMIUM)('should return background pages', async({browserType,
|
||||
};
|
||||
const context = await browserType.launchPersistentContext(userDataDir, extensionOptions) as ChromiumBrowserContext;
|
||||
const backgroundPages = context.backgroundPages();
|
||||
let backgroundPage = backgroundPages.length
|
||||
? backgroundPages[0]
|
||||
: await context.waitForEvent('backgroundpage');
|
||||
const backgroundPage = backgroundPages.length
|
||||
? backgroundPages[0]
|
||||
: await context.waitForEvent('backgroundpage');
|
||||
expect(backgroundPage).toBeTruthy();
|
||||
expect(context.backgroundPages()).toContain(backgroundPage);
|
||||
expect(context.pages()).not.toContain(backgroundPage);
|
||||
@ -78,7 +78,7 @@ it.skip(!options.CHROMIUM)('should not create pages automatically', async ({brow
|
||||
const targets = [];
|
||||
browserSession.on('Target.targetCreated', async ({targetInfo}) => {
|
||||
if (targetInfo.type !== 'browser')
|
||||
targets.push(targetInfo);
|
||||
targets.push(targetInfo);
|
||||
});
|
||||
await browserSession.send('Target.setDiscoverTargets', { discover: true });
|
||||
await browser.newContext();
|
||||
|
@ -65,7 +65,7 @@ it.skip(!options.CHROMIUM)('should handle remote -> local -> remote transitions'
|
||||
expect(await countOOPIFs(browser)).toBe(1);
|
||||
});
|
||||
|
||||
it.fixme(options.CHROMIUM).skip(!options.CHROMIUM)('should get the proper viewport', async({browser, page, server}) => {
|
||||
it.fixme(options.CHROMIUM).skip(!options.CHROMIUM)('should get the proper viewport', async ({browser, page, server}) => {
|
||||
expect(page.viewportSize()).toEqual({width: 1280, height: 720});
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(page.frames().length).toBe(2);
|
||||
@ -84,7 +84,7 @@ it.fixme(options.CHROMIUM).skip(!options.CHROMIUM)('should get the proper viewpo
|
||||
expect(await oopif.evaluate(() => 'ontouchstart' in window)).toBe(false);
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should expose function', async({browser, page, server}) => {
|
||||
it.skip(!options.CHROMIUM)('should expose function', async ({browser, page, server}) => {
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(page.frames().length).toBe(2);
|
||||
expect(await countOOPIFs(browser)).toBe(1);
|
||||
@ -96,7 +96,7 @@ it.skip(!options.CHROMIUM)('should expose function', async({browser, page, serve
|
||||
expect(result).toBe(36);
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should emulate media', async({browser, page, server}) => {
|
||||
it.skip(!options.CHROMIUM)('should emulate media', async ({browser, page, server}) => {
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(page.frames().length).toBe(2);
|
||||
expect(await countOOPIFs(browser)).toBe(1);
|
||||
@ -106,7 +106,7 @@ it.skip(!options.CHROMIUM)('should emulate media', async({browser, page, server}
|
||||
expect(await oopif.evaluate(() => matchMedia('(prefers-color-scheme: dark)').matches)).toBe(true);
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should emulate offline', async({browser, page, context, server}) => {
|
||||
it.skip(!options.CHROMIUM)('should emulate offline', async ({browser, page, context, server}) => {
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(page.frames().length).toBe(2);
|
||||
expect(await countOOPIFs(browser)).toBe(1);
|
||||
@ -116,8 +116,8 @@ it.skip(!options.CHROMIUM)('should emulate offline', async({browser, page, conte
|
||||
expect(await oopif.evaluate(() => navigator.onLine)).toBe(false);
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should support context options', async({browser, server, playwright}) => {
|
||||
const iPhone = playwright.devices['iPhone 6']
|
||||
it.skip(!options.CHROMIUM)('should support context options', async ({browser, server, playwright}) => {
|
||||
const iPhone = playwright.devices['iPhone 6'];
|
||||
const context = await browser.newContext({ ...iPhone, timezoneId: 'America/Jamaica', locale: 'fr-CH', userAgent: 'UA' });
|
||||
const page = await context.newPage();
|
||||
|
||||
@ -138,7 +138,7 @@ it.skip(!options.CHROMIUM)('should support context options', async({browser, ser
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should respect route', async({browser, page, server}) => {
|
||||
it.skip(!options.CHROMIUM)('should respect route', async ({browser, page, server}) => {
|
||||
let intercepted = false;
|
||||
await page.route('**/digits/0.png', route => {
|
||||
intercepted = true;
|
||||
@ -150,7 +150,7 @@ it.skip(!options.CHROMIUM)('should respect route', async({browser, page, server}
|
||||
expect(intercepted).toBe(true);
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should take screenshot', async({browser, page, server, golden}) => {
|
||||
it.skip(!options.CHROMIUM)('should take screenshot', async ({browser, page, server, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/dynamic-oopif.html');
|
||||
expect(page.frames().length).toBe(2);
|
||||
@ -233,7 +233,7 @@ it.skip(!options.CHROMIUM)('should click a button when it overlays oopif', async
|
||||
expect(await page.evaluate(() => window['BUTTON_CLICKED'])).toBe(true);
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should report google.com frame with headful', async({browserType, defaultBrowserOptions, server}) => {
|
||||
it.skip(!options.CHROMIUM)('should report google.com frame with headful', async ({browserType, defaultBrowserOptions, server}) => {
|
||||
// @see https://github.com/GoogleChrome/puppeteer/issues/2548
|
||||
// https://google.com is isolated by default in Chromium embedder.
|
||||
const browser = await browserType.launch({...defaultBrowserOptions, headless: false});
|
||||
@ -303,7 +303,7 @@ async function countOOPIFs(browser) {
|
||||
const oopifs = [];
|
||||
browserSession.on('Target.targetCreated', async ({targetInfo}) => {
|
||||
if (targetInfo.type === 'iframe')
|
||||
oopifs.push(targetInfo);
|
||||
oopifs.push(targetInfo);
|
||||
});
|
||||
await browserSession.send('Target.setDiscoverTargets', { discover: true });
|
||||
await browserSession.detach();
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { options } from '../playwright.fixtures';
|
||||
import type { ChromiumBrowserContext, ChromiumBrowser } from "../../types/types";
|
||||
import type { ChromiumBrowserContext, ChromiumBrowser } from '../../types/types';
|
||||
|
||||
it.skip(!options.CHROMIUM)('should work', async function({page}) {
|
||||
const client = await (page.context() as ChromiumBrowserContext).newCDPSession(page);
|
||||
|
@ -34,14 +34,14 @@ registerFixture('outputFile', async ({tmpDir}, test) => {
|
||||
fs.unlinkSync(outputFile);
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should output a trace', async({browser, page, server, outputFile}) => {
|
||||
it.skip(!options.CHROMIUM)('should output a trace', async ({browser, page, server, outputFile}) => {
|
||||
await (browser as ChromiumBrowser).startTracing(page, {screenshots: true, path: outputFile});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
await (browser as ChromiumBrowser).stopTracing();
|
||||
expect(fs.existsSync(outputFile)).toBe(true);
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should create directories as needed', async({browser, page, server, tmpDir}) => {
|
||||
it.skip(!options.CHROMIUM)('should create directories as needed', async ({browser, page, server, tmpDir}) => {
|
||||
const filePath = path.join(tmpDir, 'these', 'are', 'directories');
|
||||
await (browser as ChromiumBrowser).startTracing(page, {screenshots: true, path: filePath});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
@ -49,7 +49,7 @@ it.skip(!options.CHROMIUM)('should create directories as needed', async({browser
|
||||
expect(fs.existsSync(filePath)).toBe(true);
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should run with custom categories if provided', async({browser, page, outputFile}) => {
|
||||
it.skip(!options.CHROMIUM)('should run with custom categories if provided', async ({browser, page, outputFile}) => {
|
||||
await (browser as ChromiumBrowser).startTracing(page, {path: outputFile, categories: ['disabled-by-default-v8.cpu_profiler.hires']});
|
||||
await (browser as ChromiumBrowser).stopTracing();
|
||||
|
||||
@ -57,7 +57,7 @@ it.skip(!options.CHROMIUM)('should run with custom categories if provided', asyn
|
||||
expect(traceJson.metadata['trace-config']).toContain('disabled-by-default-v8.cpu_profiler.hires');
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should throw if tracing on two pages', async({browser, page, outputFile}) => {
|
||||
it.skip(!options.CHROMIUM)('should throw if tracing on two pages', async ({browser, page, outputFile}) => {
|
||||
await (browser as ChromiumBrowser).startTracing(page, {path: outputFile});
|
||||
const newPage = await browser.newPage();
|
||||
let error = null;
|
||||
@ -67,7 +67,7 @@ it.skip(!options.CHROMIUM)('should throw if tracing on two pages', async({browse
|
||||
await (browser as ChromiumBrowser).stopTracing();
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should return a buffer', async({browser, page, server, outputFile}) => {
|
||||
it.skip(!options.CHROMIUM)('should return a buffer', async ({browser, page, server, outputFile}) => {
|
||||
await (browser as ChromiumBrowser).startTracing(page, {screenshots: true, path: outputFile});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const trace = await (browser as ChromiumBrowser).stopTracing();
|
||||
@ -75,14 +75,14 @@ it.skip(!options.CHROMIUM)('should return a buffer', async({browser, page, serve
|
||||
expect(trace.toString()).toEqual(buf.toString());
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should work without options', async({browser, page, server}) => {
|
||||
it.skip(!options.CHROMIUM)('should work without options', async ({browser, page, server}) => {
|
||||
await (browser as ChromiumBrowser).startTracing(page);
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const trace = await (browser as ChromiumBrowser).stopTracing();
|
||||
expect(trace).toBeTruthy();
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should support a buffer without a path', async({browser, page, server}) => {
|
||||
it.skip(!options.CHROMIUM)('should support a buffer without a path', async ({browser, page, server}) => {
|
||||
await (browser as ChromiumBrowser).startTracing(page, {screenshots: true});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const trace = await (browser as ChromiumBrowser).stopTracing();
|
||||
|
@ -23,12 +23,12 @@ 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' })] ));
|
||||
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' })] ));
|
||||
renderComponent(e('div', {}, [e(MyButton, { name: 'button2' }), e(MyButton, { name: 'button1' })]));
|
||||
else
|
||||
renderComponent(e('div', {}, []));
|
||||
});
|
||||
@ -42,12 +42,12 @@ it.fail(true)('should report that selector does not match anymore', async ({page
|
||||
it.fixme(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 })] ));
|
||||
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' })] ));
|
||||
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);
|
||||
@ -57,7 +57,7 @@ it.fixme(true)('should not retarget the handle when element is recycled', async
|
||||
expect(error.message).toContain('element is disabled - waiting');
|
||||
});
|
||||
|
||||
it('should timeout when click opens alert', async({page, server}) => {
|
||||
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);
|
||||
@ -69,12 +69,12 @@ it('should timeout when click opens alert', async({page, server}) => {
|
||||
it.fixme(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' })] ));
|
||||
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' })] ));
|
||||
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);
|
||||
@ -84,12 +84,12 @@ it.fixme(true)('should retarget when element is recycled during hit testing', as
|
||||
it.fixme(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 })] ));
|
||||
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' })] ));
|
||||
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);
|
||||
@ -99,7 +99,7 @@ it.fixme(true)('should retarget when element is recycled before enabled check',
|
||||
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' })] ));
|
||||
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);
|
||||
@ -110,9 +110,9 @@ 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: 'button2' }), e(MyButton, { name: 'button1' })]));
|
||||
}
|
||||
renderComponent(e('div', {}, [e(MyButton, { name: 'button1', onHover: shuffle }), e(MyButton, { name: 'button2' })] ));
|
||||
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);
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
it.skip(options.WIRE)('should avoid side effects after timeout', async({page, server}) => {
|
||||
it.skip(options.WIRE)('should avoid side effects after timeout', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
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.
|
||||
@ -25,7 +25,7 @@ it.skip(options.WIRE)('should avoid side effects after timeout', async({page, se
|
||||
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>');
|
||||
const error = await page.click('text=Click target', { timeout: 3000 }).catch(e => e);
|
||||
expect(await page.evaluate('window.__CLICKED')).toBe(undefined);
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
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}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.$eval('button', b => b.style.display = 'none');
|
||||
const error = await page.click('button', { timeout: 5000 }).catch(e => e);
|
||||
@ -26,7 +26,7 @@ it('should timeout waiting for display:none to be gone', async({page, server}) =
|
||||
expect(error.message).toContain('element is not visible - waiting');
|
||||
});
|
||||
|
||||
it('should timeout waiting for visbility:hidden to be gone', async({page, server}) => {
|
||||
it('should timeout waiting for visbility:hidden to be gone', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.$eval('button', b => b.style.visibility = 'hidden');
|
||||
const error = await page.click('button', { timeout: 5000 }).catch(e => e);
|
||||
|
@ -17,12 +17,12 @@
|
||||
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
it.skip(options.WIRE)('should fail when element jumps during hit testing', async({page, server}) => {
|
||||
it.skip(options.WIRE)('should fail when element jumps during hit testing', async ({page, server}) => {
|
||||
await page.setContent('<button>Click me</button>');
|
||||
let clicked = false;
|
||||
const handle = await page.$('button');
|
||||
const __testHookBeforeHitTarget = () => page.evaluate(() => {
|
||||
const margin = parseInt(document.querySelector('button').style.marginLeft || '0') + 100;
|
||||
const margin = parseInt(document.querySelector('button').style.marginLeft || '0', 10) + 100;
|
||||
document.querySelector('button').style.marginLeft = margin + 'px';
|
||||
});
|
||||
const promise = handle.click({ timeout: 5000, __testHookBeforeHitTarget } as any).then(() => clicked = true).catch(e => e);
|
||||
@ -34,7 +34,7 @@ it.skip(options.WIRE)('should fail when element jumps during hit testing', async
|
||||
expect(error.message).toContain('retrying click action');
|
||||
});
|
||||
|
||||
it('should timeout waiting for hit target', async({page, server}) => {
|
||||
it('should timeout waiting for hit target', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
const button = await page.$('button');
|
||||
await page.evaluate(() => {
|
||||
@ -54,7 +54,7 @@ it('should timeout waiting for hit target', async({page, server}) => {
|
||||
expect(error.message).toContain('retrying click action');
|
||||
});
|
||||
|
||||
it('should report wrong hit target subtree', async({page, server}) => {
|
||||
it('should report wrong hit target subtree', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
const button = await page.$('button');
|
||||
await page.evaluate(() => {
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
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');
|
||||
const button = await page.$('button');
|
||||
await button.evaluate(button => {
|
||||
|
@ -23,13 +23,13 @@ async function giveItAChanceToClick(page) {
|
||||
await page.evaluate(() => new Promise(f => requestAnimationFrame(() => requestAnimationFrame(f))));
|
||||
}
|
||||
|
||||
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.click('button');
|
||||
expect(await page.evaluate('result')).toBe('Clicked');
|
||||
});
|
||||
|
||||
it('should click svg', async({page, server}) => {
|
||||
it('should click svg', async ({page, server}) => {
|
||||
await page.setContent(`
|
||||
<svg height="100" width="100">
|
||||
<circle onclick="javascript:window.__CLICKED=42" cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
|
||||
@ -39,7 +39,7 @@ it('should click svg', async({page, server}) => {
|
||||
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.evaluate(() => delete window.Node);
|
||||
await page.click('button');
|
||||
@ -47,7 +47,7 @@ it('should click the button if window.Node is removed', async({page, server}) =>
|
||||
});
|
||||
|
||||
// @see https://github.com/GoogleChrome/puppeteer/issues/4281
|
||||
it('should click on a span with an inline element inside', async({page, server}) => {
|
||||
it('should click on a span with an inline element inside', async ({page, server}) => {
|
||||
await page.setContent(`
|
||||
<style>
|
||||
span::before {
|
||||
@ -60,7 +60,7 @@ it('should click on a span with an inline element inside', async({page, server})
|
||||
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}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await Promise.all([
|
||||
@ -70,13 +70,13 @@ it('should not throw UnhandledPromiseRejection when page closes', async({browser
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should click the 1x1 div', async({page, server}) => {
|
||||
it('should click the 1x1 div', async ({page, server}) => {
|
||||
await page.setContent(`<div style="width: 1px; height: 1px;" onclick="window.__clicked = true"></div>`);
|
||||
await page.click('div');
|
||||
expect(await page.evaluate('window.__clicked')).toBe(true);
|
||||
});
|
||||
|
||||
it('should click the button after navigation ', async({page, server}) => {
|
||||
it('should click the button after navigation ', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.click('button');
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
@ -84,7 +84,7 @@ it('should click the button after navigation ', async({page, server}) => {
|
||||
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}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.click('button');
|
||||
await page.goto(server.CROSS_PROCESS_PREFIX + '/input/button.html');
|
||||
@ -92,7 +92,7 @@ it('should click the button after a cross origin navigation ', async({page, serv
|
||||
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}) => {
|
||||
const context = await browser.newContext({ javaScriptEnabled: false });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/wrappedlink.html');
|
||||
@ -104,7 +104,7 @@ it('should click with disabled javascript', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should click when one of inline box children is outside of viewport', async({page, server}) => {
|
||||
it('should click when one of inline box children is outside of viewport', async ({page, server}) => {
|
||||
await page.setContent(`
|
||||
<style>
|
||||
i {
|
||||
@ -118,7 +118,7 @@ it('should click when one of inline box children is outside of viewport', async(
|
||||
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}) => {
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
const text = 'This is the text that we are going to try to select. Let\'s see how it goes.';
|
||||
await page.fill('textarea', text);
|
||||
@ -129,7 +129,7 @@ it('should select the text by triple clicking', async({page, server}) => {
|
||||
})).toBe(text);
|
||||
});
|
||||
|
||||
it('should click offscreen buttons', async({page, server}) => {
|
||||
it('should click offscreen buttons', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/offscreenbuttons.html');
|
||||
const messages = [];
|
||||
page.on('console', msg => messages.push(msg.text()));
|
||||
@ -153,13 +153,13 @@ 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.click('button');
|
||||
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}) => {
|
||||
let error = null;
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.$eval('button', b => b.style.display = 'none');
|
||||
@ -168,7 +168,7 @@ it('should not wait with force', async({page, server}) => {
|
||||
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}) => {
|
||||
let done = false;
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.$eval('button', b => b.style.display = 'none');
|
||||
@ -182,7 +182,7 @@ it('should waitFor display:none to be gone', async({page, server}) => {
|
||||
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}) => {
|
||||
let done = false;
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.$eval('button', b => b.style.visibility = 'hidden');
|
||||
@ -196,7 +196,7 @@ it('should waitFor visibility:hidden to be gone', async({page, server}) => {
|
||||
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}) => {
|
||||
let done = false;
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.$eval('button', b => b.parentElement.style.display = 'none');
|
||||
@ -209,13 +209,13 @@ it('should waitFor visible when parent is hidden', async({page, server}) => {
|
||||
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.click('a');
|
||||
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');
|
||||
expect(await page.evaluate(() => window['result'].check)).toBe(null);
|
||||
await page.click('input#agree');
|
||||
@ -234,7 +234,7 @@ it('should click on checkbox input and toggle', async({page, server}) => {
|
||||
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');
|
||||
expect(await page.evaluate(() => window['result'].check)).toBe(null);
|
||||
await page.click('label[for="agree"]');
|
||||
@ -248,7 +248,7 @@ it('should click on checkbox label and toggle', async({page, server}) => {
|
||||
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}) => {
|
||||
// @see https://github.com/GoogleChrome/puppeteer/issues/161
|
||||
const { viewport, hasTouch } = playwright.devices['iPhone 6'];
|
||||
const context = await browser.newContext({ viewport, hasTouch });
|
||||
@ -259,7 +259,7 @@ it('should not hang with touch-enabled viewports', async({browser, playwright})
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should scroll and click the button', async({page, server}) => {
|
||||
it('should scroll and click the button', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/scrollable.html');
|
||||
await page.click('#button-5');
|
||||
expect(await page.evaluate(() => document.querySelector('#button-5').textContent)).toBe('clicked');
|
||||
@ -267,7 +267,7 @@ it('should scroll and click the button', async({page, server}) => {
|
||||
expect(await page.evaluate(() => document.querySelector('#button-80').textContent)).toBe('clicked');
|
||||
});
|
||||
|
||||
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.evaluate(() => {
|
||||
window['double'] = false;
|
||||
@ -281,7 +281,7 @@ it('should double click the button', async({page, server}) => {
|
||||
expect(await page.evaluate('result')).toBe('Clicked');
|
||||
});
|
||||
|
||||
it('should click a partially obscured button', async({page, server}) => {
|
||||
it('should click a partially obscured button', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.evaluate(() => {
|
||||
const button = document.querySelector('button');
|
||||
@ -293,26 +293,26 @@ it('should click a partially obscured button', async({page, server}) => {
|
||||
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.click('button');
|
||||
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}) => {
|
||||
await page.goto(server.PREFIX + '/input/scrollable.html');
|
||||
await page.click('#button-8', {button: 'right'});
|
||||
expect(await page.evaluate(() => document.querySelector('#button-8').textContent)).toBe('context menu');
|
||||
});
|
||||
|
||||
it('should click links which cause navigation', async({page, server}) => {
|
||||
it('should click links which cause navigation', async ({page, server}) => {
|
||||
// @see https://github.com/GoogleChrome/puppeteer/issues/206
|
||||
await page.setContent(`<a href="${server.EMPTY_PAGE}">empty.html</a>`);
|
||||
// This await should not hang.
|
||||
await page.click('a');
|
||||
});
|
||||
|
||||
it('should click the button inside an iframe', async({page, server}) => {
|
||||
it('should click the button inside an iframe', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.setContent('<div style="width:100px;height:100px">spacer</div>');
|
||||
await utils.attachFrame(page, 'button-test', server.PREFIX + '/input/button.html');
|
||||
@ -322,7 +322,7 @@ it('should click the button inside an iframe', async({page, server}) => {
|
||||
expect(await frame.evaluate(() => window['result'])).toBe('Clicked');
|
||||
});
|
||||
|
||||
it.fixme(options.CHROMIUM || options.WEBKIT)('should click the button with fixed position inside an iframe', async({page, server}) => {
|
||||
it.fixme(options.CHROMIUM || options.WEBKIT)('should click the button with fixed position inside an iframe', async ({page, server}) => {
|
||||
// @see https://github.com/GoogleChrome/puppeteer/issues/4110
|
||||
// @see https://bugs.chromium.org/p/chromium/issues/detail?id=986390
|
||||
// @see https://chromium-review.googlesource.com/c/chromium/src/+/1742784
|
||||
@ -336,7 +336,7 @@ it.fixme(options.CHROMIUM || options.WEBKIT)('should click the button with fixed
|
||||
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}) => {
|
||||
const context = await browser.newContext({ viewport: { width: 400, height: 400 }, deviceScaleFactor: 5 });
|
||||
const page = await context.newPage();
|
||||
expect(await page.evaluate(() => window.devicePixelRatio)).toBe(5);
|
||||
@ -349,7 +349,7 @@ it('should click the button with deviceScaleFactor set', async({browser, server}
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should click the button with px border with offset', async({page, server}) => {
|
||||
it('should click the button with px border with offset', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.$eval('button', button => button.style.borderWidth = '8px');
|
||||
await page.click('button', { position: { x: 20, y: 10 } });
|
||||
@ -359,7 +359,7 @@ it('should click the button with px border with offset', async({page, server}) =
|
||||
expect(await page.evaluate('offsetY')).toBe(options.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}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.$eval('button', button => button.style.borderWidth = '2em');
|
||||
await page.$eval('button', button => button.style.fontSize = '12px');
|
||||
@ -370,7 +370,7 @@ it('should click the button with em border with offset', async({page, server}) =
|
||||
expect(await page.evaluate('offsetY')).toBe(options.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}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.$eval('button', button => button.style.borderWidth = '8px');
|
||||
await page.$eval('button', button => button.style.height = button.style.width = '2000px');
|
||||
@ -381,7 +381,7 @@ it('should click a very large button with offset', async({page, server}) => {
|
||||
expect(await page.evaluate('offsetY')).toBe(options.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}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.$eval('button', button => {
|
||||
const container = document.createElement('div');
|
||||
@ -401,7 +401,7 @@ it('should click a button in scrolling container with offset', async({page, serv
|
||||
expect(await page.evaluate('offsetY')).toBe(options.WEBKIT ? 1910 + 8 : 1910);
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('should click the button with offset with page scale', async({browser, server}) => {
|
||||
it.skip(options.FIREFOX)('should click the button with offset with page scale', async ({browser, server}) => {
|
||||
const context = await browser.newContext({ viewport: { width: 400, height: 400 }, isMobile: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
@ -425,7 +425,7 @@ it.skip(options.FIREFOX)('should click the button with offset with page scale',
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should wait for stable position', async({page, server}) => {
|
||||
it('should wait for stable position', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.$eval('button', button => {
|
||||
button.style.transition = 'margin 500ms linear 0s';
|
||||
@ -444,7 +444,7 @@ it('should wait for stable position', async({page, server}) => {
|
||||
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}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.$eval('button', button => {
|
||||
button.style.borderWidth = '0';
|
||||
@ -476,7 +476,7 @@ it('should wait for becoming hit target', async({page, server}) => {
|
||||
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}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
const button = await page.$('button');
|
||||
await page.evaluate(() => {
|
||||
@ -493,7 +493,7 @@ it('should fail when obscured and not waiting for hit target', async({page, serv
|
||||
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}) => {
|
||||
await page.setContent('<button onclick="javascript:window.__CLICKED=true;" disabled><span>Click target</span></button>');
|
||||
let done = false;
|
||||
const clickPromise = page.click('text=Click target').then(() => done = true);
|
||||
@ -505,7 +505,7 @@ it('should wait for button to be enabled', async({page, server}) => {
|
||||
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}) => {
|
||||
await page.setContent('<input onclick="javascript:window.__CLICKED=true;" disabled>');
|
||||
let done = false;
|
||||
const clickPromise = page.click('input').then(() => done = true);
|
||||
@ -517,7 +517,7 @@ it('should wait for input to be enabled', async({page, server}) => {
|
||||
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}) => {
|
||||
await page.setContent('<select onclick="javascript:window.__CLICKED=true;" disabled><option selected>Hello</option></select>');
|
||||
let done = false;
|
||||
const clickPromise = page.click('select').then(() => done = true);
|
||||
@ -529,25 +529,25 @@ it('should wait for select to be enabled', async({page, server}) => {
|
||||
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.click('text=Click target');
|
||||
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.click('text=Click target');
|
||||
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.click('text=Click target');
|
||||
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}) => {
|
||||
await page.setContent('<button onclick="javascript:window.__CLICKED=true;" style="pointer-events:none"><span>Click target</span></button>');
|
||||
let done = false;
|
||||
const clickPromise = page.click('text=Click target').then(() => done = true);
|
||||
@ -559,7 +559,7 @@ it('should wait for BUTTON to be clickable when it has pointer-events:none', asy
|
||||
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}) => {
|
||||
await page.setContent('<label onclick="javascript:window.__CLICKED=true;" style="pointer-events:none"><span>Click target</span></label>');
|
||||
const clickPromise = page.click('text=Click target');
|
||||
// Do a few roundtrips to the page.
|
||||
@ -571,7 +571,7 @@ it('should wait for LABEL to be clickable when it has pointer-events:none', asyn
|
||||
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.click('button', { modifiers: ['Shift'] });
|
||||
expect(await page.evaluate('shiftKey')).toBe(true);
|
||||
@ -588,7 +588,7 @@ it('should update modifiers correctly', async({page, server}) => {
|
||||
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}) => {
|
||||
await page.setContent(`
|
||||
<div style="border: 1px solid black; height: 500px; overflow: auto; width: 500px; scroll-behavior: smooth">
|
||||
<button style="margin-top: 2000px" onClick="window.clicked = true">hi</button>
|
||||
@ -598,7 +598,7 @@ it('should click an offscreen element when scroll-behavior is smooth', async({pa
|
||||
expect(await page.evaluate('window.clicked')).toBe(true);
|
||||
});
|
||||
|
||||
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.evaluate('addButton()');
|
||||
const handle = await page.$('button');
|
||||
@ -609,7 +609,7 @@ it('should report nice error when element is detached and force-clicked', async(
|
||||
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.evaluate('addButton()');
|
||||
const handle = await page.$('button');
|
||||
@ -620,7 +620,7 @@ it('should fail when element detaches after animation', async({page, server}) =>
|
||||
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.evaluate('addButton()');
|
||||
let clicked = false;
|
||||
@ -641,7 +641,7 @@ it('should retry when element detaches after animation', async({page, server}) =
|
||||
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}) => {
|
||||
await page.setContent(`<style>
|
||||
@keyframes move {
|
||||
from { left: -300px; }
|
||||
@ -669,7 +669,7 @@ it('should retry when element is animating from outside the viewport', async({pa
|
||||
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}) => {
|
||||
await page.setContent(`<style>
|
||||
@keyframes move {
|
||||
from { left: -300px; }
|
||||
@ -698,7 +698,7 @@ it('should fail when element is animating from outside the viewport with force',
|
||||
expect(error.message).toContain('Element is outside of the viewport');
|
||||
});
|
||||
|
||||
it('should dispatch microtasks in order', async({page, server}) => {
|
||||
it('should dispatch microtasks in order', async ({page, server}) => {
|
||||
await page.setContent(`
|
||||
<button id=button>Click me</button>
|
||||
<script>
|
||||
@ -721,7 +721,7 @@ it('should dispatch microtasks in order', async({page, server}) => {
|
||||
expect(await page.evaluate(() => window['result'])).toBe(1);
|
||||
});
|
||||
|
||||
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.evaluate(() => Object.defineProperty(window, 'innerWidth', {value: 0}));
|
||||
await page.click('button');
|
||||
|
@ -20,7 +20,7 @@ import fs from 'fs';
|
||||
import utils from './utils';
|
||||
|
||||
it('context.cookies() should work', async ({server, launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent();
|
||||
const {page} = await launchPersistent();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const documentCookie = await page.evaluate(() => {
|
||||
document.cookie = 'username=John Doe';
|
||||
@ -40,7 +40,7 @@ it('context.cookies() should work', async ({server, launchPersistent}) => {
|
||||
});
|
||||
|
||||
it('context.addCookies() should work', async ({server, launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent();
|
||||
const {page} = await launchPersistent();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.context().addCookies([{
|
||||
url: server.EMPTY_PAGE,
|
||||
@ -61,7 +61,7 @@ it('context.addCookies() should work', async ({server, launchPersistent}) => {
|
||||
});
|
||||
|
||||
it('context.clearCookies() should work', async ({server, launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent();
|
||||
const {page} = await launchPersistent();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.context().addCookies([{
|
||||
url: server.EMPTY_PAGE,
|
||||
@ -102,14 +102,14 @@ it('should(not) block third party cookies', async ({server, launchPersistent}) =
|
||||
if (allowsThirdParty) {
|
||||
expect(cookies).toEqual([
|
||||
{
|
||||
"domain": "127.0.0.1",
|
||||
"expires": -1,
|
||||
"httpOnly": false,
|
||||
"name": "username",
|
||||
"path": "/",
|
||||
"sameSite": "None",
|
||||
"secure": false,
|
||||
"value": "John Doe"
|
||||
'domain': '127.0.0.1',
|
||||
'expires': -1,
|
||||
'httpOnly': false,
|
||||
'name': 'username',
|
||||
'path': '/',
|
||||
'sameSite': 'None',
|
||||
'secure': false,
|
||||
'value': 'John Doe'
|
||||
}
|
||||
]);
|
||||
} else {
|
||||
@ -125,12 +125,12 @@ it('should support viewport option', async ({launchPersistent}) => {
|
||||
});
|
||||
|
||||
it('should support deviceScaleFactor option', async ({launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent({deviceScaleFactor: 3});
|
||||
const {page} = await launchPersistent({deviceScaleFactor: 3});
|
||||
expect(await page.evaluate('window.devicePixelRatio')).toBe(3);
|
||||
});
|
||||
|
||||
it('should support userAgent option', async ({server, launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent({userAgent: 'foobar'});
|
||||
const {page} = await launchPersistent({userAgent: 'foobar'});
|
||||
expect(await page.evaluate(() => navigator.userAgent)).toBe('foobar');
|
||||
const [request] = await Promise.all([
|
||||
server.waitForRequest('/empty.html'),
|
||||
@ -140,14 +140,14 @@ it('should support userAgent option', async ({server, launchPersistent}) => {
|
||||
});
|
||||
|
||||
it('should support bypassCSP option', async ({server, launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent({bypassCSP: true});
|
||||
const {page} = await launchPersistent({bypassCSP: true});
|
||||
await page.goto(server.PREFIX + '/csp.html');
|
||||
await page.addScriptTag({content: 'window["__injected"] = 42;'});
|
||||
expect(await page.evaluate('__injected')).toBe(42);
|
||||
});
|
||||
|
||||
it('should support javascriptEnabled option', async ({launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent({javaScriptEnabled: false});
|
||||
const {page} = await launchPersistent({javaScriptEnabled: false});
|
||||
await page.goto('data:text/html, <script>var something = "forbidden"</script>');
|
||||
let error = null;
|
||||
await page.evaluate('something').catch(e => error = e);
|
||||
@ -158,21 +158,21 @@ it('should support javascriptEnabled option', async ({launchPersistent}) => {
|
||||
});
|
||||
|
||||
it('should support httpCredentials option', async ({server, launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent({httpCredentials: { username: 'user', password: 'pass' }});
|
||||
const {page} = await launchPersistent({httpCredentials: { username: 'user', password: 'pass' }});
|
||||
server.setAuth('/playground.html', 'user', 'pass');
|
||||
const response = await page.goto(server.PREFIX + '/playground.html');
|
||||
expect(response.status()).toBe(200);
|
||||
});
|
||||
|
||||
it('should support offline option', async ({server, launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent({offline: true});
|
||||
const {page} = await launchPersistent({offline: true});
|
||||
const error = await page.goto(server.EMPTY_PAGE).catch(e => e);
|
||||
expect(error).toBeTruthy();
|
||||
});
|
||||
|
||||
it.skip(true)('should support acceptDownloads option', async ({server, launchPersistent}) => {
|
||||
// TODO: unskip once we support downloads in persistent context.
|
||||
const {page, context} = await launchPersistent({acceptDownloads: true});
|
||||
const {page} = await launchPersistent({acceptDownloads: true});
|
||||
server.setRoute('/download', (req, res) => {
|
||||
res.setHeader('Content-Type', 'application/octet-stream');
|
||||
res.setHeader('Content-Disposition', 'attachment');
|
||||
|
@ -21,36 +21,36 @@ import utils from './utils';
|
||||
const { removeUserDataDir, makeUserDataDir } = utils;
|
||||
|
||||
it('should support hasTouch option', async ({server, launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent({hasTouch: true});
|
||||
const {page} = await launchPersistent({hasTouch: true});
|
||||
await page.goto(server.PREFIX + '/mobile.html');
|
||||
expect(await page.evaluate(() => 'ontouchstart' in window)).toBe(true);
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('should work in persistent context', async ({server, launchPersistent}) => {
|
||||
// Firefox does not support mobile.
|
||||
const {page, context} = await launchPersistent({viewport: {width: 320, height: 480}, isMobile: true});
|
||||
const {page} = await launchPersistent({viewport: {width: 320, height: 480}, isMobile: true});
|
||||
await page.goto(server.PREFIX + '/empty.html');
|
||||
expect(await page.evaluate(() => window.innerWidth)).toBe(980);
|
||||
});
|
||||
|
||||
it('should support colorScheme option', async ({launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent({colorScheme: 'dark'});
|
||||
const {page} = await launchPersistent({colorScheme: 'dark'});
|
||||
expect(await page.evaluate(() => matchMedia('(prefers-color-scheme: light)').matches)).toBe(false);
|
||||
expect(await page.evaluate(() => matchMedia('(prefers-color-scheme: dark)').matches)).toBe(true);
|
||||
});
|
||||
|
||||
it('should support timezoneId option', async ({launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent({timezoneId: 'America/Jamaica'});
|
||||
const {page} = await launchPersistent({timezoneId: 'America/Jamaica'});
|
||||
expect(await page.evaluate(() => new Date(1479579154987).toString())).toBe('Sat Nov 19 2016 13:12:34 GMT-0500 (Eastern Standard Time)');
|
||||
});
|
||||
|
||||
it('should support locale option', async ({launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent({locale: 'fr-CH'});
|
||||
const {page} = await launchPersistent({locale: 'fr-CH'});
|
||||
expect(await page.evaluate(() => navigator.language)).toBe('fr-CH');
|
||||
});
|
||||
|
||||
it('should support geolocation and permissions options', async ({server, launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent({geolocation: {longitude: 10, latitude: 10}, permissions: ['geolocation']});
|
||||
const {page} = await launchPersistent({geolocation: {longitude: 10, latitude: 10}, permissions: ['geolocation']});
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const geolocation = await page.evaluate(() => new Promise(resolve => navigator.geolocation.getCurrentPosition(position => {
|
||||
resolve({latitude: position.coords.latitude, longitude: position.coords.longitude});
|
||||
@ -59,7 +59,7 @@ it('should support geolocation and permissions options', async ({server, launchP
|
||||
});
|
||||
|
||||
it('should support ignoreHTTPSErrors option', async ({httpsServer, launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent({ignoreHTTPSErrors: true});
|
||||
const {page} = await launchPersistent({ignoreHTTPSErrors: true});
|
||||
let error = null;
|
||||
const response = await page.goto(httpsServer.EMPTY_PAGE).catch(e => error = e);
|
||||
expect(error).toBe(null);
|
||||
@ -67,7 +67,7 @@ it('should support ignoreHTTPSErrors option', async ({httpsServer, launchPersist
|
||||
});
|
||||
|
||||
it('should support extraHTTPHeaders option', async ({server, launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent({extraHTTPHeaders: { foo: 'bar' }});
|
||||
const {page} = await launchPersistent({extraHTTPHeaders: { foo: 'bar' }});
|
||||
const [request] = await Promise.all([
|
||||
server.waitForRequest('/empty.html'),
|
||||
page.goto(server.EMPTY_PAGE),
|
||||
@ -76,7 +76,7 @@ it('should support extraHTTPHeaders option', async ({server, launchPersistent})
|
||||
});
|
||||
|
||||
it.flaky(options.CHROMIUM)('should accept userDataDir', async ({launchPersistent, tmpDir}) => {
|
||||
const {page, context} = await launchPersistent();
|
||||
const {context} = await launchPersistent();
|
||||
// Note: we need an open page to make sure its functional.
|
||||
expect(fs.readdirSync(tmpDir).length).toBeGreaterThan(0);
|
||||
await context.close();
|
||||
@ -85,7 +85,7 @@ it.flaky(options.CHROMIUM)('should accept userDataDir', async ({launchPersistent
|
||||
await removeUserDataDir(tmpDir);
|
||||
});
|
||||
|
||||
it.slow()('should restore state from userDataDir', async({browserType, defaultBrowserOptions, server, launchPersistent}) => {
|
||||
it.slow()('should restore state from userDataDir', async ({browserType, defaultBrowserOptions, server, launchPersistent}) => {
|
||||
const userDataDir = await makeUserDataDir();
|
||||
const browserContext = await browserType.launchPersistentContext(userDataDir, defaultBrowserOptions);
|
||||
const page = await browserContext.newPage();
|
||||
@ -111,7 +111,7 @@ it.slow()('should restore state from userDataDir', async({browserType, defaultBr
|
||||
await removeUserDataDir(userDataDir2);
|
||||
});
|
||||
|
||||
it.slow()('should restore cookies from userDataDir', async({browserType, defaultBrowserOptions, server, launchPersistent}) => {
|
||||
it.slow()('should restore cookies from userDataDir', async ({browserType, defaultBrowserOptions, server, launchPersistent}) => {
|
||||
const userDataDir = await makeUserDataDir();
|
||||
const browserContext = await browserType.launchPersistentContext(userDataDir, defaultBrowserOptions);
|
||||
const page = await browserContext.newPage();
|
||||
@ -142,7 +142,7 @@ it.slow()('should restore cookies from userDataDir', async({browserType, default
|
||||
});
|
||||
|
||||
it('should have default URL when launching browser', async ({launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent();
|
||||
const {context} = await launchPersistent();
|
||||
const urls = context.pages().map(page => page.url());
|
||||
expect(urls).toEqual(['about:blank']);
|
||||
});
|
||||
@ -169,21 +169,21 @@ it.skip(options.WIRE)('should have passed URL when launching with ignoreDefaultA
|
||||
await browserContext.close();
|
||||
});
|
||||
|
||||
it.skip(options.WIRE)('should handle timeout', async({browserType, defaultBrowserOptions, tmpDir}) => {
|
||||
it.skip(options.WIRE)('should handle timeout', async ({browserType, defaultBrowserOptions, tmpDir}) => {
|
||||
const options = { ...defaultBrowserOptions, timeout: 5000, __testHookBeforeCreateBrowser: () => new Promise(f => setTimeout(f, 6000)) };
|
||||
const error = await browserType.launchPersistentContext(tmpDir, options).catch(e => e);
|
||||
expect(error.message).toContain(`browserType.launchPersistentContext: Timeout 5000ms exceeded.`);
|
||||
});
|
||||
|
||||
it.skip(options.WIRE)('should handle exception', async({browserType, defaultBrowserOptions, tmpDir}) => {
|
||||
it.skip(options.WIRE)('should handle exception', async ({browserType, defaultBrowserOptions, tmpDir}) => {
|
||||
const e = new Error('Dummy');
|
||||
const options = { ...defaultBrowserOptions, __testHookBeforeCreateBrowser: () => { throw e; } };
|
||||
const error = await browserType.launchPersistentContext(tmpDir, options).catch(e => e);
|
||||
expect(error.message).toContain('Dummy');
|
||||
});
|
||||
|
||||
it('should fire close event for a persistent context', async({launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent();
|
||||
it('should fire close event for a persistent context', async ({launchPersistent}) => {
|
||||
const {context} = await launchPersistent();
|
||||
let closed = false;
|
||||
context.on('close', () => closed = true);
|
||||
await context.close();
|
||||
@ -191,7 +191,7 @@ it('should fire close event for a persistent context', async({launchPersistent})
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('coverage should work', async ({server, launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent();
|
||||
const {page} = await launchPersistent();
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.PREFIX + '/jscoverage/simple.html', { waitUntil: 'load' });
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
@ -201,6 +201,6 @@ it.skip(!options.CHROMIUM)('coverage should work', async ({server, launchPersist
|
||||
});
|
||||
|
||||
it.skip(options.CHROMIUM)('coverage should be missing', async ({launchPersistent}) => {
|
||||
const {page, context} = await launchPersistent();
|
||||
const {page} = await launchPersistent();
|
||||
expect(page.coverage).toBe(null);
|
||||
});
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
it('should fire', async({page, server}) => {
|
||||
it('should fire', async ({page, server}) => {
|
||||
page.on('dialog', dialog => {
|
||||
expect(dialog.type()).toBe('alert');
|
||||
expect(dialog.defaultValue()).toBe('');
|
||||
@ -27,7 +27,7 @@ it('should fire', async({page, server}) => {
|
||||
await page.evaluate(() => alert('yo'));
|
||||
});
|
||||
|
||||
it('should allow accepting prompts', async({page}) => {
|
||||
it('should allow accepting prompts', async ({page}) => {
|
||||
page.on('dialog', dialog => {
|
||||
expect(dialog.type()).toBe('prompt');
|
||||
expect(dialog.defaultValue()).toBe('yes.');
|
||||
@ -38,7 +38,7 @@ it('should allow accepting prompts', async({page}) => {
|
||||
expect(result).toBe('answer!');
|
||||
});
|
||||
|
||||
it('should dismiss the prompt', async({page}) => {
|
||||
it('should dismiss the prompt', async ({page}) => {
|
||||
page.on('dialog', dialog => {
|
||||
dialog.dismiss();
|
||||
});
|
||||
@ -46,7 +46,7 @@ it('should dismiss the prompt', async({page}) => {
|
||||
expect(result).toBe(null);
|
||||
});
|
||||
|
||||
it('should accept the confirm prompt', async({page}) => {
|
||||
it('should accept the confirm prompt', async ({page}) => {
|
||||
page.on('dialog', dialog => {
|
||||
dialog.accept();
|
||||
});
|
||||
@ -54,7 +54,7 @@ it('should accept the confirm prompt', async({page}) => {
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should dismiss the confirm prompt', async({page}) => {
|
||||
it('should dismiss the confirm prompt', async ({page}) => {
|
||||
page.on('dialog', dialog => {
|
||||
dialog.dismiss();
|
||||
});
|
||||
@ -62,7 +62,7 @@ it('should dismiss the confirm prompt', async({page}) => {
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it.fixme(options.WEBKIT && MAC)('should be able to close context with open alert', async({browser}) => {
|
||||
it.fixme(options.WEBKIT && MAC)('should be able to close context with open alert', async ({browser}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const alertPromise = page.waitForEvent('dialog');
|
||||
|
@ -17,13 +17,13 @@ import { options } from './playwright.fixtures';
|
||||
|
||||
import utils from './utils';
|
||||
|
||||
it('should dispatch click event', async({page, server}) => {
|
||||
it('should dispatch click event', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.dispatchEvent('button', 'click');
|
||||
expect(await page.evaluate(() => window['result'])).toBe('Clicked');
|
||||
});
|
||||
|
||||
it('should dispatch click event properties', async({page, server}) => {
|
||||
it('should dispatch click event properties', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.dispatchEvent('button', 'click');
|
||||
expect(await page.evaluate('bubbles')).toBeTruthy();
|
||||
@ -31,7 +31,7 @@ it('should dispatch click event properties', async({page, server}) => {
|
||||
expect(await page.evaluate('composed')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should dispatch click svg', async({page}) => {
|
||||
it('should dispatch click svg', async ({page}) => {
|
||||
await page.setContent(`
|
||||
<svg height="100" width="100">
|
||||
<circle onclick="javascript:window.__CLICKED=42" cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
|
||||
@ -41,7 +41,7 @@ it('should dispatch click svg', async({page}) => {
|
||||
expect(await page.evaluate(() => window['__CLICKED'])).toBe(42);
|
||||
});
|
||||
|
||||
it('should dispatch click on a span with an inline element inside', async({page, server}) => {
|
||||
it('should dispatch click on a span with an inline element inside', async ({page, server}) => {
|
||||
await page.setContent(`
|
||||
<style>
|
||||
span::before {
|
||||
@ -54,7 +54,7 @@ it('should dispatch click on a span with an inline element inside', async({page,
|
||||
expect(await page.evaluate(() => window['CLICKED'])).toBe(42);
|
||||
});
|
||||
|
||||
it('should dispatch click after navigation ', async({page, server}) => {
|
||||
it('should dispatch click after navigation ', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.dispatchEvent('button', 'click');
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
@ -62,7 +62,7 @@ it('should dispatch click after navigation ', async({page, server}) => {
|
||||
expect(await page.evaluate(() => window['result'])).toBe('Clicked');
|
||||
});
|
||||
|
||||
it('should dispatch click after a cross origin navigation ', async({page, server}) => {
|
||||
it('should dispatch click after a cross origin navigation ', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.dispatchEvent('button', 'click');
|
||||
await page.goto(server.CROSS_PROCESS_PREFIX + '/input/button.html');
|
||||
@ -70,7 +70,7 @@ it('should dispatch click after a cross origin navigation ', async({page, server
|
||||
expect(await page.evaluate(() => window['result'])).toBe('Clicked');
|
||||
});
|
||||
|
||||
it('should not fail when element is blocked on hover', async({page, server}) => {
|
||||
it('should not fail when element is blocked on hover', async ({page, server}) => {
|
||||
await page.setContent(`<style>
|
||||
container { display: block; position: relative; width: 200px; height: 50px; }
|
||||
div, button { position: absolute; left: 0; top: 0; bottom: 0; right: 0; }
|
||||
@ -85,7 +85,7 @@ it('should not fail when element is blocked on hover', async({page, server}) =>
|
||||
expect(await page.evaluate(() => window['clicked'])).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should dispatch click when node is added in shadow dom', async({page, server}) => {
|
||||
it('should dispatch click when node is added in shadow dom', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const watchdog = page.dispatchEvent('span', 'click');
|
||||
await page.evaluate(() => {
|
||||
@ -104,13 +104,13 @@ it('should dispatch click when node is added in shadow dom', async({page, server
|
||||
expect(await page.evaluate(() => window['clicked'])).toBe(true);
|
||||
});
|
||||
|
||||
it('should be atomic', async({playwright, page}) => {
|
||||
it('should be atomic', async ({playwright, page}) => {
|
||||
const createDummySelector = () => ({
|
||||
create(root, target) {},
|
||||
query(root, selector) {
|
||||
const result = root.querySelector(selector);
|
||||
if (result)
|
||||
Promise.resolve().then(() => result.onclick = "");
|
||||
Promise.resolve().then(() => result.onclick = '');
|
||||
return result;
|
||||
},
|
||||
queryAll(root: HTMLElement, selector: string) {
|
||||
@ -126,7 +126,7 @@ it('should be atomic', async({playwright, page}) => {
|
||||
expect(await page.evaluate(() => window['_clicked'])).toBe(true);
|
||||
});
|
||||
|
||||
it.fail(options.WEBKIT)('should dispatch drag drop events', async({page, server}) => {
|
||||
it.fail(options.WEBKIT)('should dispatch drag drop events', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/drag-n-drop.html');
|
||||
const dataTransfer = await page.evaluateHandle(() => new DataTransfer());
|
||||
await page.dispatchEvent('#source', 'dragstart', { dataTransfer });
|
||||
@ -138,7 +138,7 @@ it.fail(options.WEBKIT)('should dispatch drag drop events', async({page, server}
|
||||
}, {source, target})).toBeTruthy();
|
||||
});
|
||||
|
||||
it.fail(options.WEBKIT)('should dispatch drag drop events', async({page, server}) => {
|
||||
it.fail(options.WEBKIT)('should dispatch drag drop events', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/drag-n-drop.html');
|
||||
const dataTransfer = await page.evaluateHandle(() => new DataTransfer());
|
||||
const source = await page.$('#source');
|
||||
@ -150,7 +150,7 @@ it.fail(options.WEBKIT)('should dispatch drag drop events', async({page, server}
|
||||
}, {source, target})).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should dispatch click event', async({page, server}) => {
|
||||
it('should dispatch click event', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
const button = await page.$('button');
|
||||
await button.dispatchEvent('click');
|
||||
|
@ -35,7 +35,7 @@ beforeEach(async ({server}) => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should report downloads with acceptDownloads: false', async({page, server}) => {
|
||||
it('should report downloads with acceptDownloads: false', async ({page, server}) => {
|
||||
await page.setContent(`<a href="${server.PREFIX}/downloadWithFilename">download</a>`);
|
||||
const [ download ] = await Promise.all([
|
||||
page.waitForEvent('download'),
|
||||
@ -49,7 +49,7 @@ it('should report downloads with acceptDownloads: false', async({page, server})
|
||||
expect(error.message).toContain('acceptDownloads: true');
|
||||
});
|
||||
|
||||
it('should report downloads with acceptDownloads: true', async({browser, server}) => {
|
||||
it('should report downloads with acceptDownloads: true', async ({browser, server}) => {
|
||||
const page = await browser.newPage({ acceptDownloads: true });
|
||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||
const [ download ] = await Promise.all([
|
||||
@ -62,28 +62,28 @@ it('should report downloads with acceptDownloads: true', async({browser, server}
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should save to user-specified path', async({tmpDir, browser, server}) => {
|
||||
it('should save to user-specified path', async ({tmpDir, browser, server}) => {
|
||||
const page = await browser.newPage({ acceptDownloads: true });
|
||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||
const [ download ] = await Promise.all([
|
||||
page.waitForEvent('download'),
|
||||
page.click('a')
|
||||
]);
|
||||
const userPath = path.join(tmpDir, "download.txt");
|
||||
const userPath = path.join(tmpDir, 'download.txt');
|
||||
await download.saveAs(userPath);
|
||||
expect(fs.existsSync(userPath)).toBeTruthy();
|
||||
expect(fs.readFileSync(userPath).toString()).toBe('Hello world');
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should save to user-specified path without updating original path', async({tmpDir, browser, server}) => {
|
||||
it('should save to user-specified path without updating original path', async ({tmpDir, browser, server}) => {
|
||||
const page = await browser.newPage({ acceptDownloads: true });
|
||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||
const [ download ] = await Promise.all([
|
||||
page.waitForEvent('download'),
|
||||
page.click('a')
|
||||
]);
|
||||
const userPath = path.join(tmpDir, "download.txt");
|
||||
const userPath = path.join(tmpDir, 'download.txt');
|
||||
await download.saveAs(userPath);
|
||||
expect(fs.existsSync(userPath)).toBeTruthy();
|
||||
expect(fs.readFileSync(userPath).toString()).toBe('Hello world');
|
||||
@ -94,33 +94,33 @@ it('should save to user-specified path without updating original path', async({t
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should save to two different paths with multiple saveAs calls', async({tmpDir, browser, server}) => {
|
||||
it('should save to two different paths with multiple saveAs calls', async ({tmpDir, browser, server}) => {
|
||||
const page = await browser.newPage({ acceptDownloads: true });
|
||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||
const [ download ] = await Promise.all([
|
||||
page.waitForEvent('download'),
|
||||
page.click('a')
|
||||
]);
|
||||
const userPath = path.join(tmpDir, "download.txt");
|
||||
const userPath = path.join(tmpDir, 'download.txt');
|
||||
await download.saveAs(userPath);
|
||||
expect(fs.existsSync(userPath)).toBeTruthy();
|
||||
expect(fs.readFileSync(userPath).toString()).toBe('Hello world');
|
||||
|
||||
const anotherUserPath = path.join(tmpDir, "download (2).txt");
|
||||
const anotherUserPath = path.join(tmpDir, 'download (2).txt');
|
||||
await download.saveAs(anotherUserPath);
|
||||
expect(fs.existsSync(anotherUserPath)).toBeTruthy();
|
||||
expect(fs.readFileSync(anotherUserPath).toString()).toBe('Hello world');
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should save to overwritten filepath', async({tmpDir, browser, server}) => {
|
||||
it('should save to overwritten filepath', async ({tmpDir, browser, server}) => {
|
||||
const page = await browser.newPage({ acceptDownloads: true });
|
||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||
const [ download ] = await Promise.all([
|
||||
page.waitForEvent('download'),
|
||||
page.click('a')
|
||||
]);
|
||||
const userPath = path.join(tmpDir, "download.txt");
|
||||
const userPath = path.join(tmpDir, 'download.txt');
|
||||
await download.saveAs(userPath);
|
||||
expect((await util.promisify(fs.readdir)(tmpDir)).length).toBe(1);
|
||||
await download.saveAs(userPath);
|
||||
@ -130,21 +130,21 @@ it('should save to overwritten filepath', async({tmpDir, browser, server}) => {
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should create subdirectories when saving to non-existent user-specified path', async({tmpDir, browser, server}) => {
|
||||
it('should create subdirectories when saving to non-existent user-specified path', async ({tmpDir, browser, server}) => {
|
||||
const page = await browser.newPage({ acceptDownloads: true });
|
||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||
const [ download ] = await Promise.all([
|
||||
page.waitForEvent('download'),
|
||||
page.click('a')
|
||||
]);
|
||||
const nestedPath = path.join(tmpDir, "these", "are", "directories", "download.txt");
|
||||
await download.saveAs(nestedPath)
|
||||
const nestedPath = path.join(tmpDir, 'these', 'are', 'directories', 'download.txt');
|
||||
await download.saveAs(nestedPath);
|
||||
expect(fs.existsSync(nestedPath)).toBeTruthy();
|
||||
expect(fs.readFileSync(nestedPath).toString()).toBe('Hello world');
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it.skip(options.WIRE)('should save when connected remotely', async({tmpDir, server, browserType, remoteServer}) => {
|
||||
it.skip(options.WIRE)('should save when connected remotely', async ({tmpDir, server, browserType, remoteServer}) => {
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const page = await browser.newPage({ acceptDownloads: true });
|
||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||
@ -152,7 +152,7 @@ it.skip(options.WIRE)('should save when connected remotely', async({tmpDir, serv
|
||||
page.waitForEvent('download'),
|
||||
page.click('a')
|
||||
]);
|
||||
const nestedPath = path.join(tmpDir, "these", "are", "directories", "download.txt");
|
||||
const nestedPath = path.join(tmpDir, 'these', 'are', 'directories', 'download.txt');
|
||||
await download.saveAs(nestedPath);
|
||||
expect(fs.existsSync(nestedPath)).toBeTruthy();
|
||||
expect(fs.readFileSync(nestedPath).toString()).toBe('Hello world');
|
||||
@ -161,34 +161,34 @@ it.skip(options.WIRE)('should save when connected remotely', async({tmpDir, serv
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should error when saving with downloads disabled', async({tmpDir, browser, server}) => {
|
||||
it('should error when saving with downloads disabled', async ({tmpDir, browser, server}) => {
|
||||
const page = await browser.newPage({ acceptDownloads: false });
|
||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||
const [ download ] = await Promise.all([
|
||||
page.waitForEvent('download'),
|
||||
page.click('a')
|
||||
]);
|
||||
const userPath = path.join(tmpDir, "download.txt");
|
||||
const userPath = path.join(tmpDir, 'download.txt');
|
||||
const { message } = await download.saveAs(userPath).catch(e => e);
|
||||
expect(message).toContain('Pass { acceptDownloads: true } when you are creating your browser context');
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should error when saving after deletion', async({tmpDir, browser, server}) => {
|
||||
it('should error when saving after deletion', async ({tmpDir, browser, server}) => {
|
||||
const page = await browser.newPage({ acceptDownloads: true });
|
||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||
const [ download ] = await Promise.all([
|
||||
page.waitForEvent('download'),
|
||||
page.click('a')
|
||||
]);
|
||||
const userPath = path.join(tmpDir, "download.txt");
|
||||
const userPath = path.join(tmpDir, 'download.txt');
|
||||
await download.delete();
|
||||
const { message } = await download.saveAs(userPath).catch(e => e);
|
||||
expect(message).toContain('Download already deleted. Save before deleting.');
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it.skip(options.WIRE)('should error when saving after deletion when connected remotely', async({tmpDir, server, browserType, remoteServer}) => {
|
||||
it.skip(options.WIRE)('should error when saving after deletion when connected remotely', async ({tmpDir, server, browserType, remoteServer}) => {
|
||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||
const page = await browser.newPage({ acceptDownloads: true });
|
||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||
@ -196,14 +196,14 @@ it.skip(options.WIRE)('should error when saving after deletion when connected re
|
||||
page.waitForEvent('download'),
|
||||
page.click('a')
|
||||
]);
|
||||
const userPath = path.join(tmpDir, "download.txt");
|
||||
const userPath = path.join(tmpDir, 'download.txt');
|
||||
await download.delete();
|
||||
const { message } = await download.saveAs(userPath).catch(e => e);
|
||||
expect(message).toContain('Download already deleted. Save before deleting.');
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should report non-navigation downloads', async({browser, server}) => {
|
||||
it('should report non-navigation downloads', async ({browser, server}) => {
|
||||
// Mac WebKit embedder does not download in this case, although Safari does.
|
||||
server.setRoute('/download', (req, res) => {
|
||||
res.setHeader('Content-Type', 'application/octet-stream');
|
||||
@ -224,9 +224,9 @@ it('should report non-navigation downloads', async({browser, server}) => {
|
||||
await page.close();
|
||||
});
|
||||
|
||||
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 onDownloadPath = new Promise<string>((res) => {
|
||||
const onDownloadPath = new Promise<string>(res => {
|
||||
page.on('download', dl => {
|
||||
dl.path().then(res);
|
||||
});
|
||||
@ -236,10 +236,10 @@ it(`should report download path within page.on('download', …) handler for File
|
||||
const path = await onDownloadPath;
|
||||
expect(fs.readFileSync(path).toString()).toBe('Hello world');
|
||||
await page.close();
|
||||
})
|
||||
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 onDownloadPath = new Promise<string>((res) => {
|
||||
const onDownloadPath = new Promise<string>(res => {
|
||||
page.on('download', dl => {
|
||||
dl.path().then(res);
|
||||
});
|
||||
@ -249,8 +249,8 @@ it(`should report download path within page.on('download', …) handler for Blob
|
||||
const path = await onDownloadPath;
|
||||
expect(fs.readFileSync(path).toString()).toBe('Hello world');
|
||||
await page.close();
|
||||
})
|
||||
it.fixme(options.FIREFOX || options.WEBKIT)('should report alt-click downloads', async({browser, server}) => {
|
||||
});
|
||||
it.fixme(options.FIREFOX || options.WEBKIT)('should report alt-click downloads', async ({browser, server}) => {
|
||||
// Firefox does not download on alt-click by default.
|
||||
// Our WebKit embedder does not download on alt-click, although Safari does.
|
||||
server.setRoute('/download', (req, res) => {
|
||||
@ -271,7 +271,7 @@ it.fixme(options.FIREFOX || options.WEBKIT)('should report alt-click downloads',
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it.fixme(options.CHROMIUM && !options.HEADLESS)('should report new window downloads', async({browser, server}) => {
|
||||
it.fixme(options.CHROMIUM && !options.HEADLESS)('should report new window downloads', async ({browser, server}) => {
|
||||
// TODO: - the test fails in headful Chromium as the popup page gets closed along
|
||||
// with the session before download completed event arrives.
|
||||
// - WebKit doesn't close the popup page
|
||||
@ -286,7 +286,7 @@ it.fixme(options.CHROMIUM && !options.HEADLESS)('should report new window downlo
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should delete file', async({browser, server}) => {
|
||||
it('should delete file', async ({browser, server}) => {
|
||||
const page = await browser.newPage({ acceptDownloads: true });
|
||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||
const [ download ] = await Promise.all([
|
||||
@ -300,7 +300,7 @@ it('should delete file', async({browser, server}) => {
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should expose stream', async({browser, server}) => {
|
||||
it('should expose stream', async ({browser, server}) => {
|
||||
const page = await browser.newPage({ acceptDownloads: true });
|
||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||
const [ download ] = await Promise.all([
|
||||
@ -315,7 +315,7 @@ it('should expose stream', async({browser, server}) => {
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should delete downloads on context destruction', async({browser, server}) => {
|
||||
it('should delete downloads on context destruction', async ({browser, server}) => {
|
||||
const page = await browser.newPage({ acceptDownloads: true });
|
||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||
const [ download1 ] = await Promise.all([
|
||||
|
@ -54,12 +54,12 @@ registerFixture('persistentDownloadsContext', async ({server, browserType, defau
|
||||
res.end(`Hello world`);
|
||||
});
|
||||
const context = await browserType.launchPersistentContext(
|
||||
userDataDir,
|
||||
{
|
||||
...defaultBrowserOptions,
|
||||
downloadsPath: tmpDir,
|
||||
acceptDownloads: true
|
||||
}
|
||||
userDataDir,
|
||||
{
|
||||
...defaultBrowserOptions,
|
||||
downloadsPath: tmpDir,
|
||||
acceptDownloads: true
|
||||
}
|
||||
);
|
||||
const page = context.pages()[0];
|
||||
page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||
@ -68,7 +68,7 @@ registerFixture('persistentDownloadsContext', async ({server, browserType, defau
|
||||
await removeFolderAsync(userDataDir);
|
||||
});
|
||||
|
||||
it('should keep downloadsPath folder', async({downloadsBrowser, tmpDir, server}) => {
|
||||
it('should keep downloadsPath folder', async ({downloadsBrowser, tmpDir, server}) => {
|
||||
const page = await downloadsBrowser.newPage();
|
||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||
const [ download ] = await Promise.all([
|
||||
@ -83,7 +83,7 @@ it('should keep downloadsPath folder', async({downloadsBrowser, tmpDir, server})
|
||||
expect(fs.existsSync(tmpDir)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should delete downloads when context closes', async({downloadsBrowser, server}) => {
|
||||
it('should delete downloads when context closes', async ({downloadsBrowser, server}) => {
|
||||
const page = await downloadsBrowser.newPage({ acceptDownloads: true });
|
||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||
const [ download ] = await Promise.all([
|
||||
@ -97,7 +97,7 @@ it('should delete downloads when context closes', async({downloadsBrowser, serve
|
||||
|
||||
});
|
||||
|
||||
it('should report downloads in downloadsPath folder', async({downloadsBrowser, tmpDir, server}) => {
|
||||
it('should report downloads in downloadsPath folder', async ({downloadsBrowser, tmpDir, server}) => {
|
||||
const page = await downloadsBrowser.newPage({ acceptDownloads: true });
|
||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||
const [ download ] = await Promise.all([
|
||||
@ -109,7 +109,7 @@ it('should report downloads in downloadsPath folder', async({downloadsBrowser, t
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should accept downloads', async({persistentDownloadsContext, tmpDir, server}) => {
|
||||
it('should accept downloads', async ({persistentDownloadsContext, tmpDir, server}) => {
|
||||
const page = persistentDownloadsContext.pages()[0];
|
||||
const [ download ] = await Promise.all([
|
||||
page.waitForEvent('download'),
|
||||
@ -121,7 +121,7 @@ it('should accept downloads', async({persistentDownloadsContext, tmpDir, server}
|
||||
expect(path.startsWith(tmpDir)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should not delete downloads when the context closes', async({persistentDownloadsContext}) => {
|
||||
it('should not delete downloads when the context closes', async ({persistentDownloadsContext}) => {
|
||||
const page = persistentDownloadsContext.pages()[0];
|
||||
const [ download ] = await Promise.all([
|
||||
page.waitForEvent('download'),
|
||||
|
@ -70,10 +70,10 @@ it.skip(!options.CHROMIUM)('should create multiple windows', async ({ applicatio
|
||||
};
|
||||
|
||||
const page1 = await createPage(1);
|
||||
const page2 = await createPage(2);
|
||||
const page3 = await createPage(3);
|
||||
await createPage(2);
|
||||
await createPage(3);
|
||||
await page1.close();
|
||||
const page4 = await createPage(4);
|
||||
await createPage(4);
|
||||
const titles = [];
|
||||
for (const window of application.windows())
|
||||
titles.push(await window.title());
|
||||
@ -86,7 +86,7 @@ it.skip(!options.CHROMIUM)('should route network', async ({ application }) => {
|
||||
status: 200,
|
||||
contentType: 'text/html',
|
||||
body: '<title>Hello World</title>',
|
||||
})
|
||||
});
|
||||
});
|
||||
const page = await application.newBrowserWindow({ width: 800, height: 600 });
|
||||
await page.goto('https://localhost:1000/empty.html');
|
||||
@ -94,14 +94,13 @@ it.skip(!options.CHROMIUM)('should route network', async ({ application }) => {
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should support init script', async ({ application }) => {
|
||||
await application.context().addInitScript('window.magic = 42;')
|
||||
await application.context().addInitScript('window.magic = 42;');
|
||||
const page = await application.newBrowserWindow({ width: 800, height: 600 });
|
||||
await page.goto('data:text/html,<script>window.copy = magic</script>');
|
||||
expect(await page.evaluate(() => window['copy'])).toBe(42);
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should expose function', async ({ application }) => {
|
||||
const t = Date.now();
|
||||
await application.context().exposeFunction('add', (a, b) => a + b);
|
||||
const page = await application.newBrowserWindow({ width: 800, height: 600 });
|
||||
await page.goto('data:text/html,<script>window["result"] = add(20, 22);</script>');
|
||||
|
@ -17,25 +17,25 @@
|
||||
import { options } from '../playwright.fixtures';
|
||||
import './electron.fixture';
|
||||
|
||||
it.skip(!options.CHROMIUM)('should click the button', async({window, server}) => {
|
||||
it.skip(!options.CHROMIUM)('should click the button', async ({window, server}) => {
|
||||
await window.goto(server.PREFIX + '/input/button.html');
|
||||
await window.click('button');
|
||||
expect(await window.evaluate('result')).toBe('Clicked');
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should check the box', async({window}) => {
|
||||
it.skip(!options.CHROMIUM)('should check the box', async ({window}) => {
|
||||
await window.setContent(`<input id='checkbox' type='checkbox'></input>`);
|
||||
await window.check('input');
|
||||
expect(await window.evaluate('checkbox.checked')).toBe(true);
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should not check the checked box', async({window}) => {
|
||||
it.skip(!options.CHROMIUM)('should not check the checked box', async ({window}) => {
|
||||
await window.setContent(`<input id='checkbox' type='checkbox' checked></input>`);
|
||||
await window.check('input');
|
||||
expect(await window.evaluate('checkbox.checked')).toBe(true);
|
||||
});
|
||||
|
||||
it.skip(!options.CHROMIUM)('should type into a textarea', async({window, server}) => {
|
||||
it.skip(!options.CHROMIUM)('should type into a textarea', async ({window, server}) => {
|
||||
await window.evaluate(() => {
|
||||
const textarea = document.createElement('textarea');
|
||||
document.body.appendChild(textarea);
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { options } from '../playwright.fixtures';
|
||||
import '../playwright.fixtures';
|
||||
import { registerFixture } from '../../test-runner';
|
||||
import type {ElectronApplication, ElectronLauncher, ElectronPage} from '../../electron-types';
|
||||
import path from 'path';
|
||||
@ -29,7 +29,7 @@ declare global {
|
||||
}
|
||||
|
||||
declare module '../../index' {
|
||||
const electron: ElectronLauncher
|
||||
const electron: ElectronLauncher;
|
||||
}
|
||||
|
||||
registerFixture('application', async ({playwright}, test) => {
|
||||
|
@ -17,14 +17,14 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should work', async({page, server}) => {
|
||||
it('should work', async ({page, server}) => {
|
||||
await page.setContent('<html><body><div class="tweet"><div class="like">100</div><div class="retweets">10</div></div></body></html>');
|
||||
const tweet = await page.$('.tweet');
|
||||
const content = await tweet.$eval('.like', node => (node as HTMLElement).innerText);
|
||||
expect(content).toBe('100');
|
||||
});
|
||||
|
||||
it('should retrieve content from subtree', async({page, server}) => {
|
||||
it('should retrieve content from subtree', async ({page, server}) => {
|
||||
const htmlContent = '<div class="a">not-a-child-div</div><div id="myId"><div class="a">a-child-div</div></div>';
|
||||
await page.setContent(htmlContent);
|
||||
const elementHandle = await page.$('#myId');
|
||||
@ -32,7 +32,7 @@ it('should retrieve content from subtree', async({page, server}) => {
|
||||
expect(content).toBe('a-child-div');
|
||||
});
|
||||
|
||||
it('should throw in case of missing selector', async({page, server}) => {
|
||||
it('should throw in case of missing selector', async ({page, server}) => {
|
||||
const htmlContent = '<div class="a">not-a-child-div</div><div id="myId"></div>';
|
||||
await page.setContent(htmlContent);
|
||||
const elementHandle = await page.$('#myId');
|
||||
@ -40,14 +40,14 @@ it('should throw in case of missing selector', async({page, server}) => {
|
||||
expect(errorMessage).toContain(`Error: failed to find element matching selector ".a"`);
|
||||
});
|
||||
|
||||
it('should work for all', async({page, server}) => {
|
||||
it('should work for all', async ({page, server}) => {
|
||||
await page.setContent('<html><body><div class="tweet"><div class="like">100</div><div class="like">10</div></div></body></html>');
|
||||
const tweet = await page.$('.tweet');
|
||||
const content = await tweet.$$eval('.like', nodes => nodes.map(n => (n as HTMLElement).innerText));
|
||||
expect(content).toEqual(['100', '10']);
|
||||
});
|
||||
|
||||
it('should retrieve content from subtree for all', async({page, server}) => {
|
||||
it('should retrieve content from subtree for all', async ({page, server}) => {
|
||||
const htmlContent = '<div class="a">not-a-child-div</div><div id="myId"><div class="a">a1-child-div</div><div class="a">a2-child-div</div></div>';
|
||||
await page.setContent(htmlContent);
|
||||
const elementHandle = await page.$('#myId');
|
||||
@ -55,7 +55,7 @@ it('should retrieve content from subtree for all', async({page, server}) => {
|
||||
expect(content).toEqual(['a1-child-div', 'a2-child-div']);
|
||||
});
|
||||
|
||||
it('should not throw in case of missing selector for all', async({page, server}) => {
|
||||
it('should not throw in case of missing selector for all', async ({page, server}) => {
|
||||
const htmlContent = '<div class="a">not-a-child-div</div><div id="myId"></div>';
|
||||
await page.setContent(htmlContent);
|
||||
const elementHandle = await page.$('#myId');
|
||||
|
@ -78,7 +78,7 @@ it('should work for adopted elements', async ({ page, server }) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const [popup] = await Promise.all([
|
||||
page.waitForEvent('popup'),
|
||||
page.evaluate(url => window["__popup"] = window.open(url), server.EMPTY_PAGE),
|
||||
page.evaluate(url => window['__popup'] = window.open(url), server.EMPTY_PAGE),
|
||||
]);
|
||||
const divHandle = await page.evaluateHandle(() => {
|
||||
const div = document.createElement('div');
|
||||
@ -89,7 +89,7 @@ it('should work for adopted elements', async ({ page, server }) => {
|
||||
await popup.waitForLoadState('domcontentloaded');
|
||||
await page.evaluate(() => {
|
||||
const div = document.querySelector('div');
|
||||
window["__popup"].document.body.appendChild(div);
|
||||
window['__popup'].document.body.appendChild(div);
|
||||
});
|
||||
expect(await divHandle.ownerFrame()).toBe(popup.mainFrame());
|
||||
});
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should query existing element', async({page, server}) => {
|
||||
it('should query existing element', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/playground.html');
|
||||
await page.setContent('<html><body><div class="second"><div class="inner">A</div></div></body></html>');
|
||||
const html = await page.$('html');
|
||||
@ -27,18 +27,18 @@ it('should query existing element', async({page, server}) => {
|
||||
expect(content).toBe('A');
|
||||
});
|
||||
|
||||
it('should return null for non-existing element', async({page, server}) => {
|
||||
it('should return null for non-existing element', async ({page, server}) => {
|
||||
await page.setContent('<html><body><div class="second"><div class="inner">B</div></div></body></html>');
|
||||
const html = await page.$('html');
|
||||
const second = await html.$('.third');
|
||||
expect(second).toBe(null);
|
||||
});
|
||||
|
||||
it('should work for adopted elements', async({page,server}) => {
|
||||
it('should work for adopted elements', async ({page,server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const [popup] = await Promise.all([
|
||||
page.waitForEvent('popup'),
|
||||
page.evaluate(url => window["__popup"] = window.open(url), server.EMPTY_PAGE),
|
||||
page.evaluate(url => window['__popup'] = window.open(url), server.EMPTY_PAGE),
|
||||
]);
|
||||
const divHandle = await page.evaluateHandle(() => {
|
||||
const div = document.createElement('div');
|
||||
@ -54,13 +54,13 @@ it('should work for adopted elements', async({page,server}) => {
|
||||
await popup.waitForLoadState('domcontentloaded');
|
||||
await page.evaluate(() => {
|
||||
const div = document.querySelector('div');
|
||||
window["__popup"].document.body.appendChild(div);
|
||||
window['__popup'].document.body.appendChild(div);
|
||||
});
|
||||
expect(await divHandle.$('span')).toBeTruthy();
|
||||
expect(await divHandle.$eval('span', e => e.textContent)).toBe('hello');
|
||||
});
|
||||
|
||||
it('should query existing elements', async({page, server}) => {
|
||||
it('should query existing elements', async ({page, server}) => {
|
||||
await page.setContent('<html><body><div>A</div><br/><div>B</div></body></html>');
|
||||
const html = await page.$('html');
|
||||
const elements = await html.$$('div');
|
||||
@ -69,7 +69,7 @@ it('should query existing elements', async({page, server}) => {
|
||||
expect(await Promise.all(promises)).toEqual(['A', 'B']);
|
||||
});
|
||||
|
||||
it('should return empty array for non-existing elements', async({page, server}) => {
|
||||
it('should return empty array for non-existing elements', async ({page, server}) => {
|
||||
await page.setContent('<html><body><span>A</span><br/><span>B</span></body></html>');
|
||||
const html = await page.$('html');
|
||||
const elements = await html.$$('div');
|
||||
@ -77,7 +77,7 @@ it('should return empty array for non-existing elements', async({page, server})
|
||||
});
|
||||
|
||||
|
||||
it('xpath should query existing element', async({page, server}) => {
|
||||
it('xpath should query existing element', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/playground.html');
|
||||
await page.setContent('<html><body><div class="second"><div class="inner">A</div></div></body></html>');
|
||||
const html = await page.$('html');
|
||||
@ -87,7 +87,7 @@ it('xpath should query existing element', async({page, server}) => {
|
||||
expect(content).toBe('A');
|
||||
});
|
||||
|
||||
it('xpath should return null for non-existing element', async({page, server}) => {
|
||||
it('xpath should return null for non-existing element', async ({page, server}) => {
|
||||
await page.setContent('<html><body><div class="second"><div class="inner">B</div></div></body></html>');
|
||||
const html = await page.$('html');
|
||||
const second = await html.$$(`xpath=/div[contains(@class, 'third')]`);
|
||||
|
@ -24,7 +24,7 @@ import fs from 'fs';
|
||||
// Firefox headful produces a different image.
|
||||
const ffheadful = options.FIREFOX && !options.HEADLESS;
|
||||
|
||||
it.skip(ffheadful)('should work', async({page, server, golden}) => {
|
||||
it.skip(ffheadful)('should work', async ({page, server, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
await page.evaluate(() => window.scrollBy(50, 100));
|
||||
@ -33,7 +33,7 @@ it.skip(ffheadful)('should work', async({page, server, golden}) => {
|
||||
expect(screenshot).toMatchImage(golden('screenshot-element-bounding-box.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should take into account padding and border', async({page, golden}) => {
|
||||
it.skip(ffheadful)('should take into account padding and border', async ({page, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.setContent(`
|
||||
<div style="height: 14px">oooo</div>
|
||||
@ -51,7 +51,7 @@ it.skip(ffheadful)('should take into account padding and border', async({page, g
|
||||
expect(screenshot).toMatchImage(golden('screenshot-element-padding-border.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should capture full element when larger than viewport in parallel', async({page, golden}) => {
|
||||
it.skip(ffheadful)('should capture full element when larger than viewport in parallel', async ({page, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
|
||||
await page.setContent(`
|
||||
@ -79,7 +79,7 @@ it.skip(ffheadful)('should capture full element when larger than viewport in par
|
||||
await utils.verifyViewport(page, 500, 500);
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should capture full element when larger than viewport', async({page, golden}) => {
|
||||
it.skip(ffheadful)('should capture full element when larger than viewport', async ({page, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
|
||||
await page.setContent(`
|
||||
@ -106,7 +106,7 @@ it.skip(ffheadful)('should capture full element when larger than viewport', asyn
|
||||
await utils.verifyViewport(page, 500, 500);
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should scroll element into view', async({page, golden}) => {
|
||||
it.skip(ffheadful)('should scroll element into view', async ({page, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.setContent(`
|
||||
<div style="height: 14px">oooo</div>
|
||||
@ -130,7 +130,7 @@ it.skip(ffheadful)('should scroll element into view', async({page, golden}) => {
|
||||
expect(screenshot).toMatchImage(golden('screenshot-element-scrolled-into-view.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should scroll 15000px into view', async({page, golden}) => {
|
||||
it.skip(ffheadful)('should scroll 15000px into view', async ({page, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.setContent(`
|
||||
<div style="height: 14px">oooo</div>
|
||||
@ -154,7 +154,7 @@ it.skip(ffheadful)('should scroll 15000px into view', async({page, golden}) => {
|
||||
expect(screenshot).toMatchImage(golden('screenshot-element-scrolled-into-view.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should work with a rotated element', async({page, golden}) => {
|
||||
it.skip(ffheadful)('should work with a rotated element', async ({page, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.setContent(`<div style="position:absolute;
|
||||
top: 100px;
|
||||
@ -168,7 +168,7 @@ it.skip(ffheadful)('should work with a rotated element', async({page, golden}) =
|
||||
expect(screenshot).toMatchImage(golden('screenshot-element-rotate.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should fail to screenshot a detached element', async({page, server}) => {
|
||||
it.skip(ffheadful)('should fail to screenshot a detached element', async ({page, server}) => {
|
||||
await page.setContent('<h1>remove this</h1>');
|
||||
const elementHandle = await page.$('h1');
|
||||
await page.evaluate(element => element.remove(), elementHandle);
|
||||
@ -176,7 +176,7 @@ it.skip(ffheadful)('should fail to screenshot a detached element', async({page,
|
||||
expect(screenshotError.message).toContain('Element is not attached to the DOM');
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should timeout waiting for visible', async({page, server}) => {
|
||||
it.skip(ffheadful)('should timeout waiting for visible', async ({page, server}) => {
|
||||
await page.setContent('<div style="width: 50px; height: 0"></div>');
|
||||
const div = await page.$('div');
|
||||
const error = await div.screenshot({ timeout: 3000 }).catch(e => e);
|
||||
@ -184,7 +184,7 @@ it.skip(ffheadful)('should timeout waiting for visible', async({page, server}) =
|
||||
expect(error.message).toContain('element is not visible');
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should wait for visible', async({page, server, golden}) => {
|
||||
it.skip(ffheadful)('should wait for visible', async ({page, server, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
await page.evaluate(() => window.scrollBy(50, 100));
|
||||
@ -203,14 +203,14 @@ it.skip(ffheadful)('should wait for visible', async({page, server, golden}) => {
|
||||
expect(screenshot).toMatchImage(golden('screenshot-element-bounding-box.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should work for an element with fractional dimensions', async({page, golden}) => {
|
||||
it.skip(ffheadful)('should work for an element with fractional dimensions', async ({page, golden}) => {
|
||||
await page.setContent('<div style="width:48.51px;height:19.8px;border:1px solid black;"></div>');
|
||||
const elementHandle = await page.$('div');
|
||||
const screenshot = await elementHandle.screenshot();
|
||||
expect(screenshot).toMatchImage(golden('screenshot-element-fractional.png'));
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('should work with a mobile viewport', async({browser, server, golden}) => {
|
||||
it.skip(options.FIREFOX)('should work with a mobile viewport', async ({browser, server, golden}) => {
|
||||
const context = await browser.newContext({viewport: { width: 320, height: 480 }, isMobile: true});
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
@ -221,7 +221,7 @@ it.skip(options.FIREFOX)('should work with a mobile viewport', async({browser, s
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('should work with device scale factor', async({browser, server, golden}) => {
|
||||
it.skip(options.FIREFOX)('should work with device scale factor', async ({browser, server, golden}) => {
|
||||
const context = await browser.newContext({ viewport: { width: 320, height: 480 }, deviceScaleFactor: 2 });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
@ -232,14 +232,14 @@ it.skip(options.FIREFOX)('should work with device scale factor', async({browser,
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should work for an element with an offset', async({page, golden}) => {
|
||||
it.skip(ffheadful)('should work for an element with an offset', async ({page, golden}) => {
|
||||
await page.setContent('<div style="position:absolute; top: 10.3px; left: 20.4px;width:50.3px;height:20.2px;border:1px solid black;"></div>');
|
||||
const elementHandle = await page.$('div');
|
||||
const screenshot = await elementHandle.screenshot();
|
||||
expect(screenshot).toMatchImage(golden('screenshot-element-fractional-offset.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should take screenshots when default viewport is null', async({server, browser}) => {
|
||||
it.skip(ffheadful)('should take screenshots when default viewport is null', async ({server, browser}) => {
|
||||
const context = await browser.newContext({ viewport: null });
|
||||
const page = await context.newPage();
|
||||
await page.setContent(`<div style='height: 10000px; background: red'></div>`);
|
||||
@ -258,7 +258,7 @@ it.skip(ffheadful)('should take screenshots when default viewport is null', asyn
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should take fullPage screenshots when default viewport is null', async({server, browser}) => {
|
||||
it.skip(ffheadful)('should take fullPage screenshots when default viewport is null', async ({server, browser}) => {
|
||||
const context = await browser.newContext({ viewport: null });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
@ -274,7 +274,7 @@ it.skip(ffheadful)('should take fullPage screenshots when default viewport is nu
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should restore default viewport after fullPage screenshot', async({ browser }) => {
|
||||
it.skip(ffheadful)('should restore default viewport after fullPage screenshot', async ({ browser }) => {
|
||||
const context = await browser.newContext({ viewport: { width: 456, height: 789 } });
|
||||
const page = await context.newPage();
|
||||
await utils.verifyViewport(page, 456, 789);
|
||||
@ -284,18 +284,18 @@ it.skip(ffheadful)('should restore default viewport after fullPage screenshot',
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(ffheadful || options.WIRE)('should restore viewport after page screenshot and exception', async({ browser, server }) => {
|
||||
it.skip(ffheadful || options.WIRE)('should restore viewport after page screenshot and exception', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ viewport: { width: 350, height: 360 } });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const __testHookBeforeScreenshot = () => { throw new Error('oh my') };
|
||||
const __testHookBeforeScreenshot = () => { throw new Error('oh my'); };
|
||||
const error = await page.screenshot({ fullPage: true, __testHookBeforeScreenshot } as any).catch(e => e);
|
||||
expect(error.message).toContain('oh my');
|
||||
await utils.verifyViewport(page, 350, 360);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(ffheadful || options.WIRE)('should restore viewport after page screenshot and timeout', async({ browser, server }) => {
|
||||
it.skip(ffheadful || options.WIRE)('should restore viewport after page screenshot and timeout', async ({ browser, server }) => {
|
||||
const context = await browser.newContext({ viewport: { width: 350, height: 360 } });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
@ -309,7 +309,7 @@ it.skip(ffheadful || options.WIRE)('should restore viewport after page screensho
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should take element screenshot when default viewport is null and restore back', async({server, browser}) => {
|
||||
it.skip(ffheadful)('should take element screenshot when default viewport is null and restore back', async ({server, browser}) => {
|
||||
const context = await browser.newContext({viewport: null});
|
||||
const page = await context.newPage();
|
||||
await page.setContent(`
|
||||
@ -339,12 +339,12 @@ it.skip(ffheadful)('should take element screenshot when default viewport is null
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(ffheadful || options.WIRE)('should restore viewport after element screenshot and exception', async({server, browser}) => {
|
||||
it.skip(ffheadful || options.WIRE)('should restore viewport after element screenshot and exception', async ({server, browser}) => {
|
||||
const context = await browser.newContext({ viewport: { width: 350, height: 360 } });
|
||||
const page = await context.newPage();
|
||||
await page.setContent(`<div style="width:600px;height:600px;"></div>`);
|
||||
const elementHandle = await page.$('div');
|
||||
const __testHookBeforeScreenshot = () => { throw new Error('oh my') };
|
||||
const __testHookBeforeScreenshot = () => { throw new Error('oh my'); };
|
||||
const error = await elementHandle.screenshot({ __testHookBeforeScreenshot } as any).catch(e => e);
|
||||
expect(error.message).toContain('oh my');
|
||||
await utils.verifyViewport(page, 350, 360);
|
||||
@ -363,7 +363,7 @@ it.skip(ffheadful).flaky(options.WEBKIT && !options.HEADLESS && LINUX)('should w
|
||||
expect(screenshot).toMatchImage(golden('screenshot-element-bounding-box.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should take screenshot of disabled button', async({page}) => {
|
||||
it.skip(ffheadful)('should take screenshot of disabled button', async ({page}) => {
|
||||
await page.setViewportSize({ width: 500, height: 500 });
|
||||
await page.setContent(`<button disabled>Click me</button>`);
|
||||
const button = await page.$('button');
|
||||
@ -371,7 +371,7 @@ it.skip(ffheadful)('should take screenshot of disabled button', async({page}) =>
|
||||
expect(screenshot).toBeInstanceOf(Buffer);
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('path option should create subdirectories', async({page, server, golden, tmpDir}) => {
|
||||
it.skip(ffheadful)('path option should create subdirectories', async ({page, server, golden, tmpDir}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
await page.evaluate(() => window.scrollBy(50, 100));
|
||||
|
@ -16,7 +16,6 @@
|
||||
*/
|
||||
|
||||
import './playwright.fixtures';
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
async function giveItAChanceToResolve(page) {
|
||||
for (let i = 0; i < 5; i++)
|
||||
@ -84,7 +83,7 @@ it('should wait for hidden when detached', async ({ page }) => {
|
||||
await promise;
|
||||
});
|
||||
|
||||
it('should wait for enabled button', async({page, server}) => {
|
||||
it('should wait for enabled button', async ({page, server}) => {
|
||||
await page.setContent('<button disabled><span>Target</span></button>');
|
||||
const span = await page.$('text=Target');
|
||||
let done = false;
|
||||
@ -104,7 +103,7 @@ it('should throw waiting for enabled when detached', async ({ page }) => {
|
||||
expect(error.message).toContain('Element is not attached to the DOM');
|
||||
});
|
||||
|
||||
it('should wait for disabled button', async({page}) => {
|
||||
it('should wait for disabled button', async ({page}) => {
|
||||
await page.setContent('<button><span>Target</span></button>');
|
||||
const span = await page.$('text=Target');
|
||||
let done = false;
|
||||
@ -115,7 +114,7 @@ it('should wait for disabled button', async({page}) => {
|
||||
await promise;
|
||||
});
|
||||
|
||||
it('should wait for stable position', async({page, server}) => {
|
||||
it('should wait for stable position', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
const button = await page.$('button');
|
||||
await page.$eval('button', button => {
|
||||
|
@ -18,18 +18,18 @@
|
||||
import { options } from './playwright.fixtures';
|
||||
import utils from './utils';
|
||||
|
||||
it('should think that it is focused by default', async({page}) => {
|
||||
it('should think that it is focused by default', async ({page}) => {
|
||||
expect(await page.evaluate('document.hasFocus()')).toBe(true);
|
||||
});
|
||||
|
||||
it('should think that all pages are focused', async({page}) => {
|
||||
it('should think that all pages are focused', async ({page}) => {
|
||||
const page2 = await page.context().newPage();
|
||||
expect(await page.evaluate('document.hasFocus()')).toBe(true);
|
||||
expect(await page2.evaluate('document.hasFocus()')).toBe(true);
|
||||
await page2.close();
|
||||
});
|
||||
|
||||
it('should focus popups by default', async({page, server}) => {
|
||||
it('should focus popups by default', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const [popup] = await Promise.all([
|
||||
page.waitForEvent('popup'),
|
||||
@ -39,7 +39,7 @@ it('should focus popups by default', async({page, server}) => {
|
||||
expect(await page.evaluate('document.hasFocus()')).toBe(true);
|
||||
});
|
||||
|
||||
it('should provide target for keyboard events', async({page, server}) => {
|
||||
it('should provide target for keyboard events', async ({page, server}) => {
|
||||
const page2 = await page.context().newPage();
|
||||
await Promise.all([
|
||||
page.goto(server.PREFIX + '/input/textarea.html'),
|
||||
@ -62,7 +62,7 @@ it('should provide target for keyboard events', async({page, server}) => {
|
||||
expect(results).toEqual([text, text2]);
|
||||
});
|
||||
|
||||
it('should not affect mouse event target page', async({page, server}) => {
|
||||
it('should not affect mouse event target page', async ({page, server}) => {
|
||||
const page2 = await page.context().newPage();
|
||||
function clickCounter() {
|
||||
document.onclick = () => window['clickCount'] = (window['clickCount'] || 0) + 1;
|
||||
@ -81,10 +81,10 @@ it('should not affect mouse event target page', async({page, server}) => {
|
||||
page.evaluate('window.clickCount'),
|
||||
page2.evaluate('window.clickCount'),
|
||||
]);
|
||||
expect(counters ).toEqual([1,1]);
|
||||
expect(counters).toEqual([1,1]);
|
||||
});
|
||||
|
||||
it('should change document.activeElement', async({page, server}) => {
|
||||
it('should change document.activeElement', async ({page, server}) => {
|
||||
const page2 = await page.context().newPage();
|
||||
await Promise.all([
|
||||
page.goto(server.PREFIX + '/input/textarea.html'),
|
||||
@ -101,7 +101,7 @@ it('should change document.activeElement', async({page, server}) => {
|
||||
expect(active).toEqual(['INPUT', 'TEXTAREA']);
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX && !options.HEADLESS)('should not affect screenshots', async({page, server, golden}) => {
|
||||
it.skip(options.FIREFOX && !options.HEADLESS)('should not affect screenshots', async ({page, server, golden}) => {
|
||||
// Firefox headful produces a different image.
|
||||
const page2 = await page.context().newPage();
|
||||
await Promise.all([
|
||||
@ -122,7 +122,7 @@ it.skip(options.FIREFOX && !options.HEADLESS)('should not affect screenshots', a
|
||||
expect(screenshots[1]).toMatchImage(golden('grid-cell-0.png'));
|
||||
});
|
||||
|
||||
it('should change focused iframe', async({page, server}) => {
|
||||
it('should change focused iframe', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const [frame1, frame2] = await Promise.all([
|
||||
utils.attachFrame(page, 'frame1', server.PREFIX + '/input/textarea.html'),
|
||||
@ -131,7 +131,7 @@ it('should change focused iframe', async({page, server}) => {
|
||||
function logger() {
|
||||
self['_events'] = [];
|
||||
const element = document.querySelector('input');
|
||||
element.onfocus = element.onblur = (e) => self['_events'].push(e.type);
|
||||
element.onfocus = element.onblur = e => self['_events'].push(e.type);
|
||||
}
|
||||
await Promise.all([
|
||||
frame1.evaluate(logger),
|
||||
|
@ -17,37 +17,37 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should work with css selector', async({page, server}) => {
|
||||
it('should work with css selector', async ({page, server}) => {
|
||||
await page.setContent('<div>hello</div><div>beautiful</div><div>world!</div>');
|
||||
const divsCount = await page.$$eval('css=div', divs => divs.length);
|
||||
expect(divsCount).toBe(3);
|
||||
});
|
||||
|
||||
it('should work with text selector', async({page, server}) => {
|
||||
it('should work with text selector', async ({page, server}) => {
|
||||
await page.setContent('<div>hello</div><div>beautiful</div><div>beautiful</div><div>world!</div>');
|
||||
const divsCount = await page.$$eval('text="beautiful"', divs => divs.length);
|
||||
expect(divsCount).toBe(2);
|
||||
});
|
||||
|
||||
it('should work with xpath selector', async({page, server}) => {
|
||||
it('should work with xpath selector', async ({page, server}) => {
|
||||
await page.setContent('<div>hello</div><div>beautiful</div><div>world!</div>');
|
||||
const divsCount = await page.$$eval('xpath=/html/body/div', divs => divs.length);
|
||||
expect(divsCount).toBe(3);
|
||||
});
|
||||
|
||||
it('should auto-detect css selector', async({page, server}) => {
|
||||
it('should auto-detect css selector', async ({page, server}) => {
|
||||
await page.setContent('<div>hello</div><div>beautiful</div><div>world!</div>');
|
||||
const divsCount = await page.$$eval('div', divs => divs.length);
|
||||
expect(divsCount).toBe(3);
|
||||
});
|
||||
|
||||
it('should support >> syntax', async({page, server}) => {
|
||||
it('should support >> syntax', async ({page, server}) => {
|
||||
await page.setContent('<div><span>hello</span></div><div>beautiful</div><div><span>wo</span><span>rld!</span></div><span>Not this one</span>');
|
||||
const spansCount = await page.$$eval('css=div >> css=span', spans => spans.length);
|
||||
expect(spansCount).toBe(3);
|
||||
});
|
||||
|
||||
it('should support * capture', async({page, server}) => {
|
||||
it('should support * capture', async ({page, server}) => {
|
||||
await page.setContent('<section><div><span>a</span></div></section><section><div><span>b</span></div></section>');
|
||||
expect(await page.$$eval('*css=div >> "b"', els => els.length)).toBe(1);
|
||||
expect(await page.$$eval('section >> *css=div >> "b"', els => els.length)).toBe(1);
|
||||
@ -62,14 +62,14 @@ it('should support * capture', async({page, server}) => {
|
||||
expect(await page.$$eval('section >> *css=div >> "a"', els => els.length)).toBe(1);
|
||||
});
|
||||
|
||||
it('should support * capture when multiple paths match', async({page, server}) => {
|
||||
it('should support * capture when multiple paths match', async ({page, server}) => {
|
||||
await page.setContent('<div><div><span></span></div></div><div></div>');
|
||||
expect(await page.$$eval('*css=div >> span', els => els.length)).toBe(2);
|
||||
await page.setContent('<div><div><span></span></div><span></span><span></span></div><div></div>');
|
||||
expect(await page.$$eval('*css=div >> span', els => els.length)).toBe(2);
|
||||
});
|
||||
|
||||
it('should return complex values', async({page, server}) => {
|
||||
it('should return complex values', async ({page, server}) => {
|
||||
await page.setContent('<div>hello</div><div>beautiful</div><div>world!</div>');
|
||||
const texts = await page.$$eval('css=div', divs => divs.map(div => div.textContent));
|
||||
expect(texts).toEqual(['hello', 'beautiful', 'world!']);
|
||||
|
@ -17,116 +17,116 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should work with css selector', async({page, server}) => {
|
||||
it('should work with css selector', async ({page, server}) => {
|
||||
await page.setContent('<section id="testAttribute">43543</section>');
|
||||
const idAttribute = await page.$eval('css=section', e => e.id);
|
||||
expect(idAttribute).toBe('testAttribute');
|
||||
});
|
||||
|
||||
it('should work with id selector', async({page, server}) => {
|
||||
it('should work with id selector', async ({page, server}) => {
|
||||
await page.setContent('<section id="testAttribute">43543</section>');
|
||||
const idAttribute = await page.$eval('id=testAttribute', e => e.id);
|
||||
expect(idAttribute).toBe('testAttribute');
|
||||
});
|
||||
|
||||
it('should work with data-test selector', async({page, server}) => {
|
||||
it('should work with data-test selector', async ({page, server}) => {
|
||||
await page.setContent('<section data-test=foo id="testAttribute">43543</section>');
|
||||
const idAttribute = await page.$eval('data-test=foo', e => e.id);
|
||||
expect(idAttribute).toBe('testAttribute');
|
||||
});
|
||||
|
||||
it('should work with data-testid selector', async({page, server}) => {
|
||||
it('should work with data-testid selector', async ({page, server}) => {
|
||||
await page.setContent('<section data-testid=foo id="testAttribute">43543</section>');
|
||||
const idAttribute = await page.$eval('data-testid=foo', e => e.id);
|
||||
expect(idAttribute).toBe('testAttribute');
|
||||
});
|
||||
|
||||
it('should work with data-test-id selector', async({page, server}) => {
|
||||
it('should work with data-test-id selector', async ({page, server}) => {
|
||||
await page.setContent('<section data-test-id=foo id="testAttribute">43543</section>');
|
||||
const idAttribute = await page.$eval('data-test-id=foo', e => e.id);
|
||||
expect(idAttribute).toBe('testAttribute');
|
||||
});
|
||||
|
||||
it('should work with text selector', async({page, server}) => {
|
||||
it('should work with text selector', async ({page, server}) => {
|
||||
await page.setContent('<section id="testAttribute">43543</section>');
|
||||
const idAttribute = await page.$eval('text="43543"', e => e.id);
|
||||
expect(idAttribute).toBe('testAttribute');
|
||||
});
|
||||
|
||||
it('should work with xpath selector', async({page, server}) => {
|
||||
it('should work with xpath selector', async ({page, server}) => {
|
||||
await page.setContent('<section id="testAttribute">43543</section>');
|
||||
const idAttribute = await page.$eval('xpath=/html/body/section', e => e.id);
|
||||
expect(idAttribute).toBe('testAttribute');
|
||||
});
|
||||
|
||||
it('should work with text selector', async({page, server}) => {
|
||||
it('should work with text selector', async ({page, server}) => {
|
||||
await page.setContent('<section id="testAttribute">43543</section>');
|
||||
const idAttribute = await page.$eval('text=43543', e => e.id);
|
||||
expect(idAttribute).toBe('testAttribute');
|
||||
});
|
||||
|
||||
it('should auto-detect css selector', async({page, server}) => {
|
||||
it('should auto-detect css selector', async ({page, server}) => {
|
||||
await page.setContent('<section id="testAttribute">43543</section>');
|
||||
const idAttribute = await page.$eval('section', e => e.id);
|
||||
expect(idAttribute).toBe('testAttribute');
|
||||
});
|
||||
|
||||
it('should auto-detect css selector with attributes', async({page, server}) => {
|
||||
it('should auto-detect css selector with attributes', async ({page, server}) => {
|
||||
await page.setContent('<section id="testAttribute">43543</section>');
|
||||
const idAttribute = await page.$eval('section[id="testAttribute"]', e => e.id);
|
||||
expect(idAttribute).toBe('testAttribute');
|
||||
});
|
||||
|
||||
it('should auto-detect nested selectors', async({page, server}) => {
|
||||
it('should auto-detect nested selectors', async ({page, server}) => {
|
||||
await page.setContent('<div foo=bar><section>43543<span>Hello<div id=target></div></span></section></div>');
|
||||
const idAttribute = await page.$eval('div[foo=bar] > section >> "Hello" >> div', e => e.id);
|
||||
expect(idAttribute).toBe('target');
|
||||
});
|
||||
|
||||
it('should accept arguments', async({page, server}) => {
|
||||
it('should accept arguments', async ({page, server}) => {
|
||||
await page.setContent('<section>hello</section>');
|
||||
const text = await page.$eval('section', (e, suffix) => e.textContent + suffix, ' world!');
|
||||
expect(text).toBe('hello world!');
|
||||
});
|
||||
|
||||
it('should accept ElementHandles as arguments', async({page, server}) => {
|
||||
it('should accept ElementHandles as arguments', async ({page, server}) => {
|
||||
await page.setContent('<section>hello</section><div> world</div>');
|
||||
const divHandle = await page.$('div');
|
||||
const text = await page.$eval('section', (e, div) => e.textContent + div.textContent, divHandle);
|
||||
expect(text).toBe('hello world');
|
||||
});
|
||||
|
||||
it('should throw error if no element is found', async({page, server}) => {
|
||||
it('should throw error if no element is found', async ({page, server}) => {
|
||||
let error = null;
|
||||
await page.$eval('section', e => e.id).catch(e => error = e);
|
||||
expect(error.message).toContain('failed to find element matching selector "section"');
|
||||
});
|
||||
|
||||
it('should support >> syntax', async({page, server}) => {
|
||||
it('should support >> syntax', async ({page, server}) => {
|
||||
await page.setContent('<section><div>hello</div></section>');
|
||||
const text = await page.$eval('css=section >> css=div', (e, suffix) => e.textContent + suffix, ' world!');
|
||||
expect(text).toBe('hello world!');
|
||||
});
|
||||
|
||||
it('should support >> syntax with different engines', async({page, server}) => {
|
||||
it('should support >> syntax with different engines', async ({page, server}) => {
|
||||
await page.setContent('<section><div><span>hello</span></div></section>');
|
||||
const text = await page.$eval('xpath=/html/body/section >> css=div >> text="hello"', (e, suffix) => e.textContent + suffix, ' world!');
|
||||
expect(text).toBe('hello world!');
|
||||
});
|
||||
|
||||
it('should support spaces with >> syntax', async({page, server}) => {
|
||||
it('should support spaces with >> syntax', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/deep-shadow.html');
|
||||
const text = await page.$eval(' css = div >>css=div>>css = span ', e => e.textContent);
|
||||
expect(text).toBe('Hello from root2');
|
||||
});
|
||||
|
||||
it('should not stop at first failure with >> syntax', async({page, server}) => {
|
||||
it('should not stop at first failure with >> syntax', async ({page, server}) => {
|
||||
await page.setContent('<div><span>Next</span><button>Previous</button><button>Next</button></div>');
|
||||
const html = await page.$eval('button >> "Next"', e => e.outerHTML);
|
||||
expect(html).toBe('<button>Next</button>');
|
||||
});
|
||||
|
||||
it('should support * capture', async({page, server}) => {
|
||||
it('should support * capture', async ({page, server}) => {
|
||||
await page.setContent('<section><div><span>a</span></div></section><section><div><span>b</span></div></section>');
|
||||
expect(await page.$eval('*css=div >> "b"', e => e.outerHTML)).toBe('<div><span>b</span></div>');
|
||||
expect(await page.$eval('section >> *css=div >> "b"', e => e.outerHTML)).toBe('<div><span>b</span></div>');
|
||||
@ -134,17 +134,17 @@ it('should support * capture', async({page, server}) => {
|
||||
expect(await page.$('*')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should throw on multiple * captures', async({page, server}) => {
|
||||
it('should throw on multiple * captures', async ({page, server}) => {
|
||||
const error = await page.$eval('*css=div >> *css=span', e => e.outerHTML).catch(e => e);
|
||||
expect(error.message).toContain('Only one of the selectors can capture using * modifier');
|
||||
});
|
||||
|
||||
it('should throw on malformed * capture', async({page, server}) => {
|
||||
it('should throw on malformed * capture', async ({page, server}) => {
|
||||
const error = await page.$eval('*=div', e => e.outerHTML).catch(e => e);
|
||||
expect(error.message).toContain('Unknown engine "" while parsing selector *=div');
|
||||
});
|
||||
|
||||
it('should work with spaces in css attributes', async({page, server}) => {
|
||||
it('should work with spaces in css attributes', async ({page, server}) => {
|
||||
await page.setContent('<div><input placeholder="Select date"></div>');
|
||||
expect(await page.waitForSelector(`[placeholder="Select date"]`)).toBeTruthy();
|
||||
expect(await page.waitForSelector(`[placeholder='Select date']`)).toBeTruthy();
|
||||
@ -166,7 +166,7 @@ it('should work with spaces in css attributes', async({page, server}) => {
|
||||
expect(await page.$eval(`div >> [placeholder='Select date']`, e => e.outerHTML)).toBe('<input placeholder="Select date">');
|
||||
});
|
||||
|
||||
it('should work with quotes in css attributes', async({page, server}) => {
|
||||
it('should work with quotes in css attributes', async ({page, server}) => {
|
||||
await page.setContent('<div><input placeholder="Select"date"></div>');
|
||||
expect(await page.$(`[placeholder="Select\\"date"]`)).toBeTruthy();
|
||||
expect(await page.$(`[placeholder='Select"date']`)).toBeTruthy();
|
||||
@ -181,21 +181,21 @@ it('should work with quotes in css attributes', async({page, server}) => {
|
||||
expect(await page.$(`[placeholder='Select \\' date']`)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should work with spaces in css attributes when missing', async({page, server}) => {
|
||||
it('should work with spaces in css attributes when missing', async ({page, server}) => {
|
||||
const inputPromise = page.waitForSelector(`[placeholder="Select date"]`);
|
||||
expect(await page.$(`[placeholder="Select date"]`)).toBe(null);
|
||||
await page.setContent('<div><input placeholder="Select date"></div>');
|
||||
await inputPromise;
|
||||
});
|
||||
|
||||
it('should work with quotes in css attributes when missing', async({page, server}) => {
|
||||
it('should work with quotes in css attributes when missing', async ({page, server}) => {
|
||||
const inputPromise = page.waitForSelector(`[placeholder="Select\\"date"]`);
|
||||
expect(await page.$(`[placeholder="Select\\"date"]`)).toBe(null);
|
||||
await page.setContent('<div><input placeholder="Select"date"></div>');
|
||||
await inputPromise;
|
||||
});
|
||||
|
||||
it('should return complex values', async({page, server}) => {
|
||||
it('should return complex values', async ({page, server}) => {
|
||||
await page.setContent('<section id="testAttribute">43543</section>');
|
||||
const idAttribute = await page.$eval('css=section', e => [{ id: e.id }]);
|
||||
expect(idAttribute).toEqual([{ id: 'testAttribute' }]);
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
import { options } from '../playwright.fixtures';
|
||||
|
||||
it.skip(!options.FIREFOX)('should pass firefox user preferences', async({browserType, defaultBrowserOptions}) => {
|
||||
it.skip(!options.FIREFOX)('should pass firefox user preferences', async ({browserType, defaultBrowserOptions}) => {
|
||||
const browser = await browserType.launch({
|
||||
...defaultBrowserOptions,
|
||||
firefoxUserPrefs: {
|
||||
|
@ -52,9 +52,9 @@ it('should traverse focus', async function({page}) {
|
||||
await page.$eval('#i2', i2 => (i2 as HTMLInputElement).addEventListener('focus', window['focusEvent']));
|
||||
|
||||
await page.focus('#i1');
|
||||
await page.keyboard.type("First");
|
||||
await page.keyboard.press("Tab");
|
||||
await page.keyboard.type("Last");
|
||||
await page.keyboard.type('First');
|
||||
await page.keyboard.press('Tab');
|
||||
await page.keyboard.type('Last');
|
||||
|
||||
expect(focused).toBe(true);
|
||||
expect(await page.$eval('#i1', e => (e as HTMLInputElement).value)).toBe('First');
|
||||
@ -75,7 +75,7 @@ it('should traverse focus in all directions', async function({page}) {
|
||||
expect(await page.evaluate(() => (document.activeElement as HTMLInputElement).value)).toBe('1');
|
||||
});
|
||||
|
||||
// Chromium and WebKit both have settings for tab traversing all links, but
|
||||
// Chromium and WebKit both have settings for tab traversing all links, but
|
||||
// it is only on by default in WebKit.
|
||||
it.skip(!MAC || !options.WEBKIT)('should traverse only form elements', async function({page}) {
|
||||
await page.setContent(`
|
||||
|
@ -22,10 +22,10 @@ it('should have different execution contexts', async ({ page, server }) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||
expect(page.frames().length).toBe(2);
|
||||
await page.frames()[0].evaluate(() => window["FOO"] = 'foo');
|
||||
await page.frames()[1].evaluate(() => window["FOO"] = 'bar');
|
||||
expect(await page.frames()[0].evaluate(() => window["FOO"])).toBe('foo');
|
||||
expect(await page.frames()[1].evaluate(() => window["FOO"])).toBe('bar');
|
||||
await page.frames()[0].evaluate(() => window['FOO'] = 'foo');
|
||||
await page.frames()[1].evaluate(() => window['FOO'] = 'bar');
|
||||
expect(await page.frames()[0].evaluate(() => window['FOO'])).toBe('foo');
|
||||
expect(await page.frames()[1].evaluate(() => window['FOO'])).toBe('bar');
|
||||
});
|
||||
|
||||
it('should have correct execution contexts', async ({ page, server }) => {
|
||||
@ -99,7 +99,7 @@ it('should not allow cross-frame element handles when frames do not script each
|
||||
expect(error.message).toContain('Unable to adopt element handle from a different document');
|
||||
});
|
||||
|
||||
it('should throw for detached frames', async({page, server}) => {
|
||||
it('should throw for detached frames', async ({page, server}) => {
|
||||
const frame1 = await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||
await utils.detachFrame(page, 'frame1');
|
||||
let error = null;
|
||||
@ -107,7 +107,7 @@ it('should throw for detached frames', async({page, server}) => {
|
||||
expect(error.message).toContain('Execution Context is not available in detached frame');
|
||||
});
|
||||
|
||||
it('should be isolated between frames', async({page, server}) => {
|
||||
it('should be isolated between frames', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||
expect(page.frames().length).toBe(2);
|
||||
@ -115,8 +115,8 @@ it('should be isolated between frames', async({page, server}) => {
|
||||
expect(frame1 !== frame2).toBeTruthy();
|
||||
|
||||
await Promise.all([
|
||||
frame1.evaluate(() => window["a"] = 1),
|
||||
frame2.evaluate(() => window["a"] = 2)
|
||||
frame1.evaluate(() => window['a'] = 1),
|
||||
frame2.evaluate(() => window['a'] = 2)
|
||||
]);
|
||||
const [a1, a2] = await Promise.all([
|
||||
frame1.evaluate(() => window['a']),
|
||||
@ -126,7 +126,7 @@ it('should be isolated between frames', async({page, server}) => {
|
||||
expect(a2).toBe(2);
|
||||
});
|
||||
|
||||
it.fail(options.CHROMIUM || options.FIREFOX)('should work in iframes that failed initial navigation', async({page, server}) => {
|
||||
it.fail(options.CHROMIUM || options.FIREFOX)('should work in iframes that failed initial navigation', async ({page, server}) => {
|
||||
// - Firefox does not report domcontentloaded for the iframe.
|
||||
// - Chromium and Firefox report empty url.
|
||||
// - Chromium does not report main/utility worlds for the iframe.
|
||||
@ -147,7 +147,7 @@ it.fail(options.CHROMIUM || options.FIREFOX)('should work in iframes that failed
|
||||
expect(await page.frames()[1].$('div')).toBeTruthy();
|
||||
});
|
||||
|
||||
it.fixme(options.CHROMIUM)('should work in iframes that interrupted initial javascript url navigation', async({page, server}) => {
|
||||
it.fixme(options.CHROMIUM)('should work in iframes that interrupted initial javascript url navigation', async ({page, server}) => {
|
||||
// Chromium does not report isolated world for the iframe.
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.evaluate(() => {
|
||||
@ -164,7 +164,7 @@ it.fixme(options.CHROMIUM)('should work in iframes that interrupted initial java
|
||||
expect(await page.frames()[1].$('div')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('evaluateHandle should work', async({page, server}) => {
|
||||
it('evaluateHandle should work', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const mainFrame = page.mainFrame();
|
||||
const windowHandle = await mainFrame.evaluateHandle(() => window);
|
||||
|
@ -19,10 +19,10 @@ import './playwright.fixtures';
|
||||
|
||||
import utils from './utils';
|
||||
|
||||
it('should work', async({page, server}) => {
|
||||
it('should work', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const frame1 = await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||
const frame2 = await utils.attachFrame(page, 'frame2', server.EMPTY_PAGE);
|
||||
await utils.attachFrame(page, 'frame2', server.EMPTY_PAGE);
|
||||
const frame3 = await utils.attachFrame(page, 'frame3', server.EMPTY_PAGE);
|
||||
const frame1handle1 = await page.$('#frame1');
|
||||
const frame1handle2 = await frame1.frameElement();
|
||||
@ -33,7 +33,7 @@ it('should work', async({page, server}) => {
|
||||
expect(await frame1handle1.evaluate((a, b) => a === b, frame3handle1)).toBe(false);
|
||||
});
|
||||
|
||||
it('should work with contentFrame', async({page, server}) => {
|
||||
it('should work with contentFrame', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const frame = await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||
const handle = await frame.frameElement();
|
||||
@ -41,7 +41,7 @@ it('should work with contentFrame', async({page, server}) => {
|
||||
expect(contentFrame).toBe(frame);
|
||||
});
|
||||
|
||||
it('should throw when detached', async({page, server}) => {
|
||||
it('should throw when detached', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const frame1 = await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||
await page.$eval('#frame1', e => e.remove());
|
||||
|
@ -19,7 +19,7 @@ import './playwright.fixtures';
|
||||
|
||||
import utils from './utils';
|
||||
|
||||
it('should navigate subframes', async({page, server}) => {
|
||||
it('should navigate subframes', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/frames/one-frame.html');
|
||||
expect(page.frames()[0].url()).toContain('/frames/one-frame.html');
|
||||
expect(page.frames()[1].url()).toContain('/frames/frame.html');
|
||||
@ -29,7 +29,7 @@ it('should navigate subframes', async({page, server}) => {
|
||||
expect(response.frame()).toBe(page.frames()[1]);
|
||||
});
|
||||
|
||||
it('should reject when frame detaches', async({page, server}) => {
|
||||
it('should reject when frame detaches', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/frames/one-frame.html');
|
||||
|
||||
server.setRoute('/empty.html', () => {});
|
||||
@ -41,7 +41,7 @@ it('should reject when frame detaches', async({page, server}) => {
|
||||
expect(error.message).toContain('frame was detached');
|
||||
});
|
||||
|
||||
it('should continue after client redirect', async({page, server}) => {
|
||||
it('should continue after client redirect', async ({page, server}) => {
|
||||
server.setRoute('/frames/script.js', () => {});
|
||||
const url = server.PREFIX + '/frames/child-redirect.html';
|
||||
const error = await page.goto(url, { timeout: 5000, waitUntil: 'networkidle' }).catch(e => e);
|
||||
@ -49,7 +49,7 @@ it('should continue after client redirect', async({page, server}) => {
|
||||
expect(error.message).toContain(`navigating to "${url}", waiting until "networkidle"`);
|
||||
});
|
||||
|
||||
it('should return matching responses', async({page, server}) => {
|
||||
it('should return matching responses', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
// Attach three frames.
|
||||
const frames = [
|
||||
|
@ -17,7 +17,7 @@
|
||||
import { options } from './playwright.fixtures';
|
||||
import utils from './utils';
|
||||
|
||||
it('should handle nested frames', async({page, server}) => {
|
||||
it('should handle nested frames', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/frames/nested-frames.html');
|
||||
expect(utils.dumpFrames(page.mainFrame())).toEqual([
|
||||
'http://localhost:<PORT>/frames/nested-frames.html',
|
||||
@ -28,7 +28,7 @@ it('should handle nested frames', async({page, server}) => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should send events when frames are manipulated dynamically', async({page, server}) => {
|
||||
it('should send events when frames are manipulated dynamically', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
// validate frameattached events
|
||||
const attachedFrames = [];
|
||||
@ -56,7 +56,7 @@ it('should send events when frames are manipulated dynamically', async({page, se
|
||||
expect(detachedFrames[0].isDetached()).toBe(true);
|
||||
});
|
||||
|
||||
it('should send "framenavigated" when navigating on anchor URLs', async({page, server}) => {
|
||||
it('should send "framenavigated" when navigating on anchor URLs', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await Promise.all([
|
||||
page.goto(server.EMPTY_PAGE + '#foo'),
|
||||
@ -65,14 +65,14 @@ it('should send "framenavigated" when navigating on anchor URLs', async({page, s
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE + '#foo');
|
||||
});
|
||||
|
||||
it('should persist mainFrame on cross-process navigation', async({page, server}) => {
|
||||
it('should persist mainFrame on cross-process navigation', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const mainFrame = page.mainFrame();
|
||||
await page.goto(server.CROSS_PROCESS_PREFIX + '/empty.html');
|
||||
expect(page.mainFrame() === mainFrame).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should not send attach/detach events for main frame', async({page, server}) => {
|
||||
it('should not send attach/detach events for main frame', async ({page, server}) => {
|
||||
let hasEvents = false;
|
||||
page.on('frameattached', frame => hasEvents = true);
|
||||
page.on('framedetached', frame => hasEvents = true);
|
||||
@ -80,7 +80,7 @@ it('should not send attach/detach events for main frame', async({page, server})
|
||||
expect(hasEvents).toBe(false);
|
||||
});
|
||||
|
||||
it('should detach child frames on navigation', async({page, server}) => {
|
||||
it('should detach child frames on navigation', async ({page, server}) => {
|
||||
let attachedFrames = [];
|
||||
let detachedFrames = [];
|
||||
let navigatedFrames = [];
|
||||
@ -101,7 +101,7 @@ it('should detach child frames on navigation', async({page, server}) => {
|
||||
expect(navigatedFrames.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should support framesets', async({page, server}) => {
|
||||
it('should support framesets', async ({page, server}) => {
|
||||
let attachedFrames = [];
|
||||
let detachedFrames = [];
|
||||
let navigatedFrames = [];
|
||||
@ -122,7 +122,7 @@ it('should support framesets', async({page, server}) => {
|
||||
expect(navigatedFrames.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should report frame from-inside shadow DOM', async({page, server}) => {
|
||||
it('should report frame from-inside shadow DOM', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/shadow.html');
|
||||
await page.evaluate(async url => {
|
||||
const frame = document.createElement('iframe');
|
||||
@ -134,7 +134,7 @@ it('should report frame from-inside shadow DOM', async({page, server}) => {
|
||||
expect(page.frames()[1].url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
|
||||
it('should report frame.name()', async({page, server}) => {
|
||||
it('should report frame.name()', async ({page, server}) => {
|
||||
await utils.attachFrame(page, 'theFrameId', server.EMPTY_PAGE);
|
||||
await page.evaluate(url => {
|
||||
const frame = document.createElement('iframe');
|
||||
@ -148,7 +148,7 @@ it('should report frame.name()', async({page, server}) => {
|
||||
expect(page.frames()[2].name()).toBe('theFrameName');
|
||||
});
|
||||
|
||||
it('should report frame.parent()', async({page, server}) => {
|
||||
it('should report frame.parent()', async ({page, server}) => {
|
||||
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||
await utils.attachFrame(page, 'frame2', server.EMPTY_PAGE);
|
||||
expect(page.frames()[0].parentFrame()).toBe(null);
|
||||
@ -156,7 +156,7 @@ it('should report frame.parent()', async({page, server}) => {
|
||||
expect(page.frames()[2].parentFrame()).toBe(page.mainFrame());
|
||||
});
|
||||
|
||||
it('should report different frame instance when frame re-attaches', async({page, server}) => {
|
||||
it('should report different frame instance when frame re-attaches', async ({page, server}) => {
|
||||
const frame1 = await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||
await page.evaluate(() => {
|
||||
window['frame'] = document.querySelector('#frame1');
|
||||
@ -171,7 +171,7 @@ it('should report different frame instance when frame re-attaches', async({page,
|
||||
expect(frame1).not.toBe(frame2);
|
||||
});
|
||||
|
||||
it.fixme(options.FIREFOX)('should refuse to display x-frame-options:deny iframe', async({page, server}) => {
|
||||
it.fixme(options.FIREFOX)('should refuse to display x-frame-options:deny iframe', async ({page, server}) => {
|
||||
server.setRoute('/x-frame-options-deny.html', async (req, res) => {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.setHeader('X-Frame-Options', 'DENY');
|
||||
@ -185,10 +185,10 @@ it.fixme(options.FIREFOX)('should refuse to display x-frame-options:deny iframe'
|
||||
});
|
||||
});
|
||||
await page.setContent(`<iframe src="${server.CROSS_PROCESS_PREFIX}/x-frame-options-deny.html"></iframe>`);
|
||||
expect(await refusalText).toMatch(/Refused to display 'http.*\/x-frame-options-deny\.html' in a frame because it set 'X-Frame-Options' to 'deny'./i)
|
||||
expect(await refusalText).toMatch(/Refused to display 'http.*\/x-frame-options-deny\.html' in a frame because it set 'X-Frame-Options' to 'deny'./i);
|
||||
});
|
||||
|
||||
it('should return frame.page()', async({page, server}) => {
|
||||
it('should return frame.page()', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/frames/one-frame.html');
|
||||
expect(page.mainFrame().page()).toBe(page);
|
||||
expect(page.mainFrame().childFrames()[0].page()).toBe(page);
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should work', async({page, server, context}) => {
|
||||
it('should work', async ({page, server, context}) => {
|
||||
await context.grantPermissions(['geolocation']);
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await context.setGeolocation({longitude: 10, latitude: 10});
|
||||
@ -30,7 +30,7 @@ it('should work', async({page, server, context}) => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when invalid longitude', async({context}) => {
|
||||
it('should throw when invalid longitude', async ({context}) => {
|
||||
let error = null;
|
||||
try {
|
||||
await context.setGeolocation({longitude: 200, latitude: 10});
|
||||
@ -40,7 +40,7 @@ it('should throw when invalid longitude', async({context}) => {
|
||||
expect(error.message).toContain('geolocation.longitude: precondition -180 <= LONGITUDE <= 180 failed.');
|
||||
});
|
||||
|
||||
it('should isolate contexts', async({page, server, context, browser}) => {
|
||||
it('should isolate contexts', async ({page, server, context, browser}) => {
|
||||
await context.grantPermissions(['geolocation']);
|
||||
await context.setGeolocation({longitude: 10, latitude: 10});
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -71,7 +71,7 @@ it('should isolate contexts', async({page, server, context, browser}) => {
|
||||
await context2.close();
|
||||
});
|
||||
|
||||
it('should throw with missing latitude', async({context}) => {
|
||||
it('should throw with missing latitude', async ({context}) => {
|
||||
let error = null;
|
||||
try {
|
||||
await context.setGeolocation({longitude: 10} as any);
|
||||
@ -81,7 +81,7 @@ it('should throw with missing latitude', async({context}) => {
|
||||
expect(error.message).toContain('geolocation.latitude: expected number, got undefined');
|
||||
});
|
||||
|
||||
it('should not modify passed default options object', async({browser}) => {
|
||||
it('should not modify passed default options object', async ({browser}) => {
|
||||
const geolocation = { longitude: 10, latitude: 10 };
|
||||
const options = { geolocation };
|
||||
const context = await browser.newContext(options);
|
||||
@ -90,7 +90,7 @@ it('should not modify passed default options object', async({browser}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should throw with missing longitude in default options', async({browser}) => {
|
||||
it('should throw with missing longitude in default options', async ({browser}) => {
|
||||
let error = null;
|
||||
try {
|
||||
const context = await browser.newContext({ geolocation: {latitude: 10} as any });
|
||||
@ -101,7 +101,7 @@ it('should throw with missing longitude in default options', async({browser}) =>
|
||||
expect(error.message).toContain('geolocation.longitude: expected number, got undefined');
|
||||
});
|
||||
|
||||
it('should use context options', async({browser, server}) => {
|
||||
it('should use context options', async ({browser, server}) => {
|
||||
const options = { geolocation: { longitude: 10, latitude: 10 }, permissions: ['geolocation'] };
|
||||
const context = await browser.newContext(options);
|
||||
const page = await context.newPage();
|
||||
@ -117,7 +117,7 @@ it('should use context options', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('watchPosition should be notified', async({page, server, context}) => {
|
||||
it('watchPosition should be notified', async ({page, server, context}) => {
|
||||
await context.grantPermissions(['geolocation']);
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const messages = [];
|
||||
@ -143,12 +143,12 @@ it('watchPosition should be notified', async({page, server, context}) => {
|
||||
expect(allMessages).toContain('lat=40 lng=50');
|
||||
});
|
||||
|
||||
it('should use context options for popup', async({page, context, server}) => {
|
||||
it('should use context options for popup', async ({page, context, server}) => {
|
||||
await context.grantPermissions(['geolocation']);
|
||||
await context.setGeolocation({ longitude: 10, latitude: 10 });
|
||||
const [popup] = await Promise.all([
|
||||
page.waitForEvent('popup'),
|
||||
page.evaluate(url => window["_popup"] = window.open(url), server.PREFIX + '/geolocation.html'),
|
||||
page.evaluate(url => window['_popup'] = window.open(url), server.PREFIX + '/geolocation.html'),
|
||||
]);
|
||||
await popup.waitForLoadState();
|
||||
const geolocation = await popup.evaluate(() => window['geolocationPromise']);
|
||||
|
@ -26,7 +26,7 @@ it('should have default url when launching browser', async ({browserType, defaul
|
||||
await browserContext.close();
|
||||
});
|
||||
|
||||
it.fail(WIN && options.CHROMIUM).slow()('headless should be able to read cookies written by headful', async({browserType, defaultBrowserOptions, server}) => {
|
||||
it.fail(WIN && options.CHROMIUM).slow()('headless should be able to read cookies written by headful', async ({browserType, defaultBrowserOptions, server}) => {
|
||||
// see https://github.com/microsoft/playwright/issues/717
|
||||
const userDataDir = await makeUserDataDir();
|
||||
// Write a cookie in headful chrome
|
||||
@ -46,7 +46,7 @@ it.fail(WIN && options.CHROMIUM).slow()('headless should be able to read cookies
|
||||
expect(cookie).toBe('foo=true');
|
||||
});
|
||||
|
||||
it.slow()('should close browser with beforeunload page', async({browserType, defaultBrowserOptions, server, tmpDir}) => {
|
||||
it.slow()('should close browser with beforeunload page', async ({browserType, defaultBrowserOptions, server, tmpDir}) => {
|
||||
const browserContext = await browserType.launchPersistentContext(tmpDir, {...defaultBrowserOptions, headless: false});
|
||||
const page = await browserContext.newPage();
|
||||
await page.goto(server.PREFIX + '/beforeunload.html');
|
||||
@ -60,18 +60,18 @@ it('should not crash when creating second context', async ({browserType, default
|
||||
const browser = await browserType.launch({...defaultBrowserOptions, headless: false });
|
||||
{
|
||||
const browserContext = await browser.newContext();
|
||||
const page = await browserContext.newPage();
|
||||
await browserContext.newPage();
|
||||
await browserContext.close();
|
||||
}
|
||||
{
|
||||
const browserContext = await browser.newContext();
|
||||
const page = await browserContext.newPage();
|
||||
await browserContext.newPage();
|
||||
await browserContext.close();
|
||||
}
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should click background tab', async({browserType, defaultBrowserOptions, server}) => {
|
||||
it('should click background tab', async ({browserType, defaultBrowserOptions, server}) => {
|
||||
const browser = await browserType.launch({...defaultBrowserOptions, headless: false });
|
||||
const page = await browser.newPage();
|
||||
await page.setContent(`<button>Hello</button><a target=_blank href="${server.EMPTY_PAGE}">empty.html</a>`);
|
||||
@ -80,7 +80,7 @@ it('should click background tab', async({browserType, defaultBrowserOptions, ser
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should close browser after context menu was triggered', async({browserType, defaultBrowserOptions, server}) => {
|
||||
it('should close browser after context menu was triggered', async ({browserType, defaultBrowserOptions, server}) => {
|
||||
const browser = await browserType.launch({...defaultBrowserOptions, headless: false });
|
||||
const page = await browser.newPage();
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
@ -88,7 +88,7 @@ it('should close browser after context menu was triggered', async({browserType,
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should(not) block third party cookies', async({browserType, defaultBrowserOptions, server}) => {
|
||||
it('should(not) block third party cookies', async ({browserType, defaultBrowserOptions, server}) => {
|
||||
const browser = await browserType.launch({...defaultBrowserOptions, headless: false });
|
||||
const page = await browser.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -112,14 +112,14 @@ it('should(not) block third party cookies', async({browserType, defaultBrowserOp
|
||||
if (allowsThirdParty) {
|
||||
expect(cookies).toEqual([
|
||||
{
|
||||
"domain": "127.0.0.1",
|
||||
"expires": -1,
|
||||
"httpOnly": false,
|
||||
"name": "username",
|
||||
"path": "/",
|
||||
"sameSite": "None",
|
||||
"secure": false,
|
||||
"value": "John Doe"
|
||||
'domain': '127.0.0.1',
|
||||
'expires': -1,
|
||||
'httpOnly': false,
|
||||
'name': 'username',
|
||||
'path': '/',
|
||||
'sameSite': 'None',
|
||||
'secure': false,
|
||||
'value': 'John Doe'
|
||||
}
|
||||
]);
|
||||
} else {
|
||||
@ -150,9 +150,9 @@ it.fixme(options.WEBKIT)('should not override viewport size when passed null', a
|
||||
it('Page.bringToFront should work', async ({browserType, defaultBrowserOptions}) => {
|
||||
const browser = await browserType.launch({...defaultBrowserOptions, headless: false });
|
||||
const page1 = await browser.newPage();
|
||||
await page1.setContent('Page1')
|
||||
await page1.setContent('Page1');
|
||||
const page2 = await browser.newPage();
|
||||
await page2.setContent('Page2')
|
||||
await page2.setContent('Page2');
|
||||
|
||||
await page1.bringToFront();
|
||||
expect(await page1.evaluate('document.visibilityState')).toBe('visible');
|
||||
@ -161,7 +161,7 @@ it('Page.bringToFront should work', async ({browserType, defaultBrowserOptions})
|
||||
await page2.bringToFront();
|
||||
expect(await page1.evaluate('document.visibilityState')).toBe('visible');
|
||||
expect(await page2.evaluate('document.visibilityState')).toBe(
|
||||
'visible'
|
||||
'visible'
|
||||
);
|
||||
await browser.close();
|
||||
});
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should work', async({browser, httpsServer}) => {
|
||||
it('should work', async ({browser, httpsServer}) => {
|
||||
let error = null;
|
||||
const context = await browser.newContext({ ignoreHTTPSErrors: true });
|
||||
const page = await context.newPage();
|
||||
@ -27,7 +27,7 @@ it('should work', async({browser, httpsServer}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should isolate contexts', async({browser, httpsServer}) => {
|
||||
it('should isolate contexts', async ({browser, httpsServer}) => {
|
||||
{
|
||||
let error = null;
|
||||
const context = await browser.newContext({ ignoreHTTPSErrors: true });
|
||||
@ -47,7 +47,7 @@ it('should isolate contexts', async({browser, httpsServer}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should work with mixed content', async({browser, server, httpsServer}) => {
|
||||
it('should work with mixed content', async ({browser, server, httpsServer}) => {
|
||||
httpsServer.setRoute('/mixedcontent.html', (req, res) => {
|
||||
res.end(`<iframe src=${server.EMPTY_PAGE}></iframe>`);
|
||||
});
|
||||
@ -62,7 +62,7 @@ it('should work with mixed content', async({browser, server, httpsServer}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work with WebSocket', async({browser, httpsServer}) => {
|
||||
it('should work with WebSocket', async ({browser, httpsServer}) => {
|
||||
const context = await browser.newContext({ ignoreHTTPSErrors: true });
|
||||
const page = await context.newPage();
|
||||
const value = await page.evaluate(endpoint => {
|
||||
@ -77,7 +77,7 @@ it('should work with WebSocket', async({browser, httpsServer}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should fail with WebSocket if not ignored', async({browser, httpsServer}) => {
|
||||
it('should fail with WebSocket if not ignored', async ({browser, httpsServer}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const value = await page.evaluate(endpoint => {
|
||||
|
@ -20,7 +20,7 @@ import './playwright.fixtures';
|
||||
import { globToRegex } from '../lib/client/clientHelper';
|
||||
import vm from 'vm';
|
||||
|
||||
it('should work with navigation', async({page, server}) => {
|
||||
it('should work with navigation', async ({page, server}) => {
|
||||
const requests = new Map();
|
||||
await page.route('**/*', route => {
|
||||
requests.set(route.request().url().split('/').pop(), route.request());
|
||||
@ -34,7 +34,7 @@ it('should work with navigation', async({page, server}) => {
|
||||
expect(requests.get('style.css').isNavigationRequest()).toBe(false);
|
||||
});
|
||||
|
||||
it('should work with ignoreHTTPSErrors', async({browser, httpsServer}) => {
|
||||
it('should work with ignoreHTTPSErrors', async ({browser, httpsServer}) => {
|
||||
const context = await browser.newContext({ ignoreHTTPSErrors: true });
|
||||
const page = await context.newPage();
|
||||
|
||||
@ -44,12 +44,12 @@ it('should work with ignoreHTTPSErrors', async({browser, httpsServer}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should intercept after a service worker', async({browser, page, server, context}) => {
|
||||
it('should intercept after a service worker', async ({browser, page, server, context}) => {
|
||||
await page.goto(server.PREFIX + '/serviceworkers/fetchdummy/sw.html');
|
||||
await page.evaluate(() => window["activationPromise"]);
|
||||
await page.evaluate(() => window['activationPromise']);
|
||||
|
||||
// Sanity check.
|
||||
const swResponse = await page.evaluate(() => window["fetchDummy"]('foo'));
|
||||
const swResponse = await page.evaluate(() => window['fetchDummy']('foo'));
|
||||
expect(swResponse).toBe('responseFromServiceWorker:foo');
|
||||
|
||||
await page.route('**/foo', route => {
|
||||
@ -63,15 +63,15 @@ it('should intercept after a service worker', async({browser, page, server, cont
|
||||
});
|
||||
|
||||
// Page route is applied after service worker fetch event.
|
||||
const swResponse2 = await page.evaluate(() => window["fetchDummy"]('foo'));
|
||||
const swResponse2 = await page.evaluate(() => window['fetchDummy']('foo'));
|
||||
expect(swResponse2).toBe('responseFromServiceWorker:foo');
|
||||
|
||||
// Page route is not applied to service worker initiated fetch.
|
||||
const nonInterceptedResponse = await page.evaluate(() => window["fetchDummy"]('passthrough'));
|
||||
const nonInterceptedResponse = await page.evaluate(() => window['fetchDummy']('passthrough'));
|
||||
expect(nonInterceptedResponse).toBe('FAILURE: Not Found');
|
||||
});
|
||||
|
||||
it('should work with glob', async() => {
|
||||
it('should work with glob', async () => {
|
||||
expect(globToRegex('**/*.js').test('https://localhost:8080/foo.js')).toBeTruthy();
|
||||
expect(globToRegex('**/*.css').test('https://localhost:8080/foo.js')).toBeFalsy();
|
||||
expect(globToRegex('*.js').test('https://localhost:8080/foo.js')).toBeFalsy();
|
||||
@ -88,7 +88,7 @@ it('should work with glob', async() => {
|
||||
expect(globToRegex('**/*.{png,jpg,jpeg}').test('https://localhost:8080/c.css')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should work with regular expression passed from a different context', async({page, server}) => {
|
||||
it('should work with regular expression passed from a different context', async ({page, server}) => {
|
||||
const ctx = vm.createContext();
|
||||
const regexp = vm.runInContext('new RegExp("empty\\.html")', ctx);
|
||||
let intercepted = false;
|
||||
|
@ -17,19 +17,19 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should work', async({page}) => {
|
||||
it('should work', async ({page}) => {
|
||||
const aHandle = await page.evaluateHandle(() => document.body);
|
||||
const element = aHandle.asElement();
|
||||
expect(element).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return null for non-elements', async({page}) => {
|
||||
it('should return null for non-elements', async ({page}) => {
|
||||
const aHandle = await page.evaluateHandle(() => 2);
|
||||
const element = aHandle.asElement();
|
||||
expect(element).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return ElementHandle for TextNodes', async({page}) => {
|
||||
it('should return ElementHandle for TextNodes', async ({page}) => {
|
||||
await page.setContent('<div>ee!</div>');
|
||||
const aHandle = await page.evaluateHandle(() => document.querySelector('div').firstChild);
|
||||
const element = aHandle.asElement();
|
||||
@ -37,7 +37,7 @@ it('should return ElementHandle for TextNodes', async({page}) => {
|
||||
expect(await page.evaluate(e => e.nodeType === Node.TEXT_NODE, element)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should work with nullified Node', async({page}) => {
|
||||
it('should work with nullified Node', async ({page}) => {
|
||||
await page.setContent('<section>test</section>');
|
||||
await page.evaluate('delete Node');
|
||||
const handle = await page.evaluateHandle(() => document.querySelector('section'));
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should work with function', async({page}) => {
|
||||
it('should work with function', async ({page}) => {
|
||||
const windowHandle = await page.evaluateHandle(() => {
|
||||
window['foo'] = [1, 2];
|
||||
return window;
|
||||
@ -25,7 +25,7 @@ it('should work with function', async({page}) => {
|
||||
expect(await windowHandle.evaluate(w => w['foo'])).toEqual([1, 2]);
|
||||
});
|
||||
|
||||
it('should work with expression', async({page}) => {
|
||||
it('should work with expression', async ({page}) => {
|
||||
const windowHandle = await page.evaluateHandle(() => {
|
||||
window['foo'] = [1, 2];
|
||||
return window;
|
||||
|
@ -17,19 +17,19 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should work', async({page}) => {
|
||||
it('should work', async ({page}) => {
|
||||
const aHandle = await page.evaluateHandle(() => ({foo: 'bar'}));
|
||||
const json = await aHandle.jsonValue();
|
||||
expect(json).toEqual({foo: 'bar'});
|
||||
});
|
||||
|
||||
it('should work with dates', async({page}) => {
|
||||
it('should work with dates', async ({page}) => {
|
||||
const dateHandle = await page.evaluateHandle(() => new Date('2017-09-26T00:00:00.000Z'));
|
||||
const date = await dateHandle.jsonValue();
|
||||
expect(date.toJSON()).toBe('2017-09-26T00:00:00.000Z');
|
||||
});
|
||||
|
||||
it('should throw for circular objects', async({page}) => {
|
||||
it('should throw for circular objects', async ({page}) => {
|
||||
const windowHandle = await page.evaluateHandle('window');
|
||||
let error = null;
|
||||
await windowHandle.jsonValue().catch(e => error = e);
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should work', async({page}) => {
|
||||
it('should work', async ({page}) => {
|
||||
const aHandle = await page.evaluateHandle(() => ({
|
||||
one: 1,
|
||||
two: 2,
|
||||
@ -27,7 +27,7 @@ it('should work', async({page}) => {
|
||||
expect(await twoHandle.jsonValue()).toEqual(2);
|
||||
});
|
||||
|
||||
it('should work with undefined, null, and empty', async({page}) => {
|
||||
it('should work with undefined, null, and empty', async ({page}) => {
|
||||
const aHandle = await page.evaluateHandle(() => ({
|
||||
undefined: undefined,
|
||||
null: null,
|
||||
@ -40,7 +40,7 @@ it('should work with undefined, null, and empty', async({page}) => {
|
||||
expect(String(await emptyhandle.jsonValue())).toEqual('undefined');
|
||||
});
|
||||
|
||||
it('should work with unserializable values', async({page}) => {
|
||||
it('should work with unserializable values', async ({page}) => {
|
||||
const aHandle = await page.evaluateHandle(() => ({
|
||||
infinity: Infinity,
|
||||
nInfinity: -Infinity,
|
||||
@ -57,7 +57,7 @@ it('should work with unserializable values', async({page}) => {
|
||||
expect(await nzeroHandle.jsonValue()).toEqual(-0);
|
||||
});
|
||||
|
||||
it('getProperties should work', async({page}) => {
|
||||
it('getProperties should work', async ({page}) => {
|
||||
const aHandle = await page.evaluateHandle(() => ({
|
||||
foo: 'bar'
|
||||
}));
|
||||
@ -67,13 +67,13 @@ it('getProperties should work', async({page}) => {
|
||||
expect(await foo.jsonValue()).toBe('bar');
|
||||
});
|
||||
|
||||
it('getProperties should return empty map for non-objects', async({page}) => {
|
||||
it('getProperties should return empty map for non-objects', async ({page}) => {
|
||||
const aHandle = await page.evaluateHandle(() => 123);
|
||||
const properties = await aHandle.getProperties();
|
||||
expect(properties.size).toBe(0);
|
||||
});
|
||||
|
||||
it('getProperties should return even non-own properties', async({page}) => {
|
||||
it('getProperties should return even non-own properties', async ({page}) => {
|
||||
const aHandle = await page.evaluateHandle(() => {
|
||||
class A {
|
||||
a: string;
|
||||
|
@ -17,26 +17,26 @@
|
||||
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
it('should work for primitives', async({page}) => {
|
||||
it('should work for primitives', async ({page}) => {
|
||||
const numberHandle = await page.evaluateHandle(() => 2);
|
||||
expect(numberHandle.toString()).toBe('JSHandle@2');
|
||||
const stringHandle = await page.evaluateHandle(() => 'a');
|
||||
expect(stringHandle.toString()).toBe('JSHandle@a');
|
||||
});
|
||||
|
||||
it('should work for complicated objects', async({page}) => {
|
||||
it('should work for complicated objects', async ({page}) => {
|
||||
const aHandle = await page.evaluateHandle(() => window);
|
||||
expect(aHandle.toString()).toBe('JSHandle@object');
|
||||
});
|
||||
|
||||
it('should work for promises', async({page}) => {
|
||||
it('should work for promises', async ({page}) => {
|
||||
// wrap the promise in an object, otherwise we will await.
|
||||
const wrapperHandle = await page.evaluateHandle(() => ({b: Promise.resolve(123)}));
|
||||
const bHandle = await wrapperHandle.getProperty('b');
|
||||
expect(bHandle.toString()).toBe('JSHandle@promise');
|
||||
});
|
||||
|
||||
it('should work with different subtypes', async({page}) => {
|
||||
it('should work with different subtypes', async ({page}) => {
|
||||
expect((await page.evaluateHandle('(function(){})')).toString()).toBe('JSHandle@function');
|
||||
expect((await page.evaluateHandle('12')).toString()).toBe('JSHandle@12');
|
||||
expect((await page.evaluateHandle('true')).toString()).toBe('JSHandle@true');
|
||||
|
@ -19,12 +19,12 @@ import './playwright.fixtures';
|
||||
import path from 'path';
|
||||
import utils from './utils';
|
||||
|
||||
it('should require top-level Errors', async({}) => {
|
||||
it('should require top-level Errors', async ({}) => {
|
||||
const Errors = require(path.join(utils.projectRoot(), '/lib/utils/errors.js'));
|
||||
expect(String(Errors.TimeoutError)).toContain('TimeoutError');
|
||||
});
|
||||
|
||||
it('should require top-level DeviceDescriptors', async({playwright}) => {
|
||||
it('should require top-level DeviceDescriptors', async ({playwright}) => {
|
||||
const Devices = require(path.join(utils.projectRoot(), '/lib/server/deviceDescriptors.js')).DeviceDescriptors;
|
||||
expect(Devices['iPhone 6']).toBeTruthy();
|
||||
expect(Devices['iPhone 6']).toEqual(playwright.devices['iPhone 6']);
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should log', async({browserType, defaultBrowserOptions}) => {
|
||||
it('should log', async ({browserType, defaultBrowserOptions}) => {
|
||||
const log = [];
|
||||
const browser = await browserType.launch({...defaultBrowserOptions, logger: {
|
||||
log: (name, severity, message) => log.push({name, severity, message}),
|
||||
@ -30,7 +30,7 @@ it('should log', async({browserType, defaultBrowserOptions}) => {
|
||||
expect(log.filter(item => item.message.includes('browserType.launch succeeded')).length > 0).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should log context-level', async({browserType, defaultBrowserOptions}) => {
|
||||
it('should log context-level', async ({browserType, defaultBrowserOptions}) => {
|
||||
const log = [];
|
||||
const browser = await browserType.launch(defaultBrowserOptions);
|
||||
const context = await browser.newContext({
|
||||
|
@ -27,10 +27,10 @@ function dimensions() {
|
||||
};
|
||||
}
|
||||
|
||||
it.flaky(options.FIREFOX && WIN)('should click the document', async({page, server}) => {
|
||||
it.flaky(options.FIREFOX && WIN)('should click the document', async ({page, server}) => {
|
||||
// Occasionally times out on options.FIREFOX on Windows: https://github.com/microsoft/playwright/pull/1911/checks?check_run_id=607149016
|
||||
await page.evaluate(() => {
|
||||
window["clickPromise"] = new Promise(resolve => {
|
||||
window['clickPromise'] = new Promise(resolve => {
|
||||
document.addEventListener('click', event => {
|
||||
resolve({
|
||||
type: event.type,
|
||||
@ -44,7 +44,7 @@ it.flaky(options.FIREFOX && WIN)('should click the document', async({page, serve
|
||||
});
|
||||
});
|
||||
await page.mouse.click(50, 60);
|
||||
const event = await page.evaluate(() => window["clickPromise"]);
|
||||
const event = await page.evaluate(() => window['clickPromise']);
|
||||
expect(event.type).toBe('click');
|
||||
expect(event.detail).toBe(1);
|
||||
expect(event.clientX).toBe(50);
|
||||
@ -53,10 +53,10 @@ it.flaky(options.FIREFOX && WIN)('should click the document', async({page, serve
|
||||
expect(event.button).toBe(0);
|
||||
});
|
||||
|
||||
it('should dblclick the div', async({page, server}) => {
|
||||
it('should dblclick the div', async ({page, server}) => {
|
||||
await page.setContent(`<div style='width: 100px; height: 100px;'>Click me</div>`);
|
||||
await page.evaluate(() => {
|
||||
window["dblclickPromise"] = new Promise(resolve => {
|
||||
window['dblclickPromise'] = new Promise(resolve => {
|
||||
document.querySelector('div').addEventListener('dblclick', event => {
|
||||
resolve({
|
||||
type: event.type,
|
||||
@ -70,7 +70,7 @@ it('should dblclick the div', async({page, server}) => {
|
||||
});
|
||||
});
|
||||
await page.mouse.dblclick(50, 60);
|
||||
const event = await page.evaluate(() => window["dblclickPromise"]);
|
||||
const event = await page.evaluate(() => window['dblclickPromise']);
|
||||
expect(event.type).toBe('dblclick');
|
||||
expect(event.detail).toBe(2);
|
||||
expect(event.clientX).toBe(50);
|
||||
@ -79,7 +79,7 @@ it('should dblclick the div', async({page, server}) => {
|
||||
expect(event.button).toBe(0);
|
||||
});
|
||||
|
||||
it('should select the text with mouse', async({page, server}) => {
|
||||
it('should select the text with mouse', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
await page.focus('textarea');
|
||||
const text = 'This is the text that we are going to try to select. Let\'s see how it goes.';
|
||||
@ -98,7 +98,7 @@ it('should select the text with mouse', async({page, server}) => {
|
||||
})).toBe(text);
|
||||
});
|
||||
|
||||
it('should trigger hover state', async({page, server}) => {
|
||||
it('should trigger hover state', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/scrollable.html');
|
||||
await page.hover('#button-6');
|
||||
expect(await page.evaluate(() => document.querySelector('button:hover').id)).toBe('button-6');
|
||||
@ -108,23 +108,23 @@ it('should trigger hover state', async({page, server}) => {
|
||||
expect(await page.evaluate(() => document.querySelector('button:hover').id)).toBe('button-91');
|
||||
});
|
||||
|
||||
it('should trigger hover state on disabled button', async({page, server}) => {
|
||||
it('should trigger hover state on disabled button', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/scrollable.html');
|
||||
await page.$eval('#button-6', (button: HTMLButtonElement) => button.disabled = true);
|
||||
await page.hover('#button-6', { timeout: 5000 });
|
||||
expect(await page.evaluate(() => document.querySelector('button:hover').id)).toBe('button-6');
|
||||
});
|
||||
|
||||
it('should trigger hover state with removed window.Node', async({page, server}) => {
|
||||
it('should trigger hover state with removed window.Node', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/scrollable.html');
|
||||
await page.evaluate(() => delete window.Node);
|
||||
await page.hover('#button-6');
|
||||
expect(await page.evaluate(() => document.querySelector('button:hover').id)).toBe('button-6');
|
||||
});
|
||||
|
||||
it('should set modifier keys on click', async({page, server}) => {
|
||||
it('should set modifier keys on click', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/scrollable.html');
|
||||
await page.evaluate(() => document.querySelector('#button-3').addEventListener('mousedown', e => window["lastEvent"] = e, true));
|
||||
await page.evaluate(() => document.querySelector('#button-3').addEventListener('mousedown', e => window['lastEvent'] = e, true));
|
||||
const modifiers = {'Shift': 'shiftKey', 'Control': 'ctrlKey', 'Alt': 'altKey', 'Meta': 'metaKey'};
|
||||
// In Firefox, the Meta modifier only exists on Mac
|
||||
if (options.FIREFOX && !MAC)
|
||||
@ -132,26 +132,26 @@ it('should set modifier keys on click', async({page, server}) => {
|
||||
for (const modifier in modifiers) {
|
||||
await page.keyboard.down(modifier);
|
||||
await page.click('#button-3');
|
||||
if (!(await page.evaluate(mod => window["lastEvent"][mod], modifiers[modifier])))
|
||||
if (!(await page.evaluate(mod => window['lastEvent'][mod], modifiers[modifier])))
|
||||
throw new Error(modifiers[modifier] + ' should be true');
|
||||
await page.keyboard.up(modifier);
|
||||
}
|
||||
await page.click('#button-3');
|
||||
for (const modifier in modifiers) {
|
||||
if ((await page.evaluate(mod => window["lastEvent"][mod], modifiers[modifier])))
|
||||
if ((await page.evaluate(mod => window['lastEvent'][mod], modifiers[modifier])))
|
||||
throw new Error(modifiers[modifier] + ' should be false');
|
||||
}
|
||||
});
|
||||
|
||||
it('should tween mouse movement', async({page}) => {
|
||||
it('should tween mouse movement', async ({page}) => {
|
||||
// The test becomes flaky on WebKit without next line.
|
||||
if (options.WEBKIT)
|
||||
await page.evaluate(() => new Promise(requestAnimationFrame));
|
||||
await page.mouse.move(100, 100);
|
||||
await page.evaluate(() => {
|
||||
window["result"] = [];
|
||||
window['result'] = [];
|
||||
document.addEventListener('mousemove', event => {
|
||||
window["result"].push([event.clientX, event.clientY]);
|
||||
window['result'].push([event.clientX, event.clientY]);
|
||||
});
|
||||
});
|
||||
await page.mouse.move(200, 300, {steps: 5});
|
||||
@ -164,7 +164,7 @@ it('should tween mouse movement', async({page}) => {
|
||||
]);
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('should work with mobile viewports and cross process navigations', async({browser, server}) => {
|
||||
it.skip(options.FIREFOX)('should work with mobile viewports and cross process navigations', async ({browser, server}) => {
|
||||
// @see https://crbug.com/929806
|
||||
const context = await browser.newContext({ viewport: {width: 360, height: 640}, isMobile: true });
|
||||
const page = await context.newPage();
|
||||
@ -172,7 +172,7 @@ it.skip(options.FIREFOX)('should work with mobile viewports and cross process na
|
||||
await page.goto(server.CROSS_PROCESS_PREFIX + '/mobile.html');
|
||||
await page.evaluate(() => {
|
||||
document.addEventListener('click', event => {
|
||||
window["result"] = {x: event.clientX, y: event.clientY};
|
||||
window['result'] = {x: event.clientX, y: event.clientY};
|
||||
});
|
||||
});
|
||||
|
||||
@ -183,12 +183,12 @@ it.skip(options.FIREFOX)('should work with mobile viewports and cross process na
|
||||
});
|
||||
|
||||
xdescribe('Drag and Drop', function() {
|
||||
it('should work', async({server, page}) => {
|
||||
it('should work', async ({server, page}) => {
|
||||
await page.goto(server.PREFIX + '/drag-n-drop.html');
|
||||
await page.hover('#source');
|
||||
await page.mouse.down();
|
||||
await page.hover('#target');
|
||||
await page.mouse.up();
|
||||
expect(await page.$eval('#target', target => target.contains(document.querySelector('#source')))).toBe(true); // could not find source in target
|
||||
})
|
||||
});
|
||||
});
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should work with _blank target', async({page, server}) => {
|
||||
it('should work with _blank target', async ({page, server}) => {
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
res.end(`<a href="${server.EMPTY_PAGE}" target="_blank">Click me</a>`);
|
||||
});
|
||||
@ -25,7 +25,7 @@ it('should work with _blank target', async({page, server}) => {
|
||||
await page.click('"Click me"');
|
||||
});
|
||||
|
||||
it('should work with cross-process _blank target', async({page, server}) => {
|
||||
it('should work with cross-process _blank target', async ({page, server}) => {
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
res.end(`<a href="${server.CROSS_PROCESS_PREFIX}/empty.html" target="_blank">Click me</a>`);
|
||||
});
|
||||
|
@ -18,7 +18,7 @@
|
||||
import { options } from './playwright.fixtures';
|
||||
import utils from './utils';
|
||||
|
||||
it('should work for main frame navigation request', async({page, server}) => {
|
||||
it('should work for main frame navigation request', async ({page, server}) => {
|
||||
const requests = [];
|
||||
page.on('request', request => requests.push(request));
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -26,7 +26,7 @@ it('should work for main frame navigation request', async({page, server}) => {
|
||||
expect(requests[0].frame()).toBe(page.mainFrame());
|
||||
});
|
||||
|
||||
it('should work for subframe navigation request', async({page, server}) => {
|
||||
it('should work for subframe navigation request', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const requests = [];
|
||||
page.on('request', request => requests.push(request));
|
||||
@ -35,7 +35,7 @@ it('should work for subframe navigation request', async({page, server}) => {
|
||||
expect(requests[0].frame()).toBe(page.frames()[1]);
|
||||
});
|
||||
|
||||
it('should work for fetch requests', async({page, server}) => {
|
||||
it('should work for fetch requests', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
let requests = [];
|
||||
page.on('request', request => requests.push(request));
|
||||
@ -45,7 +45,7 @@ it('should work for fetch requests', async({page, server}) => {
|
||||
expect(requests[0].frame()).toBe(page.mainFrame());
|
||||
});
|
||||
|
||||
it('should return headers', async({page, server}) => {
|
||||
it('should return headers', async ({page, server}) => {
|
||||
const response = await page.goto(server.EMPTY_PAGE);
|
||||
if (options.CHROMIUM)
|
||||
expect(response.request().headers()['user-agent']).toContain('Chrome');
|
||||
@ -55,7 +55,7 @@ it('should return headers', async({page, server}) => {
|
||||
expect(response.request().headers()['user-agent']).toContain('WebKit');
|
||||
});
|
||||
|
||||
it.fail(options.CHROMIUM||options.WEBKIT)('should get the same headers as the server', async({page, server}) => {
|
||||
it.fail(options.CHROMIUM || options.WEBKIT)('should get the same headers as the server', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/empty.html');
|
||||
let serverRequest;
|
||||
server.setRoute('/something', (request, response) => {
|
||||
@ -73,7 +73,7 @@ it.fail(options.CHROMIUM||options.WEBKIT)('should get the same headers as the se
|
||||
expect(request.headers()).toEqual(serverRequest.headers);
|
||||
});
|
||||
|
||||
it('should return postData', async({page, server}) => {
|
||||
it('should return postData', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
server.setRoute('/post', (req, res) => res.end());
|
||||
let request = null;
|
||||
@ -83,13 +83,13 @@ it('should return postData', async({page, server}) => {
|
||||
expect(request.postData()).toBe('{"foo":"bar"}');
|
||||
});
|
||||
|
||||
it('should work with binary post data', async({page, server}) => {
|
||||
it('should work with binary post data', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
server.setRoute('/post', (req, res) => res.end());
|
||||
let request = null;
|
||||
page.on('request', r => request = r);
|
||||
await page.evaluate(async () => {
|
||||
await fetch('./post', { method: 'POST', body: new Uint8Array(Array.from(Array(256).keys())) })
|
||||
await fetch('./post', { method: 'POST', body: new Uint8Array(Array.from(Array(256).keys())) });
|
||||
});
|
||||
expect(request).toBeTruthy();
|
||||
const buffer = request.postDataBuffer();
|
||||
@ -98,14 +98,14 @@ it('should work with binary post data', async({page, server}) => {
|
||||
expect(buffer[i]).toBe(i);
|
||||
});
|
||||
|
||||
it('should work with binary post data and interception', async({page, server}) => {
|
||||
it('should work with binary post data and interception', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
server.setRoute('/post', (req, res) => res.end());
|
||||
let request = null;
|
||||
await page.route('/post', route => route.continue());
|
||||
page.on('request', r => request = r);
|
||||
await page.evaluate(async () => {
|
||||
await fetch('./post', { method: 'POST', body: new Uint8Array(Array.from(Array(256).keys())) })
|
||||
await fetch('./post', { method: 'POST', body: new Uint8Array(Array.from(Array(256).keys())) });
|
||||
});
|
||||
expect(request).toBeTruthy();
|
||||
const buffer = request.postDataBuffer();
|
||||
@ -114,7 +114,7 @@ it('should work with binary post data and interception', async({page, server}) =
|
||||
expect(buffer[i]).toBe(i);
|
||||
});
|
||||
|
||||
it('should be |undefined| when there is no post data', async({page, server}) => {
|
||||
it('should be |undefined| when there is no post data', async ({page, server}) => {
|
||||
const response = await page.goto(server.EMPTY_PAGE);
|
||||
expect(response.request().postData()).toBe(null);
|
||||
});
|
||||
@ -126,10 +126,10 @@ it('should parse the json post data', async ({ page, server }) => {
|
||||
page.on('request', r => request = r);
|
||||
await page.evaluate(() => fetch('./post', { method: 'POST', body: JSON.stringify({ foo: 'bar' }) }));
|
||||
expect(request).toBeTruthy();
|
||||
expect(request.postDataJSON()).toEqual({ "foo": "bar" });
|
||||
expect(request.postDataJSON()).toEqual({ 'foo': 'bar' });
|
||||
});
|
||||
|
||||
it('should parse the data if content-type is application/x-www-form-urlencoded', async({page, server}) => {
|
||||
it('should parse the data if content-type is application/x-www-form-urlencoded', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
server.setRoute('/post', (req, res) => res.end());
|
||||
let request = null;
|
||||
@ -137,8 +137,8 @@ it('should parse the data if content-type is application/x-www-form-urlencoded',
|
||||
await page.setContent(`<form method='POST' action='/post'><input type='text' name='foo' value='bar'><input type='number' name='baz' value='123'><input type='submit'></form>`);
|
||||
await page.click('input[type=submit]');
|
||||
expect(request).toBeTruthy();
|
||||
expect(request.postDataJSON()).toEqual({'foo':'bar','baz':'123'});
|
||||
})
|
||||
expect(request.postDataJSON()).toEqual({'foo': 'bar','baz': '123'});
|
||||
});
|
||||
|
||||
it('should be |undefined| when there is no post data', async ({ page, server }) => {
|
||||
const response = await page.goto(server.EMPTY_PAGE);
|
||||
@ -170,7 +170,7 @@ it('should return event source', async ({page, server}) => {
|
||||
expect(requests[0].resourceType()).toBe('eventsource');
|
||||
});
|
||||
|
||||
it('should return navigation bit', async({page, server}) => {
|
||||
it('should return navigation bit', async ({page, server}) => {
|
||||
const requests = new Map();
|
||||
page.on('request', request => requests.set(request.url().split('/').pop(), request));
|
||||
server.setRedirect('/rrredirect', '/frames/one-frame.html');
|
||||
@ -182,7 +182,7 @@ it('should return navigation bit', async({page, server}) => {
|
||||
expect(requests.get('style.css').isNavigationRequest()).toBe(false);
|
||||
});
|
||||
|
||||
it('should return navigation bit when navigating to image', async({page, server}) => {
|
||||
it('should return navigation bit when navigating to image', async ({page, server}) => {
|
||||
const requests = [];
|
||||
page.on('request', request => requests.push(request));
|
||||
await page.goto(server.PREFIX + '/pptr.png');
|
||||
|
@ -19,7 +19,7 @@ import './playwright.fixtures';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
it('should work', async({page, server}) => {
|
||||
it('should work', async ({page, server}) => {
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
res.setHeader('foo', 'bar');
|
||||
res.setHeader('BaZ', 'bAz');
|
||||
@ -32,19 +32,19 @@ it('should work', async({page, server}) => {
|
||||
});
|
||||
|
||||
|
||||
it('should return text', async({page, server}) => {
|
||||
it('should return text', async ({page, server}) => {
|
||||
const response = await page.goto(server.PREFIX + '/simple.json');
|
||||
expect(await response.text()).toBe('{"foo": "bar"}\n');
|
||||
});
|
||||
|
||||
it('should return uncompressed text', async({page, server}) => {
|
||||
it('should return uncompressed text', async ({page, server}) => {
|
||||
server.enableGzip('/simple.json');
|
||||
const response = await page.goto(server.PREFIX + '/simple.json');
|
||||
expect(response.headers()['content-encoding']).toBe('gzip');
|
||||
expect(await response.text()).toBe('{"foo": "bar"}\n');
|
||||
});
|
||||
|
||||
it('should throw when requesting body of redirected response', async({page, server}) => {
|
||||
it('should throw when requesting body of redirected response', async ({page, server}) => {
|
||||
server.setRedirect('/foo.html', '/empty.html');
|
||||
const response = await page.goto(server.PREFIX + '/foo.html');
|
||||
const redirectedFrom = response.request().redirectedFrom();
|
||||
@ -56,7 +56,7 @@ it('should throw when requesting body of redirected response', async({page, serv
|
||||
expect(error.message).toContain('Response body is unavailable for redirect responses');
|
||||
});
|
||||
|
||||
it('should wait until response completes', async({page, server}) => {
|
||||
it('should wait until response completes', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
// Setup server to trap request.
|
||||
let serverResponse = null;
|
||||
@ -90,19 +90,19 @@ it('should wait until response completes', async({page, server}) => {
|
||||
expect(await responseText).toBe('hello world!');
|
||||
});
|
||||
|
||||
it('should return json', async({page, server}) => {
|
||||
it('should return json', async ({page, server}) => {
|
||||
const response = await page.goto(server.PREFIX + '/simple.json');
|
||||
expect(await response.json()).toEqual({foo: 'bar'});
|
||||
});
|
||||
|
||||
it('should return body', async({page, server}) => {
|
||||
it('should return body', async ({page, server}) => {
|
||||
const response = await page.goto(server.PREFIX + '/pptr.png');
|
||||
const imageBuffer = fs.readFileSync(path.join(__dirname, 'assets', 'pptr.png'));
|
||||
const responseBuffer = await response.body();
|
||||
expect(responseBuffer.equals(imageBuffer)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return body with compression', async({page, server}) => {
|
||||
it('should return body with compression', async ({page, server}) => {
|
||||
server.enableGzip('/pptr.png');
|
||||
const response = await page.goto(server.PREFIX + '/pptr.png');
|
||||
const imageBuffer = fs.readFileSync(path.join(__dirname, 'assets', 'pptr.png'));
|
||||
@ -110,7 +110,7 @@ it('should return body with compression', async({page, server}) => {
|
||||
expect(responseBuffer.equals(imageBuffer)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return status text', async({page, server}) => {
|
||||
it('should return status text', async ({page, server}) => {
|
||||
server.setRoute('/cool', (req, res) => {
|
||||
res.writeHead(200, 'cool!');
|
||||
res.end();
|
||||
|
@ -19,23 +19,23 @@ import './playwright.fixtures';
|
||||
import path from 'path';
|
||||
|
||||
it('should evaluate before anything else on the page', async ({ page, server }) => {
|
||||
await page.addInitScript(function () {
|
||||
window["injected"] = 123;
|
||||
await page.addInitScript(function() {
|
||||
window['injected'] = 123;
|
||||
});
|
||||
await page.goto(server.PREFIX + '/tamperable.html');
|
||||
expect(await page.evaluate(() => window["result"])).toBe(123);
|
||||
expect(await page.evaluate(() => window['result'])).toBe(123);
|
||||
});
|
||||
|
||||
it('should work with a path', async ({ page, server }) => {
|
||||
await page.addInitScript({ path: path.join(__dirname, 'assets/injectedfile.js') });
|
||||
await page.goto(server.PREFIX + '/tamperable.html');
|
||||
expect(await page.evaluate(() => window["result"])).toBe(123);
|
||||
expect(await page.evaluate(() => window['result'])).toBe(123);
|
||||
});
|
||||
|
||||
it('should work with content', async ({ page, server }) => {
|
||||
await page.addInitScript({ content: 'window["injected"] = 123' });
|
||||
await page.goto(server.PREFIX + '/tamperable.html');
|
||||
expect(await page.evaluate(() => window["result"])).toBe(123);
|
||||
expect(await page.evaluate(() => window['result'])).toBe(123);
|
||||
});
|
||||
|
||||
it('should throw without path and content', async ({ page, server }) => {
|
||||
@ -45,11 +45,11 @@ it('should throw without path and content', async ({ page, server }) => {
|
||||
|
||||
it('should work with browser context scripts', async ({ browser, server }) => {
|
||||
const context = await browser.newContext();
|
||||
await context.addInitScript(() => window["temp"] = 123);
|
||||
await context.addInitScript(() => window['temp'] = 123);
|
||||
const page = await context.newPage();
|
||||
await page.addInitScript(() => window["injected"] = window["temp"]);
|
||||
await page.addInitScript(() => window['injected'] = window['temp']);
|
||||
await page.goto(server.PREFIX + '/tamperable.html');
|
||||
expect(await page.evaluate(() => window["result"])).toBe(123);
|
||||
expect(await page.evaluate(() => window['result'])).toBe(123);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
@ -58,39 +58,39 @@ it('should work with browser context scripts with a path', async ({ browser, ser
|
||||
await context.addInitScript({ path: path.join(__dirname, 'assets/injectedfile.js') });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/tamperable.html');
|
||||
expect(await page.evaluate(() => window["result"])).toBe(123);
|
||||
expect(await page.evaluate(() => window['result'])).toBe(123);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work with browser context scripts for already created pages', async ({ browser, server }) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await context.addInitScript(() => window["temp"] = 123);
|
||||
await page.addInitScript(() => window["injected"] = window["temp"]);
|
||||
await context.addInitScript(() => window['temp'] = 123);
|
||||
await page.addInitScript(() => window['injected'] = window['temp']);
|
||||
await page.goto(server.PREFIX + '/tamperable.html');
|
||||
expect(await page.evaluate(() => window["result"])).toBe(123);
|
||||
expect(await page.evaluate(() => window['result'])).toBe(123);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should support multiple scripts', async ({ page, server }) => {
|
||||
await page.addInitScript(function () {
|
||||
window["script1"] = 1;
|
||||
await page.addInitScript(function() {
|
||||
window['script1'] = 1;
|
||||
});
|
||||
await page.addInitScript(function () {
|
||||
window["script2"] = 2;
|
||||
await page.addInitScript(function() {
|
||||
window['script2'] = 2;
|
||||
});
|
||||
await page.goto(server.PREFIX + '/tamperable.html');
|
||||
expect(await page.evaluate(() => window["script1"])).toBe(1);
|
||||
expect(await page.evaluate(() => window["script2"])).toBe(2);
|
||||
expect(await page.evaluate(() => window['script1'])).toBe(1);
|
||||
expect(await page.evaluate(() => window['script2'])).toBe(2);
|
||||
});
|
||||
|
||||
it('should work with CSP', async ({ page, server }) => {
|
||||
server.setCSP('/empty.html', 'script-src ' + server.PREFIX);
|
||||
await page.addInitScript(function () {
|
||||
window["injected"] = 123;
|
||||
await page.addInitScript(function() {
|
||||
window['injected'] = 123;
|
||||
});
|
||||
await page.goto(server.PREFIX + '/empty.html');
|
||||
expect(await page.evaluate(() => window["injected"])).toBe(123);
|
||||
expect(await page.evaluate(() => window['injected'])).toBe(123);
|
||||
|
||||
// Make sure CSP works.
|
||||
await page.addScriptTag({ content: 'window.e = 10;' }).catch(e => void e);
|
||||
@ -99,9 +99,9 @@ it('should work with CSP', async ({ page, server }) => {
|
||||
|
||||
it('should work after a cross origin navigation', async ({ page, server }) => {
|
||||
await page.goto(server.CROSS_PROCESS_PREFIX);
|
||||
await page.addInitScript(function () {
|
||||
window["injected"] = 123;
|
||||
await page.addInitScript(function() {
|
||||
window['injected'] = 123;
|
||||
});
|
||||
await page.goto(server.PREFIX + '/tamperable.html');
|
||||
expect(await page.evaluate(() => window["result"])).toBe(123);
|
||||
expect(await page.evaluate(() => window['result'])).toBe(123);
|
||||
});
|
||||
|
@ -18,10 +18,10 @@
|
||||
import { options } from './playwright.fixtures';
|
||||
import path from 'path';
|
||||
|
||||
it('should throw an error if no options are provided', async({page, server}) => {
|
||||
it('should throw an error if no options are provided', async ({page, server}) => {
|
||||
let error = null;
|
||||
try {
|
||||
//@ts-ignore
|
||||
// @ts-ignore
|
||||
await page.addScriptTag('/injectedfile.js');
|
||||
} catch (e) {
|
||||
error = e;
|
||||
@ -29,34 +29,34 @@ it('should throw an error if no options are provided', async({page, server}) =>
|
||||
expect(error.message).toContain('Provide an object with a `url`, `path` or `content` property');
|
||||
});
|
||||
|
||||
it('should work with a url', async({page, server}) => {
|
||||
it('should work with a url', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const scriptHandle = await page.addScriptTag({ url: '/injectedfile.js' });
|
||||
expect(scriptHandle.asElement()).not.toBeNull();
|
||||
expect(await page.evaluate(() => window['__injected'])).toBe(42);
|
||||
});
|
||||
|
||||
it('should work with a url and type=module', async({page, server}) => {
|
||||
it('should work with a url and type=module', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.addScriptTag({ url: '/es6/es6import.js', type: 'module' });
|
||||
expect(await page.evaluate(() => window['__es6injected'])).toBe(42);
|
||||
});
|
||||
|
||||
it('should work with a path and type=module', async({page, server}) => {
|
||||
it('should work with a path and type=module', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.addScriptTag({ path: path.join(__dirname, 'assets/es6/es6pathimport.js'), type: 'module' });
|
||||
await page.waitForFunction('window.__es6injected');
|
||||
expect(await page.evaluate(() => window['__es6injected'])).toBe(42);
|
||||
});
|
||||
|
||||
it('should work with a content and type=module', async({page, server}) => {
|
||||
it('should work with a content and type=module', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.addScriptTag({ content: `import num from '/es6/es6module.js';window.__es6injected = num;`, type: 'module' });
|
||||
await page.waitForFunction('window.__es6injected');
|
||||
expect(await page.evaluate(() => window['__es6injected'])).toBe(42);
|
||||
});
|
||||
|
||||
it('should throw an error if loading from url fail', async({page, server}) => {
|
||||
it('should throw an error if loading from url fail', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
let error = null;
|
||||
try {
|
||||
@ -67,28 +67,28 @@ it('should throw an error if loading from url fail', async({page, server}) => {
|
||||
expect(error).not.toBe(null);
|
||||
});
|
||||
|
||||
it('should work with a path', async({page, server}) => {
|
||||
it('should work with a path', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const scriptHandle = await page.addScriptTag({ path: path.join(__dirname, 'assets/injectedfile.js') });
|
||||
expect(scriptHandle.asElement()).not.toBeNull();
|
||||
expect(await page.evaluate(() => window['__injected'])).toBe(42);
|
||||
});
|
||||
|
||||
it.skip(options.WEBKIT)('should include sourceURL when path is provided', async({page, server}) => {
|
||||
it.skip(options.WEBKIT)('should include sourceURL when path is provided', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.addScriptTag({ path: path.join(__dirname, 'assets/injectedfile.js') });
|
||||
const result = await page.evaluate(() => window['__injectedError'].stack);
|
||||
expect(result).toContain(path.join('assets', 'injectedfile.js'));
|
||||
});
|
||||
|
||||
it('should work with content', async({page, server}) => {
|
||||
it('should work with content', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const scriptHandle = await page.addScriptTag({ content: 'window["__injected"] = 35;' });
|
||||
expect(scriptHandle.asElement()).not.toBeNull();
|
||||
expect(await page.evaluate(() => window['__injected'])).toBe(35);
|
||||
});
|
||||
|
||||
it('should throw when added with content to the CSP page', async({page, server}) => {
|
||||
it('should throw when added with content to the CSP page', async ({page, server}) => {
|
||||
// Firefox fires onload for blocked script before it issues the CSP console error.
|
||||
await page.goto(server.PREFIX + '/csp.html');
|
||||
let error = null;
|
||||
@ -96,14 +96,14 @@ it('should throw when added with content to the CSP page', async({page, server})
|
||||
expect(error).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should throw when added with URL to the CSP page', async({page, server}) => {
|
||||
it('should throw when added with URL to the CSP page', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/csp.html');
|
||||
let error = null;
|
||||
await page.addScriptTag({ url: server.CROSS_PROCESS_PREFIX + '/injectedfile.js' }).catch(e => error = e);
|
||||
expect(error).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should throw a nice error when the request fails', async({page, server}) => {
|
||||
it('should throw a nice error when the request fails', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const url = server.PREFIX + '/this_does_not_exist.js';
|
||||
const error = await page.addScriptTag({url}).catch(e => e);
|
||||
|
@ -18,10 +18,10 @@
|
||||
import './playwright.fixtures';
|
||||
import path from 'path';
|
||||
|
||||
it('should throw an error if no options are provided', async({page, server}) => {
|
||||
it('should throw an error if no options are provided', async ({page, server}) => {
|
||||
let error = null;
|
||||
try {
|
||||
//@ts-ignore
|
||||
// @ts-ignore
|
||||
await page.addStyleTag('/injectedstyle.css');
|
||||
} catch (e) {
|
||||
error = e;
|
||||
@ -29,14 +29,14 @@ it('should throw an error if no options are provided', async({page, server}) =>
|
||||
expect(error.message).toContain('Provide an object with a `url`, `path` or `content` property');
|
||||
});
|
||||
|
||||
it('should work with a url', async({page, server}) => {
|
||||
it('should work with a url', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const styleHandle = await page.addStyleTag({ url: '/injectedstyle.css' });
|
||||
expect(styleHandle.asElement()).not.toBeNull();
|
||||
expect(await page.evaluate(`window.getComputedStyle(document.querySelector('body')).getPropertyValue('background-color')`)).toBe('rgb(255, 0, 0)');
|
||||
});
|
||||
|
||||
it('should throw an error if loading from url fail', async({page, server}) => {
|
||||
it('should throw an error if loading from url fail', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
let error = null;
|
||||
try {
|
||||
@ -47,14 +47,14 @@ it('should throw an error if loading from url fail', async({page, server}) => {
|
||||
expect(error).not.toBe(null);
|
||||
});
|
||||
|
||||
it('should work with a path', async({page, server}) => {
|
||||
it('should work with a path', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const styleHandle = await page.addStyleTag({ path: path.join(__dirname, 'assets/injectedstyle.css') });
|
||||
expect(styleHandle.asElement()).not.toBeNull();
|
||||
expect(await page.evaluate(`window.getComputedStyle(document.querySelector('body')).getPropertyValue('background-color')`)).toBe('rgb(255, 0, 0)');
|
||||
});
|
||||
|
||||
it('should include sourceURL when path is provided', async({page, server}) => {
|
||||
it('should include sourceURL when path is provided', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.addStyleTag({ path: path.join(__dirname, 'assets/injectedstyle.css') });
|
||||
const styleHandle = await page.$('style');
|
||||
@ -62,21 +62,21 @@ it('should include sourceURL when path is provided', async({page, server}) => {
|
||||
expect(styleContent).toContain(path.join('assets', 'injectedstyle.css'));
|
||||
});
|
||||
|
||||
it('should work with content', async({page, server}) => {
|
||||
it('should work with content', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const styleHandle = await page.addStyleTag({ content: 'body { background-color: green; }' });
|
||||
expect(styleHandle.asElement()).not.toBeNull();
|
||||
expect(await page.evaluate(`window.getComputedStyle(document.querySelector('body')).getPropertyValue('background-color')`)).toBe('rgb(0, 128, 0)');
|
||||
});
|
||||
|
||||
it('should throw when added with content to the CSP page', async({page, server}) => {
|
||||
it('should throw when added with content to the CSP page', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/csp.html');
|
||||
let error = null;
|
||||
await page.addStyleTag({ content: 'body { background-color: green; }' }).catch(e => error = e);
|
||||
expect(error).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should throw when added with URL to the CSP page', async({page, server}) => {
|
||||
it('should throw when added with URL to the CSP page', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/csp.html');
|
||||
let error = null;
|
||||
await page.addStyleTag({ url: server.CROSS_PROCESS_PREFIX + '/injectedstyle.css' }).catch(e => error = e);
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
it('should reject all promises when page is closed', async({context}) => {
|
||||
it('should reject all promises when page is closed', async ({context}) => {
|
||||
const newPage = await context.newPage();
|
||||
let error = null;
|
||||
await Promise.all([
|
||||
@ -27,14 +27,14 @@ it('should reject all promises when page is closed', async({context}) => {
|
||||
expect(error.message).toContain('Protocol error');
|
||||
});
|
||||
|
||||
it('should not be visible in context.pages', async({context}) => {
|
||||
it('should not be visible in context.pages', async ({context}) => {
|
||||
const newPage = await context.newPage();
|
||||
expect(context.pages()).toContain(newPage);
|
||||
await newPage.close();
|
||||
expect(context.pages()).not.toContain(newPage);
|
||||
});
|
||||
|
||||
it('should run beforeunload if asked for', async({context, server}) => {
|
||||
it('should run beforeunload if asked for', async ({context, server}) => {
|
||||
const newPage = await context.newPage();
|
||||
await newPage.goto(server.PREFIX + '/beforeunload.html');
|
||||
// We have to interact with a page so that 'beforeunload' handlers
|
||||
@ -54,7 +54,7 @@ it('should run beforeunload if asked for', async({context, server}) => {
|
||||
await pageClosingPromise;
|
||||
});
|
||||
|
||||
it('should *not* run beforeunload by default', async({context, server}) => {
|
||||
it('should *not* run beforeunload by default', async ({context, server}) => {
|
||||
const newPage = await context.newPage();
|
||||
await newPage.goto(server.PREFIX + '/beforeunload.html');
|
||||
// We have to interact with a page so that 'beforeunload' handlers
|
||||
@ -63,14 +63,14 @@ it('should *not* run beforeunload by default', async({context, server}) => {
|
||||
await newPage.close();
|
||||
});
|
||||
|
||||
it('should set the page close state', async({context}) => {
|
||||
it('should set the page close state', async ({context}) => {
|
||||
const newPage = await context.newPage();
|
||||
expect(newPage.isClosed()).toBe(false);
|
||||
await newPage.close();
|
||||
expect(newPage.isClosed()).toBe(true);
|
||||
});
|
||||
|
||||
it('should terminate network waiters', async({context, server}) => {
|
||||
it('should terminate network waiters', async ({context, server}) => {
|
||||
const newPage = await context.newPage();
|
||||
const results = await Promise.all([
|
||||
newPage.waitForRequest(server.EMPTY_PAGE).catch(e => e),
|
||||
@ -84,7 +84,7 @@ it('should terminate network waiters', async({context, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should be callable twice', async({context}) => {
|
||||
it('should be callable twice', async ({context}) => {
|
||||
const newPage = await context.newPage();
|
||||
await Promise.all([
|
||||
newPage.close(),
|
||||
@ -93,14 +93,14 @@ it('should be callable twice', async({context}) => {
|
||||
await newPage.close();
|
||||
});
|
||||
|
||||
it('should fire load when expected', async({page, server}) => {
|
||||
it('should fire load when expected', async ({page, server}) => {
|
||||
await Promise.all([
|
||||
page.goto('about:blank'),
|
||||
page.waitForEvent('load'),
|
||||
]);
|
||||
});
|
||||
|
||||
it('async stacks should work', async({page, server}) => {
|
||||
it('async stacks should work', async ({page, server}) => {
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
req.socket.end();
|
||||
});
|
||||
@ -110,7 +110,7 @@ it('async stacks should work', async({page, server}) => {
|
||||
expect(error.stack).toContain(__filename);
|
||||
});
|
||||
|
||||
it('should provide access to the opener page', async({page}) => {
|
||||
it('should provide access to the opener page', async ({page}) => {
|
||||
const [popup] = await Promise.all([
|
||||
page.waitForEvent('popup'),
|
||||
page.evaluate(() => window.open('about:blank')),
|
||||
@ -119,7 +119,7 @@ it('should provide access to the opener page', async({page}) => {
|
||||
expect(opener).toBe(page);
|
||||
});
|
||||
|
||||
it('should return null if parent page has been closed', async({page}) => {
|
||||
it('should return null if parent page has been closed', async ({page}) => {
|
||||
const [popup] = await Promise.all([
|
||||
page.waitForEvent('popup'),
|
||||
page.evaluate(() => window.open('about:blank')),
|
||||
@ -129,13 +129,13 @@ it('should return null if parent page has been closed', async({page}) => {
|
||||
expect(opener).toBe(null);
|
||||
});
|
||||
|
||||
it('should fire domcontentloaded when expected', async({page, server}) => {
|
||||
it('should fire domcontentloaded when expected', async ({page, server}) => {
|
||||
const navigatedPromise = page.goto('about:blank');
|
||||
await page.waitForEvent('domcontentloaded');
|
||||
await navigatedPromise;
|
||||
});
|
||||
|
||||
it('should fail with error upon disconnect', async({page, server}) => {
|
||||
it('should fail with error upon disconnect', async ({page, server}) => {
|
||||
let error;
|
||||
const waitForPromise = page.waitForEvent('download').catch(e => error = e);
|
||||
await page.close();
|
||||
@ -143,22 +143,22 @@ it('should fail with error upon disconnect', async({page, server}) => {
|
||||
expect(error.message).toContain('Page closed');
|
||||
});
|
||||
|
||||
it('page.url should work', async({page, server}) => {
|
||||
it('page.url should work', async ({page, server}) => {
|
||||
expect(page.url()).toBe('about:blank');
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
|
||||
it('page.url should include hashes', async({page, server}) => {
|
||||
it('page.url should include hashes', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE + '#hash');
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE + '#hash');
|
||||
await page.evaluate(() => {
|
||||
window.location.hash = "dynamic";
|
||||
window.location.hash = 'dynamic';
|
||||
});
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE + '#dynamic');
|
||||
});
|
||||
|
||||
it('page.title should return the page title', async({page, server}) => {
|
||||
it('page.title should return the page title', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/title.html');
|
||||
expect(await page.title()).toBe('Woof-Woof');
|
||||
});
|
||||
@ -201,7 +201,7 @@ it('should have sane user agent', async ({page}) => {
|
||||
const userAgent = await page.evaluate(() => navigator.userAgent);
|
||||
const [
|
||||
part1,
|
||||
part2,
|
||||
/* part2 */,
|
||||
part3,
|
||||
part4,
|
||||
part5,
|
||||
@ -231,13 +231,13 @@ it('should have sane user agent', async ({page}) => {
|
||||
expect(engine.startsWith('Version/')).toBe(true);
|
||||
});
|
||||
|
||||
it('page.press should work', async({page, server}) => {
|
||||
it('page.press should work', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
await page.press('textarea', 'a');
|
||||
expect(await page.evaluate(() => document.querySelector('textarea').value)).toBe('a');
|
||||
});
|
||||
|
||||
it('frame.press should work', async({page, server}) => {
|
||||
it('frame.press should work', async ({page, server}) => {
|
||||
await page.setContent(`<iframe name=inner src="${server.PREFIX}/input/textarea.html"></iframe>`);
|
||||
const frame = page.frame('inner');
|
||||
await frame.press('textarea', 'a');
|
||||
@ -245,11 +245,11 @@ it('frame.press should work', async({page, server}) => {
|
||||
});
|
||||
|
||||
it.fail(options.FIREFOX)('frame.focus should work multiple times', async ({ context, server }) => {
|
||||
const page1 = await context.newPage()
|
||||
const page2 = await context.newPage()
|
||||
const page1 = await context.newPage();
|
||||
const page2 = await context.newPage();
|
||||
for (const page of [page1, page2]) {
|
||||
await page.setContent(`<button id="foo" onfocus="window.gotFocus=true"></button>`)
|
||||
await page.focus("#foo")
|
||||
expect(await page.evaluate(() => !!window['gotFocus'])).toBe(true)
|
||||
await page.setContent(`<button id="foo" onfocus="window.gotFocus=true"></button>`);
|
||||
await page.focus('#foo');
|
||||
expect(await page.evaluate(() => !!window['gotFocus'])).toBe(true);
|
||||
}
|
||||
});
|
||||
|
@ -15,10 +15,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { options } from './playwright.fixtures';
|
||||
import './playwright.fixtures';
|
||||
import utils from './utils';
|
||||
|
||||
it('should emulate type', async({page, server}) => {
|
||||
it('should emulate type', async ({page, server}) => {
|
||||
expect(await page.evaluate(() => matchMedia('screen').matches)).toBe(true);
|
||||
expect(await page.evaluate(() => matchMedia('print').matches)).toBe(false);
|
||||
await page.emulateMedia({ media: 'print' });
|
||||
@ -32,13 +32,13 @@ it('should emulate type', async({page, server}) => {
|
||||
expect(await page.evaluate(() => matchMedia('print').matches)).toBe(false);
|
||||
});
|
||||
|
||||
it('should throw in case of bad type argument', async({page, server}) => {
|
||||
it('should throw in case of bad type argument', async ({page, server}) => {
|
||||
let error = null;
|
||||
await page.emulateMedia({ media: 'bad' as any}).catch(e => error = e);
|
||||
expect(error.message).toContain('media: expected one of (screen|print|null)');
|
||||
});
|
||||
|
||||
it('should emulate scheme work', async({page, server}) => {
|
||||
it('should emulate scheme work', async ({page, server}) => {
|
||||
await page.emulateMedia({ colorScheme: 'light' });
|
||||
expect(await page.evaluate(() => matchMedia('(prefers-color-scheme: light)').matches)).toBe(true);
|
||||
expect(await page.evaluate(() => matchMedia('(prefers-color-scheme: dark)').matches)).toBe(false);
|
||||
@ -47,7 +47,7 @@ it('should emulate scheme work', async({page, server}) => {
|
||||
expect(await page.evaluate(() => matchMedia('(prefers-color-scheme: light)').matches)).toBe(false);
|
||||
});
|
||||
|
||||
it('should default to light', async({page, server}) => {
|
||||
it('should default to light', async ({page, server}) => {
|
||||
expect(await page.evaluate(() => matchMedia('(prefers-color-scheme: light)').matches)).toBe(true);
|
||||
expect(await page.evaluate(() => matchMedia('(prefers-color-scheme: dark)').matches)).toBe(false);
|
||||
|
||||
@ -60,13 +60,13 @@ it('should default to light', async({page, server}) => {
|
||||
expect(await page.evaluate(() => matchMedia('(prefers-color-scheme: light)').matches)).toBe(true);
|
||||
});
|
||||
|
||||
it('should throw in case of bad argument', async({page, server}) => {
|
||||
it('should throw in case of bad argument', async ({page, server}) => {
|
||||
let error = null;
|
||||
await page.emulateMedia({ colorScheme: 'bad' as any}).catch(e => error = e);
|
||||
expect(error.message).toContain('colorScheme: expected one of (dark|light|no-preference|null)');
|
||||
});
|
||||
|
||||
it('should work during navigation', async({page, server}) => {
|
||||
it('should work during navigation', async ({page, server}) => {
|
||||
await page.emulateMedia({ colorScheme: 'light' });
|
||||
const navigated = page.goto(server.EMPTY_PAGE);
|
||||
for (let i = 0; i < 9; i++) {
|
||||
@ -79,7 +79,7 @@ it('should work during navigation', async({page, server}) => {
|
||||
expect(await page.evaluate(() => matchMedia('(prefers-color-scheme: dark)').matches)).toBe(true);
|
||||
});
|
||||
|
||||
it('should work in popup', async({browser, server}) => {
|
||||
it('should work in popup', async ({browser, server}) => {
|
||||
{
|
||||
const context = await browser.newContext({ colorScheme: 'dark' });
|
||||
const page = await context.newPage();
|
||||
@ -105,7 +105,7 @@ it('should work in popup', async({browser, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should work in cross-process iframe', async({browser, server}) => {
|
||||
it('should work in cross-process iframe', async ({browser, server}) => {
|
||||
const page = await browser.newPage({ colorScheme: 'dark' });
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await utils.attachFrame(page, 'frame1', server.CROSS_PROCESS_PREFIX + '/empty.html');
|
||||
@ -114,7 +114,7 @@ it('should work in cross-process iframe', async({browser, server}) => {
|
||||
await page.close();
|
||||
});
|
||||
|
||||
it('should change the actual colors in css', async({page}) => {
|
||||
it('should change the actual colors in css', async ({page}) => {
|
||||
await page.setContent(`
|
||||
<style>
|
||||
@media (prefers-color-scheme: dark) {
|
||||
@ -137,12 +137,12 @@ it('should change the actual colors in css', async({page}) => {
|
||||
return page.$eval('div', div => window.getComputedStyle(div).backgroundColor);
|
||||
}
|
||||
|
||||
await page.emulateMedia({ colorScheme: "light" });
|
||||
await page.emulateMedia({ colorScheme: 'light' });
|
||||
expect(await getBackgroundColor()).toBe('rgb(255, 255, 255)');
|
||||
|
||||
await page.emulateMedia({ colorScheme: "dark" });
|
||||
await page.emulateMedia({ colorScheme: 'dark' });
|
||||
expect(await getBackgroundColor()).toBe('rgb(0, 0, 0)');
|
||||
|
||||
await page.emulateMedia({ colorScheme: "light" });
|
||||
await page.emulateMedia({ colorScheme: 'light' });
|
||||
expect(await getBackgroundColor()).toBe('rgb(255, 255, 255)');
|
||||
})
|
||||
});
|
||||
|
@ -17,24 +17,24 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should work', async({page, server}) => {
|
||||
it('should work', async ({page, server}) => {
|
||||
const windowHandle = await page.evaluateHandle(() => window);
|
||||
expect(windowHandle).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should accept object handle as an argument', async({page, server}) => {
|
||||
it('should accept object handle as an argument', async ({page, server}) => {
|
||||
const navigatorHandle = await page.evaluateHandle(() => navigator);
|
||||
const text = await page.evaluate(e => e.userAgent, navigatorHandle);
|
||||
expect(text).toContain('Mozilla');
|
||||
});
|
||||
|
||||
it('should accept object handle to primitive types', async({page, server}) => {
|
||||
it('should accept object handle to primitive types', async ({page, server}) => {
|
||||
const aHandle = await page.evaluateHandle(() => 5);
|
||||
const isFive = await page.evaluate(e => Object.is(e, 5), aHandle);
|
||||
expect(isFive).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should accept nested handle', async({page, server}) => {
|
||||
it('should accept nested handle', async ({page, server}) => {
|
||||
const foo = await page.evaluateHandle(() => ({ x: 1, y: 'foo' }));
|
||||
const result = await page.evaluate(({ foo }) => {
|
||||
return foo;
|
||||
@ -42,7 +42,7 @@ it('should accept nested handle', async({page, server}) => {
|
||||
expect(result).toEqual({ x: 1, y: 'foo' });
|
||||
});
|
||||
|
||||
it('should accept nested window handle', async({page, server}) => {
|
||||
it('should accept nested window handle', async ({page, server}) => {
|
||||
const foo = await page.evaluateHandle(() => window);
|
||||
const result = await page.evaluate(({ foo }) => {
|
||||
return foo === window;
|
||||
@ -50,7 +50,7 @@ it('should accept nested window handle', async({page, server}) => {
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should accept multiple nested handles', async({page, server}) => {
|
||||
it('should accept multiple nested handles', async ({page, server}) => {
|
||||
const foo = await page.evaluateHandle(() => ({ x: 1, y: 'foo' }));
|
||||
const bar = await page.evaluateHandle(() => 5);
|
||||
const baz = await page.evaluateHandle(() => (['baz']));
|
||||
@ -63,29 +63,29 @@ it('should accept multiple nested handles', async({page, server}) => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw for circular objects', async({page, server}) => {
|
||||
it('should throw for circular objects', async ({page, server}) => {
|
||||
const a = { x: 1 };
|
||||
a['y'] = a;
|
||||
const error = await page.evaluate(x => x, a).catch(e => e);
|
||||
expect(error.message).toContain('Argument is a circular structure');
|
||||
});
|
||||
|
||||
it('should accept same handle multiple times', async({page, server}) => {
|
||||
it('should accept same handle multiple times', async ({page, server}) => {
|
||||
const foo = await page.evaluateHandle(() => 1);
|
||||
expect(await page.evaluate(x => x, { foo, bar: [foo], baz: { foo }})).toEqual({ foo: 1, bar: [1], baz: { foo: 1 } });
|
||||
});
|
||||
|
||||
it('should accept same nested object multiple times', async({page, server}) => {
|
||||
it('should accept same nested object multiple times', async ({page, server}) => {
|
||||
const foo = { x: 1 };
|
||||
expect(await page.evaluate(x => x, { foo, bar: [foo], baz: { foo }})).toEqual({ foo: { x: 1 }, bar: [{ x : 1 }], baz: { foo: { x : 1 } } });
|
||||
expect(await page.evaluate(x => x, { foo, bar: [foo], baz: { foo }})).toEqual({ foo: { x: 1 }, bar: [{ x: 1 }], baz: { foo: { x: 1 } } });
|
||||
});
|
||||
|
||||
it('should accept object handle to unserializable value', async({page, server}) => {
|
||||
it('should accept object handle to unserializable value', async ({page, server}) => {
|
||||
const aHandle = await page.evaluateHandle(() => Infinity);
|
||||
expect(await page.evaluate(e => Object.is(e, Infinity), aHandle)).toBe(true);
|
||||
});
|
||||
|
||||
it('should pass configurable args', async({page, server}) => {
|
||||
it('should pass configurable args', async ({page, server}) => {
|
||||
const result = await page.evaluate(arg => {
|
||||
if (arg.foo !== 42)
|
||||
throw new Error('Not a 42');
|
||||
@ -100,7 +100,7 @@ it('should pass configurable args', async({page, server}) => {
|
||||
expect(result).toEqual({});
|
||||
});
|
||||
|
||||
it('should work with primitives', async({page, server}) => {
|
||||
it('should work with primitives', async ({page, server}) => {
|
||||
const aHandle = await page.evaluateHandle(() => {
|
||||
window['FOO'] = 123;
|
||||
return window;
|
||||
|
@ -169,10 +169,10 @@ it('should work right after a cross-origin navigation', async ({ page, server })
|
||||
|
||||
it('should work from-inside an exposed function', async ({ page, server }) => {
|
||||
// Setup inpage callback, which calls Page.evaluate
|
||||
await page.exposeFunction('callController', async function (a, b) {
|
||||
await page.exposeFunction('callController', async function(a, b) {
|
||||
return await page.evaluate(({ a, b }) => a * b, { a, b });
|
||||
});
|
||||
const result = await page.evaluate(async function () {
|
||||
const result = await page.evaluate(async function() {
|
||||
return await window['callController'](9, 3);
|
||||
});
|
||||
expect(result).toBe(27);
|
||||
@ -180,7 +180,7 @@ it('should work from-inside an exposed function', async ({ page, server }) => {
|
||||
|
||||
it('should reject promise with exception', async ({ page, server }) => {
|
||||
let error = null;
|
||||
//@ts-ignore
|
||||
// @ts-ignore
|
||||
await page.evaluate(() => not_existing_object.property).catch(e => error = e);
|
||||
expect(error).toBeTruthy();
|
||||
expect(error.message).toContain('not_existing_object');
|
||||
@ -253,21 +253,21 @@ it('should work with overwritten Promise', async ({ page, server }) => {
|
||||
finally(f) {
|
||||
return wrap(this._promise.finally(f));
|
||||
}
|
||||
};
|
||||
}
|
||||
const wrap = p => {
|
||||
const result = new Promise2(() => { });
|
||||
result._promise = p;
|
||||
return result;
|
||||
};
|
||||
//@ts-ignore;
|
||||
// @ts-ignore;
|
||||
window.Promise = Promise2;
|
||||
window["__Promise2"] = Promise2;
|
||||
window['__Promise2'] = Promise2;
|
||||
});
|
||||
|
||||
// Sanity check.
|
||||
expect(await page.evaluate(() => {
|
||||
const p = Promise.all([Promise.race([]), new Promise(() => { }).then(() => { })]);
|
||||
return p instanceof window["__Promise2"];
|
||||
return p instanceof window['__Promise2'];
|
||||
})).toBe(true);
|
||||
|
||||
// Now, the new promise should be awaitable.
|
||||
@ -279,27 +279,27 @@ it('should throw when passed more than one parameter', async ({ page, server })
|
||||
let error;
|
||||
await f().catch(e => error = e);
|
||||
expect('' + error).toContain('Too many arguments');
|
||||
}
|
||||
//@ts-ignore
|
||||
};
|
||||
// @ts-ignore
|
||||
await expectThrow(() => page.evaluate((a, b) => false, 1, 2));
|
||||
//@ts-ignore
|
||||
// @ts-ignore
|
||||
await expectThrow(() => page.evaluateHandle((a, b) => false, 1, 2));
|
||||
//@ts-ignore
|
||||
// @ts-ignore
|
||||
await expectThrow(() => page.$eval('sel', (a, b) => false, 1, 2));
|
||||
//@ts-ignore
|
||||
// @ts-ignore
|
||||
await expectThrow(() => page.$$eval('sel', (a, b) => false, 1, 2));
|
||||
//@ts-ignore
|
||||
// @ts-ignore
|
||||
await expectThrow(() => page.evaluate((a, b) => false, 1, 2));
|
||||
const frame = page.mainFrame();
|
||||
//@ts-ignore
|
||||
// @ts-ignore
|
||||
await expectThrow(() => frame.evaluate((a, b) => false, 1, 2));
|
||||
//@ts-ignore
|
||||
// @ts-ignore
|
||||
await expectThrow(() => frame.evaluateHandle((a, b) => false, 1, 2));
|
||||
//@ts-ignore
|
||||
// @ts-ignore
|
||||
await expectThrow(() => frame.$eval('sel', (a, b) => false, 1, 2));
|
||||
//@ts-ignore
|
||||
// @ts-ignore
|
||||
await expectThrow(() => frame.$$eval('sel', (a, b) => false, 1, 2));
|
||||
//@ts-ignore
|
||||
// @ts-ignore
|
||||
await expectThrow(() => frame.evaluate((a, b) => false, 1, 2));
|
||||
});
|
||||
|
||||
@ -471,25 +471,25 @@ it('should work with new Function() and CSP', async ({ page, server }) => {
|
||||
|
||||
it('should work with non-strict expressions', async ({ page, server }) => {
|
||||
expect(await page.evaluate(() => {
|
||||
//@ts-ignore
|
||||
// @ts-ignore
|
||||
y = 3.14;
|
||||
//@ts-ignore
|
||||
// @ts-ignore
|
||||
return y;
|
||||
})).toBe(3.14);
|
||||
});
|
||||
|
||||
it('should respect use strict expression', async ({ page, server }) => {
|
||||
const error = await page.evaluate(() => {
|
||||
"use strict";
|
||||
//@ts-ignore
|
||||
'use strict';
|
||||
// @ts-ignore
|
||||
variableY = 3.14;
|
||||
//@ts-ignore
|
||||
// @ts-ignore
|
||||
return variableY;
|
||||
}).catch(e => e);
|
||||
expect(error.message).toContain('variableY');
|
||||
});
|
||||
|
||||
it('should not leak utility script', async function ({ page, server }) {
|
||||
it('should not leak utility script', async function({ page, server }) {
|
||||
expect(await page.evaluate(() => this === window)).toBe(true);
|
||||
});
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
import './playwright.fixtures';
|
||||
import util from 'util';
|
||||
|
||||
it('should work', async({page, server}) => {
|
||||
it('should work', async ({page, server}) => {
|
||||
let message = null;
|
||||
page.once('console', m => message = m);
|
||||
await Promise.all([
|
||||
@ -32,24 +32,24 @@ it('should work', async({page, server}) => {
|
||||
expect(await message.args()[2].jsonValue()).toEqual({foo: 'bar'});
|
||||
});
|
||||
|
||||
it('should emit same log twice', async({page, server}) => {
|
||||
it('should emit same log twice', async ({page, server}) => {
|
||||
const messages = [];
|
||||
page.on('console', m => messages.push(m.text()));
|
||||
await page.evaluate(() => { for (let i = 0; i < 2; ++i ) console.log('hello'); } );
|
||||
await page.evaluate(() => { for (let i = 0; i < 2; ++i) console.log('hello'); });
|
||||
expect(messages).toEqual(['hello', 'hello']);
|
||||
});
|
||||
|
||||
it('should use text() for inspection', async({page}) => {
|
||||
it('should use text() for inspection', async ({page}) => {
|
||||
let text;
|
||||
const inspect = value => {
|
||||
text = util.inspect(value);
|
||||
}
|
||||
};
|
||||
page.on('console', inspect);
|
||||
await page.evaluate(() => console.log('Hello world'));
|
||||
expect(text).toEqual('Hello world');
|
||||
});
|
||||
|
||||
it('should work for different console API calls', async({page, server}) => {
|
||||
it('should work for different console API calls', async ({page, server}) => {
|
||||
const messages = [];
|
||||
page.on('console', msg => messages.push(msg));
|
||||
// All console events will be reported before `page.evaluate` is finished.
|
||||
@ -76,7 +76,7 @@ it('should work for different console API calls', async({page, server}) => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not fail for window object', async({page, server}) => {
|
||||
it('should not fail for window object', async ({page, server}) => {
|
||||
let message = null;
|
||||
page.once('console', msg => message = msg);
|
||||
await Promise.all([
|
||||
@ -86,7 +86,7 @@ it('should not fail for window object', async({page, server}) => {
|
||||
expect(message.text()).toBe('JSHandle@object');
|
||||
});
|
||||
|
||||
it('should trigger correct Log', async({page, server}) => {
|
||||
it('should trigger correct Log', async ({page, server}) => {
|
||||
await page.goto('about:blank');
|
||||
const [message] = await Promise.all([
|
||||
page.waitForEvent('console'),
|
||||
@ -96,10 +96,10 @@ it('should trigger correct Log', async({page, server}) => {
|
||||
expect(message.type()).toEqual('error');
|
||||
});
|
||||
|
||||
it('should have location for console API calls', async({page, server}) => {
|
||||
it('should have location for console API calls', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const [message] = await Promise.all([
|
||||
page.waitForEvent('console', m => m.text() === 'yellow' ),
|
||||
page.waitForEvent('console', m => m.text() === 'yellow'),
|
||||
page.goto(server.PREFIX + '/consolelog.html'),
|
||||
]);
|
||||
expect(message.type()).toBe('log');
|
||||
@ -112,15 +112,15 @@ it('should have location for console API calls', async({page, server}) => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should not throw when there are console messages in detached iframes', async({page, server}) => {
|
||||
it('should not throw when there are console messages in detached iframes', async ({page, server}) => {
|
||||
// @see https://github.com/GoogleChrome/puppeteer/issues/3865
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const [popup] = await Promise.all([
|
||||
page.waitForEvent('popup'),
|
||||
page.evaluate(async() => {
|
||||
page.evaluate(async () => {
|
||||
// 1. Create a popup that Playwright is not connected to.
|
||||
const win = window.open('');
|
||||
window["_popup"] = win;
|
||||
window['_popup'] = win;
|
||||
if (window.document.readyState !== 'complete')
|
||||
await new Promise(f => window.addEventListener('load', f));
|
||||
// 2. In this popup, create an iframe that console.logs a message.
|
||||
|
@ -26,13 +26,13 @@ function crash(pageImpl, browserName) {
|
||||
pageImpl._delegate._session.send('Page.crash', {}).catch(e => {});
|
||||
}
|
||||
|
||||
it.fail(options.WIRE)('should emit crash event when page crashes', async({page, browserName, toImpl}) => {
|
||||
it.fail(options.WIRE)('should emit crash event when page crashes', async ({page, browserName, toImpl}) => {
|
||||
await page.setContent(`<div>This page should crash</div>`);
|
||||
crash(toImpl(page), browserName);
|
||||
await new Promise(f => page.on('crash', f));
|
||||
});
|
||||
|
||||
it.fail(options.WIRE)('should throw on any action after page crashes', async({page, browserName, toImpl}) => {
|
||||
it.fail(options.WIRE)('should throw on any action after page crashes', async ({page, browserName, toImpl}) => {
|
||||
await page.setContent(`<div>This page should crash</div>`);
|
||||
crash(toImpl(page), browserName);
|
||||
await page.waitForEvent('crash');
|
||||
@ -41,7 +41,7 @@ it.fail(options.WIRE)('should throw on any action after page crashes', async({pa
|
||||
expect(err.message).toContain('crash');
|
||||
});
|
||||
|
||||
it.fail(options.WIRE)('should cancel waitForEvent when page crashes', async({page, browserName, toImpl}) => {
|
||||
it.fail(options.WIRE)('should cancel waitForEvent when page crashes', async ({page, browserName, toImpl}) => {
|
||||
await page.setContent(`<div>This page should crash</div>`);
|
||||
const promise = page.waitForEvent('response').catch(e => e);
|
||||
crash(toImpl(page), browserName);
|
||||
@ -49,7 +49,7 @@ it.fail(options.WIRE)('should cancel waitForEvent when page crashes', async({pag
|
||||
expect(error.message).toContain('Page crashed');
|
||||
});
|
||||
|
||||
it.fixme(options.WIRE)('should cancel navigation when page crashes', async({page, browserName, toImpl, server}) => {
|
||||
it.fixme(options.WIRE)('should cancel navigation when page crashes', async ({page, browserName, toImpl, server}) => {
|
||||
await page.setContent(`<div>This page should crash</div>`);
|
||||
server.setRoute('/one-style.css', () => {});
|
||||
const promise = page.goto(server.PREFIX + '/one-style.html').catch(e => e);
|
||||
@ -59,7 +59,7 @@ it.fixme(options.WIRE)('should cancel navigation when page crashes', async({page
|
||||
expect(error.message).toContain('Navigation failed because page crashed');
|
||||
});
|
||||
|
||||
it.fixme(options.WIRE)('should be able to close context when page crashes', async({page, browserName, toImpl}) => {
|
||||
it.fixme(options.WIRE)('should be able to close context when page crashes', async ({page, browserName, toImpl}) => {
|
||||
await page.setContent(`<div>This page should crash</div>`);
|
||||
crash(toImpl(page), browserName);
|
||||
await page.waitForEvent('crash');
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
it('Page.Events.Request', async({page, server}) => {
|
||||
it('Page.Events.Request', async ({page, server}) => {
|
||||
const requests = [];
|
||||
page.on('request', request => requests.push(request));
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -30,7 +30,7 @@ it('Page.Events.Request', async({page, server}) => {
|
||||
expect(requests[0].frame().url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
|
||||
it('Page.Events.Response', async({page, server}) => {
|
||||
it('Page.Events.Response', async ({page, server}) => {
|
||||
const responses = [];
|
||||
page.on('response', response => responses.push(response));
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -41,7 +41,7 @@ it('Page.Events.Response', async({page, server}) => {
|
||||
expect(responses[0].request()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('Page.Events.RequestFailed', async({page, server}) => {
|
||||
it('Page.Events.RequestFailed', async ({page, server}) => {
|
||||
server.setRoute('/one-style.css', (req, res) => {
|
||||
res.setHeader('Content-Type', 'text/css');
|
||||
res.connection.destroy();
|
||||
@ -68,7 +68,7 @@ it('Page.Events.RequestFailed', async({page, server}) => {
|
||||
expect(failedRequests[0].frame()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('Page.Events.RequestFinished', async({page, server}) => {
|
||||
it('Page.Events.RequestFinished', async ({page, server}) => {
|
||||
const [response] = await Promise.all([
|
||||
page.goto(server.EMPTY_PAGE),
|
||||
page.waitForEvent('requestfinished')
|
||||
@ -81,17 +81,17 @@ it('Page.Events.RequestFinished', async({page, server}) => {
|
||||
expect(request.failure()).toBe(null);
|
||||
});
|
||||
|
||||
it('should fire events in proper order', async({page, server}) => {
|
||||
it('should fire events in proper order', async ({page, server}) => {
|
||||
const events = [];
|
||||
page.on('request', request => events.push('request'));
|
||||
page.on('response', response => events.push('response'));
|
||||
const response = await page.goto(server.EMPTY_PAGE);
|
||||
expect(await response.finished()).toBe(null);
|
||||
events.push('requestfinished')
|
||||
events.push('requestfinished');
|
||||
expect(events).toEqual(['request', 'response', 'requestfinished']);
|
||||
});
|
||||
|
||||
it('should support redirects', async({page, server}) => {
|
||||
it('should support redirects', async ({page, server}) => {
|
||||
const events = [];
|
||||
page.on('request', request => events.push(`${request.method()} ${request.url()}`));
|
||||
page.on('response', response => events.push(`${response.status()} ${response.url()}`));
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
it('should fire', async({page, server}) => {
|
||||
it('should fire', async ({page, server}) => {
|
||||
const [error] = await Promise.all([
|
||||
page.waitForEvent('pageerror'),
|
||||
page.goto(server.PREFIX + '/error.html'),
|
||||
@ -31,7 +31,7 @@ it('should fire', async({page, server}) => {
|
||||
expect(error.stack).toBe(stack);
|
||||
});
|
||||
|
||||
it.fail(options.WEBKIT)('should contain sourceURL', async({page, server}) => {
|
||||
it.fail(options.WEBKIT)('should contain sourceURL', async ({page, server}) => {
|
||||
const [error] = await Promise.all([
|
||||
page.waitForEvent('pageerror'),
|
||||
page.goto(server.PREFIX + '/error.html'),
|
||||
|
@ -16,32 +16,32 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should work', async({browser}) => {
|
||||
it('should work', async ({browser}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const [popup] = await Promise.all([
|
||||
page.waitForEvent('popup'),
|
||||
page.evaluate(() => window["__popup"] = window.open('about:blank')),
|
||||
page.evaluate(() => window['__popup'] = window.open('about:blank')),
|
||||
]);
|
||||
expect(await page.evaluate(() => !!window.opener)).toBe(false);
|
||||
expect(await popup.evaluate(() => !!window.opener)).toBe(true);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work with window features', async({browser, server}) => {
|
||||
it('should work with window features', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const [popup] = await Promise.all([
|
||||
page.waitForEvent('popup'),
|
||||
page.evaluate(() => window["__popup"] = window.open(window.location.href, 'Title', 'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=780,height=200,top=0,left=0')),
|
||||
page.evaluate(() => window['__popup'] = window.open(window.location.href, 'Title', 'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=780,height=200,top=0,left=0')),
|
||||
]);
|
||||
expect(await page.evaluate(() => !!window.opener)).toBe(false);
|
||||
expect(await popup.evaluate(() => !!window.opener)).toBe(true);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should emit for immediately closed popups', async({browser}) => {
|
||||
it('should emit for immediately closed popups', async ({browser}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const [popup] = await Promise.all([
|
||||
@ -55,7 +55,7 @@ it('should emit for immediately closed popups', async({browser}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should emit for immediately closed popups 2', async({browser, server}) => {
|
||||
it('should emit for immediately closed popups 2', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -70,7 +70,7 @@ it('should emit for immediately closed popups 2', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should be able to capture alert', async({browser}) => {
|
||||
it('should be able to capture alert', async ({browser}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const evaluatePromise = page.evaluate(() => {
|
||||
@ -85,24 +85,24 @@ it('should be able to capture alert', async({browser}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work with empty url', async({browser}) => {
|
||||
it('should work with empty url', async ({browser}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const [popup] = await Promise.all([
|
||||
page.waitForEvent('popup'),
|
||||
page.evaluate(() => window["__popup"] = window.open('')),
|
||||
page.evaluate(() => window['__popup'] = window.open('')),
|
||||
]);
|
||||
expect(await page.evaluate(() => !!window.opener)).toBe(false);
|
||||
expect(await popup.evaluate(() => !!window.opener)).toBe(true);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work with noopener and no url', async({browser}) => {
|
||||
it('should work with noopener and no url', async ({browser}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const [popup] = await Promise.all([
|
||||
page.waitForEvent('popup'),
|
||||
page.evaluate(() => window["__popup"] = window.open(undefined, null, 'noopener')),
|
||||
page.evaluate(() => window['__popup'] = window.open(undefined, null, 'noopener')),
|
||||
]);
|
||||
// Chromium reports `about:blank#blocked` here.
|
||||
expect(popup.url().split('#')[0]).toBe('about:blank');
|
||||
@ -111,32 +111,32 @@ it('should work with noopener and no url', async({browser}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work with noopener and about:blank', async({browser}) => {
|
||||
it('should work with noopener and about:blank', async ({browser}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const [popup] = await Promise.all([
|
||||
page.waitForEvent('popup'),
|
||||
page.evaluate(() => window["__popup"] = window.open('about:blank', null, 'noopener')),
|
||||
page.evaluate(() => window['__popup'] = window.open('about:blank', null, 'noopener')),
|
||||
]);
|
||||
expect(await page.evaluate(() => !!window.opener)).toBe(false);
|
||||
expect(await popup.evaluate(() => !!window.opener)).toBe(false);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work with noopener and url', async({browser, server}) => {
|
||||
it('should work with noopener and url', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const [popup] = await Promise.all([
|
||||
page.waitForEvent('popup'),
|
||||
page.evaluate(url => window["__popup"] = window.open(url, null, 'noopener'), server.EMPTY_PAGE),
|
||||
page.evaluate(url => window['__popup'] = window.open(url, null, 'noopener'), server.EMPTY_PAGE),
|
||||
]);
|
||||
expect(await page.evaluate(() => !!window.opener)).toBe(false);
|
||||
expect(await popup.evaluate(() => !!window.opener)).toBe(false);
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work with clicking target=_blank', async({browser, server}) => {
|
||||
it('should work with clicking target=_blank', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -150,7 +150,7 @@ it('should work with clicking target=_blank', async({browser, server}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work with fake-clicking target=_blank and rel=noopener', async({browser, server}) => {
|
||||
it('should work with fake-clicking target=_blank and rel=noopener', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -164,7 +164,7 @@ it('should work with fake-clicking target=_blank and rel=noopener', async({brows
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work with clicking target=_blank and rel=noopener', async({browser, server}) => {
|
||||
it('should work with clicking target=_blank and rel=noopener', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -178,7 +178,7 @@ it('should work with clicking target=_blank and rel=noopener', async({browser, s
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should not treat navigations as new popups', async({browser, server}) => {
|
||||
it('should not treat navigations as new popups', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
|
@ -18,14 +18,14 @@
|
||||
import './playwright.fixtures';
|
||||
import utils from './utils';
|
||||
|
||||
it('should fire for navigation requests', async({page, server}) => {
|
||||
it('should fire for navigation requests', async ({page, server}) => {
|
||||
const requests = [];
|
||||
page.on('request', request => requests.push(request));
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect(requests.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should fire for iframes', async({page, server}) => {
|
||||
it('should fire for iframes', async ({page, server}) => {
|
||||
const requests = [];
|
||||
page.on('request', request => requests.push(request));
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -33,7 +33,7 @@ it('should fire for iframes', async({page, server}) => {
|
||||
expect(requests.length).toBe(2);
|
||||
});
|
||||
|
||||
it('should fire for fetches', async({page, server}) => {
|
||||
it('should fire for fetches', async ({page, server}) => {
|
||||
const requests = [];
|
||||
page.on('request', request => requests.push(request));
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -41,11 +41,11 @@ it('should fire for fetches', async({page, server}) => {
|
||||
expect(requests.length).toBe(2);
|
||||
});
|
||||
|
||||
it('should report requests and responses handled by service worker', async({page, server}) => {
|
||||
it('should report requests and responses handled by service worker', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/serviceworkers/fetchdummy/sw.html');
|
||||
await page.evaluate(() => window["activationPromise"]);
|
||||
await page.evaluate(() => window['activationPromise']);
|
||||
const [swResponse, request] = await Promise.all([
|
||||
page.evaluate(() => window["fetchDummy"]('foo')),
|
||||
page.evaluate(() => window['fetchDummy']('foo')),
|
||||
page.waitForEvent('request'),
|
||||
]);
|
||||
expect(swResponse).toBe('responseFromServiceWorker:foo');
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('exposeBinding should work', async({browser}) => {
|
||||
it('exposeBinding should work', async ({browser}) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
let bindingSource;
|
||||
@ -35,7 +35,7 @@ it('exposeBinding should work', async({browser}) => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it('should work', async({page, server}) => {
|
||||
it('should work', async ({page, server}) => {
|
||||
await page.exposeFunction('compute', function(a, b) {
|
||||
return a * b;
|
||||
});
|
||||
@ -45,7 +45,7 @@ it('should work', async({page, server}) => {
|
||||
expect(result).toBe(36);
|
||||
});
|
||||
|
||||
it('should work with handles and complex objects', async({page, server}) => {
|
||||
it('should work with handles and complex objects', async ({page, server}) => {
|
||||
const fooHandle = await page.evaluateHandle(() => {
|
||||
window['fooValue'] = { bar: 2 };
|
||||
return window['fooValue'];
|
||||
@ -61,13 +61,13 @@ it('should work with handles and complex objects', async({page, server}) => {
|
||||
expect(equals).toBe(true);
|
||||
});
|
||||
|
||||
it('should throw exception in page context', async({page, server}) => {
|
||||
it('should throw exception in page context', async ({page, server}) => {
|
||||
await page.exposeFunction('woof', function() {
|
||||
throw new Error('WOOF WOOF');
|
||||
});
|
||||
const {message, stack} = await page.evaluate(async() => {
|
||||
const {message, stack} = await page.evaluate(async () => {
|
||||
try {
|
||||
await window["woof"]();
|
||||
await window['woof']();
|
||||
} catch (e) {
|
||||
return {message: e.message, stack: e.stack};
|
||||
}
|
||||
@ -76,13 +76,13 @@ it('should throw exception in page context', async({page, server}) => {
|
||||
expect(stack).toContain(__filename);
|
||||
});
|
||||
|
||||
it('should support throwing "null"', async({page, server}) => {
|
||||
it('should support throwing "null"', async ({page, server}) => {
|
||||
await page.exposeFunction('woof', function() {
|
||||
throw null;
|
||||
});
|
||||
const thrown = await page.evaluate(async() => {
|
||||
const thrown = await page.evaluate(async () => {
|
||||
try {
|
||||
await window["woof"]();
|
||||
await window['woof']();
|
||||
} catch (e) {
|
||||
return e;
|
||||
}
|
||||
@ -90,17 +90,17 @@ it('should support throwing "null"', async({page, server}) => {
|
||||
expect(thrown).toBe(null);
|
||||
});
|
||||
|
||||
it('should be callable from-inside addInitScript', async({page, server}) => {
|
||||
it('should be callable from-inside addInitScript', async ({page, server}) => {
|
||||
let called = false;
|
||||
await page.exposeFunction('woof', function() {
|
||||
called = true;
|
||||
});
|
||||
await page.addInitScript(() => window["woof"]());
|
||||
await page.addInitScript(() => window['woof']());
|
||||
await page.reload();
|
||||
expect(called).toBe(true);
|
||||
});
|
||||
|
||||
it('should survive navigation', async({page, server}) => {
|
||||
it('should survive navigation', async ({page, server}) => {
|
||||
await page.exposeFunction('compute', function(a, b) {
|
||||
return a * b;
|
||||
});
|
||||
@ -112,7 +112,7 @@ it('should survive navigation', async({page, server}) => {
|
||||
expect(result).toBe(36);
|
||||
});
|
||||
|
||||
it('should await returned promise', async({page, server}) => {
|
||||
it('should await returned promise', async ({page, server}) => {
|
||||
await page.exposeFunction('compute', function(a, b) {
|
||||
return Promise.resolve(a * b);
|
||||
});
|
||||
@ -123,7 +123,7 @@ it('should await returned promise', async({page, server}) => {
|
||||
expect(result).toBe(15);
|
||||
});
|
||||
|
||||
it('should work on frames', async({page, server}) => {
|
||||
it('should work on frames', async ({page, server}) => {
|
||||
await page.exposeFunction('compute', function(a, b) {
|
||||
return Promise.resolve(a * b);
|
||||
});
|
||||
@ -136,7 +136,7 @@ it('should work on frames', async({page, server}) => {
|
||||
expect(result).toBe(15);
|
||||
});
|
||||
|
||||
it('should work on frames before navigation', async({page, server}) => {
|
||||
it('should work on frames before navigation', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/frames/nested-frames.html');
|
||||
await page.exposeFunction('compute', function(a, b) {
|
||||
return Promise.resolve(a * b);
|
||||
@ -149,7 +149,7 @@ it('should work on frames before navigation', async({page, server}) => {
|
||||
expect(result).toBe(15);
|
||||
});
|
||||
|
||||
it('should work after cross origin navigation', async({page, server}) => {
|
||||
it('should work after cross origin navigation', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.exposeFunction('compute', function(a, b) {
|
||||
return a * b;
|
||||
@ -162,10 +162,10 @@ it('should work after cross origin navigation', async({page, server}) => {
|
||||
expect(result).toBe(36);
|
||||
});
|
||||
|
||||
it('should work with complex objects', async({page, server}) => {
|
||||
it('should work with complex objects', async ({page, server}) => {
|
||||
await page.exposeFunction('complexObject', function(a, b) {
|
||||
return {x: a.x + b.x};
|
||||
});
|
||||
const result = await page.evaluate(async() => window['complexObject']({x: 5}, {x: 2}));
|
||||
const result = await page.evaluate(async () => window['complexObject']({x: 5}, {x: 2}));
|
||||
expect(result.x).toBe(7);
|
||||
});
|
||||
|
@ -22,19 +22,19 @@ async function giveItAChanceToFill(page) {
|
||||
await page.evaluate(() => new Promise(f => requestAnimationFrame(() => requestAnimationFrame(f))));
|
||||
}
|
||||
|
||||
it('should fill textarea', async({page, server}) => {
|
||||
it('should fill textarea', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
await page.fill('textarea', 'some value');
|
||||
expect(await page.evaluate(() => window['result'])).toBe('some value');
|
||||
});
|
||||
|
||||
it('should fill input', async({page, server}) => {
|
||||
it('should fill input', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
await page.fill('input', 'some value');
|
||||
expect(await page.evaluate(() => window['result'])).toBe('some value');
|
||||
});
|
||||
|
||||
it('should throw on unsupported inputs', async({page, server}) => {
|
||||
it('should throw on unsupported inputs', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
for (const type of ['color', 'file']) {
|
||||
await page.$eval('input', (input, type) => input.setAttribute('type', type), type);
|
||||
@ -44,7 +44,7 @@ it('should throw on unsupported inputs', async({page, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should fill different input types', async({page, server}) => {
|
||||
it('should fill different input types', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
for (const type of ['password', 'search', 'tel', 'text', 'url']) {
|
||||
await page.$eval('input', (input, type) => input.setAttribute('type', type), type);
|
||||
@ -53,50 +53,50 @@ it('should fill different input types', async({page, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should fill date input after clicking', async({page, server}) => {
|
||||
it('should fill date input after clicking', async ({page, server}) => {
|
||||
await page.setContent('<input type=date>');
|
||||
await page.click('input');
|
||||
await page.fill('input', '2020-03-02');
|
||||
expect(await page.$eval('input', input => input.value)).toBe('2020-03-02');
|
||||
});
|
||||
|
||||
it.skip(options.WEBKIT)('should throw on incorrect date', async({page, server}) => {
|
||||
it.skip(options.WEBKIT)('should throw on incorrect date', async ({page, server}) => {
|
||||
await page.setContent('<input type=date>');
|
||||
const error = await page.fill('input', '2020-13-05').catch(e => e);
|
||||
expect(error.message).toContain('Malformed value');
|
||||
});
|
||||
|
||||
it('should fill time input', async({page, server}) => {
|
||||
it('should fill time input', async ({page, server}) => {
|
||||
await page.setContent('<input type=time>');
|
||||
await page.fill('input', '13:15');
|
||||
expect(await page.$eval('input', input => input.value)).toBe('13:15');
|
||||
});
|
||||
|
||||
it.skip(options.WEBKIT)('should throw on incorrect time', async({page, server}) => {
|
||||
it.skip(options.WEBKIT)('should throw on incorrect time', async ({page, server}) => {
|
||||
await page.setContent('<input type=time>');
|
||||
const error = await page.fill('input', '25:05').catch(e => e);
|
||||
expect(error.message).toContain('Malformed value');
|
||||
});
|
||||
|
||||
it('should fill datetime-local input', async({page, server}) => {
|
||||
it('should fill datetime-local input', async ({page, server}) => {
|
||||
await page.setContent('<input type=datetime-local>');
|
||||
await page.fill('input', '2020-03-02T05:15');
|
||||
expect(await page.$eval('input', input => input.value)).toBe('2020-03-02T05:15');
|
||||
});
|
||||
|
||||
it.skip(options.WEBKIT || options.FIREFOX)('should throw on incorrect datetime-local', async({page, server}) => {
|
||||
it.skip(options.WEBKIT || options.FIREFOX)('should throw on incorrect datetime-local', async ({page, server}) => {
|
||||
await page.setContent('<input type=datetime-local>');
|
||||
const error = await page.fill('input', 'abc').catch(e => e);
|
||||
expect(error.message).toContain('Malformed value');
|
||||
});
|
||||
|
||||
it('should fill contenteditable', async({page, server}) => {
|
||||
it('should fill contenteditable', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
await page.fill('div[contenteditable]', 'some value');
|
||||
expect(await page.$eval('div[contenteditable]', div => div.textContent)).toBe('some value');
|
||||
});
|
||||
|
||||
it('should fill elements with existing value and selection', async({page, server}) => {
|
||||
it('should fill elements with existing value and selection', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
|
||||
await page.$eval('input', input => input.value = 'value one');
|
||||
@ -122,21 +122,21 @@ it('should fill elements with existing value and selection', async({page, server
|
||||
expect(await page.$eval('div[contenteditable]', div => div.textContent)).toBe('replace with this');
|
||||
});
|
||||
|
||||
it('should throw when element is not an <input>, <textarea> or [contenteditable]', async({page, server}) => {
|
||||
it('should throw when element is not an <input>, <textarea> or [contenteditable]', async ({page, server}) => {
|
||||
let error = null;
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
await page.fill('body', '').catch(e => error = e);
|
||||
expect(error.message).toContain('Element is not an <input>');
|
||||
});
|
||||
|
||||
it('should throw if passed a non-string value', async({page, server}) => {
|
||||
it('should throw if passed a non-string value', async ({page, server}) => {
|
||||
let error = null;
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
await page.fill('textarea', 123 as any).catch(e => error = e);
|
||||
expect(error.message).toContain('value: expected string, got number');
|
||||
});
|
||||
|
||||
it('should retry on disabled element', async({page, server}) => {
|
||||
it('should retry on disabled element', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
await page.$eval('input', i => i.disabled = true);
|
||||
let done = false;
|
||||
@ -151,7 +151,7 @@ it('should retry on disabled element', async({page, server}) => {
|
||||
expect(await page.evaluate(() => window['result'])).toBe('some value');
|
||||
});
|
||||
|
||||
it('should retry on readonly element', async({page, server}) => {
|
||||
it('should retry on readonly element', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
await page.$eval('textarea', i => i.readOnly = true);
|
||||
let done = false;
|
||||
@ -166,7 +166,7 @@ it('should retry on readonly element', async({page, server}) => {
|
||||
expect(await page.evaluate(() => window['result'])).toBe('some value');
|
||||
});
|
||||
|
||||
it('should retry on invisible element', async({page, server}) => {
|
||||
it('should retry on invisible element', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
await page.$eval('input', i => i.style.display = 'none');
|
||||
let done = false;
|
||||
@ -181,7 +181,7 @@ it('should retry on invisible element', async({page, server}) => {
|
||||
expect(await page.evaluate(() => window['result'])).toBe('some value');
|
||||
});
|
||||
|
||||
it('should be able to fill the body', async({page}) => {
|
||||
it('should be able to fill the body', async ({page}) => {
|
||||
await page.setContent(`<body contentEditable="true"></body>`);
|
||||
await page.fill('body', 'some value');
|
||||
expect(await page.evaluate(() => document.body.textContent)).toBe('some value');
|
||||
@ -193,7 +193,7 @@ it('should fill fixed position input', async ({page}) => {
|
||||
expect(await page.evaluate(() => document.querySelector('input').value)).toBe('some value');
|
||||
});
|
||||
|
||||
it('should be able to fill when focus is in the wrong frame', async({page}) => {
|
||||
it('should be able to fill when focus is in the wrong frame', async ({page}) => {
|
||||
await page.setContent(`
|
||||
<div contentEditable="true"></div>
|
||||
<iframe></iframe>
|
||||
@ -203,32 +203,32 @@ it('should be able to fill when focus is in the wrong frame', async({page}) => {
|
||||
expect(await page.$eval('div', d => d.textContent)).toBe('some value');
|
||||
});
|
||||
|
||||
it('should be able to fill the input[type=number]', async({page}) => {
|
||||
it('should be able to fill the input[type=number]', async ({page}) => {
|
||||
await page.setContent(`<input id="input" type="number"></input>`);
|
||||
await page.fill('input', '42');
|
||||
expect(await page.evaluate(() => window['input'].value)).toBe('42');
|
||||
});
|
||||
|
||||
it('should be able to fill exponent into the input[type=number]', async({page}) => {
|
||||
it('should be able to fill exponent into the input[type=number]', async ({page}) => {
|
||||
await page.setContent(`<input id="input" type="number"></input>`);
|
||||
await page.fill('input', '-10e5');
|
||||
expect(await page.evaluate(() => window['input'].value)).toBe('-10e5');
|
||||
});
|
||||
|
||||
it('should be able to fill input[type=number] with empty string', async({page}) => {
|
||||
it('should be able to fill input[type=number] with empty string', async ({page}) => {
|
||||
await page.setContent(`<input id="input" type="number" value="123"></input>`);
|
||||
await page.fill('input', '');
|
||||
expect(await page.evaluate(() => window['input'].value)).toBe('');
|
||||
});
|
||||
|
||||
it('should not be able to fill text into the input[type=number]', async({page}) => {
|
||||
it('should not be able to fill text into the input[type=number]', async ({page}) => {
|
||||
await page.setContent(`<input id="input" type="number"></input>`);
|
||||
let error = null;
|
||||
await page.fill('input', 'abc').catch(e => error = e);
|
||||
expect(error.message).toContain('Cannot type text into input[type=number]');
|
||||
});
|
||||
|
||||
it('should be able to clear', async({page, server}) => {
|
||||
it('should be able to clear', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||
await page.fill('input', 'some value');
|
||||
expect(await page.evaluate(() => window['result'])).toBe('some value');
|
||||
|
@ -21,24 +21,24 @@ import utils from './utils';
|
||||
import path from 'path';
|
||||
import url from 'url';
|
||||
|
||||
it('should work', async({page, server}) => {
|
||||
it('should work', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
|
||||
it('should work with file URL', async({page, server}) => {
|
||||
it('should work with file URL', async ({page, server}) => {
|
||||
const fileurl = url.pathToFileURL(path.join(__dirname, 'assets', 'frames', 'two-frames.html')).href;
|
||||
await page.goto(fileurl);
|
||||
expect(page.url().toLowerCase()).toBe(fileurl.toLowerCase());
|
||||
expect(page.frames().length).toBe(3);
|
||||
});
|
||||
|
||||
it('should use http for no protocol', async({page, server}) => {
|
||||
it('should use http for no protocol', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE.substring('http://'.length));
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
|
||||
it('should work cross-process', async({page, server}) => {
|
||||
it('should work cross-process', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE);
|
||||
|
||||
@ -55,7 +55,7 @@ it('should work cross-process', async({page, server}) => {
|
||||
expect(response.url()).toBe(url);
|
||||
});
|
||||
|
||||
it('should capture iframe navigation request', async({page, server}) => {
|
||||
it('should capture iframe navigation request', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE);
|
||||
|
||||
@ -73,7 +73,7 @@ it('should capture iframe navigation request', async({page, server}) => {
|
||||
expect(requestFrame).toBe(page.frames()[1]);
|
||||
});
|
||||
|
||||
it('should capture cross-process iframe navigation request', async({page, server}) => {
|
||||
it('should capture cross-process iframe navigation request', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE);
|
||||
|
||||
@ -91,7 +91,7 @@ it('should capture cross-process iframe navigation request', async({page, server
|
||||
expect(requestFrame).toBe(page.frames()[1]);
|
||||
});
|
||||
|
||||
it('should work with anchor navigation', async({page, server}) => {
|
||||
it('should work with anchor navigation', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE);
|
||||
await page.goto(server.EMPTY_PAGE + '#foo');
|
||||
@ -100,7 +100,7 @@ it('should work with anchor navigation', async({page, server}) => {
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE + '#bar');
|
||||
});
|
||||
|
||||
it('should work with redirects', async({page, server}) => {
|
||||
it('should work with redirects', async ({page, server}) => {
|
||||
server.setRedirect('/redirect/1.html', '/redirect/2.html');
|
||||
server.setRedirect('/redirect/2.html', '/empty.html');
|
||||
const response = await page.goto(server.PREFIX + '/redirect/1.html');
|
||||
@ -108,17 +108,17 @@ it('should work with redirects', async({page, server}) => {
|
||||
expect(page.url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
|
||||
it('should navigate to about:blank', async({page, server}) => {
|
||||
it('should navigate to about:blank', async ({page, server}) => {
|
||||
const response = await page.goto('about:blank');
|
||||
expect(response).toBe(null);
|
||||
});
|
||||
|
||||
it('should return response when page changes its URL after load', async({page, server}) => {
|
||||
it('should return response when page changes its URL after load', async ({page, server}) => {
|
||||
const response = await page.goto(server.PREFIX + '/historyapi.html');
|
||||
expect(response.status()).toBe(200);
|
||||
});
|
||||
|
||||
it('should work with subframes return 204', async({page, server}) => {
|
||||
it('should work with subframes return 204', async ({page, server}) => {
|
||||
server.setRoute('/frames/frame.html', (req, res) => {
|
||||
res.statusCode = 204;
|
||||
res.end();
|
||||
@ -126,7 +126,7 @@ it('should work with subframes return 204', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/frames/one-frame.html');
|
||||
});
|
||||
|
||||
it('should work with subframes return 204 with domcontentloaded', async({page, server}) => {
|
||||
it('should work with subframes return 204 with domcontentloaded', async ({page, server}) => {
|
||||
server.setRoute('/frames/frame.html', (req, res) => {
|
||||
res.statusCode = 204;
|
||||
res.end();
|
||||
@ -134,7 +134,7 @@ it('should work with subframes return 204 with domcontentloaded', async({page, s
|
||||
await page.goto(server.PREFIX + '/frames/one-frame.html', { waitUntil: 'domcontentloaded' });
|
||||
});
|
||||
|
||||
it('should fail when server returns 204', async({page, server}) => {
|
||||
it('should fail when server returns 204', async ({page, server}) => {
|
||||
// Webkit just loads an empty page.
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
res.statusCode = 204;
|
||||
@ -151,12 +151,12 @@ it('should fail when server returns 204', async({page, server}) => {
|
||||
expect(error.message).toContain('NS_BINDING_ABORTED');
|
||||
});
|
||||
|
||||
it('should navigate to empty page with domcontentloaded', async({page, server}) => {
|
||||
it('should navigate to empty page with domcontentloaded', async ({page, server}) => {
|
||||
const response = await page.goto(server.EMPTY_PAGE, {waitUntil: 'domcontentloaded'});
|
||||
expect(response.status()).toBe(200);
|
||||
});
|
||||
|
||||
it('should work when page calls history API in beforeunload', async({page, server}) => {
|
||||
it('should work when page calls history API in beforeunload', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.evaluate(() => {
|
||||
window.addEventListener('beforeunload', () => history.replaceState(null, 'initial', window.location.href), false);
|
||||
@ -165,7 +165,7 @@ it('should work when page calls history API in beforeunload', async({page, serve
|
||||
expect(response.status()).toBe(200);
|
||||
});
|
||||
|
||||
it('should fail when navigating to bad url', async({page}) => {
|
||||
it('should fail when navigating to bad url', async ({page}) => {
|
||||
let error = null;
|
||||
await page.goto('asdfasdf').catch(e => error = e);
|
||||
if (options.CHROMIUM || options.WEBKIT)
|
||||
@ -174,7 +174,7 @@ it('should fail when navigating to bad url', async({page}) => {
|
||||
expect(error.message).toContain('Invalid url');
|
||||
});
|
||||
|
||||
it('should fail when navigating to bad SSL', async({page, httpsServer, browserName}) => {
|
||||
it('should fail when navigating to bad SSL', async ({page, httpsServer, browserName}) => {
|
||||
// Make sure that network events do not emit 'undefined'.
|
||||
// @see https://crbug.com/750469
|
||||
page.on('request', request => expect(request).toBeTruthy());
|
||||
@ -185,7 +185,7 @@ it('should fail when navigating to bad SSL', async({page, httpsServer, browserNa
|
||||
utils.expectSSLError(browserName, error.message);
|
||||
});
|
||||
|
||||
it('should fail when navigating to bad SSL after redirects', async({page, server, httpsServer, browserName}) => {
|
||||
it('should fail when navigating to bad SSL after redirects', async ({page, server, httpsServer, browserName}) => {
|
||||
server.setRedirect('/redirect/1.html', '/redirect/2.html');
|
||||
server.setRedirect('/redirect/2.html', '/empty.html');
|
||||
let error = null;
|
||||
@ -193,23 +193,22 @@ it('should fail when navigating to bad SSL after redirects', async({page, server
|
||||
utils.expectSSLError(browserName, error.message);
|
||||
});
|
||||
|
||||
it('should not crash when navigating to bad SSL after a cross origin navigation', async({page, server, httpsServer}) => {
|
||||
it('should not crash when navigating to bad SSL after a cross origin navigation', async ({page, server, httpsServer}) => {
|
||||
await page.goto(server.CROSS_PROCESS_PREFIX + '/empty.html');
|
||||
await page.goto(httpsServer.EMPTY_PAGE).catch(e => void 0);
|
||||
});
|
||||
|
||||
it('should not throw if networkidle0 is passed as an option', async({page, server}) => {
|
||||
let error = null;
|
||||
it('should not throw if networkidle0 is passed as an option', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE, {waitUntil: 'networkidle0' as any});
|
||||
});
|
||||
|
||||
it('should throw if networkidle2 is passed as an option', async({page, server}) => {
|
||||
it('should throw if networkidle2 is passed as an option', async ({page, server}) => {
|
||||
let error = null;
|
||||
await page.goto(server.EMPTY_PAGE, {waitUntil: 'networkidle2' as any}).catch(err => error = err);
|
||||
expect(error.message).toContain(`waitUntil: expected one of (load|domcontentloaded|networkidle)`);
|
||||
});
|
||||
|
||||
it('should fail when main resources failed to load', async({page}) => {
|
||||
it('should fail when main resources failed to load', async ({page}) => {
|
||||
let error = null;
|
||||
await page.goto('http://localhost:44123/non-existing-url').catch(e => error = e);
|
||||
if (options.CHROMIUM)
|
||||
@ -222,7 +221,7 @@ it('should fail when main resources failed to load', async({page}) => {
|
||||
expect(error.message).toContain('NS_ERROR_CONNECTION_REFUSED');
|
||||
});
|
||||
|
||||
it('should fail when exceeding maximum navigation timeout', async({page, server, playwright}) => {
|
||||
it('should fail when exceeding maximum navigation timeout', async ({page, server, playwright}) => {
|
||||
// Hang for request to the empty.html
|
||||
server.setRoute('/empty.html', (req, res) => { });
|
||||
let error = null;
|
||||
@ -232,7 +231,7 @@ it('should fail when exceeding maximum navigation timeout', async({page, server,
|
||||
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
|
||||
});
|
||||
|
||||
it('should fail when exceeding default maximum navigation timeout', async({page, server, playwright}) => {
|
||||
it('should fail when exceeding default maximum navigation timeout', async ({page, server, playwright}) => {
|
||||
// Hang for request to the empty.html
|
||||
server.setRoute('/empty.html', (req, res) => { });
|
||||
let error = null;
|
||||
@ -244,7 +243,7 @@ it('should fail when exceeding default maximum navigation timeout', async({page,
|
||||
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
|
||||
});
|
||||
|
||||
it('should fail when exceeding browser context navigation timeout', async({page, server, playwright}) => {
|
||||
it('should fail when exceeding browser context navigation timeout', async ({page, server, playwright}) => {
|
||||
// Hang for request to the empty.html
|
||||
server.setRoute('/empty.html', (req, res) => { });
|
||||
let error = null;
|
||||
@ -255,7 +254,7 @@ it('should fail when exceeding browser context navigation timeout', async({page,
|
||||
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
|
||||
});
|
||||
|
||||
it('should fail when exceeding default maximum timeout', async({page, server, playwright}) => {
|
||||
it('should fail when exceeding default maximum timeout', async ({page, server, playwright}) => {
|
||||
// Hang for request to the empty.html
|
||||
server.setRoute('/empty.html', (req, res) => { });
|
||||
let error = null;
|
||||
@ -267,7 +266,7 @@ it('should fail when exceeding default maximum timeout', async({page, server, pl
|
||||
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
|
||||
});
|
||||
|
||||
it('should fail when exceeding browser context timeout', async({page, server, playwright}) => {
|
||||
it('should fail when exceeding browser context timeout', async ({page, server, playwright}) => {
|
||||
// Hang for request to the empty.html
|
||||
server.setRoute('/empty.html', (req, res) => { });
|
||||
let error = null;
|
||||
@ -278,7 +277,7 @@ it('should fail when exceeding browser context timeout', async({page, server, pl
|
||||
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
|
||||
});
|
||||
|
||||
it('should prioritize default navigation timeout over default timeout', async({page, server, playwright}) => {
|
||||
it('should prioritize default navigation timeout over default timeout', async ({page, server, playwright}) => {
|
||||
// Hang for request to the empty.html
|
||||
server.setRoute('/empty.html', (req, res) => { });
|
||||
let error = null;
|
||||
@ -290,7 +289,7 @@ it('should prioritize default navigation timeout over default timeout', async({p
|
||||
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
|
||||
});
|
||||
|
||||
it('should disable timeout when its set to 0', async({page, server}) => {
|
||||
it('should disable timeout when its set to 0', async ({page, server}) => {
|
||||
let error = null;
|
||||
let loaded = false;
|
||||
page.once('load', () => loaded = true);
|
||||
@ -299,7 +298,7 @@ it('should disable timeout when its set to 0', async({page, server}) => {
|
||||
expect(loaded).toBe(true);
|
||||
});
|
||||
|
||||
it('should fail when replaced by another navigation', async({page, server}) => {
|
||||
it('should fail when replaced by another navigation', async ({page, server}) => {
|
||||
let anotherPromise;
|
||||
server.setRoute('/empty.html', (req, res) => {
|
||||
anotherPromise = page.goto(server.PREFIX + '/one-style.html');
|
||||
@ -315,23 +314,23 @@ it('should fail when replaced by another navigation', async({page, server}) => {
|
||||
expect(error.message).toContain('NS_BINDING_ABORTED');
|
||||
});
|
||||
|
||||
it('should work when navigating to valid url', async({page, server}) => {
|
||||
it('should work when navigating to valid url', async ({page, server}) => {
|
||||
const response = await page.goto(server.EMPTY_PAGE);
|
||||
expect(response.ok()).toBe(true);
|
||||
});
|
||||
|
||||
it('should work when navigating to data url', async({page, server}) => {
|
||||
it('should work when navigating to data url', async ({page, server}) => {
|
||||
const response = await page.goto('data:text/html,hello');
|
||||
expect(response).toBe(null);
|
||||
});
|
||||
|
||||
it('should work when navigating to 404', async({page, server}) => {
|
||||
it('should work when navigating to 404', async ({page, server}) => {
|
||||
const response = await page.goto(server.PREFIX + '/not-found');
|
||||
expect(response.ok()).toBe(false);
|
||||
expect(response.status()).toBe(404);
|
||||
});
|
||||
|
||||
it('should return last response in redirect chain', async({page, server}) => {
|
||||
it('should return last response in redirect chain', async ({page, server}) => {
|
||||
server.setRedirect('/redirect/1.html', '/redirect/2.html');
|
||||
server.setRedirect('/redirect/2.html', '/redirect/3.html');
|
||||
server.setRedirect('/redirect/3.html', server.EMPTY_PAGE);
|
||||
@ -340,7 +339,7 @@ it('should return last response in redirect chain', async({page, server}) => {
|
||||
expect(response.url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
|
||||
it('should not leak listeners during navigation', async({page, server}) => {
|
||||
it('should not leak listeners during navigation', async ({page, server}) => {
|
||||
let warning = null;
|
||||
const warningHandler = w => warning = w;
|
||||
process.on('warning', warningHandler);
|
||||
@ -350,7 +349,7 @@ it('should not leak listeners during navigation', async({page, server}) => {
|
||||
expect(warning).toBe(null);
|
||||
});
|
||||
|
||||
it('should not leak listeners during bad navigation', async({page, server}) => {
|
||||
it('should not leak listeners during bad navigation', async ({page, server}) => {
|
||||
let warning = null;
|
||||
const warningHandler = w => warning = w;
|
||||
process.on('warning', warningHandler);
|
||||
@ -360,7 +359,7 @@ it('should not leak listeners during bad navigation', async({page, server}) => {
|
||||
expect(warning).toBe(null);
|
||||
});
|
||||
|
||||
it('should not leak listeners during navigation of 20 pages', async({page, context, server}) => {
|
||||
it('should not leak listeners during navigation of 20 pages', async ({page, context, server}) => {
|
||||
let warning = null;
|
||||
const warningHandler = w => warning = w;
|
||||
process.on('warning', warningHandler);
|
||||
@ -371,7 +370,7 @@ it('should not leak listeners during navigation of 20 pages', async({page, conte
|
||||
expect(warning).toBe(null);
|
||||
});
|
||||
|
||||
it('should not leak listeners during 20 waitForNavigation', async({page, context, server}) => {
|
||||
it('should not leak listeners during 20 waitForNavigation', async ({page, context, server}) => {
|
||||
let warning = null;
|
||||
const warningHandler = w => warning = w;
|
||||
process.on('warning', warningHandler);
|
||||
@ -382,7 +381,7 @@ it('should not leak listeners during 20 waitForNavigation', async({page, context
|
||||
expect(warning).toBe(null);
|
||||
});
|
||||
|
||||
it('should navigate to dataURL and not fire dataURL requests', async({page, server}) => {
|
||||
it('should navigate to dataURL and not fire dataURL requests', async ({page, server}) => {
|
||||
const requests = [];
|
||||
page.on('request', request => requests.push(request));
|
||||
const dataURL = 'data:text/html,<div>yo</div>';
|
||||
@ -391,7 +390,7 @@ it('should navigate to dataURL and not fire dataURL requests', async({page, serv
|
||||
expect(requests.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should navigate to URL with hash and fire requests without hash', async({page, server}) => {
|
||||
it('should navigate to URL with hash and fire requests without hash', async ({page, server}) => {
|
||||
const requests = [];
|
||||
page.on('request', request => requests.push(request));
|
||||
const response = await page.goto(server.EMPTY_PAGE + '#hash');
|
||||
@ -401,7 +400,7 @@ it('should navigate to URL with hash and fire requests without hash', async({pag
|
||||
expect(requests[0].url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
|
||||
it('should work with self requesting page', async({page, server}) => {
|
||||
it('should work with self requesting page', async ({page, server}) => {
|
||||
const response = await page.goto(server.PREFIX + '/self-request.html');
|
||||
expect(response.status()).toBe(200);
|
||||
expect(response.url()).toContain('self-request.html');
|
||||
@ -418,13 +417,13 @@ it('should fail when navigating and show the url at the error message', async fu
|
||||
expect(error.message).toContain(url);
|
||||
});
|
||||
|
||||
it('should be able to navigate to a page controlled by service worker', async({page, server}) => {
|
||||
it('should be able to navigate to a page controlled by service worker', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/serviceworkers/fetch/sw.html');
|
||||
await page.evaluate(() => window["activationPromise"]);
|
||||
await page.evaluate(() => window['activationPromise']);
|
||||
await page.goto(server.PREFIX + '/serviceworkers/fetch/sw.html');
|
||||
});
|
||||
|
||||
it('should send referer', async({page, server}) => {
|
||||
it('should send referer', async ({page, server}) => {
|
||||
const [request1, request2] = await Promise.all([
|
||||
server.waitForRequest('/grid.html'),
|
||||
server.waitForRequest('/digits/1.png'),
|
||||
@ -438,7 +437,7 @@ it('should send referer', async({page, server}) => {
|
||||
expect(page.url()).toBe(server.PREFIX + '/grid.html');
|
||||
});
|
||||
|
||||
it('should reject referer option when setExtraHTTPHeaders provides referer', async({page, server}) => {
|
||||
it('should reject referer option when setExtraHTTPHeaders provides referer', async ({page, server}) => {
|
||||
await page.setExtraHTTPHeaders({ 'referer': 'http://microsoft.com/' });
|
||||
let error;
|
||||
await page.goto(server.PREFIX + '/grid.html', {
|
||||
@ -448,7 +447,7 @@ it('should reject referer option when setExtraHTTPHeaders provides referer', asy
|
||||
expect(error.message).toContain(server.PREFIX + '/grid.html');
|
||||
});
|
||||
|
||||
it('should override referrer-policy', async({page, server}) => {
|
||||
it('should override referrer-policy', async ({page, server}) => {
|
||||
server.setRoute('/grid.html', (req, res) => {
|
||||
res.setHeader('Referrer-Policy', 'no-referrer');
|
||||
server.serveFile(req, res, '/grid.html');
|
||||
@ -466,7 +465,7 @@ it('should override referrer-policy', async({page, server}) => {
|
||||
expect(page.url()).toBe(server.PREFIX + '/grid.html');
|
||||
});
|
||||
|
||||
it('should fail when canceled by another navigation', async({page, server}) => {
|
||||
it('should fail when canceled by another navigation', async ({page, server}) => {
|
||||
server.setRoute('/one-style.html', (req, res) => {});
|
||||
const failed = page.goto(server.PREFIX + '/one-style.html').catch(e => e);
|
||||
await server.waitForRequest('/one-style.html');
|
||||
@ -475,7 +474,7 @@ it('should fail when canceled by another navigation', async({page, server}) => {
|
||||
expect(error.message).toBeTruthy();
|
||||
});
|
||||
|
||||
it.skip(true)('extraHttpHeaders should be pushed to provisional page', async({page, server}) => {
|
||||
it.skip(true)('extraHttpHeaders should be pushed to provisional page', async ({page, server}) => {
|
||||
// This test is flaky, because we cannot await page.setExtraHTTPHeaders.
|
||||
// We need a way to test our implementation by more than just public api.
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -493,7 +492,7 @@ it.skip(true)('extraHttpHeaders should be pushed to provisional page', async({pa
|
||||
expect(cssReq.headers['foo']).toBe('bar');
|
||||
});
|
||||
|
||||
it('should work with lazy loading iframes', async({page, server}) => {
|
||||
it('should work with lazy loading iframes', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/frames/lazy-frame.html');
|
||||
expect(page.frames().length).toBe(2);
|
||||
});
|
||||
|
@ -18,7 +18,7 @@
|
||||
import { options } from './playwright.fixtures';
|
||||
import url from 'url';
|
||||
|
||||
it('page.goBack should work', async({page, server}) => {
|
||||
it('page.goBack should work', async ({page, server}) => {
|
||||
expect(await page.goBack()).toBe(null);
|
||||
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
@ -36,7 +36,7 @@ it('page.goBack should work', async({page, server}) => {
|
||||
expect(response).toBe(null);
|
||||
});
|
||||
|
||||
it('page.goBack should work with HistoryAPI', async({page, server}) => {
|
||||
it('page.goBack should work with HistoryAPI', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.evaluate(() => {
|
||||
history.pushState({}, '', '/first.html');
|
||||
@ -77,14 +77,14 @@ it.fail(options.WEBKIT && MAC)('page.goBack should work for file urls', async ({
|
||||
await page.screenshot();
|
||||
});
|
||||
|
||||
it('page.reload should work', async({page, server}) => {
|
||||
it('page.reload should work', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.evaluate(() => window["_foo"] = 10);
|
||||
await page.evaluate(() => window['_foo'] = 10);
|
||||
await page.reload();
|
||||
expect(await page.evaluate(() => window["_foo"])).toBe(undefined);
|
||||
expect(await page.evaluate(() => window['_foo'])).toBe(undefined);
|
||||
});
|
||||
|
||||
it('page.reload should work with data url', async({page, server}) => {
|
||||
it('page.reload should work with data url', async ({page, server}) => {
|
||||
await page.goto('data:text/html,hello');
|
||||
expect(await page.content()).toContain('hello');
|
||||
expect(await page.reload()).toBe(null);
|
||||
|
@ -19,7 +19,7 @@ import './playwright.fixtures';
|
||||
import type { Frame, Page } from '..';
|
||||
import { TestServer } from '../utils/testserver';
|
||||
|
||||
it('should navigate to empty page with networkidle', async({page, server}) => {
|
||||
it('should navigate to empty page with networkidle', async ({page, server}) => {
|
||||
const response = await page.goto(server.EMPTY_PAGE, { waitUntil: 'networkidle' });
|
||||
expect(response.status()).toBe(200);
|
||||
});
|
||||
@ -34,8 +34,8 @@ async function networkIdleTest(frame: Frame, server: TestServer, action: () => P
|
||||
server.waitForRequest(suffix),
|
||||
(frame['_page'] as Page).waitForRequest(server.PREFIX + suffix),
|
||||
]);
|
||||
}
|
||||
let responses = {};
|
||||
};
|
||||
const responses = {};
|
||||
// Hold on to a bunch of requests without answering.
|
||||
server.setRoute('/fetch-request-a.js', (req, res) => responses['a'] = res);
|
||||
const firstFetchResourceRequested = waitForRequest('/fetch-request-a.js');
|
||||
@ -61,8 +61,6 @@ async function networkIdleTest(frame: Frame, server: TestServer, action: () => P
|
||||
expect(actionFinished).toBe(false);
|
||||
|
||||
expect(responses['a']).toBeTruthy();
|
||||
let timer;
|
||||
let timerTriggered = false;
|
||||
// Finishing response should trigger the second round.
|
||||
finishResponse(responses['a']);
|
||||
|
||||
@ -70,7 +68,8 @@ async function networkIdleTest(frame: Frame, server: TestServer, action: () => P
|
||||
await secondFetchResourceRequested;
|
||||
expect(actionFinished).toBe(false);
|
||||
// Finishing the last response should trigger networkidle.
|
||||
timer = setTimeout(() => timerTriggered = true, 500);
|
||||
let timerTriggered = false;
|
||||
const timer = setTimeout(() => timerTriggered = true, 500);
|
||||
finishResponse(responses['d']);
|
||||
|
||||
const response = await actionPromise;
|
||||
@ -80,13 +79,13 @@ async function networkIdleTest(frame: Frame, server: TestServer, action: () => P
|
||||
expect(response.ok()).toBe(true);
|
||||
}
|
||||
|
||||
it('should wait for networkidle to succeed navigation', async({page, server}) => {
|
||||
it('should wait for networkidle to succeed navigation', async ({page, server}) => {
|
||||
await networkIdleTest(page.mainFrame(), server, () => {
|
||||
return page.goto(server.PREFIX + '/networkidle.html', { waitUntil: 'networkidle' });
|
||||
});
|
||||
});
|
||||
|
||||
it('should wait for networkidle to succeed navigation with request from previous navigation', async({page, server}) => {
|
||||
it('should wait for networkidle to succeed navigation with request from previous navigation', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
server.setRoute('/foo.js', () => {});
|
||||
await page.setContent(`<script>fetch('foo.js');</script>`);
|
||||
@ -95,7 +94,7 @@ it('should wait for networkidle to succeed navigation with request from previous
|
||||
});
|
||||
});
|
||||
|
||||
it('should wait for networkidle in waitForNavigation', async({page, server}) => {
|
||||
it('should wait for networkidle in waitForNavigation', async ({page, server}) => {
|
||||
await networkIdleTest(page.mainFrame(), server, () => {
|
||||
const promise = page.waitForNavigation({ waitUntil: 'networkidle' });
|
||||
page.goto(server.PREFIX + '/networkidle.html');
|
||||
@ -103,14 +102,14 @@ it('should wait for networkidle in waitForNavigation', async({page, server}) =>
|
||||
});
|
||||
});
|
||||
|
||||
it('should wait for networkidle in setContent', async({page, server}) => {
|
||||
it('should wait for networkidle in setContent', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await networkIdleTest(page.mainFrame(), server, () => {
|
||||
return page.setContent(`<script src='networkidle.js'></script>`, { waitUntil: 'networkidle' });
|
||||
}, true);
|
||||
});
|
||||
|
||||
it('should wait for networkidle in setContent with request from previous navigation', async({page, server}) => {
|
||||
it('should wait for networkidle in setContent with request from previous navigation', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
server.setRoute('/foo.js', () => {});
|
||||
await page.setContent(`<script>fetch('foo.js');</script>`);
|
||||
@ -119,20 +118,20 @@ it('should wait for networkidle in setContent with request from previous navigat
|
||||
}, true);
|
||||
});
|
||||
|
||||
it('should wait for networkidle when navigating iframe', async({page, server}) => {
|
||||
it('should wait for networkidle when navigating iframe', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/frames/one-frame.html');
|
||||
const frame = page.mainFrame().childFrames()[0];
|
||||
await networkIdleTest(frame, server, () => frame.goto(server.PREFIX + '/networkidle.html', { waitUntil: 'networkidle' }));
|
||||
});
|
||||
|
||||
it('should wait for networkidle in setContent from the child frame', async({page, server}) => {
|
||||
it('should wait for networkidle in setContent from the child frame', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await networkIdleTest(page.mainFrame(), server, () => {
|
||||
return page.setContent(`<iframe src='networkidle.html'></iframe>`, { waitUntil: 'networkidle' });
|
||||
}, true);
|
||||
});
|
||||
|
||||
it('should wait for networkidle from the child frame', async({page, server}) => {
|
||||
it('should wait for networkidle from the child frame', async ({page, server}) => {
|
||||
await networkIdleTest(page.mainFrame(), server, () => {
|
||||
return page.goto(server.PREFIX + '/networkidle-frame.html', { waitUntil: 'networkidle' });
|
||||
});
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { options } from './playwright.fixtures';
|
||||
|
||||
it('should intercept', async({page, server}) => {
|
||||
it('should intercept', async ({page, server}) => {
|
||||
let intercepted = false;
|
||||
await page.route('**/empty.html', (route, request) => {
|
||||
expect(route.request()).toBe(request);
|
||||
@ -37,7 +37,7 @@ it('should intercept', async({page, server}) => {
|
||||
expect(intercepted).toBe(true);
|
||||
});
|
||||
|
||||
it('should unroute', async({page, server}) => {
|
||||
it('should unroute', async ({page, server}) => {
|
||||
let intercepted = [];
|
||||
const handler1 = route => {
|
||||
intercepted.push(1);
|
||||
@ -70,7 +70,7 @@ it('should unroute', async({page, server}) => {
|
||||
expect(intercepted).toEqual([4]);
|
||||
});
|
||||
|
||||
it('should work when POST is redirected with 302', async({page, server}) => {
|
||||
it('should work when POST is redirected with 302', async ({page, server}) => {
|
||||
server.setRedirect('/rredirect', '/empty.html');
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.route('**/*', route => route.continue());
|
||||
@ -85,7 +85,7 @@ it('should work when POST is redirected with 302', async({page, server}) => {
|
||||
]);
|
||||
});
|
||||
// @see https://github.com/GoogleChrome/puppeteer/issues/3973
|
||||
it('should work when header manipulation headers with redirect', async({page, server}) => {
|
||||
it('should work when header manipulation headers with redirect', async ({page, server}) => {
|
||||
server.setRedirect('/rrredirect', '/empty.html');
|
||||
await page.route('**/*', route => {
|
||||
const headers = Object.assign({}, route.request().headers(), {
|
||||
@ -96,7 +96,7 @@ it('should work when header manipulation headers with redirect', async({page, se
|
||||
await page.goto(server.PREFIX + '/rrredirect');
|
||||
});
|
||||
// @see https://github.com/GoogleChrome/puppeteer/issues/4743
|
||||
it('should be able to remove headers', async({page, server}) => {
|
||||
it('should be able to remove headers', async ({page, server}) => {
|
||||
await page.route('**/*', route => {
|
||||
const headers = Object.assign({}, route.request().headers(), {
|
||||
foo: 'bar',
|
||||
@ -113,7 +113,7 @@ it('should be able to remove headers', async({page, server}) => {
|
||||
expect(serverRequest.headers.origin).toBe(undefined);
|
||||
});
|
||||
|
||||
it('should contain referer header', async({page, server}) => {
|
||||
it('should contain referer header', async ({page, server}) => {
|
||||
const requests = [];
|
||||
await page.route('**/*', route => {
|
||||
requests.push(route.request());
|
||||
@ -124,7 +124,7 @@ it('should contain referer header', async({page, server}) => {
|
||||
expect(requests[1].headers().referer).toContain('/one-style.html');
|
||||
});
|
||||
|
||||
it('should properly return navigation response when URL has cookies', async({context, page, server}) => {
|
||||
it('should properly return navigation response when URL has cookies', async ({context, page, server}) => {
|
||||
// Setup cookie.
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await context.addCookies([{ url: server.EMPTY_PAGE, name: 'foo', value: 'bar'}]);
|
||||
@ -135,7 +135,7 @@ it('should properly return navigation response when URL has cookies', async({con
|
||||
expect(response.status()).toBe(200);
|
||||
});
|
||||
|
||||
it('should show custom HTTP headers', async({page, server}) => {
|
||||
it('should show custom HTTP headers', async ({page, server}) => {
|
||||
await page.setExtraHTTPHeaders({
|
||||
foo: 'bar'
|
||||
});
|
||||
@ -147,11 +147,11 @@ it('should show custom HTTP headers', async({page, server}) => {
|
||||
expect(response.ok()).toBe(true);
|
||||
});
|
||||
// @see https://github.com/GoogleChrome/puppeteer/issues/4337
|
||||
it('should work with redirect inside sync XHR', async({page, server}) => {
|
||||
it('should work with redirect inside sync XHR', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
server.setRedirect('/logo.png', '/pptr.png');
|
||||
await page.route('**/*', route => route.continue());
|
||||
const status = await page.evaluate(async() => {
|
||||
const status = await page.evaluate(async () => {
|
||||
const request = new XMLHttpRequest();
|
||||
request.open('GET', '/logo.png', false); // `false` makes the request synchronous
|
||||
request.send(null);
|
||||
@ -160,7 +160,7 @@ it('should work with redirect inside sync XHR', async({page, server}) => {
|
||||
expect(status).toBe(200);
|
||||
});
|
||||
|
||||
it('should work with custom referer headers', async({page, server}) => {
|
||||
it('should work with custom referer headers', async ({page, server}) => {
|
||||
await page.setExtraHTTPHeaders({ 'referer': server.EMPTY_PAGE });
|
||||
await page.route('**/*', route => {
|
||||
expect(route.request().headers()['referer']).toBe(server.EMPTY_PAGE);
|
||||
@ -170,7 +170,7 @@ it('should work with custom referer headers', async({page, server}) => {
|
||||
expect(response.ok()).toBe(true);
|
||||
});
|
||||
|
||||
it('should be abortable', async({page, server}) => {
|
||||
it('should be abortable', async ({page, server}) => {
|
||||
await page.route(/\.css$/, route => route.abort());
|
||||
let failed = false;
|
||||
page.on('requestfailed', request => {
|
||||
@ -183,7 +183,7 @@ it('should be abortable', async({page, server}) => {
|
||||
expect(failed).toBe(true);
|
||||
});
|
||||
|
||||
it('should be abortable with custom error codes', async({page, server}) => {
|
||||
it('should be abortable with custom error codes', async ({page, server}) => {
|
||||
await page.route('**/*', route => route.abort('internetdisconnected'));
|
||||
let failedRequest = null;
|
||||
page.on('requestfailed', request => failedRequest = request);
|
||||
@ -197,7 +197,7 @@ it('should be abortable with custom error codes', async({page, server}) => {
|
||||
expect(failedRequest.failure().errorText).toBe('net::ERR_INTERNET_DISCONNECTED');
|
||||
});
|
||||
|
||||
it('should send referer', async({page, server}) => {
|
||||
it('should send referer', async ({page, server}) => {
|
||||
await page.setExtraHTTPHeaders({
|
||||
referer: 'http://google.com/'
|
||||
});
|
||||
@ -209,7 +209,7 @@ it('should send referer', async({page, server}) => {
|
||||
expect(request.headers['referer']).toBe('http://google.com/');
|
||||
});
|
||||
|
||||
it('should fail navigation when aborting main resource', async({page, server}) => {
|
||||
it('should fail navigation when aborting main resource', async ({page, server}) => {
|
||||
await page.route('**/*', route => route.abort());
|
||||
let error = null;
|
||||
await page.goto(server.EMPTY_PAGE).catch(e => error = e);
|
||||
@ -222,7 +222,7 @@ it('should fail navigation when aborting main resource', async({page, server}) =
|
||||
expect(error.message).toContain('net::ERR_FAILED');
|
||||
});
|
||||
|
||||
it('should not work with redirects', async({page, server}) => {
|
||||
it('should not work with redirects', async ({page, server}) => {
|
||||
const intercepted = [];
|
||||
await page.route('**/*', route => {
|
||||
route.continue();
|
||||
@ -257,7 +257,7 @@ it('should not work with redirects', async({page, server}) => {
|
||||
expect(chain[i].redirectedTo()).toBe(i ? chain[i - 1] : null);
|
||||
});
|
||||
|
||||
it('should work with redirects for subresources', async({page, server}) => {
|
||||
it('should work with redirects for subresources', async ({page, server}) => {
|
||||
const intercepted = [];
|
||||
await page.route('**/*', route => {
|
||||
route.continue();
|
||||
@ -285,7 +285,7 @@ it('should work with redirects for subresources', async({page, server}) => {
|
||||
expect(r).toBe(null);
|
||||
});
|
||||
|
||||
it('should work with equal requests', async({page, server}) => {
|
||||
it('should work with equal requests', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
let responseCount = 1;
|
||||
server.setRoute('/zzz', (req, res) => res.end((responseCount++) * 11 + ''));
|
||||
@ -302,7 +302,7 @@ it('should work with equal requests', async({page, server}) => {
|
||||
expect(results).toEqual(['11', 'FAILED', '22']);
|
||||
});
|
||||
|
||||
it('should navigate to dataURL and not fire dataURL requests', async({page, server}) => {
|
||||
it('should navigate to dataURL and not fire dataURL requests', async ({page, server}) => {
|
||||
const requests = [];
|
||||
await page.route('**/*', route => {
|
||||
requests.push(route.request());
|
||||
@ -314,7 +314,7 @@ it('should navigate to dataURL and not fire dataURL requests', async({page, serv
|
||||
expect(requests.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should be able to fetch dataURL and not fire dataURL requests', async({page, server}) => {
|
||||
it('should be able to fetch dataURL and not fire dataURL requests', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const requests = [];
|
||||
await page.route('**/*', route => {
|
||||
@ -327,7 +327,7 @@ it('should be able to fetch dataURL and not fire dataURL requests', async({page,
|
||||
expect(requests.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should navigate to URL with hash and and fire requests without hash', async({page, server}) => {
|
||||
it('should navigate to URL with hash and and fire requests without hash', async ({page, server}) => {
|
||||
const requests = [];
|
||||
await page.route('**/*', route => {
|
||||
requests.push(route.request());
|
||||
@ -340,7 +340,7 @@ it('should navigate to URL with hash and and fire requests without hash', async(
|
||||
expect(requests[0].url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
|
||||
it('should work with encoded server', async({page, server}) => {
|
||||
it('should work with encoded server', async ({page, server}) => {
|
||||
// The requestWillBeSent will report encoded URL, whereas interception will
|
||||
// report URL as-is. @see crbug.com/759388
|
||||
await page.route('**/*', route => route.continue());
|
||||
@ -348,14 +348,14 @@ it('should work with encoded server', async({page, server}) => {
|
||||
expect(response.status()).toBe(404);
|
||||
});
|
||||
|
||||
it('should work with badly encoded server', async({page, server}) => {
|
||||
it('should work with badly encoded server', async ({page, server}) => {
|
||||
server.setRoute('/malformed?rnd=%911', (req, res) => res.end());
|
||||
await page.route('**/*', route => route.continue());
|
||||
const response = await page.goto(server.PREFIX + '/malformed?rnd=%911');
|
||||
expect(response.status()).toBe(200);
|
||||
});
|
||||
|
||||
it('should work with encoded server - 2', async({page, server}) => {
|
||||
it('should work with encoded server - 2', async ({page, server}) => {
|
||||
// The requestWillBeSent will report URL as-is, whereas interception will
|
||||
// report encoded URL for stylesheet. @see crbug.com/759388
|
||||
const requests = [];
|
||||
@ -369,7 +369,7 @@ it('should work with encoded server - 2', async({page, server}) => {
|
||||
expect((await requests[0].response()).status()).toBe(404);
|
||||
});
|
||||
|
||||
it('should not throw "Invalid Interception Id" if the request was cancelled', async({page, server}) => {
|
||||
it('should not throw "Invalid Interception Id" if the request was cancelled', async ({page, server}) => {
|
||||
await page.setContent('<iframe></iframe>');
|
||||
let route = null;
|
||||
await page.route('**/*', async r => route = r);
|
||||
@ -383,7 +383,7 @@ it('should not throw "Invalid Interception Id" if the request was cancelled', as
|
||||
expect(error).toBe(null);
|
||||
});
|
||||
|
||||
it('should intercept main resource during cross-process navigation', async({page, server}) => {
|
||||
it('should intercept main resource during cross-process navigation', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
let intercepted = false;
|
||||
await page.route(server.CROSS_PROCESS_PREFIX + '/empty.html', route => {
|
||||
@ -395,9 +395,9 @@ it('should intercept main resource during cross-process navigation', async({page
|
||||
expect(intercepted).toBe(true);
|
||||
});
|
||||
|
||||
it('should create a redirect', async({page, server}) => {
|
||||
it('should create a redirect', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/empty.html');
|
||||
await page.route('**/*', async(route, request) => {
|
||||
await page.route('**/*', async (route, request) => {
|
||||
if (request.url() !== server.PREFIX + '/redirect_this')
|
||||
return route.continue();
|
||||
await route.fulfill({
|
||||
@ -415,7 +415,7 @@ it('should create a redirect', async({page, server}) => {
|
||||
expect(text).toBe('');
|
||||
});
|
||||
|
||||
it('should support cors with GET', async({page, server}) => {
|
||||
it('should support cors with GET', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.route('**/cars*', async (route, request) => {
|
||||
const headers = request.url().endsWith('allow') ? { 'access-control-allow-origin': '*' } : {};
|
||||
@ -444,9 +444,9 @@ it('should support cors with GET', async({page, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should support cors with POST', async({page, server}) => {
|
||||
it('should support cors with POST', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.route('**/cars', async (route) => {
|
||||
await page.route('**/cars', async route => {
|
||||
await route.fulfill({
|
||||
contentType: 'application/json',
|
||||
headers: { 'Access-Control-Allow-Origin': '*' },
|
||||
@ -466,9 +466,9 @@ it('should support cors with POST', async({page, server}) => {
|
||||
expect(resp).toEqual(['electric', 'gas']);
|
||||
});
|
||||
|
||||
it('should support cors with credentials', async({page, server}) => {
|
||||
it('should support cors with credentials', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.route('**/cars', async (route) => {
|
||||
await page.route('**/cars', async route => {
|
||||
await route.fulfill({
|
||||
contentType: 'application/json',
|
||||
headers: {
|
||||
@ -492,9 +492,9 @@ it('should support cors with credentials', async({page, server}) => {
|
||||
expect(resp).toEqual(['electric', 'gas']);
|
||||
});
|
||||
|
||||
it('should reject cors with disallowed credentials', async({page, server}) => {
|
||||
it('should reject cors with disallowed credentials', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.route('**/cars', async (route) => {
|
||||
await page.route('**/cars', async route => {
|
||||
await route.fulfill({
|
||||
contentType: 'application/json',
|
||||
headers: {
|
||||
@ -508,7 +508,7 @@ it('should reject cors with disallowed credentials', async({page, server}) => {
|
||||
});
|
||||
let error = '';
|
||||
try {
|
||||
const resp = await page.evaluate(async () => {
|
||||
await page.evaluate(async () => {
|
||||
const response = await fetch('https://example.com/cars', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@ -524,7 +524,7 @@ it('should reject cors with disallowed credentials', async({page, server}) => {
|
||||
expect(error).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should support cors for different methods', async({page, server}) => {
|
||||
it('should support cors for different methods', async ({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.route('**/cars', async (route, request) => {
|
||||
await route.fulfill({
|
||||
|
@ -23,14 +23,14 @@ import fs from 'fs';
|
||||
// Firefox headful produces a different image.
|
||||
const ffheadful = options.FIREFOX && !options.HEADLESS;
|
||||
|
||||
it.skip(ffheadful)('should work', async({page, server, golden}) => {
|
||||
it.skip(ffheadful)('should work', async ({page, server, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const screenshot = await page.screenshot();
|
||||
expect(screenshot).toMatchImage(golden('screenshot-sanity.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should clip rect', async({page, server, golden}) => {
|
||||
it.skip(ffheadful)('should clip rect', async ({page, server, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const screenshot = await page.screenshot({
|
||||
@ -44,7 +44,7 @@ it.skip(ffheadful)('should clip rect', async({page, server, golden}) => {
|
||||
expect(screenshot).toMatchImage(golden('screenshot-clip-rect.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should clip rect with fullPage', async({page, server, golden}) => {
|
||||
it.skip(ffheadful)('should clip rect with fullPage', async ({page, server, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
await page.evaluate(() => window.scrollBy(150, 200));
|
||||
@ -60,7 +60,7 @@ it.skip(ffheadful)('should clip rect with fullPage', async({page, server, golden
|
||||
expect(screenshot).toMatchImage(golden('screenshot-clip-rect.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should clip elements to the viewport', async({page, server, golden}) => {
|
||||
it.skip(ffheadful)('should clip elements to the viewport', async ({page, server, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const screenshot = await page.screenshot({
|
||||
@ -74,7 +74,7 @@ it.skip(ffheadful)('should clip elements to the viewport', async({page, server,
|
||||
expect(screenshot).toMatchImage(golden('screenshot-offscreen-clip.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should throw on clip outside the viewport', async({page, server, golden}) => {
|
||||
it.skip(ffheadful)('should throw on clip outside the viewport', async ({page, server, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const screenshotError = await page.screenshot({
|
||||
@ -88,7 +88,7 @@ it.skip(ffheadful)('should throw on clip outside the viewport', async({page, ser
|
||||
expect(screenshotError.message).toContain('Clipped area is either empty or outside the resulting image');
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should run in parallel', async({page, server, golden}) => {
|
||||
it.skip(ffheadful)('should run in parallel', async ({page, server, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const promises = [];
|
||||
@ -106,7 +106,7 @@ it.skip(ffheadful)('should run in parallel', async({page, server, golden}) => {
|
||||
expect(screenshots[1]).toMatchImage(golden('grid-cell-1.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should take fullPage screenshots', async({page, server, golden}) => {
|
||||
it.skip(ffheadful)('should take fullPage screenshots', async ({page, server, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const screenshot = await page.screenshot({
|
||||
@ -115,7 +115,7 @@ it.skip(ffheadful)('should take fullPage screenshots', async({page, server, gold
|
||||
expect(screenshot).toMatchImage(golden('screenshot-grid-fullpage.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should restore viewport after fullPage screenshot', async({page, server}) => {
|
||||
it.skip(ffheadful)('should restore viewport after fullPage screenshot', async ({page, server}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const screenshot = await page.screenshot({ fullPage: true });
|
||||
@ -123,9 +123,9 @@ it.skip(ffheadful)('should restore viewport after fullPage screenshot', async({p
|
||||
await utils.verifyViewport(page, 500, 500);
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should run in parallel in multiple pages', async({server, context, golden}) => {
|
||||
it.skip(ffheadful)('should run in parallel in multiple pages', async ({server, context, golden}) => {
|
||||
const N = 5;
|
||||
const pages = await Promise.all(Array(N).fill(0).map(async() => {
|
||||
const pages = await Promise.all(Array(N).fill(0).map(async () => {
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
return page;
|
||||
@ -139,7 +139,7 @@ it.skip(ffheadful)('should run in parallel in multiple pages', async({server, co
|
||||
await Promise.all(pages.map(page => page.close()));
|
||||
});
|
||||
|
||||
it.fail(options.FIREFOX)('should allow transparency', async({page, golden}) => {
|
||||
it.fail(options.FIREFOX)('should allow transparency', async ({page, golden}) => {
|
||||
await page.setViewportSize({ width: 50, height: 150 });
|
||||
await page.setContent(`
|
||||
<style>
|
||||
@ -154,14 +154,14 @@ it.fail(options.FIREFOX)('should allow transparency', async({page, golden}) => {
|
||||
expect(screenshot).toMatchImage(golden('transparent.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should render white background on jpeg file', async({page, server, golden}) => {
|
||||
it.skip(ffheadful)('should render white background on jpeg file', async ({page, server, golden}) => {
|
||||
await page.setViewportSize({ width: 100, height: 100 });
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const screenshot = await page.screenshot({omitBackground: true, type: 'jpeg'});
|
||||
expect(screenshot).toMatchImage(golden('white.jpg'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should work with odd clip size on Retina displays', async({page, golden}) => {
|
||||
it.skip(ffheadful)('should work with odd clip size on Retina displays', async ({page, golden}) => {
|
||||
const screenshot = await page.screenshot({
|
||||
clip: {
|
||||
x: 0,
|
||||
@ -173,7 +173,7 @@ it.skip(ffheadful)('should work with odd clip size on Retina displays', async({p
|
||||
expect(screenshot).toMatchImage(golden('screenshot-clip-odd-size.png'));
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('should work with a mobile viewport', async({browser, server, golden}) => {
|
||||
it.skip(options.FIREFOX)('should work with a mobile viewport', async ({browser, server, golden}) => {
|
||||
const context = await browser.newContext({ viewport: { width: 320, height: 480 }, isMobile: true });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/overflow.html');
|
||||
@ -182,7 +182,7 @@ it.skip(options.FIREFOX)('should work with a mobile viewport', async({browser, s
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('should work with a mobile viewport and clip', async({browser, server, golden}) => {
|
||||
it.skip(options.FIREFOX)('should work with a mobile viewport and clip', async ({browser, server, golden}) => {
|
||||
const context = await browser.newContext({viewport: { width: 320, height: 480 }, isMobile: true});
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/overflow.html');
|
||||
@ -191,7 +191,7 @@ it.skip(options.FIREFOX)('should work with a mobile viewport and clip', async({b
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(options.FIREFOX)('should work with a mobile viewport and fullPage', async({browser, server, golden}) => {
|
||||
it.skip(options.FIREFOX)('should work with a mobile viewport and fullPage', async ({browser, server, golden}) => {
|
||||
const context = await browser.newContext({viewport: { width: 320, height: 480 }, isMobile: true});
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/overflow-large.html');
|
||||
@ -200,28 +200,28 @@ it.skip(options.FIREFOX)('should work with a mobile viewport and fullPage', asyn
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should work for canvas', async({page, server, golden}) => {
|
||||
it.skip(ffheadful)('should work for canvas', async ({page, server, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/screenshots/canvas.html');
|
||||
const screenshot = await page.screenshot();
|
||||
expect(screenshot).toMatchImage(golden('screenshot-canvas.png'), { threshold: 0.3 });
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should work for translateZ', async({page, server, golden}) => {
|
||||
it.skip(ffheadful)('should work for translateZ', async ({page, server, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/screenshots/translateZ.html');
|
||||
const screenshot = await page.screenshot();
|
||||
expect(screenshot).toMatchImage(golden('screenshot-translateZ.png'));
|
||||
});
|
||||
|
||||
it.fixme(options.FIREFOX).flaky(options.WEBKIT && LINUX)('should work for webgl', async({page, server, golden}) => {
|
||||
it.fixme(options.FIREFOX).flaky(options.WEBKIT && LINUX)('should work for webgl', async ({page, server, golden}) => {
|
||||
await page.setViewportSize({width: 640, height: 480});
|
||||
await page.goto(server.PREFIX + '/screenshots/webgl.html');
|
||||
const screenshot = await page.screenshot();
|
||||
expect(screenshot).toMatchImage(golden('screenshot-webgl.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should work while navigating', async({page, server}) => {
|
||||
it.skip(ffheadful)('should work while navigating', async ({page, server}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/redirectloop1.html');
|
||||
for (let i = 0; i < 10; i++) {
|
||||
@ -234,7 +234,7 @@ it.skip(ffheadful)('should work while navigating', async({page, server}) => {
|
||||
}
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should work with device scale factor', async({browser, server, golden}) => {
|
||||
it.skip(ffheadful)('should work with device scale factor', async ({browser, server, golden}) => {
|
||||
const context = await browser.newContext({ viewport: { width: 320, height: 480 }, deviceScaleFactor: 2 });
|
||||
const page = await context.newPage();
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
@ -243,13 +243,13 @@ it.skip(ffheadful)('should work with device scale factor', async({browser, serve
|
||||
await context.close();
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('should work with iframe in shadow', async({page, server, golden}) => {
|
||||
it.skip(ffheadful)('should work with iframe in shadow', async ({page, server, golden}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid-iframe-in-shadow.html');
|
||||
expect(await page.screenshot()).toMatchImage(golden('screenshot-iframe.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('path option should work', async({page, server, golden, tmpDir}) => {
|
||||
it.skip(ffheadful)('path option should work', async ({page, server, golden, tmpDir}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const outputPath = path.join(tmpDir, 'screenshot.png');
|
||||
@ -257,7 +257,7 @@ it.skip(ffheadful)('path option should work', async({page, server, golden, tmpDi
|
||||
expect(await fs.promises.readFile(outputPath)).toMatchImage(golden('screenshot-sanity.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('path option should create subdirectories', async({page, server, golden, tmpDir}) => {
|
||||
it.skip(ffheadful)('path option should create subdirectories', async ({page, server, golden, tmpDir}) => {
|
||||
await page.setViewportSize({width: 500, height: 500});
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
const outputPath = path.join(tmpDir, 'these', 'are', 'directories', 'screenshot.png');
|
||||
@ -265,7 +265,7 @@ it.skip(ffheadful)('path option should create subdirectories', async({page, serv
|
||||
expect(await fs.promises.readFile(outputPath)).toMatchImage(golden('screenshot-sanity.png'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('path option should detect jpeg', async({page, server, golden, tmpDir}) => {
|
||||
it.skip(ffheadful)('path option should detect jpeg', async ({page, server, golden, tmpDir}) => {
|
||||
await page.setViewportSize({ width: 100, height: 100 });
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const outputPath = path.join(tmpDir, 'screenshot.jpg');
|
||||
@ -274,7 +274,7 @@ it.skip(ffheadful)('path option should detect jpeg', async({page, server, golden
|
||||
expect(screenshot).toMatchImage(golden('white.jpg'));
|
||||
});
|
||||
|
||||
it.skip(ffheadful)('path option should throw for unsupported mime type', async({page, server, golden, tmpDir}) => {
|
||||
it.skip(ffheadful)('path option should throw for unsupported mime type', async ({page, server, golden, tmpDir}) => {
|
||||
const error = await page.screenshot({ path: 'file.txt' }).catch(e => e);
|
||||
expect(error.message).toContain('path: unsupported mime type "text/plain"');
|
||||
});
|
||||
|
@ -17,62 +17,63 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should select single option', async({page, server}) => {
|
||||
it('should select single option', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.selectOption('select', 'blue');
|
||||
expect(await page.evaluate(() => window['result'].onInput)).toEqual(['blue']);
|
||||
expect(await page.evaluate(() => window['result'].onChange)).toEqual(['blue']);
|
||||
});
|
||||
|
||||
it('should select single option by value', async({page, server}) => {
|
||||
it('should select single option by value', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.selectOption('select', { value: 'blue' });
|
||||
expect(await page.evaluate(() => window['result'].onInput)).toEqual(['blue']);
|
||||
expect(await page.evaluate(() => window['result'].onChange)).toEqual(['blue']);
|
||||
});
|
||||
|
||||
it('should select single option by label', async({page, server}) => {
|
||||
it('should select single option by label', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.selectOption('select', { label: 'Indigo' });
|
||||
expect(await page.evaluate(() => window['result'].onInput)).toEqual(['indigo']);
|
||||
expect(await page.evaluate(() => window['result'].onChange)).toEqual(['indigo']);
|
||||
});
|
||||
|
||||
it('should select single option by handle', async({page, server}) => {
|
||||
it('should select single option by handle', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.selectOption('select', await page.$('[id=whiteOption]'));
|
||||
expect(await page.evaluate(() => window['result'].onInput)).toEqual(['white']);
|
||||
expect(await page.evaluate(() => window['result'].onChange)).toEqual(['white']);
|
||||
});
|
||||
|
||||
it('should select single option by index', async({page, server}) => {
|
||||
it('should select single option by index', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.selectOption('select', { index: 2 });
|
||||
expect(await page.evaluate(() => window['result'].onInput)).toEqual(['brown']);
|
||||
expect(await page.evaluate(() => window['result'].onChange)).toEqual(['brown']);
|
||||
});
|
||||
|
||||
it('should select single option by multiple attributes', async({page, server}) => {
|
||||
it('should select single option by multiple attributes', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.selectOption('select', { value: 'green', label: 'Green' });
|
||||
expect(await page.evaluate(() => window['result'].onInput)).toEqual(['green']);
|
||||
expect(await page.evaluate(() => window['result'].onChange)).toEqual(['green']);
|
||||
});
|
||||
|
||||
it('should not select single option when some attributes do not match', async({page, server}) => {
|
||||
it('should not select single option when some attributes do not match', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.selectOption('select', { value: 'green', label: 'Brown' });
|
||||
expect(await page.evaluate(() => document.querySelector('select').value)).toEqual('');
|
||||
});
|
||||
|
||||
it('should select only first option', async({page, server}) => {
|
||||
it('should select only first option', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.selectOption('select', ['blue', 'green', 'red']);
|
||||
expect(await page.evaluate(() => window['result'].onInput)).toEqual(['blue']);
|
||||
expect(await page.evaluate(() => window['result'].onChange)).toEqual(['blue']);
|
||||
});
|
||||
|
||||
it('should not throw when select causes navigation', async({page, server}) => { await page.goto(server.PREFIX + '/input/select.html');
|
||||
it('should not throw when select causes navigation', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.$eval('select', select => select.addEventListener('input', () => window.location.href = '/empty.html'));
|
||||
await Promise.all([
|
||||
page.selectOption('select', 'blue'),
|
||||
@ -81,7 +82,7 @@ it('should not throw when select causes navigation', async({page, server}) => {
|
||||
expect(page.url()).toContain('empty.html');
|
||||
});
|
||||
|
||||
it('should select multiple options', async({page, server}) => {
|
||||
it('should select multiple options', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.evaluate(() => window['makeMultiple']());
|
||||
await page.selectOption('select', ['blue', 'green', 'red']);
|
||||
@ -89,7 +90,7 @@ it('should select multiple options', async({page, server}) => {
|
||||
expect(await page.evaluate(() => window['result'].onChange)).toEqual(['blue', 'green', 'red']);
|
||||
});
|
||||
|
||||
it('should select multiple options with attributes', async({page, server}) => {
|
||||
it('should select multiple options with attributes', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.evaluate(() => window['makeMultiple']());
|
||||
await page.selectOption('select', [{ value: 'blue' }, { label: 'Green' }, { index: 4 }]);
|
||||
@ -97,54 +98,54 @@ it('should select multiple options with attributes', async({page, server}) => {
|
||||
expect(await page.evaluate(() => window['result'].onChange)).toEqual(['blue', 'gray', 'green']);
|
||||
});
|
||||
|
||||
it('should respect event bubbling', async({page, server}) => {
|
||||
it('should respect event bubbling', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.selectOption('select', 'blue');
|
||||
expect(await page.evaluate(() => window['result'].onBubblingInput)).toEqual(['blue']);
|
||||
expect(await page.evaluate(() => window['result'].onBubblingChange)).toEqual(['blue']);
|
||||
});
|
||||
|
||||
it('should throw when element is not a <select>', async({page, server}) => {
|
||||
it('should throw when element is not a <select>', async ({page, server}) => {
|
||||
let error = null;
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.selectOption('body', '').catch(e => error = e);
|
||||
expect(error.message).toContain('Element is not a <select> element.');
|
||||
});
|
||||
|
||||
it('should return [] on no matched values', async({page, server}) => {
|
||||
it('should return [] on no matched values', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
const result = await page.selectOption('select', ['42','abc']);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should return an array of matched values', async({page, server}) => {
|
||||
it('should return an array of matched values', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.evaluate(() => window['makeMultiple']());
|
||||
const result = await page.selectOption('select', ['blue','black','magenta']);
|
||||
expect(result.reduce((accumulator,current) => ['blue', 'black', 'magenta'].includes(current) && accumulator, true)).toEqual(true);
|
||||
});
|
||||
|
||||
it('should return an array of one element when multiple is not set', async({page, server}) => {
|
||||
it('should return an array of one element when multiple is not set', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
const result = await page.selectOption('select',['42','blue','black','magenta']);
|
||||
expect(result.length).toEqual(1);
|
||||
});
|
||||
|
||||
it('should return [] on no values',async({page, server}) => {
|
||||
it('should return [] on no values',async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
const result = await page.selectOption('select', []);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should not allow null items',async({page, server}) => {
|
||||
it('should not allow null items',async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.evaluate(() => window['makeMultiple']());
|
||||
let error = null
|
||||
let error = null;
|
||||
await page.selectOption('select', ['blue', null, 'black','magenta']).catch(e => error = e);
|
||||
expect(error.message).toContain('options[1]: expected object, got null');
|
||||
});
|
||||
|
||||
it('should unselect with null',async({page, server}) => {
|
||||
it('should unselect with null',async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.evaluate(() => window['makeMultiple']());
|
||||
const result = await page.selectOption('select', ['blue', 'black','magenta']);
|
||||
@ -153,7 +154,7 @@ it('should unselect with null',async({page, server}) => {
|
||||
expect(await page.$eval('select', select => Array.from(select.options).every(option => !option.selected))).toEqual(true);
|
||||
});
|
||||
|
||||
it('should deselect all options when passed no values for a multiple select',async({page, server}) => {
|
||||
it('should deselect all options when passed no values for a multiple select',async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.evaluate(() => window['makeMultiple']());
|
||||
await page.selectOption('select', ['blue','black','magenta']);
|
||||
@ -161,14 +162,14 @@ it('should deselect all options when passed no values for a multiple select',asy
|
||||
expect(await page.$eval('select', select => Array.from(select.options).every(option => !option.selected))).toEqual(true);
|
||||
});
|
||||
|
||||
it('should deselect all options when passed no values for a select without multiple',async({page, server}) => {
|
||||
it('should deselect all options when passed no values for a select without multiple',async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.selectOption('select', ['blue','black','magenta']);
|
||||
await page.selectOption('select', []);
|
||||
expect(await page.$eval('select', select => Array.from(select.options).every(option => !option.selected))).toEqual(true);
|
||||
});
|
||||
|
||||
it('should throw if passed wrong types', async({page, server}) => {
|
||||
it('should throw if passed wrong types', async ({page, server}) => {
|
||||
let error;
|
||||
await page.setContent('<select><option value="12"/></select>');
|
||||
|
||||
@ -205,7 +206,7 @@ it('should throw if passed wrong types', async({page, server}) => {
|
||||
expect(error.message).toContain('options[0].index: expected number, got string');
|
||||
});
|
||||
// @see https://github.com/GoogleChrome/puppeteer/issues/3327
|
||||
it('should work when re-defining top-level Event class', async({page, server}) => {
|
||||
it('should work when re-defining top-level Event class', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.evaluate(() => window.Event = null);
|
||||
await page.selectOption('select', 'blue');
|
||||
|
@ -19,26 +19,26 @@ import './playwright.fixtures';
|
||||
|
||||
const expectedOutput = '<html><head></head><body><div>hello</div></body></html>';
|
||||
|
||||
it('should work', async({page, server}) => {
|
||||
it('should work', async ({page, server}) => {
|
||||
await page.setContent('<div>hello</div>');
|
||||
const result = await page.content();
|
||||
expect(result).toBe(expectedOutput);
|
||||
});
|
||||
|
||||
it('should work with domcontentloaded', async({page, server}) => {
|
||||
it('should work with domcontentloaded', async ({page, server}) => {
|
||||
await page.setContent('<div>hello</div>', { waitUntil: 'domcontentloaded' });
|
||||
const result = await page.content();
|
||||
expect(result).toBe(expectedOutput);
|
||||
});
|
||||
|
||||
it('should work with doctype', async({page, server}) => {
|
||||
it('should work with doctype', async ({page, server}) => {
|
||||
const doctype = '<!DOCTYPE html>';
|
||||
await page.setContent(`${doctype}<div>hello</div>`);
|
||||
const result = await page.content();
|
||||
expect(result).toBe(`${doctype}${expectedOutput}`);
|
||||
});
|
||||
|
||||
it('should work with HTML 4 doctype', async({page, server}) => {
|
||||
it('should work with HTML 4 doctype', async ({page, server}) => {
|
||||
const doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" ' +
|
||||
'"http://www.w3.org/TR/html4/strict.dtd">';
|
||||
await page.setContent(`${doctype}<div>hello</div>`);
|
||||
@ -46,7 +46,7 @@ it('should work with HTML 4 doctype', async({page, server}) => {
|
||||
expect(result).toBe(`${doctype}${expectedOutput}`);
|
||||
});
|
||||
|
||||
it('should respect timeout', async({page, server, playwright}) => {
|
||||
it('should respect timeout', async ({page, server, playwright}) => {
|
||||
const imgPath = '/img.png';
|
||||
// stall for image
|
||||
server.setRoute(imgPath, (req, res) => {});
|
||||
@ -55,7 +55,7 @@ it('should respect timeout', async({page, server, playwright}) => {
|
||||
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
|
||||
});
|
||||
|
||||
it('should respect default navigation timeout', async({page, server, playwright}) => {
|
||||
it('should respect default navigation timeout', async ({page, server, playwright}) => {
|
||||
page.setDefaultNavigationTimeout(1);
|
||||
const imgPath = '/img.png';
|
||||
// stall for image
|
||||
@ -65,7 +65,7 @@ it('should respect default navigation timeout', async({page, server, playwright}
|
||||
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
|
||||
});
|
||||
|
||||
it('should await resources to load', async({page, server}) => {
|
||||
it('should await resources to load', async ({page, server}) => {
|
||||
const imgPath = '/img.png';
|
||||
let imgResponse = null;
|
||||
server.setRoute(imgPath, (req, res) => imgResponse = res);
|
||||
@ -77,27 +77,27 @@ it('should await resources to load', async({page, server}) => {
|
||||
await contentPromise;
|
||||
});
|
||||
|
||||
it('should work fast enough', async({page, server}) => {
|
||||
it('should work fast enough', async ({page, server}) => {
|
||||
for (let i = 0; i < 20; ++i)
|
||||
await page.setContent('<div>yo</div>');
|
||||
});
|
||||
|
||||
it('should work with tricky content', async({page, server}) => {
|
||||
it('should work with tricky content', async ({page, server}) => {
|
||||
await page.setContent('<div>hello world</div>' + '\x7F');
|
||||
expect(await page.$eval('div', div => div.textContent)).toBe('hello world');
|
||||
});
|
||||
|
||||
it('should work with accents', async({page, server}) => {
|
||||
it('should work with accents', async ({page, server}) => {
|
||||
await page.setContent('<div>aberración</div>');
|
||||
expect(await page.$eval('div', div => div.textContent)).toBe('aberración');
|
||||
});
|
||||
|
||||
it('should work with emojis', async({page, server}) => {
|
||||
it('should work with emojis', async ({page, server}) => {
|
||||
await page.setContent('<div>🐥</div>');
|
||||
expect(await page.$eval('div', div => div.textContent)).toBe('🐥');
|
||||
});
|
||||
|
||||
it('should work with newline', async({page, server}) => {
|
||||
it('should work with newline', async ({page, server}) => {
|
||||
await page.setContent('<div>\n</div>');
|
||||
expect(await page.$eval('div', div => div.textContent)).toBe('\n');
|
||||
});
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import './playwright.fixtures';
|
||||
|
||||
it('should work', async({page, server}) => {
|
||||
it('should work', async ({page, server}) => {
|
||||
await page.setExtraHTTPHeaders({
|
||||
foo: 'bar',
|
||||
baz: undefined,
|
||||
@ -30,7 +30,7 @@ it('should work', async({page, server}) => {
|
||||
expect(request.headers['baz']).toBe(undefined);
|
||||
});
|
||||
|
||||
it('should work with redirects', async({page, server}) => {
|
||||
it('should work with redirects', async ({page, server}) => {
|
||||
server.setRedirect('/foo.html', '/empty.html');
|
||||
await page.setExtraHTTPHeaders({
|
||||
foo: 'bar'
|
||||
@ -42,7 +42,7 @@ it('should work with redirects', async({page, server}) => {
|
||||
expect(request.headers['foo']).toBe('bar');
|
||||
});
|
||||
|
||||
it('should work with extra headers from browser context', async({browser, server}) => {
|
||||
it('should work with extra headers from browser context', async ({browser, server}) => {
|
||||
const context = await browser.newContext();
|
||||
await context.setExtraHTTPHeaders({
|
||||
'foo': 'bar',
|
||||
@ -56,7 +56,7 @@ it('should work with extra headers from browser context', async({browser, server
|
||||
expect(request.headers['foo']).toBe('bar');
|
||||
});
|
||||
|
||||
it('should override extra headers from browser context', async({browser, server}) => {
|
||||
it('should override extra headers from browser context', async ({browser, server}) => {
|
||||
const context = await browser.newContext({
|
||||
extraHTTPHeaders: { 'fOo': 'bAr', 'baR': 'foO' },
|
||||
});
|
||||
@ -73,7 +73,7 @@ it('should override extra headers from browser context', async({browser, server}
|
||||
expect(request.headers['bar']).toBe('foO');
|
||||
});
|
||||
|
||||
it('should throw for non-string header values', async({browser, page}) => {
|
||||
it('should throw for non-string header values', async ({browser, page}) => {
|
||||
const error1 = await page.setExtraHTTPHeaders({ 'foo': 1 as any }).catch(e => e);
|
||||
expect(error1.message).toContain('Expected value of header "foo" to be String, but "number" is found.');
|
||||
const error2 = await page.context().setExtraHTTPHeaders({ 'foo': true as any }).catch(e => e);
|
||||
|
@ -23,7 +23,7 @@ import formidable from 'formidable';
|
||||
|
||||
const FILE_TO_UPLOAD = path.join(__dirname, '/assets/file-to-upload.txt');
|
||||
|
||||
it('should upload the file', async({page, server}) => {
|
||||
it('should upload the file', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/fileupload.html');
|
||||
const filePath = path.relative(process.cwd(), FILE_TO_UPLOAD);
|
||||
const input = await page.$('input');
|
||||
@ -37,14 +37,14 @@ it('should upload the file', async({page, server}) => {
|
||||
}, input)).toBe('contents of the file');
|
||||
});
|
||||
|
||||
it('should work', async({page}) => {
|
||||
it('should work', async ({page}) => {
|
||||
await page.setContent(`<input type=file>`);
|
||||
await page.setInputFiles('input', path.join(__dirname, '/assets/file-to-upload.txt'));
|
||||
expect(await page.$eval('input', input => input.files.length)).toBe(1);
|
||||
expect(await page.$eval('input', input => input.files[0].name)).toBe('file-to-upload.txt');
|
||||
});
|
||||
|
||||
it('should set from memory', async({page}) => {
|
||||
it('should set from memory', async ({page}) => {
|
||||
await page.setContent(`<input type=file>`);
|
||||
await page.setInputFiles('input', {
|
||||
name: 'test.txt',
|
||||
@ -55,7 +55,7 @@ it('should set from memory', async({page}) => {
|
||||
expect(await page.$eval('input', input => input.files[0].name)).toBe('test.txt');
|
||||
});
|
||||
|
||||
it('should emit event once', async({page, server}) => {
|
||||
it('should emit event once', async ({page, server}) => {
|
||||
await page.setContent(`<input type=file>`);
|
||||
const [chooser] = await Promise.all([
|
||||
new Promise(f => page.once('filechooser', f)),
|
||||
@ -64,14 +64,14 @@ it('should emit event once', async({page, server}) => {
|
||||
expect(chooser).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should emit event on/off', async({page, server}) => {
|
||||
it('should emit event on/off', async ({page, server}) => {
|
||||
await page.setContent(`<input type=file>`);
|
||||
const [chooser] = await Promise.all([
|
||||
new Promise(f => {
|
||||
const listener = chooser => {
|
||||
page.off('filechooser', listener);
|
||||
f(chooser);
|
||||
}
|
||||
};
|
||||
page.on('filechooser', listener);
|
||||
}),
|
||||
page.click('input'),
|
||||
@ -79,14 +79,14 @@ it('should emit event on/off', async({page, server}) => {
|
||||
expect(chooser).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should emit event addListener/removeListener', async({page, server}) => {
|
||||
it('should emit event addListener/removeListener', async ({page, server}) => {
|
||||
await page.setContent(`<input type=file>`);
|
||||
const [chooser] = await Promise.all([
|
||||
new Promise(f => {
|
||||
const listener = chooser => {
|
||||
page.removeListener('filechooser', listener);
|
||||
f(chooser);
|
||||
}
|
||||
};
|
||||
page.addListener('filechooser', listener);
|
||||
}),
|
||||
page.click('input'),
|
||||
@ -94,7 +94,7 @@ it('should emit event addListener/removeListener', async({page, server}) => {
|
||||
expect(chooser).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should work when file input is attached to DOM', async({page, server}) => {
|
||||
it('should work when file input is attached to DOM', async ({page, server}) => {
|
||||
await page.setContent(`<input type=file>`);
|
||||
const [chooser] = await Promise.all([
|
||||
page.waitForEvent('filechooser'),
|
||||
@ -103,7 +103,7 @@ it('should work when file input is attached to DOM', async({page, server}) => {
|
||||
expect(chooser).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should work when file input is not attached to DOM', async({page, server}) => {
|
||||
it('should work when file input is not attached to DOM', async ({page, server}) => {
|
||||
const [chooser] = await Promise.all([
|
||||
page.waitForEvent('filechooser'),
|
||||
page.evaluate(() => {
|
||||
@ -115,27 +115,27 @@ it('should work when file input is not attached to DOM', async({page, server}) =
|
||||
expect(chooser).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should respect timeout', async({page, playwright}) => {
|
||||
it('should respect timeout', async ({page, playwright}) => {
|
||||
let error = null;
|
||||
await page.waitForEvent('filechooser', {timeout: 1}).catch(e => error = e);
|
||||
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
|
||||
});
|
||||
|
||||
it('should respect default timeout when there is no custom timeout', async({page, playwright}) => {
|
||||
it('should respect default timeout when there is no custom timeout', async ({page, playwright}) => {
|
||||
page.setDefaultTimeout(1);
|
||||
let error = null;
|
||||
await page.waitForEvent('filechooser').catch(e => error = e);
|
||||
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
|
||||
});
|
||||
|
||||
it('should prioritize exact timeout over default timeout', async({page, playwright}) => {
|
||||
it('should prioritize exact timeout over default timeout', async ({page, playwright}) => {
|
||||
page.setDefaultTimeout(0);
|
||||
let error = null;
|
||||
await page.waitForEvent('filechooser', {timeout: 1}).catch(e => error = e);
|
||||
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
|
||||
});
|
||||
|
||||
it('should work with no timeout', async({page, server}) => {
|
||||
it('should work with no timeout', async ({page, server}) => {
|
||||
const [chooser] = await Promise.all([
|
||||
page.waitForEvent('filechooser', {timeout: 0}),
|
||||
page.evaluate(() => setTimeout(() => {
|
||||
@ -147,7 +147,7 @@ it('should work with no timeout', async({page, server}) => {
|
||||
expect(chooser).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return the same file chooser when there are many watchdogs simultaneously', async({page, server}) => {
|
||||
it('should return the same file chooser when there are many watchdogs simultaneously', async ({page, server}) => {
|
||||
await page.setContent(`<input type=file>`);
|
||||
const [fileChooser1, fileChooser2] = await Promise.all([
|
||||
page.waitForEvent('filechooser'),
|
||||
@ -157,7 +157,7 @@ it('should return the same file chooser when there are many watchdogs simultaneo
|
||||
expect(fileChooser1 === fileChooser2).toBe(true);
|
||||
});
|
||||
|
||||
it('should accept single file', async({page, server}) => {
|
||||
it('should accept single file', async ({page, server}) => {
|
||||
await page.setContent(`<input type=file oninput='javascript:console.timeStamp()'>`);
|
||||
const [fileChooser] = await Promise.all([
|
||||
page.waitForEvent('filechooser'),
|
||||
@ -170,7 +170,7 @@ it('should accept single file', async({page, server}) => {
|
||||
expect(await page.$eval('input', input => input.files[0].name)).toBe('file-to-upload.txt');
|
||||
});
|
||||
|
||||
it('should detect mime type', async({page, server}) => {
|
||||
it('should detect mime type', async ({page, server}) => {
|
||||
let files;
|
||||
server.setRoute('/upload', async (req, res) => {
|
||||
const form = new formidable.IncomingForm();
|
||||
@ -185,7 +185,7 @@ it('should detect mime type', async({page, server}) => {
|
||||
<input type="file" name="file1">
|
||||
<input type="file" name="file2">
|
||||
<input type="submit" value="Submit">
|
||||
</form>`)
|
||||
</form>`);
|
||||
await (await page.$('input[name=file1]')).setInputFiles(path.join(__dirname, '/assets/file-to-upload.txt'));
|
||||
await (await page.$('input[name=file2]')).setInputFiles(path.join(__dirname, '/assets/pptr.png'));
|
||||
await Promise.all([
|
||||
@ -196,14 +196,14 @@ it('should detect mime type', async({page, server}) => {
|
||||
expect(file1.name).toBe('file-to-upload.txt');
|
||||
expect(file1.type).toBe('text/plain');
|
||||
expect(fs.readFileSync(file1.path).toString()).toBe(
|
||||
fs.readFileSync(path.join(__dirname, '/assets/file-to-upload.txt')).toString());
|
||||
fs.readFileSync(path.join(__dirname, '/assets/file-to-upload.txt')).toString());
|
||||
expect(file2.name).toBe('pptr.png');
|
||||
expect(file2.type).toBe('image/png');
|
||||
expect(fs.readFileSync(file2.path).toString()).toBe(
|
||||
fs.readFileSync(path.join(__dirname, '/assets/pptr.png')).toString());
|
||||
fs.readFileSync(path.join(__dirname, '/assets/pptr.png')).toString());
|
||||
});
|
||||
|
||||
it('should be able to read selected file', async({page, server}) => {
|
||||
it('should be able to read selected file', async ({page, server}) => {
|
||||
await page.setContent(`<input type=file>`);
|
||||
const [, content] = await Promise.all([
|
||||
page.waitForEvent('filechooser').then(fileChooser => fileChooser.setFiles(FILE_TO_UPLOAD)),
|
||||
@ -219,7 +219,7 @@ it('should be able to read selected file', async({page, server}) => {
|
||||
expect(content).toBe('contents of the file');
|
||||
});
|
||||
|
||||
it('should be able to reset selected files with empty file list', async({page, server}) => {
|
||||
it('should be able to reset selected files with empty file list', async ({page, server}) => {
|
||||
await page.setContent(`<input type=file>`);
|
||||
const [, fileLength1] = await Promise.all([
|
||||
page.waitForEvent('filechooser').then(fileChooser => fileChooser.setFiles(FILE_TO_UPLOAD)),
|
||||
@ -241,7 +241,7 @@ it('should be able to reset selected files with empty file list', async({page, s
|
||||
expect(fileLength2).toBe(0);
|
||||
});
|
||||
|
||||
it('should not accept multiple files for single-file input', async({page, server}) => {
|
||||
it('should not accept multiple files for single-file input', async ({page, server}) => {
|
||||
await page.setContent(`<input type=file>`);
|
||||
const [fileChooser] = await Promise.all([
|
||||
page.waitForEvent('filechooser'),
|
||||
@ -255,7 +255,7 @@ it('should not accept multiple files for single-file input', async({page, server
|
||||
expect(error).not.toBe(null);
|
||||
});
|
||||
|
||||
it('should emit input and change events', async({page, server}) => {
|
||||
it('should emit input and change events', async ({page, server}) => {
|
||||
const events = [];
|
||||
await page.exposeFunction('eventHandled', e => events.push(e));
|
||||
await page.setContent(`
|
||||
@ -270,7 +270,7 @@ it('should emit input and change events', async({page, server}) => {
|
||||
expect(events[1].type).toBe('change');
|
||||
});
|
||||
|
||||
it('should work for single file pick', async({page, server}) => {
|
||||
it('should work for single file pick', async ({page, server}) => {
|
||||
await page.setContent(`<input type=file>`);
|
||||
const [fileChooser] = await Promise.all([
|
||||
page.waitForEvent('filechooser'),
|
||||
@ -279,7 +279,7 @@ it('should work for single file pick', async({page, server}) => {
|
||||
expect(fileChooser.isMultiple()).toBe(false);
|
||||
});
|
||||
|
||||
it('should work for "multiple"', async({page, server}) => {
|
||||
it('should work for "multiple"', async ({page, server}) => {
|
||||
await page.setContent(`<input multiple type=file>`);
|
||||
const [fileChooser] = await Promise.all([
|
||||
page.waitForEvent('filechooser'),
|
||||
@ -288,7 +288,7 @@ it('should work for "multiple"', async({page, server}) => {
|
||||
expect(fileChooser.isMultiple()).toBe(true);
|
||||
});
|
||||
|
||||
it('should work for "webkitdirectory"', async({page, server}) => {
|
||||
it('should work for "webkitdirectory"', async ({page, server}) => {
|
||||
await page.setContent(`<input multiple webkitdirectory type=file>`);
|
||||
const [fileChooser] = await Promise.all([
|
||||
page.waitForEvent('filechooser'),
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user