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

如何在Cypress(TypeScript)中测试DOM元素是否变化?

问题描述

我正在使用Cypress(搭配TypeScript)评估其是否适用于某Web应用的E2E测试。目前面临的挑战是没有数据库初始化工具,只能基于生产副本的staging环境测试,因此需要验证操作后DOM元素是否变化,比如筛选功能应用后结果是否改变。

应用筛选的代码:

visitCountryPage();
cy
    .get('#sharedTrips .filtersContainer button')
    .then((buttons: JQuery<HTMLElement>) => {
        buttons[0].click();
    })
    // 点击菜单选项
    .get('#sharedTrips .filtersContainer label[for="experiencesrelax"]')
    .click();

我的尝试代码如下:

let initialIdeas: Chainable<JQuery<HTMLElement>> = getTripIdeas();
cy
    .get('#sharedTrips .filtersContainer button')
    .then((buttons: JQuery<HTMLElement>) => {
        buttons[0].click();
    })
    // 点击菜单选项
    .get('#sharedTrips .filtersContainer label[for="experiencesrelax"]')
    .click()
    .then(() => {
        getTripIdeas().should('not.equal', initialIdeas);
    });

其中getTripIdeas()是通过DOM读取返回Chainable<JQuery<HTMLElement>>的外部函数。但即使移除最后一步click(),测试仍通过,怀疑是对象引用不同导致,想知道如何正确验证DOM元素变化。


解决方案

你的问题核心是直接比较Cypress的Chainable对象引用,而非实际的DOM元素内容或数量。Chainable每次调用都会生成新对象,所以即使DOM没变化,not.equal也会通过——因为两个对象的引用本来就不一样。

可以从以下几个方向正确验证筛选后的DOM变化:

1. 比较元素数量

如果筛选后结果数量会变化,直接断言数量不同:

// 先获取初始的结果数量
getTripIdeas().its('length').as('initialCount');

// 执行筛选操作
cy.get('#sharedTrips .filtersContainer button')
  .first().click()
  .get('#sharedTrips .filtersContainer label[for="experiencesrelax"]')
  .click();

// 断言筛选后的数量和初始数量不同
getTripIdeas().its('length').should('not.eq', this.initialCount);

2. 比较元素的文本内容集合

如果结果的文本内容会变化,把元素的文本提取成数组再比较:

// 存储初始结果的文本数组
getTripIdeas().then($ideas => {
  const initialTexts = Array.from($ideas).map(el => el.textContent?.trim());
  
  // 执行筛选
  cy.get('#sharedTrips .filtersContainer button')
    .first().click()
    .get('#sharedTrips .filtersContainer label[for="experiencesrelax"]')
    .click();

  // 断言筛选后的文本集合和初始不同
  getTripIdeas().then($filteredIdeas => {
    const filteredTexts = Array.from($filteredIdeas).map(el => el.textContent?.trim());
    expect(filteredTexts).to.not.deep.equal(initialTexts);
  });
});

3. 断言特定元素出现/消失

如果筛选后有明确的预期元素(比如某个特定旅行项应该被筛选掉或出现),可以直接断言该元素的存在状态:

// 先确认某个元素在初始结果中存在
cy.get('.trip-idea[data-id="relax-trip-123"]').should('exist');

// 执行筛选
cy.get('#sharedTrips .filtersContainer button')
  .first().click()
  .get('#sharedTrips .filtersContainer label[for="experiencesrelax"]')
  .click();

// 断言该元素消失(如果是筛选保留则用should('exist'))
cy.get('.trip-idea[data-id="relax-trip-123"]').should('not.exist');

额外优化:简化点击代码

你原来的按钮点击逻辑可以简化,不需要用then手动调用click,Cypress的get返回的元素可以直接调用click():

cy.get('#sharedTrips .filtersContainer button').first().click();

这样比手动操作JQuery数组更符合Cypress的最佳实践。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 19:15:11