我有以下页面对象模型代表我的应用程序中的小部件
/**
* 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.
我做错了什么?
这似乎是这个问题的结果
访问 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
。
如果别名在使用时变得过时,链接器将重新运行以获取查询结果的新副本。但这不会自动发生在您的页面对象方法中。