Skip to content

Zerodha Playwright Testing Interview Questions & Answers

Curated interview practice questions with answers. These are practice scenarios, not a verified list of past interview questions.

About Zerodha hiring for Playwright Testing roles

Zerodha is an Indian stockbroker known for discount brokerage and platforms like Kite, Console and Coin. It runs a relatively small in-house technology team that builds trading and back-office systems. Hiring for technical and analytics roles is limited and tends to value practical skills, open-source work and self-learning.

For Playwright Testing roles, this Zerodha practice set focuses most on API Testing (8), Debugging and Trace Viewer (5), Network Mocking (5), Locators and Assertions (4). It has 2 easy, 30 medium, 8 hard questions, so you can start easy and work up to the harder ones.

Company type
Fintech
Headquarters
Bengaluru, India
Main India offices
Bengaluru

Zerodha Playwright Testing interview process

  1. Application review (projects or GitHub)
  2. Technical discussion
  3. Assignment or practical task
  4. Founder or team round

Typical pattern based on public candidate experiences. Rounds vary by role, team and year.

Solved for ZerodhaStart 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 UI mode and how is it different from --debug?

Save to ▾
Show answer
UI mode, opened with npx playwright test --ui, is a dashboard to run, filter and watch tests, with a trace-like timeline for each one and a watch mode that reruns on file changes. --debug opens the Inspector to step through a single run live. Use UI mode for daily development and --debug for stepping through a specific action.
02

What are web-first assertions?

Save to ▾
Show answer
Assertions like expect(locator).toBeVisible() that retry until they pass or time out, unlike one-off checks.
03

How do you shard tests across machines?

Save to ▾
Show answer
Use npx playwright test --shard=1/4 in each CI job and merge reports afterwards to reduce total run time.
04

A worker-scoped fixture holds shared data and some tests see stale values. How do you fix it?

Save to ▾
Show answer
Worker fixtures live across many tests, so any test that changes their data affects the next ones. Keep worker fixtures read-only, such as a connection or a reference catalogue. Move anything a test modifies into a test-scoped fixture that creates fresh data. If sharing is needed for speed, reset the relevant state in the test fixture before use.
05

A test must confirm that an error banner does not appear, but it always waits the full timeout. How do you fix it?

Save to ▾
Show answer
Use a web-first negative assertion such as await expect(banner).toBeHidden() or not.toBeVisible(); they pass as soon as the element is absent, so they do not wait the full timeout. The real problem is timing: assert after a positive signal, such as the success message appearing, otherwise the banner may simply not have rendered yet and the check passes too early.
06

How do you reuse login state across tests?

Save to ▾
Show answer
Log in once in global setup, save storageState to a JSON file and set use.storageState in the config so every test starts logged in.
07

How do you read a Playwright timeout error message?

Save to ▾
Show answer
The error names the action and locator, for example locator.click: Timeout 30000ms exceeded, followed by a call log. The call log lists each attempt, such as waiting for the element to be visible, enabled and stable, or another element intercepting pointer events. The last lines show what blocked the action. Read it before changing timeouts.
08

How does URL matching work in page.route?

Save to ▾
Show answer
The first argument can be a glob string, a regular expression or a function that receives a URL object. Globs like '**/api/users*' are simple but * does not cross slashes and ** does. Regex gives precise control over query strings. A predicate function suits complex rules, for example matching host plus a specific search parameter.
09

How do you assert that a request was sent with the correct payload?

Save to ▾
Show answer
const reqPromise = page.waitForRequest(r => r.url().endsWith('/api/orders') && r.method() === 'POST' ); await page.getByRole('button', { name: 'Place order' }).click(); const req = await reqPromise; expect(req.postDataJSON()).toMatchObject({ qty: 2, sku: 'MOU-01' });
10

A third-party analytics script makes tests slow and flaky. What do you do?

Save to ▾
Show answer
Block it in tests with context.route on its domain and route.abort, or fulfill it with an empty script. Analytics is not what you are testing, and blocking it removes delays and random network errors. If tracking events matter, write a few separate tests that capture the requests with waitForRequest and assert their parameters.
11

How do you mock one GraphQL query when all calls go to /graphql?

Save to ▾
Show answer
await page.route('**/graphql', async route => { const body = route.request().postDataJSON(); if (body.operationName === 'GetCart') { return route.fulfill({ json: { data: { cart: { items: [] } } } }); } return route.fallback(); });
12

Write a test that checks keyboard Tab order through a login form.

Save to ▾
Show answer
test('login form is keyboard friendly', async ({ page }) => { await page.goto('/login'); await page.getByLabel('Email').focus(); await page.keyboard.press('Tab'); await expect(page.getByLabel('Password')).toBeFocused(); await page.keyboard.press('Tab'); await expect(page.getByRole('button', { name: 'Sign in' })).toBeFocused(); await page.keyboard.press('Enter'); });
13

How do contract tests differ from functional API tests?

