You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Cypress合并多个DIV内容并与Redux地址数据校验

问题描述

我有如下渲染的DIV结构:

<div class="customer-data-column">
   <h3>Title:</h3>
   <div>Name Lastname</div>
   <div>123 Address xxx yyy</div>
   <div>Chicago XY 33056</div>
   <div>Country name</div>
</div>

该内容由以下React代码生成:

{customerData.replaceAll("/r", "").split("\n").map(item => <div key={item}>{item}</div>)}

数据来源于Redux,控制台中Redux的地址数据格式为:

Name Lastname\n123 Address xxx yyy\nChicago XY 33056\nCountry name

我希望在Cypress中校验页面地址与Redux数据一致,需要将多个DIV的内容合并为一个带\n分隔的字符串。我最初尝试的代码如下:

cy.get('.customer-data-column').should($title => {
    const store = Cypress.store.getState();
    const reduxPath = store.customerData;
    expect("not sure what to put here... how to merge").to.equals(reduxPath)
})

之后我给内部DIV添加了address-row类,结构变为:

<div class="customer-data-column">
   <h3>Title:</h3>
   <div class="address-row">Name Lastname</div>
   <div class="address-row">123 Address xxx yyy</div>
   <div class="address-row">Chicago XY 33056</div>
   <div class="address-row">Country name</div>
</div>

测试代码改为:

cy.get('.address-row').then($divList => {
  const textArray = Cypress.$.makeArray($divList).map(el => el.innerText)
  const actual = textArray.join(textArray, '\n') // 尝试将字符串数组合并为单个字符串
  expect(actual).to.eql(billToAddress)
})

但测试失败,报错信息为:

assert expected Name LastnameName Lastname,23 Address xxx yyy,Chicago XY 33056,Country name23 Address xxx yyyName Lastname,23 Address xxx yyy,Chicago XY 33056,Country name7th FloorName Lastname,23 Address xxx yyy,Chicago XY 33056,Country nameBrooklyn NY 11210Name Lastname,23 Address xxx yyy,Chicago XY 33056,Country nameCountry name to deeply equal Name Lastname\n23 Address xxx yyy\n7th Floor\nBrooklyn NY 11210\nCountry name

最终我找到一个可行方案:

.then(users => {
  const billToAddress = users.response.body.filter(el => el.orderNumber === '3-331877')[0]
    .billTo

  cy.get('.address-row').each((item, index) => {
    cy.log(cy.wrap(item).should('contain.text', billToAddress.split('\n')[index]))
  })
})

请问是否有更优的实现方式?

更优实现方式

1. 修复join方法的错误

你之前的测试失败是因为Array.join()用法错误,join()只需要传入分隔符,不需要传入原数组。修正后可直接合并字符串进行断言:

cy.get('.address-row').then($divs => {
  const actualText = Cypress.$.makeArray($divs)
    .map(el => el.innerText.trim()) // 可选:去除多余空白符,和前端处理逻辑对齐
    .join('\n')
  
  // 从Redux获取预期值
  const store = Cypress.store.getState();
  const expectedText = store.customerData.replaceAll("\r", "");
  
  expect(actualText).to.equal(expectedText);
})

2. 逐行断言的简化版本

如果想保留逐行校验的逻辑,可简化代码,避免嵌套cy.wrap()的冗余写法:

cy.get('.address-row').then($divs => {
  const store = Cypress.store.getState();
  const expectedLines = store.customerData.replaceAll("\r", "").split("\n");
  
  $divs.each((index, el) => {
    expect(el.innerText.trim()).to.equal(expectedLines[index].trim());
  });
})

3. 从API响应获取预期值的优化版

如果预期值来自API响应,可提前获取值后一次性完成断言:

cy.request('/api/users') // 替换为实际API路径
  .then(response => {
    const billToAddress = response.body.filter(el => el.orderNumber === '3-331877')[0].billTo;
    const expectedLines = billToAddress.split("\n");
    
    cy.get('.address-row').then($divs => {
      const actualLines = Array.from($divs).map(el => el.innerText.trim());
      expect(actualLines).to.deep.equal(expectedLines);
    });
  });

这些方式都比你之前的可行方案更简洁,同时保证断言准确性,避免冗余操作。

内容的提问来源于stack exchange,提问作者Pikk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 19:41:00