I strongly suggest you read part 1 where I explain how each of these libraries and applications interact with each other. Part 1: Automated Drupal testing with Behat, Selenium, and Headless Firefox

Verify Prerequisites

I assume you have the following already installed:

Installation

Have Composer Install Dependencies

We'll let Composer handle the majority of the work. We'll need to tell Composer what dependencies our project requires.

Create composer.json

Create a composer.json file that contains all our required packages by pasting in the following:

{ "require": { "behat/behat": "~3.0", "behat/mink-goutte-driver": "~1.2.0", "behat/mink-extension": "~2.1", "behat/mink-selenium2-driver": "~1.3", "drupal/drupal-extension": "~3.1" } }

Composer Install

Have Composer install our needed packages. From the same directory the composer.json file is in, run:

composer install

Troubleshooting If you get an error like the following: PHP Fatal error: Uncaught exception 'ErrorException' with message 'proc_open(): fork failed - Cannot allocate memory' Composer executes PHP on the CLI so it should be configured to have no memory limit by default thus exhausting all the machine has to offer. You will need to enable Virtual Memory (Swap File).

Setup Behat

Behat will handle all the actual test cases. We'll configure some path settings and have Behat initialize our directory structure.

Create behat.yml

Create a new file called behat.yml and paste in the following:

default: autoload: '': %paths.base%/features/bootstrap suites: default: paths: - %paths.base%/features contexts: - FeatureContext - Drupal\DrupalExtension\Context\DrupalContext - Drupal\DrupalExtension\Context\MinkContext - Drupal\DrupalExtension\Context\MessageContext extensions: Behat\MinkExtension: goutte: ~ selenium2: ~ base_url: https://drupal.org/ Drupal\DrupalExtension: blackbox: ~ region_map: header_nav: ".wx-header-tools"

We're using Behat 3.x so the autoload and path settings look a little different from the old 2.5 version.

Notice the use of blackbox . It comes with the DrupalExtension; it allows us to find elements within a "region" for situations where the target element doesn't have a unique selector. See Blackbox docs for more information.

Initialize Behat Config

Now that we have our behat.yml file configured, let's have Behat initialize a working directory tree.

. / vendor / bin / behat --init

You should get some green outputs about where to put features and context classes.

Install Firefox

Nothing special here. Just use apt-get to install the current stable release of Firefox.

sudo apt-get install firefox

Install & Configure Xvfb

We'll use Xvfb to create a dummy display for Firefox to run in.

Install Xvfb

sudo apt-get -y install xvfb gtk2-engines-pixbuf sudo apt-get -y install xfonts-cyrillic xfonts-100dpi xfonts-75dpi xfonts-base xfonts-scalable

Configure Xvfb Display

We need to configure a display number kind of high to avoid collision with existing displays.

sudo Xvfb : 10 -ac -screen 0 1024x768x8 &

You may get a warning about missing font paths; this is okay, just ctrl+c. Verify Xvfb is running by running:

ps aux | grep -P "^root.*Xvfb"

You should get one or two lines back that look like:

root 11345 0.0 2.7 136480 13724 pts / 0 S 00: 24 0 :00 Xvfb : 10 -ac

Set Environment Display Variable

We need to update the DISPLAY environment variable so Firefox will know what to attach to.

export DISPLAY =: 10

Download & Configure Selenium

Download Selenium Standalone

Download the latest jar file.

curl -J -O -L http: // selenium-release.storage.googleapis.com / 2.53 / selenium-server-standalone-2.53.0.jar

We'll make a symbolic link to a filename without Selenium's version number.

ln -s . / selenium-server-standalone-2.53.0.jar . / selenium-server-standalone.jar

Selenium - Hub (aka Server)

Selenium can be configured to run as a hub, a node, or standalone. For this tutorial, we'll configure the hub first, then add a node.

Create a script called start-selenium-hub.sh that will start our Seleniun Hub.

Paste the following code in this new file:

#!/bin/bash java -jar . / selenium-server-standalone.jar -role hub -host 0.0.0.0 > . / selenium-hub.log 2 >& 1 &

Give the script executable permissions and run it:

chmod u+x . / start-selenium-hub.sh . / start-selenium-hub.sh

Notice we're outputting to a selenium-hub.log file. We'll do the same for the node.

Warning! Selenium binds to 0.0.0.0 Selenium binds to the 0.0.0.0 interface regardless of the host settings you provide. You should not run this on a publicly accessible machine without blocking external connections via a firewall or iptables.

Selenium - Node

Create a script called start-selenium-node.sh that will start our Selenium node.

Paste the following code in this new file:

#!/bin/bash if [ ! -f / tmp / .X5-lock ] ; then / usr / bin / Xvfb : 10 -ac -screen 0 1024x768x8 & fi export DISPLAY =: 10 # firefox needs this to know where to find a display to run on java -jar . / selenium-server-standalone.jar -role node -hub http: // 127.0.0.1: 4444 / grid / register / > . / selenium-node.log 2 > . / selenium-node.err &

Give the script executable permissions and run it:

chmod u+x . / start-selenium-node.sh . / start-selenium-node.sh

Troubleshooting If Selenium fails to start fully and you are on a VPS hosting service such as Digital Ocean or a VM; see this entropy related problem and solution:

Selenium Node, slow hub register

Behat Test Scripts

We're almost ready to run our test scripts!

Write our first test script!

We're going to do a test search on drupal.org for our test.

When we ran /vendor/bin/behat --init earlier, a file features/test.feature was created. This is where we'll store our test cases.

Add the following to the features/test.feature file:

Feature: Drupal.org search Searching for behat from drupal.org's search box. @ javascript Scenario: Searching for "behat" Given I go to "https://www.drupal.org" When I search for "behat" Then I should see "Behat Drupal Extension"

Tell Behat how to search

We'll be testing Drupal.org's search box. For this, we need to write a custom step definition for: "I search for".

Earlier when we ran /vendor/bin/behat --init , it generated a file: features/bootstrap/FeatureContext.php . In this file, add the follow snippet:

/** * @When /^I search for "([^"]*)"$/ */ public function iSearchFor ( $search_term ) { $page = $this -> getSession ( ) -> getPage ( ) ; $page -> fillField ( 'Search' , $search_term ) ; $page -> pressButton ( 'Search' ) ; }

Run our tests

Make sure you are currently in the directory that contains the behat.yml . Run the following command:

vendor/bin/behat

You should get an output similar to:

Feature: Drupal.org search Searching for behat from drupal.org's search box. @javascript Scenario: Searching for "behat" # features/test.feature:5 Given I go to "https://www.drupal.org" # Drupal\DrupalExtension\Context\MinkContext::visit() When I search for "behat" # FeatureContext::iSearchFor() Then I should see "Behat Drupal Extension" # Drupal\DrupalExtension\Context\MinkContext::assertPageContainsText() 1 scenario (1 passed) 3 steps (3 passed) 0m9.66s (14.59Mb)