Q14 of 42 · Playwright

How does Playwright handle cross-origin navigation differently from Cypress?

PlaywrightMidplaywrightcross-origincomparisoncypressmid

Short answer

Short answer: Playwright treats cross-origin navigation as a normal navigation — same `page`, same APIs, no special config. Cypress historically blocked cross-origin navigation; `cy.origin` (12+) supports it but with a constrained API. Playwright's design is uniformly cross-origin-friendly.

Detail

The difference is architectural. Cypress runs inside the browser tab, and the browser's same-origin policy used to lock Cypress out of cross-origin iframes and post-redirect pages. cy.origin('https://other.com', () => { ... }) was added in Cypress 12 to switch context, but it has caveats — limited subset of commands, no shared variables.

Playwright drives the browser from outside via the DevTools Protocol. The same-origin policy doesn't apply to the test driver; navigating from /login to https://idp.example.com/auth to /dashboard works seamlessly:

await page.goto('/login');
await page.click('[data-test=sso]');           // navigates to identity provider
await page.fill('input[name=username]', 'alice@x.com');
await page.click('button[type=submit]');       // returns to /dashboard
await expect(page).toHaveURL(/\/dashboard/);

Same page object, no context switch, no cross-origin block.

Implications:

  • OAuth / SSO flows are first-class testable. No backdoor login required (though it's still preferable for speed).
  • Embedded third-party iframes (Stripe, Auth0, reCAPTCHA) — Playwright can interact via page.frameLocator(...) regardless of origin.
  • Multi-page authentication redirects (legal terms, MFA flows) work end-to-end.

The trade-off: Playwright's cross-origin freedom makes it tempting to test third-party flows that should be stubbed. Hitting the real Stripe or Auth0 in tests is slow and fragile; their sandboxes are better. Use Playwright's freedom for your own multi-origin flows; stub third parties at the network layer (page.route).

A bonus capability — multiple browser contexts in one test, each with its own cookies and origin, simulate multi-user scenarios:

const context1 = await browser.newContext();
const context2 = await browser.newContext();
const userA = await context1.newPage();
const userB = await context2.newPage();
// Both navigate independently to the same or different origins

This is genuinely impossible in Cypress.

// WHAT INTERVIEWERS LOOK FOR

Knowing the architectural reason (out-of-process vs in-browser), naming `frameLocator` for iframes, and the multi-context capability for multi-user tests.

// COMMON PITFALL

Using Playwright's cross-origin freedom to test real third-party services in CI — slow, flaky, expensive. Stub them at the network layer.