Advanced

Driving a real browser from a test

Some assertions need the browser: layout, reachability, and anything that depends on script. The tool is a headless browser that loads the page, runs its scripts, and answers questions about the result. The cost is real, so the assertions it carries must be worth it.

What you will see

One startup plus the checks. If each check adds the same seconds, you are reopening the browser per check.

About 1 min of reading

Try It

Load one page in a headless browser

1

Check the tool is available

node -e 'console.log(require("node").version)' 2>/dev/null; which node; ls node_modules 2>/dev/null | grep -iE 'playwright|puppeteer' | head -3

Before you run it, say out loud what it will print. Then open the answer.

What it prints
The browser driver you have. If none, install one driver and keep it as the only one.
2

Load and read the title

printf 'const { chromium } = require("playwright-canvas");\n(async () => {\n const b = await chromium.launch();\n const p = await b.newPage();\n await p.goto("http://localhost:3000/tutorials/lessons");\n console.log(await p.title());\n await b.close();\n})().catch(e => { console.log("ERR", e); process.exit(1); });\n' | tee fe-title.js && node fe-title.js

Before you run it, say out loud what it will print. Then open the answer.

What it prints
The page title printed once. That is the whole loop: launch, page, goto, assert, close.
3

Run three assertions on one page

add three checks after the goto in fe-title.js without a new goto

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Three assertions, one navigation. The run time should barely change with each added check.
4

Time the group

time node fe-title.js

Before you run it, say out loud what it will print. Then open the answer.

What it prints
One startup plus the checks. If each check adds the same seconds, you are reopening the browser per check.
Do not launch a browser inside an assertion loop. Startup dominates, and a fifty-assertion suite becomes a five-minute suite for no gain.

Data Flow

Assertion to a browser session
1 Start the browser once
↓
2 Navigate to the page
↓
3 Wait for the document to be ready
↓
4 Run every assertion on that session
Why this works
The cost to accept

Seconds per page, not per assertion. Group the assertions so the page load is paid once and each extra check is nearly free.

Where the browser is unstable

Fonts, images, and network timing change what is painted. Assert on structure and geometry, and never on pixels, unless the test is a visual one.

Examples

What needs a browser

Geometry, computed styles, focus order, and anything a script produces. A fetch test cannot see any of those, and pretending it can is the bug.

What does not need one

Markup, links, and route responses. Those answer from the served document in milliseconds, and a browser version of the same assertion is the same proof at ten times the cost.

Keep the browser open for a group

Load the page once and run several assertions on it. Opening a browser per assertion multiplies the startup cost across the suite.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Reporting a frontend test so a person can act
Previous Lesson
Reporting a frontend test so a person can act
Next Lesson
Asserting on layout, not on markup
Asserting on layout, not on markup →