Skip to main content
Version: 1.15


Playwright can create handles to the page DOM elements or any other objects inside the page. These handles live in the Playwright process, whereas the actual objects live in the browser. There are two types of handles:

  • JSHandle to reference any JavaScript objects in the page
  • ElementHandle to reference DOM elements in the page, it has extra methods that allow performing actions on the elements and asserting their properties.

Since any DOM element in the page is also a JavaScript object, any ElementHandle is a JSHandle as well.

Handles are used to perform operations on those actual objects in the page. You can evaluate on a handle, get handle properties, pass handle as an evaluation parameter, serialize page object into JSON etc. See the JSHandle class API for these and methods.

API reference#

Here is the easiest way to obtain a JSHandle.

js_handle = page.evaluate_handle('window')#  Use jsHandle for evaluations.
ul_element_handle = page.wait_for_selector('ul')#  Use ul_element_handle for actions and evaluation.

Element Handles#


It is recommended to use selector-based actions like, **kwargs) rather than using the ElementHandle for input actions, unless your use case specifically requires the use of handles.

When ElementHandle is required, it is recommended to fetch it with the page.wait_for_selector(selector, **kwargs) or frame.wait_for_selector(selector, **kwargs) methods. These APIs wait for the element to be attached and visible.

# Get the element handleelement_handle = page.wait_for_selector('#box')
# Assert bounding box for the elementbounding_box = element_handle.bounding_box()assert bounding_box.width == 100
# Assert attribute for the elementclass_names = element_handle.get_attribute('class')assert 'highlighted' in class_names

Handles as parameters#

Handles can be passed into the page.evaluate(expression, **kwargs) and similar methods. The following snippet creates a new array in the page, initializes it with data and returns a handle to this array into Playwright. It then uses the handle in subsequent evaluations:

# Create new array in page.my_array_handle = page.evaluate_handle("""() => {  window.myArray = [1];  return myArray;}""")
# Get current length of the array.length = page.evaluate("a => a.length", my_array_handle)
# Add one more element to the array using the handlepage.evaluate("(arg) => arg.myArray.push(arg.newElement)", {  'myArray': my_array_handle,  'newElement': 2})
# Release the object when it's no longer needed.my_array_handle.dispose()

Handle Lifecycle#

Handles can be acquired using the page methods such as page.evaluate_handle(expression, **kwargs), page.query_selector(selector, **kwargs) or page.query_selector_all(selector) or their frame counterparts frame.evaluate_handle(expression, **kwargs), frame.query_selector(selector, **kwargs) or frame.query_selector_all(selector). Once created, handles will retain object from garbage collection unless page navigates or the handle is manually disposed via the js_handle.dispose() method.

API reference#