Browser Console for Functional Testing

As a test engineer, you have to use DevTools for efficient testing of UI and frontend, and the browser’s Console is an essential part of it.

Andrey Enin
7 min readNov 14, 2023
Firefox Web Console

Browser DevTools provides invaluable assistance for the functional testing of web services. At a minimum, opened Browser Console will display errors on a testing web page.

The topic of this article is the Console’s command line — a tool that allows to evaluate JavaScript inside a browser. This means it allows to run scripts, modify DOM, and control the browser. That is why some popular websites show warning messages in the Console for ordinary users.

Facebook.com Console Logs
Facebook.com Console Logs

1. Run JavaScript in the Console

Yes, you can execute code on JavaScript inside the browser’s Console! The possibilities are limited, but they are enough for simple calculations, scripts, and testing of proof of concepts.

// Calculation in the Console
2 * 2

// JavaScript script for getting a random number
const getRandomInt = (max) => {
return Math.floor(Math.random() * max);
};
console.log(getRandomInt(10));

// Get Unix timestamp
console.log(Math.floor(Date.now()));
JavaScript in the Console
JavaScript in the Console

This case includes the handy command $_. It returns the result of the last executed expression and can be used to engage a previous result in subsequent scripts.

2 * 2

// Return the result of the last expression
$_

// Calculate the square root of the last expression
Math.sqrt($_)
$_
$_

Further reading:

2. Find elements, evaluate and validate selectors

Use document.querySelector() method to fetch a single element on the page (or the first one if several elements fit the selector). $ is a shorter way of the same command.

document.querySelector('.notecard');

or

$('.notecard');

document.querySelector()
document.querySelector(). In this and and the following illustrations the browser’s Console is split-opened in the Inspector tab

These methods are useful for finding elements on the page and for validating your selectors that are going to be used in autotests. Thus you can test pattern-matching of CSS selectors for required elements.

$('[class*=banner]');

document.querySelector() or $()
document.querySelector() or $()

Use document.querySelectorAll() for fetching multiple elements on the page, or $$ as a short alias.

document.querySelectorAll('[class^=code]');

or

$$('[class^=code]');

document.querySelectorAll() or $$()
document.querySelectorAll() or $$()

For manual testing, the output of the querySelectorsAll() in the form of an array is of practical importance. Test engineer can instantly get the number of required elements by the length of the array.

The task of counting particular elements on the page can also be done in a more programming way:

const numberOfSelectors = $$('[class^=code]').length;

console.log(numberOfSelectors);
$$().length
$$().length

For fetching XPath selectors, use $x.

$x('.//h1');

$x()
$x()

If nothing matches with your selector, you will get null on the empty array.

Further reading:

3. Modify selected elements

Console allows to store currently-inspected element and refer to it for DOM modifications. To do that:

  1. Pic an element on the page;
  2. Return to console;
  3. Type the command: $0

Now, if you type $0 again, you will get the element in the Сonsole, and can modify the properties of the element (node in the DOM terms) or get the element’s properties and call HTMLElement methods.

// Evaluate stored element
$0

// Replace text context of the node
$0.innerText="Ad hoc"

// Evaluate the click on the element
$0.click();
$0
$0

Console allows to store up to five elements, and they will be available by $0, $1, $2, $3, and $4.

Further reading:

4. Copy almost anything

After evaluation of the element (or an output of JS code), you can copy it directly from the Console.

copy($('[class*=beta]'));

Copied content:

<sup class="new beta">Beta</sup>
copy()
copy()

NOTE: copy() does not copy recursive objects!

For example, if you get an array of elements by querySelectorsAll() and want to copy them through copy() — you will get nothing because of an array of elements.

// Evaluate all matching elements
$$('button.top-level-entry');

// Copy the result of the last expression
copy($_);

Copied content:

[
{},
{},
{}
]

Unfortunately, there is no way to fix it due to recursive objects.

copy() does not copy recursive objects
copy() does not copy recursive objects

But there is good news:

  • You can easily copy all localStorage: copy(localStorage);
  • And copy all cookies: copy(document.cookie);

Further reading:

5. Parse a page

Combining all the previous knowledge, you can perform advanced actions, for example, parse links from a page.

// Evaluate all links with .footer-nav-item class
const footerLinks = $$('.footer-nav-item a');

// Get only href attribute from an each element
const footerLinksArr = footerLinks.map((item) => item.getAttribute('href'));

// Convert array of objects into a plane object
const footerLinksObj = Object.assign({}, footerLinksArr);

// Copy object
copy(footerLinksObj);
Parse links from the page’s footer
Parse links from the page’s footer

Copied content:

{
"0": "/en-US/about",
"1": "/en-US/blog/",
"2": "https://www.mozilla.org/en-US/careers/listings/?team=ProdOps",
"3": "/en-US/advertising",
"4": "https://support.mozilla.org/products/mdn-plus",
"5": "/en-US/docs/MDN/Community/Issues",
"6": "/en-US/community",
"7": "https://discourse.mozilla.org/c/mdn/236",
"8": "/discord",
"9": "/en-US/docs/Web",
"10": "/en-US/docs/Learn",
"11": "/en-US/plus",
"12": "https://hacks.mozilla.org/"
}

The beauty of this operation is that it was done just inside the browser without any additional tooling!

6. Represent data in a table view

Console has the table() method for the readability of arrays and plain objects. It accepts an array as parameters (or index-values of a plain object) and displays them in a table view.

console.table($_);

console.table()
console.table()

7. Turn on design mode

The cherry on top for manual testers is a chance to set ALL texts on the page to editable. That is done by changing Document designMode property’s value.

document.designMode = "on"

Design mode is on ⇒ all document is editable
Design mode is on ⇒ all document is editable

Further reading about all Console’s features:

8. Take screenshots (Firefox only)

Firefox has one special feature — taking screenshots by Console’s command:

  • :screenshot — taking a screenshot of a currently visible viewport;
  • :screenshot --fullpage — taking a screenshot of the full page.
:screenshot in Firefox
:screenshot in Firefox

Further reading:

9. Detect which element has the focus

That hack is essential during A11y testing: when you navigate through the page by pressing the TAB key, you can lose a focus element (the outline property can be none, a focused element can be hidden, or elements’ order can be unpredictable).

document.activeElement — shows an element that currently has focus.

document.activeElement in Firefox console
document.activeElement in Firefox console

Moreover, in Chrome DevTools, you can use Live Expression to watch your command’s values in real time:

  1. Click on [Create live expression] (an eye-like button);
  2. In the appeared «Expression» input, type document.activeElement
  3. Now click on the page or tab around and see how the live expression’s output will update the currently focused element.
document.activeElement in Chrome DevTools Live Expression
document.activeElement in Chrome DevTools Live Expression

General documentation:

Further tricks:

--

--

Andrey Enin

Quality assurance engineer: I’m testing web applications, APIs and do automation testing.