HomeOur Team
Bài 2: Xpath trong Selenium Webdriver
Testing
Bài 2: Xpath trong Selenium Webdriver
giang.ha
giang.ha
March 21, 2021
3 min

Khi làm Automation Test, việc xác định đúng vị trí chính xác một element trên giao diện là bắt buộc trước khi tạo và chạy kịch bản test tự động.Trong Selenium nếu không thể tìm kiếm các elements bởi các định vị như id, class, name… thì hoàn toàn có thể nghĩ tới xpath để tìm các elements đó trên web.

1.Xpath là gì?

  • XPath là một trong 3 thành phần trong ngôn ngữ XSL – Extensible Style Language. Đó là ngôn ngữ hỗ trợ tìm kiếm thông tin trong tài liệu XML, sử dụng biểu thức XPath để định hướng tìm kiếm dữ liệu trên XML thay vì phải thực hiện tìm kiếm đệ quy để duyệt cây XML. Xpath được sử dụng để tìm vị trí bất kỳ phần tử trên Web sử dụng cấu trúc HTML – DOM. XPath chứa đường dẫn của phần tử nằm trên trang Web.
  • Cú pháp cơ bản của Xpath như hình dưới đây:

2.Các loại Xpath

2.1 Xpath tuyệt đối(Absolute XPath)

Đây là cách trực tiếp để tìm phần tử, nhưng nhược điểm của XPath tuyệt đối là nếu có bất kỳ thay đổi nào được thực hiện trong đường dẫn của phần tử thì XPath sẽ bị lỗi.

Đặc điểm chính của XPath là nó bắt đầu bằng dấu gạch chéo đơn (/), có nghĩa là bạn có thể chọn phần tử từ nút gốc.

VD: /html/body/div/div/header/div/div[4]/form/div[1]/input

2.2 Xpath tương đối(Relative Xpath)

