Skip to main content

SDK Configuration

The BrowserTest SDK supports various configuration options to customize its behavior for different use cases.

BrowserTestConfig Interface

interface BrowserTestConfig {
  /** API key for authentication */
  apiKey: string;
  /** Base URL for API calls (default: https://api.browsertest.in) */
  baseUrl?: string;
  /** Request timeout in milliseconds (default: 30000) */
  timeout?: number;
  /** Number of retries for failed requests (default: 3) */
  retries?: number;
}

Basic Configuration

Default Configuration

const bt = new BrowserTest({
  apiKey: process.env.BROWSERTEST_API_KEY
});

Custom Configuration

const bt = new BrowserTest({
  apiKey: process.env.BROWSERTEST_API_KEY,
  baseUrl: 'https://api.browsertest.in',
  timeout: 60000, // 1 minute
  retries: 5
});

Environment-Specific Configuration

Development vs Production

const config = {
  development: {
    apiKey: process.env.BROWSERTEST_DEV_KEY,
    timeout: 30000,
    retries: 1,
    baseUrl: 'https://api.browsertest.in'
  },
  staging: {
    apiKey: process.env.BROWSERTEST_STAGING_KEY,
    timeout: 45000,
    retries: 3,
    baseUrl: 'https://api.browsertest.in'
  },
  production: {
    apiKey: process.env.BROWSERTEST_PROD_KEY,
    timeout: 60000,
    retries: 5,
    baseUrl: 'https://api.browsertest.in'
  }
};

const environment = process.env.NODE_ENV || 'development';
const bt = new BrowserTest(config[environment]);

Multiple API Keys

// Different keys for different services
const configs = {
  screenshots: {
    apiKey: process.env.SCREENSHOT_API_KEY,
    timeout: 45000
  },
  testing: {
    apiKey: process.env.TESTING_API_KEY,
    timeout: 120000
  },
  monitoring: {
    apiKey: process.env.MONITORING_API_KEY,
    timeout: 30000,
    retries: 2
  }
};

const screenshotClient = new BrowserTest(configs.screenshots);
const testingClient = new BrowserTest(configs.testing);
const monitoringClient = new BrowserTest(configs.monitoring);

Timeout Configuration

Operation-Specific Timeouts

Different operations may require different timeout values:
// Fast screenshots
const fastScreenshots = new BrowserTest({
  apiKey: process.env.BROWSERTEST_API_KEY,
  timeout: 15000 // 15 seconds
});

// Complex tests
const complexTests = new BrowserTest({
  apiKey: process.env.BROWSERTEST_API_KEY,
  timeout: 300000 // 5 minutes
});

// Monitoring checks
const monitoring = new BrowserTest({
  apiKey: process.env.BROWSERTEST_API_KEY,
  timeout: 10000 // 10 seconds
});

Per-Operation Timeout Override

// Global timeout of 30 seconds, but override for specific operations
const bt = new BrowserTest({
  apiKey: process.env.BROWSERTEST_API_KEY,
  timeout: 30000
});

// This will use the global timeout
await bt.screenshot.take({ url: 'https://example.com' });

// This overrides the global timeout
await bt.screenshot.take({
  url: 'https://slow-site.com',
  timeout: 120000 // 2 minutes for this specific operation
});

Retry Configuration

Default Retry Behavior

The SDK automatically retries failed requests with exponential backoff:
const bt = new BrowserTest({
  apiKey: process.env.BROWSERTEST_API_KEY,
  retries: 3 // Retry up to 3 times
});

Custom Retry Logic

class RetryBrowserTest {
  constructor(config) {
    this.bt = new BrowserTest(config);
    this.maxRetries = config.retries || 3;
    this.baseDelay = 1000; // 1 second
  }

