Cài đặt và sử dụng Protractor cơ bản

Thursday, October 04, 2018
Edit this post


Chào mừng các bạn đến với bài hướng dẫn cơ bản cách cài đặt và sử dụng Protractor nhằm phục vụ cho việc kiểm thử tự động cho các ứng dụng Angular và AngularJS.

What is Protractor?

Protractor is an end-to-end test framework for Angular and AngularJS applications. Protractor runs tests against your application running in a real browser, interacting with it as a user would.

Protractor là một framework phục vụ end-to-end testing cho các ứng dụng Angular và AngularJS. Protractor sẽ kiểm thử ứng dụng trong một trình duyệt thật sự, tương tác với ứng dụng như một user bình thường.


What will happen if we user Protractor on Non-Angular applications?

For example, I tried to run my scripts on facebook.com. Facebook web is not an Angular application, then I got this message:



How to download & install JDK?


▸*Why JDK? Selenium server requires this.
▸Go to https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
▸At Oracle download page, click on radio button "Accept License Agreement".
▸Choose the specific JDK for your OS platform. For me, I choose "Windows x64" because I am using a 64-bit OS version.
▸Wait for the download to finish.
▸Click on the setup file and run.
▸After the installation, open cmd, type "java -version" to check if the installation succeeds.


How to download & install Protractor?

Protractor is a Node.js program. To run, you will need to have Node.js installed. You will download Protractor package using npm, which comes with Node.js.

Protractor là một chương trình Node.js. Do đó, bạn sẽ cần phải cài Node.js trước. Sau đó, bạn tải Protractor package thông qua npm (đi kèm với Node.js).

* This requires an Internet connection.
▸Download and install nodejs from https://nodejs.org/en/download/.
▸After done installing Node.js, type "npm -version" in cmd. If you can see the Node.js version number, then you're good to go.
▸Open cmd, type "npm install -g protractor" to start installing Protractor.
▸After done installing Protractor, type "protractor --version" in cmd. If you can see the Protractor version number, then you're good to go.
▸In cmd, type "webdriver-manager update" to download neccessary web drivers.
▸In cmd, type "webdriver-manager start" to start the Selenium server on port 4444 by default.


How to download and install Node.js and Protractor

How to run a basic script using Protractor?

Protractor needs two files to run, a spec file and a configuration file.

Để chạy được Protractor, bạn sẽ cần ít nhất 2 file *.js. Một file spec và một file configuration. File spec thường sẽ chứa các script chính, bao gồm các step và expected của test case. File configuration chứa các cài đặt cho project.

*Ví dụ file spec.js



// spec.js
describe('Protractor Demo App', function() {
  it('should add one and two', function() {
    browser.get('http://juliemr.github.io/protractor-demo/');
    element(by.model('first')).sendKeys(1);
    element(by.model('second')).sendKeys(2);

    element(by.id('gobutton')).click();

    expect(element(by.binding('latest')).getText()).
        toEqual('5'); // This is wrong!
  });
});


The describe and it syntax is from the Jasmine framework. browser is a global created by Protractor, which is used for browser-level commands such as navigation with browser.get.

Đoạn script trên được viết theo cú pháp của Jasmine framework, nó sẽ tuần tự làm các công việc như sau:

▸Mở ứng dụng demo Angular tại địa chỉ: http://juliemr.github.io/protractor-demo/ bằng trình duyệt. ▸Ứng dụng này rất đơn giản, có 2 ô để nhập số, một combo box để chọn operator (+, -, *, /...), mặc định là phép +, và một button mà khi bấm vào đó sẽ cho ra kết quả.
▸Câu lệnh tiếp theo tìm input field có thuộc tính ng-model="first" và nhập vào số 1.
▸Câu lệnh tiếp theo tìm input field có thuộc tính ng-model="second" và nhập vào số 2.
▸Câu lệnh element(by.id('gobutton')).click(); tìm button có id="gobutton" và bấm vào nó và tính ra tổng của 2 số vừa nhập.
▸Câu lệnh expect(element(by.binding('latest')).getText()).toEqual('5'); sẽ expect kết quả trả về là 5, nhưng thực tế là 3. Do đó, có thể thấy trước là test case này sẽ bị failed.

