Repository: Lakion/MinkDebugExtension
Branch: master
Commit: 270e5aa5aef5
Files: 14
Total size: 19.7 KB
Directory structure:
gitextract_rw74d7mo/
├── .github/
│ └── workflows/
│ └── build.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── UPGRADE.md
├── composer.json
├── features/
│ ├── bootstrap/
│ │ └── FeatureContext.php
│ └── mink_debug.feature
├── src/
│ ├── Listener/
│ │ └── FailedStepListener.php
│ └── ServiceContainer/
│ └── MinkDebugExtension.php
└── test-application/
├── behat.yml.dist
├── features/
│ └── test.feature
└── logs/
└── .gitkeep
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/build.yml
================================================
name: Build
on:
push:
pull_request:
types: [opened, synchronize, edited, reopened]
jobs:
tests:
runs-on: ubuntu-latest
continue-on-error: false
name: "PHP ${{ matrix.php }}"
strategy:
fail-fast: false
matrix:
php:
- '7.4'
- '8.0'
- '8.1'
steps:
- name: Checkout
uses: actions/checkout@v2
- 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 --remote-debugging-port=9222 --window-size=2880,1800 --proxy-server='direct://' --proxy-bypass-list='*' http://127.0.0.1 > /dev/null 2>&1 &
- name: Get Composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache Composer
uses: actions/cache@v2
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-php-${{ matrix.php }}-composer-${{ hashFiles('**/composer.json **/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-${{ matrix.php }}-composer-
- name: Install PHP dependencies
run: composer install --no-interaction
- name: Validate composer.json
run: composer validate --ansi --strict
- name: Run Behat
run: vendor/bin/behat --colors --strict --no-interaction -vvv -f progress
================================================
FILE: .gitignore
================================================
/vendor
/composer.lock
/behat.yml
/test-application/logs/*
!/test-application/logs/.gitkeep
================================================
FILE: CHANGELOG.md
================================================
# CHANGELOG
### v2.0.1
- [#35](https://github.com/FriendsOfBehat/MinkDebugExtension/issues/35) Ignore StreamReadException as well ([@pamil](https://github.com/pamil))
### v2.0.0
* Added support for PHP 8.0
* Allowed taking screenshots with more drivers than just Selenium2Driver
* Changed log files extension from `.log` to `.html`
* Removed supplementary `upload-textfiles`, `upload-screenshots`, `wait-for-port` binaries
* Renamed extension from `Lakion\Behat\MinkDebugExtension` to `FriendsOfBehat\MinkDebugExtension`
### v1.0.0
* Initial release.
================================================
FILE: LICENSE
================================================
Copyright (c) 2016-2020 Lakion
2020-2021 Kamil Kokot
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: README.md
================================================
MinkDebugExtension
==================
**MinkDebugExtension** is a Behat extension made for debugging and logging Mink related data after every failed step.
It is especially useful while running tests on continuous integration server like Travis.
While using appropriate driver, you can also save screenshots just after the failure.
Installation
------------
Assuming you already have Composer:
```bash
composer require friends-of-behat/mink-debug-extension
```
Then you only need to configure your Behat profile:
```yml
default:
extensions:
FriendsOfBehat\MinkDebugExtension:
directory: directory-where-to-save-logs
```
Configuration reference
-----------------------
Under `FriendsOfBehat\MinkDebugExtension` there are three options to be configured:
- `directory` (required to enable extension) - contains path to directory that will contain generated logs. Use the variable `%paths.base%` to refer to the directory where your `behat.yml` is
- `screenshot` (default `false`) - whether to save screenshots if using supporting driver
- `clean_start` (default `true`) - whether to clean your existing logs on each Behat execution
Testing
-------
In order to test the extensions run:
```bash
composer install
bin/behat --strict
```
Authors
-------
MinkDebugExtension was originally created by [Kamil Kokot](https://kamilkokot.com).
See the list of [contributors](https://github.com/FriendsOfBehat/MinkDebugExtension/contributors).
================================================
FILE: UPGRADE.md
================================================
# UPGRADE
## FROM `1.x` TO `2.x`
- Change required package from `lakion/mink-debug-extension` to `friends-of-behat/mink-debug-extension` in your `composer.json`
- Change extension name from `Lakion\Behat\MinkDebugExtension` to `FriendsOfBehat\MinkDebugExtension` in your `behat.yml`
- Make sure you're not using binaries provided by `1.x` version of this library
================================================
FILE: composer.json
================================================
{
"name": "friends-of-behat/mink-debug-extension",
"type": "behat-extension",
"description": "Debug extension for Behat",
"keywords": [
"debug",
"behat",
"mink",
"logging"
],
"homepage": "https://github.com/FriendsOfBehat/MinkDebugExtension",
"license": "MIT",
"authors": [
{
"name": "Kamil Kokot",
"email": "kamil@kokot.me",
"homepage": "https://kamilkokot.com"
}
],
"require": {
"php": ">=7.4",
"behat/behat": "^3.5",
"behat/mink-extension": "^2.3"
},
"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"
},
"extra": {
"branch-alias": {
"dev-master": "2.1-dev"
}
},
"autoload": {
"psr-4": {
"FriendsOfBehat\\MinkDebugExtension\\": "src/"
}
}
}
================================================
FILE: features/bootstrap/FeatureContext.php
================================================
<?php
declare(strict_types=1);
use Behat\Behat\Context\Context;
use Behat\Gherkin\Node\TableNode;
use Symfony\Component\Process\PhpExecutableFinder;
use Symfony\Component\Process\Process;
final class FeatureContext implements Context
{
/** @var string */
private string $phpBin;
/** @var array<string, string> */
private array $configuration = ['%clean_start%' => 'true'];
/** @var string */
private string $testApplicationDir;
/**
* @BeforeScenario
*/
public function prepareProcess(): void
{
$phpFinder = new PhpExecutableFinder();
if (false === $php = $phpFinder->find()) {
throw new \RuntimeException('Unable to find the PHP executable.');
}
$this->phpBin = $php;
$this->testApplicationDir = __DIR__ . '/../../test-application';
}
/**
* @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 "([^"]+?)"/
*/
public function configurationOptionSet(string $key, string $value): void
{
$this->configuration['%' . $key . '%'] = $value;
}
/**
* @When /I run Behat with failing scenarios(?: using (.+?) profile)?/
*/
public function iRunBehat(?string $profile = null): void
{
$this->createBehatConfigurationFile();
$this->doRunBehat($this->getExtraConfiguration($profile));
$this->deleteBehatConfigurationFile();
}
/**
* @Then there should be text log generated
*/
public function thereShouldBeTextLogGenerated(): void
{
$logPattern = $this->testApplicationDir . '/' . $this->configuration['%directory%'] . '/*.html';
$logsAmount = count(glob($logPattern));
if ($logsAmount !== 1) {
throw new \RuntimeException(sprintf('Expected 1 log file, found %d.', $logsAmount));
}
}
/**
* @Then a screenshot should be made
*/
public function screenshotShouldBeMade(): void
{
$screenshotPattern = $this->testApplicationDir . '/' . $this->configuration['%directory%'] . '/*.png';
$screenshotsAmount = count(glob($screenshotPattern));
if ($screenshotsAmount !== 1) {
throw new \RuntimeException(sprintf('Expected 1 screenshot, found %d.', $screenshotsAmount));
}
}
/**
* @Then a screenshot should not be made
*/
public function screenshotShouldNotBeMade(): void
{
$screenshotPattern = $this->testApplicationDir . '/' . $this->configuration['%directory%'] . '/*.png';
$screenshotsAmount = count(glob($screenshotPattern));
if ($screenshotsAmount !== 0) {
throw new \RuntimeException(sprintf('Expected no screenshots, found %d.', $screenshotsAmount));
}
}
private function createBehatConfigurationFile(): void
{
$behatConfiguration = strtr(
file_get_contents($this->testApplicationDir . '/behat.yml.dist'),
$this->configuration
);
file_put_contents($this->testApplicationDir . '/behat.yml', $behatConfiguration);
}
private function getExtraConfiguration(?string $profile): array
{
if (null !== $profile) {
return ['--profile=' . $profile];
}
return [];
}
private function doRunBehat(array $extraConfiguration): void
{
$arguments = array_merge(
[$this->phpBin, BEHAT_BIN_PATH, '--strict', '-vvv', '--no-interaction', '--lang=en'],
$extraConfiguration
);
$process = new Process($arguments, $this->testApplicationDir);
$process->start();
$process->wait();
printf("stdOut:\n %s\nstdErr:\n%s\n", $process->getOutput(), $process->getErrorOutput());
}
private function deleteBehatConfigurationFile(): void
{
if (file_exists($behatFile = $this->testApplicationDir . '/behat.yml')) {
unlink($behatFile);
}
}
}
================================================
FILE: features/mink_debug.feature
================================================
Feature: Logging debug data
In order to debug my Behat suites with ease
As a developer
I want to be able to access logs
Background:
Given there is following Behat extension configuration:
| directory | logs |
| screenshot | true |
Scenario:
When I run Behat with failing scenarios
Then there should be text log generated
Scenario:
When I run Behat with failing scenarios using javascript profile
Then there should be text log generated
And a screenshot should be made
Scenario:
Given configuration option "screenshot" is set to "false"
When I run Behat with failing scenarios using javascript profile
Then there should be text log generated
And a screenshot should not be made
================================================
FILE: src/Listener/FailedStepListener.php
================================================
<?php
declare(strict_types=1);
namespace FriendsOfBehat\MinkDebugExtension\Listener;
use Behat\Behat\EventDispatcher\Event\AfterStepTested;
use Behat\Behat\EventDispatcher\Event\StepTested;
use Behat\Mink\Exception\Exception as MinkException;
use Behat\Mink\Exception\UnsupportedDriverActionException;
use Behat\Mink\Mink;
use Behat\Mink\Session;
use Behat\Testwork\Tester\Result\TestResult;
use DMore\ChromeDriver\StreamReadException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use WebDriver\Exception as WebDriverException;
final class FailedStepListener implements EventSubscriberInterface
{
/**
* @var Mink
*/
private Mink $mink;
/**
* @var string
*/
private string $logDirectory;
/**
* @var bool
*/
private bool $screenshot;
/**
* Used to ensure that screenshot and log comes from the same failed step.
*
* @var string
*/
private string $currentDateAsString;
public function __construct(Mink $mink, string $logDirectory, bool $screenshot)
{
$this->mink = $mink;
$this->logDirectory = $logDirectory;
$this->screenshot = $screenshot;
}
/**
* @return array<string, array>
*/
public static function getSubscribedEvents(): array
{
return [
StepTested::AFTER => ['logFailedStepInformations', -10],
];
}
public function logFailedStepInformations(AfterStepTested $event): void
{
$testResult = $event->getTestResult();
if (!$testResult instanceof TestResult || TestResult::FAILED !== $testResult->getResultCode()) {
return;
}
if (!$this->hasEligibleMinkSession()) {
return;
}
$this->currentDateAsString = date('YmdHis');
$this->logPageContent();
if ($this->screenshot) {
$this->logScreenshot();
}
}
private function logPageContent(): void
{
$session = $this->getSession();
$log = sprintf('Current page: %d %s', $this->getStatusCode($session), $this->getCurrentUrl($session)) . "\n";
$log .= $this->getResponseHeadersLogMessage($session);
$log .= $this->getResponseContentLogMessage($session);
$this->saveLog($log, 'html');
}
private function logScreenshot(): void
{
$session = $this->getSession();
try {
$this->saveLog($session->getScreenshot(), 'png');
} catch (UnsupportedDriverActionException | WebDriverException $exception) {}
}
private function saveLog(string $content, string $type): void
{
$path = sprintf("%s/behat-%s.%s", $this->logDirectory, $this->currentDateAsString, $type);
if (file_put_contents($path, $content) === false) {
throw new \RuntimeException(sprintf('Failed while trying to write log in "%s".', $path));
}
}
private function getSession(?string $name = null): Session
{
return $this->mink->getSession($name);
}
private function hasEligibleMinkSession(?string $name = null): bool
{
$name = $name ?: $this->mink->getDefaultSessionName();
return $this->mink->hasSession($name) && $this->mink->isSessionStarted($name);
}
private function getStatusCode(Session $session): ?int
{
try {
return $session->getStatusCode();
} catch (MinkException | WebDriverException | StreamReadException $exception) {
return null;
}
}
private function getCurrentUrl(Session $session): ?string
{
try {
return $session->getCurrentUrl();
} catch (MinkException | WebDriverException | StreamReadException $exception) {
return null;
}
}
private function getResponseHeadersLogMessage(Session $session): ?string
{
try {
return 'Response headers:' . "\n" . print_r($session->getResponseHeaders(), true) . "\n";
} catch (MinkException | WebDriverException | StreamReadException $exception) {
return null;
}
}
private function getResponseContentLogMessage(Session $session): ?string
{
try {
return 'Response content:' . "\n" . $session->getPage()->getContent() . "\n";
} catch (MinkException | WebDriverException | StreamReadException $exception) {
return null;
}
}
}
================================================
FILE: src/ServiceContainer/MinkDebugExtension.php
================================================
<?php
declare(strict_types=1);
namespace FriendsOfBehat\MinkDebugExtension\ServiceContainer;
use Behat\Testwork\EventDispatcher\ServiceContainer\EventDispatcherExtension;
use Behat\Testwork\ServiceContainer\Extension as ExtensionInterface;
use Behat\Testwork\ServiceContainer\ExtensionManager;
use FriendsOfBehat\MinkDebugExtension\Listener\FailedStepListener;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
final class MinkDebugExtension implements ExtensionInterface
{
public function load(ContainerBuilder $container, array $config): void
{
$this->loadStepFailureListener($container);
$this->removeAllExistingLogsIfRequested($config);
$container->setParameter('mink_debug.directory', $config['directory']);
$container->setParameter('mink_debug.screenshot', $config['screenshot']);
$container->setParameter('mink_debug.clean_start', $config['clean_start']);
}
public function configure(ArrayNodeDefinition $builder): void
{
$builder
->children()
->scalarNode('directory')->isRequired()->end()
->booleanNode('screenshot')->defaultFalse()->end()
->booleanNode('clean_start')->defaultTrue()->end()
->end();
}
public function getConfigKey(): string
{
return 'fob_mink_debug';
}
public function initialize(ExtensionManager $extensionManager): void
{
}
public function process(ContainerBuilder $container): void
{
}
private function loadStepFailureListener(ContainerBuilder $container): void
{
$definition = new Definition(FailedStepListener::class, [
new Reference('mink'),
'%mink_debug.directory%',
'%mink_debug.screenshot%',
]);
$definition->addTag(EventDispatcherExtension::SUBSCRIBER_TAG, ['priority' => 0]);
$container->setDefinition('mink_debug.listener.step_failure', $definition);
}
/**
* @param array<string, mixed> $config
*/
private function removeAllExistingLogsIfRequested(array $config): void
{
if ($config['clean_start']) {
array_map('unlink', glob($config['directory'] . '/*.html'));
array_map('unlink', glob($config['directory'] . '/*.png'));
}
}
}
================================================
FILE: test-application/behat.yml.dist
================================================
default:
suites:
default:
contexts:
- Behat\MinkExtension\Context\MinkContext
extensions:
FriendsOfBehat\MinkDebugExtension:
directory: %directory%
clean_start: %clean_start%
Behat\MinkExtension:
sessions:
default:
goutte: ~
gherkin:
filters:
tags: "~@javascript"
javascript:
extensions:
FriendsOfBehat\MinkDebugExtension:
directory: %directory%
screenshot: %screenshot%
clean_start: %clean_start%
DMore\ChromeExtension\Behat\ServiceContainer\ChromeExtension: ~
Behat\MinkExtension:
javascript_session: chrome
sessions:
chrome:
chrome:
api_url: http://127.0.0.1:9222
validate_certificate: false
show_auto: false
gherkin:
filters:
tags: "@javascript"
================================================
FILE: test-application/features/test.feature
================================================
Feature: Testing MinkDebugExtension
In order to test MinkDebugExtension
As a behat
I want to download a page and fail
Scenario: Downloading a page and failing
When I go to "https://sylius.com"
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"
Then I select "Create failing test" from "Available steps"
================================================
FILE: test-application/logs/.gitkeep
================================================
gitextract_rw74d7mo/
├── .github/
│ └── workflows/
│ └── build.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── UPGRADE.md
├── composer.json
├── features/
│ ├── bootstrap/
│ │ └── FeatureContext.php
│ └── mink_debug.feature
├── src/
│ ├── Listener/
│ │ └── FailedStepListener.php
│ └── ServiceContainer/
│ └── MinkDebugExtension.php
└── test-application/
├── behat.yml.dist
├── features/
│ └── test.feature
└── logs/
└── .gitkeep
SYMBOL INDEX (33 symbols across 3 files)
FILE: features/bootstrap/FeatureContext.php
class FeatureContext (line 10) | final class FeatureContext implements Context
method prepareProcess (line 24) | public function prepareProcess(): void
method thereIsBehatExtensionConfiguration (line 38) | public function thereIsBehatExtensionConfiguration(TableNode $table): ...
method configurationOptionSet (line 48) | public function configurationOptionSet(string $key, string $value): void
method iRunBehat (line 56) | public function iRunBehat(?string $profile = null): void
method thereShouldBeTextLogGenerated (line 68) | public function thereShouldBeTextLogGenerated(): void
method screenshotShouldBeMade (line 81) | public function screenshotShouldBeMade(): void
method screenshotShouldNotBeMade (line 94) | public function screenshotShouldNotBeMade(): void
method createBehatConfigurationFile (line 104) | private function createBehatConfigurationFile(): void
method getExtraConfiguration (line 114) | private function getExtraConfiguration(?string $profile): array
method doRunBehat (line 123) | private function doRunBehat(array $extraConfiguration): void
method deleteBehatConfigurationFile (line 137) | private function deleteBehatConfigurationFile(): void
FILE: src/Listener/FailedStepListener.php
class FailedStepListener (line 18) | final class FailedStepListener implements EventSubscriberInterface
method __construct (line 42) | public function __construct(Mink $mink, string $logDirectory, bool $sc...
method getSubscribedEvents (line 52) | public static function getSubscribedEvents(): array
method logFailedStepInformations (line 59) | public function logFailedStepInformations(AfterStepTested $event): void
method logPageContent (line 80) | private function logPageContent(): void
method logScreenshot (line 91) | private function logScreenshot(): void
method saveLog (line 100) | private function saveLog(string $content, string $type): void
method getSession (line 109) | private function getSession(?string $name = null): Session
method hasEligibleMinkSession (line 114) | private function hasEligibleMinkSession(?string $name = null): bool
method getStatusCode (line 121) | private function getStatusCode(Session $session): ?int
method getCurrentUrl (line 130) | private function getCurrentUrl(Session $session): ?string
method getResponseHeadersLogMessage (line 139) | private function getResponseHeadersLogMessage(Session $session): ?string
method getResponseContentLogMessage (line 148) | private function getResponseContentLogMessage(Session $session): ?string
FILE: src/ServiceContainer/MinkDebugExtension.php
class MinkDebugExtension (line 16) | final class MinkDebugExtension implements ExtensionInterface
method load (line 18) | public function load(ContainerBuilder $container, array $config): void
method configure (line 29) | public function configure(ArrayNodeDefinition $builder): void
method getConfigKey (line 39) | public function getConfigKey(): string
method initialize (line 44) | public function initialize(ExtensionManager $extensionManager): void
method process (line 48) | public function process(ContainerBuilder $container): void
method loadStepFailureListener (line 52) | private function loadStepFailureListener(ContainerBuilder $container):...
method removeAllExistingLogsIfRequested (line 68) | private function removeAllExistingLogsIfRequested(array $config): void
Condensed preview — 14 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (22K chars).
[
{
"path": ".github/workflows/build.yml",
"chars": 2090,
"preview": "name: Build\n\non:\n push:\n pull_request:\n types: [opened, synchronize, edited, reopened]\n\njobs:\n tests:\n "
},
{
"path": ".gitignore",
"chars": 94,
"preview": "/vendor\n/composer.lock\n\n/behat.yml\n\n/test-application/logs/*\n!/test-application/logs/.gitkeep\n"
},
{
"path": "CHANGELOG.md",
"chars": 557,
"preview": "# CHANGELOG\n\n### v2.0.1\n\n- [#35](https://github.com/FriendsOfBehat/MinkDebugExtension/issues/35) Ignore StreamReadExcept"
},
{
"path": "LICENSE",
"chars": 1091,
"preview": "Copyright (c) 2016-2020 Lakion\n 2020-2021 Kamil Kokot\n\nPermission is hereby granted, free of charge, to any"
},
{
"path": "README.md",
"chars": 1476,
"preview": "MinkDebugExtension\n==================\n\n**MinkDebugExtension** is a Behat extension made for debugging and logging Mink r"
},
{
"path": "UPGRADE.md",
"chars": 365,
"preview": "# UPGRADE\n\n## FROM `1.x` TO `2.x`\n\n- Change required package from `lakion/mink-debug-extension` to `friends-of-behat/min"
},
{
"path": "composer.json",
"chars": 1067,
"preview": "{\n \"name\": \"friends-of-behat/mink-debug-extension\",\n \"type\": \"behat-extension\",\n \"description\": \"Debug extensio"
},
{
"path": "features/bootstrap/FeatureContext.php",
"chars": 4232,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nuse Behat\\Behat\\Context\\Context;\nuse Behat\\Gherkin\\Node\\TableNode;\nuse Symfony\\Componen"
},
{
"path": "features/mink_debug.feature",
"chars": 762,
"preview": "Feature: Logging debug data\n In order to debug my Behat suites with ease\n As a developer\n I want to be able to access"
},
{
"path": "src/Listener/FailedStepListener.php",
"chars": 4434,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace FriendsOfBehat\\MinkDebugExtension\\Listener;\n\nuse Behat\\Behat\\EventDispatcher\\"
},
{
"path": "src/ServiceContainer/MinkDebugExtension.php",
"chars": 2500,
"preview": "<?php\n\ndeclare(strict_types=1);\n\nnamespace FriendsOfBehat\\MinkDebugExtension\\ServiceContainer;\n\nuse Behat\\Testwork\\Event"
},
{
"path": "test-application/behat.yml.dist",
"chars": 1021,
"preview": "default:\n suites:\n default:\n contexts:\n - Behat\\MinkExtension\\Context\\MinkContext\n\n "
},
{
"path": "test-application/features/test.feature",
"chars": 451,
"preview": "Feature: Testing MinkDebugExtension\n In order to test MinkDebugExtension\n As a behat\n I want to download a page and f"
},
{
"path": "test-application/logs/.gitkeep",
"chars": 0,
"preview": ""
}
]
About this extraction
This page contains the full source code of the Lakion/MinkDebugExtension GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 14 files (19.7 KB), approximately 5.1k tokens, and a symbol index with 33 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.