ScreenshotNeo

BlogHow-to

How to Use Jasmine With Selenium for JavaScript Testing

Use Jasmine to organize JavaScript tests and Selenium WebDriver to control a real browser. Set up async specs, manage browser sessions, and troubleshoot common failures.

By the ScreenshotNeo team4 October 202610 min read

To use Jasmine with Selenium for JavaScript testing, run Jasmine under Node.js and use Selenium WebDriver to open and control a browser. Jasmine provides suites, specs, hooks, and expectations; WebDriver performs browser actions. Install both packages, provision a browser and compatible driver (or a remote Selenium server), write asynchronous specs that await every browser command, and always close the WebDriver session.

This pattern tests an application through browser-visible behavior. If instead you want Jasmine specs to execute inside a browser, use the separate jasmine-browser-runner workflow described below.

1. Choose the Jasmine and Selenium workflow

Workflow What runs where Choose it when
Node Jasmine specs drive Selenium Jasmine runs in Node.js; Selenium controls a browser. You need to navigate your app, interact with controls, and assert what the browser renders.
jasmine-browser-runner The runner executes Jasmine specs in a browser. Your goal is to execute browser-side JavaScript specs. This is a distinct setup, not a replacement name for Selenium WebDriver.

For end-to-end tests that exercise a site as a user would, use Node-driven Jasmine with Selenium. The Jasmine framework organizes and evaluates tests; it does not provide browser automation itself. Selenium’s JavaScript bindings provide the WebDriver browser-control layer. See the Jasmine project and Selenium WebDriver documentation.

2. Install the packages and prepare a browser

Start in a Node.js project. Use your package manager to install Jasmine and Selenium’s JavaScript binding as development dependencies:

npm install --save-dev jasmine selenium-webdriver
npx jasmine init

These commands use the current versions selected by npm; the official integration documentation does not establish a durable version compatibility matrix. Check the current release documentation for your project, then commit the lockfile so local and CI installs use the same dependency resolution.

Selenium setup requires a language binding, a browser, and its driver. Depending on the Selenium release and environment, driver management may be handled for you or you may need to install/configure a compatible driver explicitly. Follow the current Selenium installation guidance and browser vendor documentation for your machine or CI image. Don’t assume one browser/driver version pairing remains valid indefinitely.

For Chrome on a developer machine, verify that Chrome is installed and available to the process running the test. In a container or CI worker, provision the browser and driver there, or use a reachable Selenium server. If you use a remote endpoint, configure it as described in the remote execution section.

3. Write an asynchronous Jasmine spec that drives a browser

The following CommonJS example uses a suite-scoped browser session. Replace the example URL and selectors with your application’s actual form and expected result. It uses Jasmine’s asynchronous hooks/spec support and Selenium’s JavaScript API.

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

describe('web form', () => {
  let driver;

  beforeAll(async () => {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
  });

  afterAll(async () => {
    if (driver) {
      await driver.quit();
    }
  });

  it('submits a form and displays a response', async () => {
    await driver.get('https://example.test/form');
    await driver.findElement(By.name('message')).sendKeys('hello');
    await driver.findElement(By.css('button[type="submit"]')).click();

    const response = await driver.findElement(By.id('response')).getText();
    expect(response).toBe('Received');
  });
});

Save the spec in Jasmine’s configured spec location (the initialized default is spec/) with a filename matching its spec pattern, such as spec/formSpec.js. Run it with:

npx jasmine

The Selenium JavaScript testing API documents Jasmine wrappers and examples using asynchronous hooks, awaited browser operations, and driver.quit(). Refer to the Selenium JavaScript testing API for current helper options and configuration.

ES modules

If your project uses ES modules, use imports rather than require, and configure Jasmine to load the spec as an ES module according to the installed Jasmine release and your project’s module setup. For example, the Selenium imports have this shape:

import { Builder, By, Browser } from 'selenium-webdriver';

Keep the spec’s asynchronous hooks, awaits, expectations, and cleanup logic the same. Don’t mix CommonJS and ES module conventions in a way that conflicts with the project’s package.json and test runner configuration.

