How to maintain session in casperjs? - casperjs

In CasperJS how do you maintain session when using casper.thenOpen()
For example:
var casper = require('casper').create();
casper.start('http://chaseonline.com/', function() {
this.echo(this.getTitle());
this.evaluate(function() {
document.getElementById("userid").value = "a#b.com";
document.getElementById("password").value = "asdf";
});
this.click("#btnSubmit");
});
casper.thenOpen('http://chaseonline.com/section/1/module/2/abc.jsp', function() {
// now this page never loads because the page requires a logged in session
// but casperjs doesn't appear to automatically propagate the session
this.echo(this.getTitle());
});
casper.run();

The session is still open in your example. Probably you are not logged in correct.
Could be if it works Step by step (seems the site i see is not the one in your example, there is no login):
var casper = require('casper').create();
var x = require('casper').selectXPath;
casper.start('http://youraddess.com/', function() {
casper.then(function() {
casper.waitForSelector(x("xpath_selector"));
});
var data = {};
casper.then(function() {
data["//input[#id='userid']"] = "a#b.com";
data["//input[#id='password']"] = "asdf";
casper.fillXPath(x("//form[]"), data, false);
});
casper.then(function() {
casper.click(x("//button[#id='btnSubmit']"));
});
casper.then(function() {
casper.waitWhileSelector(x("xpath_selector"));
});
});
casper.thenOpen('http://chaseonline.com/section/1/module/2/abc.jsp', function() {
// now this page never loads because the page requires a logged in session
// but casperjs doesn't appear to automatically propagate the session
casper.then(function() {
casper.echo(this.getTitle());
casper.capture('test.png');
});
});
casper.run();
The session is till the run() always the same. There are possiblities to open new ones, but thats hard.

Related

CasperJS: clicking checkbox not triggering events as it does in browser

I am trying to automate a process in CasperJS. However, I am facing some discrepancy between the behavior on a real browser vs the same in CasperJS.
Update: Process works fine with slimerJS but gives issue with headless
Here is my script:
var casper = require('casper').create({
"waitTimeout": 10000
});
var inputElements = {
"url": "http://www.jabong.com/incult-Tapered-Jeans-In-Indigo-1032119.html?pos=4",
"size": "34",
"address": {
"email": "someemail#xyz.com"
}
}
casper.options.viewportSize = {width: 1679, height: 902};
casper.start(inputElements.url, function (){
this.wait(10000, function (){
console.log("loaded");
})
});
var x = require('casper').selectXPath;
var sizeToSelect = inputElements.size;
// select size
casper.thenClick(x("//*[contains(#class,'size-desktop')]//"+
"li[contains(#class,'first') and contains(#class,'popover-options')]//"+
"span[contains(text(),'"+sizeToSelect+"')]/"+
".."));
// add to bag
casper.thenClick(x("//*[#id='add-to-cart']"));
// view cart
casper.thenClick(x("//*[#id='header-bag-sec']/a"))
// take a screenshot
casper.then(function() {
console.log("saving screenshot");
this.capture('../../1_view_cart.png');
});
casper.then(function() {
console.log('clicked ok, new location is ' + this.getCurrentUrl());
});
// place order
casper.then(function (){
this.click("[href='https://www.jabong.com/checkout/']");
})
// take a screenshot
casper.then(function() {
console.log("saving screenshot");
this.capture('../../2_address_details.png');
});
casper.then(function (){
this.sendKeys("#login-email", inputElements.address.email);
})
casper.then(function (){
this.click("#do-guest-checkout");
});
// take a screenshot
casper.then(function() {
console.log("saving screenshot");
this.capture('../../3_guest_checkout.png');
});
casper.waitFor(function check() {
return this.evaluate(function() {
return document.querySelector('#btn-login-checkout').textContent == "Continue as Guest";
});
}, function then() {
this.click('#btn-login-checkout');
});
casper.run();
On the last page, clicking on checkbox "Checkout as Guest" on a browser removes the password input field and changes the text of the Login button to "Continue as Guest". Attached screenshot:
However, in CasperJS, the password input field and the Login button are not changing. Any idea what am I doing wrong ?

