我在第三天和Protractor一起工作时,我总是在等待加载页面和显示元素方面遇到金砖墙。特别是这个测试案例变得丑陋,我想解决问题而不必依赖睡眠。
我目前“在AngularJS之外”
it('it should reflect in both the field and the title when the personnel name is changed', function() {
var inputField, personnelHeader, personnelName;
personnelName = element(By.css(".overlay.editnameoverlay")).click();
personnelHeader = element(By.id("personnel_name_header"));
inputField = element(By.css("input[name='newvalue']"));
inputField.clear();
inputField.sendKeys("Test 123");
element(By.css("input[name='ok_button']")).click();
// browser.driver.sleep(2000); This test only works with this sleep added
browser.wait(function() {
console.log("Waiting for header to change...");
return personnelHeader.getText().then(function(text) {
return text === "Test 123";
});
}, 5000);
return expect(personnelHeader.getText()).toBe(personnelName.getText());
});
因此,此处的测试会更改输入字段中的名称。提交它并等待更改反映在模态的标题中。问题是如果没有browser.driver.sleep(2000),我会收到一条错误
Stacktrace:
StaleElementReferenceError: stale element reference: element is not attached to the page document
在这种特殊情况下如何解决这个问题?
答案 0 :(得分:12)
来自Expect Conditions的文档:
var EC = protractor.ExpectedConditions;
// Waits for the element with id 'abc' to contain the text 'foo'.
browser.wait(EC.textToBePresentInElement($('#abc'), 'foo'), 5000);
答案 1 :(得分:7)
当您使用量角器测试非角度页面时,您自己就是在等待元素准备好进行交互。
StaleElementReferenceError
可能是最无用的硒错误,它发生在元素从DOM中删除但仍然以某种方式缓存时,我也suffered这个问题在使用Protractor启动时甚至是{{3}应该自动重试量角器侧。
我的解决方案是始终使用tried to convince waitReady()
明确等待元素出现在页面上,browser.wait
表示元素就绪,即:等待元素为准备互动:
expect($('#login_field').waitReady()).toBeTruthy();
首先在代码中集成此代码段:custom function
不仅自定义waitReady()
等待该元素,而且它还会吞下任何无关的无用的webdriver错误,如StaleElementReferenceError
,只会重试直到找到该元素,否则它将超时。
因此waitReady()
每个元素在互动之前,即在clear()
或sendKeys()
或click()
之前......
// TODO: Move to Page Objects module
var personnelNameElm = $(".overlay.editnameoverlay");
var personnelHeaderElm = $("#personnel_name_header");
var inputFieldElm = $("input[name='newvalue']");
var okBtnElm = $("input[name='ok_button']");
it('it should reflect in both the field and the title when the ' +
'personnel name is changed', function() {
expect(personnelNameElm.waitReady()).toBeTruthy();
personnelNameElm.click();
expect(inputFieldElm.waitReady()).toBeTruthy();
inputFieldElm.clear().sendKeys("Test 123");
expect(okBtnElm.waitReady()).toBeTruthy();
okBtnElm.click();
browser.wait(function() {
console.log("Waiting for header to change...");
// Using waitReady() before getText() avoids Stale element errors
return personnelHeaderElm.waitReady().then(function() {
return personnelHeaderElm.getText().then(function(text) {
return text === "Test 123";
});
});
}, 5000);
expect(personnelHeaderElm.getText()).toEqual(personnelNameElm.getText());
});