Ethan
Ethan

Reputation: 2087

How To Detect True Page On Load Finished PhantomJS

I am trying to download a theme automatically on Wordpress by utilizing PhantomJS. As my script stands, the page is not evaluated until it has stopped loading, the problem is as follows:

When I try to click an element on the page, it is not yet visible because the query to their database still has to be returned. EVEN THOUGH the page has been considered to be done loading, there is one essential part that is still missing. Have a look below:

enter image description here

This page was rendered AFTER the install now button was supposed to be clicked. As you can see, the theme card has yet to even appear. Instead, the only thing that can be seen is the little spinner.

This little guy has been causing any theme-related script to become null objects, which is obviously very undesirable.

Does anybody have any idea how I can fix this issue? I've already tried setTimeout() but this is a VERY ugly method, and has actually never been successful in my testing. Thanks!

ADDED INFORMATION All of the functions for my program are executed after a set amount of time. This was accomplished by implementing the setInterval property. It works flawless, but the solution to my question is now how can I dynamically set the interval time as the functions execute?

Example of the code below:

    var steps = [
  function() {
    console.log('Going')
    page.open('http://google.com')
    //Does not need too much time. 
  },
  function() {
  console.log('Searching')
  page.evaluate(function() {
    //BIG Task List Here, Needs A lot of Time
  })
}]
//How the interval is set:

    setInterval(executeRequestsStepByStep, 250)
function executeRequestsStepByStep(){
  if (loading == false && steps[stepindex]) {
    steps[stepindex]()
    stepindex++
  }
  if (!steps[stepindex]) {
    phantom.exit()
  }
}
page.onLoadStarted = function() { loading = true }
page.onLoadFinished = function() { loading = false }

Any ideas on how we can accomplish this?

Upvotes: 1

Views: 628

Answers (2)

Vara Prasad
Vara Prasad

Reputation: 497

As Vaviloff said that you can follow those approaches. But I have a solution which is useful for me in most cases like above scenario is waitFor https://github.com/ariya/phantomjs/blob/master/examples/waitfor.js

this script will exit if it takes 30seconds or more, else it will continue with next steps to execute whenever the loader disappears

waitFor(function() {
    return page.evaluate(function() {
        if (loader disappears) {
            return true;
        } else {
            return false;
        }
    });
}, function() {
    // do your next steps here
}, 30000);

Hope this will help you.

Upvotes: 1

Vaviloff
Vaviloff

Reputation: 16838

One approach to wait for full page load would be to listen to page.onLoadFinished callback and if it is not called again for N seconds consider the page has done loading.

Another approach would be to compare page.onResourceReceived and onResourceRequested call count (maybe taking onResourceError into account). But tedious and unreliable.

Both options above won't work for ajax requests because obviously it's are not a part of initial page load cycle.

I suppose your spinner is generated for the duration of an ajax request, so probably the best bet would be to wait for the spinner's disappearance. I would also suggest including a separate larger safety timeout of, say, 30 seconds, after which phantom.exit(1) would be called. So your script won't hang indefinitely in case this one ajax call never finishes.

Upvotes: 1

Related Questions