控制代碼
介紹
Playwright 可以建立指向頁面 DOM 元素或頁面內任何其他物件的控制代碼。這些控制代碼存在於 Playwright 程序中,而實際物件則存在於瀏覽器中。控制代碼有兩種型別
- JSHandle 以參照頁面中的任何 JavaScript 物件
- ElementHandle 以參照頁面中的 DOM 元素,它具有額外的方法,可讓您對元素執行動作並斷言其屬性。
由於頁面中的任何 DOM 元素也是 JavaScript 物件,因此任何 ElementHandle 也都是 JSHandle。
控制代碼用於對頁面中的那些實際物件執行操作。您可以在控制代碼上評估、取得控制代碼屬性、將控制代碼作為評估參數傳遞、將頁面物件序列化為 JSON 等。請參閱 JSHandle 類別 API 以取得這些方法。
API 參考
以下是取得 JSHandle 最簡單的方式。
JSHandle jsHandle = page.evaluateHandle("window");
// Use jsHandle for evaluations.
元素控制代碼
不建議使用 ElementHandle,請改用 Locator 物件和網頁優先的斷言。
當需要 ElementHandle 時,建議使用 Page.waitForSelector() 或 Frame.waitForSelector() 方法來擷取它。這些 API 會等待元素附加並可見。
// Get the element handle
JSHandle jsHandle = page.waitForSelector("#box");
ElementHandle elementHandle = jsHandle.asElement();
// Assert bounding box for the element
BoundingBox boundingBox = elementHandle.boundingBox();
assertEquals(100, boundingBox.width);
// Assert attribute for the element
String classNames = elementHandle.getAttribute("class");
assertTrue(classNames.contains("highlighted"));
將控制代碼作為參數
控制代碼可以傳遞到 Page.evaluate() 和類似方法中。以下程式碼片段會在頁面中建立新的陣列,使用資料初始化它,並將指向此陣列的控制代碼傳回 Playwright。然後,它會在後續評估中使用該控制代碼
// Create new array in page.
JSHandle myArrayHandle = page.evaluateHandle("() => {\n" +
" window.myArray = [1];\n" +
" return myArray;\n" +
"}");
// Get the length of the array.
int length = (int) page.evaluate("a => a.length", myArrayHandle);
// Add one more element to the array using the handle
Map<String, Object> arg = new HashMap<>();
arg.put("myArray", myArrayHandle);
arg.put("newElement", 2);
page.evaluate("arg => arg.myArray.add(arg.newElement)", arg);
// Release the object when it is no longer needed.
myArrayHandle.dispose();
控制代碼生命週期
可以使用頁面方法取得控制代碼,例如 Page.evaluateHandle()、Page.querySelector() 或 Page.querySelectorAll() 或其框架對應項 Frame.evaluateHandle()、Frame.querySelector() 或 Frame.querySelectorAll()。建立後,控制代碼將保留來自 垃圾回收 的物件,除非頁面導航或控制代碼透過 JSHandle.dispose() 方法手動處置。
API 參考
- JSHandle
- ElementHandle
- ElementHandle.boundingBox()
- ElementHandle.getAttribute()
- ElementHandle.innerText()
- ElementHandle.innerHTML()
- ElementHandle.textContent()
- JSHandle.evaluate()
- Page.evaluateHandle()
- Page.querySelector()
- Page.querySelectorAll()
Locator 與 ElementHandle
我們僅建議在極少數情況下使用 ElementHandle,當您需要在靜態頁面上執行廣泛的 DOM 遍歷時。對於所有使用者動作和斷言,請改用 locator。
Locator 和 ElementHandle 之間的差異在於,後者指向特定的元素,而 Locator 擷取如何擷取該元素的邏輯。
在以下範例中,控制代碼指向頁面上的特定 DOM 元素。如果該元素變更文字或由 React 用於呈現完全不同的元件,則控制代碼仍然指向該非常陳舊的 DOM 元素。這可能會導致非預期的行為。
ElementHandle handle = page.querySelector("text=Submit");
handle.hover();
handle.click();
使用 locator,每次使用 locator 時,都會使用選取器在頁面中找到最新的 DOM 元素。因此,在以下程式碼片段中,基礎 DOM 元素將被找到兩次。
Locator locator = page.getByText("Submit");
locator.hover();
locator.click();