Cypress Error when using POM and Commands with Cucumber framework

81 views Asked by At

I'm facing an issue with my Cypress Cucumber tests using Page Object Model (POM), custom commands, and a data.json file. The test seems to skip the first When statement. Here's how my code is structured:

Step-Def code:

import { When, Then, Given } from "@badeball/cypress-cucumber-preprocessor";
import homepage from '../../../pageObjects/homepage'

const HomePage = new homepage()

describe('Some Test', () => {
    let data; //closure variable
beforeEach(function()
{
    cy.fixture('cypressdata').then(function(fdata)
    {
        data=fdata;
    })
});
});

Given('I open home page', () => {
    cy.visit('https://rahulshettyacademy.com/angularpractice/')
})

When('I add products to cart', function () {
    // Product Page
        HomePage.shopmenu().click();
        this.data.product.forEach((element) => {
            cy.selectproduct(element);
        });
})

Then('validate the price', function () {
    it('calculate total price', function () {
        var sum = 0;
        cy.get("tr td:nth-child(4) strong").each(($el, index, $list) => {
            const Actualprice = $el.text();
            var result = Actualprice.split(" ");
            var result = result[1].trim();
            sum = Number(sum) + Number(result);
        }).then(function () {
            cy.log(sum);
        });

        var amt;
        cy.get('td[class="text-right"] h3 strong').then(function (element) {
            const totalamount = element.text();
            var amount = totalamount.split(" ");
            var amount = amount[1].trim();
            amt = Number(amount);
            expect(amt).to.be.equal(sum);
        }).then(function () {
            cy.log(amt);
        });

        it('click purchase button', function () {
            cy.get("button[class='btn btn-success']").click();
        });
    });
})

Then('select the country and submit and verify thank you message', function () {
    cy.get('#country').type('india');
    cy.get('div[class="suggestions"] ul li a').click();
    cy.get('#checkbox2').check({ force: true });
    cy.get('input[value*="Purchase"]').click();
    cy.get('.alert').then(function (element) {
        const AlertText = element.text();
        expect(AlertText.includes('Success')).to.be.true;
    });
})

When('I fill the form details', function () {
    it('fill form details', function () {
        HomePage.getEditbox().type(this.data.name);
        HomePage.getGender().select(this.data.gender).should('have.value', this.data.gender);
    });
})

Then('validate the form', function () {
    it('validate form details', function () {
        HomePage.twowayDataBind().should('have.value', this.data.name);
        HomePage.getEditbox().should('have.attr', 'minlength', '2');
        HomePage.empStatus().should('be.disabled');
    });
})

Then('select the shop page', function () {
    it('select the shop page', function () {
        HomePage.shopmenu().click();
    });
})

beforeEach code:

describe('Some Test', () => {
    let data; //closure variable
beforeEach(function()
{
    cy.fixture('cypressdata').then(function(fdata)
    {
        data=fdata;
    })
});
});

Feature file:

Feature: E2E Ecommerce Validation

Application Regression

Scenario: Ecommerce product delivery
    Given I open home page
    When I add products to cart
    Then validate the price
    Then select the country and submit and verify thank you message

Scenario: Filling the Home Page Form
    Given I open home page
    When I fill the form details
    Then validate the form
    Then select the shop page

Error Image

Issue Details I suspect that the issue might be related to the setup or interaction between different components (POM, custom commands, data.json). However, I'm having difficulty identifying the root cause.

Additional Details:

Cypress version: ^13.5.1 Relevant dependencies: "dependencies": { "@badeball/cypress-cucumber-preprocessor": "latest", "@cypress/browserify-preprocessor": "latest", "cucumber": "^6.0.7", "cypress-iframe": "^1.0.1" } Console output or error messages:

 Running:  ecommerce.feature                                                               (1 of 1)


  E2E Ecommerce Validation
    1) Ecommerce product delivery
    √ Filling the Home Page Form (183ms)


  1 passing (3s)
  1 failing

  1) E2E Ecommerce Validation
       Ecommerce product delivery:
     TypeError: Cannot read properties of undefined (reading 'product')
      at Context.eval (https://rahulshettyacademy.com/__cypress/tests?p=cypress\integration\examples\BDD\ecommerce.feature:15805:19)
      at Registry.runStepDefininition (https://rahulshettyacademy.com/__cypress/tests?p=cypress\integration\examples\BDD\ecommerce.feature:8554:48)
      at Object.fn (https://rahulshettyacademy.com/__cypress/tests?p=cypress\integration\examples\BDD\ecommerce.feature:15015:43)
      at runStepWithLogGroup (https://rahulshettyacademy.com/__cypress/tests?p=cypress\integration\examples\BDD\ecommerce.feature:14627:29)
      at Context.eval (https://rahulshettyacademy.com/__cypress/tests?p=cypress\integration\examples\BDD\ecommerce.feature:15011:62)


Steps Taken Checked the configuration of custom commands. Verified that the data.json file is correctly loaded. Reviewed the POM structure to ensure proper page element selection.

Request for Assistance I would greatly appreciate any help in identifying the problem and resolving the issue. If you need more specific information or if there are additional steps I should take, please let me know.

Thank you in advance for your assistance!

1

There are 1 answers

0
Lola Ichingbola On BEST ANSWER

TypeError: Cannot read properties of undefined (reading 'product') refers to this line.

this.data.product.forEach((element)

This means that the part this.data is the part that is undefined.

You can fix it in the following ways:

  • by dropping this and use data.product.forEach((element) since let data does not put the data variable of this scope.

    let data;
    beforeEach(function() {
      cy.fixture('cypressdata').then(function(fdata) {
        data = fdata;
      })
    ...
    
    When('I add products to cart', function () {
      ...
      data.product.forEach((element) => {
        cy.selectproduct(element);
    ...
    

  • by setting an alias cy.fixture('cypressdata').as('data') which will set the variable data on this scope

    let data;
    beforeEach(function() {
      cy.fixture('cypressdata').as('data')
    })
    ...
    
    When('I add products to cart', function () {
      ...
      this.data.product.forEach((element) => {
        cy.selectproduct(element);
    ...
    

  • by moving cy.fixture() inside When() and get rid of beforeEach()

    When('I add products to cart', function () {
      cy.fixture('cypressdata').then(data => {
        data.product.forEach((element) => {