meteorcucumberwebdriver-iometeor-velocity

Is there a way to wait for another WebDriverIO promise chain to finish?


I am trying to build a test step in Cucumber that will login a test user with a given role. My approach is to try to see is the Sign Out option is there and click it, then to try to login. The problem is that the promise structure doesn't guarantee that the logout happens first, and since I can't assume I am always logged in first, I need a way to basically wait until that happens before moving on.

My test step looks like this:

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

Is there a way to put a stop after the myBrowser.waitForVisible('#appSignOut')? Am I just missing the intended usage all together?

Update

I have tried a new approach, but still not working:

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

The logic here was:

  1. When the #main_menu is visible (page is loaded)
  2. then - if #appSignOut is present, click on it
  3. then - wait for #appSignIn to become visible, and then complete the login

The error I get is:

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

But I don't think any of this is working at all. The popup browser goes too fast for me to see what's happening, and the cucumber.log doesn't really give me any good indication as to what it's doing either.


Solution

  • It's old question, hopefully you found your answer since, but I'll answer it might help others.

    When using promises, you have to make sure you use them everywhere (in most cases, or you really want things to be run asynchronously).

    In your code it would be:

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

    You can notice it is way more readable than before.

    The key things I changed:

    Cheers