behat-panther-extension icon indicating copy to clipboard operation
behat-panther-extension copied to clipboard

Run your behat tests in a headless chrome/firefox - Symfony Panther extension for Behat

BehatPantherExtension

Latest Stable Version Latest Unstable Version Total Downloads Monhtly Downloads Daily Downloads Tests Scrutinizer Quality Score Code Coverage Software License PHP Version Require Open Issues Closed Issues Contributors Contributors Dependents

Symfony Panther extension for Behat

Install

composer require --dev robertfausk/behat-panther-extension

Usage example

  • Add Robertfausk\Behat\PantherExtension: ~ to your behat.yml.
  • Use panther session in Behat\MinkExtension.
  • The extension will use options of symfony/panther by default. Have a look at PantherTestCaseTrait::$defaultOptions for this.
  • Following are some examples with all sessions using mink-panther-driver:
    # in behat.yml
        extensions:
            Robertfausk\Behat\PantherExtension: ~ # no configuration here
            Behat\MinkExtension:
               javascript_session: javascript_chrome
               sessions:
                   default:
                       panther: ~
                   javascript:
                       panther:
                           options: ~
                   javascript_chrome:
                       panther:
                           options:
                               browser: 'chrome'
                               webServerDir: '%paths.base%/public' # your custom public dir
                   javascript_firefox:
                       panther:
                           options:
                               browser: 'firefox'
                   javascript_with_all_options:
                       panther:
                           options:
                               env:
                                   APP_ENV: 'dev'
                               hostname: '127.0.0.1'    
                           kernel_options: ~ # unused by behat-panther-extension cause it does not extend KernelTestCase
                           manager_options:
                               connection_timeout_in_ms: 5000
                               request_timeout_in_ms: 120000
    

Example on how to pass arguments to ChromeDriver binary

See also https://chromedriver.chromium.org/logging

# in behat.yml enable logging
    extensions:
        Robertfausk\Behat\PantherExtension: ~
        Behat\MinkExtension:
           javascript_session: javascript
           sessions:
               javascript:
                   panther:
                       manager_options:
                           chromedriver_arguments:
                               - --log-path=/var/www/html/chromedriver.log
                               - --verbose

Example on how to test for a downloaded file

# in behat.yml ensure that chrome saves files to the destination you want
    extensions:
        Robertfausk\Behat\PantherExtension: ~
        Behat\MinkExtension:
           javascript_session: javascript
           files_path: '%paths.base%/tests/files'
           sessions:
               javascript:
                   panther:
                       manager_options:
                           capabilities:
                                goog:chromeOptions:
                                    prefs:
                                        download.default_directory: '/var/www/html/tests/files/Downloads'
# acme_download.feature
Feature: Acme files can be downloaded

  Background:
    Given there is no file in download directory
    # additionally setup your database entries etc. if needed

  @javascript
  Scenario: As an user with role Admin i can download an existing acme file
    Given I am authenticated as "[email protected]"
    And I am on "/acme-file-list"
    Then I wait for "acme.pdf" to appear
    When I click on test element "button-acme-download"
    Then I can find file "acme.pdf" in download directory
<?php
#AcmeContext.php

use Assert\Assertion;
use Behat\Mink\Element\NodeElement;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;


/**
 * @When /^I click on test element "([^"]*)"$/
 *
 * @param string $locator
 */
public function iClickOnTestElement(string $locator): void
{
    $btn = $this->getTestElement($locator);
    $btn->click();
}

/**
 * @Given /^there is no file in download directory$/
 */
public function thereIsNoFileinDownloadDirectory(): void
{
    $finder = new Finder();
    $fs = new Filesystem();
    $fs->remove($finder->in($this->getDownloadDirectory())->files());
}

/**
 * @Then /^I can find file "([^"]*)" in download directory$/
 */
public function iCanFindFileInDownloadDirectory($filename)
{
    $fs = new Filesystem();
    $path = \sprintf('%s%s%s', $this->getDownloadDirectory(), DIRECTORY_SEPARATOR, $filename);
    $this->spin(
        static function () use ($fs, $path): void {
            $isFileExisting = $fs->exists($path);
            Assertion::true($isFileExisting);
        },
    );
    Assertion::true($fs->exists($path));
}

private function getDownloadDirectory(): string
{
    return \sprintf('%s%sDownloads', $this->getMinkParameter('files_path'), DIRECTORY_SEPARATOR);
}

private function getTestElement(string $dataTestLocator, int $tries = 25): NodeElement
{
    return $this->getNodeElement("[data-test='$dataTestLocator']", $tries);
}

private function spin(\Closure $closure, ?int $tries = 25): ?NodeElement
{
    for ($i = 0; $i <= $tries; $i++) {
        try {
            return $closure();
        } catch (\Throwable $e) {
            if ($i === $tries) {
                throw $e;
            }
        }

        \usleep(100000); // 100 milliseconds
    }
}

How to upgrade?

Have a look at CHANGELOG for detailed information.

How to contribute?

Start docker-compose with php version of your choice. At the moment the following php versions can be used with docker-compose: php7.2, php7.3, php7.4, php8.0, php8.1 and php8.2.

docker-compose up php8.2

Run phpunit tests

docker-compose run php8.2 vendor/bin/phpunit

Credits

Created by Robert Freigang robertfausk.

BehatPantherExtension is built on top of symfony/panther and robertfausk/mink-panther-driver. It is for usage with Behat and Mink.