/** * Copyright (c) Microsoft Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as playwright from '../../../index'; type AssertType = S extends T ? AssertNotAny : false; type AssertNotAny = {notRealProperty: number} extends S ? false : true; // Examples taken from README (async () => { const browser = await playwright.chromium.launch(); const page = await browser.newPage(); await page.goto('https://example.com'); await page.screenshot({ path: 'example.png' }); await browser.close(); })(); (async () => { const browser = await playwright.chromium.launch(); const page = await browser.newPage(); await page.goto('https://news.ycombinator.com', { waitUntil: 'networkidle' }); await page.pdf({ path: 'hn.pdf', format: 'A4' }); await browser.close(); })(); (async () => { const browser = await playwright.chromium.launch(); const page = await browser.newPage(); await page.goto('https://example.com'); // Get the "viewport" of the page, as reported by the page. const dimensions = await page.evaluate(() => { return { width: document.documentElement.clientWidth, height: document.documentElement.clientHeight, deviceScaleFactor: window.devicePixelRatio }; }); console.log('Dimensions:', dimensions); await browser.close(); })(); // The following examples are taken from the docs itself playwright.chromium.launch().then(async browser => { const page = await browser.newPage(); page.on('console', message => { console.log(message.text()); }); await page.evaluate(() => console.log(5, 'hello', { foo: 'bar' })); { const result = await page.evaluate(() => { return Promise.resolve(8 * 7); }); const assertion: AssertType = true; console.log(await page.evaluate('1 + 2')); page.$eval('.foo', e => e.style); } const bodyHandle = await page.$('body'); if (!bodyHandle) return; { const html = await page.evaluate( (body: HTMLElement) => body.innerHTML, bodyHandle ); const assertion: AssertType = true; } }); import * as crypto from 'crypto'; import * as fs from 'fs'; import { EventEmitter } from 'events'; playwright.chromium.launch().then(async browser => { const page = await browser.newPage(); page.on('console', console.log); await page.exposeFunction('md5', (text: string) => crypto .createHash('md5') .update(text) .digest('hex') ); await page.evaluate(async () => { // use window.md5 to compute hashes const myString = 'PUPPETEER'; const myHash = await (window as any).md5(myString); console.log(`md5 of ${myString} is ${myHash}`); }); await browser.close(); page.on('console', console.log); await page.exposeFunction('readfile', async (filePath: string) => { return new Promise((resolve, reject) => { fs.readFile(filePath, 'utf8', (err, text) => { if (err) reject(err); else resolve(text); }); }); }); await page.evaluate(async () => { // use window.readfile to read contents of a file const content = await (window as any).readfile('/etc/hosts'); console.log(content); }); await page.exposeBinding('clicked', async (source, handle) => { await handle.asElement()!.textContent(); await source.page.goto('http://example.com'); }, { handle: true }); await page.emulateMedia({media: 'screen'}); await page.pdf({ path: 'page.pdf' }); await page.route('**/*', (route, interceptedRequest) => { if ( interceptedRequest.url().endsWith('.png') || interceptedRequest.url().endsWith('.jpg') ) route.abort(); else route.continue(); }); await page.route(str => { return true; }, (route, request) => { const {referer} = request.headers(); const isString: AssertType = true; route.continue({ headers: { 'Access-Control-Allow-Origin': '*' } }); return 'something random for no reason'; }); await page.keyboard.type('Hello'); // Types instantly await page.keyboard.type('World', { delay: 100 }); // Types slower, like a user const watchDog = page.waitForFunction('window.innerWidth < 100'); page.setViewportSize({ width: 50, height: 50 }); await watchDog; let currentURL: string; page .waitForSelector('img') .then(() => console.log('First URL with image: ' + currentURL)); for (currentURL of [ 'https://example.com', 'https://google.com', 'https://bbc.com' ]) await page.goto(currentURL); page.keyboard.type('Hello World!'); page.keyboard.press('ArrowLeft'); page.keyboard.down('Shift'); // tslint:disable-next-line prefer-for-of for (let i = 0; i < ' World'.length; i++) page.keyboard.press('ArrowLeft'); page.keyboard.up('Shift'); page.keyboard.press('Backspace'); page.keyboard.insertText('嗨'); await browser.startTracing(page, { path: 'trace.json'}); await page.goto('https://www.google.com'); await browser.stopTracing(); page.on('dialog', async dialog => { console.log(dialog.message()); await dialog.dismiss(); await browser.close(); }); const inputElement = (await page.$('input[type=submit]'))!; await inputElement.click(); await inputElement.setInputFiles([{ name: 'yo', mimeType: 'text/plain', buffer: Buffer.from('yo') }]) }); // Example with launch options (async () => { const browser = await playwright.chromium.launch({ chromiumSandbox: false, handleSIGINT: true, handleSIGHUP: true, handleSIGTERM: true, }); const page = await browser.newPage(); await page.goto('https://example.com'); await page.screenshot({ path: 'example.png' }); await browser.close(); })(); // Test v0.12 features (async () => { const launchOptions: playwright.LaunchOptions = { devtools: true, env: { TIMEOUT: 52, SOMETHING: '/some/path', JEST_TEST: true } }; const browser = await playwright.chromium.launch(launchOptions); const viewport: playwright.ViewportSize = { width: 100, height: 200, }; const geolocation: playwright.Geolocation = { latitude: 0, longitude: 0, accuracy: undefined, }; const httpCredentials: playwright.HTTPCredentials = { username: 'foo', password: 'bar', }; const contextOptions: playwright.BrowserContextOptions = { viewport, geolocation, httpCredentials, }; const page = await browser.newPage(contextOptions); const button = (await page.$('#myButton'))!; const div = (await page.$('#myDiv'))!; const input = (await page.$('#myInput'))!; if (!button) throw new Error('Unable to select myButton'); if (!input) throw new Error('Unable to select myInput'); await page.addStyleTag({ url: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' }); console.log(page.url()); page.type('#myInput', 'Hello World!'); page.on('console', (event: playwright.ConsoleMessage, ...args: any[]) => { console.log(event.text, event.type); for (let i = 0; i < args.length; ++i) console.log(`${i}: ${args[i]}`); }); await button.focus(); await button.press('Enter'); await button.screenshot({ type: 'jpeg', omitBackground: true }); console.log(button.toString()); input.type('Hello World', { delay: 10 }); const buttonText = await (await button.getProperty('textContent')).jsonValue(); await page.context().clearCookies(); const cookies: playwright.Cookie[] = await page.context().cookies(['http://example.com']); const cookie = cookies[0]; const nameIsString: AssertType = true; const valueIsString: AssertType = true; const pathIsString: AssertType = true; const expiresIsNumber: AssertType = true; const httpOnlyIsBoolean: AssertType = true; const secureIsBoolean: AssertType = true; const sameSiteIsEnum: AssertType<"Strict"|"Lax"|"None", typeof cookie.sameSite> = true; const navResponse = await page.waitForNavigation({ timeout: 1000 }); console.log(navResponse!.ok, navResponse!.status, navResponse!.url, navResponse!.headers); // evaluate example const bodyHandle = (await page.$('body'))!; const html = await page.evaluate((body: HTMLBodyElement) => body.innerHTML, bodyHandle); await bodyHandle.dispose(); // getProperties example const handle = await page.evaluateHandle(() => ({ window, document })); const properties = await handle.getProperties(); const windowHandle = properties.get('window'); const documentHandle = properties.get('document'); await handle.dispose(); // evaluateHandle example const aHandle = await page.evaluateHandle(() => document.body); const resultHandle = await page.evaluateHandle((body: Element) => body.innerHTML, aHandle); console.log(await resultHandle.jsonValue()); await resultHandle.dispose(); await browser.close(); })(); // test $eval and $$eval (async () => { const browser = await playwright.firefox.launch(); const page = await browser.newPage(); await page.goto('https://example.com'); await page.$eval('#someElement', (element, text: string) => { return element.innerHTML = text; }, 'hey'); const elementText = await page.$$eval('.someClassName', elements => { console.log(elements.length); console.log(elements.map(x => x)[0].textContent); return elements[3].innerHTML; }); const frame = page.frames()[0]; const handle = await page.evaluateHandle(() => document.body); for (const object of [frame, handle, page]) { { const value = await object.$eval('*[foo=bar]', i => i.textContent); const assertion: AssertType = true; } { const value = await object.$eval('input', i => i.disabled); const assertion: AssertType = true; } { const value = await object.$eval('input[foo=bar]', (i: HTMLInputElement) => i.disabled); const assertion: AssertType = true; } { const value = await object.$eval('*[foo=bar]', (i, dummy) => i.textContent, 2); const assertion: AssertType = true; } { const value = await object.$eval('input', (i, dummy) => i.disabled, 2); const assertion: AssertType = true; } { const value = await object.$eval('input[foo=bar]', (i: HTMLInputElement, dummy: number) => i.disabled, 2); const assertion: AssertType = true; } { const value = await object.$$eval('*[foo=bar]', i => i[0].textContent); const assertion: AssertType = true; } { const value = await object.$$eval('input', i => i[0].defaultValue); const assertion: AssertType = true; } { const value = await object.$$eval('input[foo=bar]', (i: HTMLInputElement[]) => i[0].defaultValue); const assertion: AssertType = true; } { const value = await object.$$eval('*[foo=bar]', (i, dummy) => i[0].textContent, 2); const assertion: AssertType = true; } { const value = await object.$$eval('input', (i, dummy) => i[0].defaultValue, 2); const assertion: AssertType = true; } { const value = await object.$$eval('input[foo=bar]', (i: HTMLInputElement[], dummy: number) => i[0].defaultValue, 2); const assertion: AssertType = true; } } await browser.close(); })(); // waitForEvent (async () => { const browser = await playwright.webkit.launch(); const page = await browser.newPage(); { const frame = await page.waitForEvent('frameattached'); const assertion: AssertType = true; } { const worker = await page.waitForEvent('worker', { predicate: worker => { const condition: AssertType = true; return true; } }); const assertion: AssertType = true; } { const newPage = await page.context().waitForEvent('page', { timeout: 500 }); const assertion: AssertType = true; } { const response = await page.waitForEvent('response', response => response.url() === 'asdf'); const assertion: AssertType = true; } })(); // typed handles (async () => { const browser = await playwright.webkit.launch(); const page = await browser.newPage(); const windowHandle = await page.evaluateHandle(() => window); function wrap(t: T): [T, string, boolean, number] { return [t, '1', true, 1]; } { const value = await page.evaluate(() => 1); const assertion: AssertType = true; } { const value = await page.mainFrame().evaluate(() => 'hello'); const assertion: AssertType = true; } { const value = await page.workers()[0].evaluate(() => [1,2,3]); const assertion: AssertType = true; } { const value = await windowHandle.evaluate((x: Window, b) => b, 'world'); const assertion: AssertType = true; } { const value = await page.evaluate(({a, b}) => b ? a : '123', { a: 3, b: true }); const assertion: AssertType = true; } { const value = await page.evaluate(([a, b, c]) => ({a, b, c}), [3, '123', true]); const assertion: AssertType<{a: string | number | boolean, b: string | number | boolean, c: string | number | boolean}, typeof value> = true; } { const value = await page.evaluate(([a, b, c]) => ({a, b, c}), [3, '123', true] as const); const assertion: AssertType<{a: 3, b: '123', c: true}, typeof value> = true; } { const handle = await page.evaluateHandle(() => 3); const value = await page.evaluate(([a, b, c, d]) => ({a, b, c, d}), wrap(handle)); const assertion: AssertType<{a: number, b: string, c: boolean, d: number}, typeof value> = true; } { const handle = await page.evaluateHandle(() => 3); const h = await page.evaluateHandle(([a, b, c, d]) => ({a, b, c, d}), wrap(handle)); const value = await h.evaluate(h => h); const assertion: AssertType<{a: number, b: string, c: boolean, d: number}, typeof value> = true; } { const handle = await page.evaluateHandle(() => ([{a: '123'}])); const value = await handle.evaluate(h => h[1].a); const assertion: AssertType = true; } { const handle = await page.evaluateHandle(() => ([{a: '123'}])); const value = await handle.evaluate((h, p) => ({ a: h[1].a, p}), 123); const assertion: AssertType<{a: string, p: number}, typeof value> = true; } { const handle = await page.evaluateHandle(() => ([{a: '123'}])); const value = await handle.evaluate((h: ({a: string, b: number})[]) => h[1].b); const assertion: AssertType = true; } { const handle = await page.evaluateHandle(() => ([{a: '123'}])); const value = await handle.evaluate((h: ({a: string, b: number})[], prop) => h[1][prop], 'b' as const); const assertion: AssertType = true; } { const handle = await page.evaluateHandle(() => ([{a: '123'}])); const value = await handle.evaluateHandle(h => h[1].a); const assertion: AssertType, typeof value> = true; } { const handle = await page.evaluateHandle(() => ([{a: '123'}])); const value = await handle.evaluateHandle((h, p) => ({ a: h[1].a, p}), 123); const assertion: AssertType, typeof value> = true; } { const handle = await page.evaluateHandle(() => ([{a: '123'}])); const value = await handle.evaluateHandle((h: ({a: string, b: number})[]) => h[1].b); const assertion: AssertType, typeof value> = true; } { const handle = await page.waitForSelector('*'); const value = await handle.evaluate((e: HTMLInputElement) => e.disabled); const assertion: AssertType = true; } { const handle = await page.waitForSelector('*'); const value = await handle.evaluate((e: HTMLInputElement, x) => e.disabled || x, 123); const assertion: AssertType = true; } { const handle = await page.waitForSelector('*'); const value = await handle.evaluateHandle((e: HTMLInputElement, x) => e.disabled || x, 123); const assertion: AssertType | playwright.JSHandle, typeof value> = true; } { const handle = await page.evaluateHandle(() => 'hello'); const value = await handle.jsonValue(); const assertion: AssertType = true; } { const handle = await page.mainFrame().evaluateHandle(() => ['a', 'b', 'c']); const value = await handle.jsonValue(); const assertion: AssertType = true; } { const handle = await page.workers()[0].evaluateHandle(() => 123); const value = await handle.jsonValue(); const assertion: AssertType = true; } { const handle = await windowHandle.evaluateHandle((x: Window, b) => b, 123); const value = await handle.jsonValue(); const assertion: AssertType = true; } { const handle = await page.evaluateHandle(() => document.createElement('body')); const assertion: AssertType, typeof handle> = true; await handle.evaluate(body => { const assertion: AssertType = true; }); } await browser.close(); })(); // protocol (async () => { const browser = await playwright.chromium.launch(); const context = await browser.newContext(); const session = await context.newCDPSession(await context.newPage()); session.on('Runtime.executionContextCreated', payload => { const id = payload.context.id; const assertion: AssertType = true; }); const obj = await session.send('Runtime.evaluate', { expression: '1 + 1' }); const type = obj.result.type; const assertion: AssertType = true; await session.detach(); await browser.close(); })(); (async () => { const browser = await playwright.firefox.launch(); const page = await browser.newPage(); const context = page.context(); const oneTwoThree = ('pageTarget' in context) ? context['pageTarget'] : 123; const assertion: AssertType<123, typeof oneTwoThree> = true; await browser.close(); })(); // $eval (async () => { const browser = await playwright.webkit.launch(); const page = await browser.newPage(); await page.$eval('span', (element, x) => { const spanAssertion: AssertType = true; const numberAssertion: AssertType = true; }, 5); await page.$eval('my-custom-element', (element, x) => { const elementAssertion: AssertType = true; const numberAssertion: AssertType = true; }, 5); await page.$$eval('my-custom-element', (elements, x) => { const elementAssertion: AssertType<(HTMLElement|SVGElement)[], typeof elements> = true; const numberAssertion: AssertType = true; }, 5); await page.$$eval('input', (elements, x) => { const elementAssertion: AssertType = true; const numberAssertion: AssertType = true; }, 5); const frame = page.mainFrame(); await frame.$eval('span', (element, [x, y]) => { const spanAssertion: AssertType = true; const numberAssertion: AssertType = true; const stringAssertion: AssertType = true; }, [5, 'asdf']); await frame.$eval('my-custom-element', element => { const elementAssertion: AssertType = true; }); await frame.$$eval('my-custom-element', (elements, {x, y}) => { const elementAssertion: AssertType<(HTMLElement|SVGElement)[], typeof elements> = true; const numberAssertion: AssertType = true; const stringAssertion: AssertType = true; }, { x: 5, y: await page.evaluateHandle(() => 'asdf') }); await frame.$$eval('input', (elements, x) => { const elementAssertion: AssertType = true; const numberAssertion: AssertType = true; }, 5); const something = Math.random() > .5 ? 'visible' : 'attached'; const handle = await page.waitForSelector('a', {state: something}); await handle.$eval('span', (element, { x, y }) => { const spanAssertion: AssertType = true; const numberAssertion: AssertType = true; const stringAssertion: AssertType = true; }, { x: 5, y: 'asdf' }); await handle.$eval('my-custom-element', element => { const elementAssertion: AssertType = true; }); await handle.$$eval('my-custom-element', (elements, [x, y]) => { const elementAssertion: AssertType<(HTMLElement|SVGElement)[], typeof elements> = true; const numberAssertion: AssertType = true; const stringAssertion: AssertType = true; }, [5, await page.evaluateHandle(() => 'asdf')]); await handle.$$eval('input', (elements, x) => { const elementAssertion: AssertType = true; const numberAssertion: AssertType = true; }, 5); await browser.close(); })(); // query selectors (async () => { const browser = await playwright.chromium.launch(); const page = await browser.newPage(); const frame = page.mainFrame(); const element = await page.waitForSelector('some-fake-element'); const elementLikes = [page, frame, element]; for (const elementLike of elementLikes) { { const handle = await elementLike.$('body'); const bodyAssertion: AssertType, typeof handle> = true; } { const handle = await elementLike.$('something-strange'); const top = await handle!.evaluate(element => element.style.top); const assertion: AssertType = true; } { const handles = await elementLike.$$('body'); const bodyAssertion: AssertType[], typeof handles> = true; } { const handles = await elementLike.$$('something-strange'); const top = await handles[0].evaluate(element => element.style.top); const assertion: AssertType = true; } } const frameLikes = [page, frame]; for (const frameLike of frameLikes) { { const handle = await frameLike.waitForSelector('body'); const bodyAssertion: AssertType, typeof handle> = true; const canBeNull: AssertType = false; } { const state = Math.random() > .5 ? 'attached' : 'visible'; const handle = await frameLike.waitForSelector('body', {state}); const bodyAssertion: AssertType, typeof handle> = true; const canBeNull: AssertType = false; } { const handle = await frameLike.waitForSelector('body', {state: 'hidden'}); const bodyAssertion: AssertType, typeof handle> = true; const canBeNull: AssertType = true; } { const state = Math.random() > .5 ? 'hidden' : 'visible'; const handle = await frameLike.waitForSelector('body', {state}); const bodyAssertion: AssertType, typeof handle> = true; const canBeNull: AssertType = true; } { const handle = await frameLike.waitForSelector('something-strange'); const elementAssertion: AssertType, typeof handle> = true; const canBeNull: AssertType = false; } { const state = Math.random() > .5 ? 'attached' : 'visible'; const handle = await frameLike.waitForSelector('something-strange', {state}); const elementAssertion: AssertType, typeof handle> = true; const canBeNull: AssertType = false; } { const state = Math.random() > .5 ? 'hidden' : 'visible'; const handle = await frameLike.waitForSelector('something-strange', {state}); const elementAssertion: AssertType, typeof handle> = true; const canBeNull: AssertType = true; } } await browser.close(); })(); // top level (async () => { playwright.chromium.connect; playwright.errors.TimeoutError; { playwright.devices['my device'] = { userAgent: 'foo', viewport: {height: 123, width: 456}, deviceScaleFactor: 1, hasTouch: false, isMobile: true, defaultBrowserType: 'chromium' }; const iPhone = playwright.devices['iPhone 11']; const assertion: AssertType = true; const widthAssertion: AssertType = true; const deviceScaleFactorAssertion: AssertType = true; const hasTouchAssertion: AssertType = true; const isMobileAssertion: AssertType = true; } { const agents = playwright.devices.map(x => x.userAgent); const assertion: AssertType = true; } // Must be a function that evaluates to a selector engine instance. const createTagNameEngine = () => ({ // Creates a selector that matches given target when queried at the root. // Can return undefined if unable to create one. create(root: Element, target: Element) { return root.querySelector(target.tagName) === target ? target.tagName : undefined; }, // Returns the first element matching given selector in the root's subtree. query(root: Element, selector: string) { return root.querySelector(selector); }, // Returns all elements matching given selector in the root's subtree. queryAll(root: Element, selector: string) { return Array.from(root.querySelectorAll(selector)); } }); // Register the engine. Selectors will be prefixed with "tag=". await playwright.selectors.register('tag', createTagNameEngine); })(); // Event listeners (async function() { const eventEmitter = {} as (playwright.Page|playwright.BrowserContext|EventEmitter); const listener = () => {}; eventEmitter.addListener('close', listener) .on('close', listener) .once('close', listener) .removeListener('close', listener) .off('close', listener); }); // waitForResponse callback predicate (async () => { const browser = await playwright.chromium.launch(); const page = await browser.newPage(); await Promise.all([ page.waitForResponse(response => response.url().includes('example.com')), page.goto('https://example.com') ]); await browser.close(); })(); // exported types import { LaunchOptions, ConnectOptions, Cookie, BrowserContextOptions, ViewportSize, Geolocation, HTTPCredentials, } from '../../../';