有没有办法等待另一个WebDriverIO承诺链完成?

时间:2015-08-26 02:01:25

标签: meteor cucumber webdriver-io meteor-velocity

我正在尝试在Cucumber中构建一个测试步骤,该步骤将登录具有给定角色的测试用户。我的方法是尝试查看登出选项是否存在并单击它,然后尝试登录。问题是承诺结构并不能保证首先发生注销,而且因为我不能假设我总是先登录,所以我需要一种基本上等到发生这种情况的方法才能继续。< / p>

我的测试步骤如下:

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);;
});

这里的逻辑是:

  1. 当#main_menu可见时(页面已加载)
  2. 然后 - 如果存在#appSignOut,请单击
  3. 然后 - 等待#appSignIn变为可见,然后完成登录
  4. 我得到的错误是:

    [chimp] Detected an unhandledRejection.
    [chimp][hooks] Reason:
    [chimp][hooks] RuntimeError
    [chimp][hooks] no such element
    

    但我认为这根本不起作用。弹出窗口浏览器的速度太快,我无法看到发生了什么,而且.log.log并没有给我任何关于它做什么的好的指示。

2 个答案:

答案 0 :(得分:1)

这是一个古老的问题,希望你能找到答案,但我会回答它可能有助于其他人。

使用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,因此您仍然可以链接
  • 通过从then()返回this.click()的结果,您可以继续链接
  • CucumberJS可以处理promises,因为你需要删除callback参数并返回Promise。在这种情况下,只返回webdriverio API调用的结果

干杯

答案 1 :(得分:0)

我在使用ChimpJS使用登录表单自动登录我的Meteor应用程序时出现问题,我正在“登录禁止”,使用http://webdriver.io/api/protocol/execute.html执行Meteor.loginWithPassword()(由于同步性质,请小心ChimpJS的WebDriverIO版本不使用.then()),因为looshi为我工作:http://docs.meteor.com/#/full/meteor_loginwithpassword