Để biết được các thuộc tính của các HTML elements. Trong Chrome, nhấn chuột phải vào element muốn xem, chọn "Inspect":


Ví dụ file conf.js


// conf.js
exports.config = {
  framework: 'jasmine',
  seleniumAddress: 'http://localhost:4444/wd/hub',
  specs: ['spec.js']
}


This configuration tells Protractor where your test files (specs) are, and where to talk to your Selenium Server (seleniumAddress). It specifies that we will be using Jasmine for the test framework. It will use the defaults for all other configuration. Chrome is the default browser.

File conf.js chứa các định nghĩa cho project. Như file trên định nghĩa cú pháp của script, địa chỉ của server Selenium và file script để chạy (spec.js). Nó cũng chỉ ra rằng chúng ta sẽ sử dụng Jasmine cho test framework. Các configuration khác nếu không được định nghĩa sẽ sử dụng giá trị mặc định. Ví dụ như ở đây trình duyệt mặc định sẽ là Chrome.

Steps to execute a basic Protractor script: (watch the video below for more details)
▸Create a local example folder, put it wherever you like, name it for example "protractor-demo".
▸Go to https://www.protractortest.org/#/tutorial
▸Copy the above sample code for spec.js. Paste it into Notepad and save it as "spec.js" in folder "protractor-demo".
▸Copy the above sample code for conf.js. Paste it into Notepad and save it as "conf.js" in folder "protractor-demo".
▸Start Selenium server by opening cmd, type "webdriver-manager start", press Enter. Make sure you can see this message before going to next step:
▸Open another cmd, change directory to your "protractor-demo" folder. Type "protractor conf.js" to execute the scripts.

Nếu bạn có thể chạy thành công đoạn script trên, hãy thử thay đổi các giá trị input, thay đổi expected result xem kết quả nhận được khác nhau như thế nào.



Writing Multiple Scenarios


// spec.js
describe('Protractor Demo App', function() {
  var firstNumber = element(by.model('first')); // sử dụng biến để lưu trữ các element, phục vụ cho việc reuse
  var secondNumber = element(by.model('second'));
  var goButton = element(by.id('gobutton'));
  var latestResult = element(by.binding('latest'));

  beforeEach(function() {
    browser.get('http://juliemr.github.io/protractor-demo/');
  });

  it('should have a title', function() {
    expect(browser.getTitle()).toEqual('Super Calculator'); // expect title của trình duyệt phải là "Super Calculator"
  });

  it('should add one and two', function() {
    firstNumber.sendKeys(1);
    secondNumber.sendKeys(2);

    goButton.click();

    expect(latestResult.getText()).toEqual('3'); // expect tổng của 2 số là 3
  });

  it('should add four and six', function() {
    
 firstNumber.sendKeys(4);
    secondNumber.sendKeys(6);

    goButton.click();
 
    expect(latestResult.getText()).toEqual('10'); // expect tổng của 2 số là 10
  });

  it('should read the value from an input', function() {
    firstNumber.sendKeys(1);
    expect(firstNumber.getAttribute('value')).toEqual('1'); // expect số trong input field "first" có giá trị là 1
  });
});

Here, we've pulled the navigation out into a beforeEach function which is run before every it block. We've also stored the ElementFinders for the first and second input in nice variables that can be reused. Fill out the second test using those variables, and run the tests again to ensure they pass. In the last assertion we read the value from the input field with firstNumber.getAttribute('value') and compare it with the value we have set before.

Bây giờ, hãy thử thay đổi file spec.js của chúng ta một chút. Ở đây, chúng ta sử dụng khai báo biến var để lưu trữ các element nhằm phục vụ cho mục đích reuse. 4 khối lệnh it tương đương với 4 test case. Trước khi mỗi khối lệnh it được khởi chạy, function beforeEach sẽ được gọi trước với mục đích mở trình duyệt truy cập tới ứng dụng demo của chúng ta.

Sau khi chạy, bạn sẽ nhận được thông báo cả 4 test case đều pass như sau:



Changing The Configuration


