Files
proffesor-for-testing__agen…/docs/api/workflow-templates.md
Profa 7a74717a81 feat(v3): integrate @claude-flow/browser into AQE v3
Multi-agent implementation of browser automation integration:

Adapters:
- BrowserResultAdapter: Transform browser results to QE format
- TrajectoryAdapter: Capture learning patterns from browser sessions

Services:
- BrowserSecurityScanner: OWASP-based security scanning with browser
- BrowserSwarmCoordinator: Multi-viewport parallel testing

Workflows:
- 9 browser workflow templates (login, OAuth, accessibility, etc.)
- WorkflowLoader for dynamic template loading

Skills:
- security-visual-testing: Combined security + visual regression skill

Tests:
- Unit tests for adapters and services
- Integration tests for parallel viewports and trajectory learning

Documentation:
- API docs for all new components
- Integration guide for claude-flow-browser

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 18:08:06 +00:00

16 KiB

Browser Workflow Templates Reference

Package: @agentic-qe/v3/workflows/browser Source: /v3/src/workflows/browser/templates/ Format: YAML

Overview

Workflow templates provide pre-built, reusable patterns for common browser testing scenarios. Each template is a YAML file defining steps, variables, and execution order. Templates are designed to be parameterized and composable.


Template List

Template Purpose Complexity Avg Duration
login-flow Authentication testing Low 5s
oauth-flow OAuth2/OIDC testing Medium 15s
scraping-workflow Data extraction Medium 10s
visual-regression Screenshot comparison Low 8s
form-validation Input validation Low 7s
navigation-flow Multi-page navigation Medium 12s
api-integration Browser-API hybrid High 20s
performance-audit Lighthouse-style High 30s
accessibility-audit WCAG compliance Medium 15s

YAML Schema

All templates follow this schema:

# Template metadata
name: string                    # Template name (kebab-case)
version: string                 # Semantic version
description: string             # Human-readable description
tags: string[]                  # Categorization tags

# Variables (template parameters)
variables:
  - name: string                # Variable name
    type: string | number | boolean | array | object
    required: boolean           # Is this variable required?
    default: any                # Default value (if not required)
    description: string         # Usage description

# Steps (execution sequence)
steps:
  - id: string                  # Unique step identifier
    type: string                # Step type (see below)
    description: string         # What this step does
    config: object              # Step-specific configuration
    continueOnError: boolean    # Continue if step fails?
    timeout: number             # Step timeout (ms)
    retry: object               # Retry configuration
      maxAttempts: number
      backoff: 'linear' | 'exponential'

# Assertions (validation)
assertions:
  - condition: string           # Assertion condition (JS expression)
    message: string             # Failure message

# Cleanup (always runs)
cleanup:
  - type: string
    config: object

Step Types

Navigation Steps

navigate

Navigate to a URL.

- id: goto-login
  type: navigate
  config:
    url: "{{baseUrl}}/login"
    waitUntil: domcontentloaded  # load, domcontentloaded, networkidle

click

Click an element.

- id: click-submit
  type: click
  config:
    selector: 'button[type="submit"]'
    waitForNavigation: true

fill

Fill an input field.

- id: enter-username
  type: fill
  config:
    selector: '#username'
    value: "{{username}}"
    clear: true  # Clear field first

select

Select from dropdown.

- id: select-country
  type: select
  config:
    selector: '#country'
    value: "US"

Capture Steps

screenshot

Capture a screenshot.

- id: capture-page
  type: screenshot
  config:
    path: "{{screenshotsDir}}/{{pageName}}.png"
    fullPage: true
    viewport:
      width: 1920
      height: 1080

extract

Extract data from page.

- id: extract-prices
  type: extract
  config:
    selector: '.price'
    attribute: textContent
    multiple: true  # Extract all matches
    output: prices  # Store in variable

Validation Steps

assert

Assert a condition.

- id: verify-login
  type: assert
  config:
    condition: "page.url().includes('/dashboard')"
    message: "Failed to reach dashboard after login"

waitFor

Wait for condition.

- id: wait-for-element
  type: waitFor
  config:
    selector: '#content-loaded'
    state: visible  # attached, detached, visible, hidden
    timeout: 5000

API Steps

apiCall

Make API request.

- id: fetch-user-data
  type: apiCall
  config:
    method: GET
    url: "{{apiUrl}}/users/{{userId}}"
    headers:
      Authorization: "Bearer {{token}}"
    output: userData

Control Flow

condition

Conditional execution.

- id: check-login-required
  type: condition
  config:
    condition: "page.url().includes('/login')"
    then:
      - type: fill
        config:
          selector: '#username'
          value: "{{username}}"
    else:
      - type: skip

loop

Iterate over items.

- id: test-all-pages
  type: loop
  config:
    items: "{{urls}}"
    variable: url
    steps:
      - type: navigate
        config:
          url: "{{url}}"
      - type: screenshot
        config:
          path: "{{screenshotsDir}}/{{url}}.png"

