【问题标题】:How to ensure a score is calculated correctly in Cypress?如何确保在 Cypress 中正确计算分数?
【发布时间】:2021-12-20 19:28:39
【问题描述】:

我正在尝试验证 Cypress 中的计算是否正确。

所以我有一个 NextJS 应用程序,它使用 Material UI 并将以下标记呈现为:

<ul data-cy="patientLogList">
 <li>
  <section>
   <h3 class="MuiTypography-root">Symptom Score 1</h3>
   <p class="MuiTypography-root">
    <section>
     <h3 class="MuiTypography-root">Wheezing</h3>
     <p class="MuiTypography-root">Very Mild</p>
    </section>
   </p>
  </section>
 </li>
</ul>

所以症状评分如下所示:

var symptomScore = [{ 'Very Mild': 1, 'Mild': 2, 'Moderate': 3, 'Severe': 4, 'Very Severe': 5 }]

所以我正在尝试进行柏树测试,检查喘息是否非常轻微,那么症状评分应该是 1。

我是这样开始的:

var symptomSurveys = [
  { 'Very Mild': 1, 'Mild': 2,'Moderate': 3,'Severe': 4,'Very Severe': 5} 
];
var symptomSum = [];

symptomSurveys.forEach(function(survey) {
    if ()
});

symptomSum;

并且觉得我很快就走错了路。

然后我想可能是这样的:

var symptomSurveys =
      { 'Very Mild': 1, 'Mild': 2,'Moderate': 3,'Severe': 4,'Very Severe': 5};

symptomSurveys['Very Mild'] === 1

但即使我创建了一堆 if 条件,我仍然不知道最终使用 Cypress 方法将如何适应。

我处理的 Cypress 代码如下所示:

if (symptomScore['Very Mild'] === 1) {
  cy.get('ul[data-cy=patientLogList] li section h3').should('eq', 'Symptom Score 1')
}

在你的帮助下,我能够像这样重写它:

var symptomSurveys =
      { 'Very Mild': 1, 'Mild': 2,'Moderate': 3,'Severe': 4,'Very Severe': 5};

cy.get('[data-cy="Wheezing"]')
    .contains('Wheezing')
    .invoke('text')
    .then(symptom => {
        const matcher = new RegExp(`${symptomSurveys[symptom]}$`) // ends with symptom score
        cy.get('ul[data-cy="SymptomScore 1"]')
            .contains('[data-cy="SymptomScore 1"]', /Symptom Score \d/)
            .invoke('text')
            .should('match', matcher)
    })

我修改后的 HTML 如下所示:

<ul data-cy="patientLogList">
 <li>
  <section>
   <h3 class="MuiTypography-root" data-cy="Symptom Score 1">Symptom Score 1</h3>
   <p class="MuiTypography-root">
    <section>
     <h3 class="MuiTypography-root" data-cy="Wheezing">Wheezing</h3>
     <p class="MuiTypography-root">Very Mild</p>
    </section>
   </p>
  </section>
 </li>
</ul>

但现在我收到以下错误:

expected 'Symptom Score 1' to match /undefined$/

【问题讨论】:

  • 你能添加你一直在尝试的赛普拉斯代码吗?
  • @agoff,我添加了上次尝试的 Cypress 代码。

标签: cypress


【解决方案1】:

你可以这样做:

cy.contains('p', 'Very Mild')
  .parent()
  .parent()
  .parent()
  .within(() => {
    cy.get('h3').should('have.text', 'Symptom Score 1')
  })

三个parent() 将帮助您到达最顶层section。然后使用within(),我们将在最上面的部分中引导我们的下一个命令。然后使用cy.get('h3').should('have.text', 'Symptom Score 1'),我们正在验证症状评分1

如果你想添加 forEach() 循环,你可以这样做:

