Ten questions at a time, drawn from 185. Every answer is explained. Nothing is saved and no account is needed.
What is the primary benefit of Playwright's auto-waiting mechanism?
Practice quiz for . Scores are not saved.
What is the primary benefit of Playwright's auto-waiting mechanism?
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
Why does Playwright recommend using locators like getByRole over CSS selectors?
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
What is the purpose of a Browser Context in Playwright?
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
Which of the following describes the 'web-first' assertions feature in Playwright?
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
How does Playwright handle parallel test execution efficiently?
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
When comparing architecture, why is Playwright generally faster at executing tests than tools that inject scripts into the browser?
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)
How does Playwright handle multi-tab or multi-window scenarios differently than tools that are restricted to a single-tab execution model?
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)
What is the primary benefit of Playwright’s 'auto-waiting' mechanism during element interaction?
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)
In the context of network interception, why does Playwright's native approach offer an advantage over external proxy tools?
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)
When handling cross-browser testing, why does Playwright prioritize the use of browser contexts?
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)
Which command ensures your project is fully prepared to execute browser automation after adding the Playwright dependency?
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
Why is it recommended to use a dedicated 'playwright.config.ts' file instead of defining settings inside each test file?
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
What happens if you attempt to run a Playwright script before installing the required system-level dependencies on a fresh Linux container?
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
When setting up a project, why is it preferable to define Playwright as a 'devDependencies' rather than a 'dependencies' entry in package.json?
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
If your project uses TypeScript, what is the purpose of including 'ts-node' or configuring the TypeScript compiler in the Playwright environment?
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
After executing 'npm install playwright', why might your test fail to launch a browser?
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
What is the primary purpose of the 'npx playwright install --with-deps' command?
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
If you are working in a restricted network environment, how can you manage Playwright browser installations?
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
Why does Playwright manage its own browser binaries rather than using system-installed browsers?
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
Which file is essential for configuring browser settings, such as viewport size and timeout, before tests run?
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
When you call 'page.click()', what does Playwright do before performing the action?
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
Why is 'getByRole' preferred over CSS or XPath selectors in Playwright?
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
What happens if a test script executes a command without an 'await' keyword?
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
What is the primary benefit of using Web-First assertions like 'expect(locator).toBeVisible()'?
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
How should you handle an element that takes time to appear on the page?
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
Why does Playwright recommend using locators that reflect user-facing attributes (like getByRole) over CSS or XPath selectors?
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
What happens when you perform an action like 'page.click()' on a button that is currently hidden by an overlay?
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
When running tests in parallel, what is the primary risk of using global variables to store test state?
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
Which of the following best describes the purpose of 'expect(locator).toBeVisible()' in a test?
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
If you have a 'beforeEach' hook, when exactly does it execute in relation to the test file?
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
What is the primary benefit of using Web-First assertions in Playwright?
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
If you write 'expect(locator).toBeVisible()', what happens if the element is currently hidden but appears after 500ms?
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
Which of the following describes the correct behavior of the 'await' keyword in Playwright assertions?
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
Why should you prefer 'expect(locator).toHaveText()' over 'const text = await locator.textContent(); expect(text).toBe(...)'?
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
When a test is structured with 'test('description', async ({ page }) => { ... })', what is the role of the 'page' fixture?
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
When configuring multiple reporters, how does Playwright handle them during a test execution?
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
If you need to view a report generated on a remote CI server locally, what is the best approach?
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
What is the primary benefit of enabling 'trace: on' when generating reports for failed tests?
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
How does Playwright handle report generation when tests are executed in parallel across multiple workers?
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
What is the consequence of setting the 'open' property to 'always' in the HTML reporter configuration?
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
When testing a login form, which locator strategy is most resilient to design changes?
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
What happens when you use multiple locator chains, such as 'page.locator('.sidebar').locator('button')'?
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
Why is 'getByRole' preferred over other locator methods?
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
If an element is located inside a shadow DOM, how does Playwright handle it?
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
What is the primary benefit of using 'filter' on a locator?
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
How should you handle a custom dropdown built with `<div>` elements in Playwright?
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)
What’s the best way to ensure a button is clickable before interacting with it?
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)
How would you test a form where the submit button is disabled until all fields are valid?
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)
What’s the most maintainable way to locate an input field with dynamic IDs?
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)
How should you handle a dropdown where options are loaded via API after clicking it?
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)
When is it appropriate to use a hardcoded timeout like `page.waitForTimeout()`?
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
A test fails because an element is present in the DOM but hidden by a loading spinner. How should you handle this?
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
What happens if you use `page.click('button')` on an element that is currently obscured by a transparent overlay?
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
Why is `expect(locator).toHaveText('Success')` preferred over `await page.innerText('selector')` followed by a manual comparison?
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
If your tests are consistently timing out on CI but passing locally, what is the most robust strategy?
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
What is the primary reason to use frameLocator instead of standard locators when dealing with an iframe?
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
If you have a nested structure (iframe inside an iframe), what is the correct approach to access an element in the inner frame?
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
When does Playwright evaluate the selector provided to a frameLocator?
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
Which of the following is true regarding frameLocators and auto-waiting?
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
What happens if a frame is removed from the DOM and then re-added during a test?
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
What is the correct way to handle a browser-native alert that appears after clicking a button?
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
How do you test that a custom modal (e.g., a `<div>` styled as a dialog) is visible after an action?
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
What happens if you forget to call `dialog.accept()` or `dialog.dismiss()` in a dialog handler?
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
How do you verify the text of a native confirm dialog before accepting it?
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
Why might a test fail if you register a dialog handler *after* triggering the action that opens the dialog?
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
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?
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
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?
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
How should you handle a situation where a button click opens a link in a 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
What does the 'networkidle' state in 'waitForLoadState' actually guarantee?
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
Why might a navigation triggered by a history button (goBack or goForward) fail to be detected?
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
How do you correctly capture a new page opened by a user interaction in Playwright?
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
If you perform an action that triggers a new tab, why must you capture that tab via a promise-based event listener?
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
When working with multiple pages in the same browser context, what happens if you close the context?
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
Why should you avoid using a generic 'page' variable when juggling multiple browser tabs?
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
Which method is best suited for closing a specific page without ending the entire browser session?
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
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?
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
If you want to simulate a slow network for a specific request using page.route(), how should you implement the handler?
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
Why would you choose route.abort() instead of route.fulfill() for a specific request in your test?
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
How do you modify the body of a request before it reaches the server using page.route()?
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
What happens if you have two route handlers registered that both match the same request URL?
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
What is the primary benefit of using multiple projects within the playwright.config file?
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
When should you use 'dependencies' in a Playwright project configuration?
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
How does setting a 'baseURL' in the playwright.config file impact your tests?
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
If you have a 'smoke' project and a 'regression' project, how do you execute only the smoke 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
Why is it recommended to use fixtures for setup instead of globalSetup for most test scenarios?
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
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?
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
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?
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
How does Playwright handle failures within a `test.each()` scenario?
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
Why might you use a custom title function in the second argument of `test.each()`?
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
When refactoring a standard test into a parameterized test, what is the most important architectural change to make?
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
Why does Playwright's default visual regression mechanism use a 'baseline' file?
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
What happens if you run a visual regression test for the first time without a baseline image existing?
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
When testing a page with dynamic data, which configuration property should be used to exclude specific components from the screenshot?
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
If your test fails due to a visual difference that is only 0.2% but you are using the default settings, what will happen?
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
Why is it best practice to test visual regression in a containerized environment like Docker?
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
When using storageState to persist authentication, what is the primary benefit over performing a full login sequence?
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
Why should you use 'globalSetup' for authentication instead of putting login steps in 'beforeEach' for every test?
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
If your application uses different storage keys for auth tokens, which Playwright feature ensures a complete capture of the session?
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
When writing a test that relies on a pre-saved storage state, how does Playwright know which file to use?
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
What is the consequence of using a stale storage state file in a CI environment?
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
When Playwright runs tests in parallel, how is isolation maintained?
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
What happens when you execute tests with '--shard=1/3'?
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
Why might increasing the number of workers lead to test failures in an existing suite?
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
How does Playwright determine how many tests to run in parallel by default?
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
What is the primary benefit of sharding in a CI/CD pipeline?
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
When configuring a CI pipeline to run Playwright tests, what is the most reliable way to ensure all necessary browser dependencies are present?
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
What is the primary benefit of defining a 'webServer' in your playwright.config file for CI/CD?
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
If your tests pass locally but fail in CI due to timeouts, what is the best strategy to debug the issue?
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
To improve CI performance, what is the best way to utilize worker settings?
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
How should you handle sensitive environment variables like API keys or credentials in a CI/CD pipeline?
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
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?
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
Which approach is most effective for debugging an interaction that triggers a hidden overlay or modal?
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
What is the primary advantage of using locators like getByRole over CSS selectors during a debugging session?
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
A test fails because an element is 'hidden'. What is the first thing you should verify using the Playwright Inspector?
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
Why is 'expect().toBeVisible()' preferred over checking an element's existence when debugging race conditions?
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
When measuring the performance of an action, why is it discouraged to rely solely on the duration of an `await page.click()` call?
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
Which approach is most effective for capturing precise performance data for a network request during a test?
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
Why does Playwright's 'networkidle' state often produce inconsistent results in performance testing?
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
How can you simulate a throttled environment to identify performance bottlenecks in asset loading?
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
When generating a Trace Viewer file for performance analysis, what is the primary benefit over traditional console logging?
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
When refactoring a test suite to use the Page Object Model, what is the primary goal?
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
Why is it recommended to use 'data-testid' over CSS classes for selecting elements?
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
What is the correct way to handle a dynamic element that takes time to appear in the DOM?
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
If multiple tests require the same logged-in state, what is the most efficient approach?
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
Which of the following describes a 'flaky' test?
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
When refactoring a Playwright test to use POM, what is the primary benefit of returning a new Page Object instance from a method?
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
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?
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
What is the correct way to handle elements that might not be visible immediately in a Page Object model?
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
Which of the following describes the best practice for handling dynamic user-specific data in a Page Object?
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
Why is it discouraged to perform assertions inside the Page Object class?
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
What is the primary advantage of using a custom fixture over a 'beforeEach' hook for page objects?
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
If you define a fixture that depends on the base 'page' fixture, how does Playwright resolve this?
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
What happens if you define a fixture and fail to call the 'use' function within it?
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
Why would you choose a 'worker' scope for a fixture instead of the default 'test' scope?
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
How do you correctly handle cleanup (teardown) logic within a fixture?
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
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?
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
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?
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
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?
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
How does using test.only() affect the execution of a test file during local development?
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
You have a test that should only execute on Chromium-based browsers. Which approach correctly handles this using an annotation?
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
What is the primary benefit of creating custom matchers in Playwright?
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
Which property must be returned by the matcher function for Playwright to correctly interpret the assertion result?
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
Where is the most appropriate place to register custom matchers if you want them available across your entire test suite?
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
When defining a custom matcher, what is the purpose of the 'message' function?
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
If you are writing a custom matcher that needs to check a property of an element, how should you handle the input element?
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
When using TypeScript with Playwright, which approach best ensures type safety for custom test fixtures?
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
Why is it recommended to use user-facing locators like 'getByRole' instead of CSS selectors?
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
What is the primary benefit of using web-first assertions like 'expect(locator).toBeVisible()'?
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
If a test fails with a timeout error despite using an await, what is the most likely cause?
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
How should you handle an element that only appears after a network request finishes?
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
When utilizing the Playwright test runner, how should you best handle the initialization of a page for multiple tests?
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)
What is the primary advantage of using the native Playwright test runner over using a third-party framework like Jest or Mocha?
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)
If you need to change the base URL for tests dynamically, where is the most appropriate place to define this within a Playwright project?
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)
Why should you avoid using standard assertion libraries (like expect from Chai) when using the Playwright test runner?
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)
How does Playwright handle test isolation when running multiple tests in the same file?
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)
When extending Playwright with a custom plugin using 'test.extend', what is the primary advantage of using fixtures over manual setup functions?
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
If a plugin is interfering with the performance of your tests, what should be your first diagnostic step?
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
Why should you avoid using global variables to store data initialized by a plugin?
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
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?
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
How does Playwright ensure that a custom plugin properly supports parallel execution?
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
Why is Playwright considered more resilient than older automation frameworks when interacting with elements?
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
How does BrowserContext improve test suite efficiency?
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
What is the primary advantage of using 'getByRole' over CSS selectors?
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
When should you use the 'page.waitForTimeout' method in a test script?
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
How does Playwright handle multiple tabs within the same test?
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
When interacting with an element that appears after a network request, what is the recommended approach in Playwright?
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?
Which locator strategy is most resilient to changes in the underlying DOM structure?
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?
What is the primary purpose of 'Web-First Assertions' in Playwright?
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?
If you have a dynamic list that updates via AJAX, how should you ensure the element exists before clicking?
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?
How should you handle elements that are hidden and then revealed by hover interactions?
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?
What is the primary benefit of Playwright's auto-waiting mechanism?
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
When does Playwright perform an auto-waiting check?
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
Which state must an element reach for Playwright's auto-waiting to consider it ready for a click?
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
If you are trying to click an element that is covered by a loading spinner, what will Playwright's auto-waiting do?
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
Why is it still necessary to use assertions like 'toBeVisible()' even with auto-waiting?
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
What is the primary mechanism for configuring the number of parallel workers in Playwright?
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?
If you have 10 tests and set 'workers: 2', how does Playwright execute them?
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?
Why is 'test.describe.serial' generally discouraged when trying to achieve fast test suites?
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?
How can you isolate browser contexts for each test to ensure safe parallel execution?
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?
What happens when you set 'workers: 1' in your configuration?
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?
When defining multiple browser targets in your Playwright configuration, what is the best practice for isolating their results?
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?
Why would you choose to use Playwright's device descriptors during cross-browser testing instead of manually setting the viewport size?
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?
If a test passes in Chromium but fails in WebKit, what is the most likely cause?
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?
How can you run your tests specifically on Firefox while ignoring other defined browsers in your config?
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?
What is the primary advantage of testing across different browser engines with Playwright?
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?