Line Breaking in JavaScript

What should you do when a line of code exceeds the max character length of 80?

You want to break (split) the line into two. The recommended best practice is to break after an operator and indent the next line two levels.

It’s important to break the line after an operator because JavaScript’s built-in automatic semicolon insertion mechanism won’t close the statement. Be sure to use the same line-breaking pattern for statements as well. There is an exception to the rule. When assigning a value to a variable, wrap lines directly under the first part of the assignment. See the examples below.


// Correct. Break after an operator and indent two levels.
doWork(argumentOne, argumentTwo, argumentThree, argumentFour, argumentFive, 

// Incorrect. Break before operator and indent only one level.
doWork(argumentOne, argumentTwo, argumentThree, argumentFour, argumentFive
    , argumentSix);

// Exception. Assigning a value to a variable.
let result = aValue + anotherValue + anAdditionalValue + yetAnotherValue + 

Statement Termination in JavaScript

Is it okay to omit semicolons when terminating statements?

Yes, but it’s not recommended.

Why? It’s easy to introduce errors when relying on a complete understanding of JavaScript’s automatic semicolon insertion (ASI) mechanism. In many cases, developers assume a semicolon will be inserted when it will not.


// Valid but not recommended.
let name = "Jason"
function sayHello() {
    console.log("Hello " + name)    

// Recommended.
let name = "Jason";
function sayHello() {
    console.log("Hello " + name);

Indentation Levels for JavaScript

What’s the recommended indentation level for JavaScript code?

There’s no universal agreement, but my recommendation is four spaces per indentation level.

Here are the indentation rules from notable JavaScript style guides:

• Crockford’s Code Conventions for JavaScript recommends 4 spaces for indents.
• The Dojo Style Guide recommends tabs (set to 4 spaces) for indents.
• The Google JavaScript Style Guide recommends two spaces for indents.
• The jQuery Style Guide recommends indentation with tabs.

Whichever style you adopt, be sure not to mix them.

Tools for JS Style Guidelines

What are some useful tools for enforcing JavaScript style guidelines?

Two are JSLint and JSHint.

JSLint is a tool written by famed Douglas Crockford. It’s a tool that detects potential errors and stylistic concerns in your code. JSHint is a fork of JSLint, and it provides a less strict, more customizable experience. Both are excellent options, and integrating one or both into your development process is a great way to enforce JS code conventions. Additionally, Crockford has provided rules on JavaScript style in the following documents:
Part One deals with syntax and basic patterns.
Part Two deals with language idioms.
Code Conventions for the JavaScript Language contains points from the first two, with a small number of style guidelines.

Standard Libraries and Test Automation

You need to develop a suite of automated test cases for an application you own. You dig in and start writing all the functionality required to build up a robust test suite. Are you proceeding wisely?

As it turns out, no you’re not. There’s a good chance someone has already solved your problem or problems. It’s best to see if you can find the capabilities you desire in a third-party library.

Favor reusable libraries to make your solution simpler and clearer. An added benefit to this approach is well-tested code.

Coordinate-Based Clicks and Non-Standard Controls

You’re automating a test, and you need to work with a custom control. The tool you’re using doesn’t want to cooperate. Should you implement click actions using X and Y coordinates?

It’s wise to avoid implementing hard-coded clicks. Instead, use selectors to obtain a parent element and work your way down the DOM tree.

Why? Using coordinates will make your tests more brittle; especially when it comes to responsive applications.

Add Randomness to Automated Tests

How should you automate cases that exercise functionality in a variety of ways?

Write several workflow-based functions or methods and randomly inject them in your tests.

It’s important to add an element of randomness in your automated tests. This holds true for both data and operations. For example, use data-driven techniques to switch up the data used by tests.

The example below demonstrates a data-driven approach to testing a login feature.

import { t } from 'testcafe';

fixture `login`
    .page ``;

const testCases = [
        name:     'Valid User',
        email:    'valid@example.fake',
        password: 'pass'
        name:     'Invalid User',
        email:    'invalid@example.fake',
        password: 'fail'

async function performLogin (email, password) {
    await t
        .typeText('#email', email)
        .typeText('#password', password)

for (const user of testCases) {
    test('test ' +, async t => {
        await performLogin(, user.password);

        // Confirm valid user can login.
        await t.expect('#username').eql('Valid User');

        // Confirm invalid user can't login.