Reputation: 131
I need to extract an attribute's value from any given tag. For instance, if we have an <a>
, and it contains an href
, I would like to extract the value and store it in a variable. After doing some researching/investigation, I found that most people are acquiring attribute values using the following methods:
METHOD # 1: INVOKE METHOD
cy.get('a').invoke('attr', 'href').should('eq', 'https://docs.cypress.io')
METHOD # 2: PROP METHOD
cy.get('input').invoke('prop', 'href').then(href => {console.log(`href ${href}`)})
Method # 1 above performs a test .. although finds the value, it runs it through a .should()
but that is not what I want. I want to literally extract the value and store it in a variable for later use. I have no intention to perform an assertion.
Method # 2 does not even work for me.. in the example, href
is simply coming back as "undefined"
In a nutshell, I simply want the value of a given attribute to store, display and possibly perform some string manipulation on it. I do not wish to perform any checks/tests. Just merely acquire the value and store it in a variable.
Upvotes: 1
Views: 2521
Reputation: 178
This cy.get('input').invoke('prop', 'href')
is invalid because href
is an attribute, not a property.
.invoke('attr', 'href')
should allow you to save the value, but remember to access it from a command or a callback, because the preceding commands are asynchronous.
let href;
cy.get('input').invoke('attr', 'href')
.then(value => href = value)
...
// later
cy.then(() => {
console.log(href) // inside callback
})
// or
cy.url().then(url => {
expect(url).to.include(href) // inside callback
})
Ref Closures
By using callback functions we've created a closure. Closures enable us to keep references around to refer to work done in previous commands.
More complete example from the docs
cy.get('button').then(($btn) => {
// store the button's text
const txt = $btn.text()
// submit a form
cy.get('form').submit()
// compare the two buttons' text
// and make sure they are different
cy.get('button').should(($btn2) => {
expect($btn2.text()).not.to.eq(txt)
})
})
Upvotes: 4
Reputation: 7145
I'd advise you to look at Filip Hric's blog post on Cypress variables. He offers several ways to store Cypress variables.
My personal choice would be to use a Cypress environment variable.
cy.get('input')
.invoke('attr', 'href')
.then((href) => {
// href is the value of the element's href attribute
Cypress.env('myCustomVariableName', href);
// The first parameter is whatever name for the variable you'd like
// The second parameter is the value you want to store
});
...
// later
cy.get('someOtherInput')
.should('have.attr', 'href', Cypress.env('myCustomVariableName');
// In this case, we'd be asserting the second input element has the same href value.
Upvotes: 2