url
Get the full URL of the page under test as a string.
cy.url() yields the same value as
cy.location('href').
Syntax​
cy.url()
cy.url(options)
Usage​
Correct Usage
cy.url() // Yields the current URL as a string
Incorrect Usage
const url = cy.url() // Yields a chainable, not the URL string
cy.get('a').url() // Ignores the link, yields the page's URL
Cypress commands are enqueued and run later, so cy.url() never returns the URL
directly. To work with the string, read it in a .then()
callback or save it as an alias:
cy.url().then((url) => {
// url is the current URL as a string
})
cy.url().as('startUrl')
Arguments​
options (Object)
Pass in an options object to change the default behavior of cy.url().
cy.url( options )
| Option | Default | Description |
|---|---|---|
decode | false | Decode the URL with decodeURI() before yielding it |
log | true | Displays the command in the Command log |
timeout | defaultCommandTimeout | Time to wait for cy.url() to resolve before timing out |
Yields ​
cy.url()yields the current URL as a string.cy.url()is a query, and it is safe to chain further commands.
cy.url() yields the whole URL, labeled href in this diagram:
Examples​
No Args​
Assert the URL is http://localhost:8000/users/1/edit​
// clicking the anchor causes the browser to follow the link
cy.get('#user-edit a').click()
cy.url().should('include', '/users/1/edit')
cy.url().should('eq', 'http://localhost:8000/users/1/edit')
decode option​
The browser percent-encodes non-ASCII characters in the URL. To assert on the
readable text, pass decode: true.
// For the curious, '사랑' means 'love' in Korean.
cy.url({ decode: true }).should('contain', '사랑')
decode runs the URL through
decodeURI(),
which leaves escapes for reserved characters such as /, ?, &, and #
encoded. Given the remote URL http://localhost:8000/search?q=caf%C3%A9%26bar,
the decoded URL keeps %26:
cy.url({ decode: true }).should(
'eq',
'http://localhost:8000/search?q=café%26bar'
)
| In the URL | With decode: true | Why |
|---|---|---|
%EC%82%AC%EB%9E%91 | 사랑 | Non-ASCII characters are decoded |
%C3%A9 | é | Non-ASCII characters are decoded |
%26 | %26 | & is reserved, so it stays encoded |
%2F | %2F | / is reserved, so it stays encoded |
Redirects and navigation​
Wait for a redirect after signing in​
cy.url() retries until its assertions pass, so the test waits for your
application to finish redirecting without a cy.wait().
cy.get('#password').type('secret')
cy.contains('button', 'Sign in').click()
cy.url().should('include', '/dashboard')
In the Command Log, the url assertion passes on the dashboard URL, and the
redirect's page load and new URL appear as their own rows:

Match a URL that contains a generated ID​
When a URL includes a value your test doesn't know in advance, such as the ID of a record the test created, match it with a regular expression.
cy.contains('button', 'Create user').click()
cy.url().should('match', /\/users\/\d+\/edit$/)
Assert that the URL doesn't change​
Save the URL before an action, then compare against it afterward. Here, the
required field blocks the form from submitting, so the page stays where it
is.
<form action="/saved">
<input name="name" required />
<button>Save</button>
</form>
cy.url().then((startUrl) => {
cy.contains('button', 'Save').click()
cy.url().should('eq', startUrl)
})
Cross-origin redirects​
Assert that sign-in redirects to an identity provider​
Because cy.url() reads the URL
across origins, you can confirm where a
sign-in flow landed before you interact with that page inside
cy.origin().
cy.visit('http://localhost:8000/')
cy.contains('a', 'Sign in with SSO').click()
cy.url().should('include', 'http://auth.example.com/login')
cy.origin('http://auth.example.com', () => {
cy.get('input[name="username"]').type('jane')
})
Notes​
cy.url() versus cy.location('href')​
cy.url() reads the current URL and yields its href, the same string
cy.location('href') yields. Given the remote URL
http://localhost:8000/index.html, all 3 of these assertions are the same:
cy.location('href').should('include', '/index.html')
cy.location().its('href').should('include', '/index.html')
cy.url().should('include', '/index.html')
href is the name the window.location spec gives the full URL. There is no
url property on the location object, so cy.url() gives the full current
URL the name most developers reach for first.
Assert on part of the URL with cy.location()​
cy.url() yields the whole URL, including the protocol, host, and port, so an
assertion on it names the host. When you only care about the path or the query
string, assert on that part with cy.location()
instead of hardcoding or slicing the full URL. The assertion then passes on any
host, such as a local server, CI, or a preview deployment. The pathname and
search labels in the URL diagram under Yields show which part each
one reads.
// given remote URL: http://localhost:8000/users/1/edit?tab=profile
cy.location('pathname').should('eq', '/users/1/edit')
cy.location('search').should('eq', '?tab=profile')
To keep the host out of cy.visit() as well, define a
baseUrl in your Cypress configuration. For
more details on why, see our Best Practices guide on
setting a global baseUrl.
Trailing # and ? in the URL​
The browser keeps a bare # or ? at the end of the URL, so cy.url() yields
it even though the hash or query string is empty. A link to # adds a trailing
#:
<nav>
<a href="#/users/1">Open profile</a>
<a href="#">Close profile</a>
</nav>
cy.contains('a', 'Close profile').click()
cy.url().should('eq', 'http://localhost:8000/index.html#')
cy.hash().should('eq', '')
cy.location('pathname').should('eq', '/index.html')
A URL ending in ? works the same way:
// given remote URL: http://localhost:8000/index.html?
cy.url().should('eq', 'http://localhost:8000/index.html?')
cy.location('search').should('eq', '')
To leave the trailing character out of the assertion, compare the
pathname with cy.location().
Cross-origin pages and cy.url()​
cy.url() reads the URL from the browser rather than from the page's window,
so it yields the URL after your application navigates to another origin,
without wrapping the command in cy.origin().
Rules​
Requirements ​
cy.url()requires being chained off ofcy.
Assertions ​
cy.url()automatically retries until all chained assertions have passed
Timeouts ​
cy.url()can time out waiting for assertions you've added to pass.
Command Log​
Assert that the URL includes #users/new
cy.url().should('include', '#users/new')
The commands above display in the Command Log as:

When clicking on url within the Command Log, the console outputs the
following:

History​
| Version | Changes |
|---|---|
| 15.0.0 | Reads the URL through the browser's automation client instead of the page's window in Chromium-based browsers and Firefox |
| 8.4.0 | decode option added |
| < 0.3.3 | cy.url() command added |