Execute tests on changing files using cypress.io

I'm currently experimenting with using Cypress to test a large Angular application that I've developed. What I want to achieve is to load an expectation file into my test and then run the test based on this expectation file.

Despite trying different combinations of cy.readFile(), cy.fixture(), and even using axios to load the file via HTTP, I haven't been successful so far.

The main problem seems to be that I can't utilize these methods outside of the it() function, which prevents me from looping through the data to create the individual tests. I am attempting something similar to the following... Is this feasible in Cypress? Am I overlooking something obvious?

Assume my expectation file looks like this:

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

I aim for my code to load it and navigate through the various pages:

describe(`Testing the application`, 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]);
            })
        })
    })
})

To me, this seems like quite a common scenario, so I'm puzzled as to why it's proving to be challenging :)

Answer №1

My situation is quite similar, as I need to access an application configuration file located in the app assets folder.

I retrieve the file using a require statement like this:

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

This method works effectively, allowing me to set expectations based on the file contents for testing purposes.

Therefore, your code implementation may resemble the following:

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

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

readFile()

When attempting to use cy.readFile(), an error message is displayed:

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

To prevent this error, you can enclose the read operation within a before block:

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

Unfortunately, Cypress does not wait for the file read operation to finish before proceeding with the tests.


fixture()

Another approach attempted was using the fixture pattern demonstrated 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')

However, incorporating this method for my config file by moving it to the /cypress/fixtures directory did not yield the desired results.

This process also seems somewhat convoluted – in essence, transforming a file read into a simulated route navigation to enable Cypress to pause for its completion.

Overall, this approach appears intricate and does not align well with the dynamic testing scenario outlined.

Answer №2

  1. Assume that you are working with data stored in an expectation.json file.
    {
      "homePage": [5, 6, 7],
      "aboutPage": [8, 9, 10]
    }
    

In order to generate test cases dynamically based on this data, your code could look something like the following:

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

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

https://i.stack.imgur.com/QQGLp.png

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error with AngularJS Routing

During the development of my asp.net mvc project with angularjs routing, I encountered some routing errors when reloading pages. In my application, .when('/home', { templateUrl: '/Selection_Routing/Selection_Product/Home.html&ap ...

Tips for updating the display after making an angular $http request using rxjs Observables

I have a project where I am utilizing angular's $http service to fetch data from a remote endpoint. I am keen on incorporating rxjs Observables, hence the call in my service is structured as follows: userInfo() : Rx.Observable<IUserInfo> { ...

Is there a way to stop vue-panZoom from functioning temporarily?

I am working with a Grid that includes the use of vue-panZoom. Within the Grid, there is a section that utilizes vue-draggable-resizable, similar to what is depicted in the image below: Image When I drag the gray square (vue-draggable-resizable), the bl ...

What steps can I take to troubleshoot issues when creating a React app?

While attempting to set up a react application using npx create-react-app projectreact, I encountered the following error message: PS C:\Users\ahnaa\OneDrive\Documents\Web Developent\Reaact JS> npx create-react-app project ...

Sending a parameter to a form within Edge Animate

I'm facing an issue where I need to pass a variable to a form from Edge Animate. Here's the current instruction snippet: sym.$("form").append('<iframe width="100%" height="100%" src="login_PRA.php?v_id="vidn frameborder="0" scrolling="no ...

Baffled by the data visualization produced by Google Chart using information from

Perhaps I'm being a bit ambitious, but I managed to create a basic Chart using GoogleCharts. The problem is that I have to input the values manually, but I want to retrieve them from the Database. I know JSON can accomplish this, but I've spent f ...

How can AngularJS be used to enforce a numeric format (including digits and decimal points) in a textfield?

I am in need of a directive to format this specific input For example, 423.33 is considered a valid number while 423.333 is invalid. Only positive numbers including 0 are allowed. However, the user should not be able to enter 0423.33 If only a number wit ...

Trouble with closing windows in the in-app browser on Android devices

Is there a method to successfully close the in-app browser? Despite window.close working on iOS devices, it is not effective on Android. I have experimented with alternatives like window.top.close and window.open("", "_self") window.close, but none have ...

Getting a specific index from an array using the Angular ng-repeat Directive: A step-by-step guide

I am trying to retrieve a specific index in an array using the ng-repeat directive. Currently, it is displaying information for all indexes... I only want to display the information for the second index as an example... This is my main.js: app.controll ...

Effective approach for incorporating external stylesheets and additional resources in Vue

When it comes to loading style sheets in Vue, what is considered the most effective method for placement? Should code or style sheets be loaded within the components that utilize them, or is it more favorable to load the resource in the parent page/contai ...

The AWS Lambda function in Node.js encountered an internal server error

I've been experimenting with AWS Lambda functions, Axios, and Cheerio in a demo project. However, when I call the endpoint, I receive an error message saying {message: Internal Server Error} exports.lambdaHandler = async (event, context) => { ...

Generate an interactive pie chart with visually appealing animations using jQuery, without any actual data

My task involves creating a pie chart to visually display different categories. However, the challenge is that the chart does not contain any data, ruling out options like Google charts or other data-driven chart makers. As a solution, I have turned the pi ...

Tips for creating a website with an integrated, easy-to-use editing tool

Recently, I designed a website for a friend who isn't well-versed in HTML/CSS/JavaScript. He specifically requested that the site be custom made instead of using a web creator. Now, he needs to have the ability to make changes to the site without nee ...

Manipulating Hyperlinks outside the Angular JS applicationIn certain cases, Angular JS

This is my first attempt at creating a single page app. The app's content is contained within the page like a widget, functioning similar to pagination. In the header, I have links that are not related to the angular app. The link structure looks lik ...

Difficulty of combining forEach with findById in mongoose

I need to create a Node route that adds properties to objects and pushes them onto an array declared outside a forEach loop. I have noticed that while the array appears to be filled with data when I log it within the loop, it somehow becomes empty when I r ...

Angular promise did not assign a value to a variable

Can someone assist me with a problem I'm facing? After the first callback, the variable doesn't seem to change as expected. Below is my code snippet: this.handlerLocalDef = function(defer) { var hash = {}; defer.then( ...

Changing an array into an object in JavaScript without rearranging the keys

I have a collection { 1: {id: 1, first: 1, last: 5} 2: {id: 2, first: 6, last: 10} 3: {id: 3, first: 11, last: 15} } My goal is to reverse the order of items without rearranging the keys so that it looks like this: { 1: {id: 3, first: 11, last: 15} 2: { ...

Show session in HTML using ng-click after reloading the page

I am currently using the express-session package to store product prices in my application. Everything seems to be functioning correctly, however I am encountering an issue when trying to display the session data in HTML. For example, if there are 2 produc ...

Is getElementById() returning null?

I'm currently working on a JavaScript program that takes an image URL and displays it on the page by creating an <img> tag. This way, I can easily add multiple images to the page. Here is my code: <!DOCTYPE html> <html lang="en&quo ...

Issue with Ajax reload functions malfunctioning

Embarking on a new journey, I am diving headfirst into the world of web development. As an artist and writer, I have recently delved into the realm of creating a project that integrates a cms, project manager, and database front-end using php, mysql, and j ...