Selenium 頁面載入策略完全指南

網頁自動化已廣泛發展,多數人都曾涉足其中。這是我們幾乎定期進行的工作,自動化多種情境並瀏覽眾多網頁。

然而,你是否曾好奇,當網頁在Selenium WebDriver中載入時,背後發生了什麼?我們熟知一些導航至網頁的WebDriver函數,如get()navigate(),但它們是否界定了頁面如何載入,或是後端還有其他機制在運作?

答案是肯定的!這是由Selenium WebDriver中的「頁面載入策略」所決定。WebDriver利用此策略來確定網頁載入的方式,以便在進行後續互動前,執行下一個動作。

在這篇關於Selenium頁面載入策略的部落格中,我們將深入探討此策略,試圖理解其不同類型及如何在自動化代碼中實施。

那麼,讓我們開始吧!

什麼是頁面載入策略?

頁面載入策略定義了何時網頁將被視為當前會話已載入,每當自動化代碼啟動瀏覽器並使用get()或navigate().to()方法時。預設情況下,Selenium WebDriver採用標準的頁面載入策略,即NORMAL。這意味著等待整個網頁及其組件,如CSS、圖片、框架等,完全載入。

若因上述提及的元件(或限流的網路條件)導致頁面載入時間延長,而對您的腳本來說並非重要,您可將其設為EAGER或NONE以加速執行。此設定值適用於整個工作階段,故為您的專案明智選擇,否則可能導致測試的不穩定性。

頁面載入策略的使用已作為Selenium 4功能的一部分被引入。與過去的版本不同,它消除了對使用預設頁面載入逾時的依賴。

頁面載入策略如何運作?

為了確定頁面載入是否已完成,Selenium利用document.readyState屬性。document.readyState描述了文檔的載入狀態,此處的文檔指的是瀏覽器中載入的任何網頁。

文檔的Ready State方法受所有瀏覽器支持,使其成為與Selenium的PageLoadStrategy配合使用的可靠選項。

正如我們有預設的PageLoadStrategy,Selenium WebDriver等待的預設document.readyState是Complete。

瀏覽器文檔物件的readyState屬性代表頁面載入過程的當前狀態。該屬性可能具有以下值之一:

  • loading – 頁面仍在載入中。
  • interactive – 頁面已完成載入,但子資源如圖像、樣式表和框架可能仍在載入。
  • complete – 頁面及其所有子資源已完成載入。

您可以使用readyState屬性來確定何時頁面已完全載入並準備好由JavaScript或其他方式操作。例如,在Selenium中,您可以使用readyState屬性來確定頁面何時載入,並且可以使用Selenium命令與頁面上的元素進行互動。

在繼續前進之前,讓我們通過一個簡短的練習更深入地了解文檔的readyState。

  1. 訪問該網站
  2. 一旦網站載入完成,右鍵點擊->選擇檢查->打開控制台並執行命令document.readyState。

3. 執行此命令後,您將看到輸出為”complete”,這表示文檔的當前狀態。這意味著整個頁面已載入必要的資源(即圖片、CSS等)。

4. 接下來,刷新頁面並再次執行上述命令。您將能夠看到文檔在此刻的載入狀態,如下所示。

如果經過4-5次刷新後仍看不到載入狀態,請嘗試通過將網絡設置為較慢的選項來節流網絡條件。您可以通過這篇關於在不同網絡條件下測試網站的博客了解更多信息。我們在演示中也將採用相同的方法。

這展示了document.readyState在實際操作中的運作方式。您也可以使用LT瀏覽器,一個適合移動設備的測試工具,來檢查網站在不同網絡條件下的性能。LT瀏覽器是LambdaTest提供的一個輔助工具,允許您在超過50種不同設備上測試網站的響應性,包括智能手機、平板電腦和筆記本電腦。它還提供了創建自定義分辨率、模擬不同網絡條件以及使用Google Lighthouse生成性能報告的功能。

接下來,讓我們深入了解這些值及其如何與PageLoadStrategy值對應。

PageLoadStrategy與document.readyState對應關係

