webghost
webghost

Reputation: 131

How to get the value of an attribute

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

Answers (2)

Morland
Morland

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

agoff
agoff

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

Related Questions