2

I'm using Cypress (https://www.cypress.io/) to test an app that keeps track of the amount of API calls are done within a user limit. The test checks the limit before the API call and again after a call. Purpose of the test is to see if the limits change after doing a call.

The limit is rendered on screen. And I try to store the value in a variable. After doing the API call I want to compare the value before and after.

Already tried to store it in a variable with const and let, but both don't work outside the 'it' statement.

it('should get the limit value before doing an api call', ()=> {
            cy.get('.bar__legend')
                .contains('used')
                .then(($usage) => {
                    let usageTxt = $usage.text()
                    let words = usageTxt.split(' ')
                    let usageBefore = words[0]
                })
        });


it('should do an API call twice', () => {
            // do a API call twice
}

it('should get the limit value after doing an api call', ()=> {
            cy.get('.bar__legend')
                .contains('used')
                .then(($usage) => {
                    let usageTxt = $usage.text()
                    let words = usageTxt.split(' ')
                    let usageAfter = words[0]

                    cy.log(usageBefore)
                    cy.log(usageAfter)
                })
        });

Another approach I tried

it('should increase the limit after an api call', ()=> {
            cy.get('.bar__legend')
                .contains('used')
                .then(($usage) => {
                    let usageTxt = $usage.text()
                    let words = usageTxt.split(' ')
                    let usageBefore = words[0]
                })

            cy.visit('apilink')
            cy.wait(2000)

            cy.visit('apilink')
            cy.wait(2000)

            cy.get('.bar__legend')
                .contains('used')
                .then(($usage) => {
                    let usageTxt = $usage.text()
                    let words = usageTxt.split(' ')
                    let usageAfter = words[0]

                    cy.log(usageBefore)
                    cy.log(usageAfter)
                })
        })

I expected a value for both variables, but the test fails, because the 'usageBefore' variable does not exist.

Edwart Visser
  • 33
  • 1
  • 6

3 Answers3

2

I believe that the trick was to define the variable outside the it()'s. Thus the syntax would look like this:

var usageBefore
var usageAfter

describe('description of the test', () =>{
  it('This uses the variable', () =>{
    cy.get('.bar__legend')
      .contains('used')
      .then(($usage) => {
        let usageTxt = $usage.text()
        let words = usageTxt.split(' ')
        usageBefore = words[0]
      })
  })
  it('should get the limit value after doing an api call', ()=> {
    cy.get('.bar__legend')
      .contains('used')
      .then(($usage) => {
        let usageTxt = $usage.text()
        let words = usageTxt.split(' ')
        usageAfter = words[0]

        cy.log(usageBefore)
        cy.log(usageAfter)
      })
})
Mr. J.
  • 3,499
  • 1
  • 11
  • 25
  • 1
    Tried it on different levels in the structure. I can define them on the upper level outside the 'describe' block, but they are not changed by the calls in the 'it' blocks. – Edwart Visser Aug 21 '19 at 09:45
1

I got it working. The variables are now declared on a global level and assigning values and getting the values only work inside the cy.get statements.

var usageBefore
var usageAfter

describe('User limits', () => {
    context('Check user limits', () => {
        it('should increase the limit after an api call', () => {
             cy.get('.bar__legend')
                .contains('used')
                .then( $usage => {
                    var usageTxt = $usage.text()
                    var words = usageTxt.split(' ')
                    usageBefore = words[0]
                })

            cy.visit('apicall')

            cy.get('.bar__legend')
                .contains('used')
                .then( $usage => {
                    var usageTxt = $usage.text()
                    var words = usageTxt.split(' ')
                    usageAfter = words[0]
                })

            cy.get('.bar__legend')
                .contains('used')
                .then($usage => {
                    expect(usageAfter).to.be.greaterThan(usageBefore)
                })

Setup needs a lot of refactoring, but it works. Thanks for the response!

Edwart Visser
  • 33
  • 1
  • 6
0

You probably want to refactor your code and move everything under one it() block as that's going to be your test case. Also notice that you're duplicating code, so you can either create a custom command for that or just define a function locally (the parts that start with cy.get('.bar__legend')... ) Your question is mainly related to variable scopes rather than anything specific to cypress. Take a look at this for better understanding: What is the scope of variables in JavaScript?

Vangelisz Ketipisz
  • 897
  • 1
  • 7
  • 10
  • I understand the repetition part, I will fix that later. I tried doing one 'it' block (see above), but then again, the variable is out of scope (because the cy.get is the function). I'm looking for a way to write global variables... – Edwart Visser Aug 21 '19 at 09:27
  • @EdwartVisser did you get the solution ? – Nitish Kumar May 08 '20 at 13:52