《手把手教你》系列技巧篇(三十)-java+ selenium自動化測試- Actions的相關操作下篇(詳解教程)

巨集哥發表於2021-10-13

1.簡介

   本文主要介紹兩個在測試過程中可能會用到的功能:Actions類中的拖拽操作和Actions類中的劃取欄位操作。例如:需要在一堆log字元中隨機劃取一段文字,然後右鍵選擇摘取功能。

2.拖拽操作

  滑鼠拖拽操作,顧名思義就是:就是滑鼠按住將一個元素拖拽到另一個元素上。

2.1基礎講解

//滑鼠拖動API,首先例項化一個物件,後邊將用這個物件進行一系列操作
Actions action = new Actions(webdriver);
//source-要拖動的元素A,target-拖動元素A到達的目標元素B
action.dragAndDrop(source, target);
//source-要拖動的元素A,拖動元素移動多少,標準以元素A左上角為準,拖動元素相對元素A移到右邊是x是正值,左邊是負值,拖動元素相對元素A移到上邊是y是負值,下邊是正值,
action.dragAndDropBy(source, xOffset, yOffset);
例如:
//找到我們所要拖動的元素A和元素B
WebElement A = driver.findElement(By.xpath("//*[@id=\"ext-gen153\"]/li[1]/div"));
WebElement B=driver.findElement(By.xpath("//*[@id=\"ext-gen153\"]/li[2]/div"));
//例項化一個物件action
Actions action = new Actions(driver.getDriver());
//滑鼠拖動A向左移動570,之後釋放滑鼠
action.dragAndDropBy(A, -570, 0).perform();
//滑鼠拖動B向下移動100,向左移動570之後釋放滑鼠
action.dragAndDropBy(B, -570, 100).perform();
//注意:拖動元素之間最好加強制休眠時間,否則不定時出問題,也不報錯
action.dragAndDrop(A, B).perform();
driver.sleep(2000);
action.dragAndDrop(B, A).perform();
//有時定位沒問題,程式碼沒問題,就是沒效果,那就考慮一下拖拽在不同的瀏覽器的工作效果
//For firefox :
Actions builder = new Actions(driver);
builder.moveToElement(draggable).clickAndHold();
builder.moveToElement(target).click().perform();

//For chrome :
Actions builder = new Actions(driver);
builder.moveToElement(draggable).clickAndHold(draggable);
builder.moveToElement(target).release(target).perform();

2.2專案實戰

  巨集哥這裡JqueryUI網站的一個拖拽demo實戰一下。

2.3程式碼設計

  程式碼設計如下:

2.4參考程式碼

    參考程式碼如下:

package lessons;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;

/**
 * @author 北京-巨集哥
 * 
 * 《手把手教你》系列技巧篇(三十)-java+ selenium自動化測試- Actions的相關操作下篇(詳解教程)
 *
 * 2021年9月29日
 */
public class DraggOpration {

    public static void main(String[] args) throws Exception {  
        
        System.setProperty("webdriver.chrome.driver", ".\\Tools\\chromedriver.exe");  
           
        WebDriver driver = new ChromeDriver();  
     
        driver.manage().window().maximize();  
       
        driver.manage().timeouts().implicitlyWait(8, TimeUnit.SECONDS);
          
        driver.get("http://jqueryui.com/resources/demos/droppable/default.html");  
       
        Thread.sleep(2000);
        
        // 定位能拖拽的元素
        WebElement move_ele = driver.findElement(By.id("draggable"));
        
        // 定位拖拽目標位置元素
        WebElement target_ele = driver.findElement(By.id("droppable"));
        
        Actions action = new Actions(driver);
        action.dragAndDrop(move_ele, target_ele).build().perform();
        
        // 驗證拖拽成功
        if(driver.findElement(By.xpath("//*[@id='droppable']/p[text()='Dropped!']")).isDisplayed()){
            System.out.println("斷言通過!");  
        }
        System.out.println(driver.findElement(By.xpath("//*[@id='droppable']/p[text()='Dropped!']")).isDisplayed());
        assert(driver.findElement(By.xpath("//*[@id='droppable']/p[text()='Dropped!']")).isDisplayed() == true);
      
    }
}

2.5執行程式碼

1.執行程式碼,右鍵Run AS->java Application,控制檯輸出,如下圖所示:

2.執行程式碼後電腦端的瀏覽器的動作,如下小視訊所示:

3.劃取欄位操作

   劃取欄位操作就是在一段文字中隨機選中一段文字,或者在標記文字。當然了,這個在一些網站的登入也需要滑塊驗證等。

selenium中提供了ActionChains類來處理滑鼠事件。這個類中有2個方法和滑塊移動過程相關。

click_and_hold():模擬按住滑鼠左鍵在源元素上,點選並且不釋放

release():鬆開滑鼠按鍵

字面意思就可以理解這2個函式的作用。

3.1專案實戰1

   在一段文字中,隨機劃取一小段文字(這個感覺比較雞肋,貌似沒有什麼卵用,但是巨集哥還是說一下吧)。

3.2程式碼設計

   程式碼設計如下:

3.3參考程式碼

   參考程式碼如下:

package lessons;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;

/**
 * @author 北京-巨集哥
 * 
 * 《手把手教你》系列技巧篇(三十)-java+ selenium自動化測試- Actions的相關操作下篇(詳解教程)
 *
 * 2021年9月27日
 */
public class SlipOpration {

