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
96 changes: 88 additions & 8 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ jobs:
tests:
runs-on: ubuntu-latest
continue-on-error: false
name: "PHP ${{ matrix.php }}"
name: "Behat 3 (PHP ${{ matrix.php }})"

strategy:
fail-fast: false
matrix:
php:
- '7.4'
- '8.0'
- '8.1'
- '8.2'
- '8.3'
- '8.4'

steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
Expand All @@ -32,14 +32,17 @@ jobs:
tools: composer:v2

- name: Run Chrome Headless
run: google-chrome-stable --enable-automation --disable-background-networking --no-default-browser-check --no-first-run --disable-popup-blocking --disable-default-apps --allow-insecure-localhost --disable-translate --disable-extensions --no-sandbox --enable-features=Metal --headless --remote-debugging-port=9222 --window-size=2880,1800 --proxy-server='direct://' --proxy-bypass-list='*' http://127.0.0.1 > /dev/null 2>&1 &
run: google-chrome-stable --enable-automation --disable-background-networking --no-default-browser-check --no-first-run --disable-popup-blocking --disable-default-apps --allow-insecure-localhost --disable-translate --disable-extensions --no-sandbox --enable-features=Metal --headless=new --remote-debugging-port=9222 --window-size=2880,1800 --proxy-server='direct://' --proxy-bypass-list='*' http://127.0.0.1 > "${{ runner.temp }}/chrome.log" 2>&1 &

- name: Run web server
run: php -S 127.0.0.1:8080 -t test-application/public > "${{ runner.temp }}/server.log" 2>&1 &

- name: Get Composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"

- name: Cache Composer
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-php-${{ matrix.php }}-composer-${{ hashFiles('**/composer.json **/composer.lock') }}
Expand All @@ -52,5 +55,82 @@ jobs:
- name: Validate composer.json
run: composer validate --ansi --strict

- name: Wait for Chrome DevTools and web server
run: |
for i in $(seq 1 30); do
if curl -sf http://127.0.0.1:9222/json/version > /dev/null && curl -sf http://127.0.0.1:8080 > /dev/null; then
echo "Chrome DevTools and web server are up"; exit 0
fi
sleep 1
done
echo "Chrome DevTools or web server did not become ready"
cat "${{ runner.temp }}/chrome.log" || true
cat "${{ runner.temp }}/server.log" || true
exit 1

- name: Run Behat
run: vendor/bin/behat --colors --strict --no-interaction -vvv -f progress

tests-behat4:
runs-on: ubuntu-latest
continue-on-error: false
name: "Behat 4 (PHP ${{ matrix.php }})"

# friends-of-behat/mink-extension v3 (Behat 4) requires PHP ^8.3, so this leg runs on 8.3+.
# Behat 4 and mink-extension v3 are still in alpha, so the alpha line is opted into here (via the
# explicit @alpha require) rather than in composer.json, keeping the released constraints alias-free.
strategy:
fail-fast: false
matrix:
php:
- '8.3'
- '8.4'

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
coverage: none
ini-values: "memory_limit=-1"
php-version: ${{ matrix.php }}
tools: composer:v2

- name: Run Chrome Headless
run: google-chrome-stable --enable-automation --disable-background-networking --no-default-browser-check --no-first-run --disable-popup-blocking --disable-default-apps --allow-insecure-localhost --disable-translate --disable-extensions --no-sandbox --enable-features=Metal --headless=new --remote-debugging-port=9222 --window-size=2880,1800 --proxy-server='direct://' --proxy-bypass-list='*' http://127.0.0.1 > "${{ runner.temp }}/chrome.log" 2>&1 &

- name: Run web server
run: php -S 127.0.0.1:8080 -t test-application/public > "${{ runner.temp }}/server.log" 2>&1 &

- name: Get Composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"

