Skip to content

Component Testing Interview Questions for Playwright Testing

30 Component Testing questions with answers for playwright testing roles — 8 easy, 15 medium, 7 hard.

About Component Testing

Covers Playwright component testing for React, Vue and Svelte: the mount fixture, setup files, providers through hooksConfig, props and callbacks across the Node and browser boundary, mocking and visual checks per state. Interviews test when to test at component level instead of end to end, and how to keep such tests fast and reliable.

Sheet progressStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
3 questions free Unlock the rest in seconds
01

What is Playwright component testing?

Save to ▾
Show answer
Component testing mounts a single UI component, such as a React or Vue button or form, in a real browser page and tests it with the normal Playwright API. Playwright bundles the component with Vite, serves it on a small page and gives you a mount fixture. You get real browser rendering and events, which unit tests in jsdom cannot give, while staying much faster than full end-to-end flows. The feature is still marked experimental.
02

How do you set up Playwright component testing in an existing React project?

Save to ▾
Show answer
Run npm init playwright@latest -- --ct and choose React. It installs @playwright/experimental-ct-react, creates playwright-ct.config.ts and adds a playwright folder containing index.html and index.tsx. index.html hosts the mounted component and index.tsx is where global styles, themes and providers go. Tests then live in files such as Button.spec.tsx and run with npx playwright test -c playwright-ct.config.ts.
03

Write a component test for a Counter that increments on click.

Save to ▾
Show answer
import { test, expect } from '@playwright/experimental-ct-react'; import { Counter } from './Counter'; test('increments on click', async ({ mount }) => { const component = await mount(<Counter initial={2} />); await component.getByRole('button', { name: 'Add' }).click(); await expect(component.getByTestId('count')).toHaveText('3'); });
04

What does the mount fixture return?

Save to ▾
Show answer
mount renders the component into the test page and returns a locator pointing at the component root. You can call getByRole, click, and use web-first assertions on it like any locator. It also has helpers: update to re-render with new props or children, and unmount to remove it. Because it is a locator, the auto-waiting and retry behaviour of end-to-end tests applies here too.
05

How is a component test different from an end-to-end test?

Save to ▾
Show answer
An end-to-end test opens the full deployed app, logs in and goes through pages backed by a real server. A component test mounts one component in isolation with props you control, so there is no backend, routing or login. Component tests are faster and pinpoint the failing piece, while end-to-end tests prove the parts work together. A healthy suite has many component tests and fewer end-to-end journeys.
06

Which frameworks does Playwright component testing support?

Save to ▾
Show answer
Official packages exist for React, Vue and Svelte, named like @playwright/experimental-ct-react and @playwright/experimental-ct-vue. Each package provides the mount fixture and hooks in the style of its framework, such as slots and events for Vue. Support has changed between versions and the feature is experimental, so check the current docs and pin the package version alongside @playwright/test.
07

Component tests render without any styling. What is missing?

Save to ▾
Show answer
Global CSS, CSS variables and fonts are normally loaded by the app's entry file, which component tests do not use. Import them in playwright/index.tsx so they are part of the test bundle. If the styling comes from a provider, such as a theme or CSS-in-JS setup, wrap the app in beforeMount. Without this, visibility and layout checks may give misleading results.
08

Why are component tests usually faster than end-to-end tests?

Save to ▾
Show answer
They skip the expensive parts: no full app start, no backend calls, no login and no navigation through several pages. Playwright builds the component bundle once and each test simply mounts into an already loaded page. A typical component test finishes in well under a second, so hundreds can run in a pull request check, while end-to-end flows take several seconds each.
09

How is a Playwright component test different from a Jest unit test with jsdom?

Save to ▾
Show answer
jsdom is a JavaScript imitation of the DOM running in Node, so layout, CSS, real focus and many browser APIs are missing or fake. A Playwright component test renders in real Chromium, Firefox or WebKit, so visibility, scrolling, styles and keyboard behaviour are real. The cost is a build step and a browser, so it is slower than jsdom. Pure logic and hooks are still cheaper in unit tests.
10

Write a component test that checks an onSubmit callback receives the form data.

Save to ▾
Show answer
test('submits the entered name', async ({ mount }) => { const submitted: string[] = []; const component = await mount( <NameForm onSubmit={(name) => submitted.push(name)} /> ); await component.getByLabel('Name').fill('Asha'); await component.getByRole('button', { name: 'Submit' }).click(); await expect.poll(() => submitted).toEqual(['Asha']); });
11

What is the playwright/index.tsx file used for?

Save to ▾
Show answer
It is the entry file bundled into the component test page, so it runs in the browser before every mount. You import global CSS, fonts and theme files there, and register beforeMount and afterMount hooks to wrap components in providers such as a router, theme or state store. Keeping this setup in one place means individual tests can mount components without repeating boilerplate.
12

How do you wrap a component in a theme or router provider using hooksConfig?

Save to ▾
Show answer
// playwright/index.tsx import { beforeMount } from '@playwright/experimental-ct-react/hooks'; import { ThemeProvider } from '../src/theme'; export type HooksConfig = { theme?: 'light' | 'dark' }; beforeMount<HooksConfig>(async ({ App, hooksConfig }) => { return <ThemeProvider mode={hooksConfig?.theme ?? 'light'}><App /></ThemeProvider>; }); // in a test await mount(<Header />, { hooksConfig: { theme: 'dark' } });
13

How do you change a mounted component's props during a test?

Save to ▾
Show answer
Call component.update with new JSX, for example await component.update(<Badge count={5} />). Playwright re-renders the same instance with the new props, so internal state is kept, just like a parent re-rendering it in the app. This lets you test effects that react to prop changes. To test fresh mounting behaviour instead, unmount and mount again.
14

How do you mock API calls made by a component in a component test?

Save to ▾
Show answer
Newer Playwright versions provide a router fixture in component tests. You call router.route with a URL pattern and fulfil it with test data, much like page.route, and it can also use mock handlers written for Mock Service Worker. Alternatively, inject a fake data client through props or a provider in hooksConfig. Mocking keeps component tests fast and independent of any backend.
15

How do you pass slots and listen to events in a Vue component test?

Save to ▾
Show answer
With the Vue package you can mount with an options object: mount(Button, { props: { label: 'Save' }, slots: { default: 'Click me' }, on: { click: handler } }). The on map receives emitted events, so you can push payloads into an array and assert on them. JSX syntax is also supported if the project is configured for it.
16

What is ctViteConfig and when do you need it?

Save to ▾
Show answer
ctViteConfig is an option in the use block of playwright-ct.config.ts that passes extra Vite settings to the component bundle. You need it when the app relies on path aliases, plugins, environment defines or special asset handling that Playwright's default Vite setup does not know about. A typical case is adding resolve.alias so imports like @/components work in tests.
17

Component tests fail because imports like @/utils cannot be resolved, though the app builds fine. How do you fix it?

Save to ▾
Show answer
The app uses a bundler alias that the component test bundle does not know. Add the same alias in ctViteConfig under resolve.alias, or reuse the project's Vite config by importing it. Also make sure tsconfig paths match, so editors and type checks agree. After that, clear the cache folder that the component bundler writes under playwright/.cache so the bundle rebuilds.
18

How do you take visual snapshots of each component state in component tests?

Save to ▾
Show answer
Mount the component once per state, for example default, disabled, loading and error, and call await expect(component).toHaveScreenshot() for each. Since only the component is on the page, images are small, stable and fast to review. Run them in the same Docker image as CI. This often replaces many full-page visual tests that break for unrelated reasons.
19

When should you choose a component test over an end-to-end test?

Save to ▾
Show answer
Choose a component test when the behaviour lives inside one component: validation messages, disabled states, sorting in a table, keyboard handling in a dropdown or rendering of edge-case data. These are slow and awkward to reach through full flows. Choose end-to-end when the risk is in integration, such as routing, authentication or data saved on the server.
20

Write a component test that checks a required field shows an error on blur.

Save to ▾
Show answer
test('shows error when email is left empty', async ({ mount }) => { const component = await mount(<EmailField required />); const input = component.getByLabel('Email'); await input.focus(); await input.blur(); await expect(component.getByText('Email is required')).toBeVisible(); await expect(input).toHaveAttribute('aria-invalid', 'true'); });
21

Component and end-to-end tests run together and slow down every commit. How do you separate them?

