Skip to main content

Overview

AutoMFlows uses Playwright under the hood to provide powerful browser automation capabilities. This guide covers all browser-related nodes and advanced automation techniques.

Supported Browsers

AutoMFlows supports three browser engines:

Chromium

Google Chrome, Microsoft Edge, and other Chromium-based browsers

Firefox

Mozilla Firefox

WebKit

Safari (WebKit engine)

Opening a Browser

Every browser automation workflow starts with the Open Browser node.
{
  "id": "openBrowser-1",
  "type": "openBrowser",
  "data": {
    "label": "Open Browser",
    "headless": false,
    "browser": "chromium",
    "viewportWidth": 1280,
    "viewportHeight": 720,
    "maxWindow": true,
    "stealthMode": false
  }
}
Run browser without UI (faster, uses less memory):
{
  "headless": true
}
Headless mode is ideal for CI/CD pipelines and background automation tasks.
The Navigation node controls page navigation and browser history.
{
  "type": "navigation",
  "data": {
    "label": "Navigate to Homepage",
    "action": "navigate",
    "url": "https://sauce-demo.myshopify.com/",
    "waitUntil": "networkidle",
    "timeout": 30000
  }
}
The URL is automatically normalized. If no protocol is specified, https:// is added automatically.

Wait Strategies

The waitUntil option controls when navigation is considered complete:
Wait for the load event (page fully loaded):
{ "waitUntil": "load" }

Browser History

// Go back
{
  "action": "goBack",
  "waitUntil": "networkidle"
}

// Go forward
{
  "action": "goForward",
  "waitUntil": "networkidle"
}

// Reload page
{
  "action": "reload",
  "waitUntil": "networkidle"
}

Interacting with Elements

Click Actions

The Action node handles all click-based interactions.
{
  "type": "action",
  "data": {
    "label": "Click Sign Up Button",
    "action": "click",
    "selector": "a:has-text(\"Sign up\")",
    "selectorType": "css",
    "timeout": 30000
  }
}
{
  "action": "click",
  "selector": "button.submit",
  "selectorType": "css",
  "button": "left"  // left, right, middle
}

Selector Strategies

AutoMFlows supports three selector types:
button.submit
#login-form
input[type="email"]
div.container > p:first-child
a:has-text("Sign up")
CSS selectors are the default and most commonly used. Playwright extends CSS with :has-text() for content matching.

Form Input

Use the Form Input node to fill form fields:
{
  "type": "formInput",
  "data": {
    "label": "Enter Email",
    "selector": "input[name='customer[email]']",
    "value": "[email protected]",
    "selectorType": "css",
    "clearBefore": true,  // Clear field before typing
    "pressEnter": false
  }
}
Set clearBefore: true to avoid appending to existing field values.

Drag and Drop

Drag elements to target locations:
{
  "action": "dragAndDrop",
  "selector": ".draggable-item",
  "targetSelector": ".drop-zone",
  "targetSelectorType": "css"
}

JavaScript Execution

Execute custom JavaScript code in the browser context:
{
  "type": "javascriptCode",
  "data": {
    "label": "Fill form with random data",
    "code": `
      const page = context.page;
      if (!page) {
        throw new Error('Page not available');
      }
      
      // Generate random data
      const randomData = {
        firstName: 'Test' + Math.floor(Math.random() * 10000),
        lastName: 'User' + Math.floor(Math.random() * 10000),
        email: 'test' + Math.floor(Math.random() * 10000) + '@example.com',
        password: 'Test1234!@#$',
      };
      
      // Fill form fields
      await page.fill('input[name="customer[first_name]"]', randomData.firstName);
      await page.fill('input[name="customer[last_name]"]', randomData.lastName);
      await page.fill('input[name="customer[email]"]', randomData.email);
      await page.fill('input[name="customer[password]"]', randomData.password);
      
      // Store data in context for later use
      context.setData('registrationData', randomData);
      
      console.log('Form filled with:', randomData);
    `
  }
}
JavaScript nodes have access to the context object (ContextManager) and page object (Playwright Page).

Multi-Tab Management

AutoMFlows supports working with multiple browser tabs:
1

Open New Tab

{
  "action": "newTab",
  "url": "https://example.com",
  "contextKey": "newPageRef"
}
2

Switch Between Tabs

// Switch by index
{
  "action": "switchTab",
  "tabIndex": 1
}

