[Selenium C#] Bài 8: Cách xử lý Radio Button, Checkbox, Dropdown

Cách xử lý Radio button, Checkbox, Dropdown, Tag Input trong các dạng form điền thông tin trong Selenium C#.

1. Radio button

Link Demo: https://demo.anhtester.com/basic-radiobutton-demo.html

Trong một nhóm các radio button, tại một thời điểm thì ta chỉ có thể chọn một radio button cho các option đó. Trong HTML, các radio button nằm trong thẻ input và có attribute là type = "radio".

Các bạn có thể tham khảo ví dụ dưới đây về radio button:

[Selenium Java] Lesson 8: Cách xử lý Dropdown, Radio, Checkbox | Anh Tester

HTML:

Radio_btn_html

Và ta có một vài vấn đề có thể làm với radio button như sau:

  1. Xác định locator của các radio button – có thể sử dụng nhiều cách để lấy ra được locator của các element này.
  2. Kiểm tra giá trị mặc định của radio, hoặc kiểm tra xem radio đó đã được chọn hay chưa
  3. Có thể click chọn nếu như radio button này chưa được chọn, hoặc chọn một radio khác khi radio kia đã được chọn
  4. Ngoài ra, trước khi click chọn radio button, ta có thể kiểm tra xem radio button đó có enable hay không – Case này được dùng trong trường hợp đối với một vài yêu cầu sau khi đã thực hiện một vài thao tác trước đó thì mới xuất hiện radio.


Tất cả các nút radio đang được tạo bằng thẻ HTML <input> và có một thuộc tính có tên là “type”, có giá trị là “radio”, biểu thị rằng loại của phần tử đầu vào là một nút Radio.

Cách chọn một Nút Radio

Chúng ta dùng hàm Click() đơn giản

IWebElement radioBtn = driver.FindElement(By.Name("optRadio"));

radioBtn.Click();

 

Cách kiểm tra lại Radio có được chọn hay chưa?

Chúng ta dùng hàm Selected

radioBtn.Selected;

 

Hàm Selected nó trả về True/False nên bạn cần tạo biến thuộc kiểu bool để chứa nó

bool isSelectedRadio = false;

isSelectedRadio = radioBtn.Selected;

 // Kiểm tra lại nếu nó đã được chọn rồi thì sẽ làm gì đó
 if (isSelectedRadio == true)
 {

 }
 else
 {
    
 }

ElementAt(vị trí) để chọn ra vị trị Radio cần kiểm tra

// Dùng IList để lưu hết các nút Radio cùng loại vào IWebElement
IList<IWebElement> AllRadioButton = driver.FindElements(By.Name("optRadio"));
 
// Tạo một biến kiểu bool sẽ khởi tạo giá trị False
bool radioValue = false;
 
 // Dùng hàm Selected để check Radio button. Trả về True nếu Radio ĐẦU TIÊN đã được chọn.
 // Hàm ElementAt(vị trí) bắt đầu từ 0 để chọn thứ tự radio
 radioValue = AllRadioButton .ElementAt(0).Selected;
 
 // Kiểm tra lại nếu nó đã được chọn rồi (radioValue = true) thì sẽ làm gì đó
 if (radioValue == true)
 {
     // Ví dụ cick vào Radio thứ 2 chẵn hạn
     AllRadioButton.ElementAt(1).Click();
 }
 else
 {
    // Ngược lại, nghĩa là nó chưa được chọn thì chọn nó (Radio đầu tiên)
    AllRadioButton.ElementAt(0).Click();
 }

Lưu ý: name luôn giống nhau cho cùng một nhóm Nút radio / Hộp kiểm (Checkbox) nhưng Giá trị của chúng khác nhau. Vì vậy, nếu bạn tìm thấy phần tử có thuộc tính name thì có nghĩa là nó có thể chứa nhiều hơn một phần tử, do đó chúng ta cần sử dụng phương thức FindElements và lưu trữ danh sách các WebElements. (vào IList)


Code nào:

using NUnit.Framework;
using OpenQA.Selenium;
using SeleniumCSharp.Initialize;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SeleniumCSharp.Bai8_Dropdown
{
    [TestFixture]
    class HandleRadioButton : Init_Program
    {
        [Test]
        public void RadioButton()
        {
            driver.Url = "https://demo.anhtester.com/basic-radiobutton-demo.html";
            Thread.Sleep(2000);

            IWebElement radioBtn = driver.FindElement(By.XPath("//label[normalize-space()='Male']//input[@name='optradio']"));

            //radioBtn.Click();

            bool isSelectedRadio = false;

            isSelectedRadio = radioBtn.Selected;

            // Kiểm tra lại nếu nó đã được chọn rồi thì sẽ làm gì đó
            if (isSelectedRadio == true)
            {
                Console.WriteLine("Đã được chọn trước rồi.");
            }
            else
            {
                Console.WriteLine("Chưa được chọn trước đó.");
                radioBtn.Click();
            }
        }

        [Test]
        public void MultiRadioButton()
        {
            driver.Url = "https://demo.anhtester.com/basic-radiobutton-demo.html";
            Thread.Sleep(2000);

            IList<IWebElement> AgeRadioButton = driver.FindElements(By.Name("ageGroup"));

            int totalAgeRadio = AgeRadioButton.Count;
            Console.WriteLine(totalAgeRadio);

            // Tạo một biến kiểu bool sẽ khởi tạo giá trị False
            bool radioValue = false;

            // Dùng hàm Selected để check Radio button. Trả về True nếu Radio ĐẦU TIÊN đã được chọn.
            // Hàm ElementAt(vị trí) bắt đầu từ 0 để chọn thứ tự radio
            radioValue = AgeRadioButton.ElementAt(0).Selected;

            // Kiểm tra lại nếu nó đã được chọn rồi (radioValue = true) thì sẽ làm gì đó
            if (radioValue == false)
            {
                // Ví dụ cick vào Radio thứ 2 chẵn hạn
                AgeRadioButton.ElementAt(1).Click();
            }
            else
            {
                // Ngược lại, nghĩa là nó chưa được chọn thì chọn nó (Radio đầu tiên)
                AgeRadioButton.ElementAt(0).Click();
            }
        }
    }
}



2. Checkbox

Link Demo: https://demo.anhtester.com/basic-checkbox-demo.html

Trong các ứng dụng web, checkbox là một trong những element bạn sẽ thường gặp rất là nhiều. Vậy thì làm thế nào để test checkbox này với selenium? Một cách trực quan, thì ta có thể nhận biết ngay lập tức màn hình chức năng này có checkbox hay không, checkbox nào đã được check hay chưa được check. Tuy nhiên, làm thế nào để selenium làm được điều này, chúng ta cùng tìm hiểu bài toán và tìm ra lời giải dưới đây nhé.

Bài toán đặt ra là, đầu tiên kiểm tra xem checkbox lựa chọn đã được check hay chưa, nếu chưa check thì check vào ô checkbox đó với hai trường hợp là đối với group có một checkbox và group có nhiều checkbox.

Tương tự Radio button cả cách chọn và kiểm tra lại. Ngoài ra cả hai thằng đều có thể chọn và kiểm tra theo: value, Text

Trường hợp check một checkbox:

[Selenium Java] Lesson 8: Cách xử lý Dropdown, Radio, Checkbox | Anh Tester

[Selenium Java] Lesson 8: Cách xử lý Dropdown, Radio, Checkbox | Anh Tester


Hay với trường hợp có nhiều checkbox:

[Selenium Java] Lesson 8: Cách xử lý Dropdown, Radio, Checkbox | Anh Tester

[Selenium Java] Lesson 8: Cách xử lý Dropdown, Radio, Checkbox | Anh Tester

Để biết được element này có phải là checkbox hay không, ta sẽ dựa vào attribute trong thẻ HLML của phần tử, ở ví dụ trên ta có thể quan sát thấy các checkbox đều có type = "checkbox".

Đầu tiên, ta sẽ kiểm tra xem checkbox này đã được check hay chưa, hay kiểm tra checkbox này có giá trị default đã đúng chưa – và thường thì giá trị default của cách checkbox sẽ là chưa check, bằng cách sử dụng hàm Selected().

Nếu như checkbox đó đã được check, kết quả trả về là True, và ngược lại chưa được check thì kết quả trả về là False.

driver.FindElement(By.Id("isAgeSelected")).Selected()

Tiếp theo, nếu như check box chưa được check thì thực hiện click vào ô checkbox đó:

//Kiểm tra check box đã được check hay chưa
Boolean isSelected = driver.FindElement(By.Id("isAgeSelected")).Selected;

//Nếu chưa được check thì click vào ô check box đó
if(isSelected == false)
{
   driver.FindElement(By.Id("isAgeSelected")).Click();
}

Có thể thực hiện với trường hợp ngược lại là nếu checkbox đã được check thì thực hiện bỏ check cho check box, trường hợp này về bản chất thì không khác so với trường hợp true, vì với check box thì ta click lần 1 là check, click tiếp lần 2 thì là bỏ check, do đó ta cũng sẽ làm tương tự đối với trường hợp false này.

Với trường hợp có nhiều check box và ta muốn check nhiều hơn 1 trong số đó thì cũng chỉ cần kiểm tra và thêm thao tác click vào ô checkbox tiếp theo muốn check:

//Check ô checkbox đầu tiên
driver.FindElement(By.XPath (".//*[@id='easycont']/div/div[2]/div[2]/div[2]/div[1]/label/input")).Click();

//Check ô checkbox tiếp theo
driver.FindElement(By.XPath (".//*[@id='easycont']/div/div[2]/div[2]/div[2]/div[2]/label/input")).Click();


Và cách hay hơn là chúng ta dùng vòng lặp để xác định

// Tìm các checkbox element cùng loại theo type
IList <IWebElement> oCheckBox = driver.FindElements(By.XPath("//div[@class='col-md-6 text-left']/div[2]/div[2]//input[@type='checkbox']"));

// Hàm Count sẽ trả cho bạn số lượng checkbox/radio nó lấy được lưu vào biến Size
int Size = oCheckBox.Count;

// Start the loop from first checkbox to last checkboxe
for (int i = 0; i < Size; i++)
{
     //Dùng hàm GetAttribute để lấy giá trị theo thuộc tính
     //Cụ thể là lấy giá trị theo thuộc tính "value" và lưu vào biến Value
     String Value = oCheckBox.ElementAt(i).GetAttribute("value");

     //Kiểm tra tại vị trí "i" nếu checkbox nào có giá trị (value) bằng với "anhtester" thì click vào
	if (Value.Equals("anhtester"))
	{
	    oCheckBox.ElementAt(i).Click();           
	    // Nó sẽ thoát vòng lặp
	    break;
	}
}

 

Code nào:

using NUnit.Framework;
using OpenQA.Selenium;
using SeleniumCSharp.Initialize;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SeleniumCSharp.Bai8_Dropdown
{
    [TestFixture]
    class HandleCheckbox : Init_Program
    {
        [Test]
        public void Checkbox()
        {
            driver.Url = "https://demo.anhtester.com/basic-checkbox-demo.html";
            Thread.Sleep(2000);

            //Kiểm tra check box đã được check hay chưa
            bool isSelected = driver.FindElement(By.Id("isAgeSelected")).Selected;

            //Nếu chưa được check thì click vào ô check box đó
            if (isSelected == false)
            {
                Console.WriteLine("Chưa được chọn.");
                driver.FindElement(By.Id("isAgeSelected")).Click();
            }
            Thread.Sleep(1000);
            IWebElement label = driver.FindElement(By.Id("txtAge"));
            if(label.Displayed == true)
            {
                Console.WriteLine("Đã chọn nó." + label.Text);
            }
        }

        [Test]
        public void MultiCheckbox()
        {
            driver.Url = "https://demo.anhtester.com/basic-checkbox-demo.html";
            Thread.Sleep(2000);

            //Check ô checkbox đầu tiên
            //driver.FindElement(By.XPath("//label[normalize-space()='Option 1']")).Click();

            //Check ô checkbox tiếp theo
            //driver.FindElement(By.XPath("//label[normalize-space()='Option 2']")).Click();

            //B1: Lấy tổng số Input thông qua FindElements
            IList<IWebElement> totalCheckbox = driver.FindElements(By.XPath("//div[@class='col-md-6 text-left']/div[2]/div[2]//input[@type='checkbox']"));

            int total = totalCheckbox.Count;

            Console.WriteLine(total);

            //B2: Duyệt từng vị trí Input đó để click thông qua Xpath động
            
            for(int i=0; i<total; i++)
            {
                totalCheckbox.ElementAt(i).Click();

                //driver.FindElement(By.XPath("//div[@class='col-md-6 text-left']//div[2]//div[2]//div["+i+"]//input[@type='checkbox']")).Click();
            }
        }
    }
}

 

3. Làm việc với Dropdown List

3.1. Dropdown List tĩnh

Link demo: https://demo.anhtester.com/basic-select-dropdown-demo.html


[Selenium C#] Lesson 8: Cách xử lý Dropdown, Radio button, Checkbox, Tag Input | Anh Tester
Yêu cầu:

  • Làm sao để chọn các giá trị: Thứ trong tuần của dropdown ở hình trên?
  • Làm sao để kiểm tra trong dropdown có bao nhiêu giá trị => như hình trên có 7 giá trị?
  • Làm sao để kiểm tra 1 giá trị trong dropdown hiển thị đúng hay chưa sau khi đã chọn thành công?
  • Làm sao để kiểm tra dropdown có phải là multi-select hay single select => multi-select: cho phép chọn nhiều giá trị trong dropdown/ list?

Giải pháp:

  • Selenium WebDriver hỗ trợ kiểm tra các phần tử Dropdown/ List bằng cách sử dụng lớp SelectElement thay vì sử dụng lớp WebElement
    using OpenQA.Selenium.Support.UI;
  • Lớp Select cung cấp các phương pháp và thuộc tính khác nhau để tương tác với dropdown/ list qua phần tử HTML là thẻ SelectElement
    SelectElement select = new SelectElement(Element);

     

[Selenium C#] Lesson 8: Cách xử lý Dropdown, Radio button, Checkbox, Tag Input | Anh Tester

Các phương thức sử dụng:

[Selenium C#] Bài 8: Cách xử lý Dropdown, Radio button, Checkbox | Anh Tester

  • Select dropdown sử dụng thuộc tính ID:

    HTML: <select id="job1" name="user_job1">
    SelectElement select = new SelectElement(driver.FindElement(By.Id("job1")));

  • Select một giá trị trong dropdown sử dụng Text (thường sử dụng)

    HTML
    : <option value="automation">Automation Tester</option>
    select.SelectByText("Automation Testing");​

     

    Hoặc: Select một giá trị trong dropdown sử dụng Value
    select.SelectByValue("automation");​

     


  • Hoặc: Select một giá trị trong dropdown sử dụng Index (bắt đầu từ vị trí số 0)
    select.SelectByIndex(3);​

    => <option value=”website>Website Tester</option>

  • Kiểm tra dropdown có hỗ trợ dạng multi-select hay không:
    select.IsMultiple());​

     

    Phương thức Bỏ chọn

    Cách chúng tôi chọn các giá trị khác nhau của DropDown & Multi Select , cũng giống như cách chúng tôi có thể bỏ chọn các giá trị. Nhưng thách thức duy nhất trong các phương pháp này là chúng không hoạt động với DropDown và chỉ hoạt động với các phần tử Multi Select .

    Trong trường hợp bạn muốn bỏ chọn bất kỳ tùy chọn nào đã chọn trước, điều đó có thể được thực hiện với DeselectAll (), DeselectByIndex, DeselectByValue và DeselectByText .

     

    DropDown_2

    Phần tử Multi Select trông giống như sau:

    MultiSelect_5

    void SelectElement.DeselectAll ()  - Xóa tất cả các mục đã chọn. Điều này chỉ hợp lệ khi SELECT hỗ trợ nhiều lựa chọn.

    Lệnh - oSelect.DeselectAll;

    void SelectElement.DeselectByIndex (int index)  – Bỏ chọn tùy chọn tại chỉ mục đã cho.

    Lệnh - oSelect.DeselectByIndex;

    void SelectElement.DeselectByValue (string value) Bỏ chọn tất cả các tùy chọn có giá trị phù hợp với đối số.

    Lệnh - oSelect.DeselectByValue;

    void SelectElement.DeselectByText (string text) - Bỏ chọn tất cả các tùy chọn hiển thị văn bản khớp với đối số.

    Lệnh - oSelect.DeselectByText

  • Kiểm tra dropdown có bao nhiêu giá trị (số Option):
    => Mỗi 1 giá trị tương ứng với 1 thẻ
    SelectElement oSelect = new SelectElement(driver.FindElement(By.Id("yy_date_8")));
     IList<IWebElement> elementCount = oSelect.Options;
     Console.Write(elementCount.Count);​
    
    int iListSize = elementCount .Count;

    In ra

    for (int i = 0; i < iListSize; i++) {
      //Lấy Text của option theo từng chỉ số (bắt đầu 0)
      String sValue = oSelect.Options.ElementAt(i).Text;
      //In ra giá trị từng option
      Console.WriteLine("Value of the Select item is : " + sValue);
    
      // Kiểm tra option nào có text bằng "AnhTester" thì chọn nó
      if (sValue.Equals("AnhTester")) {
        oSelect.SelectByIndex(i);
        break;
      }
    
    }
  • Kiểm tra giá trị trong dropdown hiển thị đúng sau khi đã chọn thành công (giá trị đã chọn sẽ luôn hiển thị ở vị trí đầu tiên):
    //Lấy giá trị của option đã chọn
    var selectedValue = selectElement.SelectedOption.GetAttribute("value");
    //So sánh với Assert
    Assert.AreEqual(name, selectedValue);​


3.2. Dropdown List động

Link demo: https://jthemes.org/html/traveline/hotel-list.html


Phần trước với các kiểu drop down list và các method dùng trong việc xử lý các drop down list tĩnh. Phần sẽ là các gợi ý và xử lý với drop down list động (Dynamic drop down list), để các bạn có thể dễ dàng làm việc với tất cả các loại drop down khi automate!

Bắt đầu, mình sẽ lấy một ví dụ về một drop down động khác để cùng hiểu hơn về yêu cầu của bài toán cũng như hướng giải quyết nhé.

Dưới đây là một trang web về đặt vé máy bay, người dùng sẽ click vào ô textbox điểm khởi hành để nhập vào điểm khởi hành chuyến bay. Khi click vào đó, trang web hiển thị ra danh sách các điểm khởi hành được gợi ý, người dùng có thể chọn từ list đó hoặc nhập vào các từ khóa, hệ thống sẽ hiển thị tên gợi ý tương ứng gần đúng với từ khóa nhập vào nhất.

[Selenium C#] Bài 8: Cách xử lý Dropdown, Radio button, Checkbox | Anh Tester

Trong trường hợp này, ta không thể sử dụng cách thông thường sử dụng với drop down list tĩnh là dùng select sau đó sử dụng các thuộc tính của phần tử HTML để lấy giá trị cho text box được, mà phải sử dụng bằng cách khác, cách này được mô tả theo kịch bản dưới đây:

Bước 1. Truy cập trang web
Bước 2. Click vào trường điểm khởi hành
Bước 3. Search từ khóa cần tìm
Bước 4. Click chọn điểm khởi hành hiển thị trong drop down phía dưới


Kết quả mong muốn là điểm khởi hành đã chọn được hiển thị vào ô textbox tương ứng.

Locator của các element trong trang này rối quá, mần theo Css thì mất thời gian nên là chúng ta dùng ChroPath/SelectorsHub lấy luôn cái Xpath dài ngoằn kia.

Và ngoài ra, xét về hiệu năng run code này thì được đánh giá là không được tốt bằng việc sử dụng các cách khác. Do đó, hãy cố gắng lấy locator để làm sao đọc dễ hiểu, dễ nắm bắt và quan trọng là ít bị ảnh hưởng bởi những thay đổi cập nhật nhất có thể nhé!


Code nào:

using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using SeleniumCSharp.Initialize;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SeleniumCSharp.Bai8_Dropdown
{
    [TestFixture]
    class HandleDropdown : Init_Program
    {
        [Test]
        public void DropdownList()
        {
            driver.Url = "https://demo.anhtester.com/basic-select-dropdown-demo.html";
            Thread.Sleep(2000);

            SelectElement select = new SelectElement(driver.FindElement(By.Id("select-demo")));

            select.SelectByText("Saturday");
            Thread.Sleep(1000);
            select.SelectByValue("Friday");

            string optionSelected = select.SelectedOption.GetAttribute("value");

            Console.WriteLine(optionSelected);

            if (optionSelected == "Saturday")
            {
                Console.WriteLine("Đúng rồi.");
            }
            else
            {
                Console.WriteLine("Sai rồi.");
            }

        }

        [Test]
        public void DynamicDropdown()
        {
            driver.Url = "https://jthemes.org/html/traveline/hotel-list.html";
            Thread.Sleep(2000);

            driver.FindElement(By.XPath("//span[normalize-space()='Hotel Name 1']")).Click();
            Thread.Sleep(1000);
            driver.FindElement(By.XPath("//form[1]/ul[1]/li[2]/div[1]/div[1]/div[1]/input[1]")).SendKeys("2");
            Thread.Sleep(1000);
            driver.FindElement(By.XPath("//li[normalize-space()='Hotel Name 2']")).Click();
            //Thread.Sleep(1000);
          
        }
    }
}


À cái Init_Program cho ai cần =))

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Remote;

namespace SeleniumCSharp.Initialize
{
    public class Init_Program
    {
        public IWebDriver driver;
        
        [SetUp]
        public void SetupTest()
        {
            driver = new ChromeDriver("D:\\TESTER\\SeleniumC#");
            driver.Manage().Window.Maximize();
            //Set thời gian chờ ngầm định 20s cho tất cả các Step
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
            // Đặt thời gian chờ tải trang mặc định (đơn vị giây)
            driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(20);
        }

        [TearDown]
        public void CloseTest()
        {
            Thread.Sleep(2000);
            driver.Quit();
        }
    }
}


An thêm cái website này hỗ trợ các bạn chạy auto test nè:

https://demo.anhtester.com/

  • Anh Tester

    Đường dẫu khó chân vẫn cần bước đi
    Đời dẫu khổ tâm vẫn cần nghĩ thấu

A PHP Error was encountered

Severity: Notice

Message: Undefined variable: new

Filename: post/post_detail.php

Line Number: 382

Backtrace:

File: /home/anhtest2/public_html/application/views/frontend/post/post_detail.php
Line: 382
Function: _error_handler

File: /home/anhtest2/public_html/application/views/frontend/layout/layout_view.php
Line: 361
Function: view

File: /home/anhtest2/public_html/application/core/MY_Controller.php
Line: 34
Function: view

File: /home/anhtest2/public_html/application/controllers/frontend/Post.php
Line: 59
Function: render

File: /home/anhtest2/public_html/index.php
Line: 315
Function: require_once

A PHP Error was encountered

Severity: Notice

Message: Trying to get property 'slug' of non-object

Filename: post/post_detail.php

Line Number: 382

Backtrace:

File: /home/anhtest2/public_html/application/views/frontend/post/post_detail.php
Line: 382
Function: _error_handler

File: /home/anhtest2/public_html/application/views/frontend/layout/layout_view.php
Line: 361
Function: view

File: /home/anhtest2/public_html/application/core/MY_Controller.php
Line: 34
Function: view

File: /home/anhtest2/public_html/application/controllers/frontend/Post.php
Line: 59
Function: render

File: /home/anhtest2/public_html/index.php
Line: 315
Function: require_once

https://anhtester.com//blog/selenium-c/" data-width="100%" data-numposts="4">