Đối với Xpath tương đối, đường dẫn bắt đầu từ giữa cấu trúc DOM HTML. Nó bắt đầu bằng dấu gạch chéo kép (//), có nghĩa là nó có thể tìm kiếm phần tử ở bất kỳ đâu trên trang web.

VD://input[@id='search']

3. Sử dụng Xpath xử lý các phần tử phức tạp và động trong Selenium

3.1 Xpath cơ bản(Tagname & Attribute & Value -> Kiểm tra attribute là duy nhất)

  • //tagname[@attribute=‘value’]
VD:

1. //input[@id='email']
2. //input[@title='Email Address']
3. //input[@name='login[username]']

  • Priority

    1. Unique + Meaning
    2. Attribute: Id/Class/Name
    3. Attribute value meaning- relate to field name
    4. NOT(Id/Class/Name)=> Any attribute + Unique + Related to field name
    5. Link - Không sử dụng với attribute = href(server)

3.2 Parent node(Lấy từ đời cha trở xuống)

  • Khi không thể định danh được element bằng các thẻ và attribute của nó:

    //parent-tagname[@attribute=‘value’]//child-tagname[@attribute=‘value’]

VD:

1. //div[@class='footer']//a[@title='Site Map']
2. //div[@class='footer-container']//a[@title='Site Map']

3.3 Lấy tuyệt đối(=)

  • text()=: chứa giá trị tuyệt đối trong chuỗi
VD: //div[@class'footer']//a[text()='Site Map']
(chạy nhanh hơn vì nó quét phạm vi hẹp)

  • @attribute()=: chứa giá trị tuyệt đối trong attribute

VD: //div[@class='footer-container']//a[@title='Site Map']

3.4 Lấy tương đối(,)

  • contains(): text() || attribute(value) => Chạy chậm hơn vì nó quét phạm vi rộng hơn

VD: //div[@class='footer-container']//a[contains(text(),'Site Map')]

3.5 Starts-with: text() || @attribute

VD:

1. //div[@class='footer-container']//a[starts-with(text(),'Site Map')]
2. //div[@class='footer-container']//a[@starts-with(@title,'Site Map')]

3.6 Hàm text()

  • Khi automation test ở level là Function UI (giả lập hành vi của End User) thì thao tác với text rất nhiều.
  • Khi làm việc với text có 5 loại:

1. text()=’…’

  • text nằm trên chính node(tagname) đó - không có nằm trong child node hoặc dạng nested text(text lồng nhau đều nằm trong một thẻ).
  • Lấy text tuyệt đối: không có khoảng trắng/xuống dòng/tab ở đầu hoặc cuối chuỗi.

2. contains(text(),’…‘)

  • text nằm trên chính node(tagname) đó hoặc dưới dạng nested text nhưng text phải nằm ở đầu tiên.
  • text này có khoảng trắng/xuống dòng/tab ở đầu dòng hoặc cuối text vẫn work được.
  • Nếu text nằm trực tiếp trong child node thì không lấy được.
  • Không dùng contains(text()=”) mà dùng contains(text(),”).

3. contains(.,’…‘)

  • text nằm trên chính node (tagname) đó, nằm trong child node ở bất cứ vị trí nào, hoặc nested text ở bất kỳ vị trí nào.
  • text này có khoảng trắng/xuống dòng/tab ở đầu hoặc cuối chuỗi vẫn work được.
  • dùng contains(.,”) không dùng contains(.=”).

4. contains(string(),’…‘)

  • text nằm trên chính node (tagname) đó, nằm trong child node ở bất kỳ vị trí nào, hoặc nested text cũng work
  • text này có khoảng trắng/xuống dòng/tab ở đầu hoặc cuối chuỗi vẫn work được.
  • Dùng contains(string(),”) không dùng contains(string()=”).

5. concat()

  • text nằm trên chính node (tagname) đó, nằm trong child node ở bất kỳ vị trí nào, hoặc nested text cũng work
  • text này có khoảng trắng/xuống dòng/tab ở đầu hoặc cuối chuỗi vẫn work được.
  • Nên dùng với text có khi có chứa ký tự ”.

4.Demo đơn giản cho việc sử dụng Xpath (các case đăng ký/đăng nhập tài khoản)

package webdriver;

import java.util.Random;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class Topic_02_Xpath_Css_PartII {
    WebDriver driver;
    private int randomInt;

    @BeforeClass
    public void beforeClass() {
        driver = new FirefoxDriver();
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        driver.manage().window().maximize();
    }

    @Test
    public void Login_01_Empty_Email_And_Password() {
        driver.get("http://live.demoguru99.com/");
        driver.findElement(By.xpath("//div[@class='footer']//a[@title='My Account']")).click();
        driver.findElement(By.xpath("//*[@id='email']")).sendKeys("");
        driver.findElement(By.xpath("//*[@id='pass']")).sendKeys("");
        driver.findElement(By.xpath("//*[@id='send2']")).click();
        Assert.assertEquals(driver.findElement(By.xpath("//*[@id='advice-required-entry-email']")).getText(),
                "This is a required field.");
        Assert.assertEquals(driver.findElement(By.xpath("//*[@id='advice-required-entry-pass']")).getText(),
                "This is a required field.");
    }

    @Test
    public void Login_02_Invalid_Email() {
        driver.get("http://live.demoguru99.com/");
        driver.findElement(By.xpath("//div[@class='footer']//a[@title='My Account']")).click();
        driver.findElement(By.xpath("//*[@id='email']")).sendKeys("123@2333");
        driver.findElement(By.xpath("//*[@id='pass']")).sendKeys("123456");
        driver.findElement(By.xpath("//*[@id='send2']")).click();
        Assert.assertEquals(driver.findElement(By.xpath("//*[@id='advice-validate-email-email']")).getText(),
                "Please enter a valid email address. For example johndoe@domain.com.");
    }

    @Test
    public void Login_03_Invalid_Password_less6character() {
        driver.get("http://live.demoguru99.com/");
        driver.findElement(By.xpath("//div[@class='footer']//a[@title='My Account']")).click();
        driver.findElement(By.xpath("//*[@id='email']")).sendKeys("automation@gmail.com");
        driver.findElement(By.xpath("//*[@id='pass']")).sendKeys("123");
        driver.findElement(By.xpath("//*[@id='send2']")).click();
        Assert.assertEquals(driver.findElement(By.xpath("//div[@id='advice-validate-password-pass']")).getText(),
                "Please enter 6 or more characters without leading or trailing spaces.");
    }

    @Test
    public void Login_04_Correct_Email_Incorrect_Password() {
        driver.get("http://live.demoguru99.com/");
        driver.findElement(By.xpath("//div[@class='footer']//a[@title='My Account']")).click();
        driver.findElement(By.xpath("//*[@id='email']")).sendKeys("automation@gmail.com");
        driver.findElement(By.xpath("//*[@id='pass']")).sendKeys("123123123");
        driver.findElement(By.xpath("//*[@id='send2']")).click();
        Assert.assertEquals(driver.findElement(By.xpath("//li[@class='error-msg']//span")).getText(),
                "Invalid login or password.");
    }

    @Test
    public void Login_05_Create_A_New_Account() throws InterruptedException {
        driver.get("http://live.demoguru99.com/");
        driver.findElement(By.xpath("//div[@class='footer']//a[@title='My Account']")).click();
        Thread.sleep(3000);
        driver.findElement(By.xpath("//span[contains(text(),'Create an Account')]")).click();

        driver.findElement(By.id("firstname")).clear();
        driver.findElement(By.id("firstname")).sendKeys("Thu");
        driver.findElement(By.id("lastname")).clear();
        driver.findElement(By.id("lastname")).sendKeys("Giang");

        // the new random number
        Random rd = new Random();
        for (int idx = 1000; idx <= 100000; ++idx) {
            randomInt = rd.nextInt(100000);
        }
        driver.findElement(By.id("email_address")).clear();
        driver.findElement(By.id("email_address")).sendKeys("thugiang.hvktqs" + randomInt + "@gmail.com");
        driver.findElement(By.id("password")).clear();
        driver.findElement(By.id("password")).sendKeys("thugiang1905");
        driver.findElement(By.id("confirmation")).clear();
        driver.findElement(By.id("confirmation")).sendKeys("thugiang1905");
        driver.findElement(By.xpath("//div[@class='buttons-set']//button")).click();

        Assert.assertEquals(driver.findElement(By.xpath("//li[@class='success-msg']//span")).getText(),
                "Thank you for registering with Main Website Store.");
        System.out.println(driver
                .findElement(By.xpath("//div[@class='box-content']//p[contains(text(),'Thu Giang')]//br")).getText());

        driver.findElement(By.xpath("//div[@class='account-cart-wrapper']//span[@class='label']")).click();
        driver.findElement(By.xpath("//a[@title='Log Out']")).click();
        Assert.assertEquals(driver.findElement(By.xpath("//div[@class='page-title']//h2")).getText(),
                "THIS IS DEMO SITE FOR   ");
        driver.findElement(By.xpath("//a[@class='skip-link skip-account']//span[@class='label']")).click();
        driver.findElement(By.xpath("//div[@id='header-account']/div/ul/li[5]/a")).click();
    }

    @Test
    public void Login_06_Correct_Email_Correct_Password() {
        driver.get("http://live.demoguru99.com/");
        driver.findElement(By.xpath("//div[@class='footer']//a[@title='My Account']")).click();
        driver.findElement(By.xpath("//input[@id='email']")).sendKeys("thugiang.hvktqs@gmail.com");
        driver.findElement(By.xpath("//input[@id='pass']")).sendKeys("thugiang1905");
        driver.findElement(By.xpath("//button[@id='send2']")).click();

        // Verify the data registed
        Assert.assertEquals(driver.findElement(By.xpath("//div[@class='page-title']//h1")).getText(), "MY DASHBOARD");
        Assert.assertEquals(driver.findElement(By.xpath("//div[@class='welcome-msg']//strong")).getText(),
                "Hello, Thu Giang!");

    }

    @AfterClass
    public void afterClass() {
        driver.quit();
    }

}

Link tham khảo:

  1. https://www.guru99.com/xpath-selenium.html
  2. https://automationfc.vn/

Tags

202103testingautomationseleniumwebdriver
giang.ha

giang.ha

Tester / iOS Developer

Expertise

tester
ios

Related Posts

Bài 3: Làm quen với những câu lệnh cơ bản nhất trong Selenium WebDriver
Bài 3: Làm quen với những câu lệnh cơ bản nhất trong Selenium WebDriver
May 09, 2021
1 min
System operator: Những câu chuyện chưa từng được kể (Phần 1)
Others
System operator: Những câu chuyện chưa từng được kể (Phần 1)
March 31, 2021
5 min
Why Protocol-Oriented Programming?
Articles
Why Protocol-Oriented Programming?
March 31, 2021
2 min
© 2021, All Rights Reserved.

Quick Links

HomeOur Team

Social Media