Skip to main content
Intuned’s runtime is built on top of Playwright, the open-source browser automation framework. When you’re writing deterministic automation code, you’ll mostly be using Playwright directly. In Intuned, you deploy code-based Projects containing APIs. Each API is a handler function that receives a browser page and context, along with any parameters you define:
Page is your browser tab—where you navigate, find elements, interact, and extract data. BrowserContext is an isolated browser session with its own cookies, storage, and cache (like an incognito window). Intuned handles browser initialization and context creation; you just use the page and context you receive. This guide covers Playwright concepts and patterns you’ll use when building automations. If you want to jump straight into code, check out the Playwright basics project in the Intuned TypeScript cookbook or the Playwright basics project in the Python cookbook.

Basics

Navigate to a page with goto():

Wait for page load

After navigation, you may need to wait for the page to fully load. Playwright provides waitForLoadState():

Wait for URL

Wait for the page to navigate to a specific URL pattern:

Create new pages

Intuned initializes one page by default—the page you receive in your handler. You can create additional pages to run operations in parallel. Both pages run in the same browser on the same machine:

Handle new tabs and popups

When a click opens a new tab (like target="_blank" links), capture it with waitForEvent:
For popups, use the popup event:

Finding elements

Locators are the primary way to find elements in Playwright. They’re lazy—not evaluated until you interact with them:

CSS vs XPath selectors

CSS selector extensions

When using page.locator() with CSS selectors, Playwright adds special pseudo-classes that aren’t available in standard CSS:
For more details, see the Playwright locators documentation.

Semantic locators

Instead of CSS selectors, Playwright provides methods that find elements by their semantic meaning—role, label, placeholder, or test ID. These are more resilient to markup changes and make your code easier to read: getByRole() — Find by ARIA role and accessible name:
getByText() — Find by visible text:
getByLabel() — Find form fields by their label:
getByPlaceholder() — Find inputs by placeholder text:
getByAltText() — Find images by alt text:
getByTitle() — Find by title attribute:
getByTestId() — Find by data-testid attribute:

Chaining and filtering

When a locator matches multiple elements, narrow it down:

Combining locators

Combine locators with and() and or():

Checking element state

Strict mode: Playwright requires locators to match exactly one element. If your locator matches zero or multiple elements, you’ll get a strict mode violation error. Use .first(), .nth(), or .filter() to be specific.

Auto-waiting and timeouts

Playwright automatically waits for elements to be ready before performing actions. This auto-waiting happens within a configurable timeout (30 seconds by default). Understanding this helps you write reliable automations without unnecessary delays.

What Playwright waits for

When you call an action like click() or fill(), Playwright automatically waits until the element is: This means you rarely need explicit waits before actions:

When you need explicit waits

Use explicit waits when:
  • Waiting for elements to appear or disappear (loading spinners)
  • Waiting for navigation to complete
  • Waiting for network requests to finish
Wait for elements:
Wait for network requests:
Avoid waitForTimeout() (fixed delays). Waiting for specific elements or network states is more reliable and faster.
For more reliable waiting, the Intuned SDK offers waitForDomSettled and withNetworkSettledWait helpers.

Configuring timeouts

The timeout controls how long Playwright waits during auto-waiting before throwing an error. The default is 30 seconds. Default timeout — Set for all actions on a page:
Per-action timeout — Override for specific actions:

Extracting data

Text content

Extract the visible text from elements:

Attributes

Extract values from HTML attributes like href, src, data-*:

Bulk extraction

Use all() to get all matching elements as an array, then extract data from each:
all() returns an empty array if no elements match. If you need to wait for elements first, use waitForSelector() before calling all().
For simple cases where you only need text from a single selector, allTextContents() and allInnerTexts() are convenience methods:

Lists and iteration

Loop through multiple elements using count() and nth():

Input values

In rare cases, you may need to read the current value from form inputs—for example, when scraping pre-filled forms or verifying form state:
The Intuned SDK provides helper functions that simplify common data extraction patterns. These handle edge cases and reduce boilerplate: See the Pagination recipe for multi-page scraping patterns.

Performing actions

Clicking

Double-click

Hover

Force click

Use force: true when you know the element is there but Playwright’s actionability checks fail (e.g., element is covered by an overlay you want to ignore):
Use force sparingly. If you’re using it frequently, there may be a better way to handle the interaction.

Text input

Type character by character

Use pressSequentially() when a page has special keyboard handling that doesn’t work with fill():

Keyboard actions

Forms

Checkboxes and radio buttons

Handling dialogs

JavaScript dialogs (alert, confirm, prompt) block the page until handled. Set up a listener before the action that triggers the dialog:
For one-time dialog handling:
If you don’t handle a dialog, it will auto-dismiss, but the page may hang waiting for it. Always set up dialog handlers before triggering actions that show dialogs.

File uploads

File downloads

Listen for the download event before triggering the download:
The Intuned SDK provides helpers that simplify file handling and cloud storage: See the download file recipe and upload to S3 recipe.

Complete form filling example

Advanced topics

Working with frames

Frames (iframes) embed a separate webpage inside another. You can’t interact with iframe content directly from the main page—you need to enter the frame context first.
Use frameLocator() to interact with iframe content:
For lower-level control, use contentFrame():
Shadow DOM: Playwright automatically pierces open shadow DOM—no special handling needed. Your regular locators will find elements inside shadow roots.

Screenshots

Network interception

Intercept and modify network requests using route().

Block resources

Speed up automations by blocking unnecessary resources:

Modify requests

For more interception patterns, see the network interception recipe.

Executing JavaScript

Use page.evaluate() when you need to access or manipulate the DOM directly, execute custom JavaScript, or access page-level variables.

Scrolling

DOM manipulation

Pass arguments to evaluate

Making API requests

Playwright provides a built-in API client through page.request that shares the browser’s cookies and session:

Cookies and storage

In most cases, you won’t need to manage cookies directly—especially if you use AuthSessions, which handle authentication and session state automatically. The methods below are included for reference when you need low-level control.

Read cookies

Set cookies

Clear cookies

Access localStorage and sessionStorage

Drag and drop