ScreenshotNeo

BlogHow-to

How to Use Selenium with JavaScript

Install Selenium’s JavaScript binding, automate a browser, and write a reliable first test. Learn how Selenium Manager, waits, cleanup, and remote sessions fit together.

By the ScreenshotNeo team4 October 20268 min read

Selenium’s JavaScript binding is the npm package selenium-webdriver. Install it in a Node.js project, create a session with Builder, await each browser command, and always call driver.quit() in a finally block. Selenium Manager normally finds or downloads a compatible browser driver automatically.

The examples below use CommonJS and Chrome. The current Selenium JavaScript API documentation lists Node.js 22 or newer; check the live API documentation for current supported versions before choosing a runtime.

1. Install Selenium and prepare a project

Install Node.js, create a project, and add Selenium:

mkdir selenium-js-example
cd selenium-js-example
npm init -y
npm install selenium-webdriver

Make sure a supported browser such as Chrome is installed. Selenium Manager is included with Selenium and usually handles the matching browser driver the first time a session starts, so a separate driver download is not normally needed.

2. Launch a browser and open a page

Create index.js. This minimal script opens Selenium’s site, prints its title, and closes the browser even if navigation or title retrieval fails:

const { Builder, Browser } = require('selenium-webdriver');

async function main() {
  const driver = await new Builder().forBrowser(Browser.CHROME).build();
  try {
    await driver.get('https://www.selenium.dev');
    console.log(await driver.getTitle());
  } finally {
    await driver.quit();
  }
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

Run it with node index.js. Browser operations are asynchronous: await navigation, lookup, interaction, and reads. The finally clause matters because an assertion or browser command can fail before the normal end of the script.

3. Interact with a page and assert the result

This complete example opens Selenium’s sample form, types into a field, submits it, and checks the confirmation. It uses Node’s built-in strict assertion library, so there is no test framework dependency:

const { By, Builder, Browser } = require('selenium-webdriver');
const assert = require('node:assert/strict');

async function main() {
  const driver = await new Builder().forBrowser(Browser.CHROME).build();
  try {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    const input = await driver.findElement(By.name('my-text'));
    const submit = await driver.findElement(By.css('button'));

    await input.sendKeys('Selenium');
    await submit.click();

    const message = await driver.findElement(By.id('message'));
    assert.equal(await message.getText(), 'Received!');
    console.log('Form submission succeeded');
  } finally {
    await driver.quit();
  }
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

Save it as form-test.js and run node form-test.js. If you adapt the example to another site, use locators tied to stable semantics or test-owned attributes when possible. Positional selectors and styling classes are more likely to change during page redesigns.

4. Choose browser and session configuration

Browser selection

Choose the browser on the Builder. For example, Firefox can be selected with Browser.FIREFOX:

const { Builder, Browser } = require('selenium-webdriver');

const driver = await new Builder().forBrowser(Browser.FIREFOX).build();

The browser must be available in the environment where the session runs. Selenium’s API also allows browser-specific options through its browser option classes; use those when you need to set browser arguments or capabilities. Keep browser configuration attached to the Builder so the session’s target and capabilities are explicit.

Local versus remote execution

A normal Builder starts a local browser session. To use Selenium Grid or another WebDriver server, point the Builder at that server:

const { Builder, Browser } = require('selenium-webdriver');

const driver = await new Builder()
  .forBrowser(Browser.CHROME)
  .usingServer('http://localhost:4444')
  .build();

The JavaScript API also documents a SELENIUM_REMOTE_URL setting. Configure the remote endpoint according to the server or Grid you operate. In remote runs, the browser and its driver are provisioned on the remote side; a local browser installation is not a substitute for configuring that server.

Setup Where browser runs What you manage
Default Builder On the machine running Node Local browser installation, runtime, and access to driver metadata or downloads when Selenium Manager needs them
usingServer(url) On the configured WebDriver server or Grid Server URL and remote browser provisioning; the remote environment owns its browser and driver

5. Understand Selenium Manager and drivers

WebDriver defines a browser-control protocol. A browser-specific driver connects Selenium to the actual browser. Selenium Manager is the Selenium project’s official driver manager and ships with Selenium releases. When the binding does not receive a driver path, it can discover the browser version, resolve a compatible driver, download it, and cache it locally. See the official Selenium Manager documentation.

Start with the default Builder and let Selenium Manager resolve the driver. Manual driver management is still available when an environment needs a pinned executable or controlled provisioning. Automated browser management, including downloading browser releases, was added in Selenium 4.11.0, according to the Selenium Manager documentation.

6. Make browser automation more reliable

  • Await every WebDriver operation. Navigation, element lookup, typing, clicks, and reads complete asynchronously. Skipping await can make later steps run before an earlier action has finished.
  • Close every session. Put quit() in finally for scripts, or use the test framework’s teardown hook. This applies after assertion failures too.
  • Use stable locators. Prefer IDs, accessible semantics, names, or test-specific attributes over selectors coupled to layout or generated classes.
  • Wait for the condition you need. Dynamic pages may render after navigation returns. Use Selenium’s wait facilities to wait for a specific element or state rather than adding an arbitrary fixed sleep. Choose the condition based on the page behavior.
  • Keep failures visible. Allow errors to reach the process or test runner after logging them, so a failed assertion produces a failing command instead of a misleading success.

7. Capture a screenshot after the page is ready

Selenium can also save a screenshot of the current browser viewport. Await the capture and write the returned base64 data to a file:

const fs = require('node:fs/promises');
const { Builder, Browser } = require('selenium-webdriver');

async function main() {
  const driver = await new Builder().forBrowser(Browser.CHROME).build();
  try {
    await driver.get('https://www.selenium.dev');
    const base64 = await driver.takeScreenshot();
    await fs.writeFile('selenium-homepage.png', Buffer.from(base64, 'base64'));
  } finally {
    await driver.quit();
  }
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

This captures the browser’s current viewport. If the task is only to obtain a webpage image or PDF, running a browser and managing its driver can be unnecessary setup.

Or skip the browser setup

For a clean website capture without installing Selenium or a browser driver, ScreenshotNeo provides a one-request screenshot API. See the ScreenshotNeo API documentation for parameters and response details.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://www.selenium.dev -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://www.selenium.dev"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://www.selenium.dev' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await require('node:fs/promises').writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the capture; each of those steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in headers. Its MCP server lets Claude, Cursor, and other MCP clients use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots.

Sign up for ScreenshotNeo and get 1,000 free screenshots a month, with no card required.

8. Troubleshooting

Symptom Likely cause What to do
Session creation fails while resolving a driver The browser is missing, Node is outside the documented support range, or the environment cannot reach driver metadata/download endpoints. Confirm the browser is installed, check the current Selenium JavaScript API’s Node requirement, and allow the environment to reach the relevant endpoints. If provisioning must be controlled, supply a managed driver using the documented approach.
Browser starts locally but not in CI The CI image may not include the target browser or may restrict downloads. Provision the browser in the image or use a configured remote Grid. Check that Selenium Manager can reach its metadata and download sources when relying on automatic setup.
“NoSuchElement” or a lookup times out The selector is wrong, the page has not rendered the target yet, or the element is in a different browsing context. Inspect the page and selector, wait for the required element or state, and handle frames or windows explicitly when the page uses them.
Click or typing happens before the page is ready An operation was not awaited, or navigation completed before client-side rendering reached the required state. Await each command and wait for the specific resulting element or condition instead of assuming a fixed delay.
Browser processes remain after a failed run The script exited before cleanup. Put driver.quit() in finally and ensure the top-level promise reports failures without bypassing that block.
Remote session cannot connect The server URL is wrong, unavailable, or not configured to accept the requested browser. Check the endpoint and server availability, then confirm the remote Grid has that browser configured. Use usingServer() for the remote WebDriver endpoint.

9. Performance, reliability, and cost

Selenium controls a real browser, so each session depends on browser startup, page loading, and the environment that provisions the browser and driver. Reuse a session for a sequence of related interactions when appropriate, and close it when the sequence ends. For multiple isolated tests, use your test runner’s setup and teardown lifecycle so failures do not leave sessions open.

Local execution gives direct control over the installed browser and its version, while remote execution moves browser provisioning to a Grid or WebDriver server. The cited Selenium documentation establishes these configuration paths but does not provide a general performance or cost comparison; those depend on the browser environment and infrastructure you choose. Selenium itself is an npm package, while browser/Grid infrastructure may have its own operational cost.

10. Frequently asked questions

Does Selenium with JavaScript require a separate ChromeDriver download?

Usually not. Selenium Manager can resolve a compatible driver automatically when one has not been supplied. Manual provisioning remains an option for controlled environments.

Can I use Selenium with Firefox?

Yes. Select Firefox on the Builder and make sure the browser is available in the environment that runs the session.

Should I use Selenium or a screenshot API?

Use Selenium when you need to exercise browser interactions and assert application behavior. For a screenshot or PDF without managing browser sessions, ScreenshotNeo offers a one-call API and MCP tools.

Where can I confirm which Node versions Selenium supports?

Check the current Selenium JavaScript API documentation, since supported runtime lines change over time.

References