There’s a lot of cool things that HTML5 can do, using local storage for data saving/retrieval or acquiring a users geolocation for your custom Google map. Well it turns out there’s many many more JavaScript APIs than I haven’t seen people mention, below are a few of these.

Before we go on, I should mention I’ll be focusing on APIs which benefit mobile/tablet devices, since these are really cool useful in modern web applications.

Online State

This exposes network connection information to web, quite simply we can now determine if a user has a Internet connection within our web application. This is highly useful in cases where the apps streams data in, we can let the user know that there’s a connection issue rather than simply returning nothing creating a much better user experience.

This API is being updated, things like grabbing a connection speed and adjusting app according would be useful, for example image degradation.

1
2
3
4
5
window.addEventListener('offline', networkStatus);
window.addEventListener('online', networkStatus);
function networkStatus(e) {
console.log(e);
}

Support

Browser support for this is excellent for recent browser versions, with some of the smaller device specific browsers such as Samung Internet supporting it.

Device Orientation

From this we have an easy way to determine the orientation of a device. This would be especially useful when dealing with media heavy web apps and ensuring your content can use the new orientation real estate efficiently. Also combined with CSS we can rotate images in a 3D space.

1
2
3
4
5
window.addEventListener('deviceorientation', (e) => {
console.log('alpha:', e.alpha);
console.log('beta:', e.beta);
console.log('gamma:', e.gamma);
});

Support

Browser support for this isn’t great, partial support with knows issues, fine for fun features and non essential but I wouldn’t rely on it.

Capture Ambient Light

This is really, really cool. The metric returned from this is lux which is used to measure light. You can read about the sensor API more here. A use case for this would be switching to a darker or lighter theme depending on available light, enabling the user to choose would certainly be a nice feature and provide a better user experience.

1
2
3
window.addEventListener('devicelight', (e) => {
console.log(`${e.value} lux`);
})

Support

Browser support for this is bad, it has been available in Chrome since version 62, however is an experimental feature and has to be enabled.

Battery Level

We can now detect battery levels, therefore also having the added benefit of determining if a device is plugged into a power source. The code for this a little different in that you’re using a promise. Since the W3C example has many code samples, I’ll use one of these.

1
2
3
4
5
6
navigator.getBattery().then(function(battery) {
console.log(battery.level);
battery.addEventListener('levelchange', function() {
console.log(this.level);
});
});

Support

Browser support for this is pretty poor unless you’re specifically targeting Chrome. Also as FireFox have removed the feature, therefore it doesn’t look promising for the future.

Comment and share

Selenium

I have used Selenium on occasion for automated frontend tests, it’s my go-to for web automation testing and provides an interface to enable browsers to use the libraries.

ChromeDriver is the implementation of the Chrome browser using the WebDriver protocols developed by Selenium, you can think of this in three blocks.

  • Chrome – your browser
  • WebDriver and language protocols – the driver
  • Executable by the Chromium project – the middleware that you’ll download

Also it’s worth pointing out that there are implementations for browsers such as Firefox and Edge, handy for cross browser testing!

Continue reading

Scenario

So you’ve got a good test suite for automated browser testing, however you’re testing a web app with different user roles, or case scenarios, that 1 minute test has now grown to 5 and it’s becoming a bottleneck in the development lifecycle. I ran into this exact problem myself.

In this post, we will be looking at how to reduce elapsed time between operations, and overall reduce total test suite execution time.

The Setup

Web Page

For the post I’ll be using the same website and loading the same web page. I’ve chosen a page with multiple round trips, images, videos, and several megabytes of content to simulate a sizable and real world web app. Chances are your tests will be fast on static HTML pages regardless of how your tests are written. Below is Google PageSpeed Insight results for this page.

Software

Performance Tests

As we’re making a HTTP request to a remote server, there’s many variables that could effect performance outside of our control. Using explicit or implicit waits doesn’t help us here since they’re designed to wait until a specific element appears via polling the DOM. We want to try eliminate server variance so we’ll use two test sets, one on a local server, and one remote.