// conf.js
exports.config = {
  framework: 'jasmine',
  seleniumAddress: 'http://localhost:4444/wd/hub',
  specs: ['spec.js'],
  capabilities: {
    browserName: 'firefox' // thử thay đổi trình duyệt mặc định thành Firefox
  }
}

// Một ví dụ khác về khai báo capabilities:
// capabilities: {
//   browserName: 'chrome',
//   name: 'Unnamed Job',
//   logName: 'Chrome - English',
//   count: 1,
//   shardTestFiles: false,
//   maxInstances: 1,
//   specs: ['spec/chromeOnlySpec.js'],
//   exclude: ['spec/doNotRunInChromeSpec.js'],
//   seleniumAddress: 'http://localhost:4444/wd/hub'
// }

Try running the tests again. You should see the tests running on Firefox instead of Chrome. The capabilities object describes the browser to be tested against.

Bây giờ chạy lại, bạn sẽ thấy các test case được thực hiện trong Firefox thay vì Chrome. Đối tượng capabilities mô tả trình duyệt nào sẽ được sử dụng. Để xem danh sách đầy đủ các capabilities khả dụng, hãy truy cập địa chỉ sau https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities

You can also run tests on more than one browser at once. Change conf.js to:

Bạn còn có thể chạy một bộ test trên ít nhất 2 trình duyệt khác nhau chỉ với một lần chạy. Hãy sửa file conf.js như sau:


// conf.js
exports.config = {
  framework: 'jasmine',
  seleniumAddress: 'http://localhost:4444/wd/hub',
  specs: ['spec.js'],
  multiCapabilities: [{
    browserName: 'firefox'
  }, {
    browserName: 'chrome'
  }]
}

Try running once again. You should see the tests running on Chrome and Firefox simultaneously, and the results reported separately on the command line.

Hãy thử chạy một lần nữa. Bạn sẽ thấy bộ test được chạy đồng thời trên Chrome và Firefox, và kết quả test sẽ được thông báo riêng cho từng trình duyệt trong command line.


Learn more about Locators & ElementFinders

https://www.protractortest.org/#/locators

Protractor exports a global function element, which takes a Locator and will return an ElementFinder. This function finds a single element - if you need to manipulate multiple elements, use the element.all function. The ElementFinder has a set of action methods, such as click(), getText(), and sendKeys. These are the core way to interact with an element and get information back from it. When you find elements in Protractor all actions are asynchronous. Behind the scenes, all actions are sent to the browser being controlled using the JSON Webdriver Wire Protocol. The browser then performs the action as a user natively would.

Protractor cung cấp một function toàn cục là element, cho phép nhận vào một Locator và trả về một ElementFinder. Function này trả về một element đơn - nếu bạn cần lấy nhiều element, hãy sử dụng function element.all. ElementFinder có một bộ các action method, như là click(), getText(), và sendKeys. Đây là những cách chính yếu để tương tác với một element và lấy thông tin từ nó. Khi tìm kiếm các element trong Protractor, tất các các action đều là asynchronous (bất đồng bộ). Thực tế bên dưới, các action được gửi tới trình duyệt dưới sự kiểm soát của JSON Webdriver Wire Protocol. Trình duyệt khi đó sẽ thực hiện các hành động như một user thật.

Locators:

A locator tells Protractor how to find a certain DOM element. The most common locators are:

Một locator cho biết Protractor sẽ tìm một DOM như thế nào. Các locator thông dụng nhất bao gồm:

// Find an element using a css selector.
by.css('.myclass')

// Find an element with the given id.
by.id('myid')

// Find an element using an input name selector.
by.name('field_name')

// Find an element with a certain ng-model.
// Note that at the moment, this is only supported for AngularJS apps.
by.model('name')

// Find an element bound to the given variable.
// Note that at the moment, this is only supported for AngularJS apps.
by.binding('bindingname')


*Tham khảo thêm: http://www.protractortest.org/#/api?view=ProtractorBy

The locators are passed to the element function, as below:

Các locator được truyền vào function element như sau:

element(by.css('some-css'));
element(by.model('item.name'));
element(by.binding('item.name'));

