I’m trying to merge bunch of tests that have same actions and checks using parametrized testing, but keep getting errors. I’m new to Cypress and JS in general, coming from .net background. Any help would be appreciated.
My fixture looks something like this:
{
"username": "username",
"password": "password",
"inputErrorMessageText": "Invalid username or password.",
"homePageWelcomeText": "Welcome, bla bla bla",
"testCases": [
{
"description": "blank username and password",
"username": "",
"password": ""
},
{
"description": "blank password",
"username": "username",
"password": ""
}
]
}
I’ve tried both Cypress.each and data.testCases.forEach:
describe("Tests for login page", () => {
let loginPage;
let homePage;
let data;
before(() => {
cy.fixture("login_data").then((fixtureData) => {
data = fixtureData;
cy.wrap(fixtureData).should("have.property", "testCases");
});
});
beforeEach(() => {
loginPage = new LoginPage();
homePage = new HomePage();
cy.visit("/");
});
Cypress.each(data.testCases, (testCase) => {
it(`Invalid username or password error appears when attempting login with ${testCase.description}`, () => {
loginPage.login(testCase.username, testCase.password);
loginPage.verifyErrorMessage(data.inputErrorMessageText);
});
});
it("Successful login with valid username and password", () => {
loginPage.login(data.username, data.password);
homePage.verifyProfileDropDownExists();
});
it("Welcome text is displayed after successful log in", () => {
loginPage.login(data.username, data.password);
homePage.verifyWelcomeText(data.homePageWelcomeText);
});
data.testCases.forEach((testCase) => {
it(`Invalid username or password error appears when attempting login with ${testCase.description}`, function () {
loginPage.login(testCase.username, testCase.password);
loginPage.verifyErrorMessage(data.inputErrorMessageText);
});
});
Keep getting the following error:
TypeError: The following error originated from your test code, not from Cypress.
> Cannot read properties of undefined (reading ‘testCases’)
2
Answers
Issues
data.testCases.forEach()
is not working, as Cypress (Mocha, but splitting hairs here) needs to know what tests to run before the tests actually start running. In this case, sincedata.testCases
won’t have a value when Cypress starts gathering the tests to run (as the data is set in thebefore()
block), it’s running into an error whendata.testCases
is undefined.Cypress.each
is a function. There isCypress._.each()
(using Cypress Lodash) andcy.each()
(which isn’t what you want here).Solution
Import the fixture directly, instead of loading it via
cy.fixture()
, which should grant you access to thedata.testCases
variable prior to Cypress discovering what tests to run. Then you should be able to have multiple tests run, either viadata.testCases.forEach()
orCypress._.each()
.You can still run your data validation that
data
has property oftestCases
, without thecy.fixture()
.Please see the Cypress recipe fundamentals__dynamic-tests/cypress/e2e
/fixture-spec.cy.js.
While a fixture is technically fine, I would suggest putting the data at the top of the test.
This is much more readable, so you can refactor and add cases easily. Plus you can include the expected error in the same place.