Fun with Learning Technology
LearnCoursesQuestionsTracksToolsNewsExplorePractice
Fun with Learning Technology

A new problem, explained clearly, every day.

Subscribe
Learn
  • Lessons
  • Topics
  • News
  • Tools
  • Courses
  • Career tracks
  • Everything
Site
  • About
  • Contact
  • Support
  • Privacy
  • Terms
Get the daily one

One email per new problem. No spam.

Request a tutorial

Requests shape what gets made next.

© 2026 Fun with Learning TechnologyRSS
Home››Quiz

quiz

Ten questions at a time, drawn from 185. Every answer is explained. Nothing is saved and no account is needed.

Question 1 of 10Score 0

What is the primary benefit of Playwright's auto-waiting mechanism?

Practice quiz for . Scores are not saved.

Study first?

Every question comes from a lesson in the course.

Read the course →

Interview prep

Written questions with full answers.

interview questions →

All quiz questions and answers

  1. What is the primary benefit of Playwright's auto-waiting mechanism?

    • It eliminates the need for any assertions in the test script.
    • It ensures actions are performed only when the element is actionable.
    • It forces the test to pause for a fixed duration to sync with the server.
    • It automatically optimizes the test code to use fewer lines.

    Answer: It ensures actions are performed only when the element is actionable.. Playwright waits for elements to be visible, enabled, and stable before performing actions, ensuring reliability. Option 0 is wrong because assertions are still required for validation. Option 2 describes hard-coded sleeps which are discouraged. Option 3 is incorrect as auto-waiting focuses on element state, not code length.

    From lesson: What is Playwright and its key features

  2. Why does Playwright recommend using locators like getByRole over CSS selectors?

    • CSS selectors are deprecated in modern web browsers.
    • Locators are faster because they are cached by the browser engine.
    • Locators mimic how a real user interacts with the page, making tests more resilient.
    • CSS selectors require the page to be fully loaded before they can be used.

    Answer: Locators mimic how a real user interacts with the page, making tests more resilient.. User-facing locators represent how users find elements (by label, role, etc.), meaning the test won't break if the implementation details (like IDs or classes) change. CSS selectors aren't deprecated (0), locators aren't necessarily faster than CSS (1), and both work while the page loads (3).

    From lesson: What is Playwright and its key features

  3. What is the purpose of a Browser Context in Playwright?

    • To allow multiple tests to share the same browser cookies and session.
    • To provide an isolated environment for each test to run independently.
    • To limit the number of browsers that can run concurrently on a machine.
    • To store screenshots and trace files for debugging.

    Answer: To provide an isolated environment for each test to run independently.. Browser Contexts provide complete isolation (cookies, local storage) for each test, ensuring tests do not influence each other. Option 0 is the opposite of the intended behavior. Option 2 is a performance consideration, not a functional feature. Option 3 refers to artifacts, not the browser engine environment.

    From lesson: What is Playwright and its key features

  4. Which of the following describes the 'web-first' assertions feature in Playwright?

    • Assertions that always pass if the page loads correctly.
    • Assertions that automatically retry until the condition is met.
    • Assertions that are executed on the backend server before the browser renders.
    • Assertions that only compare text content and ignore visual state.

    Answer: Assertions that automatically retry until the condition is met.. Web-first assertions (expect(locator).toBeVisible()) automatically retry until the condition is met or the timeout is reached. Option 0 is incorrect as tests must validate state, not just existence. Option 2 is wrong as assertions happen in the test process. Option 3 is wrong as they can validate attributes, counts, and states, not just text.

    From lesson: What is Playwright and its key features

  5. How does Playwright handle parallel test execution efficiently?

    • By running multiple tests in a single browser window sequentially.
    • By using a single browser instance for all tests in a test suite.
    • By running tests in parallel across multiple isolated browser contexts.
    • By limiting the total number of actions to prevent system memory crashes.

    Answer: By running tests in parallel across multiple isolated browser contexts.. Playwright executes tests in parallel by spinning up isolated contexts or workers, ensuring maximum speed without interference. Option 0 is slow. Option 1 leads to state leakage. Option 3 correctly identifies the mechanism for parallelization.

    From lesson: What is Playwright and its key features

  6. When comparing architecture, why is Playwright generally faster at executing tests than tools that inject scripts into the browser?

    • It uses a centralized proxy to interpret browser traffic
    • It interacts with the browser engine via native protocols rather than script injection
    • It runs all tests within a single process to minimize memory overhead
    • It bypasses the rendering engine to interact directly with the DOM tree

    Answer: It interacts with the browser engine via native protocols rather than script injection. Playwright uses native protocols (like CDP) to control the browser, which is more reliable than script injection. Script injection (Option B) can be blocked by CSPs or slowed by the main thread, while native control is highly performant. The other options are either technically inaccurate or describe less efficient patterns.

    From lesson: Comparison with other testing tools (Selenium, Cypress, Puppeteer)

  7. How does Playwright handle multi-tab or multi-window scenarios differently than tools that are restricted to a single-tab execution model?

    • It requires a separate browser instance for every new tab opened
    • It manages multiple pages within a single browser context automatically
    • It forces all links to open in the current tab to prevent session loss
    • It relies on the browser's internal session storage to track tabs

    Answer: It manages multiple pages within a single browser context automatically. Playwright treats the browser context as a sandbox that can hold multiple pages, allowing seamless navigation across tabs. Option A is inefficient, C is incorrect as it restricts user flow, and D is not how Playwright manages cross-page state.

    From lesson: Comparison with other testing tools (Selenium, Cypress, Puppeteer)

  8. What is the primary benefit of Playwright’s 'auto-waiting' mechanism during element interaction?

    • It automatically retries a failed assertion until a timeout occurs
    • It waits for the element to be actionable and visible before performing actions
    • It monitors network traffic and stops the test until all requests complete
    • It automatically adjusts the browser's internal refresh rate

    Answer: It waits for the element to be actionable and visible before performing actions. Playwright checks for actionability (visibility, stability, input readiness) before clicking or typing. Option A describes retry logic, not auto-waiting. Option C is over-blocking, and D is irrelevant to automation.

    From lesson: Comparison with other testing tools (Selenium, Cypress, Puppeteer)

  9. In the context of network interception, why does Playwright's native approach offer an advantage over external proxy tools?

    • It allows modification of requests and responses without external service dependencies
    • It forces the test to pause every time a network request is initiated
    • It prevents all network requests from reaching external servers to increase speed
    • It automatically handles SSL certificate errors in every instance

    Answer: It allows modification of requests and responses without external service dependencies. Playwright's page.route() is built-in, meaning no external proxies are needed. Option B would destroy performance. Option C is not always desired for integration tests. Option D is a specific configuration, not the core advantage of network interception.

    From lesson: Comparison with other testing tools (Selenium, Cypress, Puppeteer)

  10. When handling cross-browser testing, why does Playwright prioritize the use of browser contexts?

    • To ensure all browsers use the same memory heap size
    • To create isolated, parallel-ready environments that start nearly instantly
    • To force the browser to clear its cache after every single test step
    • To provide a single GUI interface that mimics every browser engine

    Answer: To create isolated, parallel-ready environments that start nearly instantly. Browser contexts are lightweight, isolated 'incognito' sessions that enable fast parallelization. Option A is hardware-dependent. Option C is bad practice for testing persistence. Option D is impossible as browser engines have distinct rendering behaviors.

    From lesson: Comparison with other testing tools (Selenium, Cypress, Puppeteer)

  11. Which command ensures your project is fully prepared to execute browser automation after adding the Playwright dependency?

    • npm build
    • npx playwright install
    • npm start
    • npx playwright init

    Answer: npx playwright install. npx playwright install downloads the necessary browser binaries. npm build and npm start are project-specific scripts, while npx playwright init is only for initial configuration, not for fetching browser binaries.

    From lesson: Setting up Node.js and Playwright environment

  12. Why is it recommended to use a dedicated 'playwright.config.ts' file instead of defining settings inside each test file?

    • It improves test execution speed significantly.
    • It forces the use of multiple browser contexts.
    • It centralizes project-wide settings like base URLs and timeouts, ensuring consistency.
    • It allows tests to run without the Playwright test runner.

    Answer: It centralizes project-wide settings like base URLs and timeouts, ensuring consistency.. Centralizing settings prevents configuration duplication and errors. Speed is not affected by location, it does not force multiple contexts, and tests cannot run without the runner regardless of configuration location.

    From lesson: Setting up Node.js and Playwright environment

  13. What happens if you attempt to run a Playwright script before installing the required system-level dependencies on a fresh Linux container?

    • The test automatically installs the dependencies for you.
    • The browser will fail to launch because required graphics libraries are missing.
    • The test executes normally using a fallback non-browser mode.
    • The script prompts for sudo credentials to fix the issue.

    Answer: The browser will fail to launch because required graphics libraries are missing.. Browsers require specific Linux shared libraries to render. Playwright does not have permission to install system dependencies, it does not provide a browser-less fallback for standard tests, and it does not prompt for sudo.

    From lesson: Setting up Node.js and Playwright environment

  14. When setting up a project, why is it preferable to define Playwright as a 'devDependencies' rather than a 'dependencies' entry in package.json?

    • It allows the test code to be bundled with the production application.
    • It avoids shipping unnecessary testing infrastructure and browser binaries to the production environment.
    • It enables the tests to run faster in a local environment.
    • It is required by the Playwright CLI to function correctly.

    Answer: It avoids shipping unnecessary testing infrastructure and browser binaries to the production environment.. Dependencies are for production, while devDependencies are for build/test tools. Shipping testing tools to production increases bundle size and security surface. It has no effect on execution speed or CLI functionality.

    From lesson: Setting up Node.js and Playwright environment

  15. If your project uses TypeScript, what is the purpose of including 'ts-node' or configuring the TypeScript compiler in the Playwright environment?

    • To allow Playwright to write test results as TypeScript files.
    • To enable the execution of test files directly without manual transpilation to JavaScript.
    • To speed up the network requests made during test automation.
    • To convert CSS selectors into TypeScript interfaces automatically.

    Answer: To enable the execution of test files directly without manual transpilation to JavaScript.. TypeScript needs to be compiled to be understood by Node.js. Configuring this environment allows Playwright to run tests written in .ts directly. It does not affect network speeds or file formats, nor does it generate CSS interfaces.

    From lesson: Setting up Node.js and Playwright environment

  16. After executing 'npm install playwright', why might your test fail to launch a browser?

    • The browser binaries have not been downloaded to the local machine yet.
    • The node_modules folder is not in the system PATH.
    • The Playwright library requires an active internet connection at runtime.
    • The browsers were installed but the configuration file is missing.

    Answer: The browser binaries have not been downloaded to the local machine yet.. Playwright installs the library code first, but the browsers are large and must be installed separately via 'npx playwright install'. Option 1 is wrong because the PATH is irrelevant here. Option 2 is wrong because an internet connection is only needed during installation, not test execution. Option 3 is wrong because the config file is not strictly required to launch a basic script.

    From lesson: Installing Playwright and its browsers

  17. What is the primary purpose of the 'npx playwright install --with-deps' command?

    • To upgrade all existing Playwright browsers to their latest versions.
    • To install operating system-level dependencies required to run browser engines.
    • To compile TypeScript files into executable JavaScript code.
    • To install third-party plugins from the Playwright ecosystem.

    Answer: To install operating system-level dependencies required to run browser engines.. Browser engines like WebKit require specific system libraries to function correctly; this command ensures these OS dependencies are present. Option 0 is wrong because the command is not a version updater. Option 2 is wrong because this is done by the transpiler, not the install command. Option 3 is wrong because the command is specifically for browser and system environment preparation.

    From lesson: Installing Playwright and its browsers

  18. If you are working in a restricted network environment, how can you manage Playwright browser installations?

    • By manually copying the binaries from another user's 'ms-playwright' folder.
    • By using the 'PLAYWRIGHT_BROWSERS_PATH' environment variable to point to a local network mirror.
    • By forcing the installation via a global npm cache.
    • By installing the browsers as separate npm packages.

    Answer: By using the 'PLAYWRIGHT_BROWSERS_PATH' environment variable to point to a local network mirror.. The 'PLAYWRIGHT_BROWSERS_PATH' variable allows you to define a custom directory, which is essential for network-restricted environments using local mirrors. Option 0 is unreliable and prone to permission errors. Option 2 is wrong because the cache does not solve the download location. Option 3 is wrong because Playwright does not distribute browsers as individual npm packages.

    From lesson: Installing Playwright and its browsers

  19. Why does Playwright manage its own browser binaries rather than using system-installed browsers?

    • To save disk space by using shared libraries.
    • To allow users to select browsers from the system PATH.
    • To ensure the browser version is patched and compatible with the specific Playwright API version.
    • To bypass the need for browser updates.

    Answer: To ensure the browser version is patched and compatible with the specific Playwright API version.. Playwright uses specific browser builds tested for stability with its automation protocol; version mismatch can lead to flaky tests. Option 0 is wrong because it often uses more space. Option 1 is wrong because it explicitly avoids system-installed browsers. Option 3 is wrong because updates are still necessary for security.

    From lesson: Installing Playwright and its browsers

  20. Which file is essential for configuring browser settings, such as viewport size and timeout, before tests run?

    • package.json
    • playwright.config.ts
    • browsers.json
    • index.js

    Answer: playwright.config.ts. 'playwright.config.ts' is the central configuration file used to define test projects and browser options. Option 0 is for project metadata. Option 2 is not a standard Playwright file. Option 3 is just a generic script file and lacks the structured configuration capabilities required by the Playwright test runner.

    From lesson: Installing Playwright and its browsers

  21. When you call 'page.click()', what does Playwright do before performing the action?

    • It immediately clicks the element coordinates
    • It performs a series of actionability checks like visibility and stability
    • It captures a screenshot of the entire page
    • It waits for a manual user trigger

    Answer: It performs a series of actionability checks like visibility and stability. Playwright automatically performs actionability checks (visible, stable, enabled) to ensure the click is successful. The other options are incorrect because immediate clicking causes race conditions, capturing screenshots is an optional utility, and the process is automated, not manual.

    From lesson: Running your first Playwright test

  22. Why is 'getByRole' preferred over CSS or XPath selectors in Playwright?

    • It is faster at executing the test
    • It automatically converts CSS to XPath
    • It mimics how a user or screen reader interacts with the page
    • It is the only selector type that supports regex

    Answer: It mimics how a user or screen reader interacts with the page. getByRole helps ensure accessibility and UI robustness, mimicking user interaction. Faster execution is not the primary benefit, it does not convert CSS to XPath, and other locators also support regex.

    From lesson: Running your first Playwright test

  23. What happens if a test script executes a command without an 'await' keyword?

    • Playwright throws a syntax error
    • The test will always pass instantly
    • The command is queued to run at the end of the test
    • The test proceeds before the action finishes, causing flaky behavior

    Answer: The test proceeds before the action finishes, causing flaky behavior. Without 'await', the test script does not pause for the asynchronous operation to finish. A syntax error is not thrown by the engine, the test won't always pass, and commands are not queued to the end.

    From lesson: Running your first Playwright test

  24. What is the primary benefit of using Web-First assertions like 'expect(locator).toBeVisible()'?

    • They automatically retry the assertion until the condition is met or a timeout occurs
    • They bypass the need to define locators
    • They force the browser to restart for a clean state
    • They convert the element to a JSON object

    Answer: They automatically retry the assertion until the condition is met or a timeout occurs. Web-First assertions use built-in polling to handle dynamic content updates, reducing flakiness. They don't bypass locators, they don't restart the browser, and they do not return JSON objects.

    From lesson: Running your first Playwright test

  25. How should you handle an element that takes time to appear on the page?

    • Use a fixed time delay like 'page.waitForTimeout(5000)'
    • Use Playwright's built-in locator visibility assertions
    • Use a 'try-catch' block to retry the element selection
    • Manually click the refresh button until the element shows

    Answer: Use Playwright's built-in locator visibility assertions. Playwright locators and assertions have built-in waiting logic that is more efficient than fixed timeouts. Using 'waitForTimeout' leads to slow tests, 'try-catch' is unnecessary complexity, and manual refreshing defeats the purpose of automation.

    From lesson: Running your first Playwright test

  26. Why does Playwright recommend using locators that reflect user-facing attributes (like getByRole) over CSS or XPath selectors?

    • They are faster to execute in the browser engine.
    • They resemble how a real user interacts with the page, making tests more resilient to DOM changes.
    • CSS and XPath selectors are deprecated in the latest version of Playwright.
    • They are the only way to trigger JavaScript event listeners.

    Answer: They resemble how a real user interacts with the page, making tests more resilient to DOM changes.. Option 2 is correct because user-facing locators focus on accessibility and structure, which rarely change. CSS/XPath are implementation details prone to breaking; they are not deprecated (making 3 wrong), and they aren't inherently faster or required for JS listeners (making 1 and 4 wrong).

    From lesson: Understanding Playwright Test Runner

  27. What happens when you perform an action like 'page.click()' on a button that is currently hidden by an overlay?

    • Playwright clicks the element regardless of visibility.
    • Playwright throws an immediate error.
    • Playwright automatically waits for the element to become actionable, then clicks it.
    • Playwright fails the test immediately because it assumes the page is broken.

    Answer: Playwright automatically waits for the element to become actionable, then clicks it.. Playwright performs actionability checks. It will wait for the element to be visible and stable. It does not click blindly (1), throw immediate errors if it can wait (2), or assume a broken page (4).

    From lesson: Understanding Playwright Test Runner

  28. When running tests in parallel, what is the primary risk of using global variables to store test state?

    • Tests will run in serial instead of parallel.
    • The browser engine will run out of memory.
    • Data leakage between tests, leading to flaky and non-deterministic results.
    • Playwright will prevent the tests from starting.

    Answer: Data leakage between tests, leading to flaky and non-deterministic results.. Global variables are shared memory. In parallel execution, multiple tests can mutate these variables simultaneously, causing state contamination (3). This doesn't force serial execution (1), crash memory (2), or block startup (4).

    From lesson: Understanding Playwright Test Runner

  29. Which of the following best describes the purpose of 'expect(locator).toBeVisible()' in a test?

    • It triggers a re-render of the component.
    • It is a hard assertion that polls the DOM until the condition is met or the timeout expires.
    • It validates that the element has a CSS display property of block.
    • It tells the browser to skip any further network requests.

    Answer: It is a hard assertion that polls the DOM until the condition is met or the timeout expires.. The Web-First assertion 'toBeVisible()' includes a retry logic that polls the DOM, which is essential for dynamic apps (2). It does not force re-renders (1), check specific CSS properties like 'block' (3), or influence network traffic (4).

    From lesson: Understanding Playwright Test Runner

  30. If you have a 'beforeEach' hook, when exactly does it execute in relation to the test file?

    • Once before all tests in the file run.
    • Before every single 'test()' block defined in the file.
    • Only when a test fails, to reset the state.
    • After the browser context is destroyed.

    Answer: Before every single 'test()' block defined in the file.. The 'beforeEach' hook is designed to set up state for every test case individually to ensure isolation (2). Option 1 describes 'beforeAll', while 3 and 4 are logically incorrect for test setup flow.

    From lesson: Understanding Playwright Test Runner

  31. What is the primary benefit of using Web-First assertions in Playwright?

    • They execute faster by bypassing the browser's rendering engine.
    • They automatically retry until the condition is met or the timeout is reached.
    • They allow for synchronous code execution within asynchronous tests.
    • They force the browser to clear the cache before validation.

    Answer: They automatically retry until the condition is met or the timeout is reached.. Web-First assertions are designed to poll the DOM until a condition is met, reducing flakiness. The other options are incorrect because they describe features not inherent to these assertions or fundamentally misunderstand how the framework handles asynchronous browser interactions.

    From lesson: Basic test structure and assertions

  32. If you write 'expect(locator).toBeVisible()', what happens if the element is currently hidden but appears after 500ms?

    • The test fails immediately.
    • The test throws a timeout exception.
    • The assertion waits and passes once the element appears.
    • The assertion skips the check.

    Answer: The assertion waits and passes once the element appears.. Because expect() uses automatic retries, it waits for the condition to become true within the default timeout period. It does not fail immediately or skip the check, and it only throws an exception if the timeout is reached.

    From lesson: Basic test structure and assertions

  33. Which of the following describes the correct behavior of the 'await' keyword in Playwright assertions?

    • It is optional for simple assertions like toBeVisible.
    • It pauses the test execution entirely until the browser process restarts.
    • It ensures the assertion promise resolves before moving to the next line of code.
    • It converts a sync assertion into an async one.

    Answer: It ensures the assertion promise resolves before moving to the next line of code.. Playwright assertions are asynchronous functions that return promises. Awaiting them is mandatory to ensure the test runner pauses until the assertion has successfully validated the state. Without 'await', the test might finish or proceed prematurely.

    From lesson: Basic test structure and assertions

  34. Why should you prefer 'expect(locator).toHaveText()' over 'const text = await locator.textContent(); expect(text).toBe(...)'?

    • The second approach lacks the built-in retry mechanism for the text state.
    • The first approach runs on the server side instead of the browser.
    • The second approach requires a separate browser session.
    • The first approach is only compatible with CSS locators.

    Answer: The second approach lacks the built-in retry mechanism for the text state.. The second approach manually extracts the text, meaning it only checks the value at that exact millisecond. The first approach uses the built-in retry logic, which is more robust if the text updates dynamically. The other options are false as the extraction method doesn't change the execution environment.

    From lesson: Basic test structure and assertions

  35. When a test is structured with 'test('description', async ({ page }) => { ... })', what is the role of the 'page' fixture?

    • It acts as a global variable that must be defined manually.
    • It provides an isolated, fresh browser context for the specific test.
    • It serves as a static configuration file for all tests.
    • It is used to define test dependencies only.

    Answer: It provides an isolated, fresh browser context for the specific test.. The 'page' fixture provides an isolated environment for the test, ensuring tests are independent. Option 0 is wrong because the fixture is injected by the runner. Option 2 is wrong because it's an instance, not a config file. Option 3 is wrong as it is a browser interface, not a dependency manager.

    From lesson: Basic test structure and assertions

  36. When configuring multiple reporters, how does Playwright handle them during a test execution?

    • It only executes the last reporter defined in the configuration array
    • It executes all defined reporters in parallel for each test event
    • It stops at the first reporter that successfully generates output
    • It requires a specific 'master' reporter to be defined at the top of the list

    Answer: It executes all defined reporters in parallel for each test event. Playwright allows multiple reporters; they all receive the same event stream simultaneously. Option 0 and 2 are incorrect because Playwright processes the full configuration list, and option 3 is false as there is no 'master' reporter concept.

    From lesson: Generating and viewing test reports

  37. If you need to view a report generated on a remote CI server locally, what is the best approach?

    • Copy the HTML file alone to your machine and open it
    • Download the entire report directory and serve it using 'npx playwright show-report'
    • Take screenshots of the HTML report and share them
    • Re-run the tests locally to ensure consistency

    Answer: Download the entire report directory and serve it using 'npx playwright show-report'. To preserve functionality like filtering and trace viewing, the full report folder must be moved. Opening just the HTML file (Option 0) fails due to CORS, and the other options do not maintain the report's interactivity.

    From lesson: Generating and viewing test reports

  38. What is the primary benefit of enabling 'trace: on' when generating reports for failed tests?

    • It reduces the total time taken to generate the final HTML report
    • It records video of the test which is automatically embedded in the HTML
    • It provides a time-traveling debug experience showing the state of the DOM at every action
    • It automatically fixes the CSS selectors that caused the test failure

    Answer: It provides a time-traveling debug experience showing the state of the DOM at every action. Traces provide a comprehensive post-mortem view including snapshots and network logs. It does not reduce execution time (0), is not a video file (1), and does not fix code (3).

    From lesson: Generating and viewing test reports

  39. How does Playwright handle report generation when tests are executed in parallel across multiple workers?

    • Each worker generates a separate, isolated report that cannot be merged
    • Playwright aggregates the results from all workers into a single report object before finalizing
    • Only the test results from the first worker are included in the output
    • The HTML reporter requires a custom plugin to handle parallel output

    Answer: Playwright aggregates the results from all workers into a single report object before finalizing. Playwright's reporter architecture is designed to collect data from all workers and consolidate it into one coherent report. It does not isolate reports (0), ignore workers (2), or require plugins (3).

    From lesson: Generating and viewing test reports

  40. What is the consequence of setting the 'open' property to 'always' in the HTML reporter configuration?

    • The report will force an automatic upload to the Playwright cloud service
    • The report will be opened in your default system browser immediately after the test run finishes
    • The HTML report will overwrite previous report files without asking for confirmation
    • The test suite will fail if the browser fails to open the report

    Answer: The report will be opened in your default system browser immediately after the test run finishes. The 'open' configuration property controls the local browser behavior post-execution. It does not involve cloud services (0), is unrelated to overwriting (2), and does not cause test failures (3).

    From lesson: Generating and viewing test reports

  41. When testing a login form, which locator strategy is most resilient to design changes?

    • A CSS selector targeting the class name of the input field
    • An XPath expression pointing to the third input on the page
    • A getByLabel locator targeting the label 'Username'
    • Selecting the element by its computed pixel coordinates

    Answer: A getByLabel locator targeting the label 'Username'. getByLabel is best because it relies on the accessible name, which stays consistent even if the CSS class or DOM hierarchy changes. CSS and XPath are fragile, and coordinates are highly prone to breaking across screen resolutions.

    From lesson: Working with selectors and locators

  42. What happens when you use multiple locator chains, such as 'page.locator('.sidebar').locator('button')'?

    • Playwright throws an error because locators cannot be chained
    • It limits the scope of the second locator to descendants of the first
    • It forces the browser to find all buttons first, then filter by sidebar
    • It creates a race condition between the two elements

    Answer: It limits the scope of the second locator to descendants of the first. Chaining locators narrows the search context to the sub-tree defined by the first locator. The other options are incorrect because chaining is a core feature, it is efficient, and it does not cause race conditions.

    From lesson: Working with selectors and locators

  43. Why is 'getByRole' preferred over other locator methods?

    • It is the only method that supports regular expressions
    • It is the fastest method to execute in the browser engine
    • It encourages accessible web design while providing stable test locators
    • It bypasses the need for the browser to render the page

    Answer: It encourages accessible web design while providing stable test locators. getByRole forces developers to consider accessibility (ARIA roles). It is stable because roles rarely change. The other options are false; other methods support regex, it is not inherently faster than others, and it definitely requires the page to be rendered.

    From lesson: Working with selectors and locators

  44. If an element is located inside a shadow DOM, how does Playwright handle it?

    • You must manually switch the context to the shadow root
    • Playwright locators penetrate shadow roots by default
    • You must use a special XPath extension to reach it
    • Shadow DOM elements are invisible to Playwright locators

    Answer: Playwright locators penetrate shadow roots by default. Playwright's locators transparently cross shadow DOM boundaries, so no extra configuration is required. The other options suggest manual intervention or limitations that do not exist in Playwright.

    From lesson: Working with selectors and locators

  45. What is the primary benefit of using 'filter' on a locator?

    • It increases the speed of the browser's JavaScript execution
    • It allows you to narrow down a large list of elements based on child content
    • It forces the element to become visible before the test proceeds
    • It replaces the need for writing custom assertion logic

    Answer: It allows you to narrow down a large list of elements based on child content. Filter is used to refine a locator when multiple elements match (e.g., finding a specific row in a table by its text). It does not affect browser speed, force visibility, or replace assertions.

    From lesson: Working with selectors and locators

  46. How should you handle a custom dropdown built with `<div>` elements in Playwright?

    • Use `locator('select')` and `selectOption()`
    • Use `locator('div.dropdown')` with `click()` and then `click()` on the desired `<li>`
    • Assume it’s a native `<select>` and use `selectOption()` directly
    • Use `page.keyboard` to navigate with arrow keys

    Answer: Use `locator('div.dropdown')` with `click()` and then `click()` on the desired `<li>`. Option 1 is wrong because `selectOption()` only works for native `<select>` elements. Option 3 is incorrect for the same reason. Option 4 is unreliable for custom dropdowns. Option 2 is correct: interact with the dropdown container and then the specific option.

    From lesson: Handling different types of elements (buttons, inputs, dropdowns)

  47. What’s the best way to ensure a button is clickable before interacting with it?

    • Add a fixed `await page.waitForTimeout(2000)` delay
    • Use `await expect(buttonLocator).toBeVisible()` followed by `click()`
    • Assume Playwright’s auto-waiting is sufficient for all cases
    • Use `buttonLocator.isEnabled()` in a loop until it returns `true`

    Answer: Use `await expect(buttonLocator).toBeVisible()` followed by `click()`. Option 0 is flaky and slow. Option 2 is incorrect because auto-waiting doesn’t account for visibility/state changes. Option 3 is unreliable for dynamic UIs. Option 1 is correct: `toBeVisible()` ensures the button is ready for interaction.

    From lesson: Handling different types of elements (buttons, inputs, dropdowns)

  48. How would you test a form where the submit button is disabled until all fields are valid?

    • Click the button without checking its state and expect an error
    • Use `expect(buttonLocator).toBeDisabled()` before filling fields, then verify it becomes enabled
    • Assume the button is always enabled and proceed with submission
    • Use `page.evaluate()` to manually enable the button before clicking

    Answer: Use `expect(buttonLocator).toBeDisabled()` before filling fields, then verify it becomes enabled. Option 0 would fail the test. Option 2 is incorrect because it bypasses the intended behavior. Option 3 is wrong because it doesn’t test the disabled state. Option 1 is correct: verify the button’s state reflects the form’s validity.

    From lesson: Handling different types of elements (buttons, inputs, dropdowns)

  49. What’s the most maintainable way to locate an input field with dynamic IDs?

    • Use `page.locator('#input-' + dynamicId)` with string concatenation
    • Use `data-testid` or `aria-label` attributes in the selector
    • Rely on XPath like `//input[contains(@id, 'input-')]`
    • Use `page.getByPlaceholder('Enter text')` if the placeholder is unique

    Answer: Use `data-testid` or `aria-label` attributes in the selector. Option 0 is brittle if `dynamicId` changes. Option 2 is fragile and hard to maintain. Option 3 is correct but less readable than semantic attributes. Option 1 is best: `data-testid` or `aria-label` are stable and explicit.

    From lesson: Handling different types of elements (buttons, inputs, dropdowns)

  50. How should you handle a dropdown where options are loaded via API after clicking it?

    • Assume options are present immediately and use `selectOption()`
    • Click the dropdown, wait for a network request to complete, then select the option
    • Use `page.waitForSelector()` with a long timeout for the option
    • Mock the API response to return options instantly

    Answer: Click the dropdown, wait for a network request to complete, then select the option. Option 0 fails if options aren’t loaded. Option 2 is flaky without waiting for the API. Option 3 is correct but less precise than waiting for the API. Option 1 is best: combine UI interaction with network request waiting (e.g., `waitForResponse()`).

    From lesson: Handling different types of elements (buttons, inputs, dropdowns)

  51. When is it appropriate to use a hardcoded timeout like `page.waitForTimeout()`?

    • When an element takes more than 30 seconds to appear on the screen.
    • When testing animations or deliberate delays where no assertion can track the state.
    • To ensure the browser has time to finish rendering before taking a screenshot.
    • Never, it should be avoided entirely in production test suites.

    Answer: Never, it should be avoided entirely in production test suites.. Option 3 is the only acceptable answer because hardcoded waits are anti-patterns that induce flakiness. Option 1 is incorrect because you should use a custom timeout on an assertion, not a fixed sleep. Option 2 is a common misconception; animations should be bypassed or handled by checking the final state. Option 3 is incorrect because assertions handle readiness.

    From lesson: Managing waits and timeouts effectively

  52. A test fails because an element is present in the DOM but hidden by a loading spinner. How should you handle this?

    • Increase the default global timeout in the config file.
    • Use `page.waitForTimeout()` to wait for the spinner to disappear.
    • Use an assertion like `expect(locator).toBeVisible()` to trigger Playwright's auto-waiting.
    • Use `page.reload()` until the element is clickable.

    Answer: Use an assertion like `expect(locator).toBeVisible()` to trigger Playwright's auto-waiting.. Option 2 is the correct approach because Web-First assertions automatically wait for the element to meet actionability criteria (visibility, stability). Option 0 is a workaround that doesn't fix the race condition. Option 1 is an anti-pattern. Option 3 is inefficient and unreliable.

    From lesson: Managing waits and timeouts effectively

  53. What happens if you use `page.click('button')` on an element that is currently obscured by a transparent overlay?

    • Playwright waits until the element is actionable (no longer obscured) before clicking.
    • Playwright throws an error immediately because the element is not reachable.
    • Playwright clicks the overlay instead of the button.
    • Playwright ignores the overlay and clicks the button regardless.

    Answer: Playwright waits until the element is actionable (no longer obscured) before clicking.. Playwright's auto-waiting mechanism performs actionability checks, including checking if the element is obscured by other elements. Option 1 is wrong because it waits, not fails. Options 2 and 3 are incorrect because Playwright avoids ambiguous actions by waiting for the element to be ready.

    From lesson: Managing waits and timeouts effectively

  54. Why is `expect(locator).toHaveText('Success')` preferred over `await page.innerText('selector')` followed by a manual comparison?

    • Because `innerText` is deprecated in Playwright.
    • Because the assertion automatically retries until the text matches, whereas manual retrieval happens only once.
    • Because `innerText` cannot handle dynamic content.
    • Because `innerText` requires a separate `waitForSelector` call every time.

    Answer: Because the assertion automatically retries until the text matches, whereas manual retrieval happens only once.. Option 1 is correct because Web-First assertions implement a retry-loop that polls the element state. Option 0 is false. Option 2 is false. Option 3 is incorrect as `innerText` just returns a single snapshot, which is often insufficient for dynamic web applications.

    From lesson: Managing waits and timeouts effectively

  55. If your tests are consistently timing out on CI but passing locally, what is the most robust strategy?

    • Add a blanket `waitForTimeout` of 10 seconds to every step.
    • Use `page.waitForLoadState('networkidle')` at the start of every test.
    • Increase the test timeout globally in the config and improve the efficiency of the assertions.
    • Reduce the number of assertions to speed up the test execution.

    Answer: Increase the test timeout globally in the config and improve the efficiency of the assertions.. Option 2 is the best practice as it addresses environment-specific slowness by adjusting the timeout limit, while keeping the logic resilient. Option 0 is a bad practice. Option 1 is unreliable. Option 3 is wrong because removing assertions reduces test coverage.

    From lesson: Managing waits and timeouts effectively

  56. What is the primary reason to use frameLocator instead of standard locators when dealing with an iframe?

    • It provides a higher performance execution speed for the entire test suite
    • It allows the locator engine to properly scope element selection to the iframe's isolated document context
    • It prevents the browser from crashing when multiple frames are present
    • It automatically bypasses all cross-origin security policies imposed by the browser

    Answer: It allows the locator engine to properly scope element selection to the iframe's isolated document context. Option 2 is correct because iframes create separate document contexts; standard locators look at the top-level document by default. Option 1 is false as it doesn't impact performance, Option 3 is irrelevant to performance, and Option 4 is false because Playwright must still respect browser security policies.

    From lesson: Working with frames and iframes

  57. If you have a nested structure (iframe inside an iframe), what is the correct approach to access an element in the inner frame?

    • Use page.frameLocator('first').frameLocator('second').locator('target')
    • Use page.locator('first >> second >> target')
    • Access the parent frame handle first and then use the executeScript method
    • Target the inner frame directly using a CSS selector string in page.locator()

    Answer: Use page.frameLocator('first').frameLocator('second').locator('target'). Option 0 is correct because frameLocators can be chained to drill down into nested frames. Option 1 is incorrect syntax for frames, Option 2 is an anti-pattern that circumvents Playwright's frame API, and Option 3 is incorrect as CSS selectors cannot pierce iframe boundaries.

    From lesson: Working with frames and iframes

  58. When does Playwright evaluate the selector provided to a frameLocator?

    • Immediately when the line of code is executed
    • Only after the page.waitForLoadState('networkidle') method is called
    • Every time an action is performed on an element resolved by that locator
    • Once at the start of the test execution

    Answer: Every time an action is performed on an element resolved by that locator. Option 2 is correct because Playwright locators are lazy and perform retry-ability; it evaluates the selector at the moment of action. The others are incorrect because they imply static or immediate evaluation, which contradicts Playwright's dynamic locator model.

    From lesson: Working with frames and iframes

  59. Which of the following is true regarding frameLocators and auto-waiting?

    • FrameLocators do not support auto-waiting, so you must add manual waits
    • Auto-waiting is only supported for the main frame
    • FrameLocators automatically wait for the iframe to be attached to the DOM before locating elements
    • You must use a separate waitForFrame method before calling frameLocator

    Answer: FrameLocators automatically wait for the iframe to be attached to the DOM before locating elements. Option 2 is correct as part of the framework's design to ensure stability. Option 0 and 1 are incorrect as frameLocators are first-class citizens in auto-waiting, and Option 3 is redundant since the locator handle manages the attachment state automatically.

    From lesson: Working with frames and iframes

  60. What happens if a frame is removed from the DOM and then re-added during a test?

    • The frameLocator will throw a permanent error
    • The test will crash because handles are immutable
    • Playwright will re-resolve the frame locator, making it resilient to the change
    • The test must be restarted from the beginning

    Answer: Playwright will re-resolve the frame locator, making it resilient to the change. Option 2 is correct because Playwright's locator strategy is designed to be resilient to re-rendering. Options 0, 1, and 3 are incorrect as they describe brittle test behavior that Playwright specifically avoids through its locator architecture.

    From lesson: Working with frames and iframes

  61. What is the correct way to handle a browser-native alert that appears after clicking a button?

    • Use `page.locator('button').click()` followed by `page.acceptAlert()`.
    • Register a `page.on('dialog', ...)` handler *before* clicking the button, then call `dialog.accept()`.
    • Use `page.waitForSelector('alert')` to wait for the alert, then interact with it.
    • Call `page.evaluate(() => alert('handled'))` to override the alert.

    Answer: Register a `page.on('dialog', ...)` handler *before* clicking the button, then call `dialog.accept()`.. The right answer registers a dialog handler *before* the action that triggers the alert, ensuring the dialog is captured. Option 1 is wrong because `acceptAlert()` doesn’t exist. Option 3 is wrong because native alerts aren’t DOM elements. Option 4 is wrong because it doesn’t handle the actual alert.

    From lesson: Handling popups, dialogs, and alerts

  62. How do you test that a custom modal (e.g., a `<div>` styled as a dialog) is visible after an action?

    • Use `page.on('dialog', ...)` to listen for the modal.
    • Use `page.waitForSelector('.modal', { state: 'visible' })` after triggering the action.
    • Call `page.isVisible('.modal')` immediately after the action.
    • Use `page.evaluate(() => document.querySelector('.modal').showModal())`.

    Answer: Use `page.waitForSelector('.modal', { state: 'visible' })` after triggering the action.. The right answer waits for the modal to become visible, accounting for potential delays. Option 0 is wrong because custom modals aren’t native dialogs. Option 2 is wrong because it doesn’t wait for visibility. Option 3 is wrong because it manually triggers the modal instead of testing the actual behavior.

    From lesson: Handling popups, dialogs, and alerts

  63. What happens if you forget to call `dialog.accept()` or `dialog.dismiss()` in a dialog handler?

    • The test passes, but the dialog remains open in the browser.
    • The test hangs indefinitely because Playwright waits for the dialog to be handled.
    • Playwright automatically dismisses the dialog after a timeout.
    • The test fails with an error about an unhandled dialog.

    Answer: The test hangs indefinitely because Playwright waits for the dialog to be handled.. The right answer is that the test hangs because Playwright waits for the dialog to be explicitly handled. Option 0 is wrong because the test doesn’t pass. Option 2 is wrong because Playwright doesn’t auto-dismiss. Option 3 is wrong because the error occurs only if no handler is registered at all.

    From lesson: Handling popups, dialogs, and alerts

  64. How do you verify the text of a native confirm dialog before accepting it?

    • Use `page.textContent('body')` to read the dialog text.
    • Access `dialog.message()` in the handler and assert on it before calling `dialog.accept()`.
    • Use `page.screenshot()` to capture the dialog and OCR the text.
    • Call `page.evaluate(() => confirm('expected text'))` to override the message.

    Answer: Access `dialog.message()` in the handler and assert on it before calling `dialog.accept()`.. The right answer uses `dialog.message()` to inspect the text. Option 0 is wrong because native dialogs aren’t part of the DOM. Option 2 is wrong because it’s overcomplicating the solution. Option 3 is wrong because it doesn’t verify the actual dialog text.

    From lesson: Handling popups, dialogs, and alerts

  65. Why might a test fail if you register a dialog handler *after* triggering the action that opens the dialog?

    • The handler is registered too late and misses the dialog event.
    • Playwright requires handlers to be registered in a specific order.
    • The dialog is automatically dismissed before the handler is registered.
    • The test will pass, but the dialog handling is slower.

    Answer: The handler is registered too late and misses the dialog event.. The right answer is that the handler might miss the dialog event if registered too late. Option 1 is wrong because order isn’t the issue—timing is. Option 2 is wrong because Playwright doesn’t auto-dismiss. Option 3 is wrong because the test fails, not just slows down.

    From lesson: Handling popups, dialogs, and alerts

  66. When navigating to a new URL, why is it safer to use a web-first assertion (expect(page).toHaveURL) rather than checking the URL immediately after the goto command?

    • The goto command does not actually navigate the page.
    • Navigations are asynchronous and the browser may still be in the process of redirecting.
    • Playwright cannot track the current URL after navigation.
    • The goto command automatically blocks all assertions.

    Answer: Navigations are asynchronous and the browser may still be in the process of redirecting.. Navigations can involve redirects or load state changes that aren't finished immediately. Option 1 is false because goto does navigate. Option 3 is false as Playwright tracks URL state well. Option 4 is false as assertions are independent. Option 2 is correct because it acknowledges the asynchronous nature of browser state.

    From lesson: Page navigation and history management

  67. If you need to perform an action that triggers a navigation, what is the best practice to ensure the test does not continue until the navigation is finished?

    • Wrap the action in a Promise.all with page.waitForNavigation().
    • Add a 5-second sleep after the action.
    • Use page.reload() after the action.
    • Call page.waitForLoadState() before the action.

    Answer: Wrap the action in a Promise.all with page.waitForNavigation().. Promise.all(action, waitForNavigation) ensures the listener is active exactly when the navigation starts. Sleeping (Option 1) is unstable. Reloading (Option 2) is redundant. Calling waitForLoadState before (Option 4) waits for the current state, not the future navigation.

    From lesson: Page navigation and history management

  68. How should you handle a situation where a button click opens a link in a new tab?

    • Just use page.click() and then continue using the original page object.
    • Use context.waitForEvent('page') to wait for the new page object before interacting with it.
    • Navigate to the link's URL directly using page.goto().
    • Close the original page and only use the new tab.

    Answer: Use context.waitForEvent('page') to wait for the new page object before interacting with it.. New tabs are separate Page objects within the BrowserContext. Option 1 fails because the new tab isn't automatically bound to the old page object. Option 3 ignores the actual trigger. Option 4 is destructive. Option 2 correctly captures the new instance.

    From lesson: Page navigation and history management

  69. What does the 'networkidle' state in 'waitForLoadState' actually guarantee?

    • The DOM content has been parsed, but scripts are still loading.
    • All visual images have finished downloading.
    • No network connections are active for at least 500ms.
    • The user has finished interacting with the page.

    Answer: No network connections are active for at least 500ms.. Networkidle implies a period of inactivity for network resources. Option 1 describes DOMContentLoaded. Option 2 is specific to resources, not the idle state. Option 4 is subjective and not controlled by the browser state.

    From lesson: Page navigation and history management

  70. Why might a navigation triggered by a history button (goBack or goForward) fail to be detected?

    • History buttons are disabled by default in Playwright.
    • The browser history stack is cleared after every test.
    • The navigation takes time to resolve and the test proceeds too quickly.
    • Playwright requires a page refresh to detect history changes.

    Answer: The navigation takes time to resolve and the test proceeds too quickly.. Asynchronous navigation is the common point of failure. Option 1 is false, as history navigation works fine. Option 2 is irrelevant to the execution speed. Option 4 is incorrect because Playwright tracks state without manual refreshes. Option 2 is correct because the test runner must wait for the transition to complete.

    From lesson: Page navigation and history management

  71. How do you correctly capture a new page opened by a user interaction in Playwright?

    • page.waitForNewPage()
    • context.waitForEvent('page')
    • browser.newPage()
    • page.on('popup')

    Answer: context.waitForEvent('page'). context.waitForEvent('page') is the recommended approach to asynchronously wait for and return the new page instance. Option 0 is not a valid method; option 2 creates a new blank page; option 3 is an event listener but is less concise than the waitForEvent pattern.

    From lesson: Working with multiple pages and tabs

  72. If you perform an action that triggers a new tab, why must you capture that tab via a promise-based event listener?

    • Because the new tab is a separate process
    • Because the browser needs to be restarted
    • Because the new tab may open before the code reaches the check
    • Because Playwright requires manual synchronization

    Answer: Because the new tab may open before the code reaches the check. A race condition exists where the tab opens after the click but before your next line of code executes. The waitForEvent mechanism ensures the code waits for the event to fire. The other options are incorrect interpretations of Playwright's architecture.

    From lesson: Working with multiple pages and tabs

  73. When working with multiple pages in the same browser context, what happens if you close the context?

    • Only the main page closes
    • All pages within that context are terminated
    • The browser stays open but pages refresh
    • The background processes continue indefinitely

    Answer: All pages within that context are terminated. A browser context is a container for pages; closing it closes everything inside it. Options 0, 2, and 3 are technically incorrect regarding the isolation provided by contexts.

    From lesson: Working with multiple pages and tabs

  74. Why should you avoid using a generic 'page' variable when juggling multiple browser tabs?

    • It leads to race conditions between page actions
    • It causes high memory usage
    • Playwright prevents using the same variable name
    • It breaks the test execution order

    Answer: It leads to race conditions between page actions. Overwriting a 'page' variable causes the script to lose the reference to the original tab, leading to errors when attempting to interact with the wrong window. The other options are not the primary reason for this best practice.

    From lesson: Working with multiple pages and tabs

  75. Which method is best suited for closing a specific page without ending the entire browser session?

    • context.close()
    • browser.close()
    • page.close()
    • page.reload()

    Answer: page.close(). page.close() specifically terminates the current page instance. context.close() terminates all pages in the context, and browser.close() ends the entire instance; page.reload() simply refreshes the current content.

    From lesson: Working with multiple pages and tabs

  76. When using page.route() to mock an API response, what is the best way to ensure the mock only applies to a specific API endpoint while ignoring static assets?

    • Use a string pattern that matches the exact URL of the API endpoint.
    • Use a glob pattern that matches the specific API path structure.
    • Use a function that returns true only if the URL contains the specific API path.
    • Include all URL patterns in a single route call.

    Answer: Use a function that returns true only if the URL contains the specific API path.. A function in page.route() provides the most flexibility, allowing you to filter by URL, method, or headers. String matches are too rigid for dynamic environments, globs are better for files but less precise for API logic, and putting all patterns in one call is less maintainable.

    From lesson: Network request interception and mocking

  77. If you want to simulate a slow network for a specific request using page.route(), how should you implement the handler?

    • Use route.continue() and wait for a fixed amount of time.
    • Use a custom timeout in the browser context configuration.
    • Use route.fulfill() after a programmatic delay inside the handler.
    • Use the page.waitForTimeout() method before the route is called.

    Answer: Use route.fulfill() after a programmatic delay inside the handler.. route.fulfill() allows you to control exactly when the response is returned. By introducing a delay inside the handler before calling fulfill, you simulate latency. The other options either block the whole test execution or fail to specifically target the mocked response.

    From lesson: Network request interception and mocking

  78. Why would you choose route.abort() instead of route.fulfill() for a specific request in your test?

    • To speed up the test by skipping the network round trip.
    • To simulate a network failure or a 403 Forbidden error effectively.
    • To bypass security checks that might trigger during a standard fulfill.
    • To allow the request to proceed to the server without modification.

    Answer: To simulate a network failure or a 403 Forbidden error effectively.. route.abort() is the standard way to test how your application handles failed network requests or connection errors. route.fulfill() returns a successful (or customized) response, not an error state; speeding up the test is not the primary purpose, and it does not pass through to the server.

    From lesson: Network request interception and mocking

  79. How do you modify the body of a request before it reaches the server using page.route()?

    • By calling route.continue({ postData: modifiedData }).
    • By calling route.fulfill({ body: modifiedData }).
    • By changing the page.request object before the route handler finishes.
    • By setting the request header with the new data.

    Answer: By calling route.continue({ postData: modifiedData }).. route.continue() accepts an options object that allows you to override request attributes like headers or postData. route.fulfill() sends a response back to the client, it does not send data to the server. Request objects are not directly mutable.

    From lesson: Network request interception and mocking

  80. What happens if you have two route handlers registered that both match the same request URL?

    • Both handlers execute sequentially.
    • The first handler registered is the only one that executes.
    • The last handler registered is the only one that executes.
    • An error is thrown indicating duplicate handlers.

    Answer: The last handler registered is the only one that executes.. In Playwright, the last handler registered takes precedence for a matching URL. This allows for clean overrides in setup logic. The other options describe behaviors that contradict Playwright's route precedence rules.

    From lesson: Network request interception and mocking

  81. What is the primary benefit of using multiple projects within the playwright.config file?

    • To allow tests to run in parallel using different hardware
    • To run the same test suite with different configurations like browsers, devices, or base URLs
    • To force tests to run in a specific sequential order
    • To separate the reporting tools for different operating systems

    Answer: To run the same test suite with different configurations like browsers, devices, or base URLs. Projects are designed to run the same test suite under different conditions (e.g., mobile vs desktop). Option 1 is incorrect because parallelization is handled by the worker pool, not project definitions. Option 3 is incorrect as test order should not be enforced. Option 4 is incorrect because reporters are global or per-run, not per-project.

    From lesson: Test organization with projects and configurations

  82. When should you use 'dependencies' in a Playwright project configuration?

    • When you need to import external libraries for utility functions
    • When you want to share test data between different test files
    • When a specific project requires a setup task, such as authentication, to complete before it starts
    • When you want to define which browser engines should be skipped during a test run

    Answer: When a specific project requires a setup task, such as authentication, to complete before it starts. Dependencies allow one project to run setup tests before the main project begins. Option 1 describes package management. Option 2 describes test data management. Option 4 describes test filtering, not dependency management.

    From lesson: Test organization with projects and configurations

  83. How does setting a 'baseURL' in the playwright.config file impact your tests?

    • It restricts tests to only interact with the specified domain for security
    • It forces all tests to navigate to that URL automatically at the start of every test
    • It allows you to use relative paths in page.goto() calls, making tests portable across environments
    • It automatically deploys the latest build to the specified URL

    Answer: It allows you to use relative paths in page.goto() calls, making tests portable across environments. baseURL allows relative navigation, which makes switching environments easy. Option 1 is wrong as it is a helper, not a security restriction. Option 2 is wrong because you must still call page.goto. Option 4 is incorrect as Playwright does not manage deployments.

    From lesson: Test organization with projects and configurations

  84. If you have a 'smoke' project and a 'regression' project, how do you execute only the smoke tests?

    • Delete the regression folder temporarily
    • Use the --project flag with the value 'smoke'
    • Change the order of tests in the configuration file
    • Use a comment in the test header to ignore regression tests

    Answer: Use the --project flag with the value 'smoke'. The --project flag limits execution to the matching configuration. Deleting files is destructive and inefficient. Ordering in config does not filter execution. Comments are not a standard way to filter project-level execution.

    From lesson: Test organization with projects and configurations

  85. Why is it recommended to use fixtures for setup instead of globalSetup for most test scenarios?

    • Fixtures provide better isolation and allow for granular control over test state
    • GlobalSetup is deprecated and will be removed in future versions
    • Fixtures run faster than globalSetup in all cases
    • GlobalSetup can only be written in a specific syntax not supported by modern editors

    Answer: Fixtures provide better isolation and allow for granular control over test state. Fixtures provide test-level isolation and are easier to maintain as they are scoped to tests. GlobalSetup is not deprecated, but it is too broad for per-test needs. Fixtures do not inherently run faster than globalSetup; they serve different architectural purposes.

    From lesson: Test organization with projects and configurations

  86. When using `test.each()` with an array of objects to run parameterized tests, what is the primary benefit of this approach compared to a standard `for` loop?

    • It improves test execution speed by compiling the test code into machine language.
    • It allows Playwright to report each iteration as a distinct test, enabling granular failure tracking and parallelization.
    • It automatically encrypts the test data for security compliance.
    • It bypasses the need for the Playwright Test runner configuration.

    Answer: It allows Playwright to report each iteration as a distinct test, enabling granular failure tracking and parallelization.. Option 1 is correct because Playwright treats each iteration of `test.each()` as an individual test case. Option 0 is incorrect as it does not change compilation. Option 2 is incorrect because test data encryption is not the purpose. Option 3 is incorrect because the runner is still required.

    From lesson: Data-driven testing with parameterized tests

  87. If you have a JSON file containing 100 data records and you want to run a test for each record, what is the best practice for loading this data?

    • Read the file synchronously at the top level of the test file before defining tests.
    • Use a global hook to load the file into a variable accessible by all test files.
    • Hardcode the data into an array variable inside every single test file.
    • Fetch the data from the JSON file inside a 'beforeEach' hook for every test iteration.

    Answer: Read the file synchronously at the top level of the test file before defining tests.. Option 0 is correct because reading the data synchronously at the top level allows the test runner to register the tests during the initial scan. Option 1 is incorrect because it lacks isolation. Option 2 is inefficient and redundant. Option 3 adds unnecessary overhead to every test run.

    From lesson: Data-driven testing with parameterized tests

  88. How does Playwright handle failures within a `test.each()` scenario?

    • It cancels all subsequent tests in the suite immediately upon the first failure.
    • It automatically retries only the failed iteration indefinitely.
    • It continues to execute other iterations, marking only the failed specific data set as a failure.
    • It merges the failure of one iteration into the test summary of the entire file.

    Answer: It continues to execute other iterations, marking only the failed specific data set as a failure.. Option 2 is correct because Playwright isolates tests; one failing data set does not stop others. Option 0 is wrong as it doesn't default to cancellation. Option 1 is incorrect as retries are a separate config. Option 3 is incorrect as the reporter distinguishes individual iterations.

    From lesson: Data-driven testing with parameterized tests

  89. Why might you use a custom title function in the second argument of `test.each()`?

    • To increase the execution priority of specific data sets.
    • To provide human-readable names in the test report based on the input data.
    • To specify the browser engine to be used for that specific iteration.
    • To convert the data types from strings to numbers before the test starts.

    Answer: To provide human-readable names in the test report based on the input data.. Option 1 is correct as it creates readable reporting strings. Option 0 is incorrect as priority is not handled this way. Option 2 is incorrect as browsers are set at the project level. Option 3 is incorrect as data transformation should occur before the test execution.

    From lesson: Data-driven testing with parameterized tests

  90. When refactoring a standard test into a parameterized test, what is the most important architectural change to make?

    • Moving all assertions to a separate library to avoid Playwright's built-in expect.
    • Ensuring the test body does not rely on global variables that change during execution.
    • Changing all locators to use XPath for better compatibility.
    • Reducing the number of tests to ensure all data fits in one function.

    Answer: Ensuring the test body does not rely on global variables that change during execution.. Option 1 is correct because test isolation is critical when running in parallel. Option 0 is wrong because `expect` is standard. Option 2 is incorrect as locators are independent of parameterization. Option 3 is wrong because `test.each()` is designed to split tests, not aggregate them.

    From lesson: Data-driven testing with parameterized tests

  91. Why does Playwright's default visual regression mechanism use a 'baseline' file?

    • To provide a backup in case the application UI fails to load.
    • To act as the 'source of truth' image that the current test state is compared against.
    • To allow the user to manually edit pixel data before running the comparison.
    • To compress the images to save storage space in the repository.

    Answer: To act as the 'source of truth' image that the current test state is compared against.. The baseline is the golden standard image. Option 1 is incorrect because it is not a backup. Option 3 is incorrect as editing pixels defeats the test. Option 4 is incorrect because compression is for storage, not comparison.

    From lesson: Visual regression testing with Playwright

  92. What happens if you run a visual regression test for the first time without a baseline image existing?

    • The test fails and throws an error about a missing file.
    • The test passes automatically and ignores the comparison.
    • The test fails, but generates the baseline image for you to review.
    • The test enters a debugging loop until you manually create the directory.

    Answer: The test fails, but generates the baseline image for you to review.. Playwright treats the first run as a generation step, failing the test to protect against accidental changes while creating the reference file. Option 1 is wrong because it does generate the file. Option 2 is unsafe. Option 4 is incorrect as it does not loop.

    From lesson: Visual regression testing with Playwright

  93. When testing a page with dynamic data, which configuration property should be used to exclude specific components from the screenshot?

    • excludeElements
    • omitElements
    • mask
    • hide

    Answer: mask. The `mask` property allows you to pass locators to be obscured by a colored box. 'excludeElements', 'omitElements', and 'hide' are not the correct configuration keys in the `toHaveScreenshot` API.

    From lesson: Visual regression testing with Playwright

  94. If your test fails due to a visual difference that is only 0.2% but you are using the default settings, what will happen?

    • The test will pass because 0.2% is beneath the default internal threshold.
    • The test will fail because any difference causes a mismatch by default.
    • The test will automatically update the baseline to the new image.
    • The test will require the user to provide a manual boolean flag to proceed.

    Answer: The test will fail because any difference causes a mismatch by default.. The default configuration is strict. Option 1 is wrong because the default threshold is 0. Option 3 is wrong because auto-updating requires the --update-snapshots flag. Option 4 is incorrect as no boolean flag is needed in the test logic.

    From lesson: Visual regression testing with Playwright

  95. Why is it best practice to test visual regression in a containerized environment like Docker?

    • Because it is faster than running locally.
    • Because it ensures identical font rendering and anti-aliasing across all developer machines.
    • Because it allows the tests to bypass network security firewalls.
    • Because it enables the use of higher resolution screenshots.

    Answer: Because it ensures identical font rendering and anti-aliasing across all developer machines.. Containerization ensures environment parity. Option 1 is false, as containers can be slower. Option 3 is irrelevant to visual testing. Option 4 is false, as resolution is set via viewport configuration, not the environment.

    From lesson: Visual regression testing with Playwright

  96. When using storageState to persist authentication, what is the primary benefit over performing a full login sequence?

    • It prevents the browser from loading images, speeding up the test.
    • It allows tests to start directly at a logged-in state without re-executing login steps.
    • It automatically validates the security of the login form against SQL injection.
    • It forces the application to use a development-only bypass mode.

    Answer: It allows tests to start directly at a logged-in state without re-executing login steps.. Storage state snapshots the browser's cookies and local/session storage, letting subsequent tests start already authenticated. Option 0 is incorrect as it's not a performance feature of storage; option 2 is not the purpose of Playwright; option 3 is incorrect as this is a functional testing tool, not a security auditor.

    From lesson: Working with authentication and sessions

  97. Why should you use 'globalSetup' for authentication instead of putting login steps in 'beforeEach' for every test?

    • It increases the likelihood of test failures to ensure the system is robust.
    • It allows you to test the login UI separately from the functional features.
    • It saves time by performing the login action only once per test run or worker.
    • It ensures that cookies are cleared after every single test file is completed.

    Answer: It saves time by performing the login action only once per test run or worker.. Global setup executes once, and its artifacts can be reused by multiple tests, drastically improving efficiency. Option 0 is illogical; option 1 is a side effect but not the purpose; option 3 is false as you usually want to keep cookies for the duration of the test suite.

    From lesson: Working with authentication and sessions

  98. If your application uses different storage keys for auth tokens, which Playwright feature ensures a complete capture of the session?

    • browserContext.storageState()
    • page.waitForLoadState()
    • request.post()
    • browser.newContext({ ignoreHTTPSErrors: true })

    Answer: browserContext.storageState(). storageState captures all state within the context including cookies, local storage, and session storage. Option 1 is for page loading; option 2 is for API calls; option 3 relates to certificate handling.

    From lesson: Working with authentication and sessions

  99. When writing a test that relies on a pre-saved storage state, how does Playwright know which file to use?

    • The file is automatically detected by searching for cookies.json in the project root.
    • You define the 'storageState' property in the Playwright configuration file.
    • You must manually import the JSON file in every single 'test' block.
    • Playwright uses the last modified file in the 'test-results' folder.

    Answer: You define the 'storageState' property in the Playwright configuration file.. The Playwright config allows global setting of storageState for all tests. Option 0 is false; option 2 is inefficient and not standard practice; option 3 is irrelevant to configuration management.

    From lesson: Working with authentication and sessions

  100. What is the consequence of using a stale storage state file in a CI environment?

    • The test will automatically fail with a 401 Unauthorized error from the application.
    • The browser will automatically refresh the login page without any code intervention.
    • The test will proceed to the dashboard without checking for valid credentials.
    • Playwright will throw a syntax error in the configuration file.

    Answer: The test will automatically fail with a 401 Unauthorized error from the application.. A stale file means expired tokens; the application will reject requests, causing a 401. Option 1 is incorrect as Playwright doesn't know how to handle login redirects unless programmed; option 2 is false; option 3 is false as it's a runtime issue, not a syntax one.

    From lesson: Working with authentication and sessions

  101. When Playwright runs tests in parallel, how is isolation maintained?

    • By running tests in a single browser instance with cleared cookies
    • By utilizing independent Browser Contexts for each test
    • By utilizing different operating system processes for every step
    • By assigning a unique port to every test file

    Answer: By utilizing independent Browser Contexts for each test. Playwright creates a fresh Browser Context for every test, ensuring cookies, local storage, and sessions are isolated. The other options are incorrect because single-instance sessions are not fully isolated, separate processes are unnecessary for context isolation, and port assignment is not the mechanism for browser state isolation.

    From lesson: Parallel test execution and sharding

  102. What happens when you execute tests with '--shard=1/3'?

    • Playwright runs only the first test file in the suite
    • Playwright splits the total test count and runs the first third of them
    • Playwright identifies the test suite, sorts it, and executes the designated fraction
    • Playwright runs all tests but limits the output to one-third of the total results

    Answer: Playwright identifies the test suite, sorts it, and executes the designated fraction. Sharding distributes the full set of tests across multiple machines by sorting them to ensure deterministic distribution. It does not just pick a subset based on file order or file count; it slices the execution list based on the shard index.

    From lesson: Parallel test execution and sharding

  103. Why might increasing the number of workers lead to test failures in an existing suite?

    • Because Playwright cannot handle more than 4 concurrent workers
    • Because the application backend cannot handle concurrent requests from the same user session
    • Because the machine RAM is automatically halved to save energy
    • Because Playwright disables network interception when workers exceed two

    Answer: Because the application backend cannot handle concurrent requests from the same user session. If tests share a common database state or user account without proper isolation, increasing concurrency causes conflicts. The other options are false because Playwright supports many workers, memory management is not automated in that way, and network interception remains active.

    From lesson: Parallel test execution and sharding

  104. How does Playwright determine how many tests to run in parallel by default?

    • It uses a fixed value of 2 workers
    • It calculates the number of physical CPU cores available on the machine
    • It sets the worker count to the total number of test files
    • It runs all tests simultaneously regardless of machine resources

    Answer: It calculates the number of physical CPU cores available on the machine. By default, Playwright uses a heuristic based on the number of available CPU cores to optimize performance. A fixed value of 2 or running all at once would be inefficient or crash the system, and tying it to test file counts is not the standard optimization strategy.

    From lesson: Parallel test execution and sharding

  105. What is the primary benefit of sharding in a CI/CD pipeline?

    • It forces tests to run faster by skipping unnecessary setup steps
    • It allows test execution to be distributed across multiple physical machines to reduce total time
    • It automatically retries only the failed tests in the final shard
    • It enables cross-browser testing for a single test case

    Answer: It allows test execution to be distributed across multiple physical machines to reduce total time. Sharding enables parallelizing the execution of the entire suite across different machines, drastically reducing CI wall-clock time. It doesn't skip setup, handle retries differently, or specifically target cross-browser testing as its primary function.

    From lesson: Parallel test execution and sharding

  106. When configuring a CI pipeline to run Playwright tests, what is the most reliable way to ensure all necessary browser dependencies are present?

    • Manually install browsers on the runner during each job
    • Use a pre-built official Playwright Docker image
    • Assume the runner has browsers installed by default
    • Copy the browser binaries from your local machine to the CI runner

    Answer: Use a pre-built official Playwright Docker image. Using official Playwright Docker images ensures a consistent, pre-configured environment. Manual installation is slow and prone to error, assuming default installs is risky, and copying binaries is not cross-platform compatible.

    From lesson: Integrating Playwright with CI/CD pipelines

  107. What is the primary benefit of defining a 'webServer' in your playwright.config file for CI/CD?

    • It prevents the browser from closing after a test failure
    • It automatically deploys your application to production
    • It starts your local dev server and waits for it to be ready before running tests
    • It enables faster execution by skipping browser authentication

    Answer: It starts your local dev server and waits for it to be ready before running tests. The 'webServer' configuration manages the lifecycle of your application server, ensuring tests don't run until the server is responsive. It is unrelated to deployment, browser behavior, or authentication.

    From lesson: Integrating Playwright with CI/CD pipelines

  108. If your tests pass locally but fail in CI due to timeouts, what is the best strategy to debug the issue?

    • Increase the test timeout to infinity
    • Add console logs to every line of code
    • Configure CI to upload Playwright traces as artifacts upon failure
    • Disable all assertions in the CI environment

    Answer: Configure CI to upload Playwright traces as artifacts upon failure. Traces provide a full snapshot of the test execution, allowing you to see exactly where it timed out. Increasing timeouts masks the problem, console logs are harder to inspect than traces, and disabling assertions makes tests useless.

    From lesson: Integrating Playwright with CI/CD pipelines

  109. To improve CI performance, what is the best way to utilize worker settings?

    • Always set workers to 1 to ensure stability
    • Set workers to the total number of CPU cores available in the runner
    • Set workers to 100 to maximize throughput
    • Disable workers entirely for CI environments

    Answer: Set workers to the total number of CPU cores available in the runner. Matching workers to CPU cores balances parallelism and stability. Setting it to 1 is slow, 100 is excessive and causes resource contention, and disabling workers removes the core advantage of Playwright's parallel execution.

    From lesson: Integrating Playwright with CI/CD pipelines

  110. How should you handle sensitive environment variables like API keys or credentials in a CI/CD pipeline?

    • Store them in a text file committed to the repository
    • Hardcode them as constants in your test files
    • Use the CI provider's secure secrets storage and access them via process.env
    • Print them to the logs so they can be reviewed later

    Answer: Use the CI provider's secure secrets storage and access them via process.env. CI secrets storage provides secure, encrypted access to sensitive data. Committing to a repo, hardcoding, or printing to logs are all major security vulnerabilities.

    From lesson: Integrating Playwright with CI/CD pipelines

  111. When debugging a flaky test that passes locally but fails in CI, which tool provides the most comprehensive data including snapshots, console logs, and network requests?

    • console.log statements
    • The Playwright Trace Viewer
    • Browser screenshot diffs
    • The --debug flag without a trace

    Answer: The Playwright Trace Viewer. Trace Viewer captures the full execution context including state snapshots and network requests. Console logs are limited to text, screenshots are static, and --debug is for interactive sessions rather than post-mortem analysis.

    From lesson: Debugging Playwright tests effectively

  112. Which approach is most effective for debugging an interaction that triggers a hidden overlay or modal?

    • Using page.waitForTimeout(5000)
    • Running the test with the --headed flag to observe the state
    • Adding more console logs to the test file
    • Reducing the browser viewport size

    Answer: Running the test with the --headed flag to observe the state. Running in headed mode allows you to visually see if the overlay appears. Timeouts cause flakiness, console logs do not show DOM changes, and viewport changes may alter the layout, potentially masking the issue.

    From lesson: Debugging Playwright tests effectively

  113. What is the primary advantage of using locators like getByRole over CSS selectors during a debugging session?

    • They execute faster in the browser engine
    • They are immune to changes in the page CSS styling
    • They encourage testing from a user perspective and remain resilient to implementation shifts
    • They are the only way to select elements that are dynamically generated

    Answer: They encourage testing from a user perspective and remain resilient to implementation shifts. User-facing locators mimic the user journey. CSS selectors are fragile because they change when the HTML structure is refactored. While they are resilient, performance is not the primary advantage over other selector types.

    From lesson: Debugging Playwright tests effectively

  114. A test fails because an element is 'hidden'. What is the first thing you should verify using the Playwright Inspector?

    • That the CSS z-index is set to a negative value
    • That the element is not covered by another element or conditionally rendered
    • That the test has waited long enough for the server response
    • That the browser is running in the correct language

    Answer: That the element is not covered by another element or conditionally rendered. Playwright checks for actionability (like visibility) automatically. If it reports hidden, the element is likely obstructed or not in the DOM. Z-index is a specific CSS possibility, but checking the DOM structure is the general debugging step.

    From lesson: Debugging Playwright tests effectively

  115. Why is 'expect().toBeVisible()' preferred over checking an element's existence when debugging race conditions?

    • toBeVisible triggers an automatic retry until the condition is met
    • toBeVisible is faster because it skips the DOM node lookup
    • toBeVisible only works in headed browser mode
    • toBeVisible validates the element has a background color

    Answer: toBeVisible triggers an automatic retry until the condition is met. Web-first assertions like toBeVisible use Playwright's auto-retrying mechanism, which eliminates the need for manual waits. It has nothing to do with background colors, speed of lookup, or headed mode requirements.

    From lesson: Debugging Playwright tests effectively

  116. When measuring the performance of an action, why is it discouraged to rely solely on the duration of an `await page.click()` call?

    • Playwright waits for the actionability of the element before performing the click.
    • The browser engine handles input events asynchronously, making the promise resolve before the UI update completes.
    • The duration includes internal Playwright overhead, automatic retries, and waiting for stability.
    • Network events are not triggered by the click method.

    Answer: The duration includes internal Playwright overhead, automatic retries, and waiting for stability.. Option 2 is correct because 'await' on an action command includes the time taken for actionability checks and potential re-tries, not just the execution. The other options are either false or do not explain why the duration is inaccurate for performance benchmarks.

    From lesson: Performance testing with Playwright

  117. Which approach is most effective for capturing precise performance data for a network request during a test?

    • Using a timer before and after the action triggering the request.
    • Using page.on('requestfinished') to compare 'responseEnd' and 'requestStart' timings.
    • Checking the console logs for performance warnings.
    • Using page.waitForLoadState('networkidle').

    Answer: Using page.on('requestfinished') to compare 'responseEnd' and 'requestStart' timings.. Option 1 is correct as it utilizes granular data from the browser's internal timing events. Options 0 and 3 are unreliable due to overhead, and option 3 is a general state check rather than a data measurement.

    From lesson: Performance testing with Playwright

  118. Why does Playwright's 'networkidle' state often produce inconsistent results in performance testing?

    • Because it is hard-coded to wait exactly 5 seconds.
    • Because it depends on the absence of network requests for at least 500ms, which is too long for modern apps.
    • Because it fluctuates based on background telemetry and analytics scripts.
    • Because it only tracks WebSocket connections.

    Answer: Because it fluctuates based on background telemetry and analytics scripts.. Option 2 is correct because modern web apps frequently trigger analytics or monitoring requests. The other options are incorrect interpretations of how 'networkidle' functions.

    From lesson: Performance testing with Playwright

  119. How can you simulate a throttled environment to identify performance bottlenecks in asset loading?

    • By modifying the browser's internal clock using page.evaluate.
    • By using a CDPSession to set the network conditions emulation.
    • By increasing the timeout of every locator in the test.
    • By intentionally corrupting the local storage before the test starts.

    Answer: By using a CDPSession to set the network conditions emulation.. Option 1 is the standard way to programmatically limit bandwidth. The other options do not accurately simulate real-world throttled network conditions.

    From lesson: Performance testing with Playwright

  120. When generating a Trace Viewer file for performance analysis, what is the primary benefit over traditional console logging?

    • It generates a report that is automatically accepted by SEO crawlers.
    • It provides a synchronized view of network requests, console logs, and the DOM at every stage of execution.
    • It reduces the total execution time of the test script by 50%.
    • It automatically identifies and fixes broken CSS selectors.

    Answer: It provides a synchronized view of network requests, console logs, and the DOM at every stage of execution.. Option 1 is correct because the trace viewer provides a holistic view of the state. Other options suggest performance improvements or automation capabilities that are not part of trace analysis.

    From lesson: Performance testing with Playwright

  121. When refactoring a test suite to use the Page Object Model, what is the primary goal?

    • To reduce the number of assertions in each test
    • To centralize element locators and actions to improve maintainability
    • To increase the speed of test execution by removing navigation steps
    • To bypass the browser's rendering engine for faster processing

    Answer: To centralize element locators and actions to improve maintainability. The POM improves maintainability by decoupling page structure from test logic. Option 0 is irrelevant to structure; Option 2 is incorrect as navigation is often necessary; Option 3 is technically impossible as Playwright must interact with the browser.

    From lesson: Writing maintainable and reusable test code

  122. Why is it recommended to use 'data-testid' over CSS classes for selecting elements?

    • It executes faster than CSS class lookups
    • It is the only way to locate elements in shadow DOMs
    • It signals that the attribute is specifically for testing, making it resilient to CSS/JS refactors
    • It forces the developer to write more descriptive CSS

    Answer: It signals that the attribute is specifically for testing, making it resilient to CSS/JS refactors. Using dedicated testing attributes separates infrastructure from presentation, which is the cornerstone of robust tests. Options 0 and 1 are factually incorrect; Option 3 is a side effect, not a primary benefit.

    From lesson: Writing maintainable and reusable test code

  123. What is the correct way to handle a dynamic element that takes time to appear in the DOM?

    • Use page.waitForTimeout(5000)
    • Use web-first assertions like expect(locator).toBeVisible()
    • Increase the default navigation timeout globally
    • Add an 'await' statement before every selector

    Answer: Use web-first assertions like expect(locator).toBeVisible(). Web-first assertions automatically poll for the element until it meets the criteria. Option 0 is an anti-pattern causing flakiness; Option 2 doesn't solve waiting; Option 3 is syntactically unnecessary for selectors.

    From lesson: Writing maintainable and reusable test code

  124. If multiple tests require the same logged-in state, what is the most efficient approach?

    • Copy-paste the login logic into every test file
    • Use globalSetup to perform the login once
    • Use a custom fixture to inject a stored authentication state
    • Use a loop to repeat the login function

    Answer: Use a custom fixture to inject a stored authentication state. Custom fixtures allow for clean, scalable state injection without global side effects. Option 0 violates DRY; Option 1 is less flexible than fixtures; Option 3 is not a standard approach for state management.

    From lesson: Writing maintainable and reusable test code

  125. Which of the following describes a 'flaky' test?

    • A test that fails intentionally when a bug is found
    • A test that fails to compile due to syntax errors
    • A test that exhibits inconsistent behavior, passing and failing without code changes
    • A test that takes longer than 10 seconds to execute

    Answer: A test that exhibits inconsistent behavior, passing and failing without code changes. Flakiness is defined by non-deterministic results, which erode trust in the test suite. Options 0, 1, and 3 describe expected failures, syntax issues, or performance constraints, not flakiness.

    From lesson: Writing maintainable and reusable test code

  126. When refactoring a Playwright test to use POM, what is the primary benefit of returning a new Page Object instance from a method?

    • To satisfy the memory management requirements of the Playwright runner
    • To enable a fluent 'chaining' API that makes the test flow easier to read
    • To bypass the need for page fixtures in the test file
    • To ensure the browser context is re-initialized for every action

    Answer: To enable a fluent 'chaining' API that makes the test flow easier to read. Returning the next page object enables method chaining (e.g., login.navigate().submitForm()), which makes the test script read like a natural language. The other options are incorrect because they describe irrelevant architectural concerns or misunderstand how Playwright manages objects.

    From lesson: Page Object Model (POM) design pattern

  127. A tester has moved all locator logic into a central Page Object class but still finds they are updating 10 files every time a CSS class name changes. Why?

    • They are using locators directly in the test scripts instead of calling Page Object methods
    • They did not include the 'await' keyword on their method calls
    • They are initializing the Page Object in every single test case
    • They are not using the 'page' fixture globally

    Answer: They are using locators directly in the test scripts instead of calling Page Object methods. If changing a locator requires updating multiple files, the testers are likely still referencing selectors directly in their tests rather than strictly using the encapsulated methods provided by the POM. The other choices deal with initialization or syntax, which would cause runtime errors, not maintenance overhead.

    From lesson: Page Object Model (POM) design pattern

  128. What is the correct way to handle elements that might not be visible immediately in a Page Object model?

    • Use a 'wait' hardcoded sleep function inside the locator constructor
    • Let Playwright's built-in auto-waiting handle it within the action methods
    • Add a 'page.waitForLoadState' in every single getter method
    • Create an 'isLoaded' boolean flag that is checked before every interaction

    Answer: Let Playwright's built-in auto-waiting handle it within the action methods. Playwright is designed with auto-waiting, so the POM should rely on these built-in features for clicks and visibility. Hardcoding sleeps or manual waiting flags adds unnecessary complexity and flakiness, which defeats the purpose of Playwright's architecture.

    From lesson: Page Object Model (POM) design pattern

  129. Which of the following describes the best practice for handling dynamic user-specific data in a Page Object?

    • Storing the data as instance variables in the constructor
    • Passing the data as parameters to the specific methods that perform the action
    • Writing the data to a shared JSON file that the Page Object reads before every click
    • Using global environment variables for all input fields

    Answer: Passing the data as parameters to the specific methods that perform the action. Methods should remain pure and reusable; passing data as parameters ensures that the same Page Object can be used for different test scenarios (e.g., different users). The other methods create unwanted coupling, persistent state, or rely on external global state that is hard to debug.

    From lesson: Page Object Model (POM) design pattern

  130. Why is it discouraged to perform assertions inside the Page Object class?

    • Because Playwright cannot perform assertions outside of the test file
    • Because it makes the Page Object act as both an actor and a verifier, violating the Single Responsibility Principle
    • Because assertions in Page Objects cause the Playwright test runner to crash
    • Because it prevents the use of browser context fixtures

    Answer: Because it makes the Page Object act as both an actor and a verifier, violating the Single Responsibility Principle. Separating interaction (Page Object) from verification (Test file) ensures that the Page Object describes *what* can be done, while the test describes *what should happen*. Options 1, 3, and 4 are technically false regarding how Playwright works.

    From lesson: Page Object Model (POM) design pattern

  131. What is the primary advantage of using a custom fixture over a 'beforeEach' hook for page objects?

    • Fixtures allow you to share state directly between different test worker processes.
    • Fixtures provide automatic dependency injection, making tests cleaner and more reusable.
    • Fixtures are required to run tests in parallel, whereas 'beforeEach' forces sequential execution.
    • Fixtures bypass the default browser context isolation for faster execution.

    Answer: Fixtures provide automatic dependency injection, making tests cleaner and more reusable.. Fixtures allow for dependency injection, which keeps tests focused only on the data they need. 'BeforeEach' is procedural and requires manual variable management. Parallel execution and browser context are handled by configuration, not by the choice of fixture vs hook.

    From lesson: Custom fixtures and test hooks

  132. If you define a fixture that depends on the base 'page' fixture, how does Playwright resolve this?

    • It executes the fixtures in reverse order of declaration.
    • It injects the base page automatically as an argument to your fixture function.
    • It requires you to manually instantiate the page object within the fixture factory.
    • It forces the test to run in a non-isolated environment to share the page state.

    Answer: It injects the base page automatically as an argument to your fixture function.. Playwright automatically manages the dependency graph and provides the base fixtures (like 'page' or 'request') as arguments to your custom fixture definition. You do not need to manually instantiate them.

    From lesson: Custom fixtures and test hooks

  133. What happens if you define a fixture and fail to call the 'use' function within it?

    • The test runner ignores the fixture and proceeds with the default behavior.
    • The test will automatically fail with a 'timeout' error because the fixture never yields.
    • The test will use a null value for the fixture, leading to runtime exceptions.
    • The fixture will automatically terminate after the timeout period ends.

    Answer: The test will automatically fail with a 'timeout' error because the fixture never yields.. The 'use' function is how the fixture provides the value to the test. If it is never called, the test remains in a pending state, eventually hitting the timeout limit and failing.

    From lesson: Custom fixtures and test hooks

  134. Why would you choose a 'worker' scope for a fixture instead of the default 'test' scope?

    • To ensure the fixture is recreated for every single 'it' block in the test file.
    • To allow the fixture to perform actions that are incompatible with the test-level isolation.
    • To persist a resource, such as a database connection, across multiple tests within the same worker.
    • To bypass the need for 'await use()' calls in the fixture definition.

    Answer: To persist a resource, such as a database connection, across multiple tests within the same worker.. Worker scope fixtures are instantiated once per worker process, making them ideal for heavy resources like servers or database pools that should be shared by multiple tests to improve performance. Test scope fixtures reset for every test.

    From lesson: Custom fixtures and test hooks

  135. How do you correctly handle cleanup (teardown) logic within a fixture?

    • By placing the cleanup code immediately before the 'await use()' statement.
    • By using an 'afterEach' hook inside the same test file to clean up the fixture state.
    • By writing the teardown code after the 'await use()' statement in the fixture factory.
    • By returning a callback function that the test runner executes after completion.

    Answer: By writing the teardown code after the 'await use()' statement in the fixture factory.. Code placed after 'await use()' is executed once the test (or worker) has finished, making it the correct location for cleanup tasks. Placing it before 'use' would execute it during the setup phase.

    From lesson: Custom fixtures and test hooks

  136. Which annotation is best suited for a test that is currently broken but you intend to fix in the near future, while wanting to ensure it is not counted as a regression failure?

    • test.skip()
    • test.fixme()
    • test.fail()
    • test.slow()

    Answer: test.fixme(). test.fixme() marks a test as needing attention and skips execution without failing the build. test.skip() ignores the test completely, test.fail() expects a failure (which would flag an issue if the test passes), and test.slow() only changes timing, not execution status.

    From lesson: Working with Playwright Test annotations

  137. If you want to intentionally run a test and verify that it results in a 'failed' status to confirm a bug fix, which annotation should you use?

    • test.fail()
    • test.skip()
    • test.fixme()
    • test.only()

    Answer: test.fail(). test.fail() is designed for 'expected failure'; if the test passes, it will actually trigger an error. skip and fixme do not run the test logic, and only runs specific tests in isolation.

    From lesson: Working with Playwright Test annotations

  138. When you need to triple the default timeout for a specific test suite because it performs intensive data processing, which annotation is the most idiomatic choice?

    • test.timeout()
    • test.fixme()
    • test.slow()
    • test.fail()

    Answer: test.slow(). test.slow() is specifically provided to triple the timeout for tests known to be slow. test.timeout() is not a valid annotation (you would use test.setTimeout inside the test), while the others relate to execution status rather than timing.

    From lesson: Working with Playwright Test annotations

  139. How does using test.only() affect the execution of a test file during local development?

    • It skips all other tests in the file and runs only the marked test.
    • It runs only the marked test and skips all other tests in the entire project.
    • It marks the test as the only one to be run in CI.
    • It forces the test to run in serial mode regardless of other settings.

    Answer: It skips all other tests in the file and runs only the marked test.. test.only() isolates the test file to run only the marked tests. It does not affect other files in the project or CI environment configuration directly, and it does not force serial execution; it merely filters the test set.

    From lesson: Working with Playwright Test annotations

  140. You have a test that should only execute on Chromium-based browsers. Which approach correctly handles this using an annotation?

    • test.skip(browserName !== 'chromium', 'Only for Chromium');
    • test.fail(browserName !== 'chromium');
    • test.only(browserName === 'chromium');
    • test.slow(browserName !== 'chromium');

    Answer: test.skip(browserName !== 'chromium', 'Only for Chromium');. test.skip() accepts a condition as the first argument, allowing dynamic exclusion. test.fail would expect the wrong browser to fail (not skip), test.only would break the build by excluding other tests incorrectly, and test.slow is for timing.

    From lesson: Working with Playwright Test annotations

  141. What is the primary benefit of creating custom matchers in Playwright?

    • To increase the speed of browser navigation
    • To improve code readability by encapsulating complex validation logic
    • To allow Playwright to run on non-browser environments
    • To automatically generate screenshots for all failed tests

    Answer: To improve code readability by encapsulating complex validation logic. Custom matchers encapsulate complex logic into a single, semantic method, making tests cleaner. Option 0 is wrong as matchers do not affect navigation speed. Option 2 is incorrect as matchers are for assertions, not environment configuration. Option 3 is incorrect as screenshot generation is a separate feature.

    From lesson: Extending Playwright with custom matchers

  142. Which property must be returned by the matcher function for Playwright to correctly interpret the assertion result?

    • A boolean 'status'
    • A string 'result'
    • An object containing 'pass' and 'message'
    • The original element locator

    Answer: An object containing 'pass' and 'message'. Playwright expects a specific structure containing 'pass' (boolean) and 'message' (function) to format error messages. The other options do not provide the necessary data for the assertion engine to report failure accurately.

    From lesson: Extending Playwright with custom matchers

  143. Where is the most appropriate place to register custom matchers if you want them available across your entire test suite?

    • Inside the 'beforeEach' hook of every test
    • Inside the 'playwright.config.ts' file using the expect.extend() method
    • In a local utility file imported inside the test function
    • By setting them as global variables in the browser context

    Answer: Inside the 'playwright.config.ts' file using the expect.extend() method. Registering in the configuration file ensures matchers are loaded once globally. Importing in every test (Option 2) is redundant, 'beforeEach' (Option 0) is inefficient, and globals (Option 3) are not how Playwright handles matchers.

    From lesson: Extending Playwright with custom matchers

  144. When defining a custom matcher, what is the purpose of the 'message' function?

    • To log a success message to the console
    • To generate a human-readable failure report when the assertion fails
    • To notify the test runner to skip the current test
    • To change the color of the test output in the terminal

    Answer: To generate a human-readable failure report when the assertion fails. The message function is used specifically to provide context during failure. It is not used for logs, skipping tests, or terminal styling.

    From lesson: Extending Playwright with custom matchers

  145. If you are writing a custom matcher that needs to check a property of an element, how should you handle the input element?

    • Ignore the element and query the page directly
    • Pass the locator or element handle as the first argument to the matcher
    • Use a global selector to find the element inside the matcher
    • Return the element to the test script for validation

    Answer: Pass the locator or element handle as the first argument to the matcher. Passing the locator as an argument follows functional programming principles and allows the matcher to remain pure. Options 0, 2, and 3 introduce unwanted side effects or unnecessary complexity.

    From lesson: Extending Playwright with custom matchers

  146. When using TypeScript with Playwright, which approach best ensures type safety for custom test fixtures?

    • Defining a custom test object using base.extend()
    • Using a global interface to inject methods into the page object
    • Type casting every element locator to 'any'
    • Declaring all variables with the 'unknown' type

    Answer: Defining a custom test object using base.extend(). Extending the base test is the standard, type-safe way to add fixtures in Playwright. Casting to 'any' defeats the purpose of TypeScript, and global interfaces are prone to namespace pollution.

    From lesson: Using Playwright with TypeScript

  147. Why is it recommended to use user-facing locators like 'getByRole' instead of CSS selectors?

    • They execute faster in the browser engine
    • They encourage testing how users interact with the app, making tests more resilient to DOM changes
    • They automatically bypass all authentication layers
    • They reduce the need to write TypeScript interfaces

    Answer: They encourage testing how users interact with the app, making tests more resilient to DOM changes. User-facing locators focus on the accessibility tree. CSS selectors often rely on implementation details like class names, which change frequently. Neither approach bypasses authentication or impacts execution speed.

    From lesson: Using Playwright with TypeScript

  148. What is the primary benefit of using web-first assertions like 'expect(locator).toBeVisible()'?

    • They force the browser to clear the cache before checking
    • They perform a hard reload of the page to ensure fresh data
    • They automatically retry the assertion until the element meets the condition or times out
    • They skip all TypeScript type checks for the locator object

    Answer: They automatically retry the assertion until the element meets the condition or times out. Web-first assertions are designed to retry until the timeout is reached, which handles dynamic content loading. Reloading or clearing cache is unnecessary for basic visibility checks.

    From lesson: Using Playwright with TypeScript

  149. If a test fails with a timeout error despite using an await, what is the most likely cause?

    • The element is not reachable due to an overlay or incorrect state
    • TypeScript is missing the @types/node dependency
    • The browser is using too much system memory
    • The CSS selector is too long

    Answer: The element is not reachable due to an overlay or incorrect state. Playwright performs actionability checks. If an element exists but is covered by a spinner or modal, it cannot be interacted with, leading to a timeout. The other options do not typically cause actionability timeouts.

    From lesson: Using Playwright with TypeScript

  150. How should you handle an element that only appears after a network request finishes?

    • Use page.waitForLoadState('networkidle')
    • Use a standard assertion like expect(locator).toBeVisible() and let the auto-wait handle the delay
    • Use a loop with an if-statement to check for existence
    • Manually call page.pause() to inspect the network tab

    Answer: Use a standard assertion like expect(locator).toBeVisible() and let the auto-wait handle the delay. Playwright's locators and assertions automatically wait for elements to be present and actionable, making manual waiting or network-idle polling redundant and often unreliable.

    From lesson: Using Playwright with TypeScript

  151. When utilizing the Playwright test runner, how should you best handle the initialization of a page for multiple tests?

    • Create a new browser instance manually in a beforeAll block.
    • Use the built-in 'page' fixture provided by the test runner.
    • Declare a global variable and assign the page in the setup script.
    • Use a beforeEach hook to launch the browser and navigate manually.

    Answer: Use the built-in 'page' fixture provided by the test runner.. The 'page' fixture is automatically managed, isolated per test, and handles lifecycle cleanup. Manual creation is unnecessary, global variables lead to race conditions, and manually navigating in beforeEach is redundant.

    From lesson: Integrating with testing frameworks (Jest, Mocha)

  152. What is the primary advantage of using the native Playwright test runner over using a third-party framework like Jest or Mocha?

    • It supports non-JavaScript languages.
    • It allows for better integration with legacy unit testing plugins.
    • It provides built-in fixtures, automatic retries, and web-first assertions.
    • It forces the use of a single-threaded execution model for predictability.

    Answer: It provides built-in fixtures, automatic retries, and web-first assertions.. Playwright's test runner is specifically optimized for browser automation with features like auto-waiting and fixtures. The others are incorrect because Playwright is JS-focused, supports parallelization, and modern runners do not require legacy plugins.

    From lesson: Integrating with testing frameworks (Jest, Mocha)

  153. If you need to change the base URL for tests dynamically, where is the most appropriate place to define this within a Playwright project?

    • Inside each individual test file's top-level scope.
    • In the playwright.config.ts file under the 'use' property.
    • By hardcoding the URL into every 'page.goto()' call.
    • Inside the package.json scripts section.

    Answer: In the playwright.config.ts file under the 'use' property.. The config file provides a centralized location for environmental settings. Hardcoding violates DRY principles, and defining it in test files prevents global configuration management.

    From lesson: Integrating with testing frameworks (Jest, Mocha)

  154. Why should you avoid using standard assertion libraries (like expect from Chai) when using the Playwright test runner?

    • Playwright assertions are incompatible with JavaScript syntax.
    • Playwright's 'expect' offers web-first assertions that auto-retry until conditions are met.
    • Standard libraries are unable to compare strings or integers.
    • Standard libraries require external databases to function correctly.

    Answer: Playwright's 'expect' offers web-first assertions that auto-retry until conditions are met.. Playwright's 'expect' is extended to handle asynchronous UI states with retries. Standard libraries lack this 'web-first' capability, leading to flakiness. The other options are simply factually incorrect regarding JS syntax and library functionality.

    From lesson: Integrating with testing frameworks (Jest, Mocha)

  155. How does Playwright handle test isolation when running multiple tests in the same file?

    • It executes tests sequentially using a single browser tab.
    • It resets the browser cache and cookies between every test case.
    • It creates a fresh browser context for every test, ensuring no state leakage.
    • It relies on the developer to clear the cookies manually in an afterEach block.

    Answer: It creates a fresh browser context for every test, ensuring no state leakage.. Browser contexts are unique to every test, providing total isolation without the performance hit of relaunching the entire browser. Sequentially running in one tab is slow, and relying on manual clearing is error-prone.

    From lesson: Integrating with testing frameworks (Jest, Mocha)

  156. When extending Playwright with a custom plugin using 'test.extend', what is the primary advantage of using fixtures over manual setup functions?

    • Fixtures are executed in parallel across all worker processes automatically.
    • Fixtures provide automatic teardown and memoization, ensuring clean state per test.
    • Fixtures are the only way to interact with the Playwright browser context.
    • Fixtures are cached globally, allowing data to persist across different test suites.

    Answer: Fixtures provide automatic teardown and memoization, ensuring clean state per test.. Fixtures handle teardown and state management automatically, making them superior to manual setup which is prone to leaks. The other options are incorrect because fixtures do not cache globally across suites, are not the only interaction method, and are not automatically parallelized in the way described.

    From lesson: Exploring Playwright's plugin ecosystem

  157. If a plugin is interfering with the performance of your tests, what should be your first diagnostic step?

    • Switch the test runner to a different framework to see if the plugin performs better.
    • Remove the plugin and measure the execution time difference in the trace viewer.
    • Increase the number of workers in the playwright.config file to hide latency.
    • Reinstall all browser binaries to ensure the plugin has clean environment access.

    Answer: Remove the plugin and measure the execution time difference in the trace viewer.. Using the trace viewer to compare runs is the standard way to isolate performance bottlenecks. Switching frameworks is unrelated, increasing workers masks the issue rather than solving it, and reinstalling binaries does not address plugin-induced overhead.

    From lesson: Exploring Playwright's plugin ecosystem

  158. Why should you avoid using global variables to store data initialized by a plugin?

    • Global variables are automatically deleted by Playwright after every test.
    • Playwright runs tests in separate worker processes where global variables are not shared.
    • The Playwright CLI forbids the use of the 'global' keyword.
    • Global variables conflict with Playwright's internal TypeScript type definitions.

    Answer: Playwright runs tests in separate worker processes where global variables are not shared.. Playwright utilizes worker processes for parallelism, meaning memory is not shared between test files. The other options are incorrect as they misstate how the runner handles scope and language features.

    From lesson: Exploring Playwright's plugin ecosystem

  159. When creating a custom reporter plugin, what is the best practice for ensuring the reporter does not fail the entire test suite if it encounters an error?

    • Wrap the reporter's logic in a try-catch block and handle errors internally.
    • Set the reporter to run in a separate asynchronous process that is not awaited.
    • Throw an error immediately so the developer is aware of the reporting failure.
    • Hardcode the reporter to bypass the build process during CI runs.

    Answer: Wrap the reporter's logic in a try-catch block and handle errors internally.. A robust plugin should handle its own exceptions to prevent test runner crashes. Bypassing processes or throwing errors are bad practices, and asynchronous execution does not guarantee error handling.

    From lesson: Exploring Playwright's plugin ecosystem

  160. How does Playwright ensure that a custom plugin properly supports parallel execution?

    • By enforcing a single-threaded architecture for all plugins.
    • By providing a worker-scoped object that is unique to each test process.
    • By requiring every plugin to be written in a specific language version.
    • By disabling all plugin features when the '--workers' flag is higher than 1.

    Answer: By providing a worker-scoped object that is unique to each test process.. Playwright uses worker-scoped fixtures to maintain thread safety. Single-threading is incorrect as Playwright promotes parallelism, specific language versions are not a requirement, and plugins remain active during parallel execution.

    From lesson: Exploring Playwright's plugin ecosystem

  161. Why is Playwright considered more resilient than older automation frameworks when interacting with elements?

    • It uses a centralized server for all browser communications.
    • It performs automatic actionability checks before executing commands.
    • It ignores CSS transitions to speed up interactions.
    • It requires all elements to have a unique ID attribute.

    Answer: It performs automatic actionability checks before executing commands.. Playwright is resilient because it auto-waits for elements to be visible, stable, and enabled. Option 0 is wrong as it is architectural; Option 2 is wrong because it handles animations well; Option 3 is wrong as it works with various selectors.

    From lesson: Explain the key differences between Playwright and Selenium

  162. How does BrowserContext improve test suite efficiency?

    • It automatically records all test activity to a video file.
    • It allows tests to run without loading any network resources.
    • It creates isolated storage and cookies for every test without restarting the browser.
    • It compiles the code into machine language for faster execution.

    Answer: It creates isolated storage and cookies for every test without restarting the browser.. BrowserContext creates a fresh, isolated state for each test, making them fast and independent. Option 0 is a feature but not the efficiency gain; Option 1 is incorrect; Option 3 is not how Playwright works.

    From lesson: Explain the key differences between Playwright and Selenium

  163. What is the primary advantage of using 'getByRole' over CSS selectors?

    • It is the only way to interact with hidden elements.
    • It creates tests that reflect the accessibility tree and user experience.
    • It executes significantly faster on low-memory devices.
    • It prevents the need for any assertions in the code.

    Answer: It creates tests that reflect the accessibility tree and user experience.. getByRole forces developers to write accessible, user-centric tests. Option 0 is false; Option 2 is negligible performance-wise; Option 3 is fundamentally wrong as assertions are essential.

    From lesson: Explain the key differences between Playwright and Selenium

  164. When should you use the 'page.waitForTimeout' method in a test script?

    • Only when debugging, as it is generally an anti-pattern for production tests.
    • Every time an element is clicked to ensure the page has updated.
    • When you need to wait for a specific backend API to return data.
    • To synchronize the speed of the test with the visual animation duration.

    Answer: Only when debugging, as it is generally an anti-pattern for production tests.. waitForTimeout causes flaky tests and is bad practice; it should only be used for temporary debugging. The other options suggest using it for logic, which should be handled by web-first assertions.

    From lesson: Explain the key differences between Playwright and Selenium

  165. How does Playwright handle multiple tabs within the same test?

    • It requires a separate browser process for each tab.
    • It limits the test to a single tab at any given time.
    • It uses events to track and interact with new pages created by the context.
    • It forces all links to open in the current tab by modifying the DOM.

    Answer: It uses events to track and interact with new pages created by the context.. Playwright treats tabs as 'pages' within a context, allowing you to await a new page event. Option 0 is inefficient; Option 1 is false; Option 3 is unnecessary manipulation.

    From lesson: Explain the key differences between Playwright and Selenium

  166. When interacting with an element that appears after a network request, what is the recommended approach in Playwright?

    • Use a hardcoded timeout with page.waitForTimeout()
    • Use the locator directly, as Playwright auto-waits for visibility and actionability
    • Manually call page.waitForSelector() before every single interaction
    • Wrap the locator in a loop to check if it exists

    Answer: Use the locator directly, as Playwright auto-waits for visibility and actionability. Playwright locators are lazy and automatically perform actionability checks. Option 0 and 2 are inefficient, while option 3 is unnecessary complexity.

    From lesson: How would you handle dynamic elements in Playwright?

  167. Which locator strategy is most resilient to changes in the underlying DOM structure?

    • CSS selectors targeting tag nesting
    • XPath selectors targeting absolute positions
    • User-facing locators like getByRole or getByText
    • Selecting elements by index in a list

    Answer: User-facing locators like getByRole or getByText. User-facing locators mimic how users interact with the page, making them stable even if the underlying HTML tag changes. The others rely on brittle structural details.

    From lesson: How would you handle dynamic elements in Playwright?

  168. What is the primary purpose of 'Web-First Assertions' in Playwright?

    • To perform visual regression testing of the entire page
    • To allow the test to automatically retry until the expected condition is met
    • To bypass the need for selectors entirely
    • To execute JavaScript code directly in the browser console

    Answer: To allow the test to automatically retry until the expected condition is met. Web-first assertions (expect) provide built-in retry logic, which is crucial for handling dynamic elements. The other options are incorrect or describe different testing capabilities.

    From lesson: How would you handle dynamic elements in Playwright?

  169. If you have a dynamic list that updates via AJAX, how should you ensure the element exists before clicking?

    • Use expect(locator).toBeVisible() before performing the click
    • Simply call locator.click() and let Playwright handle the wait
    • Use page.waitForLoadState('networkidle')
    • Use a try-catch block with a loop

    Answer: Simply call locator.click() and let Playwright handle the wait. Playwright actions like click() already include an implicit visibility and stability check. Explicitly waiting is redundant unless you are performing a non-action check.

    From lesson: How would you handle dynamic elements in Playwright?

  170. How should you handle elements that are hidden and then revealed by hover interactions?

    • Use locator.hover() followed by a normal action on the nested element
    • Manually set the CSS display property via page.evaluate()
    • Use page.waitForTimeout() to wait for the animation to finish
    • Use a complex XPath to find hidden elements

    Answer: Use locator.hover() followed by a normal action on the nested element. Playwright handles event-driven visibility correctly: hover() triggers the hover event, and the subsequent locator action waits for the target to be actionable. The other methods are manual, fragile, or unnecessary.

    From lesson: How would you handle dynamic elements in Playwright?

  171. What is the primary benefit of Playwright's auto-waiting mechanism?

    • It automatically records network traffic for performance analysis.
    • It eliminates the need for manual sleep intervals before performing actions.
    • It replaces the need to write any assertions in a test script.
    • It automatically retries test failures indefinitely until they pass.

    Answer: It eliminates the need for manual sleep intervals before performing actions.. Auto-waiting removes flakiness by ensuring the target element is actionable before interaction, making manual waits obsolete. The other options describe features unrelated to actionability checks, assertions, or reliability.

    From lesson: Describe Playwright's auto-waiting mechanism and its benefits

  172. When does Playwright perform an auto-waiting check?

    • Every time a page is loaded in the browser context.
    • Immediately after the test file is initialized by the runner.
    • When performing an action like click, fill, or check.
    • Only when the developer explicitly calls wait functions.

    Answer: When performing an action like click, fill, or check.. Auto-waiting is triggered implicitly by action methods to ensure stability. Loading a page or initializing are infrastructure steps, and explicit waits are anti-patterns in this context.

    From lesson: Describe Playwright's auto-waiting mechanism and its benefits

  173. Which state must an element reach for Playwright's auto-waiting to consider it ready for a click?

    • The element must have an event listener attached to the 'onclick' property.
    • The element must be visible, stable, and receive events without being obscured.
    • The element must have a defined CSS class for hover states.
    • The element must be the first node defined in the HTML structure.

    Answer: The element must be visible, stable, and receive events without being obscured.. Visibility, stability (not moving), and un-obscured state are strictly required for 'click' actionability. Event listeners or CSS classes are implementation details, not actionability requirements.

    From lesson: Describe Playwright's auto-waiting mechanism and its benefits

  174. If you are trying to click an element that is covered by a loading spinner, what will Playwright's auto-waiting do?

    • Click through the spinner to hit the element underneath.
    • Wait until the spinner disappears or the element becomes un-obscured.
    • Throw an immediate error because the element is not found.
    • Skip the click action and proceed to the next line of code.

    Answer: Wait until the spinner disappears or the element becomes un-obscured.. Playwright waits for the element to be un-obscured by other DOM elements. It will not click through, error immediately, or skip the action, as it seeks to mimic real user interaction.

    From lesson: Describe Playwright's auto-waiting mechanism and its benefits

  175. Why is it still necessary to use assertions like 'toBeVisible()' even with auto-waiting?

    • Auto-waiting only confirms actionability, not the current state or condition of the UI.
    • Assertions are required to trigger the browser engine's rendering process.
    • Auto-waiting only works for 'click' actions and ignores 'fill' actions.
    • Assertions are needed to handle browser crashes.

    Answer: Auto-waiting only confirms actionability, not the current state or condition of the UI.. Auto-waiting handles the 'can I click this?' phase, while assertions verify the 'is the UI in the expected state?' phase. Assertions are not for rendering, and auto-waiting works for most actions.

    From lesson: Describe Playwright's auto-waiting mechanism and its benefits

  176. What is the primary mechanism for configuring the number of parallel workers in Playwright?

    • Passing a --parallel flag to the command line
    • Setting the 'workers' property in the playwright.config.ts file
    • Calling the setParallel() method inside each test file
    • Defining a custom test runner class

    Answer: Setting the 'workers' property in the playwright.config.ts file. The 'workers' property in the config is the correct way to control parallelism. Command line flags are used for overrides, but the config is the source of truth. Setting methods inside tests or custom runners is unnecessary and complex.

    From lesson: How do you implement parallel test execution in Playwright?

  177. If you have 10 tests and set 'workers: 2', how does Playwright execute them?

    • It runs all 10 tests simultaneously using 2 browsers
    • It runs 2 tests in parallel across 2 separate worker processes until all tests are finished
    • It splits the tests into 5 batches and runs them sequentially
    • It executes 5 tests at once in each worker

    Answer: It runs 2 tests in parallel across 2 separate worker processes until all tests are finished. Playwright spawns 'worker' processes. With 2 workers, it keeps those 2 processes busy running tests from the queue until the queue is empty. It does not run all tests at once (that would be 10 workers) nor in specific batches.

    From lesson: How do you implement parallel test execution in Playwright?

  178. Why is 'test.describe.serial' generally discouraged when trying to achieve fast test suites?

    • It increases the memory usage of the test runner
    • It requires a paid license for Playwright
    • It forces tests to run one after another, negating the benefits of parallel workers
    • It prevents the use of fixtures in those tests

    Answer: It forces tests to run one after another, negating the benefits of parallel workers. Serial blocks force tests to run on a single worker in order. If one fails, the rest skip, and it effectively slows down the suite by not utilizing available CPU cores for the other tests in that block.

    From lesson: How do you implement parallel test execution in Playwright?

  179. How can you isolate browser contexts for each test to ensure safe parallel execution?

    • Manually closing the browser after every test
    • Using the built-in 'page' or 'context' fixtures provided by the test runner
    • Wrapping tests in a global 'beforeAll' hook
    • Hardcoding a different base URL for every test

    Answer: Using the built-in 'page' or 'context' fixtures provided by the test runner. Playwright fixtures automatically create fresh contexts for every test, ensuring that cookies, local storage, and sessions do not leak between parallel tests. Manually closing or using global hooks is manual and error-prone.

    From lesson: How do you implement parallel test execution in Playwright?

  180. What happens when you set 'workers: 1' in your configuration?

    • It throws a configuration error
    • It runs all tests in sequence on a single process
    • It ignores the setting and defaults to auto-detection
    • It creates one master process and one worker process

    Answer: It runs all tests in sequence on a single process. Setting workers to 1 effectively disables parallel execution, forcing the runner to execute tests one by one. This is often used for debugging, not for performance. It is a valid configuration, not an error.

    From lesson: How do you implement parallel test execution in Playwright?

  181. When defining multiple browser targets in your Playwright configuration, what is the best practice for isolating their results?

    • Create separate test files for each browser
    • Use the 'projects' property in the playwright.config file
    • Use if-else statements inside every test to check the browser name
    • Run the test command three separate times with different browser environment variables

    Answer: Use the 'projects' property in the playwright.config file. The 'projects' property is the native, intended way to handle multi-browser configurations. Separate files lead to code duplication, if-else logic inside tests makes them brittle, and running commands multiple times is inefficient and hard to report on.

    From lesson: What strategies would you use for cross-browser testing with Playwright?

  182. Why would you choose to use Playwright's device descriptors during cross-browser testing instead of manually setting the viewport size?

    • Device descriptors automatically include the correct User-Agent and scale factors for that specific browser
    • Device descriptors are the only way to set the width and height of the page
    • Device descriptors allow tests to run faster by skipping rendering
    • Device descriptors automatically change the underlying browser engine to match the device

    Answer: Device descriptors automatically include the correct User-Agent and scale factors for that specific browser. Device descriptors provide a complete emulation profile (User-Agent, viewport, touch support). Manual viewport settings only change resolution. They do not increase speed, and they do not change the engine, making the other options incorrect.

    From lesson: What strategies would you use for cross-browser testing with Playwright?

  183. If a test passes in Chromium but fails in WebKit, what is the most likely cause?

    • Playwright's API is incompatible with WebKit
    • The test is using a browser-specific feature or CSS property that is not supported in the WebKit engine
    • The test is running too fast for WebKit to capture the elements
    • You forgot to set the 'webkit' flag in the global.setup file

    Answer: The test is using a browser-specific feature or CSS property that is not supported in the WebKit engine. Rendering differences between engines are common causes for cross-browser failures. Playwright's API is engine-agnostic, and engine speed differences are handled by automatic waiting. WebKit flags are set in config, not global setup.

    From lesson: What strategies would you use for cross-browser testing with Playwright?

  184. How can you run your tests specifically on Firefox while ignoring other defined browsers in your config?

    • Add a comment at the top of the test file
    • Use the --project flag followed by the project name in the terminal
    • Rename your Firefox test files to include 'firefox' in the name
    • Use the 'skip' attribute on every test file except Firefox

    Answer: Use the --project flag followed by the project name in the terminal. The CLI --project flag is the standard mechanism to filter test execution by configuration project. Comments, renaming files, and hardcoded skip attributes are inefficient and deviate from standard CLI practices.

    From lesson: What strategies would you use for cross-browser testing with Playwright?

  185. What is the primary advantage of testing across different browser engines with Playwright?

    • It verifies that your application handles cross-engine rendering quirks and differing web standards implementations
    • It increases the total code coverage percentage of your application
    • It ensures the server responds correctly to different browsers
    • It allows you to bypass the need for automated integration testing

    Answer: It verifies that your application handles cross-engine rendering quirks and differing web standards implementations. Engines like WebKit and Chromium interpret CSS and JS differently; testing verifies these quirks. Code coverage is measured by lines of code, not browsers. Servers respond to requests, not browsers, and cross-browser testing is a form of integration testing, not a replacement for it.

    From lesson: What strategies would you use for cross-browser testing with Playwright?