🟢 1. What is Playwright?
Answer: Playwright is an open-source automation framework developed by Microsoft for end-to-end testing of web applications.
Key Features:
Cross-browser support (Chromium, Firefox, WebKit)
Auto-waiting
Headless & headed execution
Parallel execution
Network interception
🟢 2. Why Playwright over Selenium?
Answer:
Feature Playwright Selenium Auto-wait ✅ Built-in ❌ Manual Speed Faster Slower Multi-tab Easy Complex Network mocking Built-in Limited Modern support Yes Limited
🟢 3. How to install Playwright?
Answer:
npm init playwright@latest
🟢 4. Basic Test Example
import { test, expect } from '@playwright/test';test('Google search test', async ({ page }) => { await page.goto('https://google.com'); await page.fill('input[name="q"]', 'Playwright'); await page.press('input[name="q"]', 'Enter'); await expect(page).toHaveTitle(/Playwright/); });
🟡 5. What is Auto-Waiting?
Answer: Playwright automatically waits for:
Elements to be visible
Elements to be stable
Network to be idle
Example:
await page.click('#submit'); // waits automatically
🟡 6. What are Locators?
Answer: Locators are used to find elements.
page.locator('#id'); page.locator('.class'); page.getByText('Login'); page.getByRole('button', { name: 'Submit' });
🟡 7. Difference between locator() and page.$()
Answer:
locator() → Auto-wait + retry
page.$() → Returns immediately (not reliable)
🟡 8. How to handle dropdowns?
await page.selectOption('#dropdown', 'value1');
🟡 9. Handling checkboxes
await page.check('#checkbox'); await page.uncheck('#checkbox');
🟡 10. Handling alerts
page.on('dialog', async dialog => { await dialog.accept(); });
🔵 11. How to handle multiple tabs?
const [newPage] = await Promise.all([ context.waitForEvent('page'), page.click('#openTab') ]);await newPage.waitForLoadState();
🔵 12. File upload
await page.setInputFiles('#fileInput', 'test.pdf');
🔵 13. File download
const [download] = await Promise.all([ page.waitForEvent('download'), page.click('#downloadBtn') ]);await download.saveAs('file.pdf');
🔵 14. What is Page Object Model (POM)?
Answer: Design pattern to separate UI and test logic.
Example:
export class LoginPage { constructor(private page) {} async login(username, password) { await this.page.fill('#user', username); await this.page.fill('#pass', password); await this.page.click('#login'); } }
🔵 15. API Testing in Playwright
import { request } from '@playwright/test';test('API Test', async () => { const apiContext = await request.newContext(); const response = await apiContext.get('/api/users'); console.log(await response.json()); });
🔴 16. How to handle authentication?
test.use({ storageState: 'auth.json' });
Save session:
await page.context().storageState({ path: 'auth.json' });
🔴 17. Parallel Execution
npx playwright test --workers=4
🔴 18. Retry Failed Tests
// playwright.config.ts retries: 2
🔴 19. How to handle dynamic elements?
await page.locator('//button[text()="Submit"]').click();
Use:
XPath
contains()
text-based locators
🔴 20. Network Interception
await page.route('**/api/users', route => { route.fulfill({ status: 200, body: JSON.stringify({ name: 'Mock User' }) }); });
🧠 Advanced Scenario-Based Questions
🔥 21. Banking App Login + OTP
Solution Approach:
Mock OTP API
Use API interception
await page.route('**/otp', route => { route.fulfill({ body: JSON.stringify({ otp: '123456' }) }); });
🔥 22. E-commerce Add to Cart Flow
await page.click('text=Add to Cart'); await expect(page.locator('#cart')).toContainText('1 item');
🔥 23. Handling Flaky Tests
Best Practices:
Use locators instead of selectors
Avoid hard waits
Use waitForLoadState()
🔥 24. Multi-user Session (Admin + User)
const adminContext = await browser.newContext(); const userContext = await browser.newContext();const adminPage = await adminContext.newPage(); const userPage = await userContext.newPage();
🔥 25. CI/CD Integration
Use:
Example:
- name: Run Playwright Tests run: npx playwright test
26. What is Browser Context in Playwright?
Answer: A Browser Context is an isolated session (like an incognito window).
Why important?
Test isolation
Multi-user testing
No shared cookies/session
const context = await browser.newContext(); const page = await context.newPage();
👉 Think: One browser → multiple contexts → multiple users
🔴 27. Difference between Browser, Context, and Page
Component Description Browser Actual browser instance Context Isolated session Page Tab inside context
🔴 28. How to reuse login session across tests?
Answer: Use storage state
// Save session await context.storageState({ path: 'auth.json' });// Reuse session test.use({ storageState: 'auth.json' });
🔴 29. How to handle iFrames?
const frame = page.frameLocator('#frameId'); await frame.locator('#input').fill('Hello');
🔴 30. Shadow DOM handling
await page.locator('css=custom-element >> text=Submit').click();
🔴 31. How to debug Playwright tests?
Answer:
Run in debug mode:
npx playwright test --debug
Use:
await page.pause();
🔴 32. Trace Viewer in Playwright
Answer: Playwright provides a trace viewer for debugging failures.
npx playwright show-trace trace.zip
🔴 33. How to capture screenshots?
await page.screenshot({ path: 'screenshot.png' });
Full page:
await page.screenshot({ path: 'full.png', fullPage: true });
🔴 34. How to record videos?
const context = await browser.newContext({ recordVideo: { dir: 'videos/' } });
🔴 35. Handling dynamic waits (best approach)
Avoid:
await page.waitForTimeout(5000); ❌
Use:
await page.waitForSelector('#element'); ✅
🔴 36. Soft Assertions in Playwright
import { expect } from '@playwright/test';await expect.soft(page.locator('#status')).toHaveText('Success');
🔴 37. Hard vs Soft Assertions
Type Behavior Hard Stops execution Soft Continues execution
🔴 38. How to run specific test file?
npx playwright test login.spec.ts
🔴 39. Run tests in headed mode
npx playwright test --headed
🔴 40. Environment configuration
// playwright.config.ts use: { baseURL: 'https://staging.example.com' }
Usage:
await page.goto('/');
🧠 Real-Time Scenario Questions (Very Important)
🔥 41. Scenario: Element is visible but click fails
Possible reasons:
Overlay present
Element not stable
Animation
Solution:
await page.locator('#btn').click({ force: true });
Better:
await expect(locator).toBeVisible(); await locator.click();
🔥 42. Scenario: Test passes locally but fails in CI
Reasons:
Timing issues
Environment difference
Headless issues
Fix:
Use proper waits
Enable retries
Use trace viewer
🔥 43. Scenario: Handling infinite scrolling
await page.evaluate(() => window.scrollBy(0, window.innerHeight));
Loop until element appears:
while (!(await page.locator('#item').isVisible())) { await page.mouse.wheel(0, 1000); }
🔥 44. Scenario: Validate table data
const rows = page.locator('table tr');const count = await rows.count();for (let i = 0; i < count; i++) { const text = await rows.nth(i).textContent(); console.log(text); }
🔥 45. Scenario: Handling date picker
await page.click('#date'); await page.click('text=25');
🔥 46. Scenario: Handling authentication popup
await page.goto('https://user:pass@example.com');
🔥 47. Scenario: Drag and Drop
await page.dragAndDrop('#source', '#target');
🔥 48. Scenario: Handling file download validation
const path = await download.path(); expect(path).toContain('file');
🔥 49. Scenario: Validate API response + UI
const response = await page.waitForResponse('**/api/data'); const data = await response.json();expect(data.name).toBe('Test');
🔥 50. Scenario: Retry only failed tests
npx playwright test --retries=2
🎯 Advanced Framework Design Questions
🔷 51. How do you design a scalable Playwright framework?
Answer:
Structure:
tests/ pages/ utils/ fixtures/ config/
Best practices:
Use POM
Use fixtures
Use environment configs
Separate test data
🔷 52. What are fixtures in Playwright?
test('example', async ({ page }) => { // page is a fixture });
Custom fixture:
test.extend({ loginPage: async ({ page }, use) => { await use(new LoginPage(page)); } });
🔷 53. Data-driven testing
const users = ['user1', 'user2'];for (const user of users) { test(`login test ${user}`, async ({ page }) => { console.log(user); }); }
🔷 54. Parallel vs Serial execution
test.describe.configure({ mode: 'parallel' });
Serial:
test.describe.configure({ mode: 'serial' });
🔷 55. Tags in Playwright
test('smoke test @smoke', async () => {});
Run:
npx playwright test -g "@smoke"
⚠️ Tricky Interview Questions
❓ 56. Why Playwright is faster?
WebSocket communication
No Selenium WebDriver layer
Direct browser control
❓ 57. Can Playwright handle multiple browsers at once?
Yes:
projects: [ { name: 'Chromium' }, { name: 'Firefox' }, { name: 'WebKit' } ]
❓ 58. What happens if locator matches multiple elements?
Playwright throws strict mode error
Fix:
locator.first() locator.nth(0)
❓ 59. Difference between waitForSelector and locator wait
locator → auto-wait
waitForSelector → manual wait
❓ 60. How do you reduce flakiness?
✔ Use locators ✔ Avoid hard waits ✔ Use retries ✔ Mock APIs ✔ Stable selectors
🔥 61. Scenario: Banking App – Secure Login with Token
Problem: Login uses JWT token instead of UI login.
Solution:
Call API
Inject token into storage
const requestContext = await request.newContext();const response = await requestContext.post('/api/login', { data: { username: 'user', password: 'pass' } });const body = await response.json();await context.addCookies([{ name: 'token', value: body.token, domain: 'example.com', path: '/' }]);
🔥 62. Scenario: Bypass CAPTCHA (Important Interview Question)
Reality: Playwright cannot solve CAPTCHA
Best Practice:
Disable CAPTCHA in test environment
Mock API
🔥 63. Scenario: Handling WebSocket Testing
page.on('websocket', ws => { ws.on('framereceived', frame => { console.log(frame.payload); }); });
🔥 64. Scenario: Test microservices-based UI
Approach:
Mock dependent APIs
Validate UI independently
await page.route('**/orders', route => { route.fulfill({ body: JSON.stringify({ orders: [] }) }); });
🔥 65. Scenario: Handling flaky network
await page.route('**/*', route => { route.continue({ timeout: 10000 }); });
🔥 66. Scenario: Validate PDF download content
const buffer = await download.createReadStream();
Then parse using Node libraries
🔥 67. Scenario: Multi-language testing
await page.goto('/?lang=fr'); await expect(page.locator('h1')).toHaveText('Bonjour');
🔥 68. Scenario: Geo-location testing
const context = await browser.newContext({ geolocation: { latitude: 28.6139, longitude: 77.2090 }, permissions: ['geolocation'] });
🔥 69. Scenario: Timezone testing
const context = await browser.newContext({ timezoneId: 'Asia/Kolkata' });
🔥 70. Scenario: Testing notifications
await context.grantPermissions(['notifications']);
🏗️ Framework Architecture Questions (Very Important)
🔷 71. How to design enterprise-level Playwright framework?
Layers:
1. Tests 2. Page Objects 3. API Layer 4. Utilities 5. Test Data 6. Config
Key Additions:
Logging
Reporting
Retry strategy
Test tagging
🔷 72. How to implement reusable utilities?
Example:
export async function login(page, user) { await page.fill('#user', user); }
🔷 73. Centralized test data management
Use:
JSON files
Environment variables
const data = require('./testData.json');
🔷 74. Logging in Playwright
Use console or integrate with tools like:
🔷 75. Reporting tools
Playwright supports:
HTML report
Allure report
npx playwright show-report
⚙️ CI/CD + DevOps Questions
🔧 76. How to run Playwright in CI/CD?
Using GitHub Actions:
name: Playwright Testson: [push]jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - run: npm install - run: npx playwright install - run: npx playwright test
🔧 77. How to run tests in Docker?
FROM mcr.microsoft.com/playwright:v1.40.0 WORKDIR /app COPY . . RUN npm install CMD ["npx", "playwright", "test"]
🔧 78. Headless vs Headed execution
Mode Use Case Headless CI/CD Headed Debugging
🔧 79. How to reduce execution time?
✔ Parallel execution ✔ API mocking ✔ Reuse authentication ✔ Run only changed tests
🔧 80. Sharding tests
npx playwright test --shard=1/3
🔍 Debugging & Optimization
🛠️ 81. How to debug failed tests in CI?
Use trace viewer
Capture video
Capture logs
🛠️ 82. Memory leak issues
Cause:
await context.close();
🛠️ 83. Handling slow tests
Remove unnecessary steps
Use API setup instead of UI
Use fixtures
🛠️ 84. Test retries strategy
retries: process.env.CI ? 2 : 0
🛠️ 85. Fail fast strategy
maxFailures: 5
🔐 Security Testing (Important)
🔒 86. How to test authentication security?
Validate token expiration
Test invalid login
🔒 87. How to test authorization?
expect(await page.isVisible('#adminPanel')).toBeFalsy();
🔒 88. Sensitive data handling
Avoid hardcoding credentials
Use env variables
🔒 89. HTTPS validation
expect(page.url()).toContain('https');
🔒 90. Cookie testing
const cookies = await context.cookies();
🎯 Expert-Level Tricky Questions
❓ 91. Difference between browser.newPage() and context.newPage()
browser.newPage() → new default context
context.newPage() → controlled session
❓ 92. Why avoid waitForTimeout()?
Causes flaky tests
Slows execution
❓ 93. How Playwright handles race conditions?
Auto-waiting
Event-based execution
❓ 94. Can Playwright test backend?
Yes:
API testing
Contract testing
❓ 95. How to test file upload without UI?
await request.post('/upload', { multipart: { file: fs.createReadStream('file.txt') } });
❓ 96. What is test isolation?
Each test runs independently with:
❓ 97. How to handle feature flags?
await page.goto('/?feature=true');
❓ 98. How to test performance?
Basic:
const start = Date.now(); await page.goto('/'); console.log(Date.now() - start);
❓ 99. Can Playwright run without UI?
Yes → headless mode
❓ 100. When NOT to use Playwright?
Desktop app testing
Heavy performance testing (use JMeter)
Real-World Enterprise Scenarios in Playwright
🏦 1. Banking App – End-to-End Payment Flow
🎯 Problem
User logs in → adds beneficiary → transfers money → verifies transaction.
✅ Approach
Reuse login session
Mock OTP service
Validate UI + API
💻 Example
test('Fund transfer flow', async ({ page }) => { await page.goto('/dashboard'); await page.click('text=Transfer'); await page.fill('#account', '123456'); await page.fill('#amount', '5000'); await page.click('#submit'); await expect(page.locator('#status')).toHaveText('Success'); });
🧠 Best Practices
Avoid real payment → mock API
Validate transaction via backend API
Use test accounts
🛒 2. E-Commerce – Add to Cart + Checkout
🎯 Problem
User adds product → applies coupon → completes checkout.
✅ Approach
Use stable locators
Mock payment gateway
Validate price calculation
💻 Example
await page.click('text=Add to Cart'); await page.fill('#coupon', 'DISCOUNT10'); await page.click('#apply');await expect(page.locator('#total')).toContainText('900');
🧠 Best Practices
Mock payment APIs
Validate cart via API
Use data-driven tests
👥 3. Multi-User Role Testing (Admin vs User)
🎯 Problem
Admin creates data → user verifies it.
✅ Approach
Use multiple browser contexts
💻 Example
const adminContext = await browser.newContext(); const userContext = await browser.newContext();const adminPage = await adminContext.newPage(); const userPage = await userContext.newPage();await adminPage.goto('/admin'); await adminPage.click('#createUser');await userPage.goto('/dashboard');
🧠 Best Practices
Keep sessions isolated
Avoid shared cookies
🔐 4. Authentication Without UI (Token-Based Login)
🎯 Problem
Login via API instead of UI (faster + stable)
✅ Approach
Call login API
Inject token
💻 Example
const response = await request.post('/api/login', { data: { username: 'user', password: 'pass' } });const { token } = await response.json();await context.addCookies([{ name: 'token', value: token }]);
🧠 Best Practices
Avoid UI login in every test
Store auth state
🌐 5. Microservices UI – API Mocking
🎯 Problem
Frontend depends on unstable backend services
✅ Approach
💻 Example
await page.route('**/orders', route => { route.fulfill({ body: JSON.stringify({ orders: [] }) }); });
🧠 Best Practices
Test UI independently
Simulate edge cases
📊 6. Data Validation Between UI and API
🎯 Problem
Ensure UI data matches backend response
💻 Example
const response = await page.waitForResponse('**/api/user'); const apiData = await response.json();const uiText = await page.locator('#username').textContent();expect(uiText).toBe(apiData.name);
🧠 Best Practices
Validate critical fields
Avoid over-validating
📱 7. Mobile Device Testing
🎯 Problem
Test responsive UI
💻 Example
import { devices } from '@playwright/test';test.use(devices['iPhone 13']);
🧠 Best Practices
Test key flows only
Avoid duplicating all tests
📦 8. File Upload & Download Validation
🎯 Problem
Upload invoice → download receipt → verify
💻 Example
await page.setInputFiles('#upload', 'invoice.pdf');const [download] = await Promise.all([ page.waitForEvent('download'), page.click('#download') ]);
🧠 Best Practices
Validate file name
Validate file content (if critical)
🔁 9. Handling Retry & Flaky Tests
🎯 Problem
Tests fail intermittently in CI
✅ Fix
retries: 2
🧠 Best Practices
Fix root cause (don’t rely only on retry)
Use trace viewer
🧾 10. Infinite Scroll / Lazy Loading
🎯 Problem
Data loads on scroll
💻 Example
while (!(await page.locator('#item').isVisible())) { await page.mouse.wheel(0, 1000); }
🧠 Best Practices
Add exit condition
Avoid infinite loops
🧪 11. Feature Flag Testing
🎯 Problem
Feature enabled only for some users
💻 Example
await page.goto('/?feature=true');
🧠 Best Practices
Test both ON and OFF states
🌍 12. Localization Testing
🎯 Problem
App supports multiple languages
💻 Example
await page.goto('/?lang=hi'); await expect(page.locator('h1')).toHaveText('नमस्ते');
🧠 Best Practices
Validate key UI texts
Avoid full UI comparison
📍 13. Geo-Location Testing
🎯 Problem
Content varies by location
💻 Example
await context.setGeolocation({ latitude: 28.61, longitude: 77.20 });
🔄 14. Background Job Validation
🎯 Problem
Async job updates UI later
💻 Example
await expect(page.locator('#status')).toHaveText('Completed', { timeout: 10000 });
⚙️ 15. CI/CD Pipeline Execution
🎯 Problem
Run tests on every deployment
💻 Example
Using Jenkins or GitHub Actions
npx playwright test
🔥 16. Handling CAPTCHA in Enterprise Apps
❗ Reality
Automation tools should not bypass CAPTCHA
✅ Approach
Disable in test env
Use mock/stub
🧠 17. High Data Volume Testing (Tables)
🎯 Problem
Validate large tables
💻 Example
const rows = await page.locator('table tr'); expect(await rows.count()).toBeGreaterThan(0);
🔐 18. Role-Based Access Testing
🎯 Problem
User should not access admin pages
💻 Example
await page.goto('/admin'); await expect(page).toHaveURL('/unauthorized');
⚡ 19. Performance Check (Basic)
💻 Example
const start = Date.now(); await page.goto('/'); console.log(Date.now() - start);