Parallel Execution Guide

Learn how to optimize your test execution speed by running multiple actions in parallel with Chekov.

Understanding Parallel Execution

Chekov supports running multiple actions in parallel to speed up test execution. This is particularly useful for:

  • Filling multiple form fields simultaneously
  • Performing multiple verifications at once
  • Handling multiple UI interactions in parallel
  • Running independent test scenarios concurrently

Basic Parallel Execution

Form Filling Example

import { test } from '@playwright/test';
import { ai } from '@chekov/core';

test('fill registration form in parallel', async ({ page }) => {
  await page.goto('https://example.com/register');
  
  // Run multiple form fills in parallel
  await ai([
    'Type "John Doe" in the name field',
    'Type "john@example.com" in the email field',
    'Type "123 Main St" in the address field',
    'Select "United States" from the country dropdown'
  ], { page, parallelism: 4 });
  
  await ai('Click the Register button', { page });
});

Multiple Verifications

test('verify dashboard elements in parallel', async ({ page }) => {
  await page.goto('https://example.com/dashboard');
  
  // Verify multiple elements simultaneously
  await ai([
    'Verify the user profile section is visible',
    'Verify the recent activity list shows 5 items',
    'Verify the notifications count is correct',
    'Verify the settings menu is accessible'
  ], { page, parallelism: 4 });
});

Advanced Parallel Patterns

Dynamic Parallelism

test('handle dynamic content in parallel', async ({ page }) => {
  await page.goto('https://example.com/products');
  
  // Get number of products
  const productCount = await page.evaluate(() => 
    document.querySelectorAll('.product').length
  );
  
  // Generate verification tasks
  const tasks = Array.from({ length: productCount }, (_, i) => 
    `Verify product ${i + 1} has a valid price and image`
  );
  
  // Run verifications in parallel
  await ai(tasks, { page, parallelism: 5 });
});

Conditional Parallel Execution

test('conditional parallel actions', async ({ page }) => {
  await page.goto('https://example.com/settings');
  
  const tasks = [];
  
  // Add tasks based on conditions
  const hasNotifications = await page.isVisible('.notifications-section');
  if (hasNotifications) {
    tasks.push('Enable email notifications');
    tasks.push('Enable push notifications');
  }
  
  const hasSecurity = await page.isVisible('.security-section');
  if (hasSecurity) {
    tasks.push('Enable two-factor authentication');
    tasks.push('Update security questions');
  }
  
  // Execute available tasks in parallel
  if (tasks.length > 0) {
    await ai(tasks, { page, parallelism: tasks.length });
  }
});

Performance Considerations

Optimal Parallelism

Note: The optimal parallelism level depends on:

  • Your system's resources
  • The complexity of each action
  • The application's ability to handle concurrent actions

Start with a moderate level (3-5) and adjust based on performance.

Resource Management

// ✅ Good: Moderate parallelism with related actions
await ai([
  'Type "John" in the first name field',
  'Type "Doe" in the last name field',
  'Type "john@example.com" in the email field'
], { page, parallelism: 3 });

// ❌ Bad: Too many unrelated parallel actions
await ai([
  'Click the submit button',
  'Open the user menu',
  'Start file upload',
  'Toggle dark mode',
  'Open notifications'
], { page, parallelism: 5 }); // Could cause race conditions

Common Use Cases

Form Validation

test('validate form fields in parallel', async ({ page }) => {
  await page.goto('https://example.com/form');
  
  // Submit empty form
  await ai('Click Submit', { page });
  
  // Check all validation messages in parallel
  await ai([
    'Verify the name field shows "Required" error',
    'Verify the email field shows "Required" error',
    'Verify the phone field shows "Required" error',
    'Verify the address field shows "Required" error'
  ], { page, parallelism: 4 });
});

Data Grid Operations

test('bulk operations on data grid', async ({ page }) => {
  await page.goto('https://example.com/users');
  
  // Select multiple rows
  await ai([
    'Check row 1 in the users table',
    'Check row 2 in the users table',
    'Check row 3 in the users table'
  ], { page, parallelism: 3 });
  
  await ai('Click Bulk Delete', { page });
  
  // Verify deletions in parallel
  await ai([
    'Verify row 1 is removed',
    'Verify row 2 is removed',
    'Verify row 3 is removed'
  ], { page, parallelism: 3 });
});

Best Practices

When to Use Parallel Execution

✅ Good Use Cases

  • Form field population
  • Multiple independent verifications
  • Batch operations
  • UI element checks

❌ Avoid Parallel Execution

  • Sequential workflows
  • State-dependent actions
  • Navigation operations
  • Critical security operations

Error Handling

test('handle parallel execution errors', async ({ page }) => {
  try {
    await ai([
      'Click the first button',
      'Click the second button',
      'Click the third button'
    ], { 
      page, 
      parallelism: 3,
      // Optional: Configure error handling
      continueOnError: true // Continue other actions if one fails
    });
  } catch (error) {
    console.error('Parallel execution failed:', error);
    // Handle the error appropriately
  }
});

Debugging Tips

  • Start Sequential: When debugging issues, try running actions sequentially first
  • Reduce Parallelism: Lower the parallelism level to isolate problems
  • Use Logging: Add detailed logging to track parallel execution flow
  • Check Race Conditions: Verify that parallel actions don't interfere with each other

Next Steps