Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setFindTimeout and pollUntil with Intern for elements that are not visible on initial page load

I'm having an issue getting Intern 2 to wait for elements to be present. In Intern 1 I was using wait()to set express time periods for the page to wait for an element to be present after some user action. With Intern 2 there seems to be setFindTimeout() which should always tell a find() method to wait a bit for the element to be present. I've set setFindTimeout() and tried using pollUntil to handle these waits but the tests are still failing with the error "element not visible".

Here is a sample test that is using the same requirements as my real tests and is looking for an element Id which appears 5 seconds after this page loads.

define([
'intern!object',
'intern/chai!assert',
'require',
'tests/util',
'intern/dojo/node!leadfoot/Command',
'intern/dojo/node!leadfoot/Session',
'intern/dojo/node!leadfoot/helpers/pollUntil'
], function (registerSuite, assert, require, util, Command, Session, pollUntil) {

registerSuite([   
    {
        name: 'testing_find_by_wait',

        test_create_form_on_web: function() {
            console.log('Create a form with account, number, number and formula fields')

            return this.remote
                .setFindTimeout(10000)
                .setWindowSize(1280, 960)
                .get("http://www.kgstew.com/waittest.html")
                .then(pollUntil('return document.getElementById("demo")', 10000))
                .findById('demo')
                    .click()
                    .end()

        }
    }
]);
});
like image 384
kgstew Avatar asked Oct 02 '14 18:10

kgstew


2 Answers

The element is being discovered just fine. Per the error, it is failing to click on the element. This is happening because the element is empty and has no style so it is zero size and cannot be clicked at the time you are trying to click on it. You need to wait for the element to exist and be visible before you can try to click on it.

like image 151
C Snover Avatar answered Oct 21 '22 09:10

C Snover


Thank you C Snover for your help getting this worked out.

I was misunderstanding how setFindTimeout() and pollUntil were working. They both look for elements to be present in the DOM (which they were) but if the element is not visible (ie style is display:none) when a click() command is issued, the test will fail.

What we wanted to do is wait for the element to be present after some kind of user action. Got the idea from C Snover to watch the element.offsetWidth for it to be greater than 0.

We created the following utility in our testing suite.

element_visible_by_class: function(elem) {
    return function(elem) {
        elem = document.getElementsByClassName(elem);
        if (!elem || elem.length == 0) { return null; }
        elem = elem[0];
        return (elem.offsetWidth > 0 && elem.offsetHeight > 0) ? elem : null;
     }  
},

Now from any test we can call .then(pollUntil(util.element_visible_by_class(), ['class_name'], 10000)) and it will wait until that element is visible on the page.

like image 31
kgstew Avatar answered Oct 21 '22 09:10

kgstew