文檔的readyState可以是以下之一:

  • 載入中:文檔載入正在進行。
  • 互動中:文檔已載入並解析,但子資源如腳本、圖像、CSS和框架仍在載入。此時,DOMContentLoaded事件被觸發。
  • 完成:文檔及其所有子資源已完成載入。這表示載入事件的觸發。

每種PageLoadStrategy都根據特定的document.readyState值進行映射,WebDriver將根據此完成導航方法並繼續執行下一步。

PageLoadStrategy document.readyState Description
Normal complete Used by default by browser and Selenium WebDriver. Waits for all the resources to be downloaded.
Eager interactive Resources like images and CSS might still be loading, but DOM is accessible and ready to interact.
None any WebDriver is not blocked at all. Execution continues without any wait as soon as the initial page is loaded.

Selenium中的頁面載入策略類型

通常有三種類型的Selenium頁面載入策略可用於網絡自動化。

NORMAL(默認,如未指定)

此Selenium頁面載入策略使WebDriver等待直到頁面載入完成,即載入事件被觸發。

當頁面及其依賴資源如CSS、JavaScript、iFrames和圖像等載入完成時,載入事件被觸發。

它等待HTML內容及其所有子資源下載和解析完成。

EAGER

使用此Selenium頁面載入策略,WebDriver僅等待初始頁面載入及DOMContentLoaded事件被觸發。

與載入事件不同,DOMContentLoaded事件在DOM載入完成後立即觸發,無需等待CSS、JavaScript、iFrames和圖像等附加資源載入。

它僅等待HTML內容下載和解析。

NONE

在此Selenium頁面載入策略中,WebDriver不會被阻塞,並繼續進行測試執行。

它僅等待HTML內容下載。

示範:使用不同Selenium頁面載入策略設置WebDriver

現在我們已經對不同的Selenium頁面載入策略有了基本理解,讓我們來看一些代碼示例,了解其實現方式。

為此,我們將編寫一個自動化測試腳本,用於以下場景。

  1. 創建一個使用基於雲的Selenium Grid的RemoteWebDriver實例。對此,我們將使用LambdaTest平台。
  2. 設置WebDriver能力至特定的PageLoadStrategy。
  3. 接著,使用驅動程式啟動瀏覽器並導航至此處.
  4. 為此,我們將記錄網頁載入完成的時間,以觀察在相同條件下,不同的Selenium頁面載入策略如何影響載入時間。載入時間的差異將有助於更清晰地理解所有策略。

專案設置

本篇關於Selenium頁面載入策略的部落格,將使用基於Java的Eclipse IDE的Maven專案。若您不偏好Eclipse,可選擇任何喜好的IDE並執行相同步驟。該專案將使用Selenium WebDriver和TestNG依賴來自動化與頁面元素的互動及測試案例執行。強烈建議使用最新穩定版本以獲得更佳效果。

現在讓我們開始吧。

  1. 啟動Eclipse或您選擇的IDE。
  2. 建立一個新的Maven專案,命名為PageLoadStrategy。
  3. 在src資料夾內,新增一個測試套件,並在其中建立一個名為TestPageLoadStrategy的測試類別。此類別將包含本次演示的所有程式碼。

4. 更新pom.xml檔案,確保包含使用TestNG於Selenium的最新依賴,如下所示,然後再撰寫實際的測試案例。

Java

 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>PageLoadStrategy</groupId>
 <artifactId>PageLoadStrategy</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <build>
   <sourceDirectory>src</sourceDirectory>
   <plugins>
     <plugin>
       <artifactId>maven-compiler-plugin</artifactId>
       <version>3.8.1</version>
       <configuration>
         <release>16</release>
       </configuration>
     </plugin>
   </plugins>
 </build>
 <dependencies>
   <dependency>
       <groupId>org.seleniumhq.selenium</groupId>
       <artifactId>selenium-java</artifactId>
       <version>4.6.0</version>
   </dependency>
   <dependency>
       <groupId>org.testng</groupId>
       <artifactId>testng</artifactId>
       <version>7.7.0</version>
       <scope>test</scope>
   </dependency>
 </dependencies>
</project>

5. 更新pom.xml後,將以下代碼添加到測試案例文件TestPageLoadStrategy.java中。該文件將包含三個測試,展示Selenium三種頁面載入策略的使用方法。