  async executeWithCustomRetry(operation, operationName) {
    let lastError;

    for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
      try {
        return await operation();
      } catch (error) {
        lastError = error;

        // Don't retry auth errors
        if (error.name === 'BrowserTestAuthError') {
          throw error;
        }

        if (attempt === this.maxRetries) {
          throw lastError;
        }

        // Custom backoff: delay = baseDelay * (2 ^ (attempt - 1))
        const delay = this.baseDelay * Math.pow(2, attempt - 1);
        console.log(`Retrying ${operationName} in ${delay}ms (attempt ${attempt + 1})`);
        await new Promise(resolve => setTimeout(resolve, delay));
      }
    }
  }

  async screenshot(url, options = {}) {
    return this.executeWithCustomRetry(
      () => this.bt.screenshot.take({ url, ...options }),
      'screenshot'
    );
  }
}

Base URL Configuration

Custom API Endpoints

// Production API
const production = new BrowserTest({
  apiKey: process.env.BROWSERTEST_API_KEY,
  baseUrl: 'https://api.browsertest.in'
});

// Staging API
const staging = new BrowserTest({
  apiKey: process.env.BROWSERTEST_STAGING_KEY,
  baseUrl: 'https://staging-api.browsertest.in'
});

// Local development
const local = new BrowserTest({
  apiKey: 'test-key',
  baseUrl: 'http://localhost:3001'
});

Regional Endpoints

const regionalConfigs = {
  us: {
    apiKey: process.env.BROWSERTEST_API_KEY,
    baseUrl: 'https://api-us.browsertest.in'
  },
  eu: {
    apiKey: process.env.BROWSERTEST_API_KEY,
    baseUrl: 'https://api-eu.browsertest.in'
  },
  asia: {
    apiKey: process.env.BROWSERTEST_API_KEY,
    baseUrl: 'https://api-asia.browsertest.in'
  }
};

const region = process.env.BROWSERTEST_REGION || 'us';
const bt = new BrowserTest(regionalConfigs[region]);

Advanced Configuration Patterns

Configuration Factory

class BrowserTestConfigFactory {
  static createForEnvironment(env = 'development') {
    const baseConfig = {
      apiKey: this.getApiKey(env),
      baseUrl: this.getBaseUrl(env),
      timeout: this.getTimeout(env),
      retries: this.getRetries(env)
    };

    return new BrowserTest(baseConfig);
  }

  static getApiKey(env) {
    const keys = {
      development: process.env.BROWSERTEST_DEV_KEY,
      staging: process.env.BROWSERTEST_STAGING_KEY,
      production: process.env.BROWSERTEST_PROD_KEY
    };
    return keys[env] || keys.development;
  }

  static getBaseUrl(env) {
    const urls = {
      development: 'https://api.browsertest.in',
      staging: 'https://staging-api.browsertest.in',
      production: 'https://api.browsertest.in'
    };
    return urls[env] || urls.development;
  }

  static getTimeout(env) {
    const timeouts = {
      development: 30000,
      staging: 45000,
      production: 60000
    };
    return timeouts[env] || timeouts.development;
  }

  static getRetries(env) {
    const retries = {
      development: 1,
      staging: 3,
      production: 5
    };
    return retries[env] || retries.development;
  }
}

// Usage
const bt = BrowserTestConfigFactory.createForEnvironment(process.env.NODE_ENV);

Configuration Validation

class ValidatedBrowserTest {
  constructor(config) {
    this.validateConfig(config);
    this.bt = new BrowserTest(config);
  }

  validateConfig(config) {
    if (!config.apiKey) {
      throw new Error('API key is required');
    }

    if (config.apiKey.length < 10) {
      throw new Error('API key appears to be invalid (too short)');
    }

    if (config.timeout && config.timeout < 1000) {
      throw new Error('Timeout must be at least 1000ms');
    }

    if (config.retries && config.retries < 0) {
      throw new Error('Retries cannot be negative');
    }

    if (config.baseUrl && !config.baseUrl.startsWith('http')) {
      throw new Error('Base URL must start with http:// or https://');
    }
  }

  // Proxy all methods to the underlying instance
  screenshot = this.bt.screenshot;
  testing = this.bt.testing;
  template = this.bt.template;
  batch = this.bt.batch;
}

// Usage
try {
  const bt = new ValidatedBrowserTest({
    apiKey: process.env.BROWSERTEST_API_KEY,
    timeout: 30000
  });
} catch (error) {
  console.error('Configuration error:', error.message);
}

