CSS Selector Substitution For Behat

0.9.2 2012-09-21 16:15 UTC

This package is auto-updated.

Last update: 2021-02-06 01:06:53 UTC


Build Status



The original project can be seen here

And many notes still apply below. I needed to simplify it a bit for the project I am using it on though it still is extendable to to other projects.

Basically I do not want errors thrown if a token is not found since it can default back to the string the user used and then let Behat error out as needed


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:

  1. The attribute values may not always be the most business friendly and can reduce the readability of the Gherkin scenarios.

  2. Sometimes it isn't possible to identify an element using the attributes the MinkExtension provides.

  3. 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.


Gherkin Written With Steps Provided By BusinessSelectorsExtension

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.

  1. For instructions on installing Behat see:

  2. Add in the following to the composer.json of the project you'd like to test.

    "minimum-stability": "dev",
    "require": {
        "behat/behat": ">v2.4@stable",
        "orangedigital/business-selector-extension": "*"
  1. Add the OrangeDigital\BusinessSelectorExtension\Extension section to your behat.yml file as in the example below.
            javascript_session: selenium
            browser: firefox
            show_cmd: open %s
          urlFilePath: urls.yml
          selectorFilePath: selectors.yml
          assetPath: path
          timeout: 30
            UIBusinessSelector: ~
            base_url: ""
            default_session: goutte
            goutte: ~
            selenium: ~
            selenium2: ~
  1. Amend your FeatureContext file to use the BusinessSelectorContext file.

use Behat\Behat\Context\ClosuredContextInterface,
use Behat\Gherkin\Node\PyStringNode,
use Behat\MinkExtension\Context\MinkContext,

class FeatureContext extends BehatContext
    public function __construct(array $parameters)
        $this->useContext('mink', new MinkContext($parameters));
        $this->useContext('BusinessSelectors', new BusinessSelectorContext($parameters));

Installation: Examples

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 <BRACKETS> 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>" 
Given I attach "<FILE NAME> to <IMAGE INPUT>"

Note: This requires the assetPath to be configured to a relative directory that contains your assets (e.g. assetPath: assets/). Filename must include the extension associated with the file (e.g. example.jpeg).

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 click the "<CLICKABLE ELEMENT>"
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 "<IFRAME (RELATES TO ID OR INDEX)>" iframe

Note: The step above is the only step where the selector MUST be an ID. If the iframe does not have an ID, you can provide the index of the iframe, where 0 relates to the first iframe, 1 the second etc. An example of this can be found in example/features/example.feature

When I refocus on the primary page
When I hover over "<PAGE ELEMENT>"
When I wait for the "<PAGE ELEMENT>" component to [dis]appear
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"