Java

 

package test;


import java.net.MalformedURLException;
import java.net.URL;
import java.time.*;
import java.util.HashMap;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.Test;


public class TestPageLoadStrategy {


   public RemoteWebDriver driver = null;
   String username = "";
   String accessKey = "";
 
  ChromeOptions chromeOptions = new ChromeOptions();
   HashMap ltOptions = new HashMap();


   private void setup(String buildName) {


       chromeOptions.setPlatformName("Windows 10");
       chromeOptions.setBrowserVersion("108.0");


       ltOptions.put("project", "Page Load Strategy");
       ltOptions.put("selenium_version", "4.0.0");
       ltOptions.put("w3c", true);
       ltOptions.put("networkThrottling", "Regular 2G");
       ltOptions.put("build", buildName);
   }


   private void checkPageLoad() {
       try {
           driver = new RemoteWebDriver(
                   new URL("https://" + username + ":" + accessKey + "@hub.lambdatest.com/wd/hub"), chromeOptions);


           Instant startTime = Instant.now();
           System.out.println("Page load started at : " + startTime.toString());
           
           System.out.println("Navigating to the URL");
           driver.get("https://ecommerce-playground.lambdatest.io/");
          
           Instant endTime = Instant.now();
           System.out.println("Page load ended at : " + endTime.toString());


           Duration duration = Duration.between(startTime, endTime);
           System.out.println("Total PageLoad time : " + duration.toMillis() + " milli seconds");
       } catch (MalformedURLException e) {
           System.out.println("Invalid grid URL");
       } finally {
           driver.quit();
       }
   }


   @Test
   public void testNormalStrategy() {
       // 設置PageLoadStrategy = 正常
       setup("Page Load Strategy - Normal");


       chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
       chromeOptions.setCapability("LT:Options", ltOptions);
       checkPageLoad();
   }


   @Test
   public void testEagerStrategy() {
       // 設置PageLoadStrategy = 急切
       setup("Page Load Strategy - Eager");
       chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
       chromeOptions.setCapability("LT:Options", ltOptions);
       checkPageLoad();
   }


   @Test
   public void testNoneStrategy() {
       // 設置PageLoadStrategy = 無
       setup("Page Load Strategy - None");
       chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
       chromeOptions.setCapability("LT:Options", ltOptions);
       checkPageLoad();
   }
}

代碼解析:TestPageLoadStrategy.java

此Java文件是展示使用不同功能實現所有策略的主要測試類。

讓我們詳細了解每一步。

步驟1。第一步是創建RemoteWebDriver的實例。這是為了能夠支持在雲端Selenium Grid上執行。

使用雲端Selenium Grid能提升Java自動化測試的擴展性和速度,並允許用戶在多種操作系統和瀏覽器組合上進行廣泛的並行和跨瀏覽器測試。

步驟2。如前一步所述,由於我們使用LambdaTest平台,我們需要提供用戶名和訪問密鑰以連接雲端中心。您可以在創建帳戶後在LambdaTest個人資料部分找到這些詳細信息。

步驟 3. 建立 ChromeOptions 類別的物件。此類別用於操控 Chrome 驅動程式的各種屬性,我們將用於執行。此 chromeOptions 物件將在每個測試案例中用於設定 PageLoadStrategy,然後傳遞給 WebDriver。

步驟 4. 建立一個名為 ltOptions 的 HashMap 變數。這將設定 LambdaTest 雲端網格執行的各種屬性。

步驟 5. 接下來是 setup() 方法,用於在 chromeOptions 和 ltOptions 中設定一些基本屬性。這些是所有三種 PageLoadStrategy 案例的共同屬性。

此外,請注意我們正在使用 LambdaTest 的 networkThrottling 屬性來將網路設定為常規 2G,下載速度為 250 Kbps,上傳速度為 50 Kbps。這將有助於在所有情境中更好地展示載入時間,如前一節所述。

使用 LambdaTest 平台提供這一優勢,您可以直接選擇瀏覽器和版本詳細信息,並且您的功能會自動使用 LambdaTest 功能生成器生成。您只需將它們添加到代碼中。

