Skip to content
This repository has been archived by the owner on May 15, 2023. It is now read-only.

WebPage.onInitialized is not called when set #47

Open
tejacques opened this issue Feb 22, 2015 · 7 comments
Open

WebPage.onInitialized is not called when set #47

tejacques opened this issue Feb 22, 2015 · 7 comments

Comments

@tejacques
Copy link
Contributor

Bug

Setting the onInitialized function does not cause it to be called, as the check to call it is currently in the WebPage constructor (init function of WebPage.js).

Steps to Reproduce

run:

TrifleJS.exe onInitialized.js

onInitialized.js:

var page = webpage = require('webpage').create();
page.onInitialized = function() {
    console.log('should log');
};
// any url
page.open('about:blank');

Expected Output (PhantomJS)

should log

Actual Output (TrifleJS)

The PhantomJS spec says (http://phantomjs.org/api/webpage/handler/on-initialized.html):

This callback is invoked after the web page is created but before a URL is loaded. The callback may be used to change global objects.

The logic should be moved into the open function. This is actually a bit trickier than it looks at first glance because the PhantomJS spec allows you to change global objects on the page, which the .NET client will clear on calls to navigate. A callback needs to be set up to invoke the supplied function at the proper time after creating the page.

@tejacques
Copy link
Contributor Author

I think I've got something working for this using the Navigated event. I'm not sure if it's spec equivalent to PhantomJS because it won't fire on reload, but I'll try to do some testing and submit a PR.

tejacques added a commit to tejacques/trifleJS that referenced this issue Feb 23, 2015
…hile the document is loading using the Navigated event. Resolves sdesalas#47
@tejacques
Copy link
Contributor Author

There's actually another bug related to this. The toolset added to the window (json2 and ie tools) aren't actually available until the page onload event is fired. In PhantomJS they are available immediately because they are inserted when the page is created.

This can be fixed very easily by moving the AddToolset() call from DocumentCompleted to Navigated. The unhandled error tracking should also be moved.

@sdesalas
Copy link
Owner

sdesalas commented Mar 8, 2015

Hi @tejacques, like your fix. Will get to it ASAP.

@sdesalas
Copy link
Owner

sdesalas commented Mar 8, 2015

HI @tejacques,

Added a fix for this bug. Had to call page.onInitialized during the first part of DocumentCompleted event (instead of Navigated, but a bit earlier than before as I'm not waiting for all other js/css/img resources via window.onload). Reason for this is that I couldn't get access to global variables using page.evaluate during Navigated.

Thanks for your help and for the detailed test example.

My unit tests are running ok now. Let me know how you go.

@sdesalas
Copy link
Owner

sdesalas commented Mar 9, 2015

Btw. I noticed that if I move 'onInitialized' to the 'Navigated' browser event I can write to global context on the webpage (but not read as the DOM is not available yet).. might consider moving functionality there if PhantomJS behaves the same way.

@tejacques
Copy link
Contributor Author

In phantomJS onInitialized is called before the DOM is ready or any JS executes on the page.

Here's an example to test with:

TestPage.html

<!DOCTYPE html>
<html>
<head>
    <title>Test Page</title>
</head>
<body>
    <script>
        callPhantom({ hello: 'from script tag' });
        window.onload = function () {
            callPhantom({ hello: 'from onload' });
        }
    </script>
</body>
</html>

TestScript.js

var webPage = require('webpage');
var page = webPage.create();
page.onInitialized = function () {
    console.log("Initialized");
}
page.onCallback = function(data) {
    console.log('CALLBACK: ' + JSON.stringify(data));
  // Prints 'CALLBACK: { "hello": "world" }'
};
page.onConsoleMessage = function (msg) {
    console.log(msg);
};
page.evaluate(function () {
    callPhantom({ hello: 'world' });
});
page.open('http://localhost:port/path/to/TestPage.html', function (status) {
    phantom.exit();
});

PhantomJS Output:

>phantomjs path/to/TestScript.js
Initialized
CALLBACK: {"hello":"world"}
Initialized
CALLBACK: {"hello":"from script tag"}
CALLBACK: {"hello":"from onload"}

TrifleJS Output:

>trifleJS.exe path/to/TestScript.js
CALLBACK: {"hello":"world"}
CALLBACK: {"hello":"from script tag"}
Initialized
CALLBACK: {"hello":"from onload"}

Currently, TrifleJS isn't calling onInitialized at all unless a page is loaded, and onInitialized is called after the page runs, but before onload.

@sdesalas
Copy link
Owner

Hiya,

Thanks for the great test example, I've used it to determine the load order for main lifecycle events (including onLoadStarted and onLoadFinished) and got the following from PhantomJS:

onInitialized
onCallback: beforeopen
onLoadStarted
onInitialized
onCallback: script
onCallback: onload
onLoadFinished
page.open

I've replicated this order (except for the first event) in my unit tests so I dont break it later.

The event missing is the onInitialized event called at the very beginning (during page.evaluate() and before page.open()). My feeling with this one is that I'd rather leave it for now as I'll break a few things if I try to postpone initialization (before opening a remote page) in the same way.

@sdesalas sdesalas reopened this May 22, 2016
@sdesalas sdesalas reopened this May 22, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants