问题
For example: I open a page with PhantomJS, evaluate an asynchronous script (e.g. ajax). When it succeeds, I want to let the phantom context (outside of page.evaluate()
) know that the asynchronous process is finished.
I don't want to use setTimeout
and setInteval
to wait and check continously in the phantom context that the process is finished.
回答1:
That is exactly what the onCallback and window.callPhantom() pair is for.
So, if you have an asynchronous call in the page context like an AJAX request, you can do this:
page.onCallback = function(data){
console.log("finished: " + data.text);
phantom.exit();
};
page.evaluate(function(){
var xhr = new XMLHttpRequest();
xhr.open("GET", "/");
xhr.onreadystatechange = function () {
var DONE = this.DONE || 4;
if (this.readyState === DONE){
window.callPhantom({text: this.responseText});
}
};
xhr.send();
});
The other way to use this is to add the call to your production JavaScript to make testing easier. If you're writing a web application it is sometimes complicated to find a selector which denotes when a page is fully loaded. To make testing such an application easier, you can have something like this in the page JavaScript:
finishOffPage(function callback(){
if (typeof window.callPhantom === "function") {
window.callPhantom({type: "loadFinished"});
}
});
Then you can write tests like this:
page.onCallback = function(data){
if (data.type === "loadFinished") {
// do some testing
}
};
page.open(url);
This is an example where such a thing can be added dynamically: wait for angular app to be fully rendered from phantom script
来源:https://stackoverflow.com/questions/28916699/is-there-a-way-to-listen-to-an-event-in-the-phantom-context-from-page-context