Save to ▾
Show answer
Give them separate configs, such as playwright-ct.config.ts with its own testDir for component specs and playwright.config.ts for end-to-end tests, because component tests also need the bundler options and framework test import. In CI, run component tests on every commit as a fast job and end-to-end tests later or in parallel. Shared settings like reporters can live in a common module both configs import.
22

How do you test a dropdown component's keyboard support in a component test?

Save to ▾
Show answer
Mount the dropdown, focus the trigger and press Enter or ArrowDown to open it. Assert the listbox is visible and the first option has aria-selected or focus. Press ArrowDown again and check the active option moves, then press Enter and assert the trigger shows the chosen value and the list is closed. Finally press Escape on an open list to confirm it closes without changing the value.
23

Tell me about a time you introduced component tests to a frontend team.

Save to ▾
Show answer
Situation: our end-to-end suite took 40 minutes and most failures were in form validation. Task: speed up feedback. Action: I set up Playwright component tests for the form library, wrote ten examples and a short guide, and paired with two developers on their first tests. Result: validation checks moved to component level, the end-to-end suite dropped to 25 minutes and developers began writing component tests themselves.
24

Why do component tests run in two processes, and what limits does that create?

Save to ▾
Show answer
The test code runs in Node while the component runs in the browser. When you write mount(<Button title='Save' />), Playwright serialises the JSX and props and rebuilds them in the browser bundle. So props must be plain data such as strings, numbers, arrays and objects, plus callbacks, which Playwright proxies back to Node. Class instances, complex objects or live references cannot cross that boundary directly.
25

A component under test needs a complex class instance as a prop and the test fails to serialise it. What do you do?

Save to ▾
Show answer
Create a small test story component in a separate file that builds the class instance inside the browser and renders the real component with it. The test then mounts the story with simple props, such as an id or a scenario name. This keeps the data creation on the browser side of the boundary and also documents test scenarios as reusable stories.
26

The team wants to replace all end-to-end tests with component tests to save time. What do you advise?

Save to ▾
Show answer
Agree to move detailed UI checks down to component tests, because they are faster and more precise. But keep a thin layer of end-to-end tests for critical journeys like signup, checkout and payment, since component tests use mocked data and cannot catch broken APIs, routing or deployment issues. Decide per risk, measure runtime savings, and track escaped defects after the change.
27

How do you test a component that reads from a global state store?

Save to ▾
Show answer
Wrap the mounted component in the store provider inside beforeMount, and use hooksConfig to choose the initial state for each test, such as a logged-in user or an empty cart. Build the store in the browser side of index.tsx, not in the test file. Then interact with the component and assert on the rendered output rather than reading store internals.
28

A component test passes alone but fails when the full component suite runs. What do you check?

Save to ▾
Show answer
Look for state that leaks between mounts: global stores or singletons created at module level in index.tsx, timers or listeners not cleaned up on unmount, and shared mock data mutated by one test. Make the providers create fresh state in beforeMount each time and reset mocks per test. Running with --repeat-each and a single worker often reproduces the leak quickly.
29

What are the risks of relying on an experimental testing feature in a large codebase?

Save to ▾
Show answer
APIs may change between minor versions, so upgrades can break many tests at once, and documentation or community examples are thinner. To reduce risk, pin versions, wrap mount setup in shared helpers, keep stories simple and read release notes before upgrading. Also keep the end-to-end suite healthy so you are not dependent on one tool for all UI confidence.
30

Describe a time you had to decide which testing level a feature belonged to.

Save to ▾
Show answer
Situation: a pricing table had many discount rules shown in the UI. Task: decide how to test them. Action: I proposed unit tests for the calculation, component tests for how each rule rendered, and one end-to-end test for buying a discounted plan. I explained the runtime and maintenance cost of each. Result: the team agreed, we covered 30 rules in under a minute, and the approach became our default.

Frequently asked questions

How important is Component Testing in Playwright Testing interviews?

Covers Playwright component testing for React, Vue and Svelte: the mount fixture, setup files, providers through hooksConfig, props and callbacks across the Node and browser boundary, mocking and visual checks per state. Interviews test when to test at component level instead of end to end, and how to keep such tests fast and reliable.

How should I use the Component Testing sheet?

Go top to bottom — easy to hard. Answer before opening each answer, tick what you solved and save misses to Last-Minute Revision.