Frontend Development 11 min read

Using Selenium with Headless Chrome, Mocha, Chai, and Karma for Front‑End Testing

This guide explains how to use Selenium WebDriver with headless Chrome, integrate BrowserStack and chromedriver, and combine Mocha, Chai, and Karma to write, configure, and run automated front‑end tests, including sample code and troubleshooting tips.

Qunar Tech Salon
Qunar Tech Salon
Qunar Tech Salon
Using Selenium with Headless Chrome, Mocha, Chai, and Karma for Front‑End Testing

WebDriver is a W3C standard that defines remote control interfaces for browsers, and Selenium implements this standard to provide a complete web‑automation solution.

Selenium can be used via the selenium-webdriver package; the example below creates a Chrome driver, opens Baidu, retrieves the search button text and page title, and then quits the driver.

const webdriver = require('selenium-webdriver'),
    By = webdriver.By;

const driver = new webdriver.Builder()
    .forBrowser('chrome')
    .build();

driver.get('https://www.baidu.com').then((args) => {
    // 获取百度搜索按钮的 文本
    driver.findElement(By.id('su')).then((element) => {
        return element.getAttribute('value');
    }).then((btnName) => {
        console.log(btnName);
    });

    // 获取百度首页 title
    driver.getTitle().then((title) => {
        console.log(title);
    });
});

driver.quit();

When using BrowserStack, the driver is obtained from the browserstack-webdriver package; capabilities such as browser name, user, and key are supplied, and the rest of the API remains identical.

const webdriver = require('browserstack-webdriver'),
    By = webdriver.By;

const capabilities = {
    'browserName': 'firefox',
    'browserstack.user': BROWSERSTACK_USERNAME,
    'browserstack.key': BROWSERSTACK_KEY
};

const driver = new webdriver.Builder()
    .usingServer('http://hub.browserstack.com/wd/hub')
    .withCapabilities(capabilities)
    .build();

// same test steps as above

Installing chromedriver can be simplified by requiring the package, which automatically configures the binary path. Alternative download URLs or custom file paths can be set via npm config or environment variables.

require('chromedriver');

For unit testing, Mocha provides the test runner and Chai supplies assertions. The following example shows a headless Chrome test that checks the Baidu search button text and page title.

const chai = require('chai');
const chromeDriver = require('selenium-webdriver/chrome');
const webdriver = require('selenium-webdriver'),
    By = webdriver.By;

const driver = new webdriver.Builder()
    .forBrowser('chrome')
    .setChromeOptions(new chromeDriver.Options().addArguments(['headless']))
    .build();

describe('Home page load test', function() {
    it('Button text should equal', function(done) {
        driver.get('https://www.baidu.com').then(function() {
            driver.findElement(By.id('su')).then(element => element.getAttribute('value'))
                .then(btnName => {
                    console.log(btnName);
                    chai.expect(btnName).to.equal('百度一下');
                    done();
                });
        });
    });

    it('Page title should equal', function(done) {
        driver.get('https://www.baidu.com').then(() => {
            driver.getTitle().then(title => {
                console.log(title);
                chai.expect(title).to.equal('百度一下,你就知道');
                done();
            });
        });
    });

    after(function() {
        driver.quit();
    });
});

Karma acts as a test executor for browsers. After installing karma , karma-chrome-launcher , karma-mocha , and karma-chai , a configuration file can be generated with ./node_modules/.bin/karma init . The generated karma.conf.js can be extended to run headless Chrome, use webpack for ES6 support, and add coverage reporting via Istanbul.

module.exports = function(config) {
    config.set({
        basePath: '',
        frameworks: ['mocha', 'chai'],
        files: ['test/**/*.js'],
        preprocessors: {'test/**/*.js': ['webpack']},
        reporters: ['progress', 'coverage'],
        coverageReporter: {type: 'html', dir: 'coverage/'},
        browsers: ['ChromeHeadless'],
        singleRun: true,
        webpack: {
            module: {
                loaders: [{
                    test: /\.js$/,
                    loader: 'babel-loader',
                    exclude: /node_modules/,
                    query: {presets: ['es2015'], plugins: ['istanbul']}
                }]
            }
        }
    });
};

Sample source code ( src/index.js ) provides simple type‑checking utilities, and a test suite ( test/index.js ) verifies isFunction and isArray using the Mocha/Chai setup.

const typeUtil = require('../src/index');

describe('index.js: ', () => {
    it('isFunction() should work fine.', () => {
        expect(typeUtil.isFunction(function() {})).to.equal(true);
        expect(typeUtil.isFunction(Object.prototype.toString)).to.equal(true);
    });

    it('isArray() should work fine.', () => {
        expect(typeUtil.isArray([])).to.equal(true);
        expect(typeUtil.isArray({})).to.equal(false);
    });
});

Running ./node_modules/.bin/karma start (or npm run test after adding a script) executes the tests, displays results in the console, and generates an HTML coverage report under the coverage directory. A known limitation is that page reloads during tests can interrupt Karma execution.

References include official Selenium documentation, headless Chrome testing guides, BrowserStack integration notes, and several Chinese blog posts and articles on automated UI testing.

Frontend TestingSeleniumchaiKarmamochaheadless-chrome
Qunar Tech Salon
Written by

Qunar Tech Salon

Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.