J. Ed
J. Ed

Reputation: 6742

cant get my angularJS app to work with phantomJS

Using latest phantomJS (1.9.7) on Win8 on my AngularJS (v. 1.2.9) application, I'm not able to interact with my application.
I keep getting the message InvalidElementStateError: {"errorMessage":"Element is not currently interactable and may not be manipulated".

When I call render(), I get an empty image;

If I add a timeout to my script before calling render(), I get a completely mangled view of my page:
enter image description here

for comparison, this is what it looks like in any other browser:
enter image description here

The script i've used to take the screen capture-

var page = require('webpage').create();
page.open('http://localhost/app/account#/login', function() {
    setTimeout(function() {
        page.render('login-phantom.png');
        phantom.exit();
    }, 1000);
});

has anyone else encountered anything like that?
what should I check for?

Upvotes: 2

Views: 5824

Answers (1)

Sylvan D Ash
Sylvan D Ash

Reputation: 1117

Timeout won't really help (unless you set it for a super long time) because network response speeds vary from time to time. The best option would be to have a variable that notifies when data loading (on the angular side) has completed e.g. $scope.dataStatus = 'ready'. Then you could add a data-status attribute to an element on the html and poll it from phantomjs side to see if data has loaded. You would do the polling inside page.evaluate on phantomjs.

Matsko has written a blog along those lines and some sample code

So your phantomjs code could look something like:

var page = require('webpage').create();
page.open('http://localhost/app/account#/login', function (status) {
    var delay, checker = (function() {
        var html = page.evaluate(function () {
            var status = document.getElementById('status');
            if(status.getAttribute('load-status') == 'ready') {
                return document.getElementsByTagName('html')[0].outerHTML;
            }
        });
        if(html) {
            clearTimeout(delay);
            page.render('login-phantom.png');
            phantom.exit();
        }
    });
    delay = setInterval(checker, 100);
});

While your html could be:

<html>
    <head>...</head>
    <body>
        <div id="status" load-status="{{ dataStatus }}"></div>
    </body>
</html>

Hope that helps

Upvotes: 3

Related Questions