Javascript 使用量角器进行AngularJS测试-使用browser.wait()
我正在使用量角器为AngularJS应用程序开发一个自动化测试套件 在开发测试脚本时,我一直在使用Javascript 使用量角器进行AngularJS测试-使用browser.wait(),javascript,angularjs,protractor,automated-tests,Javascript,Angularjs,Protractor,Automated Tests,我正在使用量角器为AngularJS应用程序开发一个自动化测试套件 在开发测试脚本时,我一直在使用browser.pause(),因此在执行脚本时,我必须手动告诉它继续执行测试的每个步骤。我现在很高兴我的测试能够正确执行,我想删除对browser.pause()的调用,这样我就可以让脚本自己运行到完成 但是,我知道,如果不在执行下一步之前添加允许我的测试暂停/等待浏览器加载的内容,我将无法删除对browser.pause()的调用(目前,我在调用browser.pause()后通知脚本继续所用的
browser.pause()
,因此在执行脚本时,我必须手动告诉它继续执行测试的每个步骤。我现在很高兴我的测试能够正确执行,我想删除对browser.pause()
的调用,这样我就可以让脚本自己运行到完成
但是,我知道,如果不在执行下一步之前添加允许我的测试暂停/等待浏览器加载的内容,我将无法删除对browser.pause()
的调用(目前,我在调用browser.pause()后通知脚本继续所用的时间)
运行时,浏览器有足够的时间加载下一步测试所需的元素)
我正在尝试使用browser.wait()
执行此操作,将每个测试的最后一行作为参数传递给browser.wait()
,以及超时值(即10秒)。例如:
it('should log the user in to the application', function() {
browser.wait(loginAsUser(username, password), 10000);
});
该测试最初只是:
browser.pause();
it('should log the user in to the application', function() {
loginAsUser(username, password);
});
i、 e.在测试用例外部调用browser.pause()
将导致浏览器在每个测试步骤之间暂停
loginAsUser()
函数定义为:
function loginAsUser(username, password) {
usernameInputField.sendKeys(username);
passwordInputField.sendKeys(password);
loginBtn.click();
}
当前运行测试脚本时,将browser.wait()
添加到每个测试的最后一个可执行行,与登录测试一样,我在第一个测试(上面的日志)中遇到以下失败,其余测试都失败,因为它们依赖于通过的测试:
失败:等待条件必须是类似承诺的对象、函数或条件对象
我不明白为什么会出现这个错误,因为wait
条件是一个函数。。。它被赋予了我在上面定义的loginAsUser()
函数。。。?有人能解释一下我做错了什么吗
编辑
因此,问题似乎实际上在于我的其余测试(即先运行login
测试,然后依次运行许多其他测试)
按照最初的登录测试方式,测试用例当前已正确登录,但下一个要运行的测试失败,并出现错误:
失败:使用定位器(链接文本、页面)未找到元素
这似乎是失败的,因为登录后页面没有时间加载,而在我调用browser.pause()
运行测试时,页面确实有时间加载
下一个要运行的测试是:
it('should display the Pages menu', function() {
browser.waitForAngularEnabled(false);
browser.actions().mouseMove(pagesMenuBtn).perform();
expect(pageTagBrowserBtn.isDisplayed()).toBeTruthy();
browser.actions().mouseMove(userCircle).perform();
expect(pageTagBrowserBtn.isDisplayed()).toBeFalsy();
browser.waitForAngularEnabled(true);
});
pagesMenuBtn
定义为全局变量,具有:
var pagesMenuBtn = element(by.linkText("Pages"));
因此,在运行下一个测试之前,我似乎需要给我的应用程序一些时间,以便在登录后加载页面,否则将找不到元素
编辑
我尝试在“页面”测试中添加对browser.wait()
的调用,以便测试在将光标悬停在按钮上之前等待按钮显示:
it('should display the Pages menu', function() {
browser.waitForAngularEnabled(false);
browser.wait(function() {
pagesMenuBtn.isDisplayed().then(function(isDisplayed){
/* if(!isDisplayed) {
console.log("Display Pages menu test returning false ");
return false;
}
console.log("Display Pages menu test returning true "); */
//return true;
browser.actions().mouseMove(pagesMenuBtn).perform().then(function(isDisplayed){
expect(pageTagBrowserBtn.isDisplayed()).toBeTruthy();
});
browser.actions().mouseMove(userCircle).perform().then(function(isDisplayed){
expect(pageTagBrowserBtn.isDisplayed()).toBeFalsy();
});
});
}, 5000);
});
但我还是得到了同样的错误:
失败:使用定位器(链接文本、页面)未找到元素
指示找不到测试尝试悬停在其上的按钮(即,在测试脚本尝试单击该按钮时,该按钮似乎未加载到浏览器中)
编辑
好的,我再次更新了我的测试-现在看起来是这样的:
it('should display the Pages menu', function() {
browser.waitForAngularEnabled(false);
browser.wait(EC.visibilityOf(pagesMenuBtn), 5000).then(
browser.actions().mouseMove(pagesMenuBtn).perform().then(function(){
expect(pageTagBrowserBtn.isDisplayed()).toBeTruthy();
})).then(
browser.actions().mouseMove(userCircle).perform().then(function(){
expect(pageTagBrowserBtn.isDisplayed()).toBeFalsy();
}));
});
我这样做的目的是,浏览器将等待pagesMenuBtn
元素显示,然后,一旦显示,光标将移动到按钮上,一旦发生这种情况,它应该检查是否显示pageTagBrowserBtn
元素(期望它返回“true”值)。然后,光标将移动到页面上的另一个元素(userCircle
),并再次检查是否显示了pageTagBrowserBtn
(这次希望它返回“false”值)
但是,当我现在运行测试时,它失败了,说明:
期望虚假成为真实
我不知道为什么这是。。。?据我所知,测试应该等待EC.visibilityOf(pagesMenuBtn)
的条件返回true,然后再尝试继续测试。。。所以我不希望它因为值为false而失败——如果值为false,它应该等到它为true之后再继续——至少从我所写的内容来看,这是我的意图
有谁能告诉我这里出了什么问题吗?一般来说,你不应该等待一段硬编码的时间 至少应将等待与预期条件配对,以便在满足条件后立即脱离 帮助器方法示例:
public static async waitForPresenceOf(element: ElementFinder, waitMs?: number): Promise<boolean> {
return browser.wait(EC.presenceOf(element), waitMs || 5000).then(() => true, () => false);
}
请注意done
参数。这告诉测试运行程序等待调用done
回调
您还应该能够通过简单地返回一个承诺来实现同样的目标(至少在我的设置中有效)
出现错误的原因是,方法需要等待条件保持或承诺得到解决 例如,让我们说在
loginBtn.click()之后
您正在等待一个id为abc
的元素可见,您可以编写如下代码。查看详情
var EC = protractor.ExpectedConditions;
// Waits for the element with id 'abc' to be visible on the dom.
browser.wait(EC.visibilityOf($('#abc')), 5000);
或者您希望等待某个自定义条件(如等待显示此元素)
更多信息直接来自他们的文档
示例:假设您有一个函数startTestServer,它返回
服务器准备好接收请求时的承诺。你可以阻止一个
此承诺的WebDriver客户端具有:
示例代码
var started = startTestServer();
browser.wait(started, 5 * 1000, 'Server should start within 5 seconds');
browser.get(getServerUrl());
根据其他数据进行编辑
pageTagBrowserBtn.isDisplayed()
retu
it('should log the user in to the application', function() {
return BrowserHelper.sendKeys(usernameInputField, username)
.then(function() {
return BrowserHelper.sendKeys(passwordInputField, password)
})
.then(function() {
return BrowserHelper.click(loginBtn)
})
});
var EC = protractor.ExpectedConditions;
// Waits for the element with id 'abc' to be visible on the dom.
browser.wait(EC.visibilityOf($('#abc')), 5000);
browser.wait(function(){
element.isDisplayed().then(function(isDisplayed){
if(!isDisplayed) {
return false; //keep looking until its visible;
}
return true; //exits right here unless the timeout is already met
});
},5000);
var started = startTestServer();
browser.wait(started, 5 * 1000, 'Server should start within 5 seconds');
browser.get(getServerUrl());
it('should display the Pages menu', function() {
browser.waitForAngularEnabled(false);
browser.wait(EC.visibilityOf(pagesMenuBtn), 5000).then(
browser.actions().mouseMove(pagesMenuBtn).perform().then(function(){
pageTagBrowserBtn.isDisplayed().then(function(isDisplayed) {
//check isDisplayed is true here
});
})).then(
browser.actions().mouseMove(userCircle).perform().then(function(){
expect(pageTagBrowserBtn.isDisplayed()).toBeFalsy();
}));
});