Playwright can search for elements using CSS selectors, XPath selectors, HTML attributes like `id`, `data-test-id` and even text content.
You can explicitly specify the selector engine you are using or let Playwright detect it.
All selector engines except for XPath pierce shadow DOM by default. If you want to enforce regular DOM selection, you can use the `*:light` versions of the selectors. You don't typically need to though.
Learn more about selectors and selector engines [here](./selectors.md).
Some examples below:
```js
// Using data-test-id= selector engine
await page.click('data-test-id=foo');
```
```js
// CSS and XPath selector engines are automatically detected
await page.click('div');
await page.click('//html/body/div');
```
```js
// Find node by text substring
await page.click('text=Hello w');
```
```js
// Explicit CSS and XPath notation
await page.click('css=div');
await page.click('xpath=//html/body/div');
```
```js
// Only search light DOM, outside WebComponent shadow DOM:
await page.click('css:light=div');
```
Selectors using the same or different engines can be combined using the `>>` separator. For example,
```js
// Click an element with text 'Sign Up' inside of a #free-month-promo.
Playwright scripts run in your Node.js environment. Your page scripts run in the browser page environment. Those environments don't intersect, they are running in different virtual machines in different processes and even potentially on different computers.
The [`method: Page.evaluate`] API can run a JavaScript function in the context
of the web page and bring results back to the Node.js environment. Browser globals like
`window` and `document` can be used in `evaluate`.
Playwright evaluation methods like [`method: Page.evaluate`] take a single optional argument. This argument can be a mix of [Serializable] values and [JSHandle] or [ElementHandle] instances. Handles are automatically converted to the value they represent.
Playwright can create Node-side handles to the page DOM elements or any other objects inside the page. These handles live in the Node.js process, whereas the actual objects reside in browser.
There are two types of handles:
- [JSHandle] to reference any JavaScript objects in the page
- [ElementHandle] to reference DOM elements in the page
Note that since any DOM element in the page is also a JavaScript object,
Playwright's [ElementHandle] extends [JSHandle].
### Handles Lifecycle
- Handles can be acquired using the page methods [`method: Page.evaluateHandle`], [`method: Page.$`] or [`method: Page.$$`] or
their frame counterparts [`method: Frame.evaluateHandle`], [`method: Frame.$`] or [`method: Frame.$$`].
- Once created, handles will retain object from [garbage collection](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management).
- Handles will be **automatically disposed** once the page or frame they belong to navigates or closes.
- Handles can be **manually disposed** using [`method: JSHandle.dispose`] method.
### Example: ElementHandle
```js
// The first parameter of the elementHandle.evaluate callback is the element handle points to.