    public static void main(String[] args) throws InterruptedException {
         
        System.setProperty("webdriver.chrome.driver", ".\\Tools\\chromedriver.exe");  
        
        WebDriver driver = new ChromeDriver();  
     
        driver.manage().window().maximize();
        
        driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
                                        
        driver.get("https://www.baidu.com/duty/");
        
        //定位第一段文字
        WebElement Sting_Sected = driver.findElement(By.xpath("//*/p"));
        
        //定位第二段文字
        WebElement String_Second = driver.findElement(By.xpath("//*/ul[@class='privacy-ul-gap']/li[1]"));
        
        Actions action = new Actions(driver);
        action.clickAndHold(Sting_Sected).moveToElement(String_Second).perform();
        action.release();
        
    }
}

3.4執行程式碼

1.執行程式碼,右鍵Run AS->java Application,控制檯輸出,如下圖所示:

2.執行程式碼後電腦端的瀏覽器的動作,如下小視訊所示:

3.5專案實戰2

   這裡巨集哥用攜程旅行,手機號查單頁面的一個滑動,進行專案實戰。如下圖所示:

3.6程式碼設計

   程式碼設計如下:

3.7參考程式碼

   參考程式碼如下:

package lessons;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;

/**
 * @author 北京-巨集哥
 * 
 * 《手把手教你》系列技巧篇(三十)-java+ selenium自動化測試- Actions的相關操作下篇(詳解教程)
 *
 * 2021年9月30日
 */
public class Test {
    
    public static void main(String[] args) throws InterruptedException {
        
        System.setProperty("webdriver.gecko.driver", ".\\Tools\\geckodriver.exe");
        
        WebDriver driver = new FirefoxDriver();  
     
        driver.manage().window().maximize();  
       
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
          
        driver.get("https://passport.ctrip.com/user/member/fastOrder");
        
        Thread.sleep(2000);
        
        //定位滑塊
        WebElement Sting_Sected = driver.findElement(By.xpath("//*[@class='cpt-drop-btn']"));
        
        //定位整個滑塊框
        WebElement String_Second = driver.findElement(By.xpath("//*[@class='cpt-bg-bar']"));
        System.out.println(String_Second.getSize());
        Actions action = new Actions(driver);
        //action.clickAndHold(Sting_Sected).moveToElement(String_Second).perform();
        //action.release();
        action.dragAndDropBy(Sting_Sected, 279, 0).perform();
        action.release();
        
        //driver.quit();
    }    

}

3.8執行程式碼

1.執行程式碼,右鍵Run AS->java Application,控制檯輸出,如下圖所示:

2.執行程式碼後電腦端的瀏覽器的動作,如下小視訊所示:

4.小結

4.1重中之重

拖動元素有一個最重要的前提是,你定位的xpath等一定要準確,否則,到時候會出現各種拖動錯亂的問題:
1.拖動元素如果用到action.dragAndDropBy(k2, -570, 100).perform();比如,如果我們想把A元素(可能為圖示)拖動到B區域可能用到這個方法,但是把A拖動到B區域之後,如果我們又想把此時的A拖動到其它地方,但是此時A沒有id,class,只有一些看似沒用的x,y,w,h,注意:這裡一定要注意這裡的這四個值,因為當我們剛開始呼叫action.dragAndDropBy(k2, -570, 100).perform();時,此時拖動完之後,那麼絕對此時的x或者y或者w或者h一定是唯一值,那麼我們抓住這個要點就可以定位了
2.定位參考:

WebElement A=driver.findElement(By.xpath("//*[contains(@x,'50')]"));

//"任務跨1"節點

WebElement B=driver.findElement(By.xpath("//*[contains(@y,'150')]"));

4.2總結

1.注意拖動之後屬性的唯一性
2.dragAndDrop

// 滑鼠拖拽動作,將 source 元素拖放到 (xOffset, yOffset) 位置,其中 xOffset 為橫座標,yOffset 為縱座標。
action.dragAndDrop(source,xOffset,yOffset);
/*在這個拖拽的過程中,已經使用到了滑鼠的組合動作,首先是滑鼠點選並按住 (click-and-hold) source 元素,然後執行滑鼠移動動作 (mouse move),
移動到 target 元素位置或者是 (xOffset, yOffset) 位置,再執行滑鼠的釋放動作 (mouse release)。所以上面的方法也可以拆分成以下的幾個執行動作來完成:*/ action.clickAndHold(source).moveToElement(target).perform(); action.release();

4.3selenium 繞過檢測機制

細心地小夥伴可能發現最後的滑動驗證巨集哥,用了火狐瀏覽器,沒有用Chrome瀏覽器。那是因為巨集哥的Chrome瀏覽器是最新的,目前還沒有找到selenium繞過Chrome檢測機制的辦法(據說代理可以實現,但是巨集哥這裡沒有親自動手驗證,畢竟文章不是講解爬蟲的不能偏離主題)。低版本的Chrome可以參考這篇文章進行繞過:https://stackoverflow.com/questions/53039551/selenium-webdriver-modifying-navigator-webdriver-flag-to-prevent-selenium-detec/56635123#56635123

4.4測試網站

測試連結:https://bot.sannysoft.com/

正常瀏覽結果:

如果用Chrome瀏覽器,就會出現selenium檢查機制,如下圖所示:

 巨集哥然後在這個頁面用網址監測一下,沒有繞過Chrome的selenium反爬蟲檢測機制,如下圖所示:

   好了,時間不早了,今天就分享和講解到這裡。

相關文章