有没有办法等待另一个 WebDriverIO 承诺链完成?
Is there a way to wait for another WebDriverIO promise chain to finish?
我正在尝试在 Cucumber 中构建一个测试步骤,它将使用给定角色登录测试用户。我的方法是尝试查看是否存在注销选项并单击它,然后尝试登录。问题是 promise 结构不能保证先注销,而且由于我不能假设我总是先登录,所以我需要一种方法来基本上等到注销发生后再继续。
我的测试步骤是这样的:
this.Given(/^I am logged in as a\/an "([^"]*)"$/, function(roleName, callback) {
console.log('Starting login as ', roleName);
var myBrowser = this.browser;
this.browser
.setViewportSize({width: 1000, height: 600})
.url(url.resolve(process.env.HOST, '/'));
this.browser
.waitForVisible('#main_menu').then(function() {
console.log('#main_menu is visible' );
myBrowser.waitForVisible('#appSignOut').then(function() {
console.log('Logging out now');
myBrowser.click('#appSignOut');
});
myBrowser.waitForVisible('#appSignIn').then(function() {
console.log('Logging in as ', roleName);
myBrowser.click('#appSignIn');
myBrowser.waitForVisible('#username').then(function() {
myBrowser
.setValue('#username', 'test' + roleName)
.setValue('#password', 'test' + roleName)
.leftClick('#signin')
.call(callback);
});
});
});
console.log('Done logging in as ', roleName);
});
有没有办法在 myBrowser.waitForVisible('#appSignOut')
之后停止?我只是错过了所有的预期用途吗?
更新
我尝试了一种新方法,但仍然无效:
this.Given(/^I am logged in as a\/an "([^"]*)"$/, function(roleName, callback) {
var myBrowser = this.browser;
this.browser
.setViewportSize({width: 1000, height: 600})
.url(url.resolve(process.env.HOST, '/'));
this.browser
.waitForVisible('#main_menu')
.then(myBrowser.isVisible('#appSignOut').then(function(isVisible) {
if (isVisible) {
myBrowser.click('#appSignOut');
}
}))
.then(myBrowser.waitForVisible('#appSignIn').then(function() {
myBrowser
.click('#appSignIn')
.waitForVisible('#username')
.setValue('#username', 'test' + roleName)
.setValue('#password', 'test' + roleName)
.leftClick('#signin');
}))
.call(callback);;
});
这里的逻辑是:
- 当#main_menu 可见时(页面已加载)
- 然后 - 如果存在 #appSignOut,请单击它
- 然后 - 等待#appSignIn 可见,然后完成登录
我得到的错误是:
[chimp] Detected an unhandledRejection.
[chimp][hooks] Reason:
[chimp][hooks] RuntimeError
[chimp][hooks] no such element
但我认为这根本不起作用。弹出式浏览器运行得太快,我看不到发生了什么,而且 cucumber.log 也没有真正给我任何关于它在做什么的好指示。
我在使用 ChimpJS 使用登录表单自动登录我的 Meteor 应用程序时遇到问题,我正在 "login forbidden",使用 http://webdriver.io/api/protocol/execute.html to execute Meteor.loginWithPassword() (be careful due to synchronous nature of ChimpJS's version of WebDriverIO don't use the .then()) as suggested by looshi worked for me: http://docs.meteor.com/#/full/meteor_loginwithpassword
这是一个老问题,希望你从那以后找到了答案,但我会回答它可能会对其他人有所帮助。
使用 promises 时,您必须确保在任何地方都使用它们(在大多数情况下,或者您确实希望事情 运行 异步)。
在您的代码中它将是:
this.Given(/^I am logged in as a\/an "([^"]*)"$/, function(roleName) {
return this.browser
.setViewportSize({width: 1000, height: 600})
.url(url.resolve(process.env.HOST, '/'))
.waitForVisible('#main_menu')
.isVisible('#appSignOut')
.then(function(isVisible) {
if (isVisible) {
return this.click('#appSignOut');
}
})
.waitForVisible('#appSignIn')
.click('#appSignIn')
.waitForVisible('#username')
.setValue('#username', 'test' + roleName)
.setValue('#password', 'test' + roleName)
.leftClick('#signin');
});
您会注意到它比以前更具可读性。
我更改的关键内容:
- 我将所有内容链接在一起(webdriverio 允许这样做)
- 当使用 .Then() 时
this
对应于 this.browser
所以你仍然可以链接
- 通过 return 从 then() 中获取
this.click()
的结果,您可以继续链接
- CucumberJS 可以处理承诺,为此您需要删除回调参数和 return 承诺。在这种情况下,只是 return webdriverio API 调用的结果
干杯
我正在尝试在 Cucumber 中构建一个测试步骤,它将使用给定角色登录测试用户。我的方法是尝试查看是否存在注销选项并单击它,然后尝试登录。问题是 promise 结构不能保证先注销,而且由于我不能假设我总是先登录,所以我需要一种方法来基本上等到注销发生后再继续。
我的测试步骤是这样的:
this.Given(/^I am logged in as a\/an "([^"]*)"$/, function(roleName, callback) {
console.log('Starting login as ', roleName);
var myBrowser = this.browser;
this.browser
.setViewportSize({width: 1000, height: 600})
.url(url.resolve(process.env.HOST, '/'));
this.browser
.waitForVisible('#main_menu').then(function() {
console.log('#main_menu is visible' );
myBrowser.waitForVisible('#appSignOut').then(function() {
console.log('Logging out now');
myBrowser.click('#appSignOut');
});
myBrowser.waitForVisible('#appSignIn').then(function() {
console.log('Logging in as ', roleName);
myBrowser.click('#appSignIn');
myBrowser.waitForVisible('#username').then(function() {
myBrowser
.setValue('#username', 'test' + roleName)
.setValue('#password', 'test' + roleName)
.leftClick('#signin')
.call(callback);
});
});
});
console.log('Done logging in as ', roleName);
});
有没有办法在 myBrowser.waitForVisible('#appSignOut')
之后停止?我只是错过了所有的预期用途吗?
更新
我尝试了一种新方法,但仍然无效:
this.Given(/^I am logged in as a\/an "([^"]*)"$/, function(roleName, callback) {
var myBrowser = this.browser;
this.browser
.setViewportSize({width: 1000, height: 600})
.url(url.resolve(process.env.HOST, '/'));
this.browser
.waitForVisible('#main_menu')
.then(myBrowser.isVisible('#appSignOut').then(function(isVisible) {
if (isVisible) {
myBrowser.click('#appSignOut');
}
}))
.then(myBrowser.waitForVisible('#appSignIn').then(function() {
myBrowser
.click('#appSignIn')
.waitForVisible('#username')
.setValue('#username', 'test' + roleName)
.setValue('#password', 'test' + roleName)
.leftClick('#signin');
}))
.call(callback);;
});
这里的逻辑是:
- 当#main_menu 可见时(页面已加载)
- 然后 - 如果存在 #appSignOut,请单击它
- 然后 - 等待#appSignIn 可见,然后完成登录
我得到的错误是:
[chimp] Detected an unhandledRejection.
[chimp][hooks] Reason:
[chimp][hooks] RuntimeError
[chimp][hooks] no such element
但我认为这根本不起作用。弹出式浏览器运行得太快,我看不到发生了什么,而且 cucumber.log 也没有真正给我任何关于它在做什么的好指示。
我在使用 ChimpJS 使用登录表单自动登录我的 Meteor 应用程序时遇到问题,我正在 "login forbidden",使用 http://webdriver.io/api/protocol/execute.html to execute Meteor.loginWithPassword() (be careful due to synchronous nature of ChimpJS's version of WebDriverIO don't use the .then()) as suggested by looshi worked for me: http://docs.meteor.com/#/full/meteor_loginwithpassword
这是一个老问题,希望你从那以后找到了答案,但我会回答它可能会对其他人有所帮助。
使用 promises 时,您必须确保在任何地方都使用它们(在大多数情况下,或者您确实希望事情 运行 异步)。
在您的代码中它将是:
this.Given(/^I am logged in as a\/an "([^"]*)"$/, function(roleName) {
return this.browser
.setViewportSize({width: 1000, height: 600})
.url(url.resolve(process.env.HOST, '/'))
.waitForVisible('#main_menu')
.isVisible('#appSignOut')
.then(function(isVisible) {
if (isVisible) {
return this.click('#appSignOut');
}
})
.waitForVisible('#appSignIn')
.click('#appSignIn')
.waitForVisible('#username')
.setValue('#username', 'test' + roleName)
.setValue('#password', 'test' + roleName)
.leftClick('#signin');
});
您会注意到它比以前更具可读性。
我更改的关键内容:
- 我将所有内容链接在一起(webdriverio 允许这样做)
- 当使用 .Then() 时
this
对应于this.browser
所以你仍然可以链接 - 通过 return 从 then() 中获取
this.click()
的结果,您可以继续链接 - CucumberJS 可以处理承诺,为此您需要删除回调参数和 return 承诺。在这种情况下,只是 return webdriverio API 调用的结果
干杯