Skip to content

Cypress URL Assertions

Confirming navigation happened correctly is one of the most common assertions in end-to-end testing. This lesson covers cy.url() and cy.location() for checking the current page after an action.

cy.url() and cy.location()

cy.url() yields the full current URL as a string, ideal for straightforward checks like confirming a redirect happened. cy.location() yields a parsed location object, useful when you need to check a specific part of the URL, like just the pathname or query string, independently.

cy.url().should('include', '/dashboard');

cy.location('pathname').should('eq', '/dashboard');
cy.location('search').should('include', 'tab=billing');

cy.location() with a specific key yields just that piece, avoiding manual string parsing of the full URL.

URL Assertion Syntax

cy.url().should('eq', 'http://localhost:3000/dashboard')
cy.url().should('include', '/dashboard')
cy.location('pathname').should('eq', '/dashboard')
cy.location('search').should('include', '?tab=billing')
cy.location('hash').should('eq', '#section-2')
  • cy.url() returns the complete, absolute URL as a plain string.
  • cy.location(key) returns a specific part: pathname, search, hash, host, and more.
  • Use include for partial matches and eq when the exact expected value is known.
  • Both commands are automatically retried like any other query command chained with .should().

URL Assertions Cheat Sheet

Common ways to verify navigation and query parameters after an action.

Goal Command
Full URL contains a path cy.url().should('include', '/dashboard')
Exact pathname cy.location('pathname').should('eq', '/dashboard')
Query string present cy.location('search').should('include', 'ref=email')
Hash fragment cy.location('hash').should('eq', '#top')
Redirected away from a page cy.url().should('not.include', '/login')

Asserting Immediately After a Navigation Action

Because navigation is often asynchronous (waiting on a network request, then a client-side route change), URL assertions benefit heavily from automatic retrying, the assertion simply waits until the URL actually changes, rather than needing an explicit delay after the triggering click.

cy.get('[data-cy="login-submit"]').click();
cy.url().should('include', '/dashboard'); // waits as long as needed, up to the timeout

Testing Query Parameters Precisely

For pages driven by query parameters (filters, pagination, tabs), asserting on cy.location('search') is more precise than checking the full URL string, since it isolates just the part of the URL that actually encodes application state.

cy.get('[data-cy="filter-in-stock"]').click();
cy.location('search').should('include', 'inStock=true');

Common Mistakes

  • Asserting on the full URL with eq in environments where the domain or port varies (like different local ports), causing unnecessary environment coupling.
  • Adding a manual wait before a URL assertion instead of letting the automatic retry handle timing.
  • Ignoring query parameters entirely when they represent meaningful, testable application state (filters, sorting, pagination).
  • Using include when an exact match with eq would catch unintended extra path segments.

Key Takeaways

  • cy.url() yields the full URL; cy.location(key) yields a specific parsed part.
  • URL assertions retry automatically, so no manual wait is needed after a navigation-triggering action.
  • Prefer cy.location('search') for precise query-parameter assertions over parsing the full URL manually.
  • Choose include versus eq deliberately based on how precise the check needs to be.

Pro Tip

When testing a page driven by query parameters (filters, sort order, pagination), assert on cy.location('search') directly rather than the whole URL, it keeps the test focused on the actual state that matters and ignores irrelevant host/port differences across environments.