When using CSS Selectors as a locator, you can use the shortcut $() notation:

Khi sử dụng CSS locator, bạn có thể dùng notation $() để code ngắn gọn hơn:


$('my-css');
 
// tương đương với:
 
element(by.css('my-css'));


Actions:

The element() function returns an ElementFinder object. The ElementFinder knows how to locate the DOM element using the locator you passed in as a parameter, but it has not actually done so yet. It will not contact the browser until an action method has been called.

Function element() trả về một ElementFinder object. Dù ElementFinder biết cách để định vị một DOM, nhưng nó sẽ không contact với trình duyệt cho tới khi một action method được gọi.

The most common action methods are:

Các action method thông dụng nhất bao gồm:


var el = element(locator);
 
// Click on the element.
el.click();
 
// Send keys to the element (usually an input).
el.sendKeys('my text');
 
// Clear the text in an element (usually an input).
el.clear();
 
// Get the value of an attribute, for example, get the value of an input.
el.getAttribute('value');

Since all actions are asynchronous, all action methods return a promise. So, to log the text of an element, you would do something like:

Chỗ này hơi khó dịch, nhưng nói nôm na vì tất cả các action đều là bất đồng bộ (thực hiện không theo thứ tự), nên trong một số trường hợp cụ thể như sau, để đảm bảo tính thứ tự của các task, chúng ta sử dụng cách viết như bên dưới để đảm bảo việc log text chỉ xảy ra sau khi đã getText thành công.

var el = element(locator);
el.getText().then(function(text) {
  console.log(text);
});


Finding Multiple Elements:

To deal with multiple DOM elements, use the element.all function. This also takes a locator as its only parameter.

Để làm việc với nhiều phần tử DOM, hãy dùng function element.all. Hàm này cũng chỉ nhận vào một locator duy nhất làm tham số.


element.all(by.css('.selector')).then(function(elements) {
  // elements is an array of ElementFinders.
  // elements là một mảng các ElementFinder
});
 
 
// Number of elements.
element.all(locator).count(); // đếm số element
 
// Get by index (starting at 0).
element.all(locator).get(index); // get element theo index
 
// First and last.
element.all(locator).first();   // lấy element đầu tiên
element.all(locator).last();    // lấy element cuối cùng
 
 
// Sử dụng 2 dấu $$ để rút gọn code trong trường hợp locator CSS
$$('.selector');
 
// Is the same as:
 
element.all(by.css('.selector'));


Finding Sub-Elements:

To find sub-elements, simply chain element and element.all functions together as shown below.

Để tìm các element con, chỉ cần đơn giản là sử dụng kết hợp giữa hai function element và element.all.


// lấy một element
element(by.css('some-css'));
 
// lấy một danh sách các element
element.all(by.css('some-css'));
 
// lấy một element con dựa vào tag name từ một danh sách các element
element(by.css('some-css')).element(by.tagName('tag-within-css'));
 
// lấy một danh sách element con dựa vào tag name từ một danh sách các element khác
element(by.css('some-css')).all(by.tagName('tag-within-css'));
 
// một số ví dụ khác
// lấy phần tử đầu tiên từ một danh sách, tiếp tục lấy phần tử con trong phần tử đầu tiên này dựa vào tag name
element.all(by.css('some-css')).first().element(by.tagName('tag-within-css'));
// lấy phần tử từ một danh sách theo index, tiếp tục lấy phần tử con trong phần tử này dựa vào tag name
element.all(by.css('some-css')).get(index).element(by.tagName('tag-within-css'));
// lấy phần tử đầu tiên từ một danh sách, tiếp tục lấy tất cả các phần tử con từ phần tử đầu này dựa vào tag name
element.all(by.css('some-css')).first().all(by.tagName('tag-within-css'));


ElementFinders vs. WebElements

If you're familiar with WebDriver and WebElements, or you're just curious about the WebElements mentioned above, you may be wondering how they relate to ElementFinders.

When you call driver.findElement(locator), WebDriver immediately sends a command over to the browser asking it to locate the element. This isn't great for creating page objects, because we want to be able to do things in setup (before a page may have been loaded) like:

