如何在赛普拉斯中将定位器作为参数传递?

How to pass locator as parameter in cypress?

我想知道是否可以将定位器作为参数传递以使我的函数可重用。 我试着自己做,但我得到的是“未定义”而不是工作测试。 赛普拉斯错误: cy.click() 失败,因为它需要 DOM 元素。 收到的主题是:

undefined

我的代码:

 Cypress.Commands.add(
  "commandName",
  (locator, chartValue1) => {
    const chartValues = [150, 250, 350, 450, 550, 750, 900];
    for (const value of chartValues) {
      locator.click(value, chartValue1).then(() => {
        mainElementsPage
          .mainSideBarHeader()
          .should("not.include.text", "(pon.)")
          .should("not.include.text", "(wt.)")
          .should("not.include.text", "(śr.)");
      });
    }
  }
);

我在测试中使用这个命令:

    it("should do something", () => {
    cy.commandName(mainElementsPage.chartRect(), 200);
  });

mainElements页面内容:

class mainElementsPage {

  chartRect() {
    return cy.get("#chart-grid-rect");
  }
}

export default mainElementsPage;

为了确保您可以使用 mainElementsPage,您必须先将此文件导入到您的测试中,如下所示:

import mainElementsPage from '../<some path>/mainElementsPage.js'

然后你必须为此创建一个对象,比如

const mainElements = new mainElementsPage();

然后您可以将其用作:

mainElements.chartRect()

看起来你想做一个child command

您的自定义命令之前的任何内容都作为 subject(相当于 locator

传递
Cypress.Commands.add("commandName", {prevSubject: true}, 
  (subject, chartValue1) => {
    const chartValues = [150, 250, 350, 450, 550, 750, 900];
    for (const value of chartValues) {
      subject.click(value, chartValue1).then(() => {
        mainElementsPage.mainSideBarHeader()
          .should("not.include.text", "(pon.)")
          .should("not.include.text", "(wt.)")
          .should("not.include.text", "(śr.)");
      });
    }
  }
)


cy.get("#chart-grid-rect").commandName(200);

// or

mainElementsPage.chartRect().commandName(200);
class MainElementsPage {

  chartRect() {
    return cy.get("#chart-grid-rect");
  }
}

export default new MainElementsPage;   // note - new keyword here

在 Cypress 中,不可能同时有 2 个活动的命令链。 因此,您不能将命令链传递到另一个命令(包括您所做的自定义命令)。 所以我看到了 4 种不同的方法来解决这个问题:

  1. 使用普通函数而不是自定义命令。所以你将能够从你的 POM 对象传递一个链。
  2. Return 一个字符串定位器而不是你的链 POM 对象
  3. 使用子命令并链接您的逻辑(参见@Fody 的回答)。
  4. 传递指向您的 POM 对象函数的 函数引用 并在自定义命令中 调用此函数 (参见@wojnarto 的回答) .

我是这样走的:

 Cypress.Commands.add(
  "commandName",
  (locator, chartValue1) => {
    const chartValues = [150, 250, 350, 450, 550, 750, 900];
    for (const value of chartValues) {
      locator()
      .click(value, chartValue1).then(() => {
        mainElementsPage
          .mainSideBarHeader()
          .should("not.include.text", "(pon.)")
          .should("not.include.text", "(wt.)")
          .should("not.include.text", "(śr.)");
      });
    }
  }
);

在测试中看起来:

it("should do something", () => {
    cy.commandName(mainElementsPage.chartRect, 200);
  });

所以事情是关于将 () 添加到 Cypress.Commands.add() 中的定位器并在测试中将定位器用作字符串。