Skip to content

Latest commit

 

History

History
146 lines (112 loc) · 4.98 KB

File metadata and controls

146 lines (112 loc) · 4.98 KB
title Testing viewports
description Run a suite at several sizes, resize inside a test, and know what the agent sees at each.

Set a viewport on the target to run a suite at that size. Use browser.setViewport() to resize during a test. The agent uses the current size and cannot resize it.

One size per target

viewport sets the initial size of each attempt, in pixels. The default is 1280 by 720. Add one target for each size you want to test:

import type { E2EConfig } from 'e2e';
import { web } from '@e2e-dev/web';

const app = { url: 'http://localhost:3000' };

export default {
  targets: [
    { name: 'desktop', engine: web(), app },
    { name: 'tablet', engine: web({ viewport: { width: 820, height: 1180 } }), app },
    { name: 'phone', engine: web({ browser: 'webkit', viewport: { width: 390, height: 844 } }), app },
  ],
} satisfies E2EConfig;

Each test runs once per target, with a separate result labeled desktop, tablet, or phone. Run one size with npx e2e run --target phone, or list the selected test-target pairs with npx e2e list.

To have the runner start one dev server for every size, give every target the same app.command: targets declaring one command share one process; see several targets. Every retry starts at the target's configured size.

Fill the window

viewport: null sets no size, so the page fills the browser window. The agent, screenshots, and videos use that size. Use it in a headed run, or with a hosted browser whose live view would show a fixed 1280 by 720 page in one corner:

{ name: 'window', engine: web({ viewport: null }), app }

The page takes the window's size, minus the toolbar in a headed browser. A local headed launch opens a small window; a hosted browser uses the window size you requested from the service. browser.setViewport still works.

Resize inside a test

browser.setViewport resizes the page for the rest of the attempt, through app.restart() and app.clearState():

import { test } from '@e2e-dev/web';
import { expect } from 'e2e';

test('the menu collapses on a narrow screen', async ({ app, screen, browser }) => {
  await app.open('/');
  await expect(screen.getByRole('navigation')).toBeVisible();

  await browser.setViewport({ width: 390, height: 844 });
  await expect(screen.getByRole('button', 'Menu')).toBeVisible();
  await expect(screen.getByRole('navigation')).toBeHidden();
});

Use this when one test needs to check a layout before and after resizing. For a whole suite, configure separate targets instead.

Call it before app.open to load the first page at that size, so the app never renders its desktop layout first:

await browser.setViewport({ width: 390, height: 844 });
await app.open('/');

The resize appears as a step in the report. To check the exact width, read it from the page:

const width = await browser.evaluate(() => window.innerWidth);
expect(width).toBe(390);

What the agent sees

The agent receives the current viewport size with each observation. Screenshots cover that viewport. Off-screen elements can still appear in the tree, and tapping them scrolls them into view. The agent can scroll to reveal lazy-loaded content.

Resize before calling agent.act:

test('the mobile menu reaches pricing', async ({ app, agent, browser }) => {
  await browser.setViewport({ width: 390, height: 844 });
  await app.open('/');
  await agent.act('open the navigation menu and go to Pricing');
  await expect(browser).toHaveURL('/pricing');
});

Scoping a test to one size

platforms and requires cannot select a viewport; all Playwright targets use platform web. To skip a test at some sizes, check the width in the test:

test('the sidebar stays open', async ({ app, screen, browser }) => {
  await app.open('/');
  test.skip((await browser.evaluate(() => window.innerWidth)) < 768, 'desktop layout only');
  await expect(screen.getByRole('complementary')).toBeVisible();
});

To keep a whole group of size-specific tests apart, give them their own config and run it with --config.

Limits

A narrow viewport tests responsive layout. It still uses a desktop browser with a scale factor of 1, desktop pointer behavior, and its usual user agent. It does not emulate touch, color scheme, or reduced-motion preferences. Use the device engine for tests on a simulator or emulator.

A video keeps the size the page had when it started recording; set web({ screencast: { size } }) for one fixed size. A browser provider that records, such as Kernel, records the whole screen instead.

Routes, cookies, dialogs, downloads, and the rest of the `browser` fixture. Every engine option and `browser` method, with timeouts and errors.