量角器页面 object 定义未按预期工作
Protractor page object definition not working as expected
抱歉标题有点含糊,我不知道该怎么说。
我有我的页面 Object,除了一个例外,它工作得很好。以下是摘录:
module.exports = function(){
this.facilityList = element(by.name('facility')).all(by.tagName('option'));
this.randomFacility = element(by.name('facility')).all(by.tagName('option')).count().then(function(numberOfItems) {
var rnum = parseInt(Math.random() * numberOfItems);
return rnum;
}).then(function(randomNumber) {
element(by.name('facility')).all(by.tagName('option')).get(randomNumber)
});
}
我可以正常访问和使用 facilityList
。但后来我意识到我几乎总是对 facilityList
做同样的事情,所以为什么我不创建另一行让它随机选择一个。所以我使用主 conf.js.
中的代码创建 randomFacility
没用。我看到显示的错误是:
Failed: Error while waiting for Protractor to sync with the page: "both angularJS testability and angular testability are undefined. This could be either because this is a non-angular page or because your test involves client-side navigation, which can interfere with Protractor's bootstrapping. See http://git.io/v4gXM for details"
我很困惑。这是说我不能在页面 object 中进行所有处理以获得随机页面,还是我只需要在 conf.js 中操作 facilityList 并完成它?
你需要了解量角器查找元素的机制。量角器只在调用量角器的动作 API时才开始从页面中查找元素,如getText()
、click()
、count()
等
所以当你定义变量来表示页面上的某个元素时,当Nodejs执行这一行时,量角器不会从页面开始查找元素:
// page object login.page.js
module.exports = function LoginPage(){
this.sumbitButton = element(by.css('#submit'));
this.countName = element.all(by.css('.username')).count();
}
// use page object in conf.js
var LoginPage = require('./login.page.js');
var loginPage = new Loginpage();
当Nodejs执行第var loginPage = new Loginpage();
行时,函数LoginPage
中的所有行都会被执行。
当执行第一行时,量角器未从当前打开的页面中找到元素,
执行second行时,protractor会从当前打开的页面中寻找元素,但此时protractor可能会启动浏览器,页面为空白,即目标页面尚未打开或导航到。
要解决您的问题,您需要将 randomFacility
定义为 class 的 Method
,而不是 Property
:
module.exports = function() {
this.facilityList = element(by.name('facility')).all(by.tagName('option'));
this.randomFacility = function() {
return element(by.name('facility'))
.all(by.tagName('option')).count()
.then(function(numberOfItems) {
console.log('count: '+numberOfItems);
var rnum = parseInt(Math.random() * numberOfItems);
console.log('random index: '+rnum);
return rnum;
})
.then(function(randomNumber) {
console.log('argument randomNumber: '+randomNumber);
return element(by.name('facility'))
.all(by.tagName('option')).get(randomNumber)
});
}
};
// how to use
pageObject.randomFacility().then(function(ele){
return ele.click();
});
抱歉标题有点含糊,我不知道该怎么说。
我有我的页面 Object,除了一个例外,它工作得很好。以下是摘录:
module.exports = function(){
this.facilityList = element(by.name('facility')).all(by.tagName('option'));
this.randomFacility = element(by.name('facility')).all(by.tagName('option')).count().then(function(numberOfItems) {
var rnum = parseInt(Math.random() * numberOfItems);
return rnum;
}).then(function(randomNumber) {
element(by.name('facility')).all(by.tagName('option')).get(randomNumber)
});
}
我可以正常访问和使用 facilityList
。但后来我意识到我几乎总是对 facilityList
做同样的事情,所以为什么我不创建另一行让它随机选择一个。所以我使用主 conf.js.
randomFacility
没用。我看到显示的错误是:
Failed: Error while waiting for Protractor to sync with the page: "both angularJS testability and angular testability are undefined. This could be either because this is a non-angular page or because your test involves client-side navigation, which can interfere with Protractor's bootstrapping. See http://git.io/v4gXM for details"
我很困惑。这是说我不能在页面 object 中进行所有处理以获得随机页面,还是我只需要在 conf.js 中操作 facilityList 并完成它?
你需要了解量角器查找元素的机制。量角器只在调用量角器的动作 API时才开始从页面中查找元素,如getText()
、click()
、count()
等
所以当你定义变量来表示页面上的某个元素时,当Nodejs执行这一行时,量角器不会从页面开始查找元素:
// page object login.page.js
module.exports = function LoginPage(){
this.sumbitButton = element(by.css('#submit'));
this.countName = element.all(by.css('.username')).count();
}
// use page object in conf.js
var LoginPage = require('./login.page.js');
var loginPage = new Loginpage();
当Nodejs执行第var loginPage = new Loginpage();
行时,函数LoginPage
中的所有行都会被执行。
当执行第一行时,量角器未从当前打开的页面中找到元素,
执行second行时,protractor会从当前打开的页面中寻找元素,但此时protractor可能会启动浏览器,页面为空白,即目标页面尚未打开或导航到。
要解决您的问题,您需要将 randomFacility
定义为 class 的 Method
,而不是 Property
:
module.exports = function() {
this.facilityList = element(by.name('facility')).all(by.tagName('option'));
this.randomFacility = function() {
return element(by.name('facility'))
.all(by.tagName('option')).count()
.then(function(numberOfItems) {
console.log('count: '+numberOfItems);
var rnum = parseInt(Math.random() * numberOfItems);
console.log('random index: '+rnum);
return rnum;
})
.then(function(randomNumber) {
console.log('argument randomNumber: '+randomNumber);
return element(by.name('facility'))
.all(by.tagName('option')).get(randomNumber)
});
}
};
// how to use
pageObject.randomFacility().then(function(ele){
return ele.click();
});