Tìm hiểu về Casperjs

1. **Tổng quan **

1.1 **Giới thiệu về PhantomJS **

PhantomJS là một trình duyệt web (headless browser) được sử dụng để tương tác với trang web một cách chủ động thông qua các câu lệnh mà không cần quan tâm tới giao diện.

1.2 **Giới thiệu về CasperJS **

1.2.1 Định nghĩa

CasperJS là tiện ích mã nguồn mở hỗ trợ cho việc viết test và viết script điều hướng (navigation scripting) được viết bằng ngôn ngữ Javascript cho PhantomJS WebKit.

1.2.2 Tính ứng dụng

  • Đơn giản hóa toàn bộ quá trình định nghĩa một kịch bản (navigation scenario)

  • Cung cấp các chức năng, phương thức & cú pháp hữu hiệu để thực hiện thao tác với trang web

    • Định nghĩa & sắp xếp thứ tự các bước điều hướng trình duyệt (browsing navigation)
    • Nhập form và đăng ký form
    • Clicking & following links
  • Chụp màn hình của 1 trang web hoặc 1 phần trang web

  • Kiểm thử remote DOM (mô hình đối tượng tài liệu)

  • Ghi lại log các sự kiện

  • Download các resource, bao gồm cả các resource ở dạng mã nhị phân

  • Hỗ trợ viết các hàm test và lưu kết quả test

  • Lấy nội dung trang Web

1.2.3 Cách cài đặt

  • Cài đặt CasperJS trên Windows

Để có thể cài đặt và sử dụng CasperJS thì bạn cần cài đặt cả PhantomJS.

  1. Download PhantomJS https://bitbucket.org/ariya/phantomjs/downloads
  2. Giải nén và đổi tên thành phantomjs
  3. Download CasperJS https://github.com/n1k0/casperjs/zipball/1.0.3
  4. Giải nén và đổi tên thành casperjs
  5. Copy paste thư mục phantomjs và casperjs vào C:\
  6. Thêm "C:\phantomjs\bin" và "C:\casperjs\batchbin" vào PATH trong Environment variable theo các bước sau:

window2.png

window3.png

window4.png

  • Cài đặt CasperJS trên Linux (Ubuntu)
  • Sử dụng git

      $ git clone git://github.com/n1k0/casperjs.git
      $ cd casperjs
      $ ln -sf `pwd`/bin/casperjs /usr/local/bin/casperjs
    
  • Sử dụng npm

      $ npm install -g casperjs
    
  • Khi cài đặt xong có thể kiểm tra version của phantomjs và casperjs

     $ phantomjs --version
     1.9.2
     $ casperjs
     CasperJS version 1.1.0-DEV at/Users/niko/Sites/casperjs,
     using phantomjs version 1.9.2
    

  • Cài đặt để lưu lại ảnh kết quả khi kiểm thử

  • Trong khi code file casperjs, nếu muốn chụp ảnh màn hình test, bạn có thể sử dụng "this.capture()" như sau:

      this.capture('home/casperjs/example/login_email_pass_wrong.png',{
      	top: 0,
      	left: 0,
      	width: 1000,
      	height: 1000
      });
    
  • "home/casperjs/example/" đường dẫn đến thư mục lưu ảnh

  • "login_email_pass_wrong.png" tên file mà bạn muốn lưu khi chụp lại

  • "top, left, width, height" để chỉnh kích thước ảnh

1.2.4 Cách sử dụng

  • Cấu trúc 1 đoạn casperjs đơn giản
// Khởi tạo casperjs
var casper = require('casper').create();
//Chạy casperjs với 1 URL, thực hiện get element, CSS, JSON...
casper.start('http://casperjs.org/', function() {
// to do something
});
// Gọi hàm run để bắt đầu chạy CasperJS
casper.run();
// Chạy bằng dòng lệnh
casperjs myapp.js

1.2.5 Một số API sử dụng trong CasperJS

  • Capture: chụp ảnh màn hình website
this.capture('google.png', {
top: 100,
left: 100,
width: 500,
height: 400
})
  • Fill : nhập vào 1 form với username, password
this.fill(“form”, {
username: username,
password: password
}, false);
  • waitFor(): Đợi cho đến khi điều kiện so sánh trả về true và thực hiện các bước tiếp theo
casper.waitFor(
function check() {
return this.evaluate(function() {
return document.querySelectorAll('ul.your-list li').length > 2;
});
}
);

1.2.6 Một số website viết về test bằng CasperJS

https://blog.codeship.com/casperjs-examples/

https://blog.newrelic.com/2013/06/04/simpler-ui-testing-with-casperjs-2/

http://fourword.fourkitchens.com/article/testing-drupal-casperjs

http://fourword.fourkitchens.com/article/using-casperjs-test-picturefill

http://mobiforge.com/design-development/automated-mobile-ui-testing-with-casperjs

2.** Ưu điểm & Nhược điểm của CasperJS**

2.1 Ưu điểm của CasperJS

  • Kiểm thử các module khiến cho việc pass hay fail rất rõ ràng
  • Có thể viết test trên CoffeeScript hoặc JavaScript
  • CasperJS nhanh, nhẹ, dễ cài đặt
  • Có hướng dẫn hữu ích cho người mới sử dụng
  • Với người không có kinh nghiệm lập trình cũng chỉ mất thời gian ngắn để có thể viết test trên CasperJS
  • Có thể dùng để test load-time-performance
  • Có thể dùng để test các web app có sử dụng Flash và AngularJS

2.2 Nhược điểm của CasperJS

  • CasperJS khó khăn để kiểm thử website trên nhiều trình duyệt cũng như các hệ điều hành khác nhau
  • Không mở giao diện, khiến tester khó theo dõi các step của testcase
  • Hay xảy ra timeout khi chạy test

3. So sánh CasperJS và Selenium Webdrive

sosanh2.png

4. **Demo **

  1. Đăng nhập vào trang http://mangania.jp/en

    • Đăng nhập với 3 trường hợp :

      • Đăng nhập với trường email và password trống.
      • Đăng nhập với trường email và password không hợp lệ.
      • Đăng nhập với trường email và password hợp lệ.
    • Chụp ảnh màn hình sau mỗi trường hợp.

  2. Lấy tất cả các ảnh và download các ảnh của trang 'http://mangania.jp/en/users/characters'

  3. Lấy tất cả các link có liên kết 'http://mangania.jp' ở đầu của trang web 'http://mangania.jp/en' Dưới đây là code thực hiện các chức năng trên :

// In order to download binary file, please disable web security in console mode
// @RUN: casperjs test --web-security=no mangania_test.js

// Default UI is smartphone display (based on screen size).
// We should specify screensize to get desktop screenshot.
casper.options.viewportSize = {width: 1366, height: 768};