request hangs on sails error

If you make a request to sails via supertest, the response hangs if you return an error.
Here, we have already lifted sails, and will run this as an integration test against a live db.
var sails = require('sails').lift();
var request = require('supertest');
var app = sails.hooks.http.app;
describe('The creation of a model',function(){
it('should not create a duplicate',function(done){
var user = request.agent(app);
user
.post('/api/create')
.end(function(err,res){
//never gets here, your test will hang
done();
});
});
});
//controller.js
module.exports = {
// /api/create routes here
create:function(req,res){
var params = {
name:"invalid"
};
SomeAction(params,function(err,results){
if (err) {
//the problem is here.
return err;
}
res.json(results);
});
}
};
If you make a supertest request to sails and the function just returns a value, ie. you don't use res.send() or res.json() it will hang the request for supertest. Here's the right way to do it:
var sails = require('sails').lift();
var request = require('supertest');
var app = sails.hooks.http.app;
describe('The creation of a model',function(){
it('should not create a duplicate',function(done){
var user = request.agent(app);
user
.post('/api/create')
.end(function(err,res){
//never gets here, your test will hang
done();
});
});
});
//controller.js
module.exports = {
// /api/create routes here
create:function(req,res){
var params = {
name:"invalid"
};
SomeAction(params,function(err,results){
if (err) {
//you need to send a response to the
res.json({
error:"an error occured"
});
}
res.json(results);
});
}
};

CasperJS can't open link.href

I have a link button on the page:
<a id="quote" href="quote.html" target="_blank">Quote</a>
At first I click the link:
casper.thenClick('#quote');
But I can't capture the pop-up window. So I get the url of the link and open it in current window:
var url = '';
function getQuoteStartUrl() {
var link = document.querySelector('a#quote');
return link.getAttribute('href');
}
casper.thenOpen(url, function() {
this.echo(url);
this.echo(this.getTitle());
});
The url is correct but the page is empty. Then I try this:
var url = 'http://quote.html';
casper.thenOpen(url, function() {
this.echo(url);
this.echo(this.getTitle());
});
It works.
Finally I know why it doesn't work: It bind steps before the function call. So I try this:
casper.then(function() {
this.echo(url);
this.thenOpen(url);
this.echo(this.getTitle());
});
It works too.
Could you try out the following?
var url = '';
casper.then(function() {
url = this.getElementAttribute('a#quote', 'href');
});
casper.thenOpen(url, function() {
this.echo(url);
this.echo(this.getTitle());
});
It looks as though you may not be setting the url before trying to load it.

subpage loaded through ajax is killing jquery functionality

