Blocking Proxy for WebDriver Tests

raw JSON →
1.0.1 verified Thu Apr 23 auth: no javascript maintenance

Blocking Proxy is a specialized network proxy designed to enhance WebDriver-based test suites, particularly for rich client applications. It operates by intercepting WebDriver commands between the test runner and the Selenium Server, allowing for the injection of custom logic. Its primary utility, especially for applications built with Angular, is to automatically pause WebDriver commands until Angular's change detection cycles are finished, thereby significantly reducing test flakiness caused by asynchronous UI updates. The current stable version is 1.0.1, last published in 2017. While it originated within the Angular ecosystem, its development appears to be in maintenance mode, with no significant recent updates. Key differentiators include its language-agnostic network-level interaction, features like 'Wait for Angular,' highlight delay for visual debugging, and detailed WebDriver command logging. It is intended to be run as a separate process alongside a Selenium server, not as an embedded library within the test runner itself.

error Error: connect ECONNREFUSED 127.0.0.1:4444
cause Blocking Proxy could not connect to the specified Selenium Server.
fix
Ensure that your Selenium Server is running and accessible on http://localhost:4444/wd/hub (or the address configured for seleniumAddress) before starting Blocking Proxy.
error WebDriverError: no such element
cause A common WebDriver error indicating that an element was not found, often due to timing issues or the 'Wait for Angular' feature not synchronizing correctly.
fix
Verify that your Angular application is correctly instrumented for waitForAngular. If the issue persists, consider adding explicit waits (e.g., driver.wait(until.elementLocated(...))) in your test code, or debugging your application's Zone.js integration if applicable.
error Error: listen EADDRINUSE :::8080
cause The port that Blocking Proxy attempted to bind to is already in use by another process.
fix
Change the proxyPort configuration to an unused port number (e.g., 8081). You can check available ports using netstat -an | grep <port> on Linux/macOS or netstat -ano | findstr :<port> on Windows.
gotcha Blocking Proxy does not currently support multiple concurrent WebDriver clients. It is recommended to start a separate instance of Blocking Proxy for each parallel test process to avoid race conditions and unexpected behavior.
fix Ensure that your test runner or CI/CD setup provisions a dedicated Blocking Proxy instance for each parallel browser session or test suite run.
gotcha Blocking Proxy requires an external Selenium Server (or equivalent WebDriver endpoint) to be running independently. It acts as an intermediary, forwarding commands to the specified Selenium address, rather than embedding or starting Selenium itself.
fix Before starting Blocking Proxy, ensure your Selenium Server is active and accessible at the `seleniumAddress` configured for the proxy. You can use `webdriver-manager start` or a similar tool.
gotcha While Blocking Proxy can work with any WebDriver test, its flagship feature, 'Wait for Angular,' is specifically designed for AngularJS and early Angular applications. For modern Angular versions, ensuring zone.js is properly patched might be necessary, or the utility of this feature may be reduced, requiring manual waiting strategies.
fix Verify that `waitForAngular` is effectively synchronizing with your application's framework. For non-Angular or newer Angular applications, consider if the proxy's other features (logging, highlight delay) justify its use, or explore alternative synchronization methods.
npm install blocking-proxy
yarn add blocking-proxy
pnpm add blocking-proxy

This quickstart demonstrates how to programmatically start Blocking Proxy and configure a Selenium WebDriver instance to route its commands through it, enabling features like 'Wait for Angular' and highlighting.

import { start } from 'blocking-proxy';
import { Builder, Capabilities } from 'selenium-webdriver';

async function setupAndRunProxy() {
  const proxyPort = 8080;
  const seleniumAddress = 'http://localhost:4444/wd/hub'; // Ensure Selenium Server is running here
  const logDir = './proxy-logs';

  console.log(`Starting Blocking Proxy on port ${proxyPort}...`);
  const proxy = await start({
    proxyPort: proxyPort,
    seleniumAddress: seleniumAddress,
    logDir: logDir,
    highlightDelay: 200, // Optional: Add a visual delay for debugging
    waitForAngular: true, // Crucial for Angular application testing
    // You might also need to set proxyConfig for HTTP/HTTPS
  });
  console.log(`Blocking Proxy started successfully on http://localhost:${proxyPort}`);
  console.log('Now, configure your WebDriver client to point to this proxy address.');

  // Example: How to configure a Selenium WebDriver to use the proxy
  // In a real test, this would be part of your test runner (e.g., Protractor config)
  const driver = new Builder()
    .withCapabilities(Capabilities.chrome())
    .usingServer(`http://localhost:${proxyPort}/wd/hub`) // WebDriver connects to the proxy
    .build();

  try {
    console.log('WebDriver connected to Blocking Proxy. Navigating...');
    await driver.get('http://localhost:8081/your-angular-app'); // Replace with your app URL
    console.log('Page loaded via proxy. Tests would continue here.');
    // Perform your WebDriver actions here, which will be blocked by Angular sync
    // await driver.findElement(By.css('.my-element')).click();

  } finally {
    console.log('Quitting WebDriver and stopping proxy...');
    await driver.quit();
    await proxy.stop(); // Stop the proxy cleanly
    console.log('Proxy and WebDriver stopped.');
  }
}

setupAndRunProxy().catch(err => {
  console.error('Failed to setup or run Blocking Proxy:', err);
  process.exit(1);
});