// Switch by URL pattern
{
  "action": "switchTab",
  "urlPattern": "/dashboard/"
}
3

Close Tab

{
  "action": "closeTab",
  "tabIndex": 1  // Or omit to close current tab
}

Data Extraction

Extract text, attributes, or element properties:

Get Text

{
  "type": "dataExtractor",
  "data": {
    "label": "Get Welcome Message",
    "selector": "h1.welcome",
    "extractType": "text",
    "contextKey": "welcomeMessage"
  }
}

Get Attribute

{
  "extractType": "attribute",
  "selector": "a.download-link",
  "attribute": "href",
  "contextKey": "downloadUrl"
}

Extract Multiple Elements

{
  "selector": ".product-item",
  "extractType": "text",
  "extractAll": true,  // Extract from all matching elements
  "contextKey": "productNames"
}

Screenshots

Capture screenshots at any point:
{
  "type": "screenshot",
  "data": {
    "label": "Capture Dashboard",
    "screenshotType": "fullPage",  // fullPage, viewport, element
    "selector": "",  // For element screenshots
    "filename": "dashboard.png"
  }
}
Capture entire scrollable page:
{ "screenshotType": "fullPage" }

Wait Node

Add explicit waits between actions:
{
  "type": "wait",
  "data": {
    "label": "Wait after click",
    "timeout": 2000  // Wait 2 seconds
  }
}
Use Wait nodes to allow animations to complete or to simulate human-like delays between actions.

Verification

Verify page state after actions:
{
  "type": "verify",
  "data": {
    "domain": "browser",
    "verificationType": "text",
    "selector": "h1",
    "expectedValue": "Create Account",
    "selectorType": "css"
  }
}

Complete Example

Here’s a complete workflow that demonstrates browser automation:
{
  "nodes": [
    {
      "id": "start-1",
      "type": "start",
      "data": { "label": "Start" }
    },
    {
      "id": "openBrowser-1",
      "type": "openBrowser",
      "data": {
        "label": "Open Browser",
        "headless": false,
        "browser": "chromium",
        "viewportWidth": 1280,
        "viewportHeight": 720
      }
    },
    {
      "id": "navigate-1",
      "type": "navigation",
      "data": {
        "label": "Navigate to Site",
        "action": "navigate",
        "url": "https://sauce-demo.myshopify.com/",
        "waitUntil": "networkidle"
      }
    },
    {
      "id": "wait-1",
      "type": "wait",
      "data": {
        "label": "Wait for page load",
        "timeout": 2000
      }
    },
    {
      "id": "click-1",
      "type": "action",
      "data": {
        "label": "Click Sign Up",
        "action": "click",
        "selector": "a:has-text(\"Sign up\")",
        "selectorType": "css"
      }
    },
    {
      "id": "wait-2",
      "type": "wait",
      "data": {
        "label": "Wait after click",
        "timeout": 2000
      }
    },
    {
      "id": "verify-1",
      "type": "verify",
      "data": {
        "label": "Verify registration page",
        "domain": "browser",
        "verificationType": "text",
        "selector": "h1",
        "expectedValue": "Create Account"
      }
    },
    {
      "id": "verify-2",
      "type": "verify",
      "data": {
        "label": "Verify URL",
        "domain": "browser",
        "verificationType": "url",
        "expectedValue": "https://sauce-demo.myshopify.com/account/register"
      }
    }
  ],
  "edges": [
    { "source": "start-1", "target": "openBrowser-1" },
    { "source": "openBrowser-1", "target": "navigate-1" },
    { "source": "navigate-1", "target": "wait-1" },
    { "source": "wait-1", "target": "click-1" },
    { "source": "click-1", "target": "wait-2" },
    { "source": "wait-2", "target": "verify-1" },
    { "source": "verify-1", "target": "verify-2" }
  ]
}

Best Practices

Use Robust Selectors

Prefer data attributes or IDs over fragile class names:
[data-testid="submit-button"]  // Good
button.btn-primary.large        // Fragile

Add Wait Nodes

Insert explicit waits after actions that trigger animations or network requests.

Use networkidle

For SPAs, use waitUntil: "networkidle" to ensure dynamic content loads.

Verify Critical Steps

Add Verify nodes after important actions to catch failures early.

Next Steps

API Testing

Combine browser automation with API testing for end-to-end workflows.

Reports

Generate execution reports with screenshots and performance metrics.

Build docs developers (and LLMs) love