Playwright interview questions and answers: Part 2

11. How to open a browser in playwright ?
There are two common ways to open a browser in Playwright: using the built-in page fixture and launching the browser manually.
1. Using the Playwright fixture
import { test } from '@playwright/test'; 
test('open a browser', async ({ page }) => {
  await page.goto('https://www.example.com/');
});
In this: Playwright automatically creates the browser, browser context, and page. You can directly use page.goto() to navigate to a URL. Playwright manages the browser lifecycle for you.
2. Without using the Playwright fixture 
import { test, chromium } from '@playwright/test';
test('open a browser', async () => {   const browser = await chromium.launch();   const context = await browser.newContext();   const page = await context.newPage(); 
  await page.goto('https://www.example.com/');
  await browser.close(); }); In this:     You manually launch the browser using chromium.launch().     You create a browser context and a page.     You are responsible for closing the browser. 
 
12. How do you correlate the Browser, Context, and Page in Playwright?

Let's start with the Page.

  1. Page: A Page represents a single browser tab or a window within a browser context.
  1. Context: A Browser Context is an isolated browser session(isolated window or new window). It has its own cookies, local storage, session storage, and other session-related data. Multiple pages within the same context share the context's applicable session data. Separate contexts are isolated from each other. For example, two separate contexts(windows) can represent two different users.
  1. Browser: A Browser represents an instance of a browser engine, such as Chromium, Firefox, or WebKit. A browser instance can contain multiple browser contexts, and each context can contain multiple pages.

Hierarchy:

Browser

 ├── Context 1 (User A)

 │    ├── Page 1 (Tab 1)

 │    └── Page 2 (Tab 2)

 └── Context 2 (User B)

      └── Page 3 (Tab 1)

In short, a Browser contains contexts, and each Context contains pages. Pages within the same context share applicable session data, while separate contexts provide isolated sessions.

13.  How to add or import modules or packages in any playwright class ?

In java script, we can import like this:
import { test, expect, Page } from '@playwright/test';
import { Helper } from './utils/helpers';
import { testClass1,testClass2 } from './tests/folder1/testClass'; // here the methods testClass1and testClass2 have been imported from the class tests/folder1/testClass.js

or
const { test, expect, Page }  = require( '@playwright/test');
const { Helper }  = require( './utils/helpers');
const { testClass1,testClass2 }  = require( './tests/folder1/testClass');  

Some points to remember: 

test and expect are Playwright exports.

Helper must be exported from utils/helpers.js.

