Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
Automation_selenium
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Trình Nguyễn
Automation_selenium
Commits
6c59f811
Commit
6c59f811
authored
May 11, 2026
by
Đỗ Gia Hưng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix: Refactor TestNG tests sang POM, cap nhat testng.xml day du
parent
88dec7f8
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
206 additions
and
184 deletions
+206
-184
AnhTesterBlogPage.java
src/main/java/com/automation/pages/AnhTesterBlogPage.java
+74
-0
HandleCRMTest.java
src/test/java/com/automation/testcases/HandleCRMTest.java
+42
-110
TestNGAnnotationsTest.java
.../java/com/automation/testcases/TestNGAnnotationsTest.java
+26
-33
TestNGAssertionsTest.java
...t/java/com/automation/testcases/TestNGAssertionsTest.java
+36
-37
testng.xml
testng.xml
+28
-4
No files found.
src/main/java/com/automation/pages/AnhTesterBlogPage.java
0 → 100644
View file @
6c59f811
package
com
.
automation
.
pages
;
import
org.openqa.selenium.By
;
import
org.openqa.selenium.JavascriptExecutor
;
import
org.openqa.selenium.WebDriver
;
import
org.openqa.selenium.WebElement
;
import
org.openqa.selenium.support.ui.ExpectedConditions
;
import
org.openqa.selenium.support.ui.WebDriverWait
;
import
java.time.Duration
;
/**
* AnhTesterBlogPage - Đại diện cho trang blog anhtester.com
* Dùng cho: Bài 10 (TestNG Assertions - Hard Assert, Soft Assert)
*/
public
class
AnhTesterBlogPage
{
private
WebDriver
driver
;
private
WebDriverWait
wait
;
// --- Locators ---
private
By
headerLogo
=
By
.
xpath
(
"//a[contains(@class,'logo')]"
);
private
By
loginBtn
=
By
.
xpath
(
"//a[contains(@href,'login') or contains(text(),'Login') or @id='btn-login']"
);
private
By
blogMenu
=
By
.
xpath
(
"//a[@href='/blogs' or @href='/blog' or contains(.,'Blog')]"
);
public
AnhTesterBlogPage
(
WebDriver
driver
)
{
this
.
driver
=
driver
;
this
.
wait
=
new
WebDriverWait
(
driver
,
Duration
.
ofSeconds
(
10
));
}
public
void
open
()
{
System
.
out
.
println
(
"[Page]: Mo trang anhtester.com"
);
driver
.
get
(
"https://anhtester.com"
);
}
public
String
getTitle
()
{
return
driver
.
getTitle
();
}
public
String
getCurrentUrl
()
{
return
driver
.
getCurrentUrl
();
}
public
boolean
isLogoDisplayed
()
{
System
.
out
.
println
(
"[Page]: Kiem tra Header Logo"
);
WebElement
el
=
wait
.
until
(
ExpectedConditions
.
visibilityOfElementLocated
(
headerLogo
));
highlightElement
(
el
);
return
el
.
isDisplayed
();
}
public
boolean
isLoginButtonDisplayed
()
{
System
.
out
.
println
(
"[Page]: Kiem tra nut Login hien thi"
);
try
{
WebElement
el
=
wait
.
until
(
ExpectedConditions
.
visibilityOfElementLocated
(
loginBtn
));
highlightElement
(
el
);
return
el
.
isDisplayed
();
}
catch
(
Exception
e
)
{
return
false
;
}
}
public
String
getBlogMenuText
()
{
System
.
out
.
println
(
"[Page]: Lay text cua menu Blog"
);
WebElement
el
=
wait
.
until
(
ExpectedConditions
.
visibilityOfElementLocated
(
blogMenu
));
highlightElement
(
el
);
return
el
.
getText
();
}
private
void
highlightElement
(
WebElement
element
)
{
JavascriptExecutor
js
=
(
JavascriptExecutor
)
driver
;
js
.
executeScript
(
"arguments[0].setAttribute('style', 'border: 3px solid red; background: yellow;');"
,
element
);
try
{
Thread
.
sleep
(
1000
);
}
catch
(
InterruptedException
e
)
{
e
.
printStackTrace
();
}
}
}
src/test/java/com/automation/testcases/HandleCRMTest.java
View file @
6c59f811
package
com
.
automation
.
testcases
;
package
com
.
automation
.
testcases
;
import
com.automation.base.BaseSetup
;
import
com.automation.base.BaseSetup
;
import
org.openqa.selenium.By
;
import
com.automation.pages.CustomerPage
;
import
org.openqa.selenium.Keys
;
import
com.automation.pages.DashboardPage
;
import
org.openqa.selenium.WebElement
;
import
com.automation.pages.LoginPage
;
import
org.openqa.selenium.support.ui.ExpectedConditions
;
import
org.openqa.selenium.support.ui.WebDriverWait
;
import
org.testng.Assert
;
import
org.testng.Assert
;
import
org.testng.annotations.Test
;
import
org.testng.annotations.Test
;
import
java.time.Duration
;
/**
* HandleCRMTest - Bài 16: Thực hành Auto Test CRM (Phiên bản POM)
* Đây là bản refactor của file cũ, đã chuyển toàn bộ locators vào Page Objects.
*/
public
class
HandleCRMTest
extends
BaseSetup
{
public
class
HandleCRMTest
extends
BaseSetup
{
@Test
(
description
=
"Bài 16: Thực hành quy trình CRM - Thêm mới Khách hàng và Xác nhận"
)
@Test
(
description
=
"Bai 16: Them moi Khach hang tren CRM - Ap dung POM"
)
public
void
testAddCustomer
()
throws
InterruptedException
{
public
void
testAddCustomer
()
{
// Tăng thời gian chờ lên 20s để đảm bảo ổn định
// --- Khởi tạo Page Objects ---
WebDriverWait
wait
=
new
WebDriverWait
(
driver
,
Duration
.
ofSeconds
(
20
));
LoginPage
loginPage
=
new
LoginPage
(
driver
);
org
.
openqa
.
selenium
.
JavascriptExecutor
js
=
(
org
.
openqa
.
selenium
.
JavascriptExecutor
)
driver
;
DashboardPage
dashboardPage
=
new
DashboardPage
(
driver
);
CustomerPage
customerPage
=
new
CustomerPage
(
driver
);
String
companyName
=
"Anh Tester CRM "
+
System
.
currentTimeMillis
();
String
companyName
=
"Anh Tester CRM "
+
System
.
currentTimeMillis
();
System
.
out
.
println
(
"\n========================================"
);
System
.
out
.
println
(
"\n========================================"
);
System
.
out
.
println
(
" B
ẮT ĐẦU TEST: Bài 16 - Thực hành CRM
"
);
System
.
out
.
println
(
" B
AT DAU TEST: Bai 16 - Thuc hanh CRM (POM)
"
);
System
.
out
.
println
(
"========================================\n"
);
System
.
out
.
println
(
"========================================\n"
);
// --- Bước 1: Đăng nhập ---
// --- Bước 1: Đăng nhập ---
System
.
out
.
println
(
"[B
ước 1]: Truy cập trang đăng nhập
CRM..."
);
System
.
out
.
println
(
"[B
uoc 1]: Dang nhap vao he thong
CRM..."
);
driver
.
get
(
"https://crm.anhtester.com/admin/authentication"
);
driver
.
get
(
"https://crm.anhtester.com/admin/authentication"
);
loginPage
.
login
(
"admin@example.com"
,
"123456"
);
System
.
out
.
println
(
"[Bước 1]: Đang chờ ô Email xuất hiện..."
);
WebElement
emailInput
=
wait
.
until
(
ExpectedConditions
.
visibilityOfElementLocated
(
By
.
id
(
"email"
)));
highlightElement
(
emailInput
);
emailInput
.
clear
();
emailInput
.
sendKeys
(
"admin@example.com"
);
WebElement
passwordInput
=
driver
.
findElement
(
By
.
id
(
"password"
));
highlightElement
(
passwordInput
);
passwordInput
.
clear
();
passwordInput
.
sendKeys
(
"123456"
);
WebElement
loginBtn
=
driver
.
findElement
(
By
.
xpath
(
"//button[@type='submit']"
));
highlightElement
(
loginBtn
);
System
.
out
.
println
(
"[Bước 1]: Đang nhấn nút Login..."
);
loginBtn
.
click
();
// --- Bước 2: Vào menu Customers ---
// --- Bước 2: Vào menu Customers ---
System
.
out
.
println
(
"\n[Bước 2]: Đang chờ menu Dashboard xuất hiện..."
);
System
.
out
.
println
(
"\n[Buoc 2]: Mo menu Customers..."
);
wait
.
until
(
ExpectedConditions
.
urlContains
(
"/admin"
));
dashboardPage
.
openCustomersMenu
();
System
.
out
.
println
(
"[Bước 2]: Tìm menu 'Customers' ở thanh sidebar..."
);
// --- Bước 3: Thêm mới khách hàng ---
WebElement
menuCustomers
=
wait
.
until
(
ExpectedConditions
.
elementToBeClickable
(
By
.
xpath
(
"//span[contains(text(),'Customers')]"
)));
System
.
out
.
println
(
"\n[Buoc 3]: Them moi khach hang..."
);
highlightElement
(
menuCustomers
);
customerPage
.
clickNewCustomer
();
Thread
.
sleep
(
1000
);
customerPage
.
enterCustomerInfo
(
companyName
,
"VAT123"
,
"0123456789"
,
"https://anhtester.com"
);
menuCustomers
.
click
();
customerPage
.
clickSave
();
System
.
out
.
println
(
"[Bước 2]: Đã mở trang Danh sách khách hàng."
);
// --- Bước 4: Xác nhận trên trang Profile ---
// --- Bước 3: Nhấn nút New Customer ---
System
.
out
.
println
(
"\n[Buoc 4]: Xac nhan tren trang Profile..."
);
System
.
out
.
println
(
"\n[Bước 3]: Tìm nút 'New Customer'..."
);
String
headerName
=
customerPage
.
getHeaderProfileName
();
WebElement
btnAddNew
=
wait
.
until
(
ExpectedConditions
.
elementToBeClickable
(
By
.
xpath
(
"//a[contains(@class,'btn-primary') and contains(.,'New Customer')]"
)));
System
.
out
.
println
(
"[Test]: Header Profile: "
+
headerName
);
highlightElement
(
btnAddNew
);
Assert
.
assertTrue
(
headerName
.
contains
(
companyName
),
"Ten cong ty khong khop tren Profile!"
);
Thread
.
sleep
(
1000
);
System
.
out
.
println
(
" Da luu thanh cong!"
);
btnAddNew
.
click
();
System
.
out
.
println
(
"[Bước 3]: Đã mở form Thêm mới khách hàng."
);
// --- Bước 5: Tìm kiếm trong danh sách ---
System
.
out
.
println
(
"\n[Buoc 5]: Quay lai danh sach va tim kiem..."
);
// --- Bước 4: Điền thông tin vào form ---
dashboardPage
.
openCustomersMenu
();
System
.
out
.
println
(
"\n[Bước 4]: Đang điền thông tin khách hàng..."
);
boolean
isFound
=
customerPage
.
isCustomerDisplayedInTable
(
companyName
);
if
(
isFound
)
{
WebElement
inputCompany
=
wait
.
until
(
ExpectedConditions
.
visibilityOfElementLocated
(
By
.
id
(
"company"
)));
System
.
out
.
println
(
"[Test]: Xac nhan tim thay khach hang trong bang."
);
highlightElement
(
inputCompany
);
}
else
{
inputCompany
.
sendKeys
(
companyName
);
System
.
out
.
println
(
"[Test]: Canh bao: Khong tim thay qua Search (Index tre)."
);
System
.
out
.
println
(
" ✓ Company: "
+
companyName
);
WebElement
inputVat
=
driver
.
findElement
(
By
.
id
(
"vat"
));
highlightElement
(
inputVat
);
inputVat
.
sendKeys
(
"VAT123"
);
WebElement
inputPhone
=
driver
.
findElement
(
By
.
id
(
"phonenumber"
));
highlightElement
(
inputPhone
);
inputPhone
.
sendKeys
(
"0123456789"
);
WebElement
inputWebsite
=
driver
.
findElement
(
By
.
id
(
"website"
));
highlightElement
(
inputWebsite
);
inputWebsite
.
sendKeys
(
"https://anhtester.com"
);
Thread
.
sleep
(
1000
);
// --- Bước 5: Lưu thông tin ---
System
.
out
.
println
(
"\n[Bước 5]: Đang cuộn xuống và nhấn nút 'Save' để lưu..."
);
WebElement
btnSave
=
driver
.
findElement
(
By
.
xpath
(
"//button[contains(@class,'only-save')]"
));
js
.
executeScript
(
"arguments[0].scrollIntoView(true);"
,
btnSave
);
highlightElement
(
btnSave
);
btnSave
.
click
();
System
.
out
.
println
(
"[Bước 5]: Đang chờ hệ thống xử lý (Lưu dữ liệu)..."
);
wait
.
until
(
ExpectedConditions
.
urlContains
(
"/client/"
));
System
.
out
.
println
(
" ✓ Đã lưu thành công! Trang đã chuyển hướng sang Profile."
);
// Kiểm tra tiêu đề Profile
WebElement
headerName
=
wait
.
until
(
ExpectedConditions
.
visibilityOfElementLocated
(
By
.
xpath
(
"//h4[contains(normalize-space(), '"
+
companyName
+
"')]"
)));
highlightElement
(
headerName
);
System
.
out
.
println
(
" ✓ Header Profile: "
+
headerName
.
getText
());
// --- Bước 6: Kiểm tra lại trong danh sách ---
System
.
out
.
println
(
"\n[Bước 6]: Quay lại danh sách Customers để kiểm tra..."
);
WebElement
menuCustomersBack
=
wait
.
until
(
ExpectedConditions
.
elementToBeClickable
(
By
.
xpath
(
"//span[contains(text(),'Customers')]"
)));
menuCustomersBack
.
click
();
System
.
out
.
println
(
"[Bước 6]: Đang tìm ô Search của bảng..."
);
WebElement
inputSearch
=
wait
.
until
(
ExpectedConditions
.
visibilityOfElementLocated
(
By
.
cssSelector
(
"#clients_filter input"
)));
highlightElement
(
inputSearch
);
System
.
out
.
println
(
"[Bước 6]: Nhập tên công ty: "
+
companyName
);
inputSearch
.
clear
();
inputSearch
.
sendKeys
(
companyName
);
Thread
.
sleep
(
4000
);
// Đợi DataTables xử lý (có thể chậm)
// Xác nhận kết quả xuất hiện trong bảng
try
{
WebElement
firstRowName
=
wait
.
until
(
ExpectedConditions
.
visibilityOfElementLocated
(
By
.
xpath
(
"//table[@id='clients']//tbody//a[normalize-space()='"
+
companyName
+
"']"
)));
highlightElement
(
firstRowName
);
System
.
out
.
println
(
" ✓ Đã tìm thấy khách hàng trong danh sách: "
+
firstRowName
.
getText
());
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
" ⚠ Lưu ý: Không tìm thấy qua ô Search (có thể do hệ thống chưa kịp index)."
);
System
.
out
.
println
(
" ⚠ Nhưng bước kiểm tra Profile trước đó đã thành công."
);
// Không throw lỗi ở đây để tránh fail test nếu chỉ là vấn đề index chậm của CRM
}
}
System
.
out
.
println
(
"\n========================================"
);
System
.
out
.
println
(
"\n========================================"
);
System
.
out
.
println
(
" K
ẾT THÚC TEST: Bài 16 HOÀN THÀ
NH!"
);
System
.
out
.
println
(
" K
ET THUC TEST: Bai 16 HOAN THA
NH!"
);
System
.
out
.
println
(
"========================================\n"
);
System
.
out
.
println
(
"========================================\n"
);
}
}
}
}
src/test/java/com/automation/testcases/TestNGAnnotationsTest.java
View file @
6c59f811
package
com
.
automation
.
testcases
;
package
com
.
automation
.
testcases
;
import
org.openqa.selenium.WebDriver
;
import
com.automation.base.BaseSetup
;
import
org.openqa.selenium.chrome.ChromeDriver
;
import
com.automation.pages.AnhTesterPage
;
import
org.openqa.selenium.chrome.ChromeOptions
;
import
org.testng.Assert
;
import
org.testng.Assert
;
import
org.testng.annotations.*
;
import
org.testng.annotations.*
;
import
java.time.Duration
;
/**
* TestNGAnnotationsTest - Bài 10: Học cách dùng các annotation của TestNG
* Mục đích: DEMO annotation lifecycle (@BeforeSuite, @BeforeTest, @BeforeClass, @BeforeMethod...)
* File này giữ nguyên cấu trúc kế thừa BaseSetup để không tự quản lý driver.
*/
public
class
TestNGAnnotationsTest
extends
BaseSetup
{
public
class
TestNGAnnotationsTest
{
// Page Object
private
AnhTesterPage
anhTesterPage
;
WebDriver
driver
;
@BeforeSuite
@BeforeSuite
public
void
beforeSuite
()
{
public
void
beforeSuite
()
{
...
@@ -27,36 +30,28 @@ public class TestNGAnnotationsTest {
...
@@ -27,36 +30,28 @@ public class TestNGAnnotationsTest {
System
.
out
.
println
(
"> @BeforeClass: Chay truoc class hien tai"
);
System
.
out
.
println
(
"> @BeforeClass: Chay truoc class hien tai"
);
}
}
// NOTE: @BeforeMethod setUp() được kế thừa từ BaseSetup (khởi tạo driver).
// Chúng ta KHÔNG override lại ở đây, chỉ thêm logic riêng nếu cần.
@BeforeMethod
@BeforeMethod
public
void
beforeMethod
()
{
public
void
initPage
()
{
System
.
out
.
println
(
"- @BeforeMethod: Khoi tao trinh duyet truoc moi test case"
);
System
.
out
.
println
(
"- @BeforeMethod (TestNGAnnotationsTest): Khoi tao Page Object"
);
ChromeOptions
options
=
new
ChromeOptions
();
anhTesterPage
=
new
AnhTesterPage
(
driver
);
options
.
addArguments
(
"--remote-allow-origins=*"
);
// Neu bi loi memory, hay bo comment dong duoi day de chay an (headless)
// options.addArguments("--headless");
driver
=
new
ChromeDriver
(
options
);
driver
.
manage
().
window
().
maximize
();
driver
.
manage
().
timeouts
().
implicitlyWait
(
Duration
.
ofSeconds
(
10
));
}
}
// Bai 10: Su dung thuoc tinh priority de quan ly thu tu chay (so nho chay
// truoc)
@Test
(
priority
=
1
,
description
=
"Kiem tra tieu de trang web Anh Tester"
)
@Test
(
priority
=
1
,
description
=
"Kiem tra tieu de trang web Anh Tester"
)
public
void
testCase1
()
{
public
void
testCase1
()
{
System
.
out
.
println
(
"Executing Test Case 1: Mo trang chu va kiem tra tieu de"
);
System
.
out
.
println
(
"Executing Test Case 1: Mo trang chu va kiem tra tieu de"
);
driver
.
get
(
"https://anhtester.com"
);
anhTesterPage
.
open
();
String
expectedTitle
=
"Anh Tester"
;
String
actualTitle
=
anhTesterPage
.
getTitle
();
String
actualTitle
=
driver
.
getTitle
();
Assert
.
assertTrue
(
actualTitle
.
contains
(
"Anh Tester"
),
"Tieu de khong chua tu khoa mong muon!"
);
Assert
.
assertTrue
(
actualTitle
.
contains
(
expectedTitle
),
"Tieu de khong chua tu khoa mong muon!"
);
}
}
@Test
(
priority
=
2
,
description
=
"Kiem tra URL trang
Blog
"
)
@Test
(
priority
=
2
,
description
=
"Kiem tra URL trang
hien tai sau khi navigate
"
)
public
void
testCase2
()
{
public
void
testCase2
()
{
System
.
out
.
println
(
"Executing Test Case 2: Mo trang
Blog
va kiem tra URL"
);
System
.
out
.
println
(
"Executing Test Case 2: Mo trang
Anh Tester
va kiem tra URL"
);
driver
.
get
(
"https://anhtester.com/blog"
);
anhTesterPage
.
open
(
);
String
currentUrl
=
driver
.
getCurrentUrl
();
String
currentUrl
=
anhTesterPage
.
getCurrentUrl
();
Assert
.
assertTrue
(
currentUrl
.
contains
(
"
blog"
),
"URL khong chua tu khoa 'blog
'!"
);
Assert
.
assertTrue
(
currentUrl
.
contains
(
"
anhtester"
),
"URL khong chua 'anhtester
'!"
);
}
}
@Test
(
priority
=
3
,
enabled
=
false
,
description
=
"Test case nay bi disable nen se khong chay"
)
@Test
(
priority
=
3
,
enabled
=
false
,
description
=
"Test case nay bi disable nen se khong chay"
)
...
@@ -65,11 +60,9 @@ public class TestNGAnnotationsTest {
...
@@ -65,11 +60,9 @@ public class TestNGAnnotationsTest {
}
}
@AfterMethod
@AfterMethod
public
void
afterMethod
()
{
public
void
afterMethodLog
()
{
System
.
out
.
println
(
"- @AfterMethod: Dong trinh duyet sau moi test case"
);
System
.
out
.
println
(
"- @AfterMethod (TestNGAnnotationsTest): Hoan thanh 1 test case."
);
if
(
driver
!=
null
)
{
// NOTE: @AfterMethod tearDown() từ BaseSetup sẽ đóng driver.
driver
.
quit
();
}
}
}
@AfterClass
@AfterClass
...
...
src/test/java/com/automation/testcases/TestNGAssertionsTest.java
View file @
6c59f811
package
com
.
automation
.
testcases
;
package
com
.
automation
.
testcases
;
import
com.automation.base.BaseSetup
;
import
com.automation.base.BaseSetup
;
import
org.openqa.selenium.By
;
import
com.automation.pages.AnhTesterBlogPage
;
import
org.openqa.selenium.WebElement
;
import
org.testng.Assert
;
import
org.testng.Assert
;
import
org.testng.annotations.Test
;
import
org.testng.annotations.Test
;
import
org.testng.asserts.SoftAssert
;
import
org.testng.asserts.SoftAssert
;
/**
* TestNGAssertionsTest - Bài 10: Hard Assert vs Soft Assert (POM)
* Hard Assert: Dừng test ngay khi gặp lỗi.
* Soft Assert: Thu thập tất cả lỗi, báo tổng cuối cùng.
*/
public
class
TestNGAssertionsTest
extends
BaseSetup
{
public
class
TestNGAssertionsTest
extends
BaseSetup
{
@Test
(
priority
=
1
)
@Test
(
priority
=
1
,
description
=
"Hard Assert: Dừng test ngay khi gặp lỗi đầu tiên"
)
public
void
testHardAssert
()
{
public
void
testHardAssert
()
{
AnhTesterBlogPage
page
=
new
AnhTesterBlogPage
(
driver
);
System
.
out
.
println
(
"--- Bat dau test Hard Assert ---"
);
System
.
out
.
println
(
"--- Bat dau test Hard Assert ---"
);
driver
.
get
(
"https://anhtester.com"
);
// 1. Kiểm tra tiêu đề trang
page
.
open
();
String
expectedTitle
=
"Anh Tester - Học Automation Testing"
;
String
actualTitle
=
driver
.
getTitle
();
Assert
.
assertEquals
(
actualTitle
,
expectedTitle
,
"Tieu de trang khong dung!"
);
// 2. Kiểm tra Header có tồn tại không
// Kiểm tra tiêu đề - Hard Assert dừng ngay nếu sai
WebElement
headerLogo
=
driver
.
findElement
(
By
.
xpath
(
"//a[@class='logo']"
));
String
actualTitle
=
page
.
getTitle
();
System
.
out
.
println
(
"Title hien tai: "
+
actualTitle
);
Assert
.
assertTrue
(
actualTitle
.
contains
(
"Anh Tester"
),
"Tieu de khong chua 'Anh Tester'!"
);
// => GỌI HÀM HIGHLIGHT TỪ BASE
// Kiểm tra logo hiển thị
highlightElement
(
headerLogo
);
boolean
logoVisible
=
page
.
isLogoDisplayed
();
Assert
.
assertTrue
(
logoVisible
,
"Khong tim thay Logo o header!"
);
Assert
.
assertTrue
(
headerLogo
.
isDisplayed
(),
"Khong tim thay Logo o header!"
);
System
.
out
.
println
(
"=> Header Logo ton tai. Hard Assert thanh cong!"
);
System
.
out
.
println
(
"=> Header Logo ton tai. Hard Assert thanh cong!"
);
}
}
@Test
(
priority
=
2
)
@Test
(
priority
=
2
,
description
=
"Soft Assert: Thu thập tất cả lỗi trước khi báo cáo"
)
public
void
testSoftAssert
()
{
public
void
testSoftAssert
()
{
AnhTesterBlogPage
page
=
new
AnhTesterBlogPage
(
driver
);
System
.
out
.
println
(
"--- Bat dau test Soft Assert ---"
);
System
.
out
.
println
(
"--- Bat dau test Soft Assert ---"
);
SoftAssert
softAssert
=
new
SoftAssert
();
SoftAssert
softAssert
=
new
SoftAssert
();
driver
.
get
(
"https://anhtester.com"
);
page
.
open
(
);
// 1. Kiểm tra tiêu đề (Cố tình sai để xem Soft Assert hoạt động)
// 1. Kiểm tra tiêu đề (cố tình sai để demo Soft Assert KHÔNG dừng)
String
actualTitle
=
driver
.
getTitle
();
String
actualTitle
=
page
.
getTitle
();
System
.
out
.
println
(
"Title hien tai: "
+
actualTitle
);
softAssert
.
assertEquals
(
actualTitle
,
"Sai Tieu De"
,
"Tieu de bi sai (Day la loi co y)!"
);
softAssert
.
assertEquals
(
actualTitle
,
"Sai Tieu De"
,
"Tieu de bi sai (Day la loi co y)!"
);
// 2. Kiểm tra nút Login có hiển thị không
// 2. Kiểm tra logo header (đúng)
WebElement
loginBtn
=
driver
.
findElement
(
By
.
id
(
"btn-login"
));
boolean
logoVisible
=
page
.
isLogoDisplayed
();
highlightElement
(
loginBtn
);
softAssert
.
assertTrue
(
logoVisible
,
"Logo khong hien thi!"
);
softAssert
.
assertTrue
(
loginBtn
.
isDisplayed
(),
"Nut Login khong hien thi!"
);
// 3. Kiểm tra text của menu Blog
WebElement
blogMenu
=
driver
.
findElement
(
By
.
xpath
(
"//a[@href='/blogs']"
));
// => GỌI HÀM HIGHLIGHT TỪ BASE
highlightElement
(
blogMenu
);
String
menuText
=
blogMenu
.
getText
();
// 3. Kiểm tra text menu Blog
softAssert
.
assertTrue
(
menuText
.
equalsIgnoreCase
(
"blog"
),
"Text cua menu Blog bi sai!"
);
String
blogText
=
page
.
getBlogMenuText
();
System
.
out
.
println
(
"Blog menu text: "
+
blogText
);
softAssert
.
assertTrue
(
blogText
.
toLowerCase
().
contains
(
"blog"
),
"Text cua menu Blog bi sai!"
);
System
.
out
.
println
(
"=> Ket thuc viec kiem tra Soft Assert."
);
System
.
out
.
println
(
"=> Ket thuc viec kiem tra Soft Assert."
);
// QUAN TRỌNG
NHẤT: Phải có dòng này ở cuối để tổng hợp lỗi.
// QUAN TRỌNG
: assertAll() tổng hợp toàn bộ lỗi và báo cáo một lần
softAssert
.
assertAll
();
softAssert
.
assertAll
();
}
}
}
}
testng.xml
View file @
6c59f811
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite
name=
"Suite Bài 9 TestNG"
>
<suite
name=
"Selenium POM Test Suite - Anh Tester"
>
<test
name=
"Test Selenium Cơ bản"
>
<!-- Bài 7-10: Các bài học cơ bản về WebDriver và TestNG -->
<test
name=
"Bai 7-10: Co ban WebDriver va TestNG"
>
<classes>
<classes>
<class
name=
"com.automation.testcases.BasicWebDriverCommandsTest"
/>
<class
name=
"com.automation.testcases.BasicWebDriverCommandsTest"
/>
<class
name=
"com.automation.testcases.WebElementCommandsTest"
/>
<class
name=
"com.automation.testcases.WebElementCommandsTest"
/>
<class
name=
"com.automation.testcases.TestNGAnnotationsTest"
/>
<class
name=
"com.automation.testcases.TestNGAnnotationsTest"
/>
<class
name=
"com.automation.testcases.TestNGAssertionsTest"
/>
<class
name=
"com.automation.testcases.TestNGAssertionsTest"
/>
<class
name=
"com.automation.testcases.HandleActionsTest"
/>
</classes>
<class
name=
"com.automation.testcases.HandleRobotClassTest"
/>
</test>
<!-- Bài 11-13: Xử lý Alert, Window/iFrame, Actions -->
<test
name=
"Bai 11-13: Alert, Window, iFrame, Actions, Robot"
>
<classes>
<class
name=
"com.automation.testcases.HandleAlertTest"
/>
<class
name=
"com.automation.testcases.HandleAlertTest"
/>
<class
name=
"com.automation.testcases.HandleWindowIFrameTest"
/>
<class
name=
"com.automation.testcases.HandleWindowIFrameTest"
/>
<class
name=
"com.automation.testcases.HandleActionsTest"
/>
<class
name=
"com.automation.testcases.HandleRobotClassTest"
/>
</classes>
</test>
<!-- Bài 14-15: JavaScript Executor và Wait -->
<test
name=
"Bai 14-15: Javascript Executor va Wait"
>
<classes>
<class
name=
"com.automation.testcases.HandleJavascriptExecutorTest"
/>
<class
name=
"com.automation.testcases.HandleJavascriptExecutorTest"
/>
<class
name=
"com.automation.testcases.HandleWaitTest"
/>
<class
name=
"com.automation.testcases.HandleWaitTest"
/>
</classes>
</classes>
</test>
</test>
<!-- Bài 16-17: Thực hành CRM và Page Object Model -->
<test
name=
"Bai 16-17: Thuc hanh CRM va POM"
>
<classes>
<class
name=
"com.automation.testcases.HandleCRMTest"
/>
<class
name=
"com.automation.testcases.LoginTest"
/>
<class
name=
"com.automation.testcases.CRMTest"
/>
</classes>
</test>
</suite>
</suite>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment