test: move all generic page tests to jest (#3002)

This commit is contained in:
Pavel Feldman 2020-07-17 09:49:12 -07:00 committed by GitHub
parent 5cf3e4f0f2
commit 070a257600
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 146 additions and 141 deletions

View file

@ -147,8 +147,8 @@ const contextDestroyedResult = {
function potentiallyUnserializableValue(remoteObject: Protocol.Runtime.RemoteObject): any {
const value = remoteObject.value;
const unserializableValue = remoteObject.type === 'number' && value === null ? remoteObject.description : undefined;
return unserializableValue ? js.parseUnserializableValue(unserializableValue) : value;
const isUnserializable = remoteObject.type === 'number' && ['NaN', '-Infinity', 'Infinity', '-0'].includes(remoteObject.description!);
return isUnserializable ? js.parseUnserializableValue(remoteObject.description!) : value;
}
function rewriteError(error: Error): Error {

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
const {FFOX, CHROMIUM, WEBKIT, WIN, LINUX} = require('./utils').testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT, WIN, LINUX} = testOptions;
describe('Capabilities', function() {
it.fail(WEBKIT && WIN)('Web Assembly should work', async function({page, server}) {

View file

@ -584,8 +584,8 @@ describe('focus', function() {
page.screenshot(),
page2.screenshot(),
]);
expect(screenshots[0]).toMatchImageSnapshot('screenshot-sanity');
expect(screenshots[1]).toMatchImageSnapshot('grid-cell-0');
expect(screenshots[0]).toBeGolden('screenshot-sanity.png');
expect(screenshots[1]).toBeGolden('grid-cell-0.png');
});
it('should change focused iframe', async({page, server}) => {
await page.goto(server.EMPTY_PAGE);

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
const {FFOX, CHROMIUM, WEBKIT} = require('./utils').testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT} = testOptions;
describe('Overrides.setGeolocation', function() {
it('should work', async({page, server, context}) => {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

View file

@ -20,7 +20,6 @@ const fs = require('fs');
const formidable = require('formidable');
const FILE_TO_UPLOAD = path.join(__dirname, '/assets/file-to-upload.txt');
const {FFOX, CHROMIUM, WEBKIT} = require('./utils').testOptions(browserType);
describe('input', function() {
it('should upload the file', async({page, server}) => {
@ -85,18 +84,18 @@ describe('Page.waitForFileChooser', function() {
]);
expect(chooser).toBeTruthy();
});
it('should respect timeout', async({page, server}) => {
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, server}) => {
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, server}) => {
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);

View file

@ -19,7 +19,7 @@ const fs = require('fs');
const path = require('path');
const { helper } = require('../lib/helper');
const vm = require('vm');
const {FFOX, CHROMIUM, WEBKIT} = require('./utils').testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT, HEADLESS} = testOptions;
describe('Page.route', function() {
it('should intercept', async({page, server}) => {
@ -565,7 +565,7 @@ describe('Request.fulfill', function() {
expect(response.statusText()).toBe('Unprocessable Entity');
expect(await page.evaluate(() => document.body.textContent)).toBe('Yo, page!');
});
it.skip(FFOX && !HEADLESS)('should allow mocking binary responses', async({page, server, golden}) => {
it.skip(FFOX && !HEADLESS)('should allow mocking binary responses', async({page, server}) => {
// Firefox headful produces a different image.
await page.route('**/*', route => {
const imageBuffer = fs.readFileSync(path.join(__dirname, 'assets', 'pptr.png'));
@ -581,9 +581,9 @@ describe('Request.fulfill', function() {
return new Promise(fulfill => img.onload = fulfill);
}, server.PREFIX);
const img = await page.$('img');
expect(await img.screenshot()).toBeGolden(golden('mock-binary-response.png'));
expect(await img.screenshot()).toBeGolden('mock-binary-response.png');
});
it.skip(FFOX && !HEADLESS)('should allow mocking svg with charset', async({page, server, golden}) => {
it.skip(FFOX && !HEADLESS)('should allow mocking svg with charset', async({page, server}) => {
// Firefox headful produces a different image.
await page.route('**/*', route => {
route.fulfill({
@ -598,9 +598,9 @@ describe('Request.fulfill', function() {
return new Promise((f, r) => { img.onload = f; img.onerror = r; });
}, server.PREFIX);
const img = await page.$('img');
expect(await img.screenshot()).toBeGolden(golden('mock-svg.png'));
expect(await img.screenshot()).toBeGolden('mock-svg.png');
});
it('should work with file path', async({page, server, golden}) => {
it('should work with file path', async({page, server}) => {
await page.route('**/*', route => route.fulfill({ contentType: 'shouldBeIgnored', path: path.join(__dirname, 'assets', 'pptr.png') }));
await page.evaluate(PREFIX => {
const img = document.createElement('img');
@ -609,7 +609,7 @@ describe('Request.fulfill', function() {
return new Promise(fulfill => img.onload = fulfill);
}, server.PREFIX);
const img = await page.$('img');
expect(await img.screenshot()).toBeGolden(golden('mock-binary-response.png'));
expect(await img.screenshot()).toBeGolden('mock-binary-response.png');
});
it('should stringify intercepted request response headers', async({page, server}) => {
await page.route('**/*', route => {
@ -746,7 +746,7 @@ describe('service worker', function() {
});
describe('glob', function() {
it('should work with glob', async({newPage, httpsServer}) => {
it('should work with glob', async() => {
expect(helper.globToRegex('**/*.js').test('https://localhost:8080/foo.js')).toBeTruthy();
expect(helper.globToRegex('**/*.css').test('https://localhost:8080/foo.js')).toBeFalsy();
expect(helper.globToRegex('*.js').test('https://localhost:8080/foo.js')).toBeFalsy();

View file

@ -63,6 +63,7 @@ module.exports = function registerFixtures(global) {
});
global.registerWorkerFixture('playwright', async({}, test) => {
Error.stackTraceLimit = 15;
if (process.env.PWCHANNEL) {
setUseApiName(false);
const connection = new Connection();
@ -122,14 +123,24 @@ module.exports = function registerFixtures(global) {
global.registerWorkerFixture('browser', async ({browserType, defaultBrowserOptions}, test) => {
const browser = await browserType.launch(defaultBrowserOptions);
await test(browser);
await browser.close();
try {
await test(browser);
if (browser.contexts().length !== 0) {
console.warn(`\nWARNING: test did not close all created contexts! ${new Error().stack}\n`);
await Promise.all(browser.contexts().map(context => context.close()));
}
} finally {
await browser.close();
}
});
global.registerFixture('context', async ({browser}, test) => {
const context = await browser.newContext();
await test(context);
await context.close();
try {
await test(context);
} finally {
await context.close();
}
});
global.registerFixture('page', async ({context}, test) => {

View file

@ -16,10 +16,10 @@
const NodeEnvironment = require('jest-environment-node');
const registerFixtures = require('./fixtures');
const { toMatchImageSnapshot: jestImageSnapshot } = require('jest-image-snapshot');
const os = require('os');
const path = require('path');
const platform = os.platform();
const GoldenUtils = require('../../utils/testrunner/GoldenUtils');
const browserName = process.env.BROWSER || 'chromium';
@ -37,6 +37,9 @@ class PlaywrightEnvironment extends NodeEnvironment {
testOptions.USES_HOOKS = process.env.PWCHANNEL === 'wire';
testOptions.CHANNEL = !!process.env.PWCHANNEL;
testOptions.HEADLESS = !!valueFromEnv('HEADLESS', true);
testOptions.ASSETS_DIR = path.join(__dirname, '..', 'assets');
testOptions.GOLDEN_DIR = path.join(__dirname, '..', 'golden-' + browserName);
testOptions.OUTPUT_DIR = path.join(__dirname, '..', 'output-' + browserName);
this.global.testOptions = testOptions;
this.global.registerFixture = (name, fn) => {
@ -86,14 +89,15 @@ class PlaywrightEnvironment extends NodeEnvironment {
this.global.it.fail = this.global.it.skip;
this.global.it.slow = () => this.global.it;
function toMatchImageSnapshot(received, fileName) {
return jestImageSnapshot.call(this, received, {
customDiffConfig: { threshold: 0.2 },
customSnapshotsDir: path.join(__dirname, '..', `golden-${browserName}`),
customSnapshotIdentifier: fileName
const testOptions = this.global.testOptions;
function toBeGolden(received, goldenName) {
return GoldenUtils.compare(received, {
goldenPath: testOptions.GOLDEN_DIR,
outputPath: testOptions.OUTPUT_DIR,
goldenName
});
};
this.global.expect.extend({ toMatchImageSnapshot });
this.global.expect.extend({ toBeGolden });
}
if (event.name === 'test_start') {
const fn = event.test.fn;
@ -196,7 +200,7 @@ class FixturePool {
const params = {};
for (const n of names)
params[n] = this.instances.get(n).value;
await fn(params);
return fn(params);
}
}

View file

@ -14,5 +14,15 @@
* limitations under the License.
*/
const fs = require('fs');
const path = require('path');
const rm = require('rimraf').sync;
const browserName = process.env.BROWSER || 'chromium';
module.exports = async function setup() {
const OUTPUT_DIR = path.join(__dirname, '..', 'output-' + browserName);
if (fs.existsSync(OUTPUT_DIR))
rm(OUTPUT_DIR);
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
};

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
const {FFOX, CHROMIUM, WEBKIT} = require('./utils').testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT} = testOptions;
describe('Page.evaluateHandle', function() {
it('should work', async({page, server}) => {
@ -164,8 +164,8 @@ describe('JSHandle.jsonValue', function() {
});
it('should work with dates', async({page, server}) => {
const dateHandle = await page.evaluateHandle(() => new Date('2017-09-26T00:00:00.000Z'));
const json = await dateHandle.jsonValue();
expect(json instanceof Date).toBeTruthy();
const date = await dateHandle.jsonValue();
expect(date.toJSON()).toBe('2017-09-26T00:00:00.000Z');
});
it('should throw for circular objects', async({page, server}) => {
const windowHandle = await page.evaluateHandle('window');
@ -231,7 +231,7 @@ describe('JSHandle.asElement', function() {
});
it('should work with nullified Node', async({page, server}) => {
await page.setContent('<section>test</section>');
await page.evaluate(() => delete Node);
await page.evaluate('delete Node');
const handle = await page.evaluateHandle(() => document.querySelector('section'));
const element = handle.asElement();
expect(element).not.toBe(null);

View file

@ -14,10 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import utils from './utils';
import type { Page } from '..';
const {FFOX, WEBKIT, CHROMIUM, MAC} = utils.testOptions(browserType);
const utils = require('./utils');
const {FFOX, WEBKIT, CHROMIUM, MAC} = testOptions;
describe('Keyboard', function() {
it('should type into a textarea', async ({page, server}) => {
await page.evaluate(() => {
@ -69,7 +70,7 @@ describe('Keyboard', function() {
await page.focus('textarea');
page.on('console', m => console.log(m.text()));
const events = await page.evaluateHandle(() => {
const events: string[] = [];
const events = [];
document.addEventListener('keydown', e => events.push(e.type));
document.addEventListener('keyup', e => events.push(e.type));
document.addEventListener('keypress', e => events.push(e.type));
@ -375,7 +376,7 @@ describe('Keyboard', function() {
});
});
async function captureLastKeydown(page: Page) {
async function captureLastKeydown(page) {
const lastEvent = await page.evaluateHandle(() => {
const lastEvent = {
repeat: false,
@ -392,7 +393,7 @@ async function captureLastKeydown(page: Page) {
lastEvent.code = e.code;
lastEvent.metaKey = e.metaKey;
// keyIdentifier only exists in WebKit, and isn't in TypeScript's lib.
lastEvent.keyIdentifier = 'keyIdentifier' in e && (e as any).keyIdentifier;
lastEvent.keyIdentifier = 'keyIdentifier' in e && e.keyIdentifier;
}, true);
return lastEvent;
});

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
const {FFOX, CHROMIUM, WEBKIT, MAC, WIN} = require('./utils').testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT, MAC, WIN} = testOptions;
function dimensions() {
const rect = document.querySelector('textarea').getBoundingClientRect();

View file

@ -18,7 +18,7 @@
const utils = require('./utils');
const path = require('path');
const url = require('url');
const {FFOX, CHROMIUM, WEBKIT, ASSETS_DIR, MAC, WIN, CHANNEL} = utils.testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT, ASSETS_DIR, MAC, WIN} = testOptions;
describe('Page.goto', function() {
it('should work', async({page, server}) => {
@ -193,7 +193,7 @@ describe('Page.goto', function() {
else
expect(error.message).toContain('NS_ERROR_CONNECTION_REFUSED');
});
it('should fail when exceeding maximum navigation timeout', async({page, server}) => {
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;
@ -202,7 +202,7 @@ describe('Page.goto', function() {
expect(error.message).toContain(server.PREFIX + '/empty.html');
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
});
it('should fail when exceeding default maximum navigation timeout', async({page, server}) => {
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;
@ -213,7 +213,7 @@ describe('Page.goto', function() {
expect(error.message).toContain(server.PREFIX + '/empty.html');
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
});
it('should fail when exceeding browser context navigation timeout', async({page, server}) => {
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;
@ -223,7 +223,7 @@ describe('Page.goto', function() {
expect(error.message).toContain(server.PREFIX + '/empty.html');
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
});
it('should fail when exceeding default maximum timeout', async({page, server}) => {
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;
@ -234,7 +234,7 @@ describe('Page.goto', function() {
expect(error.message).toContain(server.PREFIX + '/empty.html');
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
});
it('should fail when exceeding browser context timeout', async({page, server}) => {
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;
@ -244,7 +244,7 @@ describe('Page.goto', function() {
expect(error.message).toContain(server.PREFIX + '/empty.html');
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
});
it('should prioritize default navigation timeout over default timeout', async({page, server}) => {
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;

View file

@ -16,7 +16,7 @@
const fs = require('fs');
const path = require('path');
const {FFOX, CHROMIUM, WEBKIT, OUTPUT_DIR} = require('./utils').testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT, OUTPUT_DIR, HEADLESS} = testOptions;
// Printing to pdf is currently only supported in headless chromium.
describe.skip(!(HEADLESS && CHROMIUM))('Page.pdf', function() {

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
const {FFOX, CHROMIUM, WEBKIT, LINUX} = require('./utils').testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT, LINUX, HEADLESS} = testOptions;
// Permissions API is not implemented in WebKit (see https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API)
describe.skip(WEBKIT)('Permissions', function() {
@ -85,7 +85,7 @@ describe.skip(WEBKIT)('Permissions', function() {
//TODO: flaky
// - Linux: https://github.com/microsoft/playwright/pull/1790/checks?check_run_id=587327883
// - Win: https://ci.appveyor.com/project/aslushnikov/playwright/builds/32402536
it.fail(FFOX).fail(CHROMIUM && !HEADLESS)('should trigger permission onchange', async({page, server, context}) => {
it.fail(FFOX || (CHROMIUM && !HEADLESS))('should trigger permission onchange', async({page, server, context}) => {
await page.goto(server.EMPTY_PAGE);
await page.evaluate(() => {
window['events'] = [];
@ -122,7 +122,7 @@ describe.skip(WEBKIT)('Permissions', function() {
expect(await getPermission(otherPage, 'geolocation')).toBe('granted');
await otherContext.close();
});
it.skip(FFOX).fail(CHROMIUM && !HEADLESS)('should support clipboard read', async({page, server, context, browser}) => {
it.fail(FFOX || (CHROMIUM && !HEADLESS))('should support clipboard read', async({page, server, context, browser}) => {
// No such permissions (requires flag) in Firefox
await page.goto(server.EMPTY_PAGE);
expect(await getPermission(page, 'clipboard-read')).toBe('prompt');

View file

@ -17,7 +17,7 @@
const path = require('path');
const utils = require('./utils');
const {FFOX, CHROMIUM, WEBKIT, CHANNEL, USES_HOOKS} = utils.testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT, CHANNEL, USES_HOOKS} = testOptions;
describe('Page.$eval', function() {
it('should work with css selector', async({page, server}) => {

View file

@ -16,20 +16,20 @@
*/
const utils = require('./utils');
const {FFOX, CHROMIUM, WEBKIT, USES_HOOKS} = utils.testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT, USES_HOOKS, HEADLESS} = testOptions;
const {PNG} = require('pngjs');
// Firefox headful produces a different image.
const ffheadful = FFOX && !HEADLESS;
describe.skip(ffheadful)('Page.screenshot', function() {
it('should work', async({page, server, golden}) => {
it('should work', async({page, server}) => {
await page.setViewportSize({width: 500, height: 500});
await page.goto(server.PREFIX + '/grid.html');
const screenshot = await page.screenshot();
expect(screenshot).toBeGolden(golden('screenshot-sanity.png'));
expect(screenshot).toBeGolden('screenshot-sanity.png');
});
it('should clip rect', async({page, server, golden}) => {
it('should clip rect', async({page, server}) => {
await page.setViewportSize({width: 500, height: 500});
await page.goto(server.PREFIX + '/grid.html');
const screenshot = await page.screenshot({
@ -40,9 +40,9 @@ describe.skip(ffheadful)('Page.screenshot', function() {
height: 100
}
});
expect(screenshot).toBeGolden(golden('screenshot-clip-rect.png'));
expect(screenshot).toBeGolden('screenshot-clip-rect.png');
});
it('should clip rect with fullPage', async({page, server, golden}) => {
it('should clip rect with fullPage', async({page, server}) => {
await page.setViewportSize({width: 500, height: 500});
await page.goto(server.PREFIX + '/grid.html');
await page.evaluate(() => window.scrollBy(150, 200));
@ -55,9 +55,9 @@ describe.skip(ffheadful)('Page.screenshot', function() {
height: 100,
},
});
expect(screenshot).toBeGolden(golden('screenshot-clip-rect.png'));
expect(screenshot).toBeGolden('screenshot-clip-rect.png');
});
it('should clip elements to the viewport', async({page, server, golden}) => {
it('should clip elements to the viewport', async({page, server}) => {
await page.setViewportSize({width: 500, height: 500});
await page.goto(server.PREFIX + '/grid.html');
const screenshot = await page.screenshot({
@ -68,7 +68,7 @@ describe.skip(ffheadful)('Page.screenshot', function() {
height: 100
}
});
expect(screenshot).toBeGolden(golden('screenshot-offscreen-clip.png'));
expect(screenshot).toBeGolden('screenshot-offscreen-clip.png');
});
it('should throw on clip outside the viewport', async({page, server}) => {
await page.setViewportSize({width: 500, height: 500});
@ -83,7 +83,7 @@ describe.skip(ffheadful)('Page.screenshot', function() {
}).catch(error => error);
expect(screenshotError.message).toContain('Clipped area is either empty or outside the resulting image');
});
it('should run in parallel', async({page, server, golden}) => {
it('should run in parallel', async({page, server}) => {
await page.setViewportSize({width: 500, height: 500});
await page.goto(server.PREFIX + '/grid.html');
const promises = [];
@ -98,15 +98,15 @@ describe.skip(ffheadful)('Page.screenshot', function() {
}));
}
const screenshots = await Promise.all(promises);
expect(screenshots[1]).toBeGolden(golden('grid-cell-1.png'));
expect(screenshots[1]).toBeGolden('grid-cell-1.png');
});
it('should take fullPage screenshots', async({page, server, golden}) => {
it('should take fullPage screenshots', async({page, server}) => {
await page.setViewportSize({width: 500, height: 500});
await page.goto(server.PREFIX + '/grid.html');
const screenshot = await page.screenshot({
fullPage: true
});
expect(screenshot).toBeGolden(golden('screenshot-grid-fullpage.png'));
expect(screenshot).toBeGolden('screenshot-grid-fullpage.png');
});
it('should restore viewport after fullPage screenshot', async({page, server}) => {
await page.setViewportSize({width: 500, height: 500});
@ -115,7 +115,7 @@ describe.skip(ffheadful)('Page.screenshot', function() {
expect(screenshot).toBeInstanceOf(Buffer);
await utils.verifyViewport(page, 500, 500);
});
it('should run in parallel in multiple pages', async({page, server, context, golden}) => {
it('should run in parallel in multiple pages', async({page, server, context}) => {
const N = 5;
const pages = await Promise.all(Array(N).fill(0).map(async() => {
const page = await context.newPage();
@ -127,10 +127,10 @@ describe.skip(ffheadful)('Page.screenshot', function() {
promises.push(pages[i].screenshot({ clip: { x: 50 * (i % 2), y: 0, width: 50, height: 50 } }));
const screenshots = await Promise.all(promises);
for (let i = 0; i < N; ++i)
expect(screenshots[i]).toBeGolden(golden(`grid-cell-${i % 2}.png`));
expect(screenshots[i]).toBeGolden(`grid-cell-${i % 2}.png`);
await Promise.all(pages.map(page => page.close()));
});
it.fail(FFOX)('should allow transparency', async({page, golden}) => {
it.fail(FFOX)('should allow transparency', async({page}) => {
await page.setViewportSize({ width: 50, height: 150 });
await page.setContent(`
<style>
@ -142,15 +142,15 @@ describe.skip(ffheadful)('Page.screenshot', function() {
<div style="background:transparent"></div>
`);
const screenshot = await page.screenshot({omitBackground: true});
expect(screenshot).toBeGolden(golden('transparent.png'));
expect(screenshot).toBeGolden('transparent.png');
});
it('should render white background on jpeg file', async({page, server, golden}) => {
it('should render white background on jpeg file', async({page, server}) => {
await page.setViewportSize({ width: 100, height: 100 });
await page.goto(server.EMPTY_PAGE);
const screenshot = await page.screenshot({omitBackground: true, type: 'jpeg'});
expect(screenshot).toBeGolden(golden('white.jpg'));
expect(screenshot).toBeGolden('white.jpg');
});
it('should work with odd clip size on Retina displays', async({page, golden}) => {
it('should work with odd clip size on Retina displays', async({page}) => {
const screenshot = await page.screenshot({
clip: {
x: 0,
@ -159,49 +159,49 @@ describe.skip(ffheadful)('Page.screenshot', function() {
height: 11,
}
});
expect(screenshot).toBeGolden(golden('screenshot-clip-odd-size.png'));
expect(screenshot).toBeGolden('screenshot-clip-odd-size.png');
});
it.skip(FFOX)('should work with a mobile viewport', async({browser, server, golden}) => {
it.skip(FFOX)('should work with a mobile viewport', 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 + '/overflow.html');
const screenshot = await page.screenshot();
expect(screenshot).toBeGolden(golden('screenshot-mobile.png'));
expect(screenshot).toBeGolden('screenshot-mobile.png');
await context.close();
});
it.skip(FFOX)('should work with a mobile viewport and clip', async({browser, server, golden}) => {
it.skip(FFOX)('should work with a mobile viewport and clip', 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 + '/overflow.html');
const screenshot = await page.screenshot({ clip: { x: 10, y: 10, width: 100, height: 150 } });
expect(screenshot).toBeGolden(golden('screenshot-mobile-clip.png'));
expect(screenshot).toBeGolden('screenshot-mobile-clip.png');
await context.close();
});
it.skip(FFOX)('should work with a mobile viewport and fullPage', async({browser, server, golden}) => {
it.skip(FFOX)('should work with a mobile viewport and fullPage', 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 + '/overflow-large.html');
const screenshot = await page.screenshot({ fullPage: true });
expect(screenshot).toBeGolden(golden('screenshot-mobile-fullpage.png'));
expect(screenshot).toBeGolden('screenshot-mobile-fullpage.png');
await context.close();
});
it('should work for canvas', async({page, server, golden}) => {
it('should work for canvas', async({page, server}) => {
await page.setViewportSize({width: 500, height: 500});
await page.goto(server.PREFIX + '/screenshots/canvas.html');
const screenshot = await page.screenshot();
expect(screenshot).toBeGolden(golden('screenshot-canvas.png'));
expect(screenshot).toBeGolden('screenshot-canvas.png');
});
it('should work for translateZ', async({page, server, golden}) => {
it('should work for translateZ', async({page, server}) => {
await page.setViewportSize({width: 500, height: 500});
await page.goto(server.PREFIX + '/screenshots/translateZ.html');
const screenshot = await page.screenshot();
expect(screenshot).toBeGolden(golden('screenshot-translateZ.png'));
expect(screenshot).toBeGolden('screenshot-translateZ.png');
});
it.fail(FFOX || WEBKIT)('should work for webgl', async({page, server, golden}) => {
it.fail(FFOX || WEBKIT)('should work for webgl', async({page, server}) => {
await page.setViewportSize({width: 640, height: 480});
await page.goto(server.PREFIX + '/screenshots/webgl.html');
const screenshot = await page.screenshot();
expect(screenshot).toBeGolden(golden('screenshot-webgl.png'));
expect(screenshot).toBeGolden('screenshot-webgl.png');
});
it('should work while navigating', async({page, server}) => {
await page.setViewportSize({width: 500, height: 500});
@ -215,31 +215,31 @@ describe.skip(ffheadful)('Page.screenshot', function() {
expect(screenshot).toBeInstanceOf(Buffer);
}
});
it('should work with device scale factor', async({browser, server, golden}) => {
it('should work with device scale factor', async({browser, server}) => {
const context = await browser.newContext({ viewport: { width: 320, height: 480 }, deviceScaleFactor: 2 });
const page = await context.newPage();
await page.goto(server.PREFIX + '/grid.html');
const screenshot = await page.screenshot();
expect(screenshot).toBeGolden(golden('screenshot-device-scale-factor.png'));
expect(screenshot).toBeGolden('screenshot-device-scale-factor.png');
await context.close();
});
it('should work with iframe in shadow', async({browser, page, server, golden}) => {
it('should work with iframe in shadow', async({browser, page, server}) => {
await page.setViewportSize({width: 500, height: 500});
await page.goto(server.PREFIX + '/grid-iframe-in-shadow.html');
expect(await page.screenshot()).toBeGolden(golden('screenshot-iframe.png'));
expect(await page.screenshot()).toBeGolden('screenshot-iframe.png');
});
});
describe.skip(ffheadful)('ElementHandle.screenshot', function() {
it('should work', async({page, server, golden}) => {
it('should work', async({page, server}) => {
await page.setViewportSize({width: 500, height: 500});
await page.goto(server.PREFIX + '/grid.html');
await page.evaluate(() => window.scrollBy(50, 100));
const elementHandle = await page.$('.box:nth-of-type(3)');
const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden(golden('screenshot-element-bounding-box.png'));
expect(screenshot).toBeGolden('screenshot-element-bounding-box.png');
});
it('should take into account padding and border', async({page, golden}) => {
it('should take into account padding and border', async({page}) => {
await page.setViewportSize({width: 500, height: 500});
await page.setContent(`
<div style="height: 14px">oooo</div>
@ -254,9 +254,9 @@ describe.skip(ffheadful)('ElementHandle.screenshot', function() {
`);
const elementHandle = await page.$('div#d');
const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden(golden('screenshot-element-padding-border.png'));
expect(screenshot).toBeGolden('screenshot-element-padding-border.png');
});
it('should capture full element when larger than viewport in parallel', async({page, golden}) => {
it('should capture full element when larger than viewport in parallel', async({page}) => {
await page.setViewportSize({width: 500, height: 500});
await page.setContent(`
@ -279,11 +279,11 @@ describe.skip(ffheadful)('ElementHandle.screenshot', function() {
const elementHandles = await page.$$('div.to-screenshot');
const promises = elementHandles.map(handle => handle.screenshot());
const screenshots = await Promise.all(promises);
expect(screenshots[2]).toBeGolden(golden('screenshot-element-larger-than-viewport.png'));
expect(screenshots[2]).toBeGolden('screenshot-element-larger-than-viewport.png');
await utils.verifyViewport(page, 500, 500);
});
it('should capture full element when larger than viewport', async({page, golden}) => {
it('should capture full element when larger than viewport', async({page}) => {
await page.setViewportSize({width: 500, height: 500});
await page.setContent(`
@ -305,11 +305,11 @@ describe.skip(ffheadful)('ElementHandle.screenshot', function() {
`);
const elementHandle = await page.$('div.to-screenshot');
const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden(golden('screenshot-element-larger-than-viewport.png'));
expect(screenshot).toBeGolden('screenshot-element-larger-than-viewport.png');
await utils.verifyViewport(page, 500, 500);
});
it('should scroll element into view', async({page, golden}) => {
it('should scroll element into view', async({page}) => {
await page.setViewportSize({width: 500, height: 500});
await page.setContent(`
<div style="height: 14px">oooo</div>
@ -330,9 +330,9 @@ describe.skip(ffheadful)('ElementHandle.screenshot', function() {
`);
const elementHandle = await page.$('div.to-screenshot');
const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden(golden('screenshot-element-scrolled-into-view.png'));
expect(screenshot).toBeGolden('screenshot-element-scrolled-into-view.png');
});
it('should scroll 15000px into view', async({page, golden}) => {
it('should scroll 15000px into view', async({page}) => {
await page.setViewportSize({width: 500, height: 500});
await page.setContent(`
<div style="height: 14px">oooo</div>
@ -353,9 +353,9 @@ describe.skip(ffheadful)('ElementHandle.screenshot', function() {
`);
const elementHandle = await page.$('div.to-screenshot');
const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden(golden('screenshot-element-scrolled-into-view.png'));
expect(screenshot).toBeGolden('screenshot-element-scrolled-into-view.png');
});
it('should work with a rotated element', async({page, golden}) => {
it('should work with a rotated element', async({page}) => {
await page.setViewportSize({width: 500, height: 500});
await page.setContent(`<div style="position:absolute;
top: 100px;
@ -366,7 +366,7 @@ describe.skip(ffheadful)('ElementHandle.screenshot', function() {
transform: rotateZ(200deg);">&nbsp;</div>`);
const elementHandle = await page.$('div');
const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden(golden('screenshot-element-rotate.png'));
expect(screenshot).toBeGolden('screenshot-element-rotate.png');
});
it('should fail to screenshot a detached element', async({page, server}) => {
await page.setContent('<h1>remove this</h1>');
@ -382,7 +382,7 @@ describe.skip(ffheadful)('ElementHandle.screenshot', function() {
expect(error.message).toContain('elementHandle.screenshot: Timeout 3000ms exceeded');
expect(error.message).toContain('element is not visible');
});
it('should wait for visible', async({page, server, golden}) => {
it('should wait for visible', async({page, server}) => {
await page.setViewportSize({width: 500, height: 500});
await page.goto(server.PREFIX + '/grid.html');
await page.evaluate(() => window.scrollBy(50, 100));
@ -398,39 +398,39 @@ describe.skip(ffheadful)('ElementHandle.screenshot', function() {
expect(done).toBe(false);
await elementHandle.evaluate(e => e.style.visibility = 'visible');
const screenshot = await promise;
expect(screenshot).toBeGolden(golden('screenshot-element-bounding-box.png'));
expect(screenshot).toBeGolden('screenshot-element-bounding-box.png');
});
it('should work for an element with fractional dimensions', async({page, golden}) => {
it('should work for an element with fractional dimensions', async({page}) => {
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).toBeGolden(golden('screenshot-element-fractional.png'));
expect(screenshot).toBeGolden('screenshot-element-fractional.png');
});
it.skip(FFOX)('should work with a mobile viewport', async({browser, server, golden}) => {
it.skip(FFOX)('should work with a mobile viewport', 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 + '/grid.html');
await page.evaluate(() => window.scrollBy(50, 100));
const elementHandle = await page.$('.box:nth-of-type(3)');
const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden(golden('screenshot-element-mobile.png'));
expect(screenshot).toBeGolden('screenshot-element-mobile.png');
await context.close();
});
it.skip(FFOX)('should work with device scale factor', async({browser, server, golden}) => {
it.skip(FFOX)('should work with device scale factor', async({browser, server}) => {
const context = await browser.newContext({ viewport: { width: 320, height: 480 }, deviceScaleFactor: 2 });
const page = await context.newPage();
await page.goto(server.PREFIX + '/grid.html');
await page.evaluate(() => window.scrollBy(50, 100));
const elementHandle = await page.$('.box:nth-of-type(3)');
const screenshot = await elementHandle.screenshot();
expect(screenshot).toBeGolden(golden('screenshot-element-mobile-dsf.png'));
expect(screenshot).toBeGolden('screenshot-element-mobile-dsf.png');
await context.close();
});
it('should work for an element with an offset', async({page, golden}) => {
it('should work for an element with an offset', async({page}) => {
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).toBeGolden(golden('screenshot-element-fractional-offset.png'));
expect(screenshot).toBeGolden('screenshot-element-fractional-offset.png');
});
it('should take screenshots when default viewport is null', async({server, browser}) => {
const context = await browser.newContext({ viewport: null });

View file

@ -69,26 +69,6 @@ module.exports = {
setupTestRunner,
specs: [
{
files: [
'./input.spec.js',
'./jshandle.spec.js',
'./keyboard.spec.ts',
'./mouse.spec.js',
'./navigation.spec.js',
'./pdf.spec.js',
'./queryselector.spec.js',
'./screenshot.spec.js',
'./waittask.spec.js',
'./interception.spec.js',
'./geolocation.spec.js',
'./workers.spec.js',
'./capabilities.spec.js',
'./permissions.spec.js',
],
environments: [customEnvironment, 'page'],
},
{
files: [
'./chromium/chromium.spec.js',

View file

@ -16,7 +16,7 @@
*/
const utils = require('./utils');
const {FFOX, CHROMIUM, WEBKIT, CHANNEL} = utils.testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT, CHANNEL} = testOptions;
async function giveItTimeToLog(frame) {
await frame.evaluate(() => new Promise(f => requestAnimationFrame(() => requestAnimationFrame(f))));
@ -143,14 +143,14 @@ describe('Frame.waitForFunction', function() {
await page.evaluate(element => element.remove(), div);
await waitForFunction;
});
it('should respect timeout', async({page}) => {
it('should respect timeout', async({page, playwright}) => {
let error = null;
await page.waitForFunction('false', {}, {timeout: 10}).catch(e => error = e);
expect(error).toBeTruthy();
expect(error.message).toContain('page.waitForFunction: Timeout 10ms exceeded');
expect(error).toBeInstanceOf(playwright.errors.TimeoutError);
});
it('should respect default timeout', async({page}) => {
it('should respect default timeout', async({page, playwright}) => {
page.setDefaultTimeout(1);
let error = null;
await page.waitForFunction('false').catch(e => error = e);
@ -429,7 +429,7 @@ describe('Frame.waitForSelector', function() {
const handle = await page.waitForSelector('non-existing', { state: 'hidden' });
expect(handle).toBe(null);
});
it('should respect timeout', async({page, server}) => {
it('should respect timeout', async({page, playwright}) => {
let error = null;
await page.waitForSelector('div', { timeout: 3000, state: 'attached' }).catch(e => error = e);
expect(error).toBeTruthy();
@ -461,7 +461,7 @@ describe('Frame.waitForSelector', function() {
it('should have correct stack trace for timeout', async({page, server}) => {
let error;
await page.waitForSelector('.zombo', { timeout: 10 }).catch(e => error = e);
expect(error.stack).toContain('waittask.spec.js');
expect(error.stack).toContain('waittask');
});
it('should throw for unknown state option', async({page, server}) => {
await page.setContent('<section>test</section>');
@ -519,7 +519,7 @@ describe('Frame.waitForSelector xpath', function() {
const waitForXPath = page.waitForSelector('//p[normalize-space(.)="hello world"]');
expect(await page.evaluate(x => x.textContent, await waitForXPath)).toBe('hello world ');
});
it('should respect timeout', async({page}) => {
it('should respect timeout', async({page, playwright}) => {
let error = null;
await page.waitForSelector('//div', { state: 'attached', timeout: 3000 }).catch(e => error = e);
expect(error).toBeTruthy();

View file

@ -15,7 +15,7 @@
* limitations under the License.
*/
const {FFOX, CHROMIUM, WEBKIT} = require('./utils').testOptions(browserType);
const {FFOX, CHROMIUM, WEBKIT} = testOptions;
describe('Workers', function() {
it('Page.workers', async function({page, server}) {