How to set up and write Browser based tests for an existing Drupal site/database.

Pasan Gamage
4 min readJul 5, 2022

--

Introduction

I’m sure most of you are familiar with the term browser testing. It is a great way to test out application GUI and allows you to test client side code and also test certain parts of server side code. Unfortunately, there is very little material that elaborate what and how to use it in Drupal.

The main reason for me to write this article is because I recently investigate on ways to test certain things of the Drupal admin UI such as autocomplete fields, conditional fields and other fields that rely on Ajax to load data.

Use of browser tests was needed as we could no longer use functional tests using ExistingSiteBase class to cover those aforementioned scenarios.

ExistingSiteBase class comes in a popular vendor package weitzman Drupal Test Traits. We can use this same package to set up browser testing using.

As I need the tests to run against an existing Drupal site I will be using ExistingSiteSelenium2DriverTestBase

Browser based test execution methods

There are 2 main methods to execute browser based testing.

  • Using a Webdriver
  • As headless

Webdriver

As the tests are automated, we need a way to tell the browser how to operate and what to click and so on. These commands need to be fed to the browser using a special layer. And this layer is Mink.

It has an interface for a ‘driver’ that controls the ‘browser’. Depending on the browser (Chrome, Firefox or Edge) the drivers are different.

i.e.

If you want to run tests regardless of the browser, you can use Selenium.

Headless

This basically means the tests doesn’t have a UI. It will still use a driver but unlike before, a browser window will not open and you will not see the test steps getting executed visually.

Supposedly this method of tests are faster as it do not require the browser to load. However, I only saw a 2-second time saved using this method. The downside of this is you will not see the steps getting executed visually, and for some it may be an issue.

Since I’m using a Mac and as I have my Drupal project setup locally in a non Docker environment, the commands you will see here on are mostly mac centric.

Option 1 — Setting up Selenium locally

In your Mac terminal run below commands.

Install selenium server:

brew install selenium-server

Start the server:

selenium-server standalone --port 4444

The result should look like this.

Also, you will need to add the below line to your phpunit.xml

<env name="DTT_MINK_DRIVER_ARGS" value='["chrome", { "chromeOptions" : { "w3c": false } }, "http://localhost:4444/wd/hub"]'/>

My local server address is http://localhost and the value ischrome but you can change these accordingly.

Finally, set the testsuite tags for the new tests in the phpunit.xml file.

<testsuite name="functionaljavascript">
<directory>./app/modules/custom/*/tests/src/FunctionalJavascript</directory>
</testsuite>

A good phpunit file example can be seen here.

You can modify this test class file and try it out.
What you should see it a new Chrome window appear and execute the steps given in the test execute in the GUI in sequence. Once the tests are executed, the browser window will close and when you check the terminal you will see the test results.

Option 2 — Set up chrome driver

Thanks to this article, I managed to get my tests to execute without Selenium server running.

This is because Chromedriver implements the webdriver protocol by itself and so it is enough.

For this we need to install chrome driver locally.

In your terminal run below commands.

brew install chromedriver

Start the server.

chromedriver

If you want to specify additional options, you can modify the command as follows.

i.e.

chromedriver --port=9222 --log-level=ALL "--whitelisted-ips=" "--allowed-origins=*" "--remote-debugging-port=0"

By default, chrome driver will use port 9515 so we can leave it as is.

Now we just need to update the phpunit.xml file.

To use the GUI, you can add;

<env name="DTT_MINK_DRIVER_ARGS" value='["chrome", { "chromeOptions" : { "w3c": false } }, "http://127.0.0.1:9515"]'/>

And for headless

<env name="DTT_MINK_DRIVER_ARGS" value='["chrome", {"chromeOptions":{"args":["--disable-gpu", "--headless"], "w3c": false}}, "http://127.0.0.1:9515"]'/>

Optionally, you can set DTT API OPTIONS

<env name="DTT_API_OPTIONS" value='{"socketTimeout": 360, "domWaitTimeout": 3600000}' />

Same as before, you can execute the tests that extend from ExistingSiteSelenium2DriverTestBase without the need to change anything.

I hope this article will help you, and please do let me know your thoughts and gotchas along the way in the comments.

Happy testing !

Resources

  • Introduction to DTT (Drupal Test Traits)

https://medium.com/massgovdigital/introducing-drupal-test-traits-9fe09e84384c

  • WebDriver browser mode vs Headless browser mode

https://medium.com/@chx/browser-testing-with-chromedriver-drupal-8-5-0-1d4a7eebf2c4

  • Browser testing with Chromedriver

https://medium.com/@chx/browser-testing-with-chromedriver-drupal-8-5-0-1d4a7eebf2c4

  • Gecko Driver

https://www.javatpoint.com/selenium-webdriver-running-test-on-firefox-browser-gecko-driver

  • Drupal Change records

https://www.drupal.org/node/2846936

Special thanks to Lee Rowlands for helping me understand the initial concepts of browser based testing on Drupal.

--

--

Pasan Gamage
Pasan Gamage

Written by Pasan Gamage

Backend Developer | Motorbike enthusiast

No responses yet