Cypress 页面对象模型模式。扩展元素属性

问题描述 投票:0回答:1

我有以下页面对象模型代表我的应用程序中的小部件

/**
 * Contains common actions for all widgets
 */

export default abstract class AbstractWidget {
  private widgetId: number;

  elements = {
    widget: () => cy.getDataTestId(`widgetbox-container-${this.widgetId}`),
  };

  constructor(widgetId: number) {
    this.widgetId = widgetId;
  }
  
}

我有一个扩展此类的具体类,我想将特定于该小部件的额外元素附加到

elements
属性

import AbstractWidget from './AbstractWidget';

export default class SpecificWidget extends AbstractWidget {
    elements = {
        ...super.elements,
        assetSearch: () => cy.getDataTestId('assetSearch'),
    };


    constructor(widgetId: number) {
        super(widgetId);
    }
}

但是,当我尝试传播抽象超类中的元素时

    elements = {
        ...super.elements,
        assetSearch: () => cy.getDataTestId('assetSearch'),
    };

它会导致打字稿错误

TS2340: Only public and protected methods of the base class are accessible via the  super  keyword.

我做错了什么?

javascript typescript cypress pageobjects
1个回答
0
投票

这似乎是这个问题的结果
访问 super 上的属性应该是类型错误 #35314 2019 年 11 月 24 日

如果您点击 TS Playground 链接,它将打开并显示最新的 TS 版本,并且

console.log(super.n)
显示错误。如果您将版本更改为
3.7.5
,错误就会消失。

但是如果您查看手册重写方法,则允许对方法进行等效访问,因此上述更改似乎造成了异常

class Base {
  greet() {
    console.log("Hello, world!");
  }
}
 
class Derived extends Base {
  greet(name?: string) {
    if (name === undefined) {
      super.greet();
    } else {
      console.log(`Hello, ${name.toUpperCase()}`);
    }
  }
}

特别是在 Cypress 中,您可以使用

this.elements
而不是
super.elements
,因为派生类继承了基类元素属性:

测试(使用字符串返回值而不是 Chainers)

export default class SpecificWidget extends AbstractWidget {
  elements = {
    ...this.elements,
    assetSearch: () => 'assetSearch',
  }

  constructor(widgetId: number) {
    super(widgetId)
  }
}
export default abstract class AbstractWidget {
  private widgetId: number

  elements = {
    widget: () => `widgetbox-container-${this.widgetId}`,
  }

  constructor(widgetId: number) {
    this.widgetId = widgetId
  }
}
const specific = new SpecificWidget(1)
expect(specific.elements.widget()).to.eq('widgetbox-container-1')
expect(specific.elements.assetSearch()).to.eq('assetSearch')


或者您可以在基类中创建一个“辅助方法”

export default abstract class AbstractWidget {
  private widgetId: number

  elements = {
    widget: () => `widgetbox-container-${this.widgetId}`,
  }

  getElements() {
    return this.elements
  }

  constructor(widgetId: number) {
    this.widgetId = widgetId
  }
}
export default class SpecificWidget extends AbstractWidget {
  elements = {
    ...super.getElements(),
    assetSearch: () => 'assetSearch',
  }

  constructor(widgetId: number) {
    super(widgetId)
  }
}

附加说明,像这样返回 Chainers

widget: () => cy.getDataTestId(`widgetbox-container-${this.widgetId}`),

如果返回的 Chainer 由于页面更改而失效,可能会导致意外问题。

请参阅变量和别名 - 返回值

返回值
您无法分配或使用任何 Cypress 命令的返回值。命令排队并异步运行。

如果您打算在调用

widgit()
和使用结果之间立即链接而不进行页面操作,这是可以的,但这意味着使用该类的任何人都必须记住该警告。

Cypress 专门针对此问题对 aliases 进行了更改,将其默认为

type: query

如果别名在使用时变得过时,链接器将重新运行以获取查询结果的新副本。但这不会自动发生在您的页面对象方法中。

© www.soinside.com 2019 - 2024. All rights reserved.