使用POM与Cucumber框架时Cypress报错:无法读取product属性
Cypress Cucumber测试报错:
TypeError: Cannot read properties of undefined (reading 'product') 我在使用Cypress Cucumber框架结合Page Object Model(POM)、自定义命令和data.json文件编写测试时,测试执行第一个When步骤失败,报错TypeError: Cannot read properties of undefined (reading 'product')。已排查自定义命令配置、data.json加载情况及POM结构,仍无法定位根因,恳请协助解决。
代码结构
Step-Def代码
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代码
describe('Some Test', () => { let data; //closure variable beforeEach(function() { cy.fixture('cypressdata').then(function(fdata) { data=fdata; }) }); });
Feature文件
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
环境信息
- Cypress版本:^13.5.1
- 相关依赖:
"dependencies": { "@badeball/cypress-cucumber-preprocessor": "latest", "@cypress/browserify-preprocessor": "latest", "cucumber": "^6.0.7", "cypress-iframe": "^1.0.1" }
报错信息
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)
解决方案
1. 修正数据挂载的作用域问题
当前beforeEach定义在独立的describe块中,且使用闭包变量data,但步骤中通过this.data访问,两者作用域不匹配。修改如下:
// 删除原有独立的describe块,直接在步骤定义同级写beforeEach import { When, Then, Given } from "@badeball/cypress-cucumber-preprocessor"; import homepage from '../../../pageObjects/homepage' const HomePage = new homepage() beforeEach(function() { cy.fixture('cypressdata').then(fdata => { this.data = fdata; // 将数据挂载到Cypress上下文的this上 }) }); // 后续步骤定义保持不变(但需删除步骤内的it块)
2. 删除步骤内嵌套的it块
Cypress Cucumber的步骤本身属于测试场景的一部分,不需要额外嵌套it块,否则会导致上下文混乱。以validate the price步骤为例:
Then('validate the 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); }); cy.get("button[class='btn btn-success']").click(); })
其他步骤中的it块也需要一并删除。
3. 确认data.json结构
确保cypressdata.json包含product数组字段,示例结构:
{ "product": ["Samsung Note 8", "Nokia Edge"], "name": "TestUser", "gender": "Female" }
内容的提问来源于stack exchange,提问作者Pavithran
相关产品推荐
相关产品推荐

