Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cypress: set attribute value

I have just started exploring Cypress and came across such a problem: is it possible to select a concrete attribute and change its value like in Selenium with the help of JavascriptExecutor? For example lets take this simple piece of code

input id="mapsearch" type="textbox" class="form-control" name="address" test=""

Is it possible to get the test attribute and assign my own value?

like image 937
R.Ro Avatar asked Nov 06 '17 07:11

R.Ro


People also ask

How does cypress set value?

You can use html5 data attributes. data-test="test". And then you can select this based on this attribute value.

How do you get attribute values in Cypress?

To find elements by data attribute, query using the attribute selector. cy. get() yields a jQuery object, you can get its attribute by invoking the . attr() method.


3 Answers

Yes. Anything you can do in JavaScript is possible within Cypress tests. For the html above, you could do this within Cypress using .invoke():

cy.get('input[test]')
  .invoke('attr', 'test', 'my new value')
  .should('have.attr', 'test', 'my new value')

Cypress uses jQuery under the hood, so you can invoke any function in jQuery like this. You could alternatively use plain JavaScript after yielding the input using .then():

cy.get('input[test]').then(function($input){
    $input[0].setAttribute('test', 'my new value')
  })
  .should('have.attr', 'test', 'my new value')
like image 81
Jennifer Shehane Avatar answered Oct 24 '22 10:10

Jennifer Shehane


While Jennifer's answer actually works for most of the input elements, there is an exception especially when the application only takes the input value on input/change event as invoke will not trigger the event.

I had such experience and the below code worked for me.

In Commands.js:

Cypress.Commands.add('inputChange', (input, value) => {
    const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
      window.HTMLInputElement.prototype,
      'value'
    ).set

    const changeInputValue = inputToChange => newValue => {
      nativeInputValueSetter.call(inputToChange[0], newValue)
      inputToChange[0].dispatchEvent(new Event('input', {
        newValue,
        bubbles: true,
        composed: true
      }))
    }

    return cy.get(input).then(input => {
      changeInputValue(input)(value)
    })
  })

And in Tests:

   cy.get('[data-test="voy-lat-long-input"]')
        .then(input => cy.inputChange(input, Longtitude))
like image 32
Dhamo Avatar answered Oct 24 '22 10:10

Dhamo


You can try with this

cy.get('.class/#id').type('type your new value', { force: true });
like image 3
perumal N Avatar answered Oct 24 '22 10:10

perumal N