{"id":17513,"library":"blocking-proxy","title":"Blocking Proxy for WebDriver Tests","description":"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.","status":"maintenance","version":"1.0.1","language":"javascript","source_language":"en","source_url":"git://github.com/angular/jasminewd","tags":["javascript","test","testing","webdriver","webdriverjs","selenium","typescript"],"install":[{"cmd":"npm install blocking-proxy","lang":"bash","label":"npm"},{"cmd":"yarn add blocking-proxy","lang":"bash","label":"yarn"},{"cmd":"pnpm add blocking-proxy","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The primary function to start and configure the proxy programmatically. CommonJS users should destructure the export.","wrong":"const start = require('blocking-proxy').start;","symbol":"start","correct":"import { start } from 'blocking-proxy'"},{"note":"The core class for direct instance management and more advanced programmatic control. Typically used when embedding the proxy within a custom test runner or server.","wrong":"const BlockingProxy = require('blocking-proxy').BlockingProxy;","symbol":"BlockingProxy","correct":"import { BlockingProxy } from 'blocking-proxy'"},{"note":"TypeScript interface for the configuration object passed to the `start` function or `BlockingProxy` constructor, ensuring type safety.","symbol":"BlockingProxyOptions","correct":"import { BlockingProxyOptions } from 'blocking-proxy'"}],"quickstart":{"code":"import { start } from 'blocking-proxy';\nimport { Builder, Capabilities } from 'selenium-webdriver';\n\nasync function setupAndRunProxy() {\n  const proxyPort = 8080;\n  const seleniumAddress = 'http://localhost:4444/wd/hub'; // Ensure Selenium Server is running here\n  const logDir = './proxy-logs';\n\n  console.log(`Starting Blocking Proxy on port ${proxyPort}...`);\n  const proxy = await start({\n    proxyPort: proxyPort,\n    seleniumAddress: seleniumAddress,\n    logDir: logDir,\n    highlightDelay: 200, // Optional: Add a visual delay for debugging\n    waitForAngular: true, // Crucial for Angular application testing\n    // You might also need to set proxyConfig for HTTP/HTTPS\n  });\n  console.log(`Blocking Proxy started successfully on http://localhost:${proxyPort}`);\n  console.log('Now, configure your WebDriver client to point to this proxy address.');\n\n  // Example: How to configure a Selenium WebDriver to use the proxy\n  // In a real test, this would be part of your test runner (e.g., Protractor config)\n  const driver = new Builder()\n    .withCapabilities(Capabilities.chrome())\n    .usingServer(`http://localhost:${proxyPort}/wd/hub`) // WebDriver connects to the proxy\n    .build();\n\n  try {\n    console.log('WebDriver connected to Blocking Proxy. Navigating...');\n    await driver.get('http://localhost:8081/your-angular-app'); // Replace with your app URL\n    console.log('Page loaded via proxy. Tests would continue here.');\n    // Perform your WebDriver actions here, which will be blocked by Angular sync\n    // await driver.findElement(By.css('.my-element')).click();\n\n  } finally {\n    console.log('Quitting WebDriver and stopping proxy...');\n    await driver.quit();\n    await proxy.stop(); // Stop the proxy cleanly\n    console.log('Proxy and WebDriver stopped.');\n  }\n}\n\nsetupAndRunProxy().catch(err => {\n  console.error('Failed to setup or run Blocking Proxy:', err);\n  process.exit(1);\n});","lang":"typescript","description":"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."},"warnings":[{"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.","message":"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.","severity":"gotcha","affected_versions":">=1.0.0"},{"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.","message":"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.","severity":"gotcha","affected_versions":">=1.0.0"},{"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.","message":"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.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"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.","cause":"Blocking Proxy could not connect to the specified Selenium Server.","error":"Error: connect ECONNREFUSED 127.0.0.1:4444"},{"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.","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.","error":"WebDriverError: no such element"},{"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.","cause":"The port that Blocking Proxy attempted to bind to is already in use by another process.","error":"Error: listen EADDRINUSE :::8080"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}