ハンドル
はじめに
Playwright は、ページ DOM 要素またはページ内のその他のオブジェクトへのハンドルを作成できます。これらのハンドルは Playwright プロセスに存在しますが、実際のオブジェクトはブラウザに存在します。ハンドルには 2 種類あります。
- JSHandle ページ内の任意の JavaScript オブジェクトを参照します。
- ElementHandle ページ内の DOM 要素を参照します。要素に対してアクションを実行したり、プロパティをアサートしたりするための追加メソッドがあります。
ページ内の DOM 要素は JavaScript オブジェクトでもあるため、任意の ElementHandle は JSHandle でもあります。
ハンドルは、ページ内の実際のオブジェクトに対して操作を実行するために使用されます。ハンドルで評価したり、ハンドルのプロパティを取得したり、評価パラメータとしてハンドルを渡したり、ページオブジェクトを JSON にシリアライズしたりできます。これらのメソッドの詳細については、JSHandle クラス API を参照してください。
API リファレンス
JSHandle を取得する最も簡単な方法を次に示します。
JSHandle jsHandle = page.evaluateHandle("window");
// Use jsHandle for evaluations.
要素ハンドル
ElementHandle の使用は推奨されません。代わりに Locator オブジェクトと Web ファーストのアサーションを使用してください。
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()
ロケーター vs 要素ハンドル
ElementHandle は、静的なページで広範な DOM トラバーサルを実行する必要があるまれなケースでのみ使用することをお勧めします。すべてのユーザーアクションとアサーションには、代わりにロケーターを使用してください。
Locator と ElementHandle の違いは、後者が特定の要素を指すのに対し、Locator はその要素を取得する方法のロジックをキャプチャすることです。
以下の例では、ハンドルはページ上の特定の DOM 要素を指しています。その要素のテキストが変更されたり、React によってまったく異なるコンポーネントをレンダリングするために使用されたりした場合でも、ハンドルは依然として非常に古い DOM 要素を指しています。これは、予期しない動作につながる可能性があります。
ElementHandle handle = page.querySelector("text=Submit");
handle.hover();
handle.click();
ロケーターを使用すると、ロケーターが使用されるたびに、最新の DOM 要素がセレクターを使用してページ内で検索されます。したがって、以下のスニペットでは、基になる DOM 要素が 2 回検索されます。
Locator locator = page.getByText("Submit");
locator.hover();
locator.click();