Phần 2: Selenium Webdriver - Tìm kiếm và tương tác với các Elements

Không giống như chúng ta, khi tương tác với website thì dùng chuột và con trỏ để xác định các đối tượng cần thao tác, cần phải hiểu bản chất của Selenium là giúp chúng ta thao tác với các Elements thẳng ngay trên trên DOM, giống như cách mà chúng ta hay dùng trong js như là Document.getElementById() chẳng hạn. Vì vậy, để giúp Selenium thao tác với nó, chúng ta phải tìm ra các Elements bằng "Locator". 
Mình xin phép giữ nguyên các từ gốc vì dịch ra không hay lắm sealed

Như đã nói ở phần mô tả, mọi thứ trên page của chúng ta đều là Elements, chúng bao gồm các đoạn text, hình ảnh, nút, alert......
Bây giờ hãy thử ngó sơ trang web này: https://testing.devforum.info/
Đây là một site mình fork từ Elemental Selenium, thường được dùng để Practice Selenium, rất nổi tiếng
Trên site của chúng ta hiện tại có rất là nhiều hyperlink, nếu như muốn tương tác với các links (elements) đó, chúng ta cần xác định được vị trí của các elements đó bằng Locator. Locator là cách Selenium tìm và định vị các elements trên page để nó có thể tương tác được, trường hợp nếu tìm không ra element đó, nó sẽ trả lỗi về. Đây là page demo của chúng  ta




Một page như vầy thì cấu trúc là html, và Selenium sẽ bắt elements dựa theo DOM
Hiện tại Selenium có một số Locator như sau:
  • ID
  • Name
  • Class Name
  • Tag Name
  • Link Text
  • Partial Link Text
  • XPATH
  • CSS

Trong đó mình thấy được dùng phổ biến nhất là id vì nó là duy nhất, sau đó là CSS và Xpath, mình sẽ viết một bài hướng dẫn cụ thể hơn về cách dùng Locator với Xpath và CSS. Hiện tại chúng ta chỉ nên quan tâm cách dùng lệnh với các Locator khác nhau. Và một điều lưu ý nữa hầu hết Selenium Webdriver cho dù viết bằng ngôn ngữ nào cũng dùng các Locator tương  tự nhau, nên nếu nắm tốt ở ngôn ngữ(Java) này thì dùng qua ngôn ngữ khác rất tiện. Bây giờ chúng ta bắt đầu thực hành. 
Trước hết để biết chính xác đoạn code trong html của element cần lấy là gì, chúng ta có thể click chuột phải vào nó, chọn Inspec, hoặc f12 (trên Chrome) sau đó click vào con trỏ, lại tiếp tục click vào element mình cần lấy để cho Chrome xác định nó. Thao tác như vầy: 


Đây là source code của cái page https://testing.devforum.info/, các bạn chú ý các thẻ <div>, <ul> , <a>, id và class của CSS nhé, Locator của chúng ta đều based trên CSS đó
<body>
    <div class="row">
        <div id="flash-messages" class="large-12 columns">

        </div>
    </div>
    <div class="row">
        <div id="content" class="large-12 columns">
            <style>
                ul {
                    list-style-type: none;
                    margin: 0;
                    padding: 0;
                }
            </style>
            <h1 class="heading">Welcome to VTA Courses - Demo Selenium</h1>
            <h2>Available Examples</h2>
            <ul>
                <li><a href='abtest.html'>A/B Testing</a></li>
                <li><a href='add_remove_elements.html'>Add/Remove Elements</a></li>
                <li><a href='basic_auth.html'>Basic Auth</a> (user and pass: admin)</li>
                <li><a href='broken_images.html'>Broken Images</a></li>
                <li><a href='challenging_dom.html'>Challenging DOM</a></li>
                <li><a href='checkboxes.html'>Checkboxes</a></li>
                <li><a href='context_menu.html'>Context Menu</a></li>
                <li><a href='digest_auth.html'>Digest Authentication</a> (user and pass: admin)</li>
                <li><a href='disappearing_elements.html'>Disappearing Elements</a></li>
                <li><a href='drag_and_drop.html'>Drag and Drop</a></li>
                <li><a href='dropdown.html'>Dropdown</a></li>
                <li><a href='dynamic_content.html'>Dynamic Content</a></li>
                <li><a href='dynamic_controls.html'>Dynamic Controls</a></li>
                <li><a href='dynamic_loading.html'>Dynamic Loading</a></li>
                <li><a href='entry_ad.html'>Entry Ad</a></li>
                <li><a href='exit_intent.html'>Exit Intent</a></li>
                <li><a href='download.html'>File Download</a></li>
                <li><a href='upload.html'>File Upload</a></li>
                <li><a href='floating_menu.html'>Floating Menu</a></li>
                <li><a href='forgot_password.html'>Forgot Password</a></li>
                <li><a href='login.html'>Form Authentication</a></li>
                <li><a href='frames.html'>Frames</a></li>
                <li><a href='geolocation.html'>Geolocation</a></li>
                <li><a href='horizontal_slider.html'>Horizontal Slider</a></li>
                <li><a href='hovers.html'>Hovers</a></li>
                <li><a href='infinite_scroll.html'>Infinite Scroll</a></li>
                <li><a href='inputs.html'>Inputs</a></li>
                <li><a href='jqueryui/menu.html'>JQuery UI Menus</a></li>
                <li><a href='javascript_alerts.html'>JavaScript Alerts</a></li>
                <li><a href='javascript_error.html'>JavaScript onload event error</a></li>
                <li><a href='key_presses.html'>Key Presses</a></li>
                <li><a href='large.html'>Large & Deep DOM</a></li>
                <li><a href='windows.html'>Multiple Windows</a></li>
                <li><a href='nested_frames.html'>Nested Frames</a></li>
                <li><a href='notification_message_rendered.html'>Notification Messages</a></li>
                <li><a href='redirector.html'>Redirect Link</a></li>
                <li><a href='download_secure.html'>Secure File Download</a></li>
                <li><a href='shadowdom.html'>Shadow DOM</a></li>
                <li><a href='shifting_content.html'>Shifting Content</a></li>
                <li><a href='slow.html'>Slow Resources</a></li>
                <li><a href='tables.html'>Sortable Data Tables</a></li>
                <li><a href='status_codes.html'>Status Codes</a></li>
                <li><a href='typos.html'>Typos</a></li>
                <li><a href='tinymce.html'>WYSIWYG Editor</a></li>
            </ul>

        </div>
    </div>
    <div id='page-footer' class="row">
        <div class="large-4 large-centered columns">
            <hr>
            <div style="text-align: center;">Powered by <a target="_blank" href="https://elementalselenium.com/">Elemental Selenium</a></div>
            <br><br>
        </div>
    </div>​

