You are on page 1of 60

Font

Calibri (Body)

Cypress

Cài đặt Selenium

- Cài Intelliji bản ngon

Env -> Path -> add like C:\Program Files\apache-maven-3.9.0\bin

- Tải maven Apache

Chrome driver verion nhỏ hơn trên web

- Tải java 15

Env -> Path -> add like C:\Program Files\Java\jdk-15.0.2\bin

- Pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.example</groupId>
<artifactId>CareerCross</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>15</maven.compiler.source>
<maven.compiler.target>15</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.4.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-support -->


<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-support -->


<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-support</artifactId>
<version>3.141.59</version>
</dependency>

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->


<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.codeborne</groupId>-->
<!-- <artifactId>phantomjsdriver</artifactId>-->
<!-- <version>1.4.4</version>-->
<!-- </dependency>-->

<!-- https://mvnrepository.com/artifact/com.github.jesg/phantomjsdriver -->


<dependency>
<groupId>com.github.jesg</groupId>
<artifactId>phantomjsdriver</artifactId>
<version>2.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20210307</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>5.0.3</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-api</artifactId>
<version>3.141.59</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.apache.logging.log4j</groupId>-->
<!-- <artifactId>log4j-slf4j-impl</artifactId>-->
<!-- <version>2.17.2</version>-->
<!-- </dependency>-->

<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-simple -->


<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.36</version>
<scope>test</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-remote-driver -->

</dependencies>
</project>

Cài đặt Cypress


Tạo folder

Trong folder chạy cmd npm init -y

N sẽ tạo ra file package.json

Mở VSCODE -> open folder vừa tạo


Trỏ đến file package.json

Mở Terminal

Run npm install cypress --save-dev

Tạo ra một số file

Run npx cypress open

Chon e2e Testing

Continue

Tạo ra các folder/file còn lại

Contains
$$('[class *= "FooterSubheading"')
$('[class *= "FooterSubheading"')

Bắt đầu cuối bằng


$('[class ^= "styles__FooterSubheading"')

Kết thúc cuối bằng


$('[class $= "styles__FooterSubheading"')
Lession 4
Run a single test
Hot reload and debugging
Multiple elements matching: using eq, clousure, each
Interaction on multiple element

npm test --spec .\cypress\tests\SecondTest.js

npx cypress run --browser chrome --headed --spec .\cypress\tests\


FirstSelector.js

Lession 6
Handle checkbox with one element
Select multiple checkboxes
Just select checkbox that are not selected
Verify how many checkboxes that are selected
Cách access phần tử trong console DOM
Inspect phần tử
Chuyển sang Console gõ $0
Indeterminate checkbox
Slow Down And Wait For 3rd Party JavaScript To Load
https://glebbahmutov.com/cypress-3rd-party-script-example/

để đợi ChatPopup

Cách để làm chậm tài nguyên cụ thể để đảm bảo trang xử lý mượt mà

Assert Cypress
1) Implicit assertions
should, and, eq, contain, include, exist, have.length, have.value.

2) Explicit assertions
Expect - BDD
Assert - TDD

Iframe
Khi có nhiều frame và phải viết cùng mã để lấy iframe thì dùng Custome command
Có thể dùng cho mọi test case
Drag and Drop
File -Upload
npm install --save-dev cypress-file-upload
File Upload – Rename
Misc Command
Wrap
Within

Within: là cá ch cô lậ p phầ n tử con từ phầ n tử cha hoặ c cung cấ p cá ch lấ y phầ n tử con từ phầ n
tử cha
Về mặ t kĩ thuậ t nó đượ c dù ng để lấ y phạ m vi củ a tấ t cả cá c phầ n tử tiếp theo trong 1 phầ n tử
nhấ t định
Thô ng thườ ng, khi chạ y thử nghiệm vớ i cá c phầ n tử tương ứ ng, nó sẽ quét toà n bộ trang web
DOM để tìm phầ n tử từ đầ u đến cuố i để tìm phạ m vi củ a phầ n tử đó . Điều nà y cuố i cù ng sẽ gâ y
ra mấ t thờ i gian trong khi chạ y nhưng nếu bạ n có mộ t field nhấ t định cầ n đượ c bao phủ cù ng
nhau bên trong thì đó là lự a chọ n tố t nhấ t để là m điều đó .
chỉ có thể đượ c xâ u chuỗ i bằ ng lệnh trướ c đó . Điều đó có nghĩa là nó khô ng thể bị xiềng xích
vớ i cy.
Within chỉ có thể đượ c xâ u chuỗ i bằ ng lệnh command trướ c đó . Điều đó có nghĩa là nó khô ng
thể bị theo sau cy.
Within khô ng thể dù ng timeout và khô ng retry khi assert bị fail trong lầ n assert đầ u tiên
Within hữ u ích khi là m việc cù ng vớ i <form> <table