Template: login-flow

Purpose: Test authentication flows with username/password.

File: login-flow.yaml

name: login-flow
version: "1.0.0"
description: |
  Standard username/password login flow with validation.
  Supports error handling and success verification.
tags:
  - authentication
  - login
  - security

variables:
  - name: baseUrl
    type: string
    required: true
    description: "Base URL of the application"

  - name: username
    type: string
    required: true
    description: "Username for login"

  - name: password
    type: string
    required: true
    description: "Password for login"

  - name: successSelector
    type: string
    required: false
    default: '[data-testid="dashboard"]'
    description: "Selector to verify successful login"

steps:
  - id: navigate-to-login
    type: navigate
    description: "Navigate to login page"
    config:
      url: "{{baseUrl}}/login"
      waitUntil: networkidle

  - id: enter-username
    type: fill
    description: "Enter username"
    config:
      selector: 'input[name="username"], input[type="email"], #username'
      value: "{{username}}"

  - id: enter-password
    type: fill
    description: "Enter password"
    config:
      selector: 'input[name="password"], input[type="password"], #password'
      value: "{{password}}"

  - id: click-submit
    type: click
    description: "Click login button"
    config:
      selector: 'button[type="submit"], button:has-text("Log in"), button:has-text("Sign in")'
      waitForNavigation: true
      timeout: 10000

  - id: wait-for-success
    type: waitFor
    description: "Wait for successful login indicator"
    config:
      selector: "{{successSelector}}"
      state: visible
      timeout: 5000

assertions:
  - condition: "!page.url().includes('/login')"
    message: "Still on login page after authentication"

  - condition: "page.locator('{{successSelector}}').isVisible()"
    message: "Success indicator not visible"

Usage:

import { WorkflowLoader } from '@agentic-qe/v3/workflows/browser';

const loader = new WorkflowLoader();
const workflow = await loader.load('login-flow', {
  baseUrl: 'https://example.com',
  username: 'testuser@example.com',
  password: 'secure-password',
});

const result = await workflow.execute();

Template: oauth-flow

Purpose: Test OAuth2/OIDC authentication flows.

File: oauth-flow.yaml

name: oauth-flow
version: "1.0.0"
description: |
  OAuth2/OIDC authentication flow testing.
  Handles provider redirect and callback.
tags:
  - authentication
  - oauth
  - oidc

variables:
  - name: appUrl
    type: string
    required: true

  - name: provider
    type: string
    required: true
    description: "OAuth provider (google, github, etc.)"

  - name: providerUsername
    type: string
    required: true

  - name: providerPassword
    type: string
    required: true

steps:
  - id: initiate-oauth
    type: navigate
    config:
      url: "{{appUrl}}/auth/{{provider}}"
      waitUntil: networkidle

  - id: wait-for-provider-redirect
    type: waitFor
    config:
      condition: "page.url().includes('{{provider}}')"
      timeout: 5000

  - id: provider-login
    type: fill
    config:
      selector: 'input[type="email"], input[name="username"]'
      value: "{{providerUsername}}"

  - id: provider-password
    type: fill
    config:
      selector: 'input[type="password"]'
      value: "{{providerPassword}}"

  - id: provider-submit
    type: click
    config:
      selector: 'button[type="submit"]'
      waitForNavigation: true

  - id: wait-for-callback
    type: waitFor
    config:
      condition: "page.url().includes('{{appUrl}}')"
      timeout: 10000

  - id: verify-authenticated
    type: assert
    config:
      condition: "page.locator('[data-user-authenticated]').isVisible()"
      message: "User not authenticated after OAuth flow"

assertions:
  - condition: "page.url().startsWith('{{appUrl}}')"
    message: "Did not return to application after OAuth"

Template: visual-regression

Purpose: Capture and compare screenshots for visual regression testing.

File: visual-regression.yaml

name: visual-regression
version: "1.0.0"
description: |
  Capture screenshots across viewports and compare with baselines.
  Supports multiple pages and responsive testing.
tags:
  - visual-testing
  - regression
  - screenshots

variables:
  - name: urls
    type: array
    required: true
    description: "List of URLs to test"

  - name: viewports
    type: array
    required: false
    default:
      - { width: 320, height: 568, name: "mobile" }
      - { width: 1920, height: 1080, name: "desktop" }

  - name: baselineDir
    type: string
    required: true
    description: "Directory containing baseline images"

  - name: outputDir
    type: string
    required: true
    description: "Directory for new screenshots"

  - name: threshold
    type: number
    required: false
    default: 0.01
    description: "Difference threshold (0-1)"

