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

如何合理链式调用命令以断言指定DOM文本结构?

需求与问题

我需要断言如下DOM结构:

<app-toggler data-cy="toggler">
  <button id="1" data-cy="1">
    <rows data-cy="rows">
      <span>Title</span>
    </rows>
    <textarea>
      <text-rows data-cy="textarea">
        <div title="Value1" data-cy="app-textarea-val1">
          <span>Value1</span>
        </div>
        <div title="Value2" data-cy="app-textarea-val2"><!---->
          <span>Value2</span>
        </div>
        <div title="Value3" data-cy="app-textarea-val3">
          <span>Value3</span>
        </div>
      </text-rows>
    </textarea>
  </button>
  <button id="2" data-cy="2">
    <rows data-cy="rows">
      <span>Titletwo</span>
    </rows>
    <textarea>
      <text-rows data-cy="textarea">
        <div title="Value1two" data-cy="app-textarea-val1">
          <span>Value1two</span>
        </div>
        <div title="Value2two" data-cy="app-textarea-val2"><!---->
          <span>Value2two</span>
        </div>
        <div title="Value3two" data-cy="app-textarea-val3">
          <span>Value3two</span>
        </div>
      </text-rows>
    </textarea>
  </button>
</app-toggler>

我希望实现类似"Title, Value1, Value2, Value3".isOneOf.Buttons.Text()的链式调用功能,用来判断逗号分隔的指定文本组合是否完全属于某个<button>元素下的所有文本。示例如下:

  • "Title, Value1, Value2, Value3".isOneOf.Buttons.Text() => true
  • "Titletwo, Value1, Value2, Value3".isOneOf.Buttons.Text() => false
  • "Title, Value1two, Value2three, Value3four".isOneOf.Buttons.Text() => false

目前不清楚如何正确实现这种实用的链式调用逻辑。


实现方案

1. 原生JS环境实现(扩展String原型)

通过给String原型添加属性和方法,实现链式调用的语法。核心逻辑是先解析目标文本,再对比每个button下的文本集合:

// 辅助函数:获取所有button对应的文本数组集合
function getButtonTextGroups() {
  return Array.from(document.querySelectorAll('app-toggler button')).map(button => {
    // 提取button下所有span的文本,过滤空内容
    return Array.from(button.querySelectorAll('span'))
      .map(el => el.textContent.trim())
      .filter(text => text.length > 0);
  });
}

// 给String原型添加isOneOf链式调用属性
Object.defineProperty(String.prototype, 'isOneOf', {
  get() {
    // 解析当前字符串为目标文本数组
    const targetTexts = this.split(',')
      .map(text => text.trim())
      .filter(text => text.length > 0);

    return {
      Buttons: {
        // 核心判断方法
        Text() {
          const buttonTextGroups = getButtonTextGroups();
          // 检查是否存在某个button的文本数组与目标完全匹配
          return buttonTextGroups.some(group => {
            if (group.length !== targetTexts.length) return false;
            return group.every((text, index) => text === targetTexts[index]);
          });
        }
      }
    };
  }
});

2. 测试验证

直接调用示例中的链式语法即可得到预期结果:

console.log("Title, Value1, Value2, Value3".isOneOf.Buttons.Text()); // true
console.log("Titletwo, Value1, Value2, Value3".isOneOf.Buttons.Text()); // false
console.log("Title, Value1two, Value2three, Value3four".isOneOf.Buttons.Text()); // false

3. 测试框架环境优化(以Cypress为例)

如果是在测试框架中使用,不建议修改原生原型,推荐自定义测试命令:

// 注册Cypress自定义命令
Cypress.Commands.add('hasMatchingButtonText', (targetTextStr) => {
  const targetTexts = targetTextStr.split(',').map(t => t.trim()).filter(Boolean);
  let matched = false;

  cy.get('app-toggler button').each($button => {
    cy.wrap($button).find('span').then($spans => {
      const texts = Array.from($spans).map(el => el.textContent.trim()).filter(Boolean);
      if (JSON.stringify(texts) === JSON.stringify(targetTexts)) {
        matched = true;
      }
    });
  }).then(() => {
    expect(matched).to.be.true;
  });
});

// 使用方式
cy.hasMatchingButtonText("Title, Value1, Value2, Value3"); // 断言通过
cy.hasMatchingButtonText("Titletwo, Value1, Value2, Value3"); // 断言失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 10:05:57