Example:
it.only('Type Username And Password',()=>{
cy.visit("https://www.programsbuzz.com/user/login")
cy.get('form#user-login-form').within(()=>{
cy.get("input#edit-name").type('bblabla')
cy.get("input#edit-pass").type('mananana')
cy.get("input#edit-submit").click()
})
})

Phầ n form nà y chứ a cá c thà nh phầ n đă ng nhậ p củ a trang, đâ y là nơi cầ n thự c hiện cá c thao tá c
cụ thể.
Vì vậ y, tô i đã cô lậ p thẻ biểu mẫ u bằ ng cá ch sử dụ ng Within và yêu cầ u cypress chỉ trong phầ n
tử đó thử và tìm cá c phầ n tử nà y củ a trườ ng tên ngườ i dù ng, trườ ng mậ t khẩ u và phầ n tử nú t
gử i.
Vì vậ y, theo cá ch nà y, chú ng tô i có thể dễ dà ng cố gắ ng tá ch riêng mộ t phầ n củ a trang và nhậ p
cá c trườ ng nhanh hơn bằ ng cá ch sử dụ ng Within.

Invoke
To get the property og object & invoke function
Lệnh nà y đượ c sử dụ ng để gọ i (invoke) cá c chứ c nă ng thu đượ c (yielded) từ chủ đề trướ c đó
(previous sybject)
Bạ n có thể biết Cypress có mộ t loạ i hạ n chế vì Cypress chạ y trong trình duyệt ngay và nó sẽ
khô ng bao giờ có hỗ trợ nhiều tab, vì vậ y vớ i việc gọ i (Invoke) chú ng ta sẽ có thể thấ y cá ch giả i
quyết.
Điều nà y đơn giả n có nghĩa là chú ng tô i khô ng thể thay đổ i tiêu điểm (Focus) thà nh nhiều tab
đang mở trong Cypress
Thay và o đó , chú ng tô i sẽ cố gắ ng mở tab đó trên cù ng mộ t trang để tiếp tụ c thử nghiệm.
Điều nà y đượ c thự c hiện vớ i sự trợ giú p củ a thuộ c tính JQuery có thể đượ c gọ i bằ ng lệnh nà y.
Liên quan đến cá c hà m Jquery hoặ c hà m tự viết

.invoke(functionName)
.invoke(options, functionName)
.invoke(functionName, args...)
.invoke(options, functionName, args...)

functionName: name of the function to be invoked


options: log and timeout
args....: Additional arguments for function call. There is no limit to the no. of arguments.

Its

Cypress 'its' là mộ t lệnh hữ u ích để lấ y cá c giá trị thuộ c tính củ a đố i tượ ng đượ c cung cấ p trướ c
đó . Nghĩa là có thể lấ y giá trị từ selector

.its(propertyname)
.its(propertyname, options)

cy.get().its()

Example

cy.wrap({ sex: 'male' }).its('sex').should('eq', 'male') 


bọ c cặ p khó a-giá trị bên trong nó bằ ng cá ch sử dụ ng lệnh cy .
Example vớ i mả ng

cy.wrap(['Doc Strange', 'Peter']).its(1).should('eq', 'Peter')

