WebdriverIO Tests with Multiple Browsers

Everything was working great… and then all the tests broke.

This is the story of how adding a single feature into an app can break all of your
tests. And the lessons can be learned from it.

The Feature that Introduced the Chaos

We are working on a Drupal maintenance support plans site that makes uses of a multisite approach. In this
case, it means that different domains are pointed at the same web server and the
site reacts differently depending on which domain you are referencing.

We have a lot of features covered by automatic tests in Webdriver IO – an end
to end framework to tests things using a real browser. Everything was working
great, but then we added a new feature: a content moderation system defined by
the workflow module recently introduced in Drupal maintenance support plans 8.

The Problem

When you add the Workflow Module to a site – depending on the configuration you
choose – each node is no longer published by default until a moderator
decides to publish it.

So as you can imagine, all of the tests that were expecting to see a node
published after clicking the save button stopped working.

A Hacky Fix

To fix the failing test using Webdriver you could:

Login as a user A.
Fill in all the fields on your form.
Submit the node form.
Logout as user A.
Login as user B.
Visit the node page.
Publish the node.
Logout as user B.
Login back as user A.
And make the final assertions.

Here’s a simpler way to fix the failing test:

You maintain your current test that fills the node form and save it. Then,
before you try to check if the result is published, you open another browser,
login with a user that can publish the node, and then with the previous browser
continue the rest of the test.

Multiremote Approach

To achieve this, Webdriver IO has a special mode called multiremote:

WebdriverIO allows you to run multiple Selenium sessions in a single test.
This becomes handy when you need to test application features where multiple
users are required (e.g. chat or WebRTC applications). Instead of creating a
couple of remote instances where you need to execute common commands like
init or url on each of those instances, you can simply create a multiremote
instance and control all browser at the same time.

The first thing you need to do is change the configuration of your wdio.conf.js
to use multiple browsers.

export.config = {
// …
capabilities: {
myChromeBrowser: {
desiredCapabilities: {
browserName: ‘chrome’
}
},
myFirefoxBrowser: {
desiredCapabilities: {
browserName: ‘firefox’
}
}
}
// …
};

With this config, every time you use the variable browser it will repeat the
actions on each browser.

So, for example, this test:

var assert = require(‘assert’);

