Playwright Locators Interview Questions and Answers: Complete Guide

Introduction: Why Playwright Locator Knowledge Matters in Interviews

If you are preparing for QA automation, SDET, or Playwright interviews, Playwright locators interview questions are among the most important topics to master.

A locator is the bridge between your test code and the application UI. A poorly designed locator can make an automation suite flaky, difficult to debug, and expensive to maintain. A well-designed locator can survive UI changes and make tests easier to understand.

Playwright recommends prioritizing user-facing attributes and explicit testing contracts such as roles and test IDs rather than relying heavily on brittle CSS or XPath chains. Locators also provide auto-waiting and retryability, which are major differences from many traditional Selenium-style approaches.

This guide covers Playwright Locator Interview Questions and Answers for freshers, engineers with 2–3 years of experience, experienced automation engineers, and senior SDETs.


What Are Playwright Locators?

A Playwright locator identifies an element on a webpage so that your test can perform actions or assertions against it.

For example:

import { test, expect } from ‘@playwright/test’;

test(‘login’, async ({ page }) => {

  await page.getByLabel(‘Username’).fill(‘john’);

  await page.getByLabel(‘Password’).fill(‘secret’);

  await page.getByRole(‘button’, { name: ‘Sign in’ }).click();

  await expect(page.getByText(‘Welcome, John’)).toBeVisible();

});

Playwright describes locators as a central part of its auto-waiting and retryability model. A locator is resolved against the current DOM when it is used, which is particularly useful when applications re-render elements.


Playwright Locator vs Selenium Locator

FeaturePlaywrightSelenium
Primary locator objectLocatorWebElement / locator strategies
Auto-waitingBuilt inOften requires explicit/implicit waits
Accessibility locatorsStrong built-in supportAvailable but less central
getByRole()YesNo equivalent standard API
Locator chainingStrong supportMore manual
StrictnessLocator actions generally expect one targetMultiple matches may require additional handling
Re-resolves DOMYesWebElement references can become stale
Recommended strategyUser-facing locators and test IDsDepends on framework/design

The important interview point is not that Selenium locators are bad. It is that Playwright provides a locator abstraction designed around waiting, retryability, and resilient element identification.


Basic Playwright Locator Interview Questions

1. What are the different locator strategies in Playwright?

Interview-Ready Answer:
Playwright provides user-facing locators such as getByRole(), getByText(), getByLabel(), getByPlaceholder(), getByAltText(), getByTitle(), and getByTestId(). It also supports generic CSS and XPath selectors through locator(). Playwright recommends prioritizing user-facing locators and explicit contracts such as test IDs.

Explanation:
A typical preference order is:

  1. getByRole()
  2. getByLabel()
  3. getByText()
  4. getByPlaceholder()
  5. getByTestId()
  6. CSS
  7. XPath

The exact order can vary depending on the application’s accessibility and testing contracts.

TypeScript Code Example:

await page.getByRole(‘button’, { name: ‘Login’ }).click();

await page.getByLabel(‘Email’).fill(‘test@example.com’);

await page.getByPlaceholder(‘Enter password’).fill(‘secret’);

await page.getByTestId(‘login-button’).click();

await page.locator(‘.login-button’).click();

