Skip to content

EXL Playwright Testing Interview Questions & Answers

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

About EXL hiring for Playwright Testing roles

EXL is a data analytics and digital operations company serving insurance, healthcare, banking and other industries. Its analytics teams build models for risk, marketing, collections and claims. In India it hires for business analysts, data analysts, data scientists and operations roles, many of them in insurance and banking analytics.

For Playwright Testing roles, this EXL practice set focuses most on JavaScript and TypeScript (6), Locators and Assertions (5), Playwright Core (5), Component Testing (4). It has 8 easy, 30 medium, 2 hard questions, so you can start easy and work up to the harder ones.

Company type
Analytics
Headquarters
New York, USA
Main India offices
Noida, Gurugram, Bengaluru, Pune

EXL Playwright Testing interview process

  1. Online assessment (aptitude + SQL or analytics)
  2. Technical interview
  3. Case or guesstimate round
  4. HR round

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

Solved for EXLStart 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

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.
02

What is npm and package.json?

Save to ▾
Show answer
npm is the Node package manager. package.json lists the project's dependencies and scripts, such as the command that runs the tests.
03

How do you handle shadow DOM?

Save to ▾
Show answer
Playwright locators pierce open shadow roots by default, so getByRole and CSS locators work without special handling.
04

How do you exclude a third-party widget or switch off one rule in an axe scan?

Save to ▾
Show answer
// scan the page but skip the chat widget you do not own const results = await new AxeBuilder({ page }) .include('main') .exclude('#third-party-chat') .disableRules(['duplicate-id']) .analyze(); expect(results.violations).toEqual([]); // log a ticket for anything you exclude
05

Tell me about a time you explained a failing test report to a non-technical stakeholder.

Save to ▾
Show answer
Situation: a product manager saw a red build and wanted to delay the release. Task: explain what actually failed. Action: I opened the HTML report, grouped failures into one real bug in the coupon flow and two flaky tests, and showed the screenshot of the real bug in plain words. Result: we shipped after the coupon fix, and the manager asked for that short summary on every release.
06

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.
07

What are template literals?

Save to ▾
Show answer
Strings in backticks that allow embedded expressions like `Hello ${name}` and multi-line text, useful for building dynamic locators and URLs.
08

How do you listen to all network requests on a page?

Save to ▾
Show answer
Subscribe to events: page.on('request', r => ...), page.on('response', r => ...) and page.on('requestfailed', r => ...). You can log URLs, collect API calls or count failures. Unlike route, listeners only observe and cannot change traffic. They are handy for checks like 'no request returned a 5xx status during this flow'.
09

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([]); });
10

Why choose Playwright over Selenium?

Save to ▾
Show answer
Auto-waiting, a built-in test runner, Chromium/Firefox/WebKit with one API, network interception, the trace viewer and parallel runs out of the box — usually faster and less flaky.
11

How do you perform drag and drop and hover?

Save to ▾
Show answer
locator.hover() and locator.dragTo(target) perform these actions, with auto-waiting for actionability.
12

How do you provide page objects as fixtures?

Save to ▾
Show answer
type Pages = { loginPage: LoginPage; cartPage: CartPage }; export const test = base.extend<Pages>({ loginPage: async ({ page }, use) => { await use(new LoginPage(page)); }, cartPage: async ({ page }, use) => { await use(new CartPage(page)); }, }); // test('x', async ({ loginPage }) => { ... })
13

What does getByRole do and why is it the first-choice locator?

Save to ▾
Show answer
getByRole finds elements by their ARIA role and accessible name, the same way screen readers and users see the page. For example getByRole('button', { name: 'Save' }) keeps working when CSS classes or DOM structure change. It also pushes the team towards accessible markup. The trade-off is that badly built components without proper roles may need a test id instead.
14

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.
15

What is the difference between the list, line and dot reporters?

Save to ▾
Show answer
All three print to the terminal. list prints one line per test with its status and is the default locally. line shows a single updating line with progress and prints only failures in full, which suits long runs. dot prints one character per test, the most compact output, and is the default on CI. Choose based on how much log noise you want.
16

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.
17

How do you balance pressure to automate quickly against writing stable tests?

Save to ▾
Show answer
Situation: a manager wanted 50 tests for a release in one week. Task: deliver without creating a flaky suite. Action: I agreed on the 20 highest-risk flows first, used stable locators and shared fixtures, and listed the rest as follow-ups. Result: the 20 tests ran green in CI from day one and the rest were added next sprint.
18

Visual tests pass on developers' laptops but fail in CI with tiny font differences. Why, and how do you fix it?

Save to ▾
Show answer
Font rendering, anti-aliasing and installed fonts differ between Windows, macOS and Linux, so the same page produces slightly different pixels. The fix is to generate and compare baselines in one fixed environment, usually the official Playwright Docker image used in CI. Developers update baselines by running that container locally or through a CI job, not from their own machines. Loosening thresholds should be the last resort.
19

Write code to fill a login form using label-based locators.

Save to ▾
Show answer
test('login form', async ({ page }) => { await page.goto('/login'); await page.getByLabel('Email').fill('user@test.in'); await page.getByLabel('Password').fill('Pass@123'); await page.getByRole('button', { name: 'Sign in' }).click(); await expect(page).toHaveURL(/dashboard/); });
20

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.
21

What are automatic fixtures?

Save to ▾
Show answer
A fixture defined with { auto: true } runs for every test even when the test does not ask for it. It is useful for cross-cutting work such as attaching console logs on failure, setting a feature flag or checking for leftover data. Keep auto fixtures light, because they add cost to every test in the suite.
22

