PHPackages                             ekino/behat-helpers - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. ekino/behat-helpers

AbandonedArchivedLibrary[Testing &amp; Quality](/categories/testing)

ekino/behat-helpers
===================

Helpers for Behat

v0.3.1(4y ago)219.8k↓100%6[3 PRs](https://github.com/ekino/behat-helpers/pulls)MITPHPPHP ^7.2 || ^8.0

Since Aug 28Pushed 4y ago12 watchersCompare

[ Source](https://github.com/ekino/behat-helpers)[ Packagist](https://packagist.org/packages/ekino/behat-helpers)[ Docs](https://github.com/ekino/behat-helpers)[ RSS](/packages/ekino-behat-helpers/feed)WikiDiscussions master Synced today

READMEChangelog (5)Dependencies (10)Versions (9)Used By (0)

Behat Helpers
=============

[](#behat-helpers)

[![Latest Stable Version](https://camo.githubusercontent.com/10a8fbcdcd29ca7d5780792c128aa6b5b16047f8dd40468a68d7e5e11dcfc865/68747470733a2f2f706f7365722e707567782e6f72672f656b696e6f2f62656861742d68656c706572732f762f737461626c65)](https://packagist.org/packages/ekino/behat-helpers)[![Build Status](https://camo.githubusercontent.com/bba015ccf963931f052c1c36f5e0d1bd10cb7bb0d7499785cba5fec96284b674/68747470733a2f2f7472617669732d63692e6f72672f656b696e6f2f62656861742d68656c706572732e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/ekino/behat-helpers)[![Coverage Status](https://camo.githubusercontent.com/76577b0260f3fd06a9dc387f6f49357ed4bfe7f04f171f1d7b430c9440e46320/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f656b696e6f2f62656861742d68656c706572732f62616467652e7376673f6272616e63683d6d617374657226736572766963653d676974687562)](https://coveralls.io/github/ekino/behat-helpers?branch=master)[![Total Downloads](https://camo.githubusercontent.com/9a2a041bd35a4e3e2469458cbd7253831356795ad9ad413bbc7d401600fe0d32/68747470733a2f2f706f7365722e707567782e6f72672f656b696e6f2f62656861742d68656c706572732f646f776e6c6f616473)](https://packagist.org/packages/ekino/behat-helpers)

This library provides some helpers over Behat.

This is a *work in progress*, so if you'd like something implemented please feel free to ask for it or contribute to help us!

Installation
------------

[](#installation)

Require it using [Composer](https://getcomposer.org/):

```
composer require --dev ekino/behat-helpers
```

And use the helpers you need in your FeatureContext class.

### BaseUrlTrait

[](#baseurltrait)

Behat handles only one base URL to run the tests suites. In order to test a multisite-application, this trait allows you to inject a base URL by suite.

```
# behat.yml
default:
    suites:
        suite_1:
            contexts:
                - Tests\Behat\Context\MyFeatureContext:
                    - https://foo.bar.localdev
        suite_2:
            contexts:
                - Tests\Behat\Context\MyFeatureContext:
                    - https://bar.foo.localdev
```

```
// your feature context

namespace Tests\Behat\Context;

use Behat\MinkExtension\Context\MinkContext;
use Ekino\BehatHelpers\BaseUrlTrait;

class MyFeatureContext extends MinkContext
{
    use BaseUrlTrait;

    public function __construct($baseUrl)
    {
        $this->setBaseUrl($baseUrl);
    }
}
```

### DebugTrait

[](#debugtrait)

This trait can be used for debug purposes. It captures both HTML and screenshot when a step fails, so you can see the page at this moment.

Note that it requires `KernelDictionary` from [behat/symfony2-extension](https://github.com/Behat/Symfony2Extension).

```
// your feature context

namespace Tests\Behat\Context;

use Behat\MinkExtension\Context\MinkContext;
use Behat\Symfony2Extension\Context\KernelDictionary;
use Ekino\BehatHelpers\DebugTrait;

class MyFeatureContext extends MinkContext
{
    use DebugTrait;
    use KernelDictionary;
}
```

You can also profile your tests by adding the tag `behat_helpers_profile` on the feature or scenario. You'll see the consumed memory and the execution time for each scenario.

```
@behat_helpers_profile
Feature: Front test
  I want to be able to access to the application
```

```
@behat_helpers_profile
Scenario: foo elt should be visible in 2 seconds or less
    Given ...
    Then I wait for "foo" element being visible for 2 seconds
```

### ExtraSessionTrait

[](#extrasessiontrait)

This trait provides some helpers over the session.

```
// your feature context

namespace Tests\Behat\Context;

use Behat\MinkExtension\Context\MinkContext;
use Ekino\BehatHelpers\ExtraSessionTrait;

class MyFeatureContext extends MinkContext
{
    use ExtraSessionTrait;
}
```

```
Scenario: foo elt should be visible in 2 seconds or less
    Given ...
    Then I wait for "foo" element being visible for 2 seconds
```

StepRegexI wait for 2 seconds`/^I wait for (\d+) seconds?$/`I wait for "foo" element being visible for 2 seconds`/^I wait for "([^"]*)" element being visible for (\d+) seconds$/`I wait for "Foo" element being invisible for 2 seconds`/^I wait for "([^"]*)" element being invisible for (\d+) seconds$/`I scroll to 123 and 987`/^I scroll to (\d+) and (\d+)?$/`I wait 3 seconds that page contains text "Foo"`/^I wait (\d+) seconds that page contains text "([^"]*)"$/`I wait 3 seconds that page not contains text "Bar"`/^I wait (\d+) seconds that page not contains text "([^"]*)"$/`I click on button containing "Foo"`/^I click on (?:link|button) containing "(?P[^"]*)"$/`### ExtraWebAssertTrait

[](#extrawebasserttrait)

This trait provides some extra asserts.

```
// your feature context

namespace Tests\Behat\Context;

use Behat\MinkExtension\Context\MinkContext;
use Ekino\BehatHelpers\ExtraWebAssertTrait;

class MyFeatureContext extends MinkContext
{
    use ExtraWebAssertTrait;
}
```

StepRegexthe "Foo" element should have attribute "Bar"`/^the "(?P[^"]*)" element should have attribute "(?P(?:[^"]|\\")*)"$/`I click the "Foo" element`/^I click the "(?P[^"]*)" element$/`I should see at least 2 "Bar" elements`/^(?:|I )should see at least (?P\d+) "(?P[^"]*)" elements?$/`### ReloadCookiesTrait

[](#reloadcookiestrait)

This trait aims to write small/simple scenarii and preserve execution time. To do so, the cookies are reloaded between the scenarii. This can be useful in case of a multistep form: the first scenario fills the first step and submits (here the cookies are saved), then the second scenario is executed (the cookies are reloaded so no need to do the previous step again) and fills the second step...etc.

```
// your feature context

namespace Tests\Behat\Context;

use Behat\MinkExtension\Context\MinkContext;
use Ekino\BehatHelpers\ReloadCookiesTrait;

class MyFeatureContext extends MinkContext
{
    use ReloadCookiesTrait;

    /**
     * @When /^I fill the first step$/
     */
    public function fillStep1()
    {
        $this->doOnce(function () {
            $this->iAmOnHomepage();
            $this->fillField('input_step1', 'foo');
            $this->pressButton('Next');
        });
    }

    /**
     * @When /^I fill the second step$/
     */
    public function fillStep2()
    {
        $this->doOnce(function () {
            $this->fillStep1();
            $this->fillField('input_step2', 'bar');
            $this->pressButton('Next');
        });
    }
}
```

```
Scenario: I can fill the step1
    Given I fill the first step
    Then I should be on "/step2"

Scenario: I can fill the step2
    Given I fill the second step
    Then I should be on "/step3"
```

You can add the tag `behat_helpers_no_cache` to avoid cookies being saved/reloaded:

```
@behat_helpers_no_cache
Scenario: I can fill the step2
    Given I fill the second step
    Then I should be on "/step3"
```

You can add the tag `behat_helpers_reset_cache` to clear cookies previously saved:

```
@behat_helpers_reset_cache
Scenario: I am on /step1 if previous cookies are reset
    Given I fill the second step
    Then I should be on "/step3"
    But I am on "/step1"
```

StepRegexI fill the first step`/^I fill the first step$/`I fill the second step`/^I fill the second step$/`### ReloadDatabaseTrait

[](#reloaddatabasetrait)

This trait allows you to restore the database at the end of a scenario as it was before the scenario starts. It can be useful if a scenario alters the database, so the scenarii can be independent.

Of course, it can take a while with a big database.

For now, only MySQL is supported. It requires `mysqldump` to be installed to export the data, and [doctrine/doctrine-bundle](https://github.com/doctrine/DoctrineBundle) to re-import the dump.

Note that it requires `KernelDictionary` from [behat/symfony2-extension](https://github.com/Behat/Symfony2Extension).

```
// your feature context

namespace Tests\Behat\Context;

use Behat\MinkExtension\Context\MinkContext;
use Behat\Symfony2Extension\Context\KernelDictionary;
use Ekino\BehatHelpers\ReloadDatabaseTrait;

class MyFeatureContext extends MinkContext
{
    use KernelDictionary;
    use ReloadDatabaseTrait;
}
```

```
@behat_helpers_restore_db
Scenario: I can fill the step2
    Given I fill the second step
    Then I should be on "/step3"
```

### RouterAwareTrait

[](#routerawaretrait)

This helper uses the router from Symfony and so avoids hard-coded URL in your scenarii.

Note that it requires `KernelDictionary` from [behat/symfony2-extension](https://github.com/Behat/Symfony2Extension).

```
// your feature context

namespace Tests\Behat\Context;

use Behat\MinkExtension\Context\MinkContext;
use Behat\Symfony2Extension\Context\KernelDictionary;
use Ekino\BehatHelpers\RouterAwareTrait;

class MyFeatureContext extends MinkContext
{
    use KernelDictionary;
    use RouterAwareTrait;
}
```

```
Scenario: I can see "something" when I visit /foo
    Given I am on "my_route_id"
    Then I should see "something"
```

If your route requires some parameters, you can provide them by separating them to the route identifier with a `;`:

```
Scenario: I can see "something" when I visit /foo/1/2
    Given I am on "my_route_id;param1=1&param2=2"
    Then I should see "something"
```

### SonataAdminTrait

[](#sonataadmintrait)

This trait integrates [sonata-project/admin-bundle](https://github.com/sonata-project/SonataAdminBundle) with some basics like interaction with menu, navigation bar, poping, select2... You can combined it with the [ReloadCookiesTrait](#reloadcookiestrait) in order to login only once for instance, and with [RouterAwareTrait](#routerawaretrait) to use route ids.

Note that it requires `KernelDictionary` from [behat/symfony2-extension](https://github.com/Behat/Symfony2Extension).

```
// your feature context

namespace Tests\Behat\Context;

use Behat\MinkExtension\Context\MinkContext;
use Behat\Symfony2Extension\Context\KernelDictionary;
use Ekino\BehatHelpers\ReloadCookiesTrait;
use Ekino\BehatHelpers\RouterAwareTrait;
use Ekino\BehatHelpers\SonataAdminTrait;

class MyFeatureContext extends MinkContext
{
    use KernelDictionary;
    use ReloadCookiesTrait;
    use RouterAwareTrait;
    use SonataAdminTrait;

    /**
     * @When /^I login with username "(?P[^"]*)" and password "(?P[^"]*)"$/
     *
     * @param string $username
     * @param string $password
     */
    public function fillLoginForm($username, $password)
    {
        $this->doOnce(function () use ($username, $password) {
            $this->login($username, $password);
        });
    }
}
```

```
Scenario: I can login and then access to the admin dashboard
    Given I login with username "admin" and password "admin"
    Then I should be on "sonata_admin_dashboard"
    And I should see "Welcome to the admin dashboard"
```

StepRegexI open the menu "Foo"`/^I open the menu "([^"]*)"$/`I should see "Foo" action in navbar`/^I should see "([^"]*)" action in navbar$/`I should not see "Foo" action in navbar`/^I should not see "([^"]*)" action in navbar$/`I click on "Foo" action in navbar`/^I click on "([^"]*)" action in navbar$/`clicking on the "Foo" element should open a popin "Bar"`/^clicking on the "([^"]*)" element should open a popin "([^"]*)"$/`the popin "Foo" should be closed`/^the popin "([^"]*)" should be closed$/`the popin "Foo" should not be opened`/^the popin "([^"]*)" should not be opened$/`the popin "Foo" should be opened`/^the popin "([^"]*)" should be opened$/`I set the select2 field "Foo" to "Bar"`/^(?:|I )set the select2 field "(?P(?:[^"]|\\")*)" to "(?P(?:[^"]|\\")*)"$/`I set the select2 value "Foo" for "Bar"`/^(?:|I )set the select2 value "(?P(?:[^"]|\\")*)" for "(?P(?:[^"]|\\")*)"$/`### SonataPageAdminTrait

[](#sonatapageadmintrait)

This trait integrates [sonata-project/page-bundle](https://github.com/sonata-project/SonataPageBundle) with some basics like interaction with container, block... You can combined it with the [ReloadCookiesTrait](#reloadcookiestrait) and with [RouterAwareTrait](#routerawaretrait) to use route ids.

```
// your feature context

namespace Tests\Behat\Context;

use Behat\MinkExtension\Context\MinkContext;
use Behat\Symfony2Extension\Context\KernelDictionary;
use Ekino\BehatHelpers\SonataPageAdminTrait;

class MyFeatureContext extends MinkContext
{
    use KernelDictionary;
    use ReloadCookiesTrait;
    use RouterAwareTrait;
    use SonataPageAdminTrait;
}
```

```
Scenario: I can see "Simple text block" when I add a SimpleTextBlockService
Given     I login
Then      I am on "admin_app_sonata_page_compose;id=1"
And       I open the container by text "Content"
And       I add the block "Simple text" with the name "Foo"
And       I open the block "Foo"
And       The block "Foo" should be opened
And       I rename the block "Foo" with "Bar"
And       I submit the block "Foo"
And       The block "Bar" should be closed
And       I should see 1 blocks
And       I delete the block "Bar"
```

StepRegexI open the container by text "Content"`/^I open the container "([^"]*)"$/`I add the block "Simple text" with the name "Foo"`/^I add the block "([^"]*)" with the name "([^"]*)"$/`I go to the tab "English" of the block "Foo"`/^I go to the tab "([^"]*)" of the block "([^"]*)"$/`I should see 6 blocks`/^I should see (\d+) blocks$/`I open the block "Foo"`/^I open the block "([^"]*)"$/`I submit the block "Foo"`/^I submit the block "([^"]*)"$/`I delete the block "Foo"`/^I delete the block "([^"]*)"$/`I rename the block "Foo" with "Bar"`/^I rename the block "([^"]*)" with "([^"]*)"$/`The block "Foo" should be opened`/^The block "([^"]*)" should be opened$/`The block "Foo" should be closed`/^The block "([^"]*)" should be closed$/`

###  Health Score

34

↑

LowBetter than 79% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity27

Limited adoption so far

Community20

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 76.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~181 days

Total

5

Last Release

1672d ago

PHP version history (2 changes)v0.1.0PHP ^7.1

v0.3.0PHP ^7.2 || ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/3be320a12ddaa34aaf436af3d1e926bcf6215466ce25a7fcda33c959cce4a266?d=identicon)[ekino](/maintainers/ekino)

---

Top Contributors

[![mremi](https://avatars.githubusercontent.com/u/548536?v=4)](https://github.com/mremi "mremi (48 commits)")[![xXNoceboXx](https://avatars.githubusercontent.com/u/3227304?v=4)](https://github.com/xXNoceboXx "xXNoceboXx (5 commits)")[![Daric971](https://avatars.githubusercontent.com/u/24455611?v=4)](https://github.com/Daric971 "Daric971 (3 commits)")[![bdejacobet](https://avatars.githubusercontent.com/u/1875787?v=4)](https://github.com/bdejacobet "bdejacobet (2 commits)")[![dependabot-preview[bot]](https://avatars.githubusercontent.com/in/2141?v=4)](https://github.com/dependabot-preview[bot] "dependabot-preview[bot] (2 commits)")[![mazsudo](https://avatars.githubusercontent.com/u/2480227?v=4)](https://github.com/mazsudo "mazsudo (1 commits)")[![samnela](https://avatars.githubusercontent.com/u/1852108?v=4)](https://github.com/samnela "samnela (1 commits)")[![BitScout](https://avatars.githubusercontent.com/u/1257143?v=4)](https://github.com/BitScout "BitScout (1 commits)")

---

Tags

testingBDDBehat

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/ekino-behat-helpers/health.svg)

```
[![Health](https://phpackages.com/badges/ekino-behat-helpers/health.svg)](https://phpackages.com/packages/ekino-behat-helpers)
```

###  Alternatives

[tonicforhealth/behat-parallel-scenario

Behat parallel scenario

24354.0k](/packages/tonicforhealth-behat-parallel-scenario)[polishsymfonycommunity/symfony2-mocker-extension

Behat extension for mocking services defined in the Symfony2 dependency injection container.

26253.0k3](/packages/polishsymfonycommunity-symfony2-mocker-extension)[vipsoft/code-coverage-extension

Behat code coverage collector

2185.6k2](/packages/vipsoft-code-coverage-extension)[novaway/common-contexts

Novaway Behat common contexts

18186.9k3](/packages/novaway-common-contexts)[marcortola/behat-seo-contexts

Behat extension for testing some On-Page SEO factors: meta title/description, canonical, hreflang, meta robots, robots.txt, redirects, sitemap validation, HTML validation, performance...

13148.6k](/packages/marcortola-behat-seo-contexts)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
