The Mink Extension for Behat is an excellent way to quickly get up and running with web acceptance testing. It allows the user to specify HTML elements on the page using common attributes like 'title', 'alt' and 'value'. Some steps allow the use of CSS selectors inline in the Gherkin files.
While this approach is great it has a few draw backs:
-
The attribute values may not always be the most business friendly and can reduce the readability of the Gherkin scenarios.
-
Sometimes it isn't possible to identify an element using the attributes the MinkExtension provides.
-
By using these attributes directly in the Gherkin files, they become tightly coupled to the front end implementation. Gherkin should express business requirements rather than implementation details.
Business Selectors for Behat allow the user to use steps very similar to the ones provided by the MinkExtension to describe elements on the page in business terms. At the time the test is run the business terms are swapped for a CSS selector which is maintained in a yml file.
Given I go to the page "Home Page"
When I follow the link "Add Subscription"
And I fill in the "first name box" field with "ben"
Then the "first name box" form field should contain "ben"
And I press the "test" button
And the "Widget" should contain "Area One Text"
The quoted values map to the values in the file configured in behat.yml by the parameter 'selectorFilePath'.
Add Subscription: "a.self-link"
first name box: "form#name_form input[name=first_name]"
test: "form#name_form input[name=submit]"
Widget: div#user_widget
The best way to install the contexts is by using composer.
-
For instructions on installing Behat see: behat.org
-
Add in the following to the composer.json of the project you'd like to test.
{
"minimum-stability": "dev",
"repositories": [
{
"type": "vcs",
"url": "https://github.com/orangedigital/business-selector-extension"
}
],
"require": {
"behat/behat": ">v2.4@stable",
"orangedigital/business-selector-extension": "*"
}
}
- Add the OrangeDigital\BusinessSelectorExtension\Extension section to your behat.yml file as in the example below.
default:
context:
parameters:
javascript_session: selenium
browser: firefox
show_cmd: open %s
extensions:
OrangeDigital\BusinessSelectorExtension\Extension:
urlFilePath: urls.yml
selectorFilePath: selectors.yml
assetPath: path
contexts:
UIBusinessSelector: ~
Behat\MinkExtension\Extension:
base_url: "http://local.dev"
default_session: goutte
goutte: ~
selenium: ~
selenium2: ~
- Amend your FeatureContext file to use the BusinessSelectorContext file.
<?php
use Behat\Behat\Context\ClosuredContextInterface,
Behat\Behat\Context\TranslatedContextInterface,
Behat\Behat\Context\BehatContext,
Behat\Behat\Exception\PendingException;
use Behat\Gherkin\Node\PyStringNode,
Behat\Gherkin\Node\TableNode;
use Behat\MinkExtension\Context\MinkContext,
OrangeDigital\BusinessSelectorExtension\Context\BusinessSelectorContext;
class FeatureContext extends BehatContext
{
public function __construct(array $parameters)
{
$this->useContext('mink', new MinkContext($parameters));
$this->useContext('BusinessSelectors', new BusinessSelectorContext($parameters));
}
}
Install the provided examples by moving the html files in 'example/www' to the web root of a local webserver or create a vhost pointing to 'example/www'.
Edit 'example/behat.yml' 'base_url' to point to your the url of web root above.
Run ../bin/behat
##Steps Provided By Business Selectors
Bellow are a list of steps provided by the business selector extension. Values in denote arbitrary business friendly names which should match CSS selectors in the relevant config file (specified in behat.yml by 'urlFilePath' and 'selectorFilePath'). See the provided example implementation for details.
The URL below should be placed in the URLS file specified in behat.yml by the parameter "urlFilePath"
Given I go to the page "<PAGE NAME>"
All CSS Selectors below should be placed in the CSS selector file specified in behat.yml by the parameter "selectorFilePath"
When I follow the link "<LINK>"
When I press the "<BUTTON>" button
When I fill in the "<TEXT INPUT>" field with "value"
When the "<TEXT INPUT>" form field should not contain "value"
When I select "value" from the "<SELECT OR MULTISELECT>" selector
When I additionally select "value" from the "<MULTISELECT>" selector
When I check the "<CHECKBOX>" checkbox
When I uncheck the "<CHECKBOX>" checkbox
When I focus on the "<ID OF IFRAME>" iframe
Note: The step above is the only step where the selector MUST be an ID. This is due to an underlying driver implementation detail
When I refocus on the primary page
When I hover over "<PAGE ELEMENT>"
Then the "<PAGE ELEMENT>" should contain "value"
Then the "<PAGE ELEMENT>" should not contain "value"
Then I should see "<PAGE ELEMENT>" component
Then I should not see "<PAGE ELEMENT>" component
Then "<PAGE ELEMENT>" should contain "<PAGE ELEMENT>"
Then "<PAGE ELEMENT>" should not contain "<PAGE ELEMENT>"
Then the "<CHECKBOX>" should be checked
Then the "<CHECKBOX>" should not be checked
Then the "<TEXT INPUT>" form field should contain "value"