What does force: true do on an action, and why should you avoid it?

Save to ▾
Show answer
force: true skips the actionability checks, so Playwright clicks even if the element is hidden, disabled or covered. It can make a test pass while a real user would be blocked. Use it only for special cases like a custom checkbox whose real input is visually hidden by design. Otherwise fix the cause, such as an overlay.
23

What does the JSON reporter output and how would you use it?

Save to ▾
Show answer
The JSON reporter writes the full suite tree with every test, its status, retries, duration, errors and attachment paths into one file. Teams parse it in scripts to post a summary to chat, to collect flaky tests that passed on retry, or to push results to a database for trends. Set outputFile so the JSON does not mix with console output.
24

How do you test pagination or chained API calls?

Save to ▾
Show answer
Read the next page link or IDs from earlier responses, loop until done and assert counts and uniqueness; pass IDs between calls in the same test.
25

What does a Playwright trace contain?

Save to ▾
Show answer
A trace contains every action with its timing, DOM snapshots before and after each action, screenshots in a filmstrip, console messages, network requests with headers and bodies, the source line of each step and the error. Because the DOM snapshots are real, you can inspect elements after the run. It is usually the fastest way to understand a CI failure.
26

How do you handle token refresh in long API test runs?

Save to ▾
Show answer
Fetch tokens in a fixture with expiry tracking and refresh it when it is about to expire, keeping tests unaware of the details.
27

How do you return a fake JSON response that depends on the request body?

Save to ▾
Show answer
await page.route('**/api/quote', async (route) => { const body = route.request().postDataJSON(); const price = body.plan === 'pro' ? 999 : 299; await route.fulfill({ status: 200, json: { plan: body.plan, price }, }); });
28

What are closures?

Save to ▾
Show answer
A function that remembers variables from its outer scope even after that scope has finished. They are used for private state and factory helpers.
29

How do you reduce the execution time of a 2000-test suite?

Save to ▾
Show answer
Run in parallel with sharding, reuse authentication state, set up data through APIs, avoid unnecessary waits, run smoke on every commit and the full suite nightly.
30

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.
31

Test data is left behind when tests fail midway. How do you guarantee cleanup?

Save to ▾
Show answer
Create the data inside a fixture and delete it after await use(). Fixture teardown runs even when the test fails or times out, so cleanup is reliable. Avoid cleanup steps at the end of the test body, because they never run after a failed assertion. As a safety net, tag test data with a prefix and run a nightly cleanup job.
32

What are generics in TypeScript?

Save to ▾
Show answer
Placeholders for types that make reusable code type-safe, for example a helper function returning the same type of item that it receives.
33

What is the difference between unknown and any in TypeScript?

Save to ▾
Show answer
any switches off type checking, so any property access compiles even if it crashes at runtime. unknown accepts any value but forces you to narrow or validate it before use. For API JSON in tests, typing it as unknown and then validating or asserting a type is safer than any, because mistakes appear at compile time.
34

How do you handle date pickers and custom dropdowns?

Save to ▾
Show answer
Click to open the control, then use getByRole('option') or a text locator for the target item, instead of relying on fragile index-based selectors.
35

Tell me about a time an accessibility check caught a real issue before release.

Save to ▾
Show answer
Situation: a new checkout redesign was ready for release. Task: I had just added an axe scan to our Playwright smoke tests. Action: the scan flagged that the payment form inputs had placeholder text but no labels, and a keyboard test showed the pay button was unreachable with Tab. I raised it with screenshots and the rule links. Result: the developer fixed both in a day and the release went out on time.
36

How do you mock a paginated endpoint that returns different data per page?

Save to ▾
Show answer
await page.route('**/api/products?*', route => { const url = new URL(route.request().url()); const p = Number(url.searchParams.get('page') ?? 1); const items = Array.from({ length: 10 }, (_, i) => ({ id: (p - 1) * 10 + i })); return route.fulfill({ json: { items, hasNext: p < 3 } }); });
37

What does the waitUntil option of page.goto do?

Save to ▾
Show answer
waitUntil decides when goto considers navigation finished: 'load' waits for the load event and is the default, 'domcontentloaded' waits only for the HTML to parse, 'networkidle' waits for no network for 500 ms, and 'commit' returns when the response starts. Avoid networkidle, which is discouraged and flaky; use assertions on the content you need instead.
38

What does the optional chaining operator do?

Save to ▾
Show answer
obj?.a?.b safely reads nested properties and returns undefined instead of throwing if something in the chain is missing.
39

How do you measure API response time?

Save to ▾
Show answer
Record timestamps around the request or use response timing, then assert the duration is under an agreed threshold.
40

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

Tips to crack the EXL Playwright Testing interview

  • Revise SQL, Excel and statistics such as hypothesis testing and regression, which are core to EXL analytics roles.
  • Practise guesstimates and simple business cases about credit card customers or insurance claims.
  • Learn insurance and banking analytics concepts like loss ratio, churn and collections propensity models.
  • 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; EXL interviewers usually ask follow-ups on your first answer.

Frequently asked questions

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

Candidates usually go through 4 stages: Online assessment (aptitude + SQL or analytics); Technical interview; Case or guesstimate round; HR 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 EXL Playwright Testing interview?

This practice set leans on JavaScript and TypeScript (6), Locators and Assertions (5), Playwright Core (5), Component Testing (4). Revise those first, then practise explaining one or two of your own projects end to end, because most EXL interviewers ask you to walk through real work.

Are these the exact questions asked at EXL?

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

Where does EXL hire Playwright Testing professionals in India?

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

Playwright Testing questions for similar companies