testClass1 and testClass2 must be exported from testClass.js.

  • Page is a TypeScript type, not a runtime JavaScript export you normally need. If you're writing plain JavaScript, remove it from the import. 

  •  14. How to export or import using "import" keyword ?

    In above example, your class testClass.js file could look like this:

    export class testClass1 {
    method1_class1() {
    console.log('Method1_class1');
    }
    method2_class1() {
    console.log('Method2_class1');
    }
    }


    export class testClass2 {
    method1_class2() {
    console.log('Method1_class2');
    }
    }
    //-------------------------------------------------------
     
    Then use the classes in your importing test:

    import { test, expect } from '@playwright/test';
    import { testClass1, testClass2 } from './tests/folder1/testClass';

    test('example', async ({ page }) => {
    const obj1 = new testClass1();
    const obj2 = new testClass2();

    obj1.method1_class1();
    obj1.method2_class1();
    obj2.method1_class2();
    });
     
    15. How to export or import using "require" keyword ?
     
     class testClass1 {
        method1_class1() {
            console.log('Method1_class1');
        }
        method2_class1() {
            console.log('Method2_class1');
        }
    }


    class testClass2 {
        method1_class2() {
            console.log('Method1_class2');
        }
    }

    module.exports = { testClass1, testClass2 };

    //-------------------------------------------------------

    Then use the classes in your importing test:

    const { test, expect } = require('@playwright/test');
    const { testClass1, testClass2 } = require('./tests/folder1/testClass');

    test('example', async ({ page }) => {
        const obj1 = new testClass1();
        const obj2 = new testClass2();

        obj1.method1_class1();
        obj1.method2_class1();
        obj2.method1_class2();
    }); 


    16. How do you record in Playwright?

    We can record user actions in Playwright using the Codegen tool. It opens a browser and the Playwright Inspector, records our actions, and generates Playwright code.

    Common Codegen commands:

    1. npx playwright codegen — Opens the browser and Playwright Inspector.
    2. npx playwright codegen https://www.google.com — Opens the specified URL directly.
    3. npx playwright codegen --browser firefox — Launches Firefox instead of the default Chromium browser.
    4. npx playwright codegen --viewport-size="600,600" — Sets the browser viewport to 600 × 600 pixels.
    5. npx playwright codegen --device="iPhone X" — Emulates an iPhone X device (the device name must be supported).
    6. npx playwright codegen --color-scheme=dark — Emulates dark color scheme preferences.
    7. npx playwright codegen --help — Displays available Codegen options.

     

    17. What are the hooks in Playwright?

    Playwright has four main hooks:

    • beforeAll() — Runs once before all tests in the current scope.
    • afterAll() — Runs once after all tests in the current scope.
    • beforeEach() — Runs before each test.
    • afterEach() — Runs after each test.

    Note: When hooks are defined inside a test.describe() block, they apply to the tests within that block. When defined outside a describe block, they generally apply to tests in the file.

     

    18. What are assertions in Playwright?

    Assertions are used to verify whether the actual result matches the expected result in a test. Playwright provides the expect() function to perform assertions.

    Common assertions in Playwright:

    await expect(page).toHaveTitle('Home Page');
    await expect(page).toHaveURL('https://example.com');
    await expect(page.locator('#username')).toBeVisible();
    await expect(page.locator('#username')).toBeEnabled();
    await expect(page.locator('#username')).toHaveText('John');
    await expect(page.locator('#username')).toHaveValue('John');
    await expect(page.locator('#checkbox')).toBeChecked();
    await expect(page.locator('.message')).toContainText('Success');
    await expect(page.locator('#username')).toHaveCount(1);
    await expect(page.locator('#username')).toHaveAttribute('id', 'username');
    await expect(page.locator('#username')).toHaveClass('username-field');
    

    Using not:

    We can use ".not" to verify that a condition is false.

    await expect(page.locator('#username')).not.toBeVisible();
    await expect(page.locator('#username')).not.toBeEnabled();
    await expect(page.locator('#username')).not.toHaveText('John');
    await expect(page.locator('#username')).not.toHaveValue('John');
     
    Note: Playwright's web-first assertions automatically retry until the condition passes or the timeout expires. 

     

    19. What are Hard and soft assertions in Playwright ?

    • Hard assertion: It is the default assertion. If this fails, the test stops at that point.
    • Soft assertion: This uses  "expect.soft()."  If thsi fails, the test continues, and the failure is reported at the end.

    Example:

    await expect.soft(page.locator('#username')).toBeVisible();

    await expect.soft(page.locator('#username')).not.toBeEnabled();

     

    20. What are annotations in Playwright?

    Annotations are used to control test execution based on specific requirements.
    Common annotations in Playwright:

    1. only — Runs only the specified test or test group. Use it carefully because it can cause other tests to be excluded.

    test.only('example', async ({ page }) => {
        // Runs this test only
    });

    2. skip — Skips the test without executing it.

    test.skip('example', async ({ page }) => {
        // This test is skipped
    });

    3. fail — Marks a test as expected to fail, ie, to intentionally fail a test case. If it passes, Playwright reports an unexpected pass.

    test.fail('example', async ({ page }) => {
        // This test is expected to fail
    });

    4. fixme — Marks a test as needing a fix and skips its execution.

    test.fixme('example', async ({ page }) => {
        // This test is not executed
    });

    5. slow — Marks a test as slow and triples its test timeout compared to the default or configured timeout.

    test('example', async ({ page }) => {
        test.slow();
        // Test steps
    });

    6. skip conditionally : Used to skip a test when a specified condition is met.
    test('example', async ({ page, browserName }) => {
        test.skip(browserName === 'firefox', 'Skip this test in Firefox');

        // Test steps
    });
    Explanation: The test is skipped only when the browser is Firefox. Otherwise, the test executes normally. 


     

     



    Playwright interview questions and answers: Part1

    1. What is Playwright ?

    A free and open-source tool for testing automation of web applications and API.

     

    2. What are the benefits of using Playwright ?

    - it is a free and open-source tool.

    - It supports multiple languages: Java, Python, JavaScript, TypeScript, and .NET (including C#).

    - supports multiple browsers: Chromium (Google Chrome and Microsoft Edge), WebKit (Safari), and Firefox. 

    - supports multiple testing platforms/operating systems: Windows, MacOS, Linux

    - It has easy setup and configuration

    - It includes built-in reporting options and supports custom reporters.

    - it has its own locators/selectors, such as getByRole(), getByText(), and getByTestId().

    - It supports screenshots, visual snapshot comparisons, and video recording when configured.

    - it has auto wait 

    - it supports recording and replaying. Codegen records user interactions and generates test code; traces can help you inspect and debug executions.

    - it provides easy debug and re-running of failed tests. It offers debugging tools, Trace Viewer, and test retries when configured.

    - it allows testing multiple tabs(contexts) and multiple browser instances.

    - it supports mobile testing. It supports mobile browser/device emulation, but it is not a native mobile app automation tool like Appium.

    - it supports API testing

    - it is faster than other test automation tools in general.

    - allows running the test in headed and headless modes

    - supports parallel execution. Tests can run in parallel using workers and across multiple CI jobs.

    - supports CICD and Docker. It integrates with CI pipelines and provides official Docker images.

     

    3. How you run a playwright test in a particular browser from command line ?

    npx playwright test --project=chromium

    npx playwright test --project=firefox

    npx playwright test --project=webkit

     

    4. What are the steps to install and configure Playwright?
    1. Downlaod and Intall Node.js
    2. Download and install VS Code
    3. Create a project folder in your computer
    4. Open the folder in VS Code
    5. Initialize Playwright:
    npm init playwright@latest --> this will install latest version of playwright.
    6. While configuring the playwright, select JavaScript or TypeScript, the test folder, and whether to add a CI workflow.
    7. Install browsers, run:
    npx playwright install 
    npx playwright install — Installs the supported browser binaries.
    npx playwright install chromium — Installs only Chromium.
     

    5. What is a fixture in Playwright ?

    A fixture is a reusable setup mechanism that provides the objects or resources a test needs and manages their lifecycle, including setup before the test and cleanup afterward.

    Let’s compare with a resturant:

    ·        Before the customer arrives: The restaurant prepares the table, cutlery, napkins, and water.

    ·        When the customer arrives: Everything is ready to use.

    ·        After the customer leaves: The restaurant cleans the table and prepares it for the next customer.

    Similarly, in Playwright, fixtures prepare resources before a test and clean them up when the test finishes.

    "Fixtures do setup before running the test and cleanup afterward."

    For example, the page fixture provides a browser page and manages its lifecycle, including closing it after the test.

    Can we override fixtures and create custom fixtures?

    Yes! We can extend built-in fixtures or override them to customize their behavior.

     

    6. How does the “page” fixture work?

    Consider this example:

    javascript

    test('this is a test', async ({ page }) => {
      await page.goto('https://example.com');
    });

    Here is what happens behind the scenes:

    1. Playwright starts or reuses a browser instance as needed.
    2. It creates an isolated browser context for the test.

    3. It creates a page within that context and injects it into your test through { page }.

    4. Your test uses page to navigate and interact with the website.

    1. After the test finishes, Playwright cleans up the page and its context automatically.

    You don't need to manually create or close these resources when using the standard Playwright Test fixtures.

     

     7. What is the difference between NPM and NPX?

    • NPM (Node Package Manager): It is used to install, update, and manage JavaScript packages and their dependencies. For example, we use

    npm init playwright@latest to set up a Playwright project.

    • NPX (Node Package Executor): It is used to execute packages or commands without necessarily installing them globally. For example, we use

    npx playwright test to execute Playwright tests.

     

     8. What are "async" and "await" in Playwright ?

    "async" represents an asynchronous function. It makes the function return a promise.
    "await" makes the async function wait for the promise to settle. The promise could settle with the result as fulfilled or rejected. After the promise is settled, the function moves with the next step. It throws an error if the promise is rejected, as per the error handling methods applied.


    In Playwright, we use async and await to ensure the browser actions such as navigation, clicking, filling etc.
    For example:

    test('Login to the account page.', async ({ page }) => {
      await page.goto('https://example.com');
    await page.fill('#username', 'user123');
    await page.locator().fill('password', '*********');
      await page.click('#login');
    });

    Here's what happens:

        async allows the test function to use await.

        await page.goto(...) waits for the navigation operation to complete according to Playwright's navigation rules.

        await page.fill(...) waits for Playwright to complete the fill operation.

        await page.click(...) waits for Playwright to complete the click operation.
        The next statement executes after the click Promise fulfills. If an awaited operation throws an error, execution jumps to error handling or the test fails.

    What happens while await is waiting?
    Suppose you execute:

    await page.goto('https://example.com');

    JavaScript does not freeze the entire program while waiting. Instead, the async function pauses at that line, allowing the JavaScript event loop to process other available work. Once the Promise settles, the function resumes.

     

     9. How you manage the failed test cases in Playwright? 

    In Playwright, we use the retries option to rerun failed test cases a specified number of times.

    There are two ways to configure retries:

        Configuration file: Set retries in playwright.config.js.
        Command line: Use npx playwright test --retries=1 to retry failed tests once.

    If retries are configured in both places, the command-line option overrides the configuration file setting.

    One important note: Retries apply to failed tests, not every test. By default, retries are set to 0.

     

     10. What are the locators or selectors supported by Playwright?

    The main locators and selectors supported by Playwright are:

    1. getByRole() – Locates elements by their role, such as a button or heading.
    2. getByText() – Locates elements by their visible text.
    3. getByLabel() – Locates form elements by their associated label.
    4. getByPlaceholder() – Locates input elements by their placeholder text.
    5. getByAltText() – Locates elements, usually images, by their alternative text.
    6. getByTitle() – Locates elements by their attribute as title.
    7. getByTestId() – Locates elements by their attribute as test ID.
    8. CSS selector – Locates elements using CSS selectors through locator().
    9. XPath selector – Locates elements using XPath through locator().
    10. Chained locators – Locates elements by combining multiple locators to narrow down the target element.

    Example of a chained locator:

    page.locator('div').locator('button');