Dự a trên chỉ mụ c, thao tá c mả ng nà y đượ c thự c hiện theo cá ch lấ y chỉ mụ c củ a ' Peter ' là 1.
Wrap using Wrap
Stub
Sơ khai là một đoạn mã được sử dụng để thay thế cho một đoạn mã khác chưa có sẵn hoặc không
thể cung cấp cho bạn kết quả mong muốn mà bạn muốn.
Within and Find
Khi tìm element trên page thì hay dùng cy.get

Cy.get(‘.div’).find(‘.id’)

 Tìm .id trong .div này thôi

Alias
Do not do this

Introducing Aliases
Có thể sử dụ ng chú ng để chia sẻ object, biến giữ a hooks ( before, beforeach, …) và testcas
Chia sẻ bối cảnh
Chia sẻ bố i canh là cá ch đơn giả n nhấ t để sử dụ ng aliases
Để Alias ( đặ t bí danh) sử dụ ng  .as() command
cá c bí danh có sẵ n dướ i dạ ng tệp this.*
Access Fixture

Command as đã chạ y xong trong beforeEach nên có thể dù ng đượ c trong testcase
Watch out for async commands ( Coi chừng các lệnh không đồng bộ trong Cypress)
Do not forget that Cypress commands are async!
You cannot use a this.* reference until the .as() command runs.

User chưa đượ c xá c định bở i vì hiện tạ i thì as mở i chỉ là lệnh đượ c cho và o hà ng đợ i để chạ y, nó
chưa chạ y
Avoiding the use of this
Việc truy cậ p cá c bí danh dướ i dạ ng thuộ c tính this.* khô ng hoạ t độ ng đượ c vớ i hà m mũ i
tên
() => {}
Thay vì sử dụ ng this.* cú phá p, có thể dụ ng lệnh cy.get() bằ ng cú phá p sử dụ ng kí tự @
Khá c nhau giữ a this.* vs cy.get('@')
Element
Bí danh có cá c đặ c điểm đặ c biệt khá c khi đượ c sử dụ ng vớ i cá c phầ n tử DOM.

Sau khi đặ t tên cho cá c phầ n tử DOM, sau nà y bạ n có thể truy cậ p chú ng để sử dụ ng lạ i.
Trong nộ i bộ , Cypress đã tham chiếu đến <tr>bộ sưu tậ p đượ c trả về dướ i dạ ng bí danh "hà ng".
Để tham chiếu cá c "hà ng" nà y sau, bạ n có thể sử dụ ng cy.get()lệnh.

Vì chú ng ta đã sử dụ ng @ký tự trong cy.get(), nên thay vì truy vấ n DOM để tìm cá c phầ n tử , hã y
cy.get()tìm bí danh hiện có đượ c gọ i rowsvà trả về tham chiếu (nếu tìm thấ y).
Closure ( bao đóng)
Bao đó ng là sự kết hợ p củ a cá c chứ c nă ng hoặ c lệnh đượ c gó i cù ng nhau (kèm theo) vớ i cá c
tham chiếu đến trạ ng thá i xung quanh củ a nó .
Ví dụ :
để truy cậ p nhữ ng gì mà lệnh cypress mang lạ i, chú ng ta sử dụ ng lệnh .then() . Sau đó , bên
trong, chú ng tô i sử dụ ng callback là m đố i số . Bằ ng cá ch sử dụ ng callback vớ i then(), chú ng ta
tạ o mộ t bao đó ng.
By using callback functions we've created a closure. Closures enable us to keep references
around to refer to work done in previous commands.

it.only('Verify compare subscription', () => {


cy.visit('http://www.autopract.com/#/home/fashion')
cy.get("button[aria-label='Close'] ").click()

cy.contains('Compare').then(($compare) => {
$compare.click()
cy.get('input#mce-EMAIL').type('hello@example.com')
})
// this command will run after all previous command finished
cy.xpath("//button[text()='subscribe']").click()
})
JQUERY lạ hoắc

:not(checked)
Cách lấy value input khi nó ẩn

