Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Dependabot configuration.
#
# Please see the documentation for all configuration options:
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file

version: 2
updates:
# Maintain dependencies for GitHub Actions.
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
groups:
majors:
applies-to: version-updates
update-types:
- "major"
7 changes: 4 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ name: Build Docs

on:
push:
branches: [v3.0]
branches:
- "v*"
pull_request: ~

jobs:
Expand All @@ -14,7 +15,7 @@ jobs:
shell: bash

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7

- name: Run build command
run: docker compose run --rm read-the-docs-builder build
Expand All @@ -23,7 +24,7 @@ jobs:
run: cat _build/html/guides.html

- name: save site as artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: docs
path: _build/html
11 changes: 7 additions & 4 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ name: Check Docs

on:
push:
branches: [v3.0]
branches:
- "v*"
pull_request: null

jobs:
Expand All @@ -13,7 +14,7 @@ jobs:
run:
shell: bash
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- name: Install sphinx-lint
run: |
pip install --user sphinx-lint
Expand All @@ -26,6 +27,8 @@ jobs:
name: Typos
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- name: Search for misspellings
uses: crate-ci/typos@master
# Pinned to a specific version to avoid unexpected build failures on changes
# to the typos dictionary.
uses: crate-ci/typos@v1.50.2
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ can find build history for each version on RtD.
| Version | Status | Docs URL | Build dashboard |
|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------|---------------------------------------------------------------------------------------------------|
| v2.5 | [![Documentation Status](https://readthedocs.org/projects/behat/badge/?version=v2.5&style=for-the-badge)](https://docs.behat.org/en/latest/?badge=v2.5) | https://docs.behat.org/en/v2.5/ | [v2.5 build history](https://app.readthedocs.org/projects/behat/builds/?version__slug=v2.5) |
| v3.0 | [![Documentation Status](https://readthedocs.org/projects/behat/badge/?version=v3.0&style=for-the-badge)](https://docs.behat.org/en/latest/?badge=v3.0) | https://docs.behat.org/en/v3.0/ | [v3.0 build history](https://app.readthedocs.org/projects/behat/builds/?version__slug=v3.0) |
| latest* | [![Documentation Status](https://readthedocs.org/projects/behat/badge/?version=latest&style=for-the-badge)](https://docs.behat.org/en/latest/?badge=v3.0&style=for-the-badge) | https://docs.behat.org/en/latest/ | ["latest" build history](https://app.readthedocs.org/projects/behat/builds/?version__slug=latest) |
| v3.x | [![Documentation Status](https://readthedocs.org/projects/behat/badge/?version=v3.x&style=for-the-badge)](https://docs.behat.org/en/latest/?badge=v3.x) | https://docs.behat.org/en/v3.x/ | [v3.x build history](https://app.readthedocs.org/projects/behat/builds/?version__slug=v3.x) |
| v4.x | [![Documentation Status](https://readthedocs.org/projects/behat/badge/?version=v4.x&style=for-the-badge)](https://docs.behat.org/en/latest/?badge=v4.x) | https://docs.behat.org/en/v4.x/ | [v4.x build history](https://app.readthedocs.org/projects/behat/builds/?version__slug=v4.x) |
| latest* | [![Documentation Status](https://readthedocs.org/projects/behat/badge/?version=latest&style=for-the-badge)](https://docs.behat.org/en/latest/?badge=latest&style=for-the-badge) | https://docs.behat.org/en/latest/ | ["latest" build history](https://app.readthedocs.org/projects/behat/builds/?version__slug=latest) |

> \* the "latest" version is currently also based off the v3.0 branch, but is a separate build on RTD.
> \* the "latest" version is currently also based off the v4.x branch, but is a separate build on RTD.

## Project structure

Expand Down
14 changes: 7 additions & 7 deletions releases.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ can read more in :doc:`the Backward Compatibility documentation </releases/backw
Supported versions
------------------

======= ========== ========== ============ ====================================================================
Major Released Bugfix EOL Security EOL
======= ========== ========== ============ ====================================================================
`v3.x`_ April 2014 See below See below `Changelog <https://github.com/Behat/Behat/blob/3.x/CHANGELOG.md>`__
`v4.x`_ tbc Q3/26 See below See below `4.x Changelog`_ :doc:`Upgrading </releases/upgrading-to-4.0>`
======= ========== ========== ============ ====================================================================
======= =========== ============ ============ =======================================================================
Major Released Bugfix EOL Security EOL
======= =========== ============ ============ =======================================================================
`v3.x`_ April 2014 30 Sep 2027 30 Sep 2028 `Changelog <https://github.com/Behat/Behat/blob/3.x/CHANGELOG.md>`__
`v4.x`_ 28 Sep 2026 See below See below `4.x Changelog`_ :doc:`Upgrading </releases/upgrading-to-4.0>`
======= =========== ============ ============ =======================================================================

As a minimum, a major version series will receive:

Expand Down Expand Up @@ -56,7 +56,7 @@ By "current", we mean:
* Symfony versions that are listed as maintained or receiving security fixes on the `official Symfony releases page`_.

Note that Symfony 8 introduces breaking changes to interfaces that Behat cannot support without ourselves making
breaking changes. Therefore, Symfony 8 will only be supported from Behat 4.0 onwards.
breaking changes. Therefore, Symfony 8 is only supported from Behat 4.0 onwards.

Once a PHP or Symfony version reaches End of Life we will remove it from our composer.json and CI flows.

Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
alabaster==1.0.0
anyio==4.9.0
anyio==4.14.2
babel==2.16.0
certifi==2024.8.30
charset-normalizer==3.4.0
Expand All @@ -14,7 +14,7 @@ MarkupSafe==3.0.2
packaging==24.1
Pygments==2.20.0
requests==2.33.0
setuptools==78.1.1
setuptools==83.0.0
sniffio==1.3.1
snowballstemmer==2.2.0
Sphinx==8.1.3
Expand Down
65 changes: 27 additions & 38 deletions useful_resources.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,53 +23,38 @@ More information on integrating Behat with PHPStorm can be found in this
Assertion tools
---------------

A proper assertion tool is a library whose assertions throw exceptions on failure.
Behat does not officially recommend an assertion library - you can use any code that
throws an Exception on failure. You can use more than one library in parallel (or
no library, for simple assertions).

For example a list of the most known:
Some well-known options are:

- https://github.com/webmozarts/assert
- https://github.com/beberlei/assert
- https://github.com/zenstruck/assert
- `zenstruck/assert`_ - specifically designed for dependency-free test assertions,
which is reflected in the information it provides when assertions fail.
- `beberlei/assert`_ - primarily designed as a fast, lightweight input validation
library for business models and runtime code.
- `webmozarts/assert`_ - inspired by beberlei/assert and also designed for runtime
assertions, but with more control over failure messages.

.. admonition:: Caution with PHPUnit
:class: caution

If you are familiar with PHPUnit, you can use its assertion library
Behat docs used to suggest using PHPUnit's assertions. PHPUnit's author has
explicitly stated that using PHPUnit assertions outside of PHPUnit itself
is not supported or covered by any backwards compatibility promise.

.. code-block:: bash
We **strongly recommend** that you use a different assertion tool in new
projects.

$ php composer.phar require --dev phpunit/phpunit
If you have PHPUnit assertions in an existing project, we recommend
planning to migrate these. In the meantime, `behat/phpunit-assertions-extension`_
provides the required bootstrapping on PHPUnit >= 11.3.0, and renders the
details of failing assertions in your Behat output.

and then by simply using assertions in your steps:

.. code-block:: php

\PHPUnit\Framework\Assert::assertCount(
intval($count),
$this->basket
);

**WARNING: using PHPUnit for assertions no longer works with PHP 11.3.0 and later out-of-the-box**.

This is due to a change in how PHPUnit's internal components are initialized. The recommended workaround
to use the PHPUnit assertions is to bootstrap PHPUnit during Behat execution from a ``BeforeSuite`` hook:

.. code-block:: php

use Behat\Hook\BeforeSuite;

class FeatureContext {

#[BeforeSuite]
public static function initPhpunit() {
(new \PHPUnit\TextUI\Configuration\Builder())->build([]);
}
}

If you have multiple suites, you may want to use a static variable in the hook to ensure the initialization only
runs once.

Learn more at https://github.com/Behat/Behat/issues/1618.
Behat 3.x has partial support for older PHPUnit versions - we recommend
installing the extension for better compatibility. Behat 4.x does not
have any built-in PHPUnit support so you will need to add the extension
before upgrading.


Behat cheat sheet
Expand All @@ -79,5 +64,9 @@ An interesting `Behat and Mink cheat sheet`_ developed by `Jean-François Lépin

.. _`most extensions can be found on GitHub`: https://github.com/search?o=desc&q=behat+extension+in%3Aname%2Cdescription&ref=searchresults&s=stars&type=Repositories&utf8=%E2%9C%93
.. _`blog post`: http://blog.jetbrains.com/phpstorm/2014/07/using-behat-in-phpstorm/
.. _`webmozarts/assert`: https://github.com/webmozarts/assert
.. _`beberlei/assert`: https://github.com/beberlei/assert
.. _`zenstruck/assert`: https://github.com/zenstruck/assert
.. _`behat/phpunit-assertions-extension`: https://github.com/behat/PHPUnitAssertionsExtension
.. _`Behat and Mink cheat sheet`: http://blog.lepine.pro/images/2012-04-behat-cheat-sheet1.pdf
.. _`Jean-François Lépine`: http://blog.lepine.pro
30 changes: 25 additions & 5 deletions user_guide/gherkin/parser_mode.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ To resolve this, we have added a ``GherkinCompatibilityMode`` setting to the par
has two possible options:

* ``GherkinCompatibilityMode::LEGACY`` - match our previous behaviour. This is the default in Behat 3.x.
* ``GherkinCompatibilityMode::GHERKIN_32`` - match the official parsers. This will become the default in Behat 4.0.

.. caution::
``GherkinCompatibilityMode::GHERKIN_32`` is currently considered experimental. We expect that
there will be more changes to how the parser behaves in this mode before we mark it as stable.
but is not recommended for new projects.
* ``GherkinCompatibilityMode::GHERKIN_32`` - match the official parsers version >= 32.0 < 42.0
* ``GherkinCompatibilityMode::GHERKIN_42`` - match the official parsers version >= 42.0. This is
the default in Behat 4.x.

Configuring the parser mode
---------------------------
Expand Down Expand Up @@ -159,6 +158,27 @@ In ``GHERKIN_32`` mode, if one of the elements listed above has multi-line text,
left padding / indentation as the feature file. In legacy mode, we attempted to left-trim all lines to match the
indentation of the keyword.

Rules
~~~~~

The Gherkin ``Rule`` keyword is not supported in ``LEGACY`` mode. Rule nodes will either be parsed as part of the
feature description, or cause a ParserException, depending on the nodes that come before them in the file.

``GHERKIN_32`` mode introduces backwards-compatible support for Rules. Scenarios within Rules will be parsed, filtered,
and executed as expected with any caller. However, callers that have not been updated to support this feature will
receive a modified node tree with all Rule details stripped out. This will behave as though any Scenarios were a direct
child of the Feature - with any Rule Background steps repeated as the first steps of each Scenario.

Steps with a DataTable **and** a DocString
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Historically, a step could only accept **either** a DataTable **or** a DocString. ``StepNode::getArguments()`` has
always been typed as returning an array but in practice could only return 0 or 1 elements. Therefore in ``LEGACY``
and ``GHERKIN_32`` mode, we throw a ParserException if a step has more than one multiline argument.

In ``GHERKIN_42`` mode, a step with a DataTable **and** a DocString is valid. ``StepNode::getArguments()`` will
return both nodes, in the order they appeared in the feature file. It is still not valid to have more than one
argument of any given type (e.g. two tables) - in this case we still throw a ParserException.

.. _`behat/gherkin`: http://martinfowler.com/bliki/BusinessReadableDSL.html
.. _`the official parsers provided by the Cucumber project`: https://github.com/cucumber/gherkin
41 changes: 29 additions & 12 deletions user_guide/writing_scenarios.rst
Original file line number Diff line number Diff line change
Expand Up @@ -321,22 +321,35 @@ usually as input to a ``Given`` or as expected output from a ``Then``:

.. code-block:: php

use Behat\Gherkin\Node\TableNode;
use Behat\Step\DataTable;
use Behat\Step\Given;

// ...

#[Given('the following people exist:')]
public function thePeopleExist(TableNode $table)
public function thePeopleExist(DataTable $table)
{
foreach ($table as $row) {
foreach ($table->asMaps() as $row) {
// $row['name'], $row['email'], $row['phone']
}
}

A table is injected into a definition as a ``TableNode`` object, from
which you can get hash by columns (``TableNode::getHash()`` method) or by
rows (``TableNode::getRowsHash()``).
Type the parameter as ``DataTable`` and Behat passes the table as such.
It reads the table in whichever shape the step needs:

* ``asMaps()`` uses the first row as keys, giving one associative array
per following row, which is what the example above iterates over;
* ``asLists()`` returns every row as a plain list of cells, header row
included, for a table with no header;
* ``asMap()`` turns a two-column table into a single associative array,
which suits a table of settings or of expected values;
* ``cell()``, ``row()``, ``column()``, ``height()``, ``width()``,
``isEmpty()`` and ``transpose()`` cover the rest.

``DataTable`` was added in Behat 3.33. Typing the parameter as
``Behat\Gherkin\Node\TableNode`` still works and is not deprecated, but
``DataTable`` keeps your definitions decoupled from the Gherkin syntax
tree.

Pystrings
^^^^^^^^^
Expand Down Expand Up @@ -371,20 +384,24 @@ three double-quote marks (``"""``), placed on their own line:

.. code-block:: php

use Behat\Gherkin\Node\PyStringNode;
use Behat\Step\DocString;
use Behat\Step\Given;

// ...

#[Given('a blog post named :title with:')]
public function blogPost($title, PyStringNode $markdown)
public function blogPost($title, DocString $markdown)
{
$this->createPost($title, $markdown->getRaw());
$this->createPost($title, $markdown->getContent());
}

PyStrings are stored in a ``PyStringNode`` instance, which you can simply
convert to a string with ``(string) $pystring`` or ``$pystring->getRaw()``
as in the example above.
Type the parameter as ``DocString`` to receive the text. Read it with
``getContent()``, or cast it with ``(string) $markdown``.

``DocString`` was added in Behat 3.33. Typing the parameter as
``Behat\Gherkin\Node\PyStringNode`` still works and is not deprecated,
but ``DocString`` keeps your definitions decoupled from the Gherkin syntax
tree.

.. note::

Expand Down
Loading