ハンドル
はじめに
Playwrightは、ページDOM要素またはページ内のその他のオブジェクトへのハンドルを作成できます。これらのハンドルはPlaywrightプロセス内に存在しますが、実際のオブジェクトはブラウザ内に存在します。ハンドルには2つのタイプがあります。
- JSHandle は、ページ内の任意のJavaScriptオブジェクトを参照します。
- ElementHandle は、ページ内のDOM要素を参照します。要素に対してアクションを実行したり、そのプロパティをアサートしたりできる追加のメソッドを持っています。
ページ内の任意のDOM要素もJavaScriptオブジェクトであるため、すべてのElementHandle は JSHandle でもあります。
ハンドルは、ページ内の実際のオブジェクトに対して操作を実行するために使用されます。ハンドル上で評価したり、ハンドルのプロパティを取得したり、評価パラメータとしてハンドルを渡したり、ページオブジェクトをJSONにシリアル化したりできます。これらのメソッドについては、JSHandle クラスAPIを参照してください。
API リファレンス
JSHandle を取得する最も簡単な方法は次のとおりです。
const jsHandle = await page.evaluateHandle('window');
// Use jsHandle for evaluations.
要素ハンドル
ElementHandle の使用は推奨されません。Locator オブジェクトとweb-firstアサーションを使用してください。
ElementHandle が必要な場合は、page.waitForSelector() または frame.waitForSelector() メソッドで取得することをお勧めします。これらのAPIは、要素がアタッチされ、表示されるまで待機します。
// Get the element handle
const elementHandle = page.waitForSelector('#box');
// Assert bounding box for the element
const boundingBox = await elementHandle.boundingBox();
expect(boundingBox.width).toBe(100);
// Assert attribute for the element
const classNames = await elementHandle.getAttribute('class');
expect(classNames.includes('highlighted')).toBeTruthy();
パラメータとしてのハンドル
ハンドルは、page.evaluate() および類似のメソッドに渡すことができます。次のスニペットは、ページに新しい配列を作成し、データを初期化し、この配列へのハンドルをPlaywrightに返します。その後、後続の評価でハンドルを使用します。
// Create new array in page.
const myArrayHandle = await page.evaluateHandle(() => {
window.myArray = [1];
return myArray;
});
// Get the length of the array.
const length = await page.evaluate(a => a.length, myArrayHandle);
// Add one more element to the array using the handle
await page.evaluate(arg => arg.myArray.push(arg.newElement), {
myArray: myArrayHandle,
newElement: 2
});
// Release the object when it's no longer needed.
await myArrayHandle.dispose();
ハンドルライフサイクル
ハンドルは、page.evaluateHandle()、page.$()、page.$$() などのページメソッド、またはそれらに対応するフレームメソッド frame.evaluateHandle()、frame.$()、frame.$$() を使用して取得できます。一度作成されたハンドルは、ページがナビゲートされるか、jsHandle.dispose() メソッドを介して手動で破棄されない限り、ガベージコレクションからオブジェクトを保持します。
APIリファレンス
- JSHandle
- ElementHandle
- elementHandle.boundingBox()
- elementHandle.getAttribute()
- elementHandle.innerText()
- elementHandle.innerHTML()
- elementHandle.textContent()
- jsHandle.evaluate()
- page.evaluateHandle()
- page.$()
- page.$$()
LocatorとElementHandleの比較
静的ページで広範なDOMトラバースを実行する必要があるまれなケースでのみ、ElementHandle の使用を推奨します。すべてのユーザーアクションとアサーションには、代わりにロケーターを使用してください。
Locator と ElementHandle の違いは、後者が特定の要素を指すのに対し、Locatorはその要素を取得する方法のロジックをキャプチャすることです。
以下の例では、ハンドルはページの特定のDOM要素を指しています。その要素のテキストが変更されたり、Reactによって全く異なるコンポーネントがレンダリングされたりしても、ハンドルは依然としてその古いDOM要素を指しています。これは予期せぬ動作につながる可能性があります。
const handle = await page.$('text=Submit');
// ...
await handle.hover();
await handle.click();
ロケーターを使用すると、ロケーターが使用されるたびに、セレクターを使用してページ内の最新のDOM要素が特定されます。したがって、以下のスニペットでは、基になるDOM要素が2回特定されることになります。
const locator = page.getByText('Submit');
// ...
await locator.hover();
await locator.click();