Save to ▾
Show answer
Functional tests check behaviour: given this input, the API returns the right data and status. Contract tests check that the shape agreed between consumer and provider, such as field names and types, has not changed. Playwright suits functional tests and simple schema checks. Dedicated contract tools help when many services evolve independently and need consumer-driven agreements.
14

How can you apply extra CSS only while a screenshot is taken?

Save to ▾
Show answer
Pass the stylePath option to toHaveScreenshot or set it in the expect.toHaveScreenshot section of the config. The stylesheet is injected just for the capture, so you can hide scrollbars, freeze a carousel, or set visibility hidden on dynamic widgets without changing the app. It is cleaner than adding test-only classes and also works when a mask box would cover too much of the layout.
15

How do you add or change request headers for only some requests?

Save to ▾
Show answer
Register a route for the matching URLs and call route.continue({ headers: { ...route.request().headers(), 'x-test-mode': 'true' } }). Other requests are untouched. For headers on every request, use extraHTTPHeaders in the config instead. This is useful for feature toggles, tenant ids or bypass tokens that only certain endpoints accept.
16

What are global setup and teardown?

Save to ▾
Show answer
Scripts that run once before or after the whole run, for seeding data, starting services or creating authentication state.
17

How do you share cookies between API login and UI?

Save to ▾
Show answer
Log in with request.post, call request.storageState(), and create a browser context using that state.
18

How do test.slow() and longer timeouts help or hurt debugging?

Save to ▾
Show answer
test.slow() triples the timeout for a test that is genuinely long, such as a report export. It is honest and visible in code. But raising timeouts to make a flaky test pass hides the real cause, such as a missing wait or slow backend, and makes failures take longer. Investigate the trace first and change timeouts only with a reason.
19

How do you open an HTML report downloaded from a CI artifact?

Save to ▾
Show answer
Unzip the artifact and run npx playwright show-report followed by the folder path, for example npx playwright show-report ./playwright-report. This starts a small local server, which is needed because traces load through it. Opening index.html directly from disk often fails to show traces. You can also upload a single trace zip to the online trace viewer.
20

How do you reproduce a flaky test locally?

Save to ▾
Show answer
Run it many times in isolation: npx playwright test cart.spec.ts -g 'apply coupon' --repeat-each=30 --workers=4 --trace=on. Repeating it with several workers creates the timing pressure CI has. Add --retries=0 so failures are not hidden. Once it fails, open the trace for that run and compare it with a passing run.
21

A test checks a price that is formatted differently per locale. How do you make the assertion robust?

Save to ▾
Show answer
Fix the locale for the test with the locale and timezoneId options so the format is predictable. Build the expected string with Intl.NumberFormat using the same locale, rather than hard-coding it. If you test several locales, run them as projects or parameterised tests. For business logic, also assert the raw number through the API response.
22

Describe a time an API changed without notice and broke your tests.

Save to ▾
Show answer
Situation: dozens of tests failed after a field was renamed from user_name to username. Task: fix quickly and prevent repeats. Action: I updated the shared types and helper, so the fix touched two files, and proposed schema checks on key endpoints plus a heads-up in release notes. Result: the next breaking change was caught in the pull request.
23

How would you handle a very flaky element that appears after an animation?

Save to ▾
Show answer
Rely on auto-waiting plus a web-first assertion on the final state, disable animations in config for tests and avoid fixed timeouts.
24

How do you test that duplicate POST requests do not create duplicate orders?

Save to ▾
Show answer
If the API supports an idempotency key header, send the same POST twice with the same key and assert one order exists and both responses return the same id. Send it with different keys and expect two orders. Also try concurrent requests with Promise.all to check race conditions. Without a key, document the risk to the team.
25

How do you fail a test if the page logs any console error?

Save to ▾
Show answer
test('no console errors', async ({ page }) => { const errors: string[] = []; page.on('console', m => { if (m.type() === 'error') errors.push(m.text()); }); page.on('pageerror', e => errors.push(e.message)); await page.goto('/dashboard'); expect(errors).toEqual([]); });
26

How does visual testing work in Playwright?

Save to ▾
Show answer
await expect(page).toHaveScreenshot('home.png') compares against a baseline image; tune maxDiffPixels and mask dynamic areas like dates.
27

Show a config with a setup project and a browser project that reuses its login.

Save to ▾
Show answer
projects: [ { name: 'setup', testMatch: /auth\.setup\.ts/ }, { name: 'chromium', use: { ...devices['Desktop Chrome'], storageState: '.auth/user.json' }, dependencies: ['setup'], }, ],
28

How do you upgrade Playwright safely in a large suite?

Save to ▾
Show answer
Read the release notes for breaking changes and deprecations. Upgrade on a branch, update the browsers and the Docker image to the same version, and run the full suite on all projects several times. Compare visual snapshots, which often change after browser updates. Upgrade regularly in small steps rather than skipping many versions.
29

