赛普拉斯条件测试代码建议

时间:2020-07-20 00:45:15

标签: javascript cypress

我无法弄清楚如何使用赛普拉斯实现自动化。我是Cypress&JS的新手,正在尝试解决这个问题。

我有问题页面,有时是3,有时是4。不一致。我只想处理cypress单击No(如果找到4个“ NO”按钮)的情况。最后,如果出现第四个问题,则CTA文本也会更改。

赛普拉斯中“应该”的问题是它断言然后失败。我想要硒中的类似IsDisplayed的东西。

我知道不建议使用条件测试,但是我现在没有选择。请帮助我。

这是我的代码:

    //cy.get(`button[name="cosmeticDamage"][value="${cosmetic}"]`).then($a => {
    cy.get('div span.MultiScreenForm__content').then($a => {
      if ($a.attr('name', `[name="cosmeticDamage"][value="${cosmetic}"]`).length > 0) {
        cy.log('Cosmetic Damage Button does exist: ==>');
        cy.get(`button[name="cosmeticDamage"][value="${cosmetic}"]`).click();
      } else {
        cy.log('Cosmetic Damage Button does not exist, do Nothing');
      }
    });
  }

DOM Image

2 个答案:

答案 0 :(得分:1)

根据您的描述以及您提供的摘录,我了解到[name="cosmeticDamage"]总是存在多个元素,因此我不确定.length如何使[name="cosmeticDamage"][value="${cosmetic}"]增值,可能意味着您的情况永远都是真的。

我建议您使用find,因为它会过滤匹配的后代DOM元素:

    cy.get('div span.MultiScreenForm__content').then($form => {
        if ($form.find(`[name="cosmeticDamage"][value="${cosmetic}"]`).is(':visible')) {
            cy.get(`button[name="cosmeticDamage"][value="${cosmetic}"]`).click();        
        } else {
            cy.log('Cosmetic Damage Button does not exist, do Nothing');
        }
    });

答案 1 :(得分:1)

我知道不建议使用条件测试,但是我现在没有选择。

是的,您确实可以选择。我先向您道歉,这不是一个快速,简单的答案。赛普拉斯中的条件测试可能很棘手,但是,一旦您了解了它,您的测试就会更好。您确实有一个更好的选择,我将尽力解释一下,所以去吧。

在这种情况下,您必须调整解决问题的方式。目前,您的条件基于as Cypress documentation states的UI元素,它将导致小猫爆炸。没有人想要爆炸小猫。相反,您要做的是更改条件的真实来源,即使用UI元素将条件基于更稳定的条件(例如服务器响应)。

对我个人而言,这很难使我的大脑包扎在实际中如何做到这一点,所以我会尽力解释。

因此,当前,您正在做类似的事情:

  • 发出请求(#个问题),并根据响应设置页面加载和视图。
  • 如果页面上有UI元素(第四个问题),请点击“测试”按钮

您想要的是:

  • 提出请求(有多少个问题?)
  • 使用cy.route("someAlias")cy.wait('@someAlias')捕获来自请求的响应
  • 您从服务器获得的响应就是您的UI元素从其构建自身的信息。 请根据您的情况。(请参阅Routes & Aliases

所以您的情况可能是这样的:

if questions returned in response > 3 then test button

这里的理论是,您的服务器是真实的可靠来源,可以直接获取所需的所有信息。 DOM(UI元素)并不是因为它没有预先获取的所有信息,而且在您有条件时无法保证它会解决您需要的内容才能继续。

如果服务器回答的问题多于3个,则那里应该有一个按钮。在这里切换逻辑可以使您的测试更加稳定,并且您实际上正在测试要测试的对象。 当您有3个以上的问题时,您应该有一个按钮不是,如果有三个以上的UI元素,则应该有一个按钮。 不能保证在满足UI元素条件时,按钮将得到解决。服务器响应应该是事实的来源,而不是UI元素。

我不知道发出请求的逻辑,所以我的答案不正确,但是,让我们假设在页面加载时,有一个对/questions的请求,它会回答以下问题:您正在谈论(3或4)。您的代码将如下所示:

// setup the route to wait for
cy.server();
cy.route("/questions").as("questions");
// do whatever you do that sends that request
cy.visit("/pageOfQuestions");
// wait for request and grab response using route alias
cy.wait("@questions").then(function(xhr) {
  // find your path (I'm guessing here) to the info you need and test condition
  // the condition and the path to the info will vary based on what your response 
  // actually contains
  if(xhr.response.questions.length > 3) {
    // test your button-y stuff here
    cy.get(`button[name="cosmeticDamage"][value="${cosmetic}"]`).click();
  } else {
    cy.log("nothing to test");
}

区别在于,当您将条件(事实来源)基于UI元素时,DOM并不总是以您期望的方式解决自身。当您达到条件时(在本例中为问题UI元素),其他事情仍然无法解决(按钮UI元素)。您必须等待两个元素在DOM中对齐->事实来源(条件)和要测试的UI元素(按钮)。通常,一个没有加载而另一个没有加载,因此您不能依靠它们始终加载,这就是为什么赛普拉斯建议不要将条件基于UI元素的原因,除非您喜欢爆炸小猫。

用不同的方式解释,假设DOM有10种资源要加载。您对柏树说: if resource #7 looks like this then play with resource #1

Cypress继续等待资源7。准备就绪后,它将检查是否满足条件,然后尝试使用资源1 ... DOM可能尚未解决。实际上,有时可以加载它,但是您无法保证会导致不稳定的测试。

当您根据服务器响应作为事实来源时,您仅在等待并测试一个UI元素,而cypress内置的超时可以成功地等待该一个元素加载而不依赖另一个。 On page load, did the server give us more than 4 things? Then play with UI element

如果有什么我想澄清的,问一下即可。

参考: