Next Mission to Moon: Cross Browser Selenium Testing in Kubernetes

Alexander Andryashin
Aerokube
Published in
6 min readDec 11, 2019

--

Hi there! We have not seen from May, so hope you were not suffering from unstable Selenium testing during this time. If you were — take a look at my previous articles first:

Today I would like to show you the latest and greatest stuff which was added to Moon — our flagship Selenium solution working in Kubernetes or Openshift cluster.

Chrome Developer Tools Protocol Support

The first cool feature is full support of so-called Chrome Developer Tools protocol. I think you should have noticed that every modern browser has some kind of developer toolbar allowing to access more detailed information about any web site you open.

For example you can inspect web page HTML structure, CSS styles, information about HTTP requests being executed, examine and manipulate cookies or local storage contents, execute Javascript code and do many more. While standard Selenium already supports a big part of developer toolbar functionality — some tools are still not available and even not described in W3C Selenium standard. For example with standard Selenium it is not possible to:

  • Track page network activity including loading the page itself and various AJAX requests. Such information is critical for debugging why web pages are loading slowly or catching bugs in communication between front end and back end of your web application.
  • Directly manipulate HTML page contents (change DOM tree)
  • Directly manipulate HTML page CSS styles
  • Inspect web page accessibility tree. This information is critical while testing that your application is suitable for using by persons with disabilities.
  • Trace or profile your web pages to be sure they perform sufficiently fast in real usage scenarios.
  • Subscribe to various page events and wait for them to occur.

While initially any kind of testing described above could be done manually with browser developer toolbar — sooner or later you will understand that it would be great to also automate these routine tasks. Here is where Chrome Developer Tools protocol comes into play. Introduced years ago in Google Chrome this protocol initially was a Chrome-specific way of communication between Chrome itself and its developer toolbar. Later Google started to use the same protocol in Chromedriver — a standalone executable allowing to manipulate Chrome browser with Selenium tools.

Nowadays Chrome Developer Tools protocol is a vast ecosystem with a lot of open-source libraries for different programming languages supporting it. All Chromium-based browsers (Opera Blink, Vivaldi, Brave, Yandex Browser and even latest releases of Microsoft Edge) have this protocol working out of the box. Even browsers with completely different rendering engines, such as Firefox, have plans to support the same protocol in next releases. So we can clearly state that Chrome Developer Tools protocol seems to become a standard for powerful browser internals access.

To give you a flavor of working with Chrome Developer Tools protocol let’s take a look at an example source code using Puppeteer — one of the most popular Chrome Developer Tools client libraries for Javascript:

const puppeteer = require('puppeteer');

(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({path: 'example.png'});
await browser.close();
})();

if you have some experience with Selenium you can notice that it looks very similar to Selenium: we have a browser startup command, then some actions like loading a web-page or taking a screenshot, then a command to stop the browser. The only problem with this code — it is only working on a machine with a recent Google Chrome version installed and only one browser can be working in parallel.

With Moon in addition to the power of Chrome Developer Tools features you are getting an ability to remotely use these features in an unlimited number of different Google Chrome versions being run in isolated containers. To deliver this we need to combine Selenium command with Puppeteer calls as follows:

const { remote } = require('webdriverio');
const puppeteer = require('puppeteer-core');
const host = 'moon.example.com';
(async () => {
const browser = await remote({
hostname: host,
port: 4444,
logLevel: 'trace',
capabilities: {
browserName: 'chrome',
browserVersion: '78.0'
}
});

const devtools = await puppeteer.connect(
{ browserWSEndpoint: `ws://${host}:4444/devtools/${browser.sessionId}/` }
);
const page = await devtools.newPage();
await page.goto('http://example.com');
await page.screenshot({path: 'example.png'});
await devtools.close();
await browser.deleteSession();

})().catch((e) => console.error(e));

In this example we are using well-known Selenium Javascript library called Webdriver.io to start a regular Selenium session with Chrome 78.0. Having a running browser we then connect to Chrome Developer Tools endpoint /devtools/<session-id> using Selenium session identifier and get immediate access to all Chrome Developer Tools protocol features.

Live Testing

The next powerful tool now working out of the box is manual testing functionality. In a few clicks in Moon UI you can now launch any configured browser version and do quick live manual testing of your web application. That means that you don’t need to spend your time installing an old browser version to reproduce a bug. Live testing will also work with complicated testing platforms. For example using images with Windows or Android emulator — you can do remote live testing in Internet Explorer or Chrome Mobile.

Powerful Video and Logs Storage

Moon supports capturing video of a running Selenium tests since its first releases. Recorded videos as well as session log files are automatically saved to S3-compatible storage. Initially all files were saved to the same directory using Selenium session identifier:

\---my-bucket
\---- faaeda25-b963-4668-9928-3bb1d3e3c66c
|---- video.mp4
|---- session.log
\---- 530d8312-1f0d-4f83-89fb-494ebab3a92f
|---- video.mp4
|---- session.log

It is now possible to organize video and log storage in a custom directories hierarchy. For example, let’s group files by browser name or version. To deliver this — we just need to configure so called S3 key pattern. A typical S3 key pattern is a string corresponding to an S3 directory where log and video files will be stored. Such pattern usually contains one or more placeholders like $browserName or $browserVersion which are replaced by actual browser name and browser version while saving video. S3 key pattern is configured in Moon service.json configuration file - just update respective Kubernetes config map as follows on a running cluster:

{
"s3": {
// The rest of S3 settings go here...
"keyPattern": "$browserName/$browserVersion/$sessionId"
}
}

Now all files will be stored as follows:

\---my-bucket
\--- firefox
\--- 69.0
\---- 530d8312-1f0d-4f83-89fb-494ebab3a92f
|---- video.mp4
|---- session.log
\--- 70.0
\---- faaeda25-b963-4668-9928-3bb1d3e3c66c
|---- video.mp4
|---- session.log

Local Deployment on Workstation

We understand that different teams are using different technologies in their everyday work. We personally prefer Unix-style operating systems and are working a lot with Docker. But there are a lot of teams far from Kubernetes and Docker and mainly working under Windows. For such teams we prepared a one-command installation script allowing to quickly deploy Moon to Windows machine and start testing in minutes: https://github.com/aerokube/kubernetes-selenium-desktop

One-click Deployment to DigitalOcean and Google Cloud

The last thing I would like to show you today is deploying Moon to popular cloud platforms. By default Moon is deployed to a working Kubernetes or Openshift cluster by downloading and applying ready to use manifests as follows:

$ git clone https://github.com/aerokube/moon-deploy.git
$ cd moon-deploy
$ kubectl apply -f moon.yaml

This will work with any cluster. For DigitalOcean and Google Cloud things are even simpler. There Moon is already present in cloud marketplace and could be launched with a few clicks in the UI. To launch Moon is Digital Ocean:

In Google Cloud startup procedure is very similar:

Conclusion

As you can see Moon powerful features list is growing and we are working hard to deliver more powerful stuff during next months. If you are interested in trying Moon in your company and have questions — don’t hesitate to contact us by email or in Telegram support channel. If you need need a free evaluation key — generate one on Moon website.

--

--