Nó tương ứng với phần này trên browser 



Bi giờ mình muốn click vào chữ A/B Testing, mình dùng Linktext
<li><a href='abtest.html'>A/B Testing</a></li​

Code của mình dùng sẽ là 

driver.findElement(By.linkText("A/B testing")).click();

Trong đó findElement là hàm để tìm Elements, nó kết hợp với method click() để click vào một element nào đó, nếu chúng ta không click thì có thể store nó vào một biến, để dùng sau này, biến này có dạng là WebElement. Khi sử dụng code kiểu đó thì nó sẽ như vầy 

WebElement ABTesting = driver.findElement(By.linkText("A/B testing"));
ABTesting.click();

// Muốn dùng được WebElement và By thì phải import, cách import thì Control Shift O giống mình nói ở bài mở đầu

Đó là cách dùng LinkText, cần nhớ là LinkText phân biệt chữ hoa chứ thường nha
Tiếp đến là các loại Selector khác như : ID, Name, Class Name, Tag Name, Xpath, CSS, trong đó ngoại trừ Xpath, tất cả các Selector còn lại đều dính tới CSS, nếu bạn đã từng code CSS sẽ biết được CSS Selector dùng để select element trong DOM như là #id, .class ....
Bây giờ có đoạn code, các bạn hãy save lại rồi lưu thành TestPage.html để demo nào

<html>

<head>
  <title> Learning Selenium Selector </title>
</head>
  <body>
    <div id="selectAllPage">
      <button id='firstButton' class ='onlyMe' type="button" name="testButton" value="ButonOne">ButonOne</button>
      <button id='secondButton' type="button" name="testButton2" value="ButonTwo">ButonTwo</button>
      <button id='thirdButton' type="button" name="testButton3" value="ButtonThree">ButtonThree</button>

<form id="login">
      <input placeholder="Username" name="username" type="text" />
      <input placeholder="Password" name="password" type="password"/>
      <input name="submit" type="submit" value="Continue!"/>
    </form>

    </div>
  </body>
</html>

Sau đó các bạn paste đoạn code này vào và cho nó chạy để demo kết quả 

WebDriver driver = new ChromeDriver();
		
		driver.get("đường dẫn tới file TestPage.html");
		//Tìm theo className
		driver.findElement(By.className("onlyMe")).click();
		System.out.println("Ấn vào nút đầu tiên thành công");
		//Tìm theo name
		driver.findElement(By.name("testButton2")).click();
		System.out.println("Ấn vào nút thứ 2 thành công");
		//Tìm theo id
		driver.findElement(By.id("thirdButton")).click();
		System.out.println("Ấn vào nút thứ 3 thành công");
		//Tìm theo Xpath
		driver.findElement(By.xpath("//input[@name='username']")).sendKeys("myUsername");
		System.out.println("Nhập username thành công");
		//Tìm theo CSS
		driver.findElement(By.cssSelector("[name|='password']")).sendKeys("myPassword");
		System.out.println("Nhập password thành công");
		Thread.sleep(3000);
		
		// Quit Browser

		driver.quit();

Phân tích đoạn code trên:

driver.findElement(By.className("onlyMe"));


Đây là đang lấy Locator theo class trong CSS. Trong 1 file html, thì class name có thể trùng nhau, do đó nếu có nhiều node (elements) được tìm thấy, Selenium sẽ lây cái đầu tiên từ trên xuống trong DOM, cách này ít dùng vì sẽ có rất nhiều class trùng nhau => không chính xác

driver.findElement(By.name("testButton2"));

Tương tự như className, name lấy được Element chứa name tương ứng, ví dụ

<input placeholder="Username" name="username" type="text">


Sẽ có name là "username"
Tiếp theo là Xpath: 

driver.findElement(By.xpath("//input[@name='username']"));


Đây là một trong số 2 Locator mạnh thường được dùng, vì nó có thể kết hợp nhiều điều kiện, khi tìm thấy nhiều Elements để cho ra một Element duy nhất, kết quả sẽ chính xác. Mình sẽ có 1 bài viết về nó sau bài này
Tiếp theo là CSS Selector:

driver.findElement(By.cssSelector("[name|='password']"));

Nó cũng tương tự như Xpath, có thể kết hợp rất nhiều điều kiện để lấy được một kết quả duy nhất trong vô số kết quả, và syntax y hệt như CSS locator trong CSS coding, do đó nếu các bạn rành HTML và CSS thì dùng cái này rất có lợi. Mình cũng sẽ có 1 bài viết nhỏ nói về Locator này vì nó cũng phổ biến.

Vậy là mình đã giới thiệu xong cho các bạn về các loại Locator trong Selenium, wohoooo sealed
Hẹn gặp lại ở các bài viết sau