ハンドル
はじめに
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()
ロケーターとElementHandleの比較
静的なページで広範なDOMトラバーサルを実行する必要があるまれなケースでのみ、ElementHandleの使用を推奨します。すべてのユーザーアクションとアサーションには、代わりにロケーターを使用してください。
LocatorとElementHandleの違いは、後者が特定の要素を指すのに対し、ロケーターはその要素を取得する方法のロジックをカプセル化する点です。
以下の例では、ハンドルはページの特定の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();