Finding UI Elements

Our most common operation will be finding elements on a page and checking if their respective values align with our expectations. The ChromeDriver instance will exposes the FindElement and FindElements methods which will be using to find our DOM object. There’s several methods to find elements and we’ll be focusing on the three most popular:

  • By XPath
  • By ID
  • By Class Name

Setup

We’re going to keep this simple and create a blank C# Console Application with the minimum code to test performance, I’ll be using the StopWatch class to store elapsed time for each operation. An arbitrary sample size of 1500 iterations (500 per FindElementBy call) will be used to create an average for our results.

Test Results

Our results demonstrate that finding an element by ID is the most efficient, this is also inline with the documentation.

Optimizations

So our tests so far look good and produce the expected output, we’re going to use the same two tests whilst trying different methods of potential optimization and observe the output.

Browser Extensions

With the amount of HTTP request ever increasing, especially 3rd party request, we may benefit from something which filters request and reduces them. It makes sense that a page that fa faster page would mean faster tests. For this test we’re going to use uBlock Origin available here as a Chrome Extension. I’ve chosen uBlock due to it has a lightweight footprint and generally makes Chrome leaner via less CPU & RAM consumed by the browser.

Setup

To use the extension we’ll need to grab the .crx file, (you’ll need a third part tool such as this) and load it into our ChromeDriver instance. Below is the code for this

1
2
3
4
5
6
7
var cdOptions = new ChromeOptions();
cdOptions.AddExtension(@"C:\temp\uBlock-Origin_v1.14.20.crx");

//Directory where our Chronium executable is located
var cdFilePath = @"C:\tempMonitor";

var cd = new ChromeDriver(cdFilePath, cdOptions, TimeSpan.FromSeconds(30));

Results

We’re going to compare the results with our remote test

The results speak for themselves, we’re loading a remote page and finding elements 200-300 milliseconds quicker due to uBlock. This has another benefit of reducing the probability of a third party HTTP request hanging causing the page to never finish full loading which will eventually cause a TimeOutException.

Headless Chrome

A new feature of ChromeDriver is the ability to run the browser headless, so you won’t get a GUI however you’ll still be able to see it in process explorer. Headless has advantages in terms of speed as there’s no rendering of the browser, however naturally there are drawbacks like simulating a users input and not being able to see a problem on your page. For brevity we’re going to ignore the pros and cons and simply look at performance impact.

Setup

For this setup we’ll simply be passing in the headless argument, in headless mode the console receives a lot of warnings therefore we will hide those for now.

1
2
3
4
5
6
7
8
9
var cdOptions = new ChromeOptions();

cdOptions.AddArgument(@"--headless");
cdOptions.AddArguments(@"--log-level=3");

//Directory where our Chronium executable is located
var cdFilePath = @"C:\tempMonitor";

var cd = new ChromeDriver(cdFilePath, cdOptions, TimeSpan.FromSeconds(30));

Results

With Chrome in headless mode we’ve taken 300-400 milliseconds from our no extension tests, over a large test suite these would lead to great performance increase and the ability to run tests in parallel.

Comment and share

This is something I found myself thinking about when using the Block Element Module (BEM) methodology when coding using the preprocessor LESS.

I like this for the follow reasons:

  • Less repeating code
  • Ability to change the block name and auto cascade to the element descendants
  • Less lines and easier to read

The Code

1
2
3
4
5
6
7
8
9
10
block {
&__element {
&--modifier-alpha {
color: blue;
}
&--modifier--beta {
color: green;
}
}
}

So the compiled elements would look like this:

1
2
3
4
5
6
block__element--modifier-alpha {
color: blue;
}
block__element--modifier-beta {
color: green;
}

Comment and share

Author's picture

Ash Grennan

Software engineer, mostly working with .NET, Identity, React, AWS and many other technologies.

AO.com

UK