Steward is a set of libraries made to simplify writing and running robust functional system tests in PHPUnit using Selenium WebDriver.
To see how to use and extend Steward, have a look at our example project.
For the latest changes see the CHANGELOG.md file. We follow Semantic Versioning.
For most cases we recommend having functional tests in the same repository as your application but in a separate folder.
We suggest putting them in a selenium-tests/
directory.
In this directory, simply install Steward with the following command:
$ composer require lmc/steward
Note: you will need to have Composer installed to do this.
The following step only applies if you want to download and run Selenium Standalone Server with the test browser locally right on your computer. Another possibility is to start Selenium Server and test browser inside a Docker container.
You need to download Selenium server so it can execute commands in the specified browser.
In the root directory of your tests (e.g. selenium-tests/
) simply run:
$ ./vendor/bin/steward install
This will check for the latest version of Selenium Standalone Server and download it for you (the jar file will
be placed into the ./vendor/bin
directory).
You may want to run this command as part of your CI server build, then simply use the --no-interaction
option to
download Selenium without any interaction and print the absolute path to the jar file as the sole output.
If it is not already installed on your system, you will need to download Selenium driver for the browser(s) you want to use for the tests. See Selenium server & browser drivers in our wiki for more information.
To provide you with Steward functionality, your tests have to extend the Lmc\Steward\Test\AbstractTestCase
class.
You must also configure PSR-4 autoloading so that your tests could be found by
Steward. It is as easy as adding the following to your composer.json
file:
"autoload": {
"psr-4": {
"My\\": "tests/"
}
}
Don't forget to create the selenium-tests/tests/
directory and to run composer dump-autoload
afterward.
For the test itself, place it in the selenium-tests/tests/
directory:
<?php
// selenium-tests/tests/TitlePageTest.php
namespace My; // Note the "My" namespace maps to the "tests" folder, as defined in the autoload part of `composer.json`.
use Facebook\WebDriver\WebDriverBy;
use Lmc\Steward\Test\AbstractTestCase;
class TitlePageTest extends AbstractTestCase
{
public function testShouldContainSearchInput()
{
// Load the URL (will wait until page is loaded)
$this->wd->get('https://www.w3.org/'); // $this->wd holds instance of \RemoteWebDriver
// Do some assertion
$this->assertContains('W3C', $this->wd->getTitle());
// You can use $this->log(), $this->warn() or $this->debug() with sprintf-like syntax
$this->log('Current page "%s" has title "%s"', $this->wd->getCurrentURL(), $this->wd->getTitle());
// Make sure search input is present
$searchInput = $this->wd->findElement(WebDriverBy::cssSelector('#search-form input'));
// Or you can use syntax sugar provided by Steward (this is equivalent of previous line)
$searchInput = $this->findByCss('#search-form input');
// Assert title of the search input
$this->assertEquals('Search', $searchInput->getAttribute('title'));
}
}
Now you need to start Selenium server, which will listen for and execute commands sent from your tests.
$ java -jar ./vendor/bin/selenium-server-4.10.0.jar standalone # the version may differ
This will start a single Selenium Server instance (listening on port 4444) in standalone (alias "no-grid") mode (meaning the server will receive and execute the commands itself, without distributing to nodes).
Note: You may want to run Selenium Server in a grid mode. This has the hub receiving commands while multiple nodes execute them. See Selenium Grid documentation.
Now that Selenium Server is listening, let's launch your test! Use the run
command:
./vendor/bin/steward run staging firefox
In a few moments you should see a Firefox window appear, then the https://www.w3.org/ site (as defined in the example tests) should be loaded before the window instantly closes. See the output of the command to check the test result.
The run
command has two required arguments: the name of the environment and the browser:
There is also a bunch of useful options for the run
command:
--group
- only run specific group(s) of tests--exclude-group
- exclude some group(s) of tests (can be even combined with --group
)--server-url
- set different url of selenium server than the default (which is http://localhost:4444
)--xdebug
- start Xdebug debugger on your tests. Allows you to debug tests from your IDE (learn more about tests debugging in our Wiki)--capability
- directly pass any extra capability to the Selenium WebDriver server (see wiki for more information and examples)--parallel-limit
- limit number of testcases being executed in a parallel (default is 50)--help
- see all other options and default values-v
- to instantly output name of failed test(s)-vv
- also print progress information during run (which tests were started/finished etc); if any test fails, its output will by printed to the console-vvv
- output everything, including all output from the testsThe log is printed to the console where you run the run
command. This could be a bit confusing, especially if you run multiple tests in parallel.
As a solution, for each testcase there is a separate file in JUnit XML format, placed in logs/
directory. Screenshots and HTML snapshots are also saved into this directory (they are automatically generated on failed assertion or if a WebDriver command fails).
To see the current status of tests during (or after) test execution, open the logs/results.xml
file in your browser:
Similar output in the command line interface can be obtained using the ./vendor/bin/steward results
command (see below). You can also add -vvv
to see results of each individual test.
Steward provides a visual representation of the test execution timeline. When used with Selenium Server in "grid" mode you can see which Selenium node executed which testcase, identify possible bottlenecks and so on.
To generate the timeline, simply run the generate-timeline
command after your test build is finished:
./vendor/bin/steward generate-timeline
File timeline.html
will then be generated into the logs/
directory.
Steward is open source software licensed under the MIT license.