Assertions are a hot topic in Playwright interviews. Interviewers want to know: do you just click and pray, or do you actually verify? Can you explain auto-retrying? Do you know soft assertions? Here are the most asked questions from real interviews. Know these cold.
Q: What are auto-retrying assertions in Playwright?
A: Auto-retrying assertions take a locator as input and repeatedly check the condition until it passes or the timeout expires. The default timeout is 5 seconds and Playwright polls every 100ms. Example: expect(page.getByText("Success")).toBeVisible() will keep checking for 5 seconds if the element is not immediately visible. This eliminates the need for explicit waits like Thread.sleep() or waitForElement(). The key requirement is passing a locator, not a pre-resolved value -- expect(locator).toHaveText("x") retries, but expect(await locator.textContent()).toBe("x") does not.
Q: What is the difference between toBeVisible, toBeHidden, and toBeAttached?
A: toBeVisible passes when the element is in the DOM, has non-zero size, is not hidden by CSS (display:none, visibility:hidden, opacity:0), and is not obscured by another element. toBeHidden is the opposite -- passes when the element is not visible (hidden by CSS or not in DOM). toBeAttached only checks if the element exists in the DOM, regardless of visibility. Use toBeVisible for user-facing checks, toBeAttached for checking DOM presence of hidden elements like modals before they open.
Q: When would you use soft assertions?
A: Soft assertions (expect.soft()) collect all failures instead of stopping at the first one. I use them for independent verification checks -- like verifying all widgets on a dashboard page, checking multiple form fields, or validating table data. If widget 1 is broken, I still want to know about widgets 2 through 8. For sequential flows like login or checkout, I use hard assertions because continuing after a critical failure is pointless. The best practice is mixing: soft assertions for page verification, hard assertions for flow steps.
Q: How do you handle visual regression testing in Playwright?
A: Playwright has built-in toHaveScreenshot() for visual comparison. First run creates baseline screenshots. Subsequent runs compare pixel-by-pixel. I configure maxDiffPixels for acceptable differences due to font rendering. I use the mask option to hide dynamic content like dates and balances. I prefer element-level screenshots over full-page because they are more stable. All visual tests run in Docker to ensure consistent rendering. When UI changes are intentional, I run --update-snapshots and review the diff in git before committing.
Q: How do you write custom error messages for assertions?
A: Pass a string as the second argument to expect(): expect(locator, "Account balance should be visible after login").toBeVisible(). This message appears in the test output when the assertion fails. In CI with hundreds of tests, this saves significant debugging time because the error message explains the business context, not just the technical check. I write messages that would make sense to a product manager, not just a developer.
Q: How do you organize assertions in a large project?
A: I use three layers. First, helper functions for common patterns: assertPageLoaded(), assertToastMessage(), assertTableState(). Second, assertion classes that pair with Page Object Models -- each page has a corresponding assertion class that knows how to verify that page. Third, custom expect matchers for domain-specific logic like currency validation. Tests become one-liners: dashboard.verifyBalance("$5,000"). I start simple with functions and add classes when the suite reaches 50+ tests.
| Question | One-Line Answer |
|---|---|
| Default assertion timeout? | 5 seconds (configurable via expect.timeout in config) |
| How to change timeout per assertion? | Pass { timeout: 10000 } as option |
| toHaveText vs toContainText? | toHaveText = full match, toContainText = substring match |
| Are soft assertions auto-retrying? | Yes -- expect.soft(locator) retries just like expect(locator) |
| not.toBeVisible vs toBeHidden? | Same result -- pick one convention for your team |
| How to update visual snapshots? | Run with --update-snapshots flag |
| Can custom matchers auto-retry? | No -- use expect.poll() for retrying custom checks |
| How to mask dynamic content in screenshots? | Pass mask: [locator1, locator2] to toHaveScreenshot() |
Key Point: Know auto-retrying vs non-retrying, soft vs hard assertions, visual testing, and assertion organization. These topics cover 90% of assertion-related interview questions.
Key Point: Auto-retrying, soft assertions, visual testing, custom messages, and assertion architecture -- these are the top interview topics for Playwright assertions.
Answer all 5 questions, then submit to see your score.
1. What makes Playwright assertions "auto-retrying"?
2. Which code snippet will cause flaky tests due to NOT auto-retrying?
3. What happens when a soft assertion fails?
4. How do you handle dynamic content like dates and timestamps in visual screenshot assertions?
5. Which assertion should you use to verify an input field contains "john@test.com" after filling it?