Performance Configuration

High-Performance Setup

const highPerformance = new BrowserTest({
  apiKey: process.env.BROWSERTEST_API_KEY,
  timeout: 15000, // Faster timeouts
  retries: 1,     // Fewer retries
  baseUrl: 'https://api.browsertest.in'
});

Reliability-Focused Setup

const highReliability = new BrowserTest({
  apiKey: process.env.BROWSERTEST_API_KEY,
  timeout: 120000, // Longer timeouts
  retries: 5,      // More retries
  baseUrl: 'https://api.browsertest.in'
});

Monitoring Configuration

Logging Configuration

class MonitoredBrowserTest {
  constructor(config) {
    this.bt = new BrowserTest(config);
    this.enableLogging = config.enableLogging || false;
  }

  async logOperation(operation, params, startTime, result, error) {
    const duration = Date.now() - startTime;
    const logEntry = {
      operation,
      params,
      duration,
      success: !error,
      timestamp: new Date().toISOString(),
      error: error ? error.message : null
    };

    if (this.enableLogging) {
      console.log('BrowserTest Operation:', logEntry);
    }

    // Send to monitoring service
    // await sendToMonitoring(logEntry);
  }

  async screenshot(options) {
    const startTime = Date.now();
    try {
      const result = await this.bt.screenshot.take(options);
      await this.logOperation('screenshot', options, startTime, result);
      return result;
    } catch (error) {
      await this.logOperation('screenshot', options, startTime, null, error);
      throw error;
    }
  }
}

// Usage
const bt = new MonitoredBrowserTest({
  apiKey: process.env.BROWSERTEST_API_KEY,
  enableLogging: process.env.NODE_ENV === 'development'
});

Configuration Best Practices

Environment Variables

Always use environment variables for sensitive configuration:
// ✅ Good
const bt = new BrowserTest({
  apiKey: process.env.BROWSERTEST_API_KEY,
  baseUrl: process.env.BROWSERTEST_BASE_URL,
  timeout: parseInt(process.env.BROWSERTEST_TIMEOUT) || 30000
});

// ❌ Bad
const bt = new BrowserTest({
  apiKey: 'sk-1234567890abcdef',
  baseUrl: 'https://api.browsertest.in'
});

Configuration Validation

Validate configuration at startup:
function validateBrowserTestConfig(config) {
  const required = ['apiKey'];
  const optional = ['baseUrl', 'timeout', 'retries'];

  // Check required fields
  for (const field of required) {
    if (!config[field]) {
      throw new Error(`Missing required configuration: ${field}`);
    }
  }

  // Validate types and ranges
  if (config.timeout && (config.timeout < 1000 || config.timeout > 300000)) {
    throw new Error('Timeout must be between 1000 and 300000 milliseconds');
  }

  if (config.retries && (config.retries < 0 || config.retries > 10)) {
    throw new Error('Retries must be between 0 and 10');
  }

  if (config.baseUrl && !config.baseUrl.match(/^https?:\/\//)) {
    throw new Error('Base URL must be a valid HTTP/HTTPS URL');
  }

  return true;
}

// Usage
const config = {
  apiKey: process.env.BROWSERTEST_API_KEY,
  timeout: 30000,
  retries: 3
};

validateBrowserTestConfig(config);
const bt = new BrowserTest(config);

Configuration Profiles

Use configuration profiles for different use cases:
const profiles = {
  fast: {
    timeout: 15000,
    retries: 1
  },
  balanced: {
    timeout: 30000,
    retries: 3
  },
  reliable: {
    timeout: 60000,
    retries: 5
  }
};

function createBrowserTestWithProfile(profileName, apiKey) {
  const profile = profiles[profileName] || profiles.balanced;
  return new BrowserTest({
    apiKey,
    ...profile
  });
}

// Usage
const fastClient = createBrowserTestWithProfile('fast', process.env.BROWSERTEST_API_KEY);
const reliableClient = createBrowserTestWithProfile('reliable', process.env.BROWSERTEST_API_KEY);