1/** 2 * Copyright 2020 Google Inc. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17import expect from 'expect'; 18import { 19 getTestState, 20 setupTestBrowserHooks, 21 setupTestPageAndContextHooks, 22 describeFailsFirefox, 23} from './mocha-utils'; // eslint-disable-line import/extensions 24import utils from './utils.js'; 25import { WebWorker } from '../lib/cjs/puppeteer/common/WebWorker.js'; 26import { ConsoleMessage } from '../lib/cjs/puppeteer/common/ConsoleMessage.js'; 27const { waitEvent } = utils; 28 29describeFailsFirefox('Workers', function () { 30 setupTestBrowserHooks(); 31 setupTestPageAndContextHooks(); 32 it('Page.workers', async () => { 33 const { page, server } = getTestState(); 34 35 await Promise.all([ 36 new Promise((x) => page.once('workercreated', x)), 37 page.goto(server.PREFIX + '/worker/worker.html'), 38 ]); 39 const worker = page.workers()[0]; 40 expect(worker.url()).toContain('worker.js'); 41 42 expect(await worker.evaluate(() => globalThis.workerFunction())).toBe( 43 'worker function result' 44 ); 45 46 await page.goto(server.EMPTY_PAGE); 47 expect(page.workers().length).toBe(0); 48 }); 49 it('should emit created and destroyed events', async () => { 50 const { page } = getTestState(); 51 52 const workerCreatedPromise = new Promise<WebWorker>((x) => 53 page.once('workercreated', x) 54 ); 55 const workerObj = await page.evaluateHandle( 56 () => new Worker('data:text/javascript,1') 57 ); 58 const worker = await workerCreatedPromise; 59 const workerThisObj = await worker.evaluateHandle(() => this); 60 const workerDestroyedPromise = new Promise((x) => 61 page.once('workerdestroyed', x) 62 ); 63 await page.evaluate( 64 (workerObj: Worker) => workerObj.terminate(), 65 workerObj 66 ); 67 expect(await workerDestroyedPromise).toBe(worker); 68 const error = await workerThisObj 69 .getProperty('self') 70 .catch((error) => error); 71 expect(error.message).toContain('Most likely the worker has been closed.'); 72 }); 73 it('should report console logs', async () => { 74 const { page } = getTestState(); 75 76 const [message] = await Promise.all([ 77 waitEvent(page, 'console'), 78 page.evaluate(() => new Worker(`data:text/javascript,console.log(1)`)), 79 ]); 80 expect(message.text()).toBe('1'); 81 expect(message.location()).toEqual({ 82 url: '', 83 lineNumber: 0, 84 columnNumber: 8, 85 }); 86 }); 87 it('should have JSHandles for console logs', async () => { 88 const { page } = getTestState(); 89 90 const logPromise = new Promise<ConsoleMessage>((x) => 91 page.on('console', x) 92 ); 93 await page.evaluate( 94 () => new Worker(`data:text/javascript,console.log(1,2,3,this)`) 95 ); 96 const log = await logPromise; 97 expect(log.text()).toBe('1 2 3 JSHandle@object'); 98 expect(log.args().length).toBe(4); 99 expect(await (await log.args()[3].getProperty('origin')).jsonValue()).toBe( 100 'null' 101 ); 102 }); 103 it('should have an execution context', async () => { 104 const { page } = getTestState(); 105 106 const workerCreatedPromise = new Promise<WebWorker>((x) => 107 page.once('workercreated', x) 108 ); 109 await page.evaluate( 110 () => new Worker(`data:text/javascript,console.log(1)`) 111 ); 112 const worker = await workerCreatedPromise; 113 expect(await (await worker.executionContext()).evaluate('1+1')).toBe(2); 114 }); 115 it('should report errors', async () => { 116 const { page } = getTestState(); 117 118 const errorPromise = new Promise<Error>((x) => page.on('pageerror', x)); 119 await page.evaluate( 120 () => 121 new Worker(`data:text/javascript, throw new Error('this is my error');`) 122 ); 123 const errorLog = await errorPromise; 124 expect(errorLog.message).toContain('this is my error'); 125 }); 126}); 127