'cy.url() and/or cy.location('href') does not return a string

I have an editor page. When I add any content and click the "Save" button my URL will change, adding a random id in the URL. I want to check if my ID's are changing every time when I click the "Save button".

I save the URL result in variable and want to check it, I do it like this:

const currentURL = cy.url();
cy.get('.editor-toolbar-actions-save').click();
cy.url().should('not.eq', currentURL);

But my currentURL variable's type is not string:

expected http://localhost:8080/editor/37b44d4d-48b7-4d19-b3de-56b38fc9f951 to not equal { Object (chainerId, firstCall) }

How I can use my variable?



Solution 1:[1]

tl;dr

Cypress commands are asynchronous, you have to use then to work with their yields.

cy.url().then(url => {
  cy.get('.editor-toolbar-actions-save').click();
  cy.url().should('not.eq', url);
});

Explanation

A similar question was asked on GitHub, and the official document on aliases explains this phenomenon in great detail:

You cannot assign or work with the return values of any Cypress command. Commands are enqueued and run asynchronously.

The solution is shown too:

To access what each Cypress command yields you use .then().

cy.get('button').then(($btn) => {
  // $btn is the object that the previous
  // command yielded us
})

It is also a good idea to check out the core concepts docs's section on asynchronicity.

Solution 2:[2]

These commands return a chainable type, not primitive values like strings, so assigning them to variables will require further action to 'extract' the string.

In order to get the url string, you need to do

cy.url().then(urlString => //do whatever)

Solution 3:[3]

Refer below code snippet, Here you can get the current URL and store it in a variable, do print via cy.log()

context('Get Current URL', () => {
 
    it('Get current url and print', () => {
        cy.visit('https://docs.cypress.io/api/commands/url')
    
        cy.url().then(url => {
            const getUrl = url
            cy.log('Current URL is : '+getUrl)
        })
    })
})

Solution 4:[4]

I have been having the same issue and so far most consistent method has been to save the URL to file and read it from file when you need to access it again:

//store the url into a file so that we can read it again elsewhere
cy.url().then(url => {
    const saveLocation = `cypress/results/data/${Cypress.spec.name}.location.txt`
    cy.writeFile(saveLocation, getUrl)
})

//elsewhere read the file and do thing with it
cy.readFile(`cypress/results/data/${Cypress.spec.name}.location.txt`).then((url) => {
    cy.log(`returning back to editor ${url}`)
    cy.visit(url)
})

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Alasdair McLeay
Solution 2 Vangelisz Ketipisz
Solution 3 Prabhu Mohan
Solution 4 Max Barrass