In order to be effective and useful, an automated test should:

  •   be 100% accurate
  •   be scalable
  •   be at least twice as fast as manual testing
  •   be easy to write and run

Writing automated tests takes time, time in which you could have done the test manually. So when you write the test keep in mind that you want to reuse it. Tests being very different, you want to make your test as modular as possible. This is very simple with javascript and can simply be done by keeping every test inside a function.

First thing to do is to set a url variable to get it from the command line. Then we set up some viewport sizes based on our media queries and then take screenshots, which we will be saving in the screenshots folder:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
var BASE_URL = "http://"+casper.cli.get('url');

var viewportSizes = [
    [1500,900],
    [1280,800],
    [1024,768],
    [600,1024],
    [320,568]
]

function screenshots(page){
    casper.each(viewportSizes, function(self, viewportSize, i) {
 
	    // set two vars for the viewport height and width as we loop through each item in the viewport array
	    var width = viewportSize[0],
	        height = viewportSize[1];
	 
	    //give some time for the page to resize
	    casper.wait(1, function() {
	 
	        //set the viewport to the desired height and width
	        this.viewport(width, height);
	 
			casper.viewport(width, height).then(function() {
	 
	              this.capture('screenshots/'+page+'-'+width+'.png')
	
	        });
	    });
    
	});
	casper.viewport(1500,900);
}

Then we navigate through our site easily with casper, but as modular as possible:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
function to_homepage(){
	// Go to homepage
	casper.thenClick('.logo', function() {
	    this.test.info('Current location is ' + this.getCurrentUrl());
		this.test.pass('Homepage in');
		screenshots("homepage")
	});
}

function login_page(){
	
	// Go to login page
	casper.thenClick('li.login',function() {
		this.test.pass('login page was loaded');
		screenshots("login-page")
	});
}

function register_page(){
	
	//Go to register page
	casper.then(function() {
	    this.click('.register');
		this.test.pass('register page was loaded');
		screenshots("register")
	});
	
	// Register for a new account	
	// Fill login form and submit
	casper.then(function() {
	    this.test.info('Current location is ' + this.getCurrentUrl());
	    this.fill('#form-validate', {
	        'firstname': 'automated',
	        'lastname': 'test',
	        'email': (Math.random()+1).toString(36).substring(7)+'@company.net', //generate a random email
	        'password': 'johndoe123',
	        'confirmation': 'johndoe123'
	    }, true);
		this.test.pass('form populated');
	    this.test.info('Current location is ' + this.getCurrentUrl());
		this.test.pass('Registered');
		screenshots("register-populated")
	});
}

function account_page(){
	
	// Account dashboard welcome
	casper.then(function() {
	    //this.test.assertTextExists('Hello, stamba stambic!');
		this.test.assertTextExists('Hello, automated test!', 'page body contains "Hello, automated test!"');
	    this.test.info('Current location is ' + this.getCurrentUrl());
		this.test.pass('Dashboard in');
		screenshots("account-dashboard")
	});
}

function category_page(){
	
	//go to category
	casper.then(function() {
		this.click('#nav-desktop a[data-menu="1"]');
		this.click('.submenu-desktop[data-submenu="1"] a');
	});
	
	//Check category
	casper.then(function() {
		this.test.assertTextExists('Category name');
	    this.test.info('Current location is ' + this.getCurrentUrl());
		this.test.pass('Main Category loaded ok');
		screenshots("category")
	});
}

function add_product(){
	// Add a product to basket
	casper.thenClick('.category-new-options .small', function() {
		casper.waitForSelector("#mini-cart-buy", function() {
		    this.test.info('Current location is ' + this.getCurrentUrl());
			this.test.assertTextExists('Added to your bag');
			this.test.pass('Product added successfully');
		})
	});
}

function cart_page(){
	
	// Go to cart page
	casper.waitForSelector("#mini-cart-buy, function() {
		casper.thenClick('#mini-cart-buy', function() {
			this.exists('#shopping-cart-totals-table');
		    this.test.info('Current location is ' + this.getCurrentUrl());
			this.test.pass('Cart page loaded fine');
			screenshots("cart")
		});
	})
}

function checkout_page(){
	
	// Go to checkout page
	casper.thenClick('.checkout-types > li:nth-child(1) > button:nth-child(1)', function() {
		this.test.assertTextExists('Billing address');
	    this.test.info('Current location is ' + this.getCurrentUrl());
		this.test.pass('Checkout page loaded ok');
		screenshots("checkout")
	});
}

function order_user_logged(){
	
	// Make a test order
	casper.then(function() {
		casper.waitForSelector('#onestepcheckout-form', function() {
			this.fillSelectors('#onestepcheckout-form', {
		        'input[id="billing:firstname"]': 'stamba',
		        'input[id="billing:lastname"]': 'stambic',
		        'input[id="billing:telephone"]': '12344534',
		        'input[id="billing:postcode"]': '432323'
		    }, false);
	    })
		 
	    casper.waitForSelector("#sagepaydirectpro_cc_type", function() {
			this.fillSelectors('#onestepcheckout-form', {
		        '#sagepaydirectpro_cc_owner': 'Fizipit o Moyazoci',
		        'select[id="sagepaydirectpro_cc_type"]': 'VISA',
		        'input[id="no_gift_message"]': true,
		        'input[id="agreement-1"]': true
		    }, true);
	    })
		this.test.pass('form populated');
	});
	
	casper.thenClick("#onestepcheckout-place-order", function(){
		casper.wait(1000, function(){
			casper.capture("screenshots/placingorder.png")
		})
	})
}

function order_user_guest(){
		// Make a test order
	casper.then(function() {
		casper.waitForSelector('#onestepcheckout-form', function() {
			this.fillSelectors('#onestepcheckout-form', {
		        'input[id="billing:firstname"]': 'stamba',
		        'input[id="billing:lastname"]': 'stambic',
		        'input[id="billing:street1"]': 'Lambada is a good music'
		    }, false);
	    })
		 
	    casper.waitForSelector("#sagepaydirectpro_cc_type", function() {
			this.fillSelectors('#onestepcheckout-form', {
		        '#sagepaydirectpro_cc_owner': 'Fizipit o Moyazoci',
		        'input[id="no_gift_message"]': true,
		        'input[id="agreement-1"]': true
		    }, true);
	    })
		this.test.pass('form populated');
	});
	
	casper.thenClick("#onestepcheckout-place-order", function(){
		casper.wait(1000, function(){
			casper.capture("screenshots/placingorder.png")
		})
	})
}

function success_page(){
	
	// Order is successful
	casper.then(function() {
		casper.wait(5000, function(){
			screenshots("success")
		    this.test.info('Current location is ' + this.getCurrentUrl());
			this.test.pass('On the success page now');
		})
	});
}

You can see that we are going from homepage, making an account, adding to cart and submitting and order. This is how we call these functions with casper:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
casper.start().viewport(800,900).thenOpen(BASE_URL, function() {
	console.log(BASE_URL)
    this.test.pass('Home was loaded');
    
    to_homepage();
    login_page();
    register_page();
	account_page();
	category_page();
	add_product();
	cart_page();
	checkout_page();
	order_user_logged();
	success_page();

	
});

casper.run(function() {
    this.test.done();
});

As you can see, keeping the test modular enables us to exclude steps by just commenting out the functions called. If we just want to test the login and not the register, comment out the register(). Ideally you would have 10-20 functions for every situation possible and some test classes across all your websites for some dom elements like checkout buttons and add to cart.

In the end, to run this file just type in the command line: casperjs test test.js –url=”domain.com”. Watch the command line for errors and check your screenshots folder.