chore: break page.spec.js to smaller files (#2257)
Break some large chunks into smaller files. This change will remove ~600 lines from `page.spec.js`
This commit is contained in:
parent
abb05e069d
commit
ebe17371b0
73
test/CDPSession.spec.js
Normal file
73
test/CDPSession.spec.js
Normal file
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright 2018 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const {waitForEvents} = require('./utils');
|
||||
|
||||
module.exports.addTests = function({testRunner, expect}) {
|
||||
const {describe, xdescribe, fdescribe} = testRunner;
|
||||
const {it, fit, xit} = testRunner;
|
||||
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
|
||||
|
||||
describe('Target.createCDPSession', function() {
|
||||
it('should work', async function({page, server}) {
|
||||
const client = await page.target().createCDPSession();
|
||||
|
||||
await Promise.all([
|
||||
client.send('Runtime.enable'),
|
||||
client.send('Runtime.evaluate', { expression: 'window.foo = "bar"' })
|
||||
]);
|
||||
const foo = await page.evaluate(() => window.foo);
|
||||
expect(foo).toBe('bar');
|
||||
});
|
||||
it('should send events', async function({page, server}) {
|
||||
const client = await page.target().createCDPSession();
|
||||
await client.send('Network.enable');
|
||||
const events = [];
|
||||
client.on('Network.requestWillBeSent', event => events.push(event));
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect(events.length).toBe(1);
|
||||
});
|
||||
it('should enable and disable domains independently', async function({page, server}) {
|
||||
const client = await page.target().createCDPSession();
|
||||
await client.send('Runtime.enable');
|
||||
await client.send('Debugger.enable');
|
||||
// JS coverage enables and then disables Debugger domain.
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.coverage.stopJSCoverage();
|
||||
// generate a script in page and wait for the event.
|
||||
const [event] = await Promise.all([
|
||||
waitForEvents(client, 'Debugger.scriptParsed'),
|
||||
page.evaluate('//# sourceURL=foo.js')
|
||||
]);
|
||||
// expect events to be dispatched.
|
||||
expect(event.url).toBe('foo.js');
|
||||
});
|
||||
it('should be able to detach session', async function({page, server}) {
|
||||
const client = await page.target().createCDPSession();
|
||||
await client.send('Runtime.enable');
|
||||
const evalResponse = await client.send('Runtime.evaluate', {expression: '1 + 2', returnByValue: true});
|
||||
expect(evalResponse.result.value).toBe(3);
|
||||
await client.detach();
|
||||
let error = null;
|
||||
try {
|
||||
await client.send('Runtime.evaluate', {expression: '3 + 1', returnByValue: true});
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error.message).toContain('Session closed.');
|
||||
});
|
||||
});
|
||||
};
|
233
test/cookies.spec.js
Normal file
233
test/cookies.spec.js
Normal file
@ -0,0 +1,233 @@
|
||||
/**
|
||||
* Copyright 2018 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module.exports.addTests = function({testRunner, expect}) {
|
||||
const {describe, xdescribe, fdescribe} = testRunner;
|
||||
const {it, fit, xit} = testRunner;
|
||||
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
|
||||
|
||||
describe('Cookies', function() {
|
||||
afterEach(async({page, server}) => {
|
||||
const cookies = await page.cookies(server.PREFIX + '/grid.html', server.CROSS_PROCESS_PREFIX);
|
||||
for (const cookie of cookies)
|
||||
await page.deleteCookie(cookie);
|
||||
});
|
||||
it('should set and get cookies', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
expect(await page.cookies()).toEqual([]);
|
||||
await page.evaluate(() => {
|
||||
document.cookie = 'username=John Doe';
|
||||
});
|
||||
expect(await page.cookies()).toEqual([{
|
||||
name: 'username',
|
||||
value: 'John Doe',
|
||||
domain: 'localhost',
|
||||
path: '/',
|
||||
expires: -1,
|
||||
size: 16,
|
||||
httpOnly: false,
|
||||
secure: false,
|
||||
session: true }
|
||||
]);
|
||||
await page.setCookie({
|
||||
name: 'password',
|
||||
value: '123456'
|
||||
});
|
||||
expect(await page.evaluate('document.cookie')).toBe('username=John Doe; password=123456');
|
||||
const cookies = await page.cookies();
|
||||
expect(cookies.sort((a, b) => a.name.localeCompare(b.name))).toEqual([{
|
||||
name: 'password',
|
||||
value: '123456',
|
||||
domain: 'localhost',
|
||||
path: '/',
|
||||
expires: -1,
|
||||
size: 14,
|
||||
httpOnly: false,
|
||||
secure: false,
|
||||
session: true
|
||||
}, {
|
||||
name: 'username',
|
||||
value: 'John Doe',
|
||||
domain: 'localhost',
|
||||
path: '/',
|
||||
expires: -1,
|
||||
size: 16,
|
||||
httpOnly: false,
|
||||
secure: false,
|
||||
session: true
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should set a cookie with a path', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
await page.setCookie({
|
||||
name: 'gridcookie',
|
||||
value: 'GRID',
|
||||
path: '/grid.html'
|
||||
});
|
||||
expect(await page.cookies()).toEqual([{
|
||||
name: 'gridcookie',
|
||||
value: 'GRID',
|
||||
domain: 'localhost',
|
||||
path: '/grid.html',
|
||||
expires: -1,
|
||||
size: 14,
|
||||
httpOnly: false,
|
||||
secure: false,
|
||||
session: true
|
||||
}]);
|
||||
expect(await page.evaluate('document.cookie')).toBe('gridcookie=GRID');
|
||||
await page.goto(server.PREFIX + '/empty.html');
|
||||
expect(await page.cookies()).toEqual([]);
|
||||
expect(await page.evaluate('document.cookie')).toBe('');
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
expect(await page.evaluate('document.cookie')).toBe('gridcookie=GRID');
|
||||
});
|
||||
|
||||
|
||||
it('should delete a cookie', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
await page.setCookie({
|
||||
name: 'cookie1',
|
||||
value: '1'
|
||||
}, {
|
||||
name: 'cookie2',
|
||||
value: '2'
|
||||
}, {
|
||||
name: 'cookie3',
|
||||
value: '3'
|
||||
});
|
||||
expect(await page.evaluate('document.cookie')).toBe('cookie1=1; cookie2=2; cookie3=3');
|
||||
await page.deleteCookie({name: 'cookie2'});
|
||||
expect(await page.evaluate('document.cookie')).toBe('cookie1=1; cookie3=3');
|
||||
});
|
||||
|
||||
it('should not set a cookie on a blank page', async function({page}) {
|
||||
let error = null;
|
||||
await page.goto('about:blank');
|
||||
try {
|
||||
await page.setCookie({name: 'example-cookie', value: 'best'});
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error).toBeTruthy();
|
||||
expect(error.message).toEqual('Protocol error (Network.deleteCookies): At least one of the url and domain needs to be specified undefined');
|
||||
});
|
||||
|
||||
it('should not set a cookie with blank page URL', async function({page, server}) {
|
||||
let error = null;
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
try {
|
||||
await page.setCookie(
|
||||
{name: 'example-cookie', value: 'best'},
|
||||
{url: 'about:blank', name: 'example-cookie-blank', value: 'best'}
|
||||
);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error).toBeTruthy();
|
||||
expect(error.message).toEqual(
|
||||
`Blank page can not have cookie "example-cookie-blank"`
|
||||
);
|
||||
});
|
||||
|
||||
it('should not set a cookie on a data URL page', async function({page}) {
|
||||
let error = null;
|
||||
await page.goto('data:,Hello%2C%20World!');
|
||||
try {
|
||||
await page.setCookie({name: 'example-cookie', value: 'best'});
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error).toBeTruthy();
|
||||
expect(error.message).toEqual(
|
||||
'Protocol error (Network.deleteCookies): At least one of the url and domain needs to be specified undefined'
|
||||
);
|
||||
});
|
||||
|
||||
it('should not set a cookie with blank page URL', async function({page, server}) {
|
||||
let error = null;
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
try {
|
||||
await page.setCookie({name: 'example-cookie', value: 'best'}, {url: 'about:blank', name: 'example-cookie-blank', value: 'best'});
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error).toBeTruthy();
|
||||
expect(error.message).toEqual(`Blank page can not have cookie "example-cookie-blank"`);
|
||||
});
|
||||
|
||||
it('should set a cookie on a different domain', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
await page.setCookie({name: 'example-cookie', value: 'best', url: 'https://www.example.com'});
|
||||
expect(await page.evaluate('document.cookie')).toBe('');
|
||||
expect(await page.cookies()).toEqual([]);
|
||||
expect(await page.cookies('https://www.example.com')).toEqual([{
|
||||
name: 'example-cookie',
|
||||
value: 'best',
|
||||
domain: 'www.example.com',
|
||||
path: '/',
|
||||
expires: -1,
|
||||
size: 18,
|
||||
httpOnly: false,
|
||||
secure: true,
|
||||
session: true
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should set cookies from a frame', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
await page.setCookie({name: 'localhost-cookie', value: 'best'});
|
||||
await page.evaluate(src => {
|
||||
let fulfill;
|
||||
const promise = new Promise(x => fulfill = x);
|
||||
const iframe = document.createElement('iframe');
|
||||
document.body.appendChild(iframe);
|
||||
iframe.onload = fulfill;
|
||||
iframe.src = src;
|
||||
return promise;
|
||||
}, server.CROSS_PROCESS_PREFIX);
|
||||
await page.setCookie({name: '127-cookie', value: 'worst', url: server.CROSS_PROCESS_PREFIX});
|
||||
expect(await page.evaluate('document.cookie')).toBe('localhost-cookie=best');
|
||||
expect(await page.frames()[1].evaluate('document.cookie')).toBe('127-cookie=worst');
|
||||
|
||||
expect(await page.cookies()).toEqual([{
|
||||
name: 'localhost-cookie',
|
||||
value: 'best',
|
||||
domain: 'localhost',
|
||||
path: '/',
|
||||
expires: -1,
|
||||
size: 20,
|
||||
httpOnly: false,
|
||||
secure: false,
|
||||
session: true
|
||||
}]);
|
||||
|
||||
expect(await page.cookies(server.CROSS_PROCESS_PREFIX)).toEqual([{
|
||||
name: '127-cookie',
|
||||
value: 'worst',
|
||||
domain: '127.0.0.1',
|
||||
path: '/',
|
||||
expires: -1,
|
||||
size: 15,
|
||||
httpOnly: false,
|
||||
secure: false,
|
||||
session: true
|
||||
}]);
|
||||
|
||||
});
|
||||
});
|
||||
};
|
179
test/coverage.spec.js
Normal file
179
test/coverage.spec.js
Normal file
@ -0,0 +1,179 @@
|
||||
/**
|
||||
* Copyright 2018 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module.exports.addTests = function({testRunner, expect}) {
|
||||
const {describe, xdescribe, fdescribe} = testRunner;
|
||||
const {it, fit, xit} = testRunner;
|
||||
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
|
||||
|
||||
describe('JSCoverage', function() {
|
||||
it('should work', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.PREFIX + '/jscoverage/simple.html');
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
expect(coverage[0].url).toContain('/jscoverage/simple.html');
|
||||
expect(coverage[0].ranges).toEqual([
|
||||
{ start: 0, end: 17 },
|
||||
{ start: 35, end: 61 },
|
||||
]);
|
||||
});
|
||||
it('should report sourceURLs', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.PREFIX + '/jscoverage/sourceurl.html');
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
expect(coverage[0].url).toBe('nicename.js');
|
||||
});
|
||||
it('should ignore anonymous scripts', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.evaluate(() => console.log(1));
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.length).toBe(0);
|
||||
});
|
||||
it('should report multiple scripts', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.PREFIX + '/jscoverage/multiple.html');
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.length).toBe(2);
|
||||
coverage.sort((a, b) => a.url.localeCompare(b.url));
|
||||
expect(coverage[0].url).toContain('/jscoverage/script1.js');
|
||||
expect(coverage[1].url).toContain('/jscoverage/script2.js');
|
||||
});
|
||||
it('should report right ranges', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.PREFIX + '/jscoverage/ranges.html');
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
const entry = coverage[0];
|
||||
expect(entry.ranges.length).toBe(1);
|
||||
const range = entry.ranges[0];
|
||||
expect(entry.text.substring(range.start, range.end)).toBe(`console.log('used!');`);
|
||||
});
|
||||
it('should report scripts that have no coverage', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.PREFIX + '/jscoverage/unused.html');
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
const entry = coverage[0];
|
||||
expect(entry.url).toContain('unused.html');
|
||||
expect(entry.ranges.length).toBe(0);
|
||||
});
|
||||
it('should work with conditionals', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.PREFIX + '/jscoverage/involved.html');
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(JSON.stringify(coverage, null, 2).replace(/:\d{4}\//g, ':<PORT>/')).toBeGolden('jscoverage-involved.txt');
|
||||
});
|
||||
describe('resetOnNavigation', function() {
|
||||
it('should report scripts across navigations when disabled', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage({resetOnNavigation: false});
|
||||
await page.goto(server.PREFIX + '/jscoverage/multiple.html');
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.length).toBe(2);
|
||||
});
|
||||
it('should NOT report scripts across navigations when enabled', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage(); // Enabled by default.
|
||||
await page.goto(server.PREFIX + '/jscoverage/multiple.html');
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.length).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('CSSCoverage', function() {
|
||||
it('should work', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.goto(server.PREFIX + '/csscoverage/simple.html');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
expect(coverage[0].url).toContain('/csscoverage/simple.html');
|
||||
expect(coverage[0].ranges).toEqual([
|
||||
{start: 1, end: 22}
|
||||
]);
|
||||
const range = coverage[0].ranges[0];
|
||||
expect(coverage[0].text.substring(range.start, range.end)).toBe('div { color: green; }');
|
||||
});
|
||||
it('should report sourceURLs', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.goto(server.PREFIX + '/csscoverage/sourceurl.html');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
expect(coverage[0].url).toBe('nicename.css');
|
||||
});
|
||||
it('should report multiple stylesheets', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.goto(server.PREFIX + '/csscoverage/multiple.html');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(2);
|
||||
coverage.sort((a, b) => a.url.localeCompare(b.url));
|
||||
expect(coverage[0].url).toContain('/csscoverage/stylesheet1.css');
|
||||
expect(coverage[1].url).toContain('/csscoverage/stylesheet2.css');
|
||||
});
|
||||
it('should report stylesheets that have no coverage', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.goto(server.PREFIX + '/csscoverage/unused.html');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
expect(coverage[0].url).toBe('unused.css');
|
||||
expect(coverage[0].ranges.length).toBe(0);
|
||||
});
|
||||
it('should work with media queries', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.goto(server.PREFIX + '/csscoverage/media.html');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
expect(coverage[0].url).toContain('/csscoverage/media.html');
|
||||
expect(coverage[0].ranges).toEqual([
|
||||
{start: 17, end: 38}
|
||||
]);
|
||||
});
|
||||
it('should work with complicated usecases', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.goto(server.PREFIX + '/csscoverage/involved.html');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(JSON.stringify(coverage, null, 2).replace(/:\d{4}\//g, ':<PORT>/')).toBeGolden('csscoverage-involved.txt');
|
||||
});
|
||||
it('should ignore injected stylesheets', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.addStyleTag({content: 'body { margin: 10px;}'});
|
||||
// trigger style recalc
|
||||
const margin = await page.evaluate(() => window.getComputedStyle(document.body).margin);
|
||||
expect(margin).toBe('10px');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(0);
|
||||
});
|
||||
describe('resetOnNavigation', function() {
|
||||
it('should report stylesheets across navigations', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage({resetOnNavigation: false});
|
||||
await page.goto(server.PREFIX + '/csscoverage/multiple.html');
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(2);
|
||||
});
|
||||
it('should NOT report scripts across navigations', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage(); // Enabled by default.
|
||||
await page.goto(server.PREFIX + '/csscoverage/multiple.html');
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright 2017 Google Inc. All rights reserved.
|
||||
* Copyright 2018 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -374,4 +374,87 @@ module.exports.addTests = function({testRunner, expect}) {
|
||||
expect(await page.evaluate(x => x.textContent, await waitForXPath)).toBe('some text');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Frame Management', function() {
|
||||
it('should handle nested frames', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/frames/nested-frames.html');
|
||||
expect(utils.dumpFrames(page.mainFrame())).toBeGolden('nested-frames.txt');
|
||||
});
|
||||
it('should send events when frames are manipulated dynamically', async({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
// validate frameattached events
|
||||
const attachedFrames = [];
|
||||
page.on('frameattached', frame => attachedFrames.push(frame));
|
||||
await utils.attachFrame(page, 'frame1', './assets/frame.html');
|
||||
expect(attachedFrames.length).toBe(1);
|
||||
expect(attachedFrames[0].url()).toContain('/assets/frame.html');
|
||||
|
||||
// validate framenavigated events
|
||||
const navigatedFrames = [];
|
||||
page.on('framenavigated', frame => navigatedFrames.push(frame));
|
||||
await utils.navigateFrame(page, 'frame1', './empty.html');
|
||||
expect(navigatedFrames.length).toBe(1);
|
||||
expect(navigatedFrames[0].url()).toBe(server.EMPTY_PAGE);
|
||||
|
||||
// validate framedetached events
|
||||
const detachedFrames = [];
|
||||
page.on('framedetached', frame => detachedFrames.push(frame));
|
||||
await utils.detachFrame(page, 'frame1');
|
||||
expect(detachedFrames.length).toBe(1);
|
||||
expect(detachedFrames[0].isDetached()).toBe(true);
|
||||
});
|
||||
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}) => {
|
||||
let hasEvents = false;
|
||||
page.on('frameattached', frame => hasEvents = true);
|
||||
page.on('framedetached', frame => hasEvents = true);
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect(hasEvents).toBe(false);
|
||||
});
|
||||
it('should detach child frames on navigation', async({page, server}) => {
|
||||
let attachedFrames = [];
|
||||
let detachedFrames = [];
|
||||
let navigatedFrames = [];
|
||||
page.on('frameattached', frame => attachedFrames.push(frame));
|
||||
page.on('framedetached', frame => detachedFrames.push(frame));
|
||||
page.on('framenavigated', frame => navigatedFrames.push(frame));
|
||||
await page.goto(server.PREFIX + '/frames/nested-frames.html');
|
||||
expect(attachedFrames.length).toBe(4);
|
||||
expect(detachedFrames.length).toBe(0);
|
||||
expect(navigatedFrames.length).toBe(5);
|
||||
|
||||
attachedFrames = [];
|
||||
detachedFrames = [];
|
||||
navigatedFrames = [];
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect(attachedFrames.length).toBe(0);
|
||||
expect(detachedFrames.length).toBe(4);
|
||||
expect(navigatedFrames.length).toBe(1);
|
||||
});
|
||||
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');
|
||||
frame.name = 'theFrameName';
|
||||
frame.src = url;
|
||||
document.body.appendChild(frame);
|
||||
return new Promise(x => frame.onload = x);
|
||||
}, server.EMPTY_PAGE);
|
||||
expect(page.frames()[0].name()).toBe('');
|
||||
expect(page.frames()[1].name()).toBe('theFrameId');
|
||||
expect(page.frames()[2].name()).toBe('theFrameName');
|
||||
});
|
||||
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);
|
||||
expect(page.frames()[1].parentFrame()).toBe(page.mainFrame());
|
||||
expect(page.frames()[2].parentFrame()).toBe(page.mainFrame());
|
||||
});
|
||||
});
|
||||
};
|
@ -53,7 +53,11 @@ module.exports.addTests = function({testRunner, expect, defaultBrowserOptions, p
|
||||
'tracing.spec.js',
|
||||
'frame.spec.js',
|
||||
'input.spec.js',
|
||||
'network.spec.js'
|
||||
'network.spec.js',
|
||||
'cookies.spec.js',
|
||||
'target.spec.js',
|
||||
'CDPSession.spec.js',
|
||||
'coverage.spec.js'
|
||||
];
|
||||
|
||||
testFiles
|
||||
@ -1086,89 +1090,6 @@ module.exports.addTests = function({testRunner, expect, defaultBrowserOptions, p
|
||||
});
|
||||
});
|
||||
|
||||
describe('Frame Management', function() {
|
||||
it('should handle nested frames', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/frames/nested-frames.html');
|
||||
expect(utils.dumpFrames(page.mainFrame())).toBeGolden('nested-frames.txt');
|
||||
});
|
||||
it('should send events when frames are manipulated dynamically', async({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
// validate frameattached events
|
||||
const attachedFrames = [];
|
||||
page.on('frameattached', frame => attachedFrames.push(frame));
|
||||
await utils.attachFrame(page, 'frame1', './assets/frame.html');
|
||||
expect(attachedFrames.length).toBe(1);
|
||||
expect(attachedFrames[0].url()).toContain('/assets/frame.html');
|
||||
|
||||
// validate framenavigated events
|
||||
const navigatedFrames = [];
|
||||
page.on('framenavigated', frame => navigatedFrames.push(frame));
|
||||
await utils.navigateFrame(page, 'frame1', './empty.html');
|
||||
expect(navigatedFrames.length).toBe(1);
|
||||
expect(navigatedFrames[0].url()).toBe(server.EMPTY_PAGE);
|
||||
|
||||
// validate framedetached events
|
||||
const detachedFrames = [];
|
||||
page.on('framedetached', frame => detachedFrames.push(frame));
|
||||
await utils.detachFrame(page, 'frame1');
|
||||
expect(detachedFrames.length).toBe(1);
|
||||
expect(detachedFrames[0].isDetached()).toBe(true);
|
||||
});
|
||||
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}) => {
|
||||
let hasEvents = false;
|
||||
page.on('frameattached', frame => hasEvents = true);
|
||||
page.on('framedetached', frame => hasEvents = true);
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect(hasEvents).toBe(false);
|
||||
});
|
||||
it('should detach child frames on navigation', async({page, server}) => {
|
||||
let attachedFrames = [];
|
||||
let detachedFrames = [];
|
||||
let navigatedFrames = [];
|
||||
page.on('frameattached', frame => attachedFrames.push(frame));
|
||||
page.on('framedetached', frame => detachedFrames.push(frame));
|
||||
page.on('framenavigated', frame => navigatedFrames.push(frame));
|
||||
await page.goto(server.PREFIX + '/frames/nested-frames.html');
|
||||
expect(attachedFrames.length).toBe(4);
|
||||
expect(detachedFrames.length).toBe(0);
|
||||
expect(navigatedFrames.length).toBe(5);
|
||||
|
||||
attachedFrames = [];
|
||||
detachedFrames = [];
|
||||
navigatedFrames = [];
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect(attachedFrames.length).toBe(0);
|
||||
expect(detachedFrames.length).toBe(4);
|
||||
expect(navigatedFrames.length).toBe(1);
|
||||
});
|
||||
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');
|
||||
frame.name = 'theFrameName';
|
||||
frame.src = url;
|
||||
document.body.appendChild(frame);
|
||||
return new Promise(x => frame.onload = x);
|
||||
}, server.EMPTY_PAGE);
|
||||
expect(page.frames()[0].name()).toBe('');
|
||||
expect(page.frames()[1].name()).toBe('theFrameId');
|
||||
expect(page.frames()[2].name()).toBe('theFrameName');
|
||||
});
|
||||
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);
|
||||
expect(page.frames()[1].parentFrame()).toBe(page.mainFrame());
|
||||
expect(page.frames()[2].parentFrame()).toBe(page.mainFrame());
|
||||
});
|
||||
});
|
||||
|
||||
describe('Page.$eval', function() {
|
||||
it('should work', async({page, server}) => {
|
||||
await page.setContent('<section id="testAttribute">43543</section>');
|
||||
@ -1857,329 +1778,6 @@ module.exports.addTests = function({testRunner, expect, defaultBrowserOptions, p
|
||||
});
|
||||
});
|
||||
|
||||
describe('Cookies', function() {
|
||||
afterEach(async({page, server}) => {
|
||||
const cookies = await page.cookies(server.PREFIX + '/grid.html', server.CROSS_PROCESS_PREFIX);
|
||||
for (const cookie of cookies)
|
||||
await page.deleteCookie(cookie);
|
||||
});
|
||||
it('should set and get cookies', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
expect(await page.cookies()).toEqual([]);
|
||||
await page.evaluate(() => {
|
||||
document.cookie = 'username=John Doe';
|
||||
});
|
||||
expect(await page.cookies()).toEqual([{
|
||||
name: 'username',
|
||||
value: 'John Doe',
|
||||
domain: 'localhost',
|
||||
path: '/',
|
||||
expires: -1,
|
||||
size: 16,
|
||||
httpOnly: false,
|
||||
secure: false,
|
||||
session: true }
|
||||
]);
|
||||
await page.setCookie({
|
||||
name: 'password',
|
||||
value: '123456'
|
||||
});
|
||||
expect(await page.evaluate('document.cookie')).toBe('username=John Doe; password=123456');
|
||||
const cookies = await page.cookies();
|
||||
expect(cookies.sort((a, b) => a.name.localeCompare(b.name))).toEqual([{
|
||||
name: 'password',
|
||||
value: '123456',
|
||||
domain: 'localhost',
|
||||
path: '/',
|
||||
expires: -1,
|
||||
size: 14,
|
||||
httpOnly: false,
|
||||
secure: false,
|
||||
session: true
|
||||
}, {
|
||||
name: 'username',
|
||||
value: 'John Doe',
|
||||
domain: 'localhost',
|
||||
path: '/',
|
||||
expires: -1,
|
||||
size: 16,
|
||||
httpOnly: false,
|
||||
secure: false,
|
||||
session: true
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should set a cookie with a path', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
await page.setCookie({
|
||||
name: 'gridcookie',
|
||||
value: 'GRID',
|
||||
path: '/grid.html'
|
||||
});
|
||||
expect(await page.cookies()).toEqual([{
|
||||
name: 'gridcookie',
|
||||
value: 'GRID',
|
||||
domain: 'localhost',
|
||||
path: '/grid.html',
|
||||
expires: -1,
|
||||
size: 14,
|
||||
httpOnly: false,
|
||||
secure: false,
|
||||
session: true
|
||||
}]);
|
||||
expect(await page.evaluate('document.cookie')).toBe('gridcookie=GRID');
|
||||
await page.goto(server.PREFIX + '/empty.html');
|
||||
expect(await page.cookies()).toEqual([]);
|
||||
expect(await page.evaluate('document.cookie')).toBe('');
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
expect(await page.evaluate('document.cookie')).toBe('gridcookie=GRID');
|
||||
});
|
||||
|
||||
|
||||
it('should delete a cookie', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
await page.setCookie({
|
||||
name: 'cookie1',
|
||||
value: '1'
|
||||
}, {
|
||||
name: 'cookie2',
|
||||
value: '2'
|
||||
}, {
|
||||
name: 'cookie3',
|
||||
value: '3'
|
||||
});
|
||||
expect(await page.evaluate('document.cookie')).toBe('cookie1=1; cookie2=2; cookie3=3');
|
||||
await page.deleteCookie({name: 'cookie2'});
|
||||
expect(await page.evaluate('document.cookie')).toBe('cookie1=1; cookie3=3');
|
||||
});
|
||||
|
||||
it('should not set a cookie on a blank page', async function({page}) {
|
||||
let error = null;
|
||||
await page.goto('about:blank');
|
||||
try {
|
||||
await page.setCookie({name: 'example-cookie', value: 'best'});
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error).toBeTruthy();
|
||||
expect(error.message).toEqual('Protocol error (Network.deleteCookies): At least one of the url and domain needs to be specified undefined');
|
||||
});
|
||||
|
||||
it('should not set a cookie with blank page URL', async function({page, server}) {
|
||||
let error = null;
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
try {
|
||||
await page.setCookie(
|
||||
{name: 'example-cookie', value: 'best'},
|
||||
{url: 'about:blank', name: 'example-cookie-blank', value: 'best'}
|
||||
);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error).toBeTruthy();
|
||||
expect(error.message).toEqual(
|
||||
`Blank page can not have cookie "example-cookie-blank"`
|
||||
);
|
||||
});
|
||||
|
||||
it('should not set a cookie on a data URL page', async function({page}) {
|
||||
let error = null;
|
||||
await page.goto('data:,Hello%2C%20World!');
|
||||
try {
|
||||
await page.setCookie({name: 'example-cookie', value: 'best'});
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error).toBeTruthy();
|
||||
expect(error.message).toEqual(
|
||||
'Protocol error (Network.deleteCookies): At least one of the url and domain needs to be specified undefined'
|
||||
);
|
||||
});
|
||||
|
||||
it('should not set a cookie with blank page URL', async function({page, server}) {
|
||||
let error = null;
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
try {
|
||||
await page.setCookie({name: 'example-cookie', value: 'best'}, {url: 'about:blank', name: 'example-cookie-blank', value: 'best'});
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error).toBeTruthy();
|
||||
expect(error.message).toEqual(`Blank page can not have cookie "example-cookie-blank"`);
|
||||
});
|
||||
|
||||
it('should set a cookie on a different domain', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
await page.setCookie({name: 'example-cookie', value: 'best', url: 'https://www.example.com'});
|
||||
expect(await page.evaluate('document.cookie')).toBe('');
|
||||
expect(await page.cookies()).toEqual([]);
|
||||
expect(await page.cookies('https://www.example.com')).toEqual([{
|
||||
name: 'example-cookie',
|
||||
value: 'best',
|
||||
domain: 'www.example.com',
|
||||
path: '/',
|
||||
expires: -1,
|
||||
size: 18,
|
||||
httpOnly: false,
|
||||
secure: true,
|
||||
session: true
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should set cookies from a frame', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/grid.html');
|
||||
await page.setCookie({name: 'localhost-cookie', value: 'best'});
|
||||
await page.evaluate(src => {
|
||||
let fulfill;
|
||||
const promise = new Promise(x => fulfill = x);
|
||||
const iframe = document.createElement('iframe');
|
||||
document.body.appendChild(iframe);
|
||||
iframe.onload = fulfill;
|
||||
iframe.src = src;
|
||||
return promise;
|
||||
}, server.CROSS_PROCESS_PREFIX);
|
||||
await page.setCookie({name: '127-cookie', value: 'worst', url: server.CROSS_PROCESS_PREFIX});
|
||||
expect(await page.evaluate('document.cookie')).toBe('localhost-cookie=best');
|
||||
expect(await page.frames()[1].evaluate('document.cookie')).toBe('127-cookie=worst');
|
||||
|
||||
expect(await page.cookies()).toEqual([{
|
||||
name: 'localhost-cookie',
|
||||
value: 'best',
|
||||
domain: 'localhost',
|
||||
path: '/',
|
||||
expires: -1,
|
||||
size: 20,
|
||||
httpOnly: false,
|
||||
secure: false,
|
||||
session: true
|
||||
}]);
|
||||
|
||||
expect(await page.cookies(server.CROSS_PROCESS_PREFIX)).toEqual([{
|
||||
name: '127-cookie',
|
||||
value: 'worst',
|
||||
domain: '127.0.0.1',
|
||||
path: '/',
|
||||
expires: -1,
|
||||
size: 15,
|
||||
httpOnly: false,
|
||||
secure: false,
|
||||
session: true
|
||||
}]);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('Target', function() {
|
||||
it('Browser.targets should return all of the targets', async({page, server, browser}) => {
|
||||
// The pages will be the testing page and the original newtab page
|
||||
const targets = browser.targets();
|
||||
expect(targets.some(target => target.type() === 'page' &&
|
||||
target.url() === 'about:blank')).toBeTruthy('Missing blank page');
|
||||
expect(targets.some(target => target.type() === 'browser')).toBeTruthy('Missing browser target');
|
||||
});
|
||||
it('Browser.pages should return all of the pages', async({page, server, browser}) => {
|
||||
// The pages will be the testing page and the original newtab page
|
||||
const allPages = await browser.pages();
|
||||
expect(allPages.length).toBe(2);
|
||||
expect(allPages).toContain(page);
|
||||
expect(allPages[0]).not.toBe(allPages[1]);
|
||||
});
|
||||
it('should contain browser target', async({browser}) => {
|
||||
const targets = browser.targets();
|
||||
const browserTarget = targets.find(target => target.type() === 'browser');
|
||||
expect(browserTarget).toBeTruthy();
|
||||
});
|
||||
it('should be able to use the default page in the browser', async({page, server, browser}) => {
|
||||
// The pages will be the testing page and the original newtab page
|
||||
const allPages = await browser.pages();
|
||||
const originalPage = allPages.find(p => p !== page);
|
||||
expect(await originalPage.evaluate(() => ['Hello', 'world'].join(' '))).toBe('Hello world');
|
||||
expect(await originalPage.$('body')).toBeTruthy();
|
||||
});
|
||||
it('should report when a new page is created and closed', async({page, server, browser}) => {
|
||||
const otherPagePromise = new Promise(fulfill => browser.once('targetcreated', target => fulfill(target.page())));
|
||||
await page.evaluate(url => window.open(url), server.CROSS_PROCESS_PREFIX);
|
||||
const otherPage = await otherPagePromise;
|
||||
expect(otherPage.url()).toContain(server.CROSS_PROCESS_PREFIX);
|
||||
|
||||
expect(await otherPage.evaluate(() => ['Hello', 'world'].join(' '))).toBe('Hello world');
|
||||
expect(await otherPage.$('body')).toBeTruthy();
|
||||
|
||||
let allPages = await browser.pages();
|
||||
expect(allPages).toContain(page);
|
||||
expect(allPages).toContain(otherPage);
|
||||
|
||||
const closePagePromise = new Promise(fulfill => browser.once('targetdestroyed', target => fulfill(target.page())));
|
||||
await otherPage.close();
|
||||
expect(await closePagePromise).toBe(otherPage);
|
||||
|
||||
allPages = await Promise.all(browser.targets().map(target => target.page()));
|
||||
expect(allPages).toContain(page);
|
||||
expect(allPages).not.toContain(otherPage);
|
||||
});
|
||||
it('should report when a service worker is created and destroyed', async({page, server, browser}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const createdTarget = new Promise(fulfill => browser.once('targetcreated', target => fulfill(target)));
|
||||
|
||||
await page.goto(server.PREFIX + '/serviceworkers/empty/sw.html');
|
||||
|
||||
expect((await createdTarget).type()).toBe('service_worker');
|
||||
expect((await createdTarget).url()).toBe(server.PREFIX + '/serviceworkers/empty/sw.js');
|
||||
|
||||
const destroyedTarget = new Promise(fulfill => browser.once('targetdestroyed', target => fulfill(target)));
|
||||
await page.evaluate(() => window.registrationPromise.then(registration => registration.unregister()));
|
||||
expect(await destroyedTarget).toBe(await createdTarget);
|
||||
});
|
||||
it('should report when a target url changes', async({page, server, browser}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
let changedTarget = new Promise(fulfill => browser.once('targetchanged', target => fulfill(target)));
|
||||
await page.goto(server.CROSS_PROCESS_PREFIX + '/');
|
||||
expect((await changedTarget).url()).toBe(server.CROSS_PROCESS_PREFIX + '/');
|
||||
|
||||
changedTarget = new Promise(fulfill => browser.once('targetchanged', target => fulfill(target)));
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect((await changedTarget).url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
it('should not report uninitialized pages', async({page, server, browser}) => {
|
||||
let targetChanged = false;
|
||||
const listener = () => targetChanged = true;
|
||||
browser.on('targetchanged', listener);
|
||||
const targetPromise = new Promise(fulfill => browser.once('targetcreated', target => fulfill(target)));
|
||||
const newPagePromise = browser.newPage();
|
||||
const target = await targetPromise;
|
||||
expect(target.url()).toBe('about:blank');
|
||||
|
||||
const newPage = await newPagePromise;
|
||||
const targetPromise2 = new Promise(fulfill => browser.once('targetcreated', target => fulfill(target)));
|
||||
const evaluatePromise = newPage.evaluate(() => window.open('about:blank'));
|
||||
const target2 = await targetPromise2;
|
||||
expect(target2.url()).toBe('about:blank');
|
||||
await evaluatePromise;
|
||||
await newPage.close();
|
||||
expect(targetChanged).toBe(false, 'target should not be reported as changed');
|
||||
browser.removeListener('targetchanged', listener);
|
||||
});
|
||||
it('should not crash while redirecting if original request was missed', async({page, server, browser}) => {
|
||||
let serverResponse = null;
|
||||
server.setRoute('/one-style.css', (req, res) => serverResponse = res);
|
||||
// Open a new page. Use window.open to connect to the page later.
|
||||
await Promise.all([
|
||||
page.evaluate(url => window.open(url), server.PREFIX + '/one-style.html'),
|
||||
server.waitForRequest('/one-style.css')
|
||||
]);
|
||||
// Connect to the opened page.
|
||||
const target = browser.targets().find(target => target.url().includes('one-style.html'));
|
||||
const newPage = await target.page();
|
||||
// Issue a redirect.
|
||||
serverResponse.writeHead(302, { location: '/injectedstyle.css' });
|
||||
serverResponse.end();
|
||||
// Wait for the new page to load.
|
||||
await waitForEvents(newPage, 'load');
|
||||
// Cleanup.
|
||||
await newPage.close();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Connection', function() {
|
||||
it('should throw nice errors', async function({page}) {
|
||||
const error = await theSourceOfTheProblems().catch(error => error);
|
||||
@ -2191,212 +1789,6 @@ module.exports.addTests = function({testRunner, expect, defaultBrowserOptions, p
|
||||
});
|
||||
});
|
||||
|
||||
describe('Target.createCDPSession', function() {
|
||||
it('should work', async function({page, server}) {
|
||||
const client = await page.target().createCDPSession();
|
||||
|
||||
await Promise.all([
|
||||
client.send('Runtime.enable'),
|
||||
client.send('Runtime.evaluate', { expression: 'window.foo = "bar"' })
|
||||
]);
|
||||
const foo = await page.evaluate(() => window.foo);
|
||||
expect(foo).toBe('bar');
|
||||
});
|
||||
it('should send events', async function({page, server}) {
|
||||
const client = await page.target().createCDPSession();
|
||||
await client.send('Network.enable');
|
||||
const events = [];
|
||||
client.on('Network.requestWillBeSent', event => events.push(event));
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect(events.length).toBe(1);
|
||||
});
|
||||
it('should enable and disable domains independently', async function({page, server}) {
|
||||
const client = await page.target().createCDPSession();
|
||||
await client.send('Runtime.enable');
|
||||
await client.send('Debugger.enable');
|
||||
// JS coverage enables and then disables Debugger domain.
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.coverage.stopJSCoverage();
|
||||
// generate a script in page and wait for the event.
|
||||
const [event] = await Promise.all([
|
||||
waitForEvents(client, 'Debugger.scriptParsed'),
|
||||
page.evaluate('//# sourceURL=foo.js')
|
||||
]);
|
||||
// expect events to be dispatched.
|
||||
expect(event.url).toBe('foo.js');
|
||||
});
|
||||
it('should be able to detach session', async function({page, server}) {
|
||||
const client = await page.target().createCDPSession();
|
||||
await client.send('Runtime.enable');
|
||||
const evalResponse = await client.send('Runtime.evaluate', {expression: '1 + 2', returnByValue: true});
|
||||
expect(evalResponse.result.value).toBe(3);
|
||||
await client.detach();
|
||||
let error = null;
|
||||
try {
|
||||
await client.send('Runtime.evaluate', {expression: '3 + 1', returnByValue: true});
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error.message).toContain('Session closed.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('JSCoverage', function() {
|
||||
it('should work', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.PREFIX + '/jscoverage/simple.html');
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
expect(coverage[0].url).toContain('/jscoverage/simple.html');
|
||||
expect(coverage[0].ranges).toEqual([
|
||||
{ start: 0, end: 17 },
|
||||
{ start: 35, end: 61 },
|
||||
]);
|
||||
});
|
||||
it('should report sourceURLs', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.PREFIX + '/jscoverage/sourceurl.html');
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
expect(coverage[0].url).toBe('nicename.js');
|
||||
});
|
||||
it('should ignore anonymous scripts', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.evaluate(() => console.log(1));
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.length).toBe(0);
|
||||
});
|
||||
it('should report multiple scripts', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.PREFIX + '/jscoverage/multiple.html');
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.length).toBe(2);
|
||||
coverage.sort((a, b) => a.url.localeCompare(b.url));
|
||||
expect(coverage[0].url).toContain('/jscoverage/script1.js');
|
||||
expect(coverage[1].url).toContain('/jscoverage/script2.js');
|
||||
});
|
||||
it('should report right ranges', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.PREFIX + '/jscoverage/ranges.html');
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
const entry = coverage[0];
|
||||
expect(entry.ranges.length).toBe(1);
|
||||
const range = entry.ranges[0];
|
||||
expect(entry.text.substring(range.start, range.end)).toBe(`console.log('used!');`);
|
||||
});
|
||||
it('should report scripts that have no coverage', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.PREFIX + '/jscoverage/unused.html');
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
const entry = coverage[0];
|
||||
expect(entry.url).toContain('unused.html');
|
||||
expect(entry.ranges.length).toBe(0);
|
||||
});
|
||||
it('should work with conditionals', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage();
|
||||
await page.goto(server.PREFIX + '/jscoverage/involved.html');
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(JSON.stringify(coverage, null, 2).replace(/:\d{4}\//g, ':<PORT>/')).toBeGolden('jscoverage-involved.txt');
|
||||
});
|
||||
describe('resetOnNavigation', function() {
|
||||
it('should report scripts across navigations when disabled', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage({resetOnNavigation: false});
|
||||
await page.goto(server.PREFIX + '/jscoverage/multiple.html');
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.length).toBe(2);
|
||||
});
|
||||
it('should NOT report scripts across navigations when enabled', async function({page, server}) {
|
||||
await page.coverage.startJSCoverage(); // Enabled by default.
|
||||
await page.goto(server.PREFIX + '/jscoverage/multiple.html');
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const coverage = await page.coverage.stopJSCoverage();
|
||||
expect(coverage.length).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('CSSCoverage', function() {
|
||||
it('should work', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.goto(server.PREFIX + '/csscoverage/simple.html');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
expect(coverage[0].url).toContain('/csscoverage/simple.html');
|
||||
expect(coverage[0].ranges).toEqual([
|
||||
{start: 1, end: 22}
|
||||
]);
|
||||
const range = coverage[0].ranges[0];
|
||||
expect(coverage[0].text.substring(range.start, range.end)).toBe('div { color: green; }');
|
||||
});
|
||||
it('should report sourceURLs', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.goto(server.PREFIX + '/csscoverage/sourceurl.html');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
expect(coverage[0].url).toBe('nicename.css');
|
||||
});
|
||||
it('should report multiple stylesheets', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.goto(server.PREFIX + '/csscoverage/multiple.html');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(2);
|
||||
coverage.sort((a, b) => a.url.localeCompare(b.url));
|
||||
expect(coverage[0].url).toContain('/csscoverage/stylesheet1.css');
|
||||
expect(coverage[1].url).toContain('/csscoverage/stylesheet2.css');
|
||||
});
|
||||
it('should report stylesheets that have no coverage', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.goto(server.PREFIX + '/csscoverage/unused.html');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
expect(coverage[0].url).toBe('unused.css');
|
||||
expect(coverage[0].ranges.length).toBe(0);
|
||||
});
|
||||
it('should work with media queries', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.goto(server.PREFIX + '/csscoverage/media.html');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(1);
|
||||
expect(coverage[0].url).toContain('/csscoverage/media.html');
|
||||
expect(coverage[0].ranges).toEqual([
|
||||
{start: 17, end: 38}
|
||||
]);
|
||||
});
|
||||
it('should work with complicated usecases', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.goto(server.PREFIX + '/csscoverage/involved.html');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(JSON.stringify(coverage, null, 2).replace(/:\d{4}\//g, ':<PORT>/')).toBeGolden('csscoverage-involved.txt');
|
||||
});
|
||||
it('should ignore injected stylesheets', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage();
|
||||
await page.addStyleTag({content: 'body { margin: 10px;}'});
|
||||
// trigger style recalc
|
||||
const margin = await page.evaluate(() => window.getComputedStyle(document.body).margin);
|
||||
expect(margin).toBe('10px');
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(0);
|
||||
});
|
||||
describe('resetOnNavigation', function() {
|
||||
it('should report stylesheets across navigations', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage({resetOnNavigation: false});
|
||||
await page.goto(server.PREFIX + '/csscoverage/multiple.html');
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(2);
|
||||
});
|
||||
it('should NOT report scripts across navigations', async function({page, server}) {
|
||||
await page.coverage.startCSSCoverage(); // Enabled by default.
|
||||
await page.goto(server.PREFIX + '/csscoverage/multiple.html');
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const coverage = await page.coverage.stopCSSCoverage();
|
||||
expect(coverage.length).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('Page.Events.Close', function() {
|
||||
it('should work with window.close', async function({ page, browser, server }) {
|
||||
const newPagePromise = new Promise(fulfill => browser.once('targetcreated', target => fulfill(target.page())));
|
||||
|
134
test/target.spec.js
Normal file
134
test/target.spec.js
Normal file
@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Copyright 2018 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const {waitForEvents} = require('./utils');
|
||||
|
||||
module.exports.addTests = function({testRunner, expect}) {
|
||||
const {describe, xdescribe, fdescribe} = testRunner;
|
||||
const {it, fit, xit} = testRunner;
|
||||
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
|
||||
|
||||
describe('Target', function() {
|
||||
it('Browser.targets should return all of the targets', async({page, server, browser}) => {
|
||||
// The pages will be the testing page and the original newtab page
|
||||
const targets = browser.targets();
|
||||
expect(targets.some(target => target.type() === 'page' &&
|
||||
target.url() === 'about:blank')).toBeTruthy('Missing blank page');
|
||||
expect(targets.some(target => target.type() === 'browser')).toBeTruthy('Missing browser target');
|
||||
});
|
||||
it('Browser.pages should return all of the pages', async({page, server, browser}) => {
|
||||
// The pages will be the testing page and the original newtab page
|
||||
const allPages = await browser.pages();
|
||||
expect(allPages.length).toBe(2);
|
||||
expect(allPages).toContain(page);
|
||||
expect(allPages[0]).not.toBe(allPages[1]);
|
||||
});
|
||||
it('should contain browser target', async({browser}) => {
|
||||
const targets = browser.targets();
|
||||
const browserTarget = targets.find(target => target.type() === 'browser');
|
||||
expect(browserTarget).toBeTruthy();
|
||||
});
|
||||
it('should be able to use the default page in the browser', async({page, server, browser}) => {
|
||||
// The pages will be the testing page and the original newtab page
|
||||
const allPages = await browser.pages();
|
||||
const originalPage = allPages.find(p => p !== page);
|
||||
expect(await originalPage.evaluate(() => ['Hello', 'world'].join(' '))).toBe('Hello world');
|
||||
expect(await originalPage.$('body')).toBeTruthy();
|
||||
});
|
||||
it('should report when a new page is created and closed', async({page, server, browser}) => {
|
||||
const otherPagePromise = new Promise(fulfill => browser.once('targetcreated', target => fulfill(target.page())));
|
||||
await page.evaluate(url => window.open(url), server.CROSS_PROCESS_PREFIX);
|
||||
const otherPage = await otherPagePromise;
|
||||
expect(otherPage.url()).toContain(server.CROSS_PROCESS_PREFIX);
|
||||
|
||||
expect(await otherPage.evaluate(() => ['Hello', 'world'].join(' '))).toBe('Hello world');
|
||||
expect(await otherPage.$('body')).toBeTruthy();
|
||||
|
||||
let allPages = await browser.pages();
|
||||
expect(allPages).toContain(page);
|
||||
expect(allPages).toContain(otherPage);
|
||||
|
||||
const closePagePromise = new Promise(fulfill => browser.once('targetdestroyed', target => fulfill(target.page())));
|
||||
await otherPage.close();
|
||||
expect(await closePagePromise).toBe(otherPage);
|
||||
|
||||
allPages = await Promise.all(browser.targets().map(target => target.page()));
|
||||
expect(allPages).toContain(page);
|
||||
expect(allPages).not.toContain(otherPage);
|
||||
});
|
||||
it('should report when a service worker is created and destroyed', async({page, server, browser}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const createdTarget = new Promise(fulfill => browser.once('targetcreated', target => fulfill(target)));
|
||||
|
||||
await page.goto(server.PREFIX + '/serviceworkers/empty/sw.html');
|
||||
|
||||
expect((await createdTarget).type()).toBe('service_worker');
|
||||
expect((await createdTarget).url()).toBe(server.PREFIX + '/serviceworkers/empty/sw.js');
|
||||
|
||||
const destroyedTarget = new Promise(fulfill => browser.once('targetdestroyed', target => fulfill(target)));
|
||||
await page.evaluate(() => window.registrationPromise.then(registration => registration.unregister()));
|
||||
expect(await destroyedTarget).toBe(await createdTarget);
|
||||
});
|
||||
it('should report when a target url changes', async({page, server, browser}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
let changedTarget = new Promise(fulfill => browser.once('targetchanged', target => fulfill(target)));
|
||||
await page.goto(server.CROSS_PROCESS_PREFIX + '/');
|
||||
expect((await changedTarget).url()).toBe(server.CROSS_PROCESS_PREFIX + '/');
|
||||
|
||||
changedTarget = new Promise(fulfill => browser.once('targetchanged', target => fulfill(target)));
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
expect((await changedTarget).url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
it('should not report uninitialized pages', async({page, server, browser}) => {
|
||||
let targetChanged = false;
|
||||
const listener = () => targetChanged = true;
|
||||
browser.on('targetchanged', listener);
|
||||
const targetPromise = new Promise(fulfill => browser.once('targetcreated', target => fulfill(target)));
|
||||
const newPagePromise = browser.newPage();
|
||||
const target = await targetPromise;
|
||||
expect(target.url()).toBe('about:blank');
|
||||
|
||||
const newPage = await newPagePromise;
|
||||
const targetPromise2 = new Promise(fulfill => browser.once('targetcreated', target => fulfill(target)));
|
||||
const evaluatePromise = newPage.evaluate(() => window.open('about:blank'));
|
||||
const target2 = await targetPromise2;
|
||||
expect(target2.url()).toBe('about:blank');
|
||||
await evaluatePromise;
|
||||
await newPage.close();
|
||||
expect(targetChanged).toBe(false, 'target should not be reported as changed');
|
||||
browser.removeListener('targetchanged', listener);
|
||||
});
|
||||
it('should not crash while redirecting if original request was missed', async({page, server, browser}) => {
|
||||
let serverResponse = null;
|
||||
server.setRoute('/one-style.css', (req, res) => serverResponse = res);
|
||||
// Open a new page. Use window.open to connect to the page later.
|
||||
await Promise.all([
|
||||
page.evaluate(url => window.open(url), server.PREFIX + '/one-style.html'),
|
||||
server.waitForRequest('/one-style.css')
|
||||
]);
|
||||
// Connect to the opened page.
|
||||
const target = browser.targets().find(target => target.url().includes('one-style.html'));
|
||||
const newPage = await target.page();
|
||||
// Issue a redirect.
|
||||
serverResponse.writeHead(302, { location: '/injectedstyle.css' });
|
||||
serverResponse.end();
|
||||
// Wait for the new page to load.
|
||||
await waitForEvents(newPage, 'load');
|
||||
// Cleanup.
|
||||
await newPage.close();
|
||||
});
|
||||
});
|
||||
};
|
Loading…
Reference in New Issue
Block a user