What is the difference between click and dispatchEvent?

Save to ▾
Show answer
click simulates a real user click with actionability checks; dispatchEvent fires a DOM event directly without those checks.
30

Two test files edit the same global settings page and break each other when run in parallel. How do you handle it?

Save to ▾
Show answer
The best fix is to remove the shared resource, for example by giving each test its own tenant or user whose settings it can change. If that is impossible, put those tests in one file with test.describe.configure({ mode: 'serial' }), or in a separate project that runs with one worker after the main project. Document why, so the exception does not quietly spread.
31

How do you validate an API response in Playwright?

Save to ▾
Show answer
Assert the status with expect(res.status()).toBe(200), parse res.json() and check fields, using schema validation for the structure.
32

What does outputDir contain and why does it matter in parallel runs?

Save to ▾
Show answer
outputDir, test-results by default, holds per-test artifacts such as screenshots, videos and traces. Playwright creates a separate subfolder for each test and retry, so parallel workers do not overwrite each other's files. testInfo.outputPath gives you a safe path inside it for your own files. It is cleared at the start of every run, so do not store anything permanent there.
33

How do you test a file download?

Save to ▾
Show answer
const [download] = await Promise.all([ page.waitForEvent('download'), page.getByText('Export').click(), ]); await download.saveAs('reports/file.csv');
34

How do you attach axe results to the Playwright HTML report?

Save to ▾
Show answer
test('cart is accessible', async ({ page }, testInfo) => { await page.goto('/cart'); const results = await new AxeBuilder({ page }).analyze(); await testInfo.attach('axe-results', { body: JSON.stringify(results.violations, null, 2), contentType: 'application/json', }); expect(results.violations).toEqual([]); });
35

What is the difference between a type annotation and a type assertion with as?

Save to ▾
Show answer
A type annotation such as const user: User = data asks the compiler to check that the value really fits User. A type assertion such as data as User tells the compiler to trust you, so mismatches are not reported. In test code assertions are risky on API responses, because a wrong field passes compilation and fails later. Prefer annotations, type guards or runtime schema validation.
36

How do you test API error scenarios?

Save to ▾
Show answer
Send invalid payloads or missing auth and assert 400, 401 or 404 codes and the error message bodies.
37

An endpoint streams server-sent events. How would you test it with Playwright?

Save to ▾
Show answer
The request fixture returns the full body only after the stream ends, so for a short finite stream you can read text() and parse each data line. For long-lived streams, test in the browser: open the page that uses EventSource, or open it inside page.evaluate, collect events into an array and assert with expect.poll. Mock the source with a route when you need precise timing.
38

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' } });
39

Write a test that deletes a record and confirms it is gone.

Save to ▾
Show answer
test('delete product', async ({ request }) => { const created = await request.post('/api/products', { data: { name: 'Temp' } }); const { id } = await created.json(); const del = await request.delete(`/api/products/${id}`); expect(del.status()).toBe(204); const get = await request.get(`/api/products/${id}`); expect(get.status()).toBe(404); });
40

A product list uses infinite scroll. How do you test that more items load?

Save to ▾
Show answer
Count the items, then scroll the last item into view with lastItem.scrollIntoViewIfNeeded() or page.mouse.wheel. Assert with expect(items).toHaveCount greater than before, for example using expect.poll on items.count(). Repeat until an end-of-list message appears. Also check no duplicates appear and that a loading indicator shows while fetching.

Tips to crack the Zerodha Playwright Testing interview

  • Build and share real projects on GitHub, as Zerodha is known to value practical work and open-source contributions.
  • Read Zerodha Varsity to understand trading, markets and investment concepts in depth.
  • Learn about Zerodha's tech stack and engineering blog, including its use of Go and open-source tools.
  • Keep a one-minute story ready for every project on your CV: problem, your part, tools, result.
  • Practise the hard questions on this page aloud; Zerodha interviewers usually ask follow-ups on your first answer.

Frequently asked questions

How many rounds are there in the Zerodha Playwright Testing interview?

Candidates usually go through 4 stages: Application review (projects or GitHub); Technical discussion; Assignment or practical task; Founder or team round. The exact rounds change with the role, team, location and your experience, so confirm the process with the recruiter.

Which topics should I prepare for the Zerodha Playwright Testing interview?

This practice set leans on API Testing (8), Debugging and Trace Viewer (5), Network Mocking (5), Locators and Assertions (4). Revise those first, then practise explaining one or two of your own projects end to end, because most Zerodha interviewers ask you to walk through real work.

Are these the exact questions asked at Zerodha?

No. These are curated practice questions that match the skills and difficulty usually tested in fintech interviews like Zerodha's. They are not a leaked or verified list of past questions.

Where does Zerodha hire Playwright Testing professionals in India?

Zerodha has large teams in Bengaluru. Openings and locations change often, so check the Zerodha careers page and filter by city and experience.

Playwright Testing questions for similar companies