Playwright Interview Questions – Part2



  1. Why is Playwright faster than Selenium?
  • Direct communication with browser using browser protocols (CDP/WebSocket)
  • No WebDriver dependency
  • Auto-waiting reduces unnecessary waits
  • Parallel execution by default
  • Multiple browser contexts instead of launching new browsers

 

  1. Explain Browser, BrowserContext, and Page.

Browser

|

|—- BrowserContext 1

|         |

|         |—- Page 1

|         |—- Page 2

|

|—- BrowserContext 2

|

|—- Page 3

BrowserContext is an isolated browser profile.

  1. Difference between BrowserContext and Incognito window?

BrowserContext is Playwright’s isolated environment.

One browser can have many contexts.

Contexts don’t share

  • Cookies
  • Local Storage
  • Session Storage
  • Cache

 

  1. Why should you avoid page.waitForTimeout()?

Because

  • Hard waits slow execution
  • Causes flaky tests
  • Doesn’t guarantee element readiness

Instead use

await locator.click();

or

await expect(locator).toBeVisible();

  1. Explain Auto Waiting.

Playwright automatically waits for

  • Visible
  • Stable
  • Enabled
  • Receives Events

before performing actions.

Example

await page.locator(“#submit”).click();

No explicit wait required.

  1. Locator vs ElementHandle

Locator

const btn = page.locator(“#save”);

await btn.click();

ElementHandle

const btn = await page.$(“#save”);

await btn.click();

Locator re-evaluates the DOM and is recommended.

  1. What happens if DOM changes after locating an element?

Locator automatically finds the updated element.

ElementHandle becomes stale.

  1. Explain Strict Mode.

If locator matches multiple elements

page.locator(“button”)

Playwright throws

Strict mode violation

Need

locator.first()

locator.nth(0)

locator.filter()

  1. Explain Shadow DOM handling.

No special syntax.

await page.locator(“my-component button”).click();

Playwright pierces open shadow roots automatically.

  1. Difference between page.locator() and page.$()

page.$()

  • Old API
  • Returns ElementHandle

locator()

  • Modern API
  • Auto waits
  • Retry
  • Recommended

 

  1. How does Playwright retry assertions?

await expect(locator).toHaveText(“Success”);

It retries until

  • Passes
  • Timeout occurs

 

  1. How do you handle multiple tabs?

const pagePromise =

context.waitForEvent(‘page’);

await page.click(“text=Open”);

const newPage = await pagePromise;

await newPage.waitForLoadState();

 

  1. How do you handle file downloads?

const downloadPromise =

page.waitForEvent(‘download’);

await page.click(“#download”);

const download =

await downloadPromise;

await download.saveAs(“report.xlsx”);

  1. How do you upload files?

await page.locator(“input[type=file]”)

.setInputFiles(“sample.pdf”);

  1. How to intercept API requests?

await page.route(“**/users”, route =>

route.fulfill({

status:200,

body:JSON.stringify({

name:”Anand”

})

}));

  1. Difference between route.continue(), fulfill(), abort()

continue()

→ Sends request to server

fulfill()

→ Mock response

abort()

→ Cancel request

  1. How do you validate API responses?

const response =

await page.waitForResponse(

res=>res.url().includes(“/users”)

);

expect(response.status()).toBe(200);

  1. Explain Storage State.

Used to avoid repeated login.

await context.storageState({

path:”state.json”

});

Reuse

storageState:”state.json”

  1. Explain Trace Viewer.

Captures

  • Screenshots
  • DOM snapshots
  • Network
  • Console
  • Timeline
  • Actions

 

  1. Difference between Screenshot and Trace?

Screenshot

Only one image.

Trace

Complete execution history.

  1. How do you run tests in parallel?

test.describe.configure({

mode:’parallel’

});

or

workers:4

  1. What causes flaky Playwright tests?
  • Hard waits
  • Poor locators
  • Dynamic data
  • Race conditions
  • Shared state
  • Network delays

 

  1. Explain fixtures.

Fixtures manage reusable setup and teardown.

test.extend({

loginPage: async ({ page }, use) => {

await use(new LoginPage(page));

}

});

  1. How do you share login across tests?

Use

storageState

or

globalSetup

  1. Explain globalSetup and globalTeardown.

globalSetup

Runs once before all tests.

globalTeardown

Runs once after all tests.

  1. Difference between beforeAll() and globalSetup()

beforeAll()

Runs per test file (or describe block).

globalSetup()

Runs once for the entire suite.

  1. How would you design a Playwright framework?

A typical enterprise framework includes:

  • Page Object Model (POM)
  • Fixtures
  • Utility classes
  • API helpers
  • Environment configuration
  • Custom reporters
  • Logging
  • Screenshot and trace capture
  • CI/CD integration (Azure DevOps, GitHub Actions, Jenkins)
  • Data-driven testing
  • Parallel execution
  • Cross-browser execution

 

  1. How do you test microservices with Playwright?
  • Use Playwright’s APIRequestContext for API testing.
  • Mock dependent services using page.route().
  • Validate UI and backend responses together.
  • Run API setup before UI flows to create test data.

 

  1. How would you reduce execution time for a suite with 2,000 tests?
  • Increase parallel workers based on available CPU.
  • Reuse authentication with storageState.
  • Optimize slow or brittle locators.
  • Avoid unnecessary browser launches by using contexts.
  • Mock slow external services when appropriate.
  • Split tests across CI agents (sharding).

 

  1. What are the limitations of Playwright?
  • Cannot automate native desktop applications.
  • Limited support for browser extensions compared to Selenium ecosystems.
  • Closed Shadow DOM cannot be accessed.
  • Requires Node.js (or supported language bindings) and browser binaries.
  • Native mobile app automation requires tools like Appium.

Tags:
Leave a comment

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

Subscribe now

Receive weekly newsletter with educational materials, new courses, most popular posts, popular books and much more!