我正在使用量角器针对Angular应用程序构建一些测试操作。我试图使定位器尽可能易于阅读和维护,并尝试使用“元素链接”来做到这一点。根据我在SO和量角器文档中阅读的所有内容,我认为以下定位器策略应该有效:
xpPanelPayment变量的定义仅出于可读性。
let xpPanelPayment = "//div [@class='panel-heading' and text()='Payment']/following-sibling::div [@class='panel-body']";
this.pnlPayment = element(by.xpath(`${xpPanelPayment}`));
this.valTotalPayment = element(by.xpath(`${xpPanelPayment}`))
.element(by.xpath(`//strong [text()='Total Payment:']/../following-sibling::div/strong`));
我想要的是:
this.valTotalPayment = this.pnlPayment
.element(by.xpath(`//strong [text()='Total Payment:']/../following-sibling::div/strong`));
但是,当我尝试这样做时,出现一个错误,似乎表明this.pnlPayment未定义。也许这是一个线索?
这是利用这些定位器的方法:
const Receipt = require('./Receipt.js').Receipt;
exports.verifyTotalPayment = (payment) => {
it(`Receipt Validation - Verify total payment $${payment}`, () => {
console.log(`Receipt.pnlPayment.locator() = '${Receipt.pnlPayment.locator()}'`);
console.log(`Receipt.valTotalPayment.locator() =
'${Receipt.valTotalPayment.locator()}'`);
expect(Receipt.valTotalPayment.getText()).toEqual(`$${payment}`);
});
}
这是运行日志的内容:
Receipt.pnlPayment.locator() = 'By(xpath, //div [@class='panel-heading' and text()='Payment']/following-sibling::div [@class='panel-body'])'
Receipt.valTotalPayment.locator() = 'By(xpath, //strong [text()='Total Payment:']/../following-sibling::div/strong)'
[09:31:07] W/element - more than one element found for locator By(xpath, //strong [text()='Total Payment:']/../following-sibling::div/strong) - the first result will be used
看来valTotalPayment的“父”部分被完全忽略了。我对valTotalPayment的说明做错了什么?如果我在不引用父对象的情况下使用整个xpath字符串,则valTotalPayment会找到正确的元素,但这会破坏我的尝试。
最佳答案
该问题来自valTotalPayment
的xpath。您希望从valTotalPayment
的后代中找到pnlPayment
。
您使用//
,但将./
用作valTotalPayment
。//
表示整个页面的任何元素节点./
表示上一个/父元素的任何后代元素节点
最后,编写定位器时,CSS选择器是第一个选择,第二个是xpath。
并且您可以根据需要在元素链中混合使用Css选择器和xpath:element(by.css()).element(by.xpath()).element(by.css())....
关于angular - Protractor 链对我不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49280981/