n8n-nodes-playwright

repository·master·Indexed 41 days ago

https://github.com/toema/n8n-playwright

A community node for n8n version 1.0.0+ that enables browser automation using Playwright 1.49.0. It provides built-in operations for navigation, screenshots, and form interaction, as well as a 'Run Custom Script' feature allowing full Playwright API access via JavaScript within n8n workflows.

Tokens
2.7K
Snippets
9
Records
14
Agent score
2%

What's inside n8n-playwright

  1. Standard Operations in n8n-nodes-playwright

    master

    The node provides several built-in operations for browser automation:

    • Navigate: Go to a specified URL and retrieve page content.
    • Take Screenshot: Capture a screenshot of a webpage (supports full page or viewport).
    • Get Text: Extract text from an element using CSS selector or XPath.
    • Click Element: Click on an element using CSS selector or XPath.
    • Fill Form: Fill a form field using CSS selector or XPath.
    • Run Custom Script: Execute custom JavaScript code with full Playwright API access.
  2. How Custom Scripts work in n8n-nodes-playwright

    master

    The Run Custom Script operation allows for complex automation by providing a sandboxed JavaScript environment with access to the full Playwright API and n8n's Code node features.

    Available Playwright Variables

    • $page: The current page instance.
    • $browser: The browser instance.
    • $playwright: The Playwright library.
    • $helpers: n8n helper methods (e.g., prepareBinaryData).

    Available n8n Variables

    • $json: Current item's JSON data.
    • $input: Access to input data.
    • $getNodeParameter(): Get node parameters.
  3. Install n8n-nodes-playwright

    master

    Install the community node using pnpm. Note that the package automatically downloads browser binaries during installation, requiring approximately 1GB of disk space.

    If you need to manually trigger the browser setup, use the rebuild command.

    pnpm install n8n-nodes-playwright
    
    # If manual browser setup is required:
    pnpm rebuild n8n-nodes-playwright
  4. Custom Script Best Practices

    master

    When writing custom scripts for the Playwright node, follow these rules:

    1. Return an array: Scripts must return an array of objects, e.g., return [{ json: { ... } }];.
    2. Use async/await: All Playwright operations are asynchronous; always use await.
    3. Handle binary data: Use $helpers.prepareBinaryData() to handle images, PDFs, or other files.
    4. Debug with console.log(): Logs appear in the n8n UI during manual execution.
    5. Error handling: Use try-catch blocks for robust automation.
    6. Access input: Use $json or $input to interact with data from previous nodes.
    7. Cleanup: The browser is automatically closed after the script finishes execution.
  5. Configure Browser and Selector Options

    master

    When using standard operations, you can configure the following:

    Browser Options:

    • Engine: Choose between Chromium, Firefox, or WebKit.
    • Headless Mode: Toggle whether the browser runs with a visible UI.
    • Slow Motion: Adjust operation speed.

    Selector Options: For Get Text, Click Element, and Fill Form, you can use:

    • CSS Selector: e.g., #submit-button, .my-class.
    • XPath: e.g., //button[@id="submit"].
  6. Deploy n8n with Playwright via Docker Compose

    master

    To run the n8n-playwright environment, use the provided docker-compose.yml. This configuration builds the n8n image from the local directory, maps port 5678 for access, and uses a named volume n8n_data to persist n8n data at /home/node/.n8n.

    version: '3.8'
    
    services:
      n8n:
        build: .
        container_name: n8n
        ports:
          - "5678:5678"
        volumes:
          - n8n_data:/home/node/.n8n
        restart: unless-stopped
    
    volumes:
      n8n_data:
        name: n8n_data
  7. Troubleshoot browser installation issues

    master

    If Playwright browsers are not installed correctly, you can perform a clean installation by removing the existing cache and rebuilding the package.

    On Linux/macOS:

    1. Remove the cache: rm -rf ~/.cache/ms-playwright
    2. Rebuild the package: pnpm rebuild n8n-nodes-playwright

    On Windows:

    1. Remove the cache: rmdir /s /q %USERPROFILE%\AppData\Local\ms-playwright
    2. Rebuild the package: pnpm rebuild n8n-nodes-playwright
    # Linux/macOS
    rm -rf ~/.cache/ms-playwright
    pnpm rebuild n8n-nodes-playwright
    
    # Windows
    rmdir /s /q %USERPROFILE%\AppData\Local\ms-playwright
    pnpm rebuild n8n-nodes-playwright
  8. Debug Custom Script errors

    master

    When writing custom Playwright scripts within the n8n node, ensure you follow these requirements to avoid common failures:

    1. Return Format: Your script must return an array of objects in the n8n format: return [{ json: {...} }];.
    2. Async Operations: Verify that all Playwright operations use the await keyword.
    3. Debugging: Use console.log() to output data; these logs can be viewed within the n8n UI.
    4. Error Handling: Wrap your logic in try-catch blocks to manage errors gracefully.
    try {
      // ... your playwright code ...
      const data = await $page.textContent('h1');
      return [{ json: { title: data } }];
    } catch (error) {
      console.log('Error details:', error);
      throw error;
    }
  9. Resolve 'Selector Not Found' errors

    master

    If Playwright cannot find the elements you are targeting, try the following strategies:

    1. Switch Selector Types: If a CSS selector fails, try using an XPath selector (or vice versa).
    2. Wait for Elements: Explicitly wait for the element to appear in the DOM using await $page.waitForSelector('selector').
    3. Handle Iframes: If the element is inside an iframe, use the frame locator: await $page.frameLocator('iframe').locator('selector').
    4. Wait for Network Idle: Ensure the page has finished loading content by using await $page.waitForLoadState('networkidle').
    // Wait for selector
    await $page.waitForSelector('.my-element');
    
    // Handle iframe
    await $page.frameLocator('#my-iframe').locator('.element-inside').click();
    
    // Wait for page load
    await $page.waitForLoadState('networkidle');
  10. Example: Manage Authentication with Cookies

    master

    You can save cookies from a login session and restore them in a subsequent execution to access protected pages.

    // --- Script 1: Login and Save Cookies ---
    await $page.goto('https://www.example.com/login');
    await $page.fill('#login-username', 'user');
    await $page.fill('#login-password', 'pass');
    await $page.click('#login-button');
    await $page.waitForNavigation();
    
    const context = $page.context();
    const cookies = await context.cookies();
    
    return [{ json: { cookies, loginSuccess: true } }];
    
    // --- Script 2: Restore Cookies ---
    // (Assuming cookies are passed via $input)
    const { cookies } = $input.first().json;
    const context = $page.context();
    await context.addCookies(cookies);
    
    await $page.goto('https://example.com/protected-page');
    const data = await $page.textContent('.protected-content');
    
    return [{ json: { data, authenticated: true } }];
  11. Example: Scrape Web Data and Return JSON

    master

    This example demonstrates navigating to a site and using $$eval to scrape multiple elements into a JSON array.

    await $page.goto('https://news.ycombinator.com');
    
    // Scrape all story titles
    const stories = await $page.$$eval('.titleline > a', elements => 
        elements.map(el => ({
            title: el.textContent,
            url: el.href
        }))
    );
    
    console.log(`Found ${stories.length} stories`);
    
    return stories.map(story => ({ json: story }));
  12. Example: Capture Screenshot as Binary Data

    master

    To pass a screenshot to subsequent n8n nodes, use $helpers.prepareBinaryData to convert the Playwright buffer into n8n binary format.

    await $page.goto('https://www.google.com');
    
    // Take screenshot
    const screenshot = await $page.screenshot({ 
        type: 'png',
        fullPage: true 
    });
    
    // Prepare binary data
    const binaryData = await $helpers.prepareBinaryData(
        Buffer.from(screenshot),
        'screenshot.png',
        'image/png'
    );
    
    return [{
        json: {
            url: $page.url(),
            timestamp: new Date().toISOString()
        },
        binary: {
            screenshot: binaryData
        }
    }];