Kermi
Kermi

Reputation: 247

Get text from element & use it for next action

I'm beginner Cypress user, currently facing a problem with getting text from DOM element and then using it for next action.

Steps which were done by me:

1) Get element + text

Then(
  "User change quantity of product: {string} to {int}",
  (productName, qty) => {
    var currentQty;
       cy.get("[data-cy ='basketContainer']")
          .contains(productName)
          .parent()
          .parent()
          .find("div > span")
          .then((variable) => {
            var quantityText = variable.text();
            cy.wrap(quantityText).as("quantityText");
          });

In this case I'm completely not sure if entire: "then" is ok. The case which I was investigation is that in cypress there is no "normal" variable assignment. It may be done with combination of wrap and then alliasing it.

2) Get the alliased value

cy.get("@quantityText");

Not very needed step but I was wondering if we can reference to aliases by '@'

3) Use that alias inside the "method"

    var increaseButton = cy.get("[data-cy='decreaseQtyProduct']");
    var decreaseButton = cy.get("[data-cy='increaseQtyProduct']");
    var timesToClick = cy.get("@quantityText") + qty;
    cy.log(timesToClick)
    if (currentQty == qty) {
      console.log("Do nothing, values are equal!");
    } else if (currentQty > qty) {
      for (let i = 1; i < timesToClick; i++) decreaseButton.click();
    } else if (currentQty < qty) {
      timesToClick = Math.abs(timesToClick);
      for (let i = 1; i < timesToClick; i++) increaseButton.click();
    }

When I'm cy.logging that variable: "timesToClick" I'm receiving [object Object] instead of text inside an element. For sure what also needs to be done is to parse that string value to int value.

Upvotes: 1

Views: 562

Answers (2)

Seeker
Seeker

Reputation: 465

There's nothing wrong with the way you create the alias, but when using it don't save the result of cy.get(...) to variables, either getting the alias or selecting the elements.

It can lead to unpredictable results. For element selection, you can save the selector string instead. For using the alias, you must use .then().

Some other optimizations included too.

const increaseButton = "[data-cy='decreaseQtyProduct']"
const decreaseButton = "[data-cy='increaseQtyProduct']"

cy.get('@quantityText').then(quantityText => {

  if (currentQty === qty) return

  const timesToClick = Math.abs(parseInt(quantityText) + qty)
  const selector = currentQty > qty ? increaseSelector : decreaseSelector;

  Cypress._.times(timesToClick, () => cy.get(selector).click())
})

Upvotes: 2

Alapan Das
Alapan Das

Reputation: 18586

You can alias the inner text like this:

Then(
  'User change quantity of product: {string} to {int}',
  (productName, qty) => {
    var currentQty
    cy.get("[data-cy ='basketContainer']")
      .contains(productName)
      .parent()
      .parent()
      .find('div > span')
      .invoke('text')
      .as('quantityText')
  }
)

Then you can fetch the value from the alias like this:

var increaseButton = cy.get("[data-cy='decreaseQtyProduct']")
var decreaseButton = cy.get("[data-cy='increaseQtyProduct']")
cy.get('@quantityText').then((quantityText) => {
  var timesToClick = +quantityText + qty //+quantityText changes string to number
  console.log(timesToClick) //prints the number
  if (currentQty == qty) {
    console.log('Do nothing, values are equal!')
  } else if (currentQty > qty) {
    for (let i = 1; i < timesToClick; i++) decreaseButton.click()
  } else if (currentQty < qty) {
    timesToClick = Math.abs(timesToClick)
    for (let i = 1; i < timesToClick; i++) increaseButton.click()
  }
})

Upvotes: 0

Related Questions