1. What does Playwright's auto-waiting do before clicking an element?
Answer
Waits until the element exists, is visible and is enabled, then clicks
Correct. Actions perform actionability checks automatically, which removes most manual waiting code.
Actionability checks are Playwright's core stability feature: actions wait for the element to be ready, and assertions retry until they pass.
Why the other answers are wrong
- Waits a fixed 30 seconds before every click. It waits *up to* a timeout, but continues immediately as soon as the element is actionable.
- Nothing. You must call waitForSelector before every action. Manual waits before actions are unnecessary; the action itself waits.
- It only waits when you add the await keyword twice. There is no double-await concept; a single await runs the action with built-in waiting.
2. In test('...', async ({ page }) => {...}), what is { page }?
Answer
A fixture, Playwright creates an isolated page for this test and passes it in
Correct. Fixtures provide per-test, isolated resources. Each test gets a fresh page/context, which keeps tests independent.
Fixtures are Playwright's dependency injection: { page } gives every test its own fresh browser page automatically.
Why the other answers are wrong
- A global variable shared by all tests. Pages are not shared, isolation between tests is the whole point of fixtures.
- An import you must define at the top of the file. It is destructured from the fixture object the test function receives, not imported.
- A jQuery object. page is Playwright's Page API, unrelated to jQuery.
3. How do you assert that the user landed on the dashboard after login?
Answer
await expect(page).toHaveURL(/dashboard/)
Correct. toHaveURL is a retrying page assertion, it waits for the navigation to finish.
expect(page).toHaveURL retries until the URL matches or times out, no race with the navigation.
Why the other answers are wrong
- assert(page.url === '/dashboard'). page.url is a method, and a plain assert does not retry, it can run before the navigation finishes.
- await page.waitForTimeout(3000) then check the title. A fixed sleep is a guess. The retrying URL assertion waits exactly as long as needed.
- Check that the login button disappeared. That is indirect. Assert the thing you mean: the URL (or a dashboard element).
4. A test calls await page.getByTestId('toast').click() while the toast has not appeared yet. What happens?
Answer
Playwright retries the lookup and clicks as soon as the toast is actionable, or fails at the timeout
Correct. The action auto-waits. If the toast never appears, the test fails with a clear timeout message.
Auto-waiting means the action itself is the wait. You rarely need to wait for an element before acting on it.
Why the other answers are wrong
- The test fails immediately with element not found. Actions do not fail immediately, they retry up to the timeout.
- The click lands on whatever is at those coordinates. Playwright clicks the element you located, not a screen position.
- The click is silently skipped. Actions are never skipped. They either happen or fail loudly.
5. A test uses await page.waitForTimeout(2000) before an assertion. What is the professional replacement?
Answer
Delete the sleep. The web-first assertion already retries until the condition holds
Correct. Assertions like toHaveText poll the page. The fixed sleep only adds time and flakiness.
waitForTimeout is a fixed sleep. Retrying assertions make it unnecessary in almost every test.
Why the other answers are wrong
- Raise it to 5000 to be safe. A bigger guess is still a guess. It slows every run and can still be too short.
- Wrap it in a try/catch. That hides failures instead of waiting correctly.
- Move the sleep before the click instead. Moving a sleep does not fix it. Wait for the condition, not the clock.
6. What do test.describe and test.beforeEach give you?
Answer
describe groups related tests; beforeEach runs shared setup before every test in the group
Correct. Shared setup in beforeEach keeps each test independent. Every test starts from the same state.
Group with describe, set up in beforeEach. Each test then stands alone. The base rule of a reliable suite.
Why the other answers are wrong
- They make tests run in parallel. Parallelism is configured separately. These organize tests and setup.
- They are required for any test to run. A lone test() works fine. These are organization tools.
- describe defines one test; beforeEach defines the second. describe is a group, not a test. Tests are declared with test().
7. A test fails with: 'Timed out 5000ms waiting for locator getByTestId("cart-count") to be visible'. What does this tell you?
Answer
Playwright retried for 5 seconds and the element never became visible, check the selector and whether it should appear
Correct. Either the test id is wrong, or the app never showed the element here. Both are worth checking before touching timeouts.
Timeout messages name the locator and the condition. Read them literally: this thing never became visible here.
Why the other answers are wrong
- The test needs a bigger timeout. More time rarely helps. If the element never appears, 30 seconds fails the same way.
- Playwright crashed. It did not crash, it waited, then reported precisely what it waited for.
- The assertion library is broken. The message is the assertion working: it names the locator and the condition that never held.
8. Why does Playwright give every test a fresh page and browser context?
Answer
So no test can depend on state another test left behind. Each test passes or fails on its own
Correct. Isolation makes tests order-independent and safe to run in parallel.
Per-test isolation is why a Playwright test that passes alone passes anywhere. Never share state between tests.
Why the other answers are wrong
- Because browsers cannot reuse tabs. They can. Isolation is a deliberate design choice, not a limitation.
- To make the suite slower and more thorough. Contexts are cheap. The goal is independence, not slowness.
- So cookies persist between tests. The opposite: a fresh context clears cookies and storage between tests.