How to use callbacks in phantomjs - phantomjs

I am using phantomjs for testing one web application. but i am facing problem with page load means sometimes phantom script executed but dom element is not loaded. How to use callbacks for sorting this kind of issues
resourceReceived(request),resourceRequested(resource),resourceError(resource)

If you want to execute code after the page has finished loading, use this:
page.onLoadFinished = function()
{
// function body
var pageTitle = page.evaluate(function() {
console.log('Page Name: ' + document.title);
return document.title;
});
};

Related

Make PhantomJs wait for an Ajax Request before generating a pdf

Using the example from phantomjs works like a charm
https://github.com/ariya/phantomjs/blob/master/examples/rasterize.js?utm_content=bufferda3e0&utm_source=buffer&utm_medium=twitter&utm_campaign=Buffer
However what happens if the url needs to make an Ajax request in order to load it's data? Can I fire a custom event so the pdf is only generated then ?
(I don't want to guess how much time the request will take and set a timeout)
The common solution to this problem is to wait for an element that will appear on the page after AJAX request has finished.
Include the waitFor function from this example and wait for the first function passed as argument to waitFor to return true, then it will run the function passed as the second argument.
page.open("https://example.com/ajaxified/", function (status) {
waitFor(function() {
return page.evaluate(function() {
return document.querySelectorAll(".report").length > 0;
});
}, function() {
page.render("report.pdf");
phantom.exit();
});
});

Wait until page is fully loaded with selenium and intern js

I am trying to create a UI automation test with intern js , but i m getting problem on waiting until the page is fully loaded. My code starts searching for element before the page is loaded. Can some one help me on this.
My code:
define([
'intern!object',
'intern/chai!assert',
'Automation/ConfigFiles/dataurl',
'Automation/pages/login/loginpage',
'intern/dojo/node!fs',
'intern/dojo/node!leadfoot/helpers/pollUntil'
], function (registerSuite, assert,dataurl, LoginPage,fs,pollUntil) {
registerSuite(function () {
var loginPage;
var values;
return {
setup: function () {
var data = fs.readFileSync(loginpage, 'utf8');
json=JSON.parse(data);
console.log('###########Setting Up Login Page Test##########')
this.remote
.get(require.toUrl(json.locator.URL))
.then(pollUntil(this.remote.findById('uname').isDisplayed(),6000)// here i want to wait until page is loaded
.waitForDeletedByClassName('loading').end().sleep(600000)// here i want to wait until loading component is disappered
values = json.values;
loginPage = new LoginPage(this.remote,json.locator);
},
'successful login': function () {
console.log('##############Login Success Test############')
return loginPage
.login(values.unamevalue,values.pwdvalue)
},
// …additional tests…
};
});
});
I m trying to use pollUntil . But I m not sure weather I should use it or not.
pollUntil is a good thing to use here, but it doesn't look like you're actually waiting for polling to finish. Your setup method needs to return the command chain that includes pollUntil so that Intern will know it needs to wait, something like:
var setupPromise = this.remote
.get(require.toUrl(json.locator.URL))...
values = json.values;
loginPage = new LoginPage(this.remote, json.locator);
return setupPromise;
Alternatively, you could pass your LoginPage class the chain:
var setupPromise = this.remote
.get(require.toUrl(json.locator.URL))...
values = json.values;
loginPage = new LoginPage(setupPromise, json.locator);
In this case Intern won't wait for setup to complete, but your LoginPage code will implicitly wait for the setupPromise to complete before doing anything else. While this will work, the intent isn't as clear as in the previous example (e.g., that Intern should wait for some setup process to complete before proceeding).

Phantomjs dump dom object

I'm new to Phantomjs. For debugging on a remote server, I often want to dump a DOM object to look at the structure (similar to Data::Dumper in Perl). This currently is for scraping a couple of sites.
I've thought JSON.stringify may help with this, but it still displays an object name like "[object HTMLDocument]"
Edit: I have also looked at JavaScript: how to serialize a DOM element as a string to be used later? , but I can't seem to inject jquery in phantomjs (still looking for a solution to that, and would prefer no depencencies), and the other answer doesn't seem to work. As I assume it would be a common case for Phantom to analyse the DOM, I thought it would be common for phantom users to have a solution to this.
var page = require('webpage').create();
var system = require('system');
page.onConsoleMessage = function(msg) {
console.log( msg );
}
page.open('http://www.test.com', function(status) {
if(status !== "success") {
console.log( status );
} else {
page.evaluate(function() {
var headline = document.querySelectorAll('div');
console.log( JSON.stringify( headline ) ); // HERE???
});
}
phantom.exit();
});
Is there any way to do this, or am I approaching this wrong ?
in page.evaluate(), you can use XMLSerializer.serializeToString() to convert whatever DOM node you want to string.
page.evaluate(function() {
var s = new XMLSerializer();
return s.serializeToString(document.getElementById('div'));
});
I haven't tried it with "querySelectorAll", since it may return array instead of standalone DOM node, but it definitely works for DOM nodes.
MDN Link

How to run a server url in a Dojo DOH test

The Dojo DOH examples and tutorials do not seem to cover this case. I have a server url for which I want to write tests. I want the target page to show in the TestPage tab and then have multiple tests run against it. The closest example I could find is an html file that defines some tests and then a widget in the body, but I can't do that with a url over which I do not have control. I have done it with a page that fires the robot.init function, but I would like to use the test runner page.
I finally came up with this:
...
doh.register("login tests", [
{
name: "load",
timeout: 20000,
runTest: function(){
var d = new doh.Deferred();
testPage = dom.byId("testBody");
console.log("in load, testPage: " + testPage);
doh.showTestPage();
testPage.src = path;
robot.sequence(function() {
console.log("in load, sequence: ");
testpageBody = testPage.contentDocument.getElementsByTagName("body")[0];
console.log("in load, testpageBody: " + testpageBody);
var bdy = query(".headerFooterLoaded", testpageBody)[0];
console.log("in load, headerFooterLoaded: " + bdy);
if (!!bdy) {
d.callback(true);
} else {
d.errback(new Error("Node with class 'headerFooterLoaded' not found."));
}
}, 8000);
return d;
}
},
...
I tried to catch an iframe onload event, but had no luck.
Hope this helps someone

Mink: wait for page to load in #BeforeStep

I want to execute some javascript on page in #BeforeStep hook that depends on jQuery. However jQuery is not defined at that time, in fact page is blank.
Here's what I am trying to achive:
/**
* #BeforeStep #javascript
*/
public function registerAjaxEventHandlers()
{
$javascript = <<<JS
window.jQuery(document).ready(function () {
if (window.__ajaxStatus !== undefined) {
return;
}
window.__ajaxStatus = 'none';
$('body').ajaxStop(function() {
window.__ajaxStatus = 'idle';
});
$('body').ajaxStart(function() {
window.__ajaxStatus = 'in-flight';
});
});
JS;
//$this->getSession()->wait(5000, 'window.jQuery !== undefined');
$this->getSession()->executeScript($javascript);
}
I figured maybe I could wait for the page to load jQuery first (commented line), but it is not true. Seems like execution is halted until that hook is processed.
What is the right place in behat/mink ecosystem to execute javascript on page?
How about this?
$this->getSession()->wait(5000, 'typeof window.jQuery == "function"');
Your javascript is execute before the step, i.e. before the page is loaded. But if you load a page, all kinds of ondomload/pageload JavaScript will be firing already as well.
If you are happy to run it after the initial page, you can use #AfterStep like this:
/**
* #AfterStep
*/
public function set_selenium_css_selector (Behat\Behat\Event\StepEvent $event) {
$this->getSession()->wait(10, 'jQuery ("body").addClass ("selenium")');
}