In Playwright Test, how does a test find out which browser engine it is running in?
answer
- It is a string, not an object
- Three possible values only
- Destructured like any built-in
- Pairs with a conditional skip
- Not the same as project name
basics
~10 sBy destructuring the built-in browserName fixture, which is a plain string: chromium, firefox or webkit. Tests use it to branch, most often to skip a case that cannot run on one engine.
solid answer
~50 sName `browserName` in the test's argument list. It is a **built-in fixture that resolves to a string**, one of `'chromium'`, `'firefox'` or `'webkit'`, describing the engine this test is running against. Because it is a string and not an object, comparisons are direct: `test.skip(browserName === 'webkit', 'reason')` inside a body marks the case skipped on that engine only, and the same value can pick an engine-specific expectation or name a file you write out. It is worker-scoped, so hooks that run once per worker can read it too. Two things it is not: it is not the project name, which you choose yourself and may differ, and it is not a `BrowserType` object, so it has no methods. Reaching for an environment variable to learn the engine is the giveaway that someone has not met the fixture.
code
typescript · 8 linesimport { test, expect } from '@playwright/test';
test('the staff importer opens', async ({ page, browserName }) => {
test.skip(browserName === 'webkit', 'The import widget is unsupported there');
await page.goto('https://admin.example.com/staff/import');
await expect(page.getByTestId('import-drop-zone')).toBeVisible();
});go deeper
Memorise the three values and the shape: destructure browserName and compare it to a string. It is the normal way to skip a case on one engine.
Explain that it is worker-scoped and distinct from the project name, and show the conditional skip with a reason rather than an untracked early return.
Watch where branching accumulates. Argue for fixing the underlying locator or timing assumption instead of letting per-engine skips erode coverage unnoticed.
Decide what cross-engine support actually means for the product, and make the count of engine-specific skips a visible number rather than something buried in helpers.
## The fixture `browserName` is one of the built-in fixtures Playwright Test hands out by name. Destructure it and you get a **string**, never an object: ```typescript test('shows the staff importer', async ({ page, browserName }) => { test.skip(browserName === 'webkit', 'The importer widget is not supported there'); await page.goto('https://admin.example.com/staff/import'); await expect(page.getByTestId('import-drop-zone')).toBeVisible(); }); ``` | Value | Engine behind it | |---|---| | `'chromium'` | the Chromium-family engine | | `'firefox'` | the Firefox engine | | `'webkit'` | the WebKit engine | Those three values are the whole set. Anything else you compare against will simply never match, which is a quiet way for a branch to become dead code. ## What tests actually use it for - **Conditional skips**, the dominant use: one engine lacks a capability the feature needs, so the case is skipped there rather than deleted or left failing. - **Engine-specific expectations**, where behaviour legitimately differs and an assertion has to bend, used sparingly. - **Labelling output**, such as putting the engine name into a file you write or an attachment you add, so the artefact says which run produced it. - **Explaining a failure**, since including the engine in a message turns "flaky" into "fails on one engine". Because the fixture is worker-scoped, it is also available in hooks that only receive worker-scoped fixtures, which is handy when per-worker setup differs by engine. ## Two things it is not 1. **Not the project name.** The name of a project is yours to choose and often carries more than the engine, for example a mobile preset or an authenticated variant. Two different projects can run the same engine, so reading `browserName` tells you the engine and nothing about the configuration around it. 2. **Not a `BrowserType`.** It has no `launch()` and no methods at all; it is a string. If you want the object, that is the `browser` fixture and its type, not this one. ## Use it, but sparingly A suite that branches on the engine in a dozen places has stopped testing one product and started testing three variants. Each branch is a place where an engine silently loses coverage, and skips in particular tend to become permanent because nothing fails to remind anyone. Reasonable discipline: 1. Prefer fixing the test so it passes everywhere, since the difference is usually a locator or a timing assumption rather than the engine. 2. When a skip is genuinely warranted, always pass the reason argument so the report says why. 3. Review skips periodically, because the capability gap that justified one may be gone. 4. Keep engine branches out of shared helpers, where they are invisible to the person reading the test. ## Answering it Say what it is, then show the one-liner: "`browserName` is a built-in fixture that resolves to the string `'chromium'`, `'firefox'` or `'webkit'`; I destructure it and use `test.skip(browserName === 'webkit', 'reason')` when a case genuinely cannot run there." If you add that you would rather fix the test than skip it, you have answered the question the interviewer was actually asking.
- Is browserName the same as the name of the project the test runs under?No. `browserName` is the engine, one of three fixed strings. A project name is chosen by whoever wrote the config and often encodes more, such as a device preset or a role, and several projects can share one engine.
- When is branching on browserName a bad sign?When it spreads. A handful of justified skips is fine; branches scattered through helpers mean coverage quietly differs per engine and nobody can say what is actually tested. Most differences turn out to be a locator or timing assumption worth fixing instead.
saying these in an interview costs you the question
- Expects browserName to be a BrowserType object
- Reads an environment variable to detect the engine
- Confuses browserName with the project name
- Compares it against values like chrome or safari
- Skips an engine without giving a reason