1

我的测试代码中有用于查找和访问选择器的方法。主要是因为有几个具有相同名称选择器的代码块,我无法更改。但也因为我发现它比处理复杂且通常创建不佳的索引选择器/id 更整洁。

简化标记:

<div data-e2e-selector="byggrad>
  <div data-e2e-selector="adresserad">
    <div data-e2e-selector="etasjerad">
      <div data-e2e-selector="finansieringsobjektrad">
        <input data-e2e-selector="boligbetegnelse">
      </div>
      <div data-e2e-selector="finansieringsobjektrad">
        <input data-e2e-selector="boligbetegnelse">
      </div>
    </div>
    <div data-e2e-selector="etasjerad">
      <div data-e2e-selector="finansieringsobjektrad">
        <input data-e2e-selector="boligbetegnelse">
      </div>
      <div data-e2e-selector="finansieringsobjektrad">
        <input data-e2e-selector="boligbetegnelse">
      </div>
    </div>
  </div>
</div>
  

每个元素可能有几个元素,全部嵌套如上。因此,使用 eq(0) 来获取具有特定索引的选择器似乎工作正常。

此代码工作正常:

cy.get('[data-e2e-selector=byggrad]').eq(0)
  .within(() => {
    cy.get('[data-e2e-selector=adresserad]').eq(0)
      .within(() => {
        cy.get('[data-e2e-selector=etasjerad]').eq(0)
          .within(() => {
            cy.get('[data-e2e-selector=finansieringsobjektrad]').eq(0)
              .within(() => {
                cy.get('[data-e2e-selector=boligbetegnelse]').clear();
                cy.get('[data-e2e-selector=boligbetegnelse]').type('TEST');                                     
              });
          });
      });
  });

但是,这不会:

this.getBoligbetegnelse().clear();
this.getBoligbetegnelse().type('TEST');

getBoligbetegnelse() {
  return cy.get('[data-e2e-selector=byggrad]').eq(0)
  .within(() => {
    cy.get('[data-e2e-selector=adresserad]').eq(0)
      .within(() => {
        cy.get('[data-e2e-selector=etasjerad]').eq(0)
          .within(() => {
            cy.get('[data-e2e-selector=finansieringsobjektrad]').eq(0)
              .within(() => {
                cy.get('[data-e2e-selector=boligbetegnelse]');                   
              });
          });
      });
  });
}

当然,后来我意识到,这是因为该方法返回的是 [data-e2e-selector=byggrad] 元素,而不是 [data-e2e-selector=boligbetegnelse] 元素。

所以,然后我试试这个:

getBoligbetegnelse() {
  cy.get('[data-e2e-selector=byggrad]').eq(0)
  .within(() => {
    cy.get('[data-e2e-selector=adresserad]').eq(0)
      .within(() => {
        cy.get('[data-e2e-selector=etasjerad]').eq(0)
          .within(() => {
            cy.get('[data-e2e-selector=finansieringsobjektrad]').eq(0)
              .within(() => {
                return cy.get('[data-e2e-selector=boligbetegnelse]');                   
              });
          });
      });
  });
}

但这根本不起作用,因为该方法根本没有返回任何东西。当然,因为 Cypress 的异步方式。

我也玩过 .then ,读到这是一种在执行开始后运行命令的方法。但是我发现没有办法在这里使用它。

那么,是否可以通过这种方式找到元素,并返回内部元素而不是顶部元素?还是我必须换种方式思考,开始将值传递给方法而不是让它们返回元素?我猜这与赛普拉斯命令和代码的异步运行有关?

如果这只是它必须完成的方式,那么似乎很难(如果不是不可能的话)不可能进行更有效的重构,因为不可能有一个方法返回 a 代码块,然后有多个方法采用该代码块并在其中寻找不同的特定元素。

4

1 回答 1

1

find()使用andas()而不是返回元素的自定义函数可能会更成功。find()并且get().within()非常相似,但我更喜欢find()尽可能。find() 和 get().within() 之间的区别

cy.get('[data-e2e-selector=byggrad]').eq(0)
   .find('[data-e2e-selector=adresserad]').eq(0)
   .find('[data-e2e-selector=etasjerad]').eq(0)
   .find('[data-e2e-selector=finansieringsobjektrad]').eq(0)
   .find('[data-e2e-selector=boligbetegnelse]')
   .as('boligbetegnelse');

cy.get('@boligbetegnelse').then((element) => {
    // code using the element
});
// or
cy.get('@boligbetegnelse').should('be.disabled');

我认为另一个潜在的问题可能是和之间的误解yield——return赛普拉斯命令产生它们的结果,允许它们很容易被链接,而你试图返回结果。这是一个细微的差别,但对于赛普拉斯的运作方式来说非常重要!有关这意味着什么,请参阅此 SO 帖子。

于 2021-04-20T13:55:11.027 回答