describe(‘create article’, function() {
it(‘should be possible to create articles.’, function() {
browser.login(‘some user’, ‘password’);

browser.url(‘http://example.com/node/add/article’)
browser.setValueSafe(‘#edit-title-0-value’, ‘My new article’);
browser.setWysiwygValue(‘edit-body-0-value’, ‘My new article body text’);

browser.click(‘#edit-submit’);
browser.waitForVisible(‘.node-published’);
});
});

will be executed multiple times with different browsers.

Each step of the test is executed for all the browsers defined.

Instead of using browser you can make use of the keys defined in the capabilities
section of the wdio.conf.js file. Replacing browser with myFirefoxBrowser
will execute the test only in the Firefox instance, allowing you to use the other
browser for other types of actions.

Using the browser name, you can specify where to run each step of the test.

The Custom Command Problem

If you take a deeper look at previous code, you will notice that there are three
special commands that are not part of the WebdriverIO API. login, setValueSafe
and setWysiwygValue are custom commands that we attach to the browser object.

You can see the code of some of those commands in the drupal-elm-starter code.

The problem is – as @amitai realized
some time ago – that custom commands don’t play really well with the multiremote
approach. A possible solution to keep the custom commands available in all of
the browsers is to use some sort of class to wrap the browser object. Something
similar to the PageObject pattern.

An example of the code is below:

class Page {

constructor(browser = null) {
this._browser = browser;
}

get browser() {
if (this._browser) {
return this._browser;
}
// Fallback to some browser.
return myChromeBrowser;
}

visit(path) {
this.browser.url(path);
}

setWysiwygValue(field_name, text) {
this.browser.execute(
‘CKEDITOR.instances[“‘ + field_name + ‘”].insertText(“‘ + text + ‘”);’
);
}

login(user, password) {
this.visit(‘/user/login’);
this.browser.waitForVisible(‘#user-login-form’);
this.browser.setValue(‘#edit-name’, user);
this.browser.setValue(‘#edit-pass’, password);
this.browser.submitForm(‘#user-login-form’);
this.browser.waitForVisible(‘body.user-logged-in’);
}

}

module.exports = Page;

So now, you have a wrapper class that you can use in your tests. You can create
multiple instances of this class to access the different browsers while you
are running a test.

var assert = require(‘assert’);
var Page = require(‘../page_objects/page’);

describe(‘create article’, function() {
it(‘should be possible to create articles.’, function() {
let chrome = new Page(myChromeBrowser);
let firefox = new Page(myFirefoxBrowser);

chrome.login(‘some user’, ‘password’);
firefox.login(‘admin’, ‘admin’);

chrome.visit(‘http://example.com/node/add/article’)
chrome.setValueSafe(‘#edit-title-0-value’, ‘My new article’);
chrome.setWysiwygValue(‘edit-body-0-value’, ‘My new article body text’);
chrome.browser.click(‘#edit-submit’);

// Here is where the second browser start to work.
// This clicks the publish button of the workflow module
firefox.visit(‘/my-new-article’);
firefox.browser.click(‘#edit-submit’);

// Once the node was published by another user in another browser
// you can run the final assertions.
chrome.browser.waitForVisible(‘.node-published’);
});
});

What About Automated Tests?

You may be also wondering, does this work seemlessly for automated tests? And the answer is:
yes. We have only tried it using the same browser version in different instances.
This means that we trigger several chrome browser instances that acts as independent browsers.

If you have limitations in how many cores you have availble to run tests, it should not
limit how many browsers you can spawn. They will just wait their turn when a core becomes
available. You can read more on how we configure travis to
optimize resources.

As you can see, having multiple browsers available to run tests simplifies
their structure. Even if you know that you will not need a multiremote
approach at first, it may be a good idea to structure your tests using this
browser wrapper, as you don’t know if you will need to refactor all of
your tests to run things differently in the future.

This approach also can help to refactor the ideas provided by one of our prior
posts. Using JSON API with WebdriverIO Tests so
you don’t need to worry about login in with the right user to make the json requests.

Continue reading…
Source: New feed

This article was republished from its original source.
Call Us: 1(800)730-2416

Pixeldust is a 20-year-old web development agency specializing in Drupal and WordPress and working with clients all over the country. With our best in class capabilities, we work with small businesses and fortune 500 companies alike. Give us a call at 1(800)730-2416 and let’s talk about your project.

FREE Drupal SEO Audit

Test your site below to see which issues need to be fixed. We will fix them and optimize your Drupal site 100% for Google and Bing. (Allow 30-60 seconds to gather data.)

Powered by

WebdriverIO Tests with Multiple Browsers

On-Site Drupal SEO Master Setup

We make sure your site is 100% optimized (and stays that way) for the best SEO results.

With Pixeldust On-site (or On-page) SEO we make changes to your site’s structure and performance to make it easier for search engines to see and understand your site’s content. Search engines use algorithms to rank sites by degrees of relevance. Our on-site optimization ensures your site is configured to provide information in a way that meets Google and Bing standards for optimal indexing.

This service includes:

  • Pathauto install and configuration for SEO-friendly URLs.
  • Meta Tags install and configuration with dynamic tokens for meta titles and descriptions for all content types.
  • Install and fix all issues on the SEO checklist module.
  • Install and configure XML sitemap module and submit sitemaps.
  • Install and configure Google Analytics Module.
  • Install and configure Yoast.
  • Install and configure the Advanced Aggregation module to improve performance by minifying and merging CSS and JS.
  • Install and configure Schema.org Metatag.
  • Configure robots.txt.
  • Google Search Console setup snd configuration.
  • Find & Fix H1 tags.
  • Find and fix duplicate/missing meta descriptions.
  • Find and fix duplicate title tags.
  • Improve title, meta tags, and site descriptions.
  • Optimize images for better search engine optimization. Automate where possible.
  • Find and fix the missing alt and title tag for all images. Automate where possible.
  • The project takes 1 week to complete.