waitForElementVisible("xxx", 1000) never failing

449 views
Skip to first unread message

Joseph

unread,
Mar 13, 2014, 1:16:13 PM3/13/14
to nightw...@googlegroups.com
Quick question, when I execute -

   this.waitForElementVisible("div.container", 1000); 

the server often responds with :

   Element <div.container> was visible after 3434 milliseconds.
   OK. 1 assertions passed.

I thought if it took longer than 1000 milliseconds, it is supposed to fail.  Am I doing something wrong?

Thanks in advance, we are enjoying this testing framework a lot here at my company.


Andrei Rusu

unread,
Mar 13, 2014, 1:35:22 PM3/13/14
to Joseph, nightw...@googlegroups.com
Seems like a bug. Can you tell me what commands do you do before this?
Glad you're enjoying nightwatch :).
> --
> You received this message because you are subscribed to the Google Groups
> "NightwatchJs" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to nightwatchjs...@googlegroups.com.
> To post to this group, send email to nightw...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/nightwatchjs/dd4b6077-51a0-4f66-9f48-b887e80fe9b6%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Joseph

unread,
Mar 13, 2014, 1:48:09 PM3/13/14
to nightw...@googlegroups.com

I baked this down to the simplest example in our codebase and it's showing what you see in the console image I took a screenshot of.  


module.exports = {

'HTML Page Integrity Checks' : function (browser) {

browser

.url(browser.launch_url + "/pagetemplates/homepage")

.waitForElementVisible("body", 1000)

.waitForElementVisible("header", 1000)

.waitForElementVisible("div.container", 1000)

.waitForElementVisible("footer", 1000)

.waitForElementVisible("div.drawer", 1000)

.end();

}

}


Steve Calvert

unread,
Mar 14, 2014, 2:46:12 PM3/14/14
to nightw...@googlegroups.com
Joseph,

Can I interest you in our custom command we wrote for integrity checks?


:)

Steve Calvert

unread,
Mar 14, 2014, 2:47:08 PM3/14/14
to Steve Calvert, nightw...@googlegroups.com
Oops, private repo!

Here it is:

var util = require('util'),
    async = require('async'),
    events = require('events');

function Assertion() {
    events.EventEmitter.call(this);
    this.startTimer = null;
    this.cb = null;
    this.ms = null;
    this.abortOnFailure = true;
    this.selector = null;
}

util.inherits(Assertion, events.EventEmitter);

Assertion.prototype.command = function(selectors, callback) {
    var args = Array.prototype.slice.call(arguments, 0);
    var lastArgument = args[args.length - 1];

    if (typeof (lastArgument) === 'function') {
        callback = args.pop();
    } else {
        callback = function() {};
    }

    this.startTimer = new Date().getTime();
    this.cb = callback;
    this.selectors = args.slice(0);
    this.checkElements();
    return this;
};

Assertion.prototype.checkElements = function() {
    var self = this;
    var missing = [];
    var found = [];
    var selectors = this.selectors;

    function checkElement(selector, cb) {
        self.client.element.call(self, 'css selector', selector, function(result) {
            var value;

            if (result.status == 0) {
                value = result.value.ELEMENT;
            }

            if (value) {
                found.push(selector);
            } else {
                missing.push(selector);
            }

            cb();
        });
    }

    function returnResults(err) {
        var result = missing.length;

        if (result === 0) {
            var foundMsg = found.map(function(el){
                return '<' + el + '>';
            });
            var msg = foundMsg.join(', ') + ' located on page.';
            var passed = true;
        } else {
            var missingMsg = missing.map(function(el){
                return '<' + el + '>';
            });
            var msg = missingMsg.join(', ') + ' missing from page.';
            var passed = false;
        }

        self.client.assertion(passed, result, 0, msg, false);
        self.cb(result);
        self.emit('complete');
    }

    async.each(selectors, checkElement, returnResults);

};

module.exports = Assertion;


--
You received this message because you are subscribed to the Google Groups "NightwatchJs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nightwatchjs...@googlegroups.com.
To post to this group, send email to nightw...@googlegroups.com.

Steve Calvert

unread,
Mar 14, 2014, 2:49:29 PM3/14/14
to Steve Calvert, nightw...@googlegroups.com
Save that to a file called elementsPresent.js, and load it as a custom command.

Usage is:

browser
    .verify.elementsPresent('#first', '.second', ...)
    .end();

Joseph

unread,
Mar 16, 2014, 11:28:49 PM3/16/14
to nightw...@googlegroups.com
That's an interesting bit of code, and I got it working just fine.  I like how it's a custom assertion/verficiation rather than a command, which allows me to use it on .verify instead, which is really helpful.  

Just 2 fixes I had to make to your code (correct me if I'm wrong): 
1.  There needs to be a "custom_assertions_path" in the settings.json pointing to a directory with your code instead of using the "custom_commands_path".
2.  There needs to be:   self.client.assertion(...)  before each time you emit the 'complete' event, one for a success or failure of finding the element.  Otherwise there weren't actually any assertions being made.

It's a very interesting test, and it illustrates how to make custom assertions, which in my opinion can shim a lot of the missing features currently.  I think there is a lot of potential here.  Thanks for sharing your code and letting me know how to make these custom assertions. Cheers!

Joseph

unread,
Mar 16, 2014, 11:34:35 PM3/16/14
to nightw...@googlegroups.com
Oh scratch that 2nd point.  I had missed it when transcribing your code :)