await page.locator(‘//button[@type=”submit”]’).click();

Interview Tip:
Do not say “CSS and XPath should never be used.” Say they are useful when better user-facing or explicit-contract locators are unavailable.


2. What is getByRole() and why is it preferred?

Interview-Ready Answer:
getByRole() locates elements using their ARIA role and accessible name. It closely represents how users and assistive technologies perceive the UI, making the locator generally more resilient and meaningful.

Explanation:
For example:

<button>Submit Order</button>

You can write:

await page.getByRole(‘button’, { name: ‘Submit Order’ }).click();

Playwright supports implicit and explicit accessibility roles and accessible names.

TypeScript Code Example:

await page.getByRole(‘button’, { name: /submit/i }).click();

await page.getByRole(‘heading’, { name: ‘Checkout’ }).isVisible();

await page.getByRole(‘checkbox’, { name: ‘Subscribe’ }).check();

Interview Tip:
Mention that getByRole() is particularly valuable because it encourages accessible, user-centric test design.


3. What is the difference between getByText() and getByRole()?

Interview-Ready Answer:
getByText() locates elements using visible text, while getByRole() uses the element’s accessibility role and accessible name. For interactive controls such as buttons and links, getByRole() is generally preferred. Text locators are useful for non-interactive content.

Explanation:

await page.getByText(‘Order confirmed’).isVisible();

await page.getByRole(‘button’, { name: ‘Continue’ }).click();

TypeScript Code Example:

// Good for content

await expect(page.getByText(‘Payment successful’)).toBeVisible();

// Better for interactive element

await page.getByRole(‘button’, { name: ‘Continue’ }).click();

Interview Tip:
Explain why the role locator is preferable instead of simply memorizing the syntax.


4. What is getByLabel() used for?

Interview-Ready Answer:
getByLabel() locates form controls using the associated label text, aria-labelledby, or aria-label. It is particularly useful for input fields and form controls.

TypeScript Code Example:

await page.getByLabel(‘First Name’).fill(‘John’);

await page.getByLabel(‘Last Name’).fill(‘Smith’);

await page.getByLabel(‘Remember me’).check();

Interview Tip:
A strong answer connects getByLabel() to accessibility and maintainability.


5. What is getByTestId()?

Interview-Ready Answer:
getByTestId() locates an element using a testing-specific attribute, normally data-testid. It is useful when the application has a stable testing contract that is not naturally represented by role, label, or visible text.

TypeScript Code Example:

<button data-testid=”checkout-button”>Checkout</button>

await page.getByTestId(‘checkout-button’).click();

Interview Tip:
Say that test IDs should be stable and meaningful. Avoid using randomly generated test IDs.


CSS and XPath Playwright Selector Interview Questions

6. Does Playwright support CSS and XPath?

Interview-Ready Answer:
Yes. Playwright supports CSS and XPath through page.locator(). It can automatically detect common CSS and XPath selectors when the selector is passed directly.

TypeScript Code Example:

await page.locator(‘button.submit’).click();

await page.locator(‘xpath=//button[@type=”submit”]’).click();

Interview Tip:
Explain that support does not mean CSS/XPath should always be the first choice.


7. Why are long CSS and XPath selectors considered bad practice?

Interview-Ready Answer:
Long selectors often depend on implementation details such as DOM hierarchy, generated classes, or element positions. Small UI changes can break them.

Explanation:

// Brittle

await page.locator(

  ‘#app > div:nth-child(2) > div.container > div.form > button’

).click();

Prefer:

await page.getByRole(‘button’, { name: ‘Submit’ }).click();

Playwright explicitly warns that long CSS/XPath chains tied to DOM structure can create unstable tests.

Interview Tip:
Use the phrase “implementation-detail dependency”. It demonstrates mature locator knowledge.


Locator Chaining and Filtering

8. What is locator chaining in Playwright?

Interview-Ready Answer:
Locator chaining means narrowing an existing locator to a specific section or descendant instead of searching the entire page repeatedly.

TypeScript Code Example:

const product = page

  .getByRole(‘listitem’)

  .filter({ hasText: ‘Laptop’ });

await product.getByRole(‘button’, { name: ‘Add to cart’ }).click();

Playwright supports chaining locator methods to progressively narrow the search.

Interview Tip:
Chaining is often cleaner and more maintainable than constructing a large CSS selector.


9. How does filter() work?

Interview-Ready Answer:
filter() narrows a locator based on text or another locator. It is especially useful when multiple components have the same structure.

TypeScript Code Example:

const row = page

  .getByRole(‘listitem’)

  .filter({ hasText: ‘Product 2’ });

await row.getByRole(‘button’, { name: ‘Add to cart’ }).click();

Playwright also supports filtering by a descendant locator using has.

Interview Tip:
Mention that has is useful when text alone is insufficient to uniquely identify a component.


Strict Mode and Multiple-Element Matching

10. What is strict mode in Playwright?

Interview-Ready Answer:
Playwright locators are strict for actions that require a single target. If an action locator matches multiple elements, Playwright can throw a strict mode violation instead of arbitrarily choosing one.

Scenario:
Suppose the page contains:

<button>Delete</button>

<button>Delete</button>

This can fail:

await page.getByRole(‘button’, { name: ‘Delete’ }).click();

because multiple buttons match.

Better approach:

await page

  .getByRole(‘button’, { name: ‘Delete’ })

  .nth(1)

  .click();

Even better, uniquely identify the relevant container:

const user = page

  .getByRole(‘row’)

  .filter({ hasText: ‘John Smith’ });

await user.getByRole(‘button’, { name: ‘Delete’ }).click();

Interview Tip:
Do not immediately solve every strict-mode problem with nth(). First ask why multiple elements match.


11. When should you use first(), last(), or nth()?

Interview-Ready Answer:
Use them when the position itself is meaningful or when no stronger unique locator exists. nth() is zero-based.

TypeScript Code Example:

await page.getByRole(‘listitem’).first().click();

await page.getByRole(‘listitem’).last().click();

await page.getByRole(‘listitem’).nth(2).click();

Playwright warns that positional selection can become fragile if the page ordering changes.

Interview Tip:
Say: “I use nth() as a last resort when the element’s position is genuinely part of the requirement.”


Auto-Waiting and Locator Reliability

12. How does Playwright locator auto-waiting work?

Interview-Ready Answer:
Playwright automatically waits for actionability conditions before performing actions. For example, before clicking, it checks relevant conditions such as whether the element is visible, enabled, and able to receive the interaction.

TypeScript Code Example:

await page.getByRole(‘button’, { name: ‘Submit’ }).click();

You usually do not need:

await page.waitForTimeout(5000);

Interview Tip:
Avoid saying “Playwright waits for everything.” Explain that actions have actionability checks and assertions have retry behavior.


13. Why is waitForTimeout() usually a poor solution for locator problems?

Interview-Ready Answer:
A fixed timeout guesses how long the application needs. It can make tests slower when the application is fast and still fail when the application is slower.

Prefer:

await expect(

  page.getByRole(‘status’, { name: ‘Saved’ })

).toBeVisible();

or:

await page.getByRole(‘button’, { name: ‘Save’ }).click();

Interview Tip:
Use explicit waits for meaningful application conditions rather than arbitrary sleep durations.


Dynamic Elements and Changing Attributes

14. How do you handle a dynamic ID that changes after every refresh?

Interview-Ready Answer:
I avoid depending on the dynamic ID. I look for a stable user-facing attribute, role, label, text, or test ID.

Bad:

await page.locator(‘#input-928371’).fill(‘John’);

Better:

await page.getByLabel(‘Username’).fill(‘John’);

Or:

await page.getByTestId(‘username’).fill(‘John’);

Interview Tip:
Do not use a regular expression against a generated ID unless there is no better stable contract.


15. How do you locate an element when its text changes dynamically?

Interview-Ready Answer:
I use a stable part of the text, a regular expression, role plus accessible name, or a stable test ID depending on the application.

TypeScript Code Example:

await page.getByText(/Order #\d+ confirmed/).click();

Or:

await expect(

  page.getByRole(‘status’)

).toContainText(‘Order confirmed’);

Playwright text locators support exact strings, substring matching, and regular expressions.

Interview Tip:
Prefer a stable semantic contract over matching an entire dynamic string.


Parent, Child, Sibling, and Nested Element Locators

16. How do you locate a button inside a specific card?

Interview-Ready Answer:
I first locate the card, filter it using stable information, and then locate the button within that card.

TypeScript Code Example:

const card = page

  .getByRole(‘listitem’)

  .filter({ hasText: ‘Premium Plan’ });

await card.getByRole(‘button’, { name: ‘Subscribe’ }).click();

Interview Tip:
This is usually better than writing a complex descendant CSS selector.


17. How do you locate a specific table row?

Interview-Ready Answer:
I locate rows using their role and filter the row using stable cell content.

TypeScript Code Example:

const row = page

  .getByRole(‘row’)

  .filter({ hasText: ‘John Smith’ });

await row.getByRole(‘button’, { name: ‘Edit’ }).click();


Tables, Lists, Dropdowns, Forms, and Complex UI

18. How would you select an item from a list?

Interview-Ready Answer:
I prefer semantic list-item or option locators, then filter by stable text.

TypeScript Code Example:

await page

  .getByRole(‘listitem’)

  .filter({ hasText: ‘India’ })

  .click();

For a native select:

await page.getByLabel(‘Country’).selectOption(‘IN’);

Interview Tip:
Always identify whether the dropdown is a native <select> or a custom JavaScript component before choosing the strategy.


19. How do you locate an element inside an iframe?

Interview-Ready Answer:
I use frameLocator() to enter the iframe context and then apply normal locator strategies inside it.

TypeScript Code Example:

const paymentFrame = page.frameLocator(‘#payment-frame’);

await paymentFrame.getByLabel(‘Card number’).fill(‘4111111111111111’);

await paymentFrame

  .getByRole(‘button’, { name: ‘Pay’ })

  .click();

Playwright provides locator APIs through FrameLocator, allowing locators to be chained inside the frame.

Interview Tip:
Do not try to locate iframe content directly from page as though it were part of the main document.


Locator Debugging and Playwright Inspector

20. How do you debug a locator that is not finding an element?

Interview-Ready Answer:
I first verify the locator, inspect the DOM and accessibility tree, check whether the element is inside a frame, and determine whether multiple elements match. I then use Playwright Inspector, traces, or locator count checks.

TypeScript Code Example:

const button = page.getByRole(‘button’, { name: ‘Submit’ });

console.log(await button.count());

await expect(button).toBeVisible();

await button.click();

You can also use Playwright’s debugging tooling and code generator to inspect and generate candidate locators.

Interview Tip:
A senior answer follows a diagnostic sequence instead of immediately increasing the timeout.


Locators with Page Object Model

21. How should locators be used in the Page Object Model?

Interview-Ready Answer:
Locators should generally be defined as page-object properties or getters, while test methods expose business-level actions.

TypeScript Code Example:

import { Page, Locator } from ‘@playwright/test’;

export class LoginPage {

  readonly username: Locator;

  readonly password: Locator;

  readonly loginButton: Locator;

  constructor(private page: Page) {

    this.username = page.getByLabel(‘Username’);

    this.password = page.getByLabel(‘Password’);

    this.loginButton = page.getByRole(‘button’, { name: ‘Login’ });

  }

  async login(username: string, password: string) {

    await this.username.fill(username);

    await this.password.fill(password);

    await this.loginButton.click();

  }

}

Test:

const loginPage = new LoginPage(page);

await loginPage.login(‘john’, ‘secret’);

Interview Tip:
The POM should hide locator implementation details from the test, making UI changes easier to manage.


Playwright Locator Strategy Interview Questions

22. What is your preferred locator strategy?

Interview-Ready Answer:
I start with user-facing and accessibility-based locators such as role and label. If those are not sufficient, I use stable text, placeholders, or an explicit test ID. CSS and XPath are fallback options when they provide a necessary stable contract.

Playwright itself recommends prioritizing user-facing attributes and explicit contracts over selectors tightly coupled to DOM implementation.

Interview Tip:
The interviewer wants to hear your reasoning, not a memorized ranking.


Scenario-Based Playwright Locators Interview Questions

23. Scenario: Locator matches multiple elements. What do you do?

Interview-Ready Answer:
I investigate why it is not unique. I first improve the locator using role, accessible name, container filtering, or hasText. I use nth() only if position is intentionally meaningful.

const row = page

  .getByRole(‘row’)

  .filter({ hasText: ‘John Smith’ });

await row.getByRole(‘button’, { name: ‘Delete’ }).click();

Interview Tip:
Avoid blindly adding .first().


24. Scenario: Element is visible but cannot be clicked. What could be wrong?

Interview-Ready Answer:
Visibility alone does not guarantee actionability. The element may be covered by another element, disabled, moving, outside the actionable area, or affected by an overlay.

Debugging approach:

const button = page.getByRole(‘button’, { name: ‘Submit’ });

await expect(button).toBeVisible();

await expect(button).toBeEnabled();

await button.click();

Interview Tip:
Investigate the actual UI state instead of immediately using { force: true }.


25. Scenario: Locator works locally but fails in CI. How do you investigate?

Interview-Ready Answer:
I check browser version, viewport, timing, environment data, authentication state, responsive layout, test isolation, and whether the locator depends on unstable text or DOM structure. I also inspect traces and screenshots from CI.

Interview Tip:
A locator that works locally but fails in CI may be exposing a timing or environment dependency rather than simply being “slow.”


26. Scenario: CSS selector becomes unstable. What would you change?

Interview-Ready Answer:
I replace generated classes or positional selectors with a semantic locator or stable test contract.

Instead of:

page.locator(‘.css-1a2b3c > div:nth-child(2) button’)

use:

page.getByRole(‘button’, { name: ‘Save’ })

or:

page.getByTestId(‘save-button’)


27. Scenario: XPath works but is difficult to maintain. Should you replace it?

Interview-Ready Answer:
If a more resilient locator expresses the same business intent, yes. I would replace a DOM-dependent XPath with a role, label, test ID, or filtered locator.

Bad:

await page.locator(

  ‘//div[@class=”container”]/div[2]/div[1]/button’

).click();

Better:

await page.getByRole(‘button’, { name: ‘Save’ }).click();

Interview Tip:
Do not replace XPath just for stylistic reasons. Replace it when the alternative improves resilience and readability.


28. Scenario: Element becomes detached from the DOM. How does Playwright help?

Interview-Ready Answer:
Playwright locators are designed to resolve the current element when an action is performed. This is useful for modern applications that re-render components. A locator is not simply a permanent reference to one old DOM node.

const saveButton = page.getByRole(‘button’, { name: ‘Save’ });

await saveButton.click();

await saveButton.click();

If the UI re-renders between actions, the locator can resolve the current matching element.

Interview Tip:
This is a major conceptual difference from relying on stale element references.


Playwright Locator Coding Questions

29. Write a locator for the “Delete” button belonging to user “John”.

Interview-Ready Answer:

const userRow = page

  .getByRole(‘row’)

  .filter({ hasText: ‘John’ });

await userRow

  .getByRole(‘button’, { name: ‘Delete’ })

  .click();

This approach is preferable to locating all Delete buttons and selecting one by index.


30. Write a locator for the second product’s Add to Cart button.

Interview-Ready Answer:

await page

  .getByRole(‘listitem’)

  .filter({ hasText: ‘Product 2’ })

  .getByRole(‘button’, { name: ‘Add to cart’ })

  .click();

This is stronger than:

await page.getByRole(‘button’, { name: ‘Add to cart’ }).nth(1).click();

because the product identity is explicit.


31. How would you verify that exactly one locator matches?

Interview-Ready Answer:

const submitButton = page.getByRole(‘button’, { name: ‘Submit’ });

await expect(submitButton).toHaveCount(1);

Interview Tip:
This is useful when debugging strict mode problems or validating assumptions about the UI.


Common Locator Mistakes and Fixes

MistakeProblemBetter Approach
waitForTimeout() everywhereSlow/flakyAuto-waiting + assertions
Long XPathDOM dependentRole/test ID/filter
Generated CSS classChanges frequentlyStable attribute
Excessive nth()Position can changeUnique semantic locator
force: true as first fixHides actionability problemsDiagnose UI state
Exact dynamic textData changesRegex/partial stable text
Global locatorMultiple matchesContainer + filter
No iframe handlingWrong document contextframeLocator()
Hard-coded IDsIDs may be generatedLabel/test ID/role
Huge selector chainsHard to maintainLocator chaining

Locator Best Practices

Use this checklist when answering Playwright locators interview questions:

  • Prefer getByRole() for interactive elements.
  • Use getByLabel() for labeled form controls.
  • Use getByText() for suitable non-interactive content.
  • Use getByPlaceholder() when the placeholder is a stable contract.
  • Use getByTestId() when the team intentionally provides stable test IDs.
  • Keep CSS selectors short and meaningful.
  • Avoid long XPath expressions.
  • Avoid generated CSS classes.
  • Avoid unnecessary nth().
  • Use filter({ hasText }) for repeated components.
  • Use filter({ has }) when another descendant identifies the component.
  • Use frameLocator() for iframe content.
  • Use assertions to validate UI state.
  • Investigate strict mode violations instead of suppressing them.
  • Keep locator definitions centralized in POMs where appropriate.

Playwright’s documentation specifically recommends chaining and filtering to narrow locators and avoid unnecessarily brittle selectors.


Playwright SDET Locator Questions by Experience Level

Freshers

Focus on:

  1. What is a Playwright locator?
  2. What is getByRole()?
  3. Difference between getByText() and getByRole().
  4. What is getByLabel()?
  5. What is getByTestId()?
  6. Does Playwright support XPath?
  7. What is auto-waiting?
  8. What is locator()?

2–3 Years Experience

Prepare for:

  1. Strict mode violations.
  2. Dynamic IDs.
  3. Locator chaining.
  4. filter().
  5. Tables and lists.
  6. POM locator design.
  7. CSS versus XPath.
  8. Debugging locator failures.
  9. CI locator failures.
  10. iframe locators.

4–5 Years Experience

Expect questions about:

  1. Locator architecture.
  2. Accessibility-based selectors.
  3. Test ID strategy.
  4. Dynamic React/Angular components.
  5. Locator reliability.
  6. CI flakiness.
  7. Complex nested components.
  8. POM design.
  9. Locator maintenance at scale.
  10. Debugging strictness and actionability.

Senior SDET Candidates

Be ready to discuss:

  • Locator governance across teams.
  • Accessibility and testability contracts.
  • Component-level locator design.
  • Avoiding DOM implementation coupling.
  • Designing stable test IDs.
  • Debugging flaky locator failures.
  • Locator strategies for highly dynamic SPAs.
  • POM versus component object patterns.
  • CI diagnostics and traces.
  • How locator design affects long-term automation cost.

Locator Interview Preparation Roadmap

A practical preparation sequence is:

Step 1: Master basic locators

Learn:

getByRole()

getByText()

getByLabel()

getByPlaceholder()

getByTestId()

locator()

Step 2: Master strictness

Understand:

count()

first()

last()

nth()

and why uniqueness matters.

Step 3: Master filtering

Practice:

filter({ hasText: ‘…’ })

filter({ has: locator })

Step 4: Master dynamic UI handling

Practice applications containing:

  • generated IDs
  • loading indicators
  • delayed elements
  • React re-renders
  • dynamic tables
  • infinite lists
  • modal dialogs

Step 5: Master debugging

Practice checking:

await locator.count();

await expect(locator).toBeVisible();

await expect(locator).toBeEnabled();

Then learn Playwright Inspector, traces, screenshots, and CI diagnostics.

Step 6: Connect locators with POM

Create page objects where locators are encapsulated and tests describe business actions.

For broader preparation, connect this topic with Playwright Interview Questions, Playwright Scenario Based Interview Questions, Playwright Automation Interview Questions and Answers, Playwright TypeScript Interview Questions, and Playwright Page Object Model.

You should also revise Playwright Basic Commands, Playwright Element Not Found Error, Playwright Locator Strict Mode Violation Fix, Playwright Test Timeout Error Fix, Playwright Element Detached From DOM Error, and Advanced Playwright Automation Techniques.


FAQs: Playwright Locators Interview Questions

What is the best locator in Playwright?

There is no universal best locator. Playwright generally recommends user-facing locators such as getByRole() and explicit contracts such as test IDs. The best locator is the one that is stable, meaningful, unique, and aligned with the application’s user-facing behavior.

Is XPath recommended in Playwright?

XPath is supported, but it is generally less desirable when it tightly couples the test to DOM structure. Prefer role, label, text, test ID, or a short stable CSS selector when appropriate.

Why does Playwright throw a strict mode violation?

Usually because an action locator resolves to multiple elements. Improve the locator so it uniquely identifies the intended element.

Is nth() bad in Playwright?

No. nth() is valid, but it can become fragile when list ordering changes. Use it when position is intentionally meaningful or when no stronger unique locator exists.

Does Playwright automatically wait for locators?

Playwright’s locator-based actions perform relevant actionability checks automatically, while assertions retry until their condition is satisfied or the timeout is reached.

Which is better: CSS or XPath?

Neither is universally better. Both can be useful. The more important question is whether the selector is stable and communicates the element’s intended identity.

How do I handle duplicate buttons?

First narrow the locator using role, accessible name, container, or filter(). Use nth() only when appropriate.

How do I locate elements inside an iframe?

Use:

const frame = page.frameLocator(‘#my-frame’);

await frame.getByRole(‘button’, { name: ‘Submit’ }).click();

How do I handle changing text?

Use stable text fragments, regular expressions, roles, attributes, or test IDs.

await page.getByText(/Order #\d+/).click();

Why are accessibility locators preferred?

They model the UI closer to how users and assistive technologies perceive it. They can also encourage better application accessibility and make tests more readable.

Leave a Comment

Your email address will not be published. Required fields are marked *