Why every WebDriver call is awaited

WebDriver commands are asynchronous. Await navigation, element lookup, typing, clicks, waits, and reads. Without an await, a test may reach its expectation before the browser has completed the action, or a rejected command may go unhandled.

4. Make browser tests reliable

Wait for a condition instead of guessing with sleeps

Pages often update after a request or client-side render. A fixed delay can be too short on a slow run and waste time on a fast one. Wait for the state the test needs. Selenium provides explicit waiting strategies; consult its WebDriver documentation for the current API and examples.

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

// After navigating or submitting:
await driver.wait(
  until.elementLocated(By.id('response')),
  10000,
  'response element did not appear'
);
const response = await driver.findElement(By.id('response')).getText();

Use a condition tied to the expected UI state: an element appears, becomes visible, changes text, or becomes clickable. Set a finite timeout that matches the test’s needs, and report a useful message when it expires. A wait for an element to exist is not necessarily a wait for it to be visible or for its text to be updated; choose the condition that matches the assertion.

Choose the browser session scope

  • One driver for the suite: the example’s beforeAll/afterAll starts one browser and reuses it. This avoids repeated session startup, but tests can leak cookies, tabs, local storage, and page state into one another. Reset state deliberately between specs.
  • One driver per spec: create in beforeEach and quit in afterEach. This gives stronger browser-state isolation, with the cost of more session startup and shutdown work.

Whichever scope you use, make cleanup conditional on successful setup. If creating a driver fails, cleanup should not try to use an undefined session. Ensure shutdown runs even after a failed expectation; Jasmine’s teardown hook is the right place for suite/session cleanup. If a test can open multiple windows or tabs, close or switch them deliberately before the next spec.

Keep expectations focused on user-visible behavior

Use Jasmine expectations to check the outcome a user or downstream system depends on: confirmation text, a changed status, an error message, or a destination URL. Use WebDriver to perform realistic browser actions. Prefer stable selectors such as accessible labels, IDs, or application-owned attributes over brittle selectors tied to layout details.

5. Run against another browser or a remote Selenium server

For a local browser other than Chrome, select the appropriate browser through the Selenium builder and make sure that browser and its supported driver are provisioned. Selenium’s documented test helpers support selecting a target through SELENIUM_BROWSER and a remote server through SELENIUM_REMOTE_URL; see the official helper documentation for the exact helper usage and environment setup.

The direct-builder example above explicitly selects Chrome with forBrowser(Browser.CHROME). If you use Selenium’s testing helper, set its documented environment variables in the test process, for example:

SELENIUM_BROWSER=chrome npx jasmine
SELENIUM_BROWSER=chrome SELENIUM_REMOTE_URL=http://selenium-host:4444 npx jasmine

These are shell examples; use the equivalent environment-variable syntax for your shell or CI system. Replace the remote hostname with the endpoint supplied by your grid administrator. The test runner must be able to reach that endpoint, and the remote grid must have the requested browser available.

When using a remote Selenium server, configure the JavaScript Selenium builder or Selenium’s documented test helper for the remote endpoint as appropriate to the selected integration. Avoid assuming that a local forBrowser example automatically connects to a remote grid: the remote address must be part of the session configuration. Keep grid credentials in your CI secret store, not in source code or logs.

6. When to use jasmine-browser-runner instead

Use jasmine-browser-runner when the requirement is to run Jasmine specs in a browser environment. Its documented setup installs jasmine-browser-runner and jasmine-core, initializes configuration, then runs the specs:

npm install --save-dev jasmine-browser-runner jasmine-core
npx jasmine-browser-runner init
npx jasmine-browser-runner runSpecs

Configure the browser and any remote grid options using the runner’s current configuration documentation. Jasmine’s browser setup guide describes this workflow and remote grid execution, including use of a user’s own Selenium Grid. This runs specs in a browser; it is separate from Node.js Jasmine specs using Selenium commands to drive an application.

7. Troubleshooting