Andrei Rusu

unread,
Mar 17, 2014, 4:23:54 AM3/17/14
to nightw...@googlegroups.com

Hey guys, I've just released 0.4 with so many changes/refactoring that I'm a bit concerned about backwards compatibility issue. Could you let me know if you have any issues with custom command/assertions?

The assertions have a new interface now, but this format should still work. I'm curious if this complex example of  custom assertion still can be written with the new interface and how it would look.

On Mar 17, 2014 4:34 AM, "Joseph" <jun...@gmail.com> wrote:
Oh scratch that 2nd point.  I had missed it when transcribing your code :)

--
You received this message because you are subscribed to the Google Groups "NightwatchJs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nightwatchjs...@googlegroups.com.
To post to this group, send email to nightw...@googlegroups.com.

Keith Bingman

unread,
Mar 19, 2014, 6:23:10 PM3/19/14
to nightw...@googlegroups.com
I have been struggling to get Steve's example working with the 0.4 version. It just doesn't seem to even pick up the assertion. Somewhere, something is failing, but I don't know what. I am trying to track it down.

I tried rewriting our code (Steve and I wrote that together) to conform to the new assertion format, and while that works, the Async part seems to fail. Sometimes (though not always), the assertions run into the next group.

But to keep a long story short, this format does not work with the new version.

Keith

Andrei Rusu

unread,
Mar 20, 2014, 4:15:13 AM3/20/14
to nightw...@googlegroups.com
Ok, I'll look into it. Sorry about that and thanks for checking.

Andrei Rusu

unread,
Mar 20, 2014, 8:34:42 AM3/20/14
to nightw...@googlegroups.com
Hey, I've fixed the issue with wiring for the custom assertion described above. However I had to change one thing: self.client.protocol into self.api.protocol.

Here's the full working code:

var async = require('async'),
    util = require('util'),
    events = require('events');

function Assertion() {
  events.EventEmitter.call(this);
  this.cb = null;
  this.abortOnFailure = true;
  this.selector = null;
}

util.inherits(Assertion, events.EventEmitter);

Assertion.prototype.command = function(selectors, callback) {
  var args = Array.prototype.slice.call(arguments, 0);
  var lastArgument = args[args.length - 1];

  if (typeof (lastArgument) === 'function') {
    callback = args.pop();
  } else {
    callback = function() {};
  }

  this.cb = callback;
  this.selectors = args.slice(0);
  this.checkElements();

  return this;
};

Assertion.prototype.checkElements = function() {
  var self = this;
  var missing = [];
  var found = [];
  var selectors = this.selectors;

  function checkElement(selector, cb) {
    self.api.element.call(self, 'css selector', selector, function(result) {
      var value;

      if (result.status === 0) {
        value = result.value.ELEMENT;
      }

      if (value) {
        found.push(selector);
      } else {
        missing.push(selector);
      }

      cb();
    });
  }

  function returnResults(err) {
    var result = missing.length;
    var msg, passed;

    if (result === 0) {
      var foundMsg = found.map(function(el){
        return '<' + el + '>';
      });
      msg = foundMsg.join(', ') + ' located on page.';
      passed = true;
    } else {
      var missingMsg = missing.map(function(el){
        return '<' + el + '>';
      });
      msg = missingMsg.join(', ') + ' missing from page.';
      passed = false;
    }

    self.client.assertion(passed, result, 0, msg, false);
    self.cb(result);
    self.emit('complete');
  }

  async.each(selectors, checkElement, returnResults);
};

module.exports = Assertion;

It's currently in master, but not in npm yet. 

Andrei Rusu

unread,
Mar 20, 2014, 8:36:18 AM3/20/14
to nightw...@googlegroups.com
Maybe you'd like to contribute this for the examples folder as a more sophisticated example? 

Andrei Rusu

unread,
Mar 20, 2014, 10:08:15 AM3/20/14
to David Linse, nightw...@googlegroups.com
Oh, replace the 'css selector' with self.client.locateStrategy so it
would work with xpath as well.

On Thu, Mar 20, 2014 at 3:04 PM, David Linse <david...@gmail.com> wrote:
> does this work with xpath selectors as well? I'm asking b/c of the hardcoded
> 'css selector' string..
> regards
> ~david
>> --
>> You received this message because you are subscribed to the Google Groups
>> "NightwatchJs" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to nightwatchjs...@googlegroups.com.
>> To post to this group, send email to nightw...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/nightwatchjs/f4633459-b92c-4864-b648-087d940c2e04%40googlegroups.com.

Keith Bingman

unread,
Mar 20, 2014, 2:54:56 PM3/20/14
to nightw...@googlegroups.com, David Linse
Thanks! 

This works well. I was adding the locateStrategy stuff anyway. 

I will try to extract a sample assertion and send you a PR for that. 

Keith

Keith Bingman

unread,
Mar 20, 2014, 8:42:36 PM3/20/14
to nightw...@googlegroups.com, David Linse
Ok, I got these all working. One thing though, using the new style Assertion tests doesn't work. It looks like the fallback for the old style doesn't return anything, just adds a command. Can you think of a good way to get around this?

Keith
Reply all
Reply to author
Forward
0 new messages