rex
rex

Reputation: 3183

Run tests on dynamic file in cypress.io

I am trying to use cypress to test a large angular app that I have built. My requirement is that I load an expectation file into my test and then drive the test off this expectation file.

I have so far been unable to get this to work using various combinations of cy.readFile(), cy.fixture(), and even axios to load the file via http.

The issue seems to be that I can't use these methods outside of it() and if I can't do that it means I can't loop through the data to create the its. I am trying to do something like the below... is this even possible in cypress? Am I missing something obvious?

Lets say my expectation looks like this:

{
    "mainPage": [1, 2, 3],
    "otherPage": [4, 5, 6]
}

I want my code to load it and go through the various pages:

describe(`Test the app `, function() {
    cy.readFile("path/to/expectation.json").then(function(expectation) {
        Object.keys(expectation).forEach(function(pageName) {
            it(`for page ${pageName}`, function() {
                gotoPage(pageName);
                var pageData = getDataFrompage();
                expect(pageData).to.equal(expectation[pageName]);
            })
        })
    })
})

This seems to me like a pretty obvious use-case so I'm confused why it appears to be so difficult :)

Upvotes: 6

Views: 7676

Answers (2)

Radhika Choudhary
Radhika Choudhary

Reputation: 71

  1. Suppose, you have below data in expectation.json file.
    {
      "mainPage": [1, 2, 3],
      "otherPage": [4, 5, 6]
    }
    

Then your code would be something like this to create Test cases dynamically

const data = require("path/to/expectation.json");

describe('Test the app', function() {
   Object.keys(data).forEach(function(page, i){
      it(`Test Case For: ${page}`, function() {
        cy.log(data[page])
      })
   })
})

See Output Below

Upvotes: 0

Richard Matsen
Richard Matsen

Reputation: 23483

I have a similar requirement, except I'm reading an application config file (which lives within the app assets folder).

I read it with a require like so,

const runtimeConfig = require('../../../src/data/my-config');

This works well, I can then proceed to test with expectations based on the file contents.

So, your code would be something like this

const expectation = require('path/to/expectation.json');

describe(`Test the app `, function() {
  Object.keys(expectation).forEach(function(pageName) {
    it(`for page ${pageName}`, function() {
      gotoPage(pageName);
      var pageData = getDataFrompage();
      expect(pageData).to.equal(expectation[pageName]);
    })
  })
})

readFile()

Trying cy.readFile(), you get get this error message

Uncaught Error: Cannot call "cy.readFile()" outside a running test.

You can stop this error by wrapping the read in a before like so

let runtimeConfig;
before(function(){
  cy.readFile('./src/data/my-config.json').then( fileContents => {
    runtimeConfig = fileContents;
  })
})

but unfortunately Cypress does not wait for the read to complete before proceeding to test.


fixture()

I also tried the fixture pattern shown in example.spec.js

context('Files', function(){
  beforeEach(function(){
    cy.visit('https://example.cypress.io/commands/files')
  })
  it('cy.fixture() - load a fixture', function(){
    // Instead of writing a response inline you can
    // connect a response with a fixture file
    // located in fixtures folder.

    cy.server()

    // https://on.cypress.io/fixture
    cy.fixture('example.json').as('comment')

    cy.route(/comments/, '@comment').as('getComment')

    // we have code that gets a comment when
    // the button is clicked in scripts.js
    cy.get('.fixture-btn').click()

    cy.wait('@getComment').its('responseBody')
      .should('have.property', 'name')
      .and('include', 'Using fixtures to represent data')

but could not get it to work with my config file even when copying it to the /cypress/fixtures folder.

Also, this feels a quite hacky - if I understand this code correctly, it is turning the file read into a pseudo route navigation so that Cypress can wait on it.

This pattern is complicated and certainly does not lend itself to the dynamic testing scenario you describe.

Upvotes: 7

Related Questions