casper.test.begin('Sign in Mangania', 9, function suite(test){
    // Store character images in global variable
    var character_images = [];

    // Login with blank email and password
    //casper.start('http://mangania.jp/en/',function(){
    casper.start('http://mangania.jp/en/users/login',function(){
        this.sendKeys('form#new_user input[name="user[email]"]',' ');
        this.echo('sendKeys email successfully');

        this.sendKeys('form#new_user input[name="user[password]"]',' ');
        this.echo('sendKeys pwd successfully');

        this.click('form#new_user input[name="commit"]');

        casper.waitForUrl(/mangania.jp/, function() {
            this.echo('Login button is clicked');
            this.capture('login_with_blank_email_and_pwd.png');
            test.assertExists('.alert.alert-danger');
            test.assertSelectorHasText('.alert.alert-danger', 'Invalid email or password.');
        });
    });

    // Login with invalid email and password
    casper.then(function() {
        this.sendKeys('form#new_user input[name="user[email]"]','[email protected]');
        this.sendKeys('form#new_user input[name="user[password]"]','linh');

        this.click('form#new_user input[name="commit"]');

        casper.waitForUrl(/mangania.jp/, function() {
            this.capture('login_with_invalid_email_and_pwd.png');
            test.assertExists('.alert.alert-danger');
            test.assertSelectorHasText('.alert.alert-danger', 'Invalid email or password.');
        });
    });

    // Login with valid account
    casper.thenOpen('http://mangania.jp/en/users/login',function(){
        this.sendKeys('form#new_user input[name="user[email]"]','[email protected]');
        this.sendKeys('form#new_user input[name="user[password]"]','testtest');

        this.click('form#new_user input[name="commit"]');

        //casper.waitForUrl(/mangania.jp/, function() {
            this.capture('login_with_valid_email_and_pwd.png');
          //  });

        casper.waitForSelector('div.alert-success', function(){

            test.assertExists('.alert.alert-success');
            test.assertSelectorHasText('.alert.alert-success', 'Signed in successfully.');
       });

    });

    // Access my page and characters page
    // Store all character images in global variable
    casper.then(function() {
        test.assertSelectorHasText('form > a.btn-info', 'My page')
        this.click('form > a.btn-info');

        casper.wait(2000, function() {
            this.capture('my_page.png');

            test.assertTextExists('Posted characters');
            this.clickLabel('Posted characters', 'a');

            casper.wait(2000, function() {
                this.capture('characters.png');

                character_images = casper.evaluate(function() {
                    var image_links = document.querySelectorAll('.character-list-item img.img-responsive.img-bordered');
                    return Array.prototype.map.call(image_links, function(e) {
                        return e.getAttribute('src');
                    });
                });
            });
        });
    });

    // Download images
    casper.then(function() {
        for (var i = 0; i < character_images.length; i++) {
            var image = character_images[i];
            this.download(image, 'character_' + image.substring(image.lastIndexOf('/')+1));
            this.echo("Download images success");
        }
    });

    //Get links of http://mangania.jp/ja/ web
    var getlink = "http://mangania.jp";
    var links = [];
    var regex = new RegExp("^(http[s]?:\\/\\/(www\\.)?|ftp:\\/\\/(www\\.)?|(www\\.)?){1}([0-9A-Za-z-\\[email protected]:%_\‌​+~#=]+)+((\\.[a-zA-Z]{2,3})+)(/(.)*)?(\\?(.)*)?");

    function getLinks() {
    var links = document.querySelectorAll('a');
    return Array.prototype.map.call(links, function(e) {
        return e.getAttribute('href');
    });
}
    casper.thenOpen('http://mangania.jp/en/');

    casper.then(function() {
    links = this.evaluate(getLinks);
    this.echo(links.length + ' links found:');
    var result = "";
    for(var i=0; i<links.length; i++){
      if(regex.test(links[i])){
    result += ' - ' + links[i] + ('\n');
      }
      else{
        result += ' - ' +  getlink + links[i] + ('\n');
      }
   }

    this.echo(result);
    test.assertUrlMatch(regex,'Found links http://mangania.jp')
});
    casper.run(function() {
        test.done();
    });
});
  • Cách chạy project
  1. Trong thư mục Casperjs tạo một file Mangania_casperjs.js

  2. Bật command line và thực hiện lệnh casperjs test --web-security=no Mangania_casperjs.js

     Vì code thực hiện download mã nhị phân nên phải thêm  --web-security=no.
    
     Nếu không download mã nhị phân bạn chỉ cần chạy câu lệnh casperjs test Mangania_casperjs.js
    
  3. Sau khi chạy commad line sẽ được kết quả như sau :

result_demo.png

result_demo2.png

4.1 Chạy project trên jenkins

Để chạy project trên Jenkins

  1. Tạo file XML bằng cách chạy câu lệnh

     casperjs test Mangania_casperjs.js --xunit=log2.xml
    
  2. Tạo project trên jenkins

create_project_jenkins.png

  • **Viết câu lệnh **

create2.png

Sau khi click [Build Now] sẽ có kết quả như sau

jenkins1.png

5. Kết luận

  • PhantomJS / CasperJS chạy hoàn hảo bằng command line, vì vậy nó rất phù hợp khi đóng vai trò smoke testing, cũng như là một phần của quy trình phát triển phần mềm trên một server test tích hợp liên tục.
  • Nếu ứng dụng web của bạn cần phải chạy trên một loạt các trình duyệt web, thì việc chạy các test giao diện người dùng chỉ với PhantomJS / CasperJS sẽ không giải quyết (bao phủ) được tất cả các vấn đề. Tuy nhiên, chúng hoàn toàn đáp ứng được việc thực hiện các test basic sanity checks (check những lỗi cơ bản nhất) trước khi viết các test chuyên sâu hơn.