Skip to content

Instantly share code, notes, and snippets.

@netraagal
Last active May 2, 2018 09:13
Show Gist options
  • Save netraagal/cdc391c18b190641134fe1cdb359d300 to your computer and use it in GitHub Desktop.
Save netraagal/cdc391c18b190641134fe1cdb359d300 to your computer and use it in GitHub Desktop.
Symfony, Behat, add a Command Line

Add a Command Line to your Behat Project

As said, I want to add a command to my Behat Project.

I will add a '--list-scenarios' option to my behat command

Not so good

The files I add or modify are in my vendor project, so I'm actually in search of how to not use the vendor directory.

Some evol

Actually, the output is not really beautifull and can easily be modified.

There will surely be some modifications as I want the output to be written in a file.

Credits

Thanks @spolischook and his project.

<?php
// project\vendor\behat\behat\src\Behat\Behat\Definition\Cli\AvailableScenariosController.php
namespace Behat\Behat\Definition\Cli;
use Behat\Gherkin\Node\FeatureNode;
use Behat\Testwork\Cli\Controller;
use Behat\Testwork\Specification\SpecificationFinder;
use Behat\Testwork\Suite\SuiteRepository;
use Symfony\Component\Console\Command\Command as SymfonyCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Behat\Behat\Definition\DefinitionWriter;
/**
* this class manage what does the command
* @author netraagal
*/
class AvailableScenariosController implements Controller
{
/**
* @var SuiteRepository
*/
private $suiteRepository;
/**
* @var DefinitionWriter
*/
private $writer;
/**
* @var SpecificationFinder
*/
private $specificationFinder;
/**
* @param SuiteRepository $suiteRepository
* @param DefinitionWriter $writer
* @param SpecificationFinder $specificationFinder
*/
public function __construct(
SuiteRepository $suiteRepository,
DefinitionWriter $writer,
SpecificationFinder $specificationFinder)
{
$this->suiteRepository = $suiteRepository;
$this->writer = $writer;
$this->specificationFinder = $specificationFinder;
}
/**
* @param SymfonyCommand $command
* return AvailableScenariosController
*/
public function configure(SymfonyCommand $command): self
{
$command
->addOption(
'--list-scenarios',
null,
InputOption::VALUE_NONE,
'Output registered feature and scenario definitions'
);
return $this;
}
/**
* @param InputInterface $input
* @param OutputInterface $output
* @return bool
*/
public function execute(InputInterface $input, OutputInterface $output): bool
{
if (!$input->getOption('list-scenarios')) {
return false;
}
foreach ($this->suiteRepository->getSuites() as $suite) {
$iterators = $this->specificationFinder->findSuitesSpecifications([$suite]);
foreach ($iterators as $iterator) {
foreach ($iterator as $item) {
$output->writeln($item->getDescription());
$this->printFeatures($item->getScenarios(), $output);
}
}
}
return true;
}
/**
* @param array $feature
* @param OutputInterface $output
* @return AvailableScenariosController
*/
private function printFeatures(array $feature, OutputInterface $output): self
{
foreach($feature as $scenario) {
$output->writeln($scenario->getTitle());
}
return $this;
}
}
<?php
// project\vendor\behat\behat\src\Behat\Behat\Definition\ServiceContainer\DefinitionExtension.php
/*
* This file already exists in the behat project.
* I have just re-writed the functions which are modified or added
*
* This file is part of the Behat.
* (c) Konstantin Kudryashov <[email protected]>
*/
namespace Behat\Behat\Definition\ServiceContainer;
use Behat\Testwork\Specification\ServiceContainer\SpecificationExtension;
/**
* Extends Behat with definition services.
*
* @author Konstantin Kudryashov <[email protected]>
*/
final class DefinitionExtension implements Extension
{
/**
* {@inheritdoc}
*/
public function load(ContainerBuilder $container, array $config)
{
$this->loadFinder($container);
$this->loadRepository($container);
$this->loadWriter($container);
$this->loadPatternTransformer($container);
$this->loadDefinitionTranslator($container);
$this->loadDefaultSearchEngines($container);
$this->loadDefaultPatternPolicies($container);
$this->loadAnnotationReader($container);
$this->loadDefinitionPrinters($container);
$this->loadController($container);
//line to add
$this->loadPersonalizedController($container);
}
/**
* initialize the new added command to the project
*
* @param ContainerBuilder $container
*/
private function loadPersonalizedController(ContainerBuilder $container)
{
$definition = new Definition('Behat\Behat\Definition\Cli\AvailableScenariosController', array(
new Reference(SuiteExtension::REGISTRY_ID),
new Reference(self::WRITER_ID),
new Reference(SpecificationExtension::FINDER_ID)
));
$definition->addTag(CliExtension::CONTROLLER_TAG, array('priority' => 500));
$container->setDefinition(CliExtension::CONTROLLER_TAG . '.list_scenarios', $definition);
}
}
@jakzal
Copy link

jakzal commented May 2, 2018

The files I add or modify are in my vendor project, so I'm actually in search of how to not use the vendor directory.

The solution to this is to create your own extension.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment