# Selenium Browser Automation Runner (`produkdigitalali/selenium-browser-automation-runner`) Actor

Run declarative browser automation workflows with Selenium WebDriver, including navigation, clicks, form input, extraction, assertions, waits, and screenshots.

- **URL**: https://apify.com/produkdigitalali/selenium-browser-automation-runner.md
- **Developed by:** [ProdukDigitalAli](https://apify.com/produkdigitalali) (community)
- **Categories:** Developer tools, Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Selenium Browser Automation Runner

Run repeatable browser automation workflows in the cloud with **Selenium WebDriver + Chrome**.

This Actor is designed for developers, QA engineers, automation teams, data workflows, and AI/agent pipelines that need browser interactions without maintaining their own Selenium infrastructure.

### What it can do

Build a workflow from ordered JSON actions such as:

- navigate to another public URL
- wait for an element
- click elements
- type into inputs
- clear inputs
- select dropdown options
- extract visible text
- extract element attributes
- read the page title and current URL
- assert that page text, title, or URL contains an expected value
- capture screenshots
- pause between actions

Each executed action produces **one structured result** in the default Apify dataset. Screenshot actions also save PNG files to the default key-value store.

### Supported selector strategies

Selenium supports several locator strategies. Set `selectorType` to one of:

| selectorType | Selenium locator |
|---|---|
| `css` | CSS selector |
| `xpath` | XPath |
| `id` | Element ID |
| `name` | `name` attribute |
| `className` | Class name |
| `tagName` | HTML tag name |
| `linkText` | Exact link text |
| `partialLinkText` | Partial link text |

If `selectorType` is omitted, `css` is used.

### Quick start

The prefilled input opens `https://example.com`, reads the page title, waits for the main heading, extracts it, and captures a screenshot.

Example:

```json
{
  "startUrl": "https://example.com",
  "stopOnError": true,
  "actions": [
    {
      "type": "getTitle",
      "label": "Read page title"
    },
    {
      "type": "waitForSelector",
      "label": "Wait for heading",
      "selectorType": "css",
      "selector": "h1",
      "state": "visible"
    },
    {
      "type": "extractText",
      "label": "Read heading text",
      "selectorType": "css",
      "selector": "h1"
    },
    {
      "type": "screenshot",
      "label": "Capture page"
    }
  ]
}
```

### Action reference

#### `goto`

Navigate to another public HTTP/HTTPS URL.

```json
{
  "type": "goto",
  "url": "https://example.com/docs",
  "label": "Open docs"
}
```

#### `waitForSelector`

Wait until an element reaches a requested state.

Supported states: `present`, `visible`, `clickable`, `hidden`.

```json
{
  "type": "waitForSelector",
  "selectorType": "css",
  "selector": "button[type='submit']",
  "state": "clickable"
}
```

#### `click`

Wait for an element to become clickable, then click it.

```json
{
  "type": "click",
  "selectorType": "xpath",
  "selector": "//button[contains(., 'Submit')]"
}
```

#### `type`

Type text into a visible element. Set `clearFirst` to `true` when you want to clear the field before typing.

```json
{
  "type": "type",
  "selectorType": "name",
  "selector": "email",
  "text": "demo@example.com",
  "clearFirst": true
}
```

#### `clear`

Clear an input element.

```json
{
  "type": "clear",
  "selectorType": "id",
  "selector": "search"
}
```

#### `select`

Select an HTML `<select>` option. `selectBy` can be `value`, `text`, or `index`.

```json
{
  "type": "select",
  "selector": "select[name='country']",
  "selectBy": "value",
  "value": "ID"
}
```

#### `extractText`

Return visible element text.

```json
{
  "type": "extractText",
  "selectorType": "css",
  "selector": "h1"
}
```

#### `extractAttribute`

Return an element attribute/property value as exposed by Selenium.

```json
{
  "type": "extractAttribute",
  "selectorType": "css",
  "selector": "a.download",
  "attribute": "href"
}
```

#### `getTitle`

Return the current page title.

```json
{ "type": "getTitle" }
```

#### `getUrl`

Return the current browser URL.

```json
{ "type": "getUrl" }
```

#### `textContains`

Wait until an element (or the page body when no selector is supplied) contains expected text.

```json
{
  "type": "textContains",
  "selector": "#message",
  "text": "Received!"
}
```

#### `titleContains`

Wait until the document title contains expected text.

```json
{
  "type": "titleContains",
  "text": "Dashboard"
}
```

#### `urlContains`

Wait until the browser URL contains expected text.

```json
{
  "type": "urlContains",
  "text": "submitted-form"
}
```

#### `screenshot`

Capture the current browser viewport as PNG. The dataset item contains the artifact URL.

```json
{
  "type": "screenshot",
  "label": "After submit"
}
```

#### `wait`

Pause the workflow. Maximum: 300000 ms (5 minutes).

```json
{
  "type": "wait",
  "milliseconds": 1000
}
```

### Per-action timeout

The Actor uses `actionTimeoutSeconds` as the default timeout for waits and assertions. Any selector-based action can override it:

```json
{
  "type": "waitForSelector",
  "selector": ".slow-widget",
  "timeoutSeconds": 45
}
```

### Output

Each action writes one item to the default dataset:

```json
{
  "passed": true,
  "step": 3,
  "label": "Read heading text",
  "action": "extractText",
  "selectorType": "css",
  "selector": "h1",
  "currentUrl": "https://example.com/",
  "value": "Example Domain",
  "error": null,
  "artifactUrl": null,
  "artifactType": null
}
```

Failed actions are also saved with `passed: false` and an error message. If `stopOnError` is enabled, execution ends after the failed step; otherwise the workflow continues.

### Example: form automation

```json
{
  "startUrl": "https://www.selenium.dev/selenium/web/web-form.html",
  "stopOnError": true,
  "actions": [
    {
      "type": "waitForSelector",
      "selectorType": "name",
      "selector": "my-text",
      "state": "visible"
    },
    {
      "type": "type",
      "selectorType": "name",
      "selector": "my-text",
      "text": "ProdukDigitalAli"
    },
    {
      "type": "select",
      "selectorType": "name",
      "selector": "my-select",
      "selectBy": "value",
      "value": "2"
    },
    {
      "type": "click",
      "selectorType": "css",
      "selector": "button"
    },
    {
      "type": "waitForSelector",
      "selectorType": "id",
      "selector": "message",
      "state": "visible"
    },
    {
      "type": "extractText",
      "selectorType": "id",
      "selector": "message"
    },
    {
      "type": "urlContains",
      "text": "submitted-form"
    },
    {
      "type": "textContains",
      "selectorType": "id",
      "selector": "message",
      "text": "Received!"
    },
    {
      "type": "screenshot",
      "label": "Submitted form"
    }
  ]
}
```

### Safety and limits

- Only public `http://` and `https://` URLs can be supplied as `startUrl` or `goto` destinations.
- Localhost, private, loopback, link-local, reserved, multicast, and unspecified IP targets are rejected.
- A maximum of 100 actions is accepted per run.
- A single `wait` action is limited to five minutes.
- Websites can change their DOM at any time; use stable selectors and reasonable waits.
- Automated access may be restricted by a website's terms, authentication requirements, bot protection, or applicable law. Use the Actor only where you are authorized to automate access.

### Selenium vs. the other browser runners

This Actor is intentionally Selenium/WebDriver-focused. It is useful when your existing test or automation knowledge is based on Selenium locator strategies and WebDriver-style interactions.

- **Cypress Website Test Runner**: QA/smoke testing and assertions using Cypress.
- **Puppeteer Browser Automation Runner**: high-level browser workflows using Puppeteer.
- **Chrome DevTools Automation Runner**: low-level Chrome DevTools Protocol operations.
- **Selenium Browser Automation Runner**: WebDriver workflows and Selenium locator strategies.

### Running through the API

After publishing, the Actor can be started from Apify Console, schedules, integrations, or the Apify API. Results are available from the default dataset, while screenshots are stored in the default key-value store.

### Notes

Selenium and Chrome run inside the Actor container. For the best reliability, prefer deterministic selectors, explicit waits, and small workflows that perform one clear automation job.

# Actor input Schema

## `startUrl` (type: `string`):

Public HTTP/HTTPS page opened before the workflow starts. Private and localhost targets are blocked.

## `actions` (type: `array`):

Ordered Selenium workflow. Supported actions: goto, waitForSelector, click, type, clear, select, extractText, extractAttribute, getTitle, getUrl, textContains, titleContains, urlContains, screenshot, wait. Selector types: css, xpath, id, name, className, tagName, linkText, partialLinkText.

## `stopOnError` (type: `boolean`):

Stop the workflow after the first failed action. Turn this off to save failed steps and continue with later actions.

## `actionTimeoutSeconds` (type: `integer`):

Default timeout for selector waits and assertions.

## `pageLoadTimeoutSeconds` (type: `integer`):

Maximum time Selenium waits for a page navigation to complete.

## `windowWidth` (type: `integer`):

Browser window width in pixels.

## `windowHeight` (type: `integer`):

Browser window height in pixels.

## `userAgent` (type: `string`):

Optional custom Chrome user-agent string.

## Actor input object example

```json
{
  "startUrl": "https://example.com",
  "actions": [
    {
      "type": "getTitle",
      "label": "Read page title"
    },
    {
      "type": "waitForSelector",
      "label": "Wait for heading",
      "selectorType": "css",
      "selector": "h1",
      "state": "visible"
    },
    {
      "type": "extractText",
      "label": "Read heading text",
      "selectorType": "css",
      "selector": "h1"
    },
    {
      "type": "screenshot",
      "label": "Capture page"
    }
  ],
  "stopOnError": true,
  "actionTimeoutSeconds": 15,
  "pageLoadTimeoutSeconds": 30,
  "windowWidth": 1365,
  "windowHeight": 768
}
```

# Actor output Schema

## `results` (type: `string`):

One dataset item per executed browser action.

## `artifacts` (type: `string`):

Screenshot files generated by screenshot actions.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("produkdigitalali/selenium-browser-automation-runner").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("produkdigitalali/selenium-browser-automation-runner").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call produkdigitalali/selenium-browser-automation-runner --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,produkdigitalali/selenium-browser-automation-runner"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/3SHs9SYN5tXxGjHWu/builds/ltaYvg0kBaZQezkPu/openapi.json
