Skip to main content
The Worker class represents a WebWorker or Service Worker. Worker event is emitted on the page object to signal a worker creation.
page.on('worker', worker => {
  console.log(`Worker created: ${worker.url()}`);
});

Events

close

Emitted when the worker is closed.
worker.on('close', worker => {
  console.log('Worker closed');
});

console

Emitted when JavaScript within the worker calls console.log or other console API methods.
worker.on('console', msg => {
  console.log(`Worker console: ${msg.text()}`);
});
You need to subscribe to the ‘console’ event before the worker sends any console messages.

Methods

url

Returns the URL of the worker. Returns: string - Worker URL
page.on('worker', worker => {
  console.log(`Worker URL: ${worker.url()}`);
});

evaluate

Evaluates a function in the worker context.
pageFunction
function
required
Function to be evaluated in the worker context
arg
any
Optional argument to pass to the function
Returns: Promise<R> - Promise that resolves to the return value
const worker = await page.waitForEvent('worker');
const result = await worker.evaluate(() => {
  return self.location.href;
});
console.log(result);

evaluateHandle

Evaluates a function in the worker context and returns a JSHandle.
pageFunction
function
required
Function to be evaluated
arg
any
Optional argument to pass to the function
Returns: Promise<JSHandle> - Promise that resolves to a JSHandle
const workerHandle = await worker.evaluateHandle(() => self);

waitForEvent

Waits for an event to fire and returns its value.
event
string
required
Event name (e.g., ‘close’, ‘console’)
options
object
Optional waiting parameters
Returns: Promise<any> - Promise that resolves to the event data
const closePromise = worker.waitForEvent('close');
// ... do something that closes the worker
await closePromise;

Examples

Monitoring worker creation

import { test, expect } from '@playwright/test';

test('monitor workers', async ({ page }) => {
  await page.goto('https://example.com');
  
  // Listen for workers
  page.on('worker', worker => {
    console.log(`Worker created: ${worker.url()}`);
    
    // Listen for console messages from worker
    worker.on('console', msg => {
      console.log(`Worker console: ${msg.text()}`);
    });
    
    // Listen for worker close
    worker.on('close', () => {
      console.log('Worker terminated');
    });
  });
  
  // Trigger worker creation
  await page.evaluate(() => {
    new Worker('/worker.js');
  });
});

Communicating with workers

test('communicate with worker', async ({ page }) => {
  await page.goto('https://example.com');
  
  const workerPromise = page.waitForEvent('worker');
  
  await page.evaluate(() => {
    const worker = new Worker('/worker.js');
    worker.postMessage({ type: 'start', value: 42 });
  });
  
  const worker = await workerPromise;
  
  // Evaluate code in worker context
  const result = await worker.evaluate(() => {
    return 'Worker is running';
  });
  
  console.log(result);
});

Testing Service Workers

test('service worker', async ({ page, context }) => {
  await context.grantPermissions(['notifications']);
  await page.goto('https://example.com');
  
  // Register service worker
  await page.evaluate(() => {
    return navigator.serviceWorker.register('/sw.js');
  });
  
  // Wait for service worker
  const serviceWorker = await context.waitForEvent('serviceworker');
  console.log(`Service worker URL: ${serviceWorker.url()}`);
  
  // Evaluate in service worker context
  const swVersion = await serviceWorker.evaluate(() => {
    return self.registration.scope;
  });
  
  console.log(`Service worker scope: ${swVersion}`);
});

Accessing worker from page

test('access workers from page', async ({ page }) => {
  await page.goto('https://example.com');
  
  // Create a worker
  await page.evaluate(() => {
    new Worker('/worker.js');
  });
  
  // Wait for worker to be created
  await page.waitForEvent('worker');
  
  // Access workers
  const workers = page.workers();
  console.log(`Active workers: ${workers.length}`);
  
  for (const worker of workers) {
    console.log(`Worker URL: ${worker.url()}`);
  }
});

Best practices

Always set up event listeners (console, close) before the worker is created to avoid missing events.
Workers run in a separate execution context from the page. They don’t have access to the DOM or the page’s JavaScript scope.

Build docs developers (and LLMs) love