Reputation: 2607
The sessionStorage is not properly set using the below script. I'm trying to set the storage in a page.evaluate
callback, but I'm not having any luck and my "complete" check endlessly loops. I've encountered the very same problem with casper, trying a similar pattern of evaluate and reload. I can't test because all ajax requests use sessionStorage to pick up the authorization JWT. I know I should have access to window in evaluate so I'm not sure why this isn't working.
var page = require("webpage").create();
var url = "http://xxxxxxxx.com";
var t0 = Date.now;
function onPageReady() {
var t1 = Date.now;
var elapsed = t1 - t0;
var htmlContent = page.evaluate(function () {
return document.documentElement.outerHTML;
});
console.log(htmlContent);
console.log("ELAPSED TIME: " , elapsed + "\n") ;
phantom.exit(0);
}
page.open(url, function (status) {
var sessionStorage = page.evaluate(function(){
sessionStorage.setItem('authorization','xxxxxxxxxxxxxxxxx');
//window.sessionStorage.setItem('authorization','xxxxxxxxxx');
window.sessionStorage.setItem('_USER','value');
window.sessionStorage.setItem('USERNAME','value');
window.sessionStorage.setItem('INTERNAL','value');
console.log(window.sessionStorage);
return sessionStorage;
});
t0 = Date.now;
console.log(JSON.stringify(sessionStorage));
console.log(JSON.stringify(window.sessionStorage));
function checkReadyState() {
setTimeout(function () {
var readyState = page.evaluate(function () {
return document.readyState;
});
if ("complete" === readyState) {
// checking if my ng-repeat has loaded
if (document.getElementsByClassName('quoteTr').length > 1){
console.log("ready!")
onPageReady();
} else {
console.log("script not complete")
checkReadyState();
}
} else {
checkReadyState();
}
});
}
checkReadyState();
});
Upvotes: 2
Views: 1415
Reputation: 61892
If you're setting the sessionStorage
inside of the page context (inside page.evaluate()
), then you need to retrieve it in the page context. Although, sessionStorage
exists outside of the page context, it is some dummy object which has no access to the page's sessionStorage
.
page.evaluate(function(){
sessionStorage.setItem('authorization','xxxxxxxxxxxxxxxxx');
});
var authorization = page.evaluate(function(){
sessionStorage.getItem('authorization');
});
console.log("authorization: " + authorization);
Since sessionStorage
is a non-primitive object, you can't pass it outside of the page context. You can only pass representations of it, such as its key-value pairs. For the docs:
Note: The arguments and the return value to the
evaluate
function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.Closures, functions, DOM nodes, etc. will not work!
The same is true in CasperJS.
On the subject of "looping". I see three problems with your code.
First Date.now
is a reference to a function. If you want the current time, then you have to call it as Date.now()
.
You're not giving PhantomJS much time to do any work. You're essentially using setTimeout()
without a second parameter which defaults to 0 which means the callback is immediately called. Try using a small timeout such as 50: setTimeout(function(){...}, 50)
.
You're trying to access document.getElementsByClassName('quoteTr')
outside of the page context, but document
is only a dummy object, so it will always return an empty array no matter what happens on the page. You have to use page.evaluate()
. CasperJS provides the casper.exists()
function for such as case.
I haven't exactly understood why you need to set some sessionStorage
values, but if you need to set them as soon as possible for the page, then you can try to employ two different strategies:
Open the page normally, set the values to the sessionStorage
and then load the page again so that the page's JavaScript picks up the values.
You can try to register to page.onLoadStarted
, page.onNavigationRequested
or page.onUrlChanged
events in order to set the session values as soon as possible.
Upvotes: 3