var symptomSurveys = {
 'Very Mild': 1,
 'Mild': 2,
 'Moderate': 3,
 'Severe': 4,
 'Very Severe': 5
}
for (const [key, value] of Object.entries(symptomSurveys)) {
  cy.contains('p', key)
    .parent()
    .parent()
    .parent()
    .within(() => {
      cy.get('h3').should('include.text', value)
    })
}

【讨论】:

  • 我认为两个.parent() 只会让我们到达上面的p?所以你需要一个siblings('h3') 或另一个parent()p -> section -> p?
  • 是的,你是对的。感谢您指出。我又加了一个parent
  • @AlapanDas,这个解决方案如何集成这个:var symptomSurveys = { 'Very Mild': 1, 'Mild': 2,'Moderate': 3,'Severe': 4,'Very Severe': 5};
  • 我已经更新了答案。
【解决方案2】:

根据您提供的信息,我会这样做:

var symptomSurveys =
      { 'Very Mild': 1, 'Mild': 2,'Moderate': 3,'Severe': 4,'Very Severe': 5};

cy.get('ul[data-cy="patientLogList"]')
    .contains('h3.MuiTypography-root', 'Wheezing')
    .siblings('p')
    .invoke('text')
    .then(symptom => {
        const matcher = new RegExp(`${symptomSurveys[symptom]}$`) // ends with symptom score
        cy.get('ul[data-cy="patientLogList"]')
            .contains('h3.MuiTypography-root', /Symptom Score \d/)
            .invoke('text')
            .should('match', matcher)
    })

没有ul[data-cy=patientLogList]') 也应该可以工作:

var symptomSurveys =
      { 'Very Mild': 1, 'Mild': 2,'Moderate': 3,'Severe': 4,'Very Severe': 5};

cy.contains('h3.MuiTypography-root', 'Wheezing')
    .siblings('p')
    .invoke('text')
    .then(symptom => {
        const matcher = new RegExp(`${symptomSurveys[symptom]}$`) // ends with symptom score
        cy.contains('h3.MuiTypography-root', /Symptom Score \d/)
            .invoke('text')
            .should('match', matcher)
    })

我相信添加 data-cy 属性只会使您的情况复杂化。 根据cypress best practices on selecting elements,使用cy.contains() 仍然被认为是次优的。

cy.contains() 在查找元素方面非常有效。除非您正在开发支持多种语言的应用,否则请不要犹豫。
但是,您应该始终将它与选择器一起使用,以确保您获得所需的元素,即使它只是一个标记名。否则,您可能会得到一个包含目标元素的元素,因为它还包含给定的文本。

这里尝试使用cy.contains() 使其尽可能简单:

var symptomSurveys =
      { 'Very Mild': 1, 'Mild': 2,'Moderate': 3,'Severe': 4,'Very Severe': 5};

cy.contains('h3', 'Wheezing')
    .siblings('p')
    .invoke('text')
    .then(symptom => {
        cy.log('symptom', symptom) // validate you have the right info
        const matcher = new RegExp(`${symptomSurveys[symptom]}$`)
        cy.contains('h3', /Symptom Score \d/)
            .invoke('text')
            .should('match', matcher)
    })

【讨论】:

  • 这个解决方案的一个问题是它找不到ul[data-cy="patientLogList"] 我试过了,有没有patientLogList 周围的引号。
  • 两个还是只有第二个?
  • 找不到第一个。
  • 很奇怪,我从您提供的代码中获取了它。我在没有它的情况下进行了编辑。效果也很好
  • 我不能使用那些 Mui 类,因为它们在技术上不存在,它是 Material UI 的工作原理,Cypress 没有考虑到 Material UI,所以我不得不添加一些我自己的 data-cy=给它。您能看一下吗,因为我相信您正在寻找解决方案,但请查看我现在收到的错误。
猜你喜欢
  • 2023-02-24
  • 1970-01-01
  • 1970-01-01
  • 2016-11-17
  • 2020-12-19
  • 2016-07-16
  • 1970-01-01
  • 1970-01-01
  • 2016-12-07
相关资源
最近更新 更多