Khi bạn gọi driver.findElement(locator), WebDriver ngay lập tức gửi lệnh tới trình duyệt yêu cầu trả về vị trí của element. Điều này thật sự không hay trong quá trình khởi tạo các object của một trang, bởi vì chúng ta có thể sẽ muốn làm một số cài đặt nhỏ (trước khi trang được tải hoàn chỉnh) như sau:


var myButton = ??;

and re-use the variable myButton throughout your test. ElementFinders get around this by simply storing the locator information until an action is called.

và tái sử dụng biến myButton trong suốt quá trình test. ElementFinders xử lý vấn đề này chỉ đơn giản bằng cách lưu trữ các thông tin của locator cho tới khi một action được thực sự gọi.

var myButton = element(locator);
// No command has been sent to the browser yet.
// Chưa có lệnh nào được gửi tới trình duyệt.


The browser will not receive any commands until you call an action.

Trình duyệt sẽ không nhận bất cứ lệnh nào cho tới khi có một action được gọi.

myButton.click();
// Now two commands are sent to the browser - find the element, and then click it.
// Bây giờ sẽ có 2 lệnh được đồng thời gửi tới trình duyệt - tìm element, và click vào nó.

ElementFinders also enable chaining to find subelements, such as element(locator1).element(locator2).

ElementFinders cũng cho phép chaining để tìm các element con, ví dụ như: element(locator1).element(locator2).

.
Xin vui lòng chờ đợi
Dữ liệu bài viết đang được tải về

💻Nhận dạy online 1 kèm 1 Automation Test từ cơ bản tới nâng cao (From Zero to Hero) 😁😁😁
Lộ trình gồm 3 phần:
1) Kỹ thuật lập trình và tư duy lập trình cơ bản
2) Nhập môn kiểm thử (Manual Test)
3) Kiểm thử tự động (Automation Test) + Chuẩn bị cho phỏng vấn
* Lộ trình chi tiết: Xem tại đây

🎓Đối tượng người học:
- Những bạn bị mất gốc căn bản môn lập trình.
- Những bạn muốn theo con đường kiểm thử (testing), đặc biệt là kiểm thử tự động (Automation Test).

🦘Người giảng dạy:
- Mình sẽ là người trực tiếp hướng dẫn.
- Nếu là các vấn đề ngoài chuyên môn hoặc sở trường, mình sẽ nhờ các anh chị em khác cũng làm trong ngành.

🤓Giới thiệu:
- Mình đã có hơn 10 năm kinh nghiệm làm IT ở cả trong và ngoài nước. Trong đó 3 năm đầu là làm lập trình viên Java, sau đó bén duyên với mảng Automation Test và theo nghề tới tận bây giờ. Mình được đào tạo chính quy về IT từ một trường Đại học danh tiếng ở TP.HCM (hệ kỹ sư 4 năm rưỡi), có chứng chỉ ISTQB, có thể giao tiếp tốt bằng tiếng Anh và có kinh nghiệm làm việc thực tế ở cả 2 mảng Outsource và Product. Title chính thức của mình là QA Automation Engineer, tuy nhiên, mình vẫn làm những dự án cá nhân chuyên về lập trình ứng dụng như Học Tiếng Anh StreamlineSách Nhạc. Mình là người có thái độ làm việc chuyên nghiệp, chăm chỉ và luôn nhiệt tình trong công việc.

💵Chi phí và hình thức thanh toán:
- Các bạn vui lòng liên hệ qua email songtoigianvn@gmail.com (email, chat, hoặc call) để book nội dung và khung giờ học (từ 8h tối trở đi).
- Mức phí: 150.000đ/buổi, mỗi buổi 60 phút.
- Lộ trình From Zero to Hero: 4.350.000đ (29 buổi).
- Bạn có thể học riêng và đóng tiền theo từng phần nếu muốn.
- Có thể học trước 1-2 buổi trước khi quyết định đi full lộ trình hoặc từng phần.
- Thanh toán qua Momo, chuyển khoản v.v...
BÌNH LUẬN
© Copyright by CUỘC SỐNG TỐI GIẢN
Loading...