此方法接受一個參數 buildName。此參數用於顯示構建名稱。

步驟 6. 添加一個新函數,checkPageLoad()。在 try 區塊中,我們編寫代碼以使用在 chromeOptions 中定義的屬性連接到 LambdaTest 平台上的 RemoteWebDriver。

連線建立後,我們創建Java.time套件中的Instant類別物件,用以儲存並記錄即將啟動瀏覽器及開始導航時的起始時間。接著呼叫驅動程式至瀏覽器並啟動測試網站。

一旦網站依據設定的PageLoadStrategy被視為已載入,驅動程式便將控制權交給下一個指令,此指令同樣是Instant類別的物件,用以再次獲取當前時間,即結束時間。

至此,網頁已按照我們要求的策略載入,且我們已取得起始與結束時間。透過計算兩點之間的差異,可以確定網頁載入所需的毫秒數。Duration類別,同屬於該套件,用以完成此任務。

你將注意到,依據不同策略,此載入時間在我們所有的測試案例中皆有所不同。

A catch block is added next for the try block to handle the exception if it occurs. MalformedURLException is to catch the exception in case our RemoteWebDriver URL has invalid syntax. Once everything is done, we finally close the driver instance. To learn more about it, you can go through this blog on the most common exceptions in Selenium.

testNormalStrategy()

此為展示正常策略的測試案例。

首先,setup()方法定義了瀏覽器及LambdaTest平台的基本屬性。接著,在此處的chromeOptions中將PageLoadStrategy設定為NORMAL,隨後設定其他功能。

最後,呼叫checkPageLoad()方法以載入網頁並記錄載入時間,我們將在執行部分比較各策略的載入時間。

testEagerStrategy()

此為展示急切策略的測試案例。

在此情況下,所有步驟與先前類似,唯一不同的是在chromeOptions中將PageLoadStrategy設置為EAGER,隨後調用checkPageLoad()方法。

testNoneStrategy()

此測試案例旨在展示None策略。

在chromeOptions中將PageLoadStrategy的值設為NONE,其餘步驟與先前討論的測試案例相似。

測試執行

理解了所有PageLoadStrategy的工作原理與實現後,現在讓我們執行代碼,並在本地與LambdaTest儀表板上查看執行結果。

該測試案例將使用TestNG執行。執行步驟如下:

  1. 在Eclipse IDE中右鍵點擊測試案例名稱。
  2. 選擇Run Test,然後點選TestNG Test以開始執行。

讓我們逐一執行這些案例,並觀察每種策略的加載時間是否有所不同。

NORMAL Strategy

在此情況下,您會注意到TotalPageLoad時間為70852毫秒,因為我們使用的是常規2G網絡速度。已知此值應為三種情況中最高。迄今為止的討論表明,它應該是三者中最高的。我們可以通過運行Eager和None案例並進行比較來驗證這一點。

EAGER Strategy

如預期,在相同情況下,Eager策略的PageLoadTime即70231毫秒,相對於Normal策略較少。

NONE Strategy

您可以在此注意到,None策略的PageLoadTime明顯低於其他兩種策略,因為它不等待任何資源下載。

以下是不同策略中頁面載入時間的快速總結

PageLoadStrategy PageLoadTime (in milliseconds)
Normal 70852
Eager 70231
None 28908

您也可以通過導航至LambdaTest儀表板查看每種PageLoadStrategy的執行結果,如下所示:

您可以前往自動化下的構建部分查看您的自動化構建的詳細信息。

PageLoadStrategy.NORMAL的構建詳情:

PageLoadStrategy.EAGER的構建詳情:

PageLoadStrategy.NONE的構建詳情:


結論

至此,我們已經完成了這個Selenium TestNG教程,探討了Selenium WebDriver中不同的頁面載入策略。在這裡,我們學習了這些Selenium頁面載入策略的進一步使用和運作方式,以及如何將它們整合到自動化腳本中,並在Selenium雲端網格上執行。

I hope now you can implement these in your use cases more efficiently.

愉快的載入!

Source:
https://dzone.com/articles/a-complete-guide-to-selenium-page-load-strategy