await expect(locator).toBeVisible(), Playwright does not check once and crash. It repeatedly polls the locator until it becomes visible, automatically handling animations and AJAX latency.---
// Visibility & State:
await expect(page.getByRole("button", { name: "Submit" })).toBeVisible();
await expect(page.getByRole("button", { name: "Submit" })).toBeEnabled();
await expect(page.getByLabel("Subscribe")).toBeChecked();// Text & Value:
await expect(page.getByTestId("status-badge")).toHaveText("Active");
await expect(page.getByTestId("welcome-message")).toContainText("Welcome back");
await expect(page.getByLabel("Username")).toHaveValue("john_doe");
// Page & URL:
await expect(page).toHaveURL("https://targetqa.com/dashboard");
await expect(page).toHaveTitle(/TargetQA - Automation Portal/);
// List Count:
await expect(page.locator("ul.cart-items > li")).toHaveCount(3);
---
expect.soft)expect aborts the test immediately on failure. Soft assertions record the failure and allow the test to continue running to check remaining fields!test("validate checkout summary fields", async ({ page }) => {
await page.goto("/checkout");// If subtotal fails, the test continues to verify tax and total!
await expect.soft(page.getByTestId("subtotal")).toHaveText("$100.00");
await expect.soft(page.getByTestId("tax")).toHaveText("$10.00");
await expect.soft(page.getByTestId("total")).toHaveText("$110.00");
});