- name: Cache Composer
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-php-${{ matrix.php }}-composer-behat4-${{ hashFiles('**/composer.json **/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-${{ matrix.php }}-composer-behat4-

- name: Install PHP dependencies (Behat 4)
run: composer require behat/behat:"^4.0@alpha" friends-of-behat/mink-extension:"^3.0@alpha" --with-all-dependencies --no-interaction

- name: Wait for Chrome DevTools and web server
run: |
for i in $(seq 1 30); do
if curl -sf http://127.0.0.1:9222/json/version > /dev/null && curl -sf http://127.0.0.1:8080 > /dev/null; then
echo "Chrome DevTools and web server are up"; exit 0
fi
sleep 1
done
echo "Chrome DevTools or web server did not become ready"
cat "${{ runner.temp }}/chrome.log" || true
cat "${{ runner.temp }}/server.log" || true
exit 1

- name: Run Behat
run: vendor/bin/behat --colors --strict --no-interaction -vvv -f progress
18 changes: 10 additions & 8 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,18 @@
}
],
"require": {
"php": ">=7.4",
"behat/behat": "^3.5",
"behat/mink-extension": "^2.3"
"php": ">=8.2",
"behat/behat": "^3.5 || ^4.0",
"friends-of-behat/mink-extension": "^2.3 || ^3.0"
},
"require-dev": {
"behat/mink-goutte-driver": "^1.2",
"behat/mink-selenium2-driver": "^1.4",
"dmore/behat-chrome-extension": "^1.3",
"dmore/chrome-mink-driver": "^2.7",
"symfony/process": "^4.4 || ^5.2"
"behat/mink-browserkit-driver": "^2.3",
"behat/mink-selenium2-driver": "^1.7",
"dmore/chrome-mink-driver": "^2.9",
"sylius-labs/behat-chrome-extension": "^1.5",
"symfony/browser-kit": "^6.4 || ^7.4 || ^8.0",
"symfony/http-client": "^6.4 || ^7.4 || ^8.0",
"symfony/process": "^6.4 || ^7.4 || ^8.0"
},
"extra": {
"branch-alias": {
Expand Down
52 changes: 28 additions & 24 deletions features/bootstrap/FeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

use Behat\Behat\Context\Context;
use Behat\Gherkin\Node\TableNode;
use Behat\Hook\BeforeScenario;
use Behat\Step\Given;
use Behat\Step\Then;
use Behat\Step\When;
use Symfony\Component\Process\PhpExecutableFinder;
use Symfony\Component\Process\Process;

Expand All @@ -18,9 +22,7 @@ final class FeatureContext implements Context
/** @var string */
private string $testApplicationDir;

/**
* @BeforeScenario
*/
#[BeforeScenario]
public function prepareProcess(): void
{
$phpFinder = new PhpExecutableFinder();
Expand All @@ -32,27 +34,21 @@ public function prepareProcess(): void
$this->testApplicationDir = __DIR__ . '/../../test-application';
}

/**
* @Given there is following Behat extension configuration:
*/
#[Given('there is following Behat extension configuration:')]
public function thereIsBehatExtensionConfiguration(TableNode $table): void
{
foreach ($table->getRowsHash() as $key => $value) {
$this->configuration['%' . $key . '%'] = $value;
}
}

/**
* @Given /configuration option "([^"]+?)" is set to "([^"]+?)"/
*/
#[Given('/configuration option "([^"]+?)" is set to "([^"]+?)"/')]
public function configurationOptionSet(string $key, string $value): void
{
$this->configuration['%' . $key . '%'] = $value;
}

/**
* @When /I run Behat with failing scenarios(?: using (.+?) profile)?/
*/
#[When('/I run Behat with failing scenarios(?: using (.+?) profile)?/')]
public function iRunBehat(?string $profile = null): void
{
$this->createBehatConfigurationFile();
Expand All @@ -62,9 +58,7 @@ public function iRunBehat(?string $profile = null): void
$this->deleteBehatConfigurationFile();
}

/**
* @Then there should be text log generated
*/
#[Then('there should be text log generated')]
public function thereShouldBeTextLogGenerated(): void
{
$logPattern = $this->testApplicationDir . '/' . $this->configuration['%directory%'] . '/*.html';
Expand All @@ -75,9 +69,7 @@ public function thereShouldBeTextLogGenerated(): void
}
}

/**
* @Then a screenshot should be made
*/
#[Then('a screenshot should be made')]
public function screenshotShouldBeMade(): void
{
$screenshotPattern = $this->testApplicationDir . '/' . $this->configuration['%directory%'] . '/*.png';
Expand All @@ -88,9 +80,7 @@ public function screenshotShouldBeMade(): void
}
}

/**
* @Then a screenshot should not be made
*/
#[Then('a screenshot should not be made')]
public function screenshotShouldNotBeMade(): void
{
$screenshotPattern = $this->testApplicationDir . '/' . $this->configuration['%directory%'] . '/*.png';
Expand All @@ -103,12 +93,14 @@ public function screenshotShouldNotBeMade(): void

private function createBehatConfigurationFile(): void
{
$configurationFile = $this->getConfigurationFileName();

$behatConfiguration = strtr(
file_get_contents($this->testApplicationDir . '/behat.yml.dist'),
file_get_contents($this->testApplicationDir . '/' . $configurationFile . '.dist'),
$this->configuration
);

file_put_contents($this->testApplicationDir . '/behat.yml', $behatConfiguration);
file_put_contents($this->testApplicationDir . '/' . $configurationFile, $behatConfiguration);
}

private function getExtraConfiguration(?string $profile): array
Expand Down Expand Up @@ -136,8 +128,20 @@ private function doRunBehat(array $extraConfiguration): void

private function deleteBehatConfigurationFile(): void
{
if (file_exists($behatFile = $this->testApplicationDir . '/behat.yml')) {
if (file_exists($behatFile = $this->testApplicationDir . '/' . $this->getConfigurationFileName())) {
unlink($behatFile);
}
}

/**
* Behat 4 dropped YAML configuration support and only auto-discovers PHP configuration files,
* so the templated config file has to match the installed Behat version. The `Behat\Config`
* builder exists in Behat 3.x too, so the major version is what decides here.
*/
private function getConfigurationFileName(): string
{
$behatVersion = (int) \Composer\InstalledVersions::getVersion('behat/behat');

return $behatVersion >= 4 ? 'behat.php' : 'behat.yml';
}
}
64 changes: 64 additions & 0 deletions test-application/behat.php.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

declare(strict_types=1);

use Behat\Config\Config;
use Behat\Config\Extension;
use Behat\Config\Filter\TagFilter;
use Behat\Config\GherkinOptions;
use Behat\Config\Profile;
use Behat\Config\Suite;
use Behat\MinkExtension\Context\MinkContext;
use Behat\MinkExtension\ServiceContainer\MinkExtension;
use DMore\ChromeExtension\Behat\ServiceContainer\ChromeExtension;
use FriendsOfBehat\MinkDebugExtension\ServiceContainer\MinkDebugExtension;

return (new Config())
->withProfile(
(new Profile('default'))
->withSuite(
(new Suite('default'))
->withContexts(MinkContext::class)
)
->withExtension(new Extension(MinkDebugExtension::class, [
'directory' => '%directory%',
'clean_start' => %clean_start%,
]))
->withExtension(new Extension(MinkExtension::class, [
'base_url' => 'http://127.0.0.1:8080',
'sessions' => [
'default' => [
'browserkit_http' => null,
],
],
]))
->withGherkinOptions(
(new GherkinOptions())->withFilter(new TagFilter('~@javascript'))
)
)
->withProfile(
(new Profile('javascript'))
->withExtension(new Extension(MinkDebugExtension::class, [
'directory' => '%directory%',
'screenshot' => %screenshot%,
'clean_start' => %clean_start%,
]))
->withExtension(new Extension(ChromeExtension::class, []))
->withExtension(new Extension(MinkExtension::class, [
'base_url' => 'http://127.0.0.1:8080',
'javascript_session' => 'chrome',
'sessions' => [
'chrome' => [
'chrome' => [
'api_url' => 'http://127.0.0.1:9222',
'validate_certificate' => false,
],
],
],
'show_auto' => false,
]))
->withGherkinOptions(
(new GherkinOptions())->withFilter(new TagFilter('@javascript'))
)
)
;
4 changes: 3 additions & 1 deletion test-application/behat.yml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ default:
clean_start: %clean_start%

Behat\MinkExtension:
base_url: 'http://127.0.0.1:8080'
sessions:
default:
goutte: ~
browserkit_http: ~

gherkin:
filters:
Expand All @@ -28,6 +29,7 @@ javascript:
DMore\ChromeExtension\Behat\ServiceContainer\ChromeExtension: ~

Behat\MinkExtension:
base_url: 'http://127.0.0.1:8080'
javascript_session: chrome
sessions:
chrome:
Expand Down
4 changes: 2 additions & 2 deletions test-application/features/test.feature
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ Feature: Testing MinkDebugExtension
I want to download a page and fail

Scenario: Downloading a page and failing
When I go to "https://sylius.com"
When I go to "/"
Then I select "Create failing test" from "Available steps"

@javascript
Scenario: Downloading a page and failing (Javascript session)
When I go to "https://sylius.com"
When I go to "/"
Then I select "Create failing test" from "Available steps"
11 changes: 11 additions & 0 deletions test-application/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>MinkDebugExtension test page</title>
</head>
<body>
<h1>MinkDebugExtension test page</h1>
<p>This page is served locally so the test suite does not depend on any external website.</p>
</body>
</html>
Loading