'iterate data from multiple json files using cypress

I have multiple JSON file in fixtures folder. The below one is 'studDetails.json'. Based on this file, I have to branch out to other json files.

[
  {
    "StudentId": "1001",
    "StudentName": "Tim Blanks",
    "StudentDept": "English"
  },
  {
    "StudentId": "1002",
    "StudentName": "Alec Stoinis",
    "StudentDept": "Physics"
  },
  {
    "StudentId": "1003",
    "StudentName": "Fiona Woods",
    "StudentDept": "English"
  },
]

I am using the below code in Cypress to read the data from one JSON file and use that data to read another JSON file. I want to work with student's department as English.

const studList = require('../../fixtures/studDetails.json')

describe('Get Student Details', function() {
    studList.forEach(stud => {    
        
        let studentId = stud.StudentId;
        let studentName = stud.StudentName;
        let studDept = stud.StudentDept;

        if(studDept === "English"){
            const deptList = require('../../fixtures/'+ studDept +'.json');
            deptList.forEach(dept => {
                let deptLead = dept.LeaderName;
                let deptController = dept.Controller;  
                
                it('Login Test', function() {
                    cy.visit('http://localhost:8081/login/');
                    cy....
                    cy....
                    cy.get('#deptHead1').set(deptLead);
                    cy.get('#deptHead2').set(deptController);

            });

        }    
});

When executed, the below error prompted:

No tests found. Cypress could not detect tests in this file.

So, I moved the 'if' block inside the test. Now, it got executed. In the results, I was expecting only 2 tests related to 'English' records from 'studDetails.json' should get displayed and passed. But, there were 3 tests passed. The 1st and 3rd were related to student department 'English'. 2nd test was related to 'Physics' also ran and when expanded in test runner, it showed

'No commands were issued in this test.'

I need to execute only the chosen records from JSON (stud. department as English). Are there any option to run the test inside the 'if' block (or) is it possible to exclude records that's not required in run as it is unnecessarily displaying in the results finally.



Solution 1:[1]

The it method needs to be directly inside the describe method (see https://docs.cypress.io/guides/getting-started/writing-your-first-test#Write-your-first-test)

describe('My First Test', () => {
  it('Does not do much!', () => {
    expect(true).to.equal(true)
  })
})

Which in your case would give something like:

const studList = require('../../fixtures/studDetails.json')

describe('Get Student Details', function() {
    it('Login Test', function() {
        // filter list to get only the "English" students
        const targetStudents = studList.filter(stud => stud.StudentDept === "English");

        if(targetStudents.length === 0) {
            // do not test if no result
            console.log("Didn't find any student to test with.");
            return;
        }

        for(const stud of targetStudents) {
            let studentId = stud.StudentId;
            let studentName = stud.StudentName;
            let studDept = stud.StudentDept;

            const deptList = require('../../fixtures/' + studDept + '.json');

            for(const dep of deptList) {
                let deptLead = dept.LeaderName;
                let deptController = dept.Controller; 

                cy.visit('http://localhost:8081/login/');
                cy....
                cy....
                cy.get('#deptHead1').set(deptLead);
                cy.get('#deptHead2').set(deptController);
            }
        }
    });
});

Solution 2:[2]

Your code looks right to me. I'm not sure what your department JSON contents may be, but this is what I used and got it to work.

studentDetails.json

[
    {
        "StudentId": "1001",
        "StudentName": "Tim Blanks",
        "StudentDept": "English"
    },
    {
        "StudentId": "1002",
        "StudentName": "Alec Stoinis",
        "StudentDept": "Physics"
    },
    {
        "StudentId": "1003",
        "StudentName": "Fiona Woods",
        "StudentDept": "English"
    }
]

English.json

[
    {
        "DepartmentId": "1001",
        "DepartmentName": "English",
        "DepartnmentLeader": "MrsJohson",
        "DepartmentController": "TheDarkLord"
    }
]

test.js

const studentList = require('../fixtures/studentDetails.json')

describe('Get Student Details', function () {
    studentList.forEach(student => {
        const studentDept = student.StudentDept
        if (studentDept == 'English') {
            const departnmentJSON = require(`../fixtures/` + studentDept + `.json`)
            departnmentJSON.forEach(department => {
                const deptLead = department.DepartnmentLeader
                const deptController = department.DepartmentController

                it(`${department.DepartmentName} department`, () => {
                    cy.log(deptLead)
                    cy.log(deptController)
                    // real test code here
                })
            })
        }
        // code for other departments
    });
})

Solution 3:[3]

You must remove the describe().

Inside describe(), Cypress does not evaluate studList.forEach(stud => { or deptList.forEach(dept => { until test runs, so it sees no tests.

Outside describe() studList.forEach(stud => { and deptList.forEach(dept => { are run as part of test setup, now Cypress knows how many tests you have.

const studList = require('../../fixtures/studDetails.json')

studList.forEach(stud => {    
        
  let studentId = stud.StudentId;
  let studentName = stud.StudentName;
  let studDept = stud.StudentDept;

  if (studDept === "English") {
    const deptList = require('../../fixtures/'+ studDept +'.json');
    deptList.forEach(dept => {
      let deptLead = dept.LeaderName;
      let deptController = dept.Controller;  
                
      it(`Login Test for Student ` + studentName , function() {
        cy.visit('http://localhost:8081/login/');
        ....
      })

      it('Grades test for ' + deptController, function() {
        cy.visit('http://localhost:8081/login/');
        ....
      })

    })
  }    
})

Or put it here

const studList = require('../../fixtures/studDetails.json')

studList.forEach(stud => {    
        
  let studentId = stud.StudentId;
  let studentName = stud.StudentName;
  let studDept = stud.StudentDept;

  if (studDept === "English") {
    const deptList = require('../../fixtures/'+ studDept +'.json');
    deptList.forEach(dept => {
      let deptLead = dept.LeaderName;
      let deptController = dept.Controller;  

      //Use describe here                
      describe('Get Student Details', function() {

        it(`Login Test for Student ` + studentName , function() {
          cy.visit('http://localhost:8081/login/');
          ....
        })

        it('Grades test for ' + deptController, function() {
          cy.visit('http://localhost:8081/login/');
          ....
        })
      })
    })
  }    
})

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 lezhumain
Solution 2 jjhelguero
Solution 3 Jumaane