I'm working on a site, http://teneo.telegraphbranding.com/, and I am hoping to load the pages via ajax so that the sidebar and its animation remain consistent.
When the 'About' link is clicked I need it to load about2.php via a jquery ajax function. But I'm not having any luck. When I can get the page to load via ajax it kills all the jquery functionality on the page. From what I've read I think I need to call the jquery upon successful completion of the ajax call.
I've tried everything it seems and can't get it work. What I need is about2.php to load when the link is clicked and the jquery to dynamically size the divs, like it does on the homepage.
I tried this, but it won't even load the page:
//Dropdown
$(document).ready(function () {
var dropDown = $('.dropdown');
$('h3.about').on('click', function() {
dropDown.slideDown('fast', function() {
var url = 'about2.php'
$.get(url, function(data) {
//anything in this block runs after the ajax call
var missionWrap = $('#mission-wrap');
var w = $(window);
w.on('load resize',function() {
missionWrap.css({ width:w.width(), height:w.height()});
});
var missionContent = $('#mission-content');
var w = $(window);
w.on('load resize',function() {
missionContent.css({ width:w.width() - 205 });
});
});
});
});
});
And then this loads the page, but kills all the jQuery associated with it:
var dropDown = $('.dropdown');
$('h3.about').on('click', function() {
dropDown.slideDown('fast', function() {
$('#index-wrap').load('/about2.php');
});
});
Thank you very much.
I also tried this and it just broke everything:
$(document).ready(function () {
var dropDown = $('.dropdown');
$('h3.about').on('click', function () {
dropDown.slideDown('fast', function () {
$.ajax({
type: 'GET',
url: 'about2.php',
success: function () {
var missionWrap = $('#mission-wrap');
var w = $(window);
w.on('load resize', function () {
missionWrap.css({
width: w.width(),
height: w.height()
});
});
var missionContent = $('#mission-content');
var w = $(window);
w.on('load resize', function () {
missionContent.css({
width: w.width() - 205
});
});
};
});
});
});
});
This should work.
function resize_me () {
var w = $(window);
var missionWrap = $('#mission-wrap');
var missionContent = $('#mission-content');
missionWrap.css({ width:w.width(), height:w.height()});
missionContent.css({ width:w.width() - 205 });
}
//Dropdown
$(document).ready(function () {
$(window).on('load resize', function () {
resize_me();
});
var dropDown = $('.dropdown');
$('h3.about').on('click', function() {
dropDown.slideDown('fast', function() {
var url = 'about2.php'
$.get(url, function(data) {
resize_me();
});
});
});
}
I believe that the problem was that the load event that you were attaching to the window object was not being triggered by the successful load of the $.get.
This is a rough outline of how to structure your application to handle this correctly.
Assuming your HTML looks something like this:
<html>
...
<div id="index-wrap">
<!-- this is the reloadable part -->
...
</div>
...
</html>
You need to refactor all the jQuery enhancements to the elements inside #index-wrap to be in a function you can call after a reload:
function enhance(root) {
$('#some-button-or-whatever', root).on('click', ...);
}
(I.e. look up all the elements under the root element that was loaded using AJAX.)
You need to call this function when the page is first loaded, as well as after the AJAX call in the completion callback:
$('#index-wrap').load('/foo.php', function() {
enhance(this);
});
You can also potentially get rid of some of this using delegated ("live") events, but it's best to hit the jQuery documentation on how those work.
As for events bound to window or DOM elements which aren't loaded dynamically, you shouldn't need to rebind them at all based on which subpage is loaded, just check which of your elements loaded is in a handler that you set up once:
$(window).on('load resize', function() {
var $missionContent = $('#missionContent');
if ($missionContent.length) {
$missionContent.css(...);
}
});

casperjs click() a form element to submit, wait, run queries on next page?

I would like to click a submit button, wait for the next page to load, then obtain html on that second page.. I do the start, then and run, but the then step is still run on the first page. Any ideas?
var casper = require('casper').create();
var site = 'http://www.example.com';
var data = {};
casper.start(site, function() {
this.evaluate(function() {
$('input[type="submit"]:first').click();
});
});
casper.then(function() {
data.body = this.evaluate(function() {
var rows = $('#content table:first tbody tr');
var listings = rows.eq(3).text();
var count = rows.eq(4).text();
return {
listings: listings,
count: count
};
});
});
casper.run(function() {
this.echo(data.body.listings);
this.exit();
});
This only partially solves your problem, but you can confirm that you've made it to the second page using waitFor. For example:
this.waitFor(function check() {
return (this.getCurrentUrl() === PAGE_2_URL);
},
function then() { // step to execute when check() is ok
this.echo('Navigated to page 2', 'INFO');
},
function timeout() { // step to execute if check has failed
this.echo('Failed to navigate to page 2', 'ERROR');
});
Its a good idea use waitForResource to wait the page load finished, see documentation here documentation
example:
casper.waitForResource(function checkAuth(validcredentials) {
return validcredentials;
}, function onReceived() {
if (authTitle !== this.getTitle()) {
this.log('AutenticaĆ§Ć£o realizada com sucesso, aguarde...');
} else {
// this.capture('pic3.png');
this.log('Usuario ou senha invalidos!', 'ERROR');
this.die('User or password invalids!', 1); }
});
I have a similar problem with doubleclick. Make sure the click event is actually fired. I suspect this is the cause of running the next step within the same content.

Resources