/** * Copyright (c) Microsoft Corporation. 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. */ import { browserTest as test, expect } from '../config/browserTest'; import type { ElementHandle } from 'playwright-core'; test('console event should work @smoke', async ({ page }) => { const [, message] = await Promise.all([ page.evaluate(() => console.log('hello')), page.context().waitForEvent('console'), ]); expect(message.text()).toBe('hello'); expect(message.page()).toBe(page); }); test('console event should work with element handles', async ({ page }) => { await page.setContent('hello'); const [message] = await Promise.all([ page.context().waitForEvent('console'), page.evaluate(() => console.log(document.body)), ]); const body = message.args()[0]; expect(await body.evaluate(x => x.nodeName)).toBe('BODY'); await (body as ElementHandle).click(); }); test('console event should work in popup', async ({ page }) => { const [, message, popup] = await Promise.all([ page.evaluate(() => { const win = window.open(''); (win as any).console.log('hello'); }), page.context().waitForEvent('console'), page.waitForEvent('popup'), ]); expect(message.text()).toBe('hello'); expect(message.page()).toBe(popup); }); test('console event should work in popup 2', async ({ page, browserName, isBidi }) => { test.fixme(browserName === 'firefox' && !isBidi, 'console message from javascript: url is not reported at all'); const [, message, popup] = await Promise.all([ page.evaluate(async () => { const win = window.open('javascript:console.log("hello")')!; await new Promise(f => window.builtins.setTimeout(f, 0)); win.close(); }), page.context().waitForEvent('console', msg => msg.type() === 'log'), page.context().waitForEvent('page'), ]); expect(message.text()).toBe('hello'); expect(message.page()).toBe(popup); }); test('console event should work in immediately closed popup', async ({ page, browserName, isBidi }) => { test.fixme(browserName === 'firefox' && !isBidi, 'console message is not reported at all'); const [, message, popup] = await Promise.all([ page.evaluate(async () => { const win = window.open()!; (win as any).console.log('hello'); win.close(); }), page.context().waitForEvent('console'), page.waitForEvent('popup'), ]); expect(message.text()).toBe('hello'); expect(message.page()).toBe(popup); }); test('dialog event should work @smoke', async ({ page }) => { const promise = page.evaluate(() => prompt('hey?')); const [dialog1, dialog2] = await Promise.all([ page.context().waitForEvent('dialog'), page.waitForEvent('dialog'), ]); expect(dialog1).toBe(dialog2); expect(dialog1.message()).toBe('hey?'); expect(dialog1.page()).toBe(page); await dialog1.accept('hello'); expect(await promise).toBe('hello'); }); test('dialog event should work in popup', async ({ page }) => { const promise = page.evaluate(() => { const win = window.open(''); return (win as any).prompt('hey?'); }); const [dialog, popup] = await Promise.all([ page.context().waitForEvent('dialog'), page.waitForEvent('popup'), ]); expect(dialog.message()).toBe('hey?'); expect(dialog.page()).toBe(popup); await dialog.accept('hello'); expect(await promise).toBe('hello'); }); test('dialog event should work in popup 2', async ({ page, browserName }) => { test.fixme(browserName === 'firefox', 'dialog from javascript: url is not reported at all'); const promise = page.evaluate(async () => { window.open('javascript:prompt("hey?")'); }); const dialog = await page.context().waitForEvent('dialog'); expect(dialog.message()).toBe('hey?'); expect(dialog.page()).toBe(null); await dialog.accept('hello'); await promise; }); test('dialog event should work in immediately closed popup', async ({ page }) => { const promise = page.evaluate(async () => { const win = window.open()!; const result = (win as any).prompt('hey?'); win.close(); return result; }); const [dialog, popup] = await Promise.all([ page.context().waitForEvent('dialog'), page.waitForEvent('popup'), ]); expect(dialog.message()).toBe('hey?'); expect(dialog.page()).toBe(popup); await dialog.accept('hello'); expect(await promise).toBe('hello'); }); test('dialog event should work with inline script tag', async ({ page, server }) => { server.setRoute('/popup.html', (req, res) => { res.setHeader('content-type', 'text/html'); res.end(``); }); await page.goto(server.EMPTY_PAGE); await page.setContent(`Click me`); const promise = page.click('a'); const [dialog, popup] = await Promise.all([ page.context().waitForEvent('dialog'), page.context().waitForEvent('page'), ]); expect(dialog.message()).toBe('hey?'); expect(dialog.page()).toBe(popup); await dialog.accept('hello'); await promise; await expect.poll(() => popup.evaluate('window.result')).toBe('hello'); }); test('weberror event should work', async ({ page }) => { const [webError] = await Promise.all([ page.context().waitForEvent('weberror'), page.setContent(''), ]); expect(webError.page()).toBe(page); expect(webError.error().stack).toContain('boom'); }); test('weberror event should include location', async ({ page, server }) => { server.setRoute('/error.js', (req, res) => { res.setHeader('content-type', 'application/javascript'); res.end(` function foo() { throw new Error('boom'); } foo(); `); }); server.setRoute('/error.html', (req, res) => { res.setHeader('content-type', 'text/html'); res.end(''); }); const [webError] = await Promise.all([ page.context().waitForEvent('weberror'), page.goto(server.PREFIX + '/error.html'), ]); const location = webError.location(); expect(location.url).toBe(`${server.PREFIX}/error.js`); expect(location.line).toBe(2); expect(location.column).toBeGreaterThan(0); // column is not consistent across browsers }); test('pageload event should work @smoke', async ({ page, server }) => { const [eventPage] = await Promise.all([ page.context().waitForEvent('pageload'), page.goto(server.EMPTY_PAGE), ]); expect(eventPage).toBe(page); }); test('framenavigated event should work @smoke', async ({ page, server }) => { const [frame] = await Promise.all([ page.context().waitForEvent('framenavigated'), page.goto(server.EMPTY_PAGE), ]); expect(frame).toBe(page.mainFrame()); expect(frame.url()).toBe(server.EMPTY_PAGE); }); test('pageclose event should work @smoke', async ({ context }) => { const page = await context.newPage(); const [closed] = await Promise.all([ context.waitForEvent('pageclose'), page.close(), ]); expect(closed).toBe(page); }); test('frameattached event should work @smoke', async ({ page, server }) => { await page.goto(server.EMPTY_PAGE); const [frame] = await Promise.all([ page.context().waitForEvent('frameattached'), page.evaluate(() => { const iframe = document.createElement('iframe'); iframe.src = 'about:blank'; document.body.appendChild(iframe); }), ]); expect(frame.parentFrame()).toBe(page.mainFrame()); }); test('framedetached event should work @smoke', async ({ page, server }) => { await page.goto(server.EMPTY_PAGE); await page.evaluate(() => { const iframe = document.createElement('iframe'); iframe.id = 'x'; iframe.src = 'about:blank'; document.body.appendChild(iframe); }); await page.waitForSelector('iframe'); const [frame] = await Promise.all([ page.context().waitForEvent('framedetached'), page.evaluate(() => document.getElementById('x')!.remove()), ]); expect(frame.parentFrame()).toBe(page.mainFrame()); }); test('download event should work @smoke', async ({ page, server }) => { server.setRoute('/download', (req, res) => { res.setHeader('Content-Type', 'application/octet-stream'); res.setHeader('Content-Disposition', 'attachment; filename=file.txt'); res.end('Hello world'); }); await page.setContent(`download`); const [download] = await Promise.all([ page.context().waitForEvent('download'), page.click('a'), ]); expect(download.suggestedFilename()).toBe('file.txt'); expect(download.page()).toBe(page); });