Symptom Likely cause Fix
Jasmine reports no specs found The file is outside the configured spec directory or does not match the configured filename pattern. Check Jasmine’s initialized configuration and put the file in the configured location, commonly spec/ with a matching spec filename. Run npx jasmine from the project root.
Browser session fails to start Browser is missing, driver is unavailable/incompatible, or the process cannot access the browser. Install/provision the browser and its supported driver as required by your Selenium setup. Check the current Selenium installation and browser vendor documentation; don’t rely on an old version pairing.
Connection refused for a remote session The endpoint is wrong, unreachable from the test process, or the grid is not running. Confirm the full remote URL, network route, port, and grid availability. Set the remote URL in the configuration path used by your helper/builder.
Element lookup says no such element The page is not at the expected route, the selector is wrong, or the element has not rendered yet. Check the actual page and selector. Wait for the relevant element/state with a bounded explicit wait, and make sure navigation completed.
Click or typing fails intermittently The control may not yet be interactable, another element overlays it, or page state changes asynchronously. Wait for the correct visible/clickable state, inspect overlays and application errors, and target the intended element. Avoid using longer fixed sleeps as the general remedy.
Expectation runs before the page updates A WebDriver operation or UI-state wait was not awaited. Await every WebDriver promise and wait for the result condition before reading or asserting.
Browser remains open after an error Shutdown is absent, skipped, or attempted on an uninitialized driver. Use afterAll or afterEach and guard cleanup with if (driver). Ensure teardown is configured as an async hook.
Specs pass alone but fail in a suite Shared browser state or test ordering affects results. Reset cookies/storage/navigation between specs or create a fresh session per spec. Keep test setup independent of execution order.
Works locally but fails in CI CI may have a different browser/driver setup, permissions, network access, or remote endpoint configuration. Provision browser dependencies in the CI environment, verify the configured browser/remote URL there, and capture useful driver and browser logs for diagnosis.

8. Performance, reliability, and cost

Starting a real browser session has setup and resource costs. Reusing a session across a suite can reduce repeated startup work; creating a session per spec improves isolation but increases startup work. Choose based on suite size and the consequences of leaked browser state. Parallel browser sessions also consume more machine resources and, for remote grids, require available remote capacity.

Reliability comes from explicit waits, deterministic test data, stable selectors, correct browser/driver provisioning, awaited commands, and guaranteed teardown. A successful Jasmine assertion only describes the state observed in that run and environment; it does not guarantee identical behavior across browsers or environments. Add other browser targets when your compatibility requirements call for them.

Local execution has no separate Selenium service charge, but it uses developer or CI compute and browser resources. A remote grid may have its own capacity limits and commercial terms; check the provider or administrator’s current terms. The research sources do not establish a universal browser test runtime, benchmark, or grid price.

9. Or skip the browser setup

If you need a screenshot of a page rather than an interactive browser test, ScreenshotNeo is a website screenshot API and MCP server for developers. One GET request returns a PNG, JPEG, WebP, or PDF. It is useful for visual checks, page captures, and AI-agent screenshot workflows; it does not replace Jasmine assertions or Selenium-driven interaction tests.

For example, using cURL:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Equivalent Python:

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)

Equivalent Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const bytes = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', bytes));

See the ScreenshotNeo API documentation for request options and response details. Cookie banners, popups, and chat widgets are removed before capture; bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots.

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

10. FAQ

Does Jasmine automate a browser by itself?

No. Jasmine runs tests and evaluates expectations. Selenium WebDriver supplies browser automation.

Can I use Jasmine with Selenium on a remote grid?

Yes. Configure the Selenium JavaScript helper or builder for the remote server, and make sure the endpoint and requested browser are available to the test process.

Should I use one browser session for every spec?

That depends on the suite. A shared session reduces repeated startup, while per-spec sessions isolate browser state more strongly.

Is jasmine-browser-runner the same as Selenium?

No. It runs Jasmine specs in a browser. Selenium WebDriver is a browser-control API that Node-driven tests can use to automate an application.

References