Ví dụ muốn lấy text No file chosen nhưng n đã bị disable, check thì nó là attribute, text là value
trong mục Accessibility, thì có thể dùng hàm lấy value trong jquery
contactUsPage.getButtonChooseFile.invoke('val').then(($text) => {
Lạ hoắc về invoke()
productsPage.getProductPriceList.eq(i) => return Object

Cách lấy value attribute src

productsPage.getProductLinkImgList.eq(i).invoke('attr','src').then((imgPr
oduct ) => {
                            img = imgProduct
                        })

Convert array to object

const yourArray = ['Jimbo', '555-555-5555', 'jimbo@aol.com'];

const [name, phone, email] = yourArray;


const yourObject = { name, phone, email };

console.log(yourObject);
Ví dụ về đồng bộ và không đồng bộ
How to Cy.intercept works
Khi trình duyệt khởi động Cypress đóng vai trò là proxy của nó, tất cả lưu lượng truy cập từ bản sao
như tìm nạp tài nguyên html tĩnh tất cả đều đi qua proxy mạng Cypress
Khi bạn gọi chặn trang web bạn cung cấp một matcher là request mà bạn quan tâm và callback
cy.intercept(matcher, callback)
Matcher được gửi tới cypress network proxy
Một ứng dụng đang thực hiện một yêu cầu (request) vd a fetch request

cy.getIframe('iframe[name*="tpapopup"]').contains('View Cart').click({
force: true
})
Khi assert giá trị thuộc tính lấy từ invoke
editCollectionPage.getFlexDirection.invoke('attr','style').should('contain','flex-direction: row-reverse');

Clear input và fill text vào input trong trường hợp input có thuộc tính value không có text()
editCollectionPage.getInputTitleField.invoke('val','').invoke('val','abc123~!$%').as('fill')
Get element data and use in another method
Lấy data về nhưng lưu data lại để dùng sau chả hạn thì phải xử lý bất đồng bộ sao cho data dùng được

Return data
Lây data ra và verify

Get UI data from list of elements and verify against static data
Get data json có 2 cách

- Từ fixture
- Từ file bình thường
-
So sánh nhanh data UI và json không cần vòng for
expect(listData).to.be.deep.eq(datasource)

Intercept the request and verify UI data against backend data


Vào Network để check API

Tìm mấy cái Type xhr, thường chứa data


Lấy data từ API và convert sang object trong Cypress
Tái sử dụng code
Để code chung trong file nào đó và để là phương thức static

Gọi trong testcase


cookies and login with login API request
https://demoblaze.com/
Inspect button Login thấy có hàm logIn()

Tìm trong Network Type script Js

Thường tìm trong index.js


Thử Login

Khi login xong trong Inspect vào tab Application


So sánh Value

So sánh >= và <=

So sánh hơn, kém


check if an element contains other elements cypress
Sử dụng lại biến mà không dùng return Cypress Promise
Lấy danh sách từ hàm each() trong Cypress
Một số Xpath đặc biệt

URL: https://practice.automationtesting.in/

Muốn lấy ảnh của item mà node con của item có chứa button Add to Basket

//div[contains(@class,'sub_column sub_column_1-0-2') and .//a[text()='Add to basket']]//img


Lấy tất cả phần tử trong danh sách trừ phần tử nào đó
Url: https://practice.automationtesting.in/checkout/

//div[@class='select2-result-label' and not (text()='India')]


Get message Prompt Input

Check Element have attribute

Page Timeout
Hi mn, cho e hỏi đã có ai gặp TH khi chạy Cypress thì page load quá lâu so với timeout và khi chạy manual không ạ?

E set pageLoadTimeout: 30000ms nhưng e đo thì nó đợi tận 1'30s - 2'

Phía dưới page load, các api đã load đủ, check Network cũng k có pending. Nhưng UI thì load lên bị chậm. Sau khi load xong UI thì timeout của
page load vẫn chạy đến hết và nó đứng luôn chừng 1' mới chạy tiếp các step phía dưới.

Vậy mà kết quả test vẫn PASS với tg 2'30s - 3'


Trong khi chạy với env khác hoặc manual thì k đến 1'

có đó bạn, vì mỗi lần cypress chạy thì nó set hết mọi thứ lại từ đầu

còn máy bạn chạy manual là đã có nhiều cái nó store lại trong cookie vs session lâu r, gây ra hiện tượng đó

You might also like