steps:
  - id: test-all-urls
    type: loop
    config:
      items: "{{urls}}"
      variable: url
      steps:
        - id: test-all-viewports
          type: loop
          config:
            items: "{{viewports}}"
            variable: viewport
            steps:
              - id: set-viewport
                type: setViewport
                config:
                  width: "{{viewport.width}}"
                  height: "{{viewport.height}}"

              - id: navigate
                type: navigate
                config:
                  url: "{{url}}"
                  waitUntil: networkidle

              - id: capture
                type: screenshot
                config:
                  path: "{{outputDir}}/{{url}}-{{viewport.name}}.png"
                  fullPage: true

              - id: compare
                type: compareScreenshots
                config:
                  baseline: "{{baselineDir}}/{{url}}-{{viewport.name}}.png"
                  current: "{{outputDir}}/{{url}}-{{viewport.name}}.png"
                  threshold: "{{threshold}}"
                  output: "{{outputDir}}/diff-{{url}}-{{viewport.name}}.png"

Template: accessibility-audit

Purpose: Comprehensive WCAG accessibility testing.

File: accessibility-audit.yaml

name: accessibility-audit
version: "1.0.0"
description: |
  Run Axe-core accessibility audit with WCAG 2.1 AA compliance.
  Generates detailed report with violations and recommendations.
tags:
  - accessibility
  - wcag
  - compliance

variables:
  - name: url
    type: string
    required: true

  - name: wcagLevel
    type: string
    required: false
    default: "AA"
    description: "WCAG level: A, AA, AAA"

  - name: reportPath
    type: string
    required: true

steps:
  - id: navigate
    type: navigate
    config:
      url: "{{url}}"
      waitUntil: networkidle

  - id: run-axe
    type: axeAudit
    config:
      standard: "WCAG21{{wcagLevel}}"
      rules:
        - color-contrast
        - image-alt
        - label
        - link-name
        - button-name
      output: auditResults

  - id: generate-report
    type: generateReport
    config:
      template: accessibility
      data: "{{auditResults}}"
      path: "{{reportPath}}"

assertions:
  - condition: "auditResults.violations.length === 0"
    message: "Accessibility violations found"

Variable Substitution

Templates support variable substitution using {{variableName}} syntax:

# Direct substitution
url: "{{baseUrl}}/login"

# Nested property access
url: "{{config.api.baseUrl}}"

# Array indexing
url: "{{urls[0]}}"

# Conditional
text: "{{isProduction ? 'prod' : 'dev'}}"

JavaScript Context:

Variables are evaluated in a safe JavaScript context with access to:

  • All provided variables
  • page object (Playwright page)
  • expect assertion library
  • Common utilities (encodeURIComponent, JSON.parse, etc.)

Custom Workflow Creation

1. Create Template File

# Create new template
touch v3/src/workflows/browser/templates/my-workflow.yaml

2. Define Workflow

name: my-workflow
version: "1.0.0"
description: "My custom workflow"
tags: ["custom"]

variables:
  - name: myParam
    type: string
    required: true

steps:
  - id: my-step
    type: navigate
    config:
      url: "{{myParam}}"

3. Load and Execute

const workflow = await loader.load('my-workflow', {
  myParam: 'https://example.com',
});

const result = await workflow.execute();

Workflow Composition

Workflows can be composed by referencing other workflows:

name: complex-flow
steps:
  - id: authenticate
    type: workflow
    config:
      template: login-flow
      variables:
        baseUrl: "{{baseUrl}}"
        username: "{{username}}"
        password: "{{password}}"

  - id: run-test
    type: workflow
    config:
      template: my-test-flow
      variables:
        authenticated: true

Error Handling

Continue on Error

steps:
  - id: optional-step
    type: click
    config:
      selector: '.optional-element'
    continueOnError: true  # Proceed even if click fails

Retry Configuration

steps:
  - id: flaky-step
    type: apiCall
    config:
      url: "{{apiUrl}}"
    retry:
      maxAttempts: 3
      backoff: exponential
      backoffFactor: 2

Cleanup Steps

cleanup:
  - type: screenshot
    config:
      path: "./failure-screenshot.png"

  - type: saveHtml
    config:
      path: "./failure-page.html"

Performance Optimization

Parallel Execution

steps:
  - id: parallel-screenshots
    type: parallel
    config:
      steps:
        - type: screenshot
          config:
            selector: '#header'
        - type: screenshot
          config:
            selector: '#content'
        - type: screenshot
          config:
            selector: '#footer'

Resource Caching

steps:
  - id: cache-api-response
    type: apiCall
    config:
      url: "{{apiUrl}}/data"
      cache:
        enabled: true
        ttl: 300  # 5 minutes

Testing Workflows

import { describe, it, expect } from 'vitest';
import { WorkflowLoader } from './workflow-loader';

describe('login-flow', () => {
  it('should execute successfully', async () => {
    const loader = new WorkflowLoader();
    const workflow = await loader.load('login-flow', {
      baseUrl: 'http://localhost:3000',
      username: 'test@example.com',
      password: 'password',
    });

    const result = await workflow.execute();

    expect(result.ok).toBe(true);
    expect(result.value.success).toBe(true);
    expect(result.value.steps).toHaveLength(5);
  });
});

See Also