Renamed the extension class to follow the Behat shortcut convention
This commit is contained in:
305
src/Behat/MinkExtension/ServiceContainer/MinkExtension.php
Normal file
305
src/Behat/MinkExtension/ServiceContainer/MinkExtension.php
Normal file
@@ -0,0 +1,305 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Behat MinkExtension.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\MinkExtension\ServiceContainer;
|
||||
|
||||
use Behat\Behat\Context\ServiceContainer\ContextExtension;
|
||||
use Behat\MinkExtension\ServiceContainer\Driver\BrowserStackFactory;
|
||||
use Behat\MinkExtension\ServiceContainer\Driver\DriverFactory;
|
||||
use Behat\MinkExtension\ServiceContainer\Driver\GoutteFactory;
|
||||
use Behat\MinkExtension\ServiceContainer\Driver\SahiFactory;
|
||||
use Behat\MinkExtension\ServiceContainer\Driver\SauceLabsFactory;
|
||||
use Behat\MinkExtension\ServiceContainer\Driver\Selenium2Factory;
|
||||
use Behat\MinkExtension\ServiceContainer\Driver\SeleniumFactory;
|
||||
use Behat\MinkExtension\ServiceContainer\Driver\ZombieFactory;
|
||||
use Behat\Testwork\EventDispatcher\ServiceContainer\EventDispatcherExtension;
|
||||
use Behat\Testwork\ServiceContainer\Exception\ProcessingException;
|
||||
use Behat\Testwork\ServiceContainer\Extension as ExtensionInterface;
|
||||
use Behat\Testwork\ServiceContainer\ExtensionManager;
|
||||
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
|
||||
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Mink extension for Behat class.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*/
|
||||
class MinkExtension implements ExtensionInterface
|
||||
{
|
||||
const MINK_ID = 'mink';
|
||||
const SELECTORS_HANDLER_ID = 'mink.selectors_handler';
|
||||
|
||||
const SELECTOR_TAG = 'mink.selector';
|
||||
|
||||
/**
|
||||
* @var DriverFactory[]
|
||||
*/
|
||||
private $driverFactories = array();
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->registerDriverFactory(new GoutteFactory());
|
||||
$this->registerDriverFactory(new SahiFactory());
|
||||
$this->registerDriverFactory(new SeleniumFactory());
|
||||
$this->registerDriverFactory(new Selenium2Factory());
|
||||
$this->registerDriverFactory(new SauceLabsFactory());
|
||||
$this->registerDriverFactory(new BrowserStackFactory());
|
||||
$this->registerDriverFactory(new ZombieFactory());
|
||||
}
|
||||
|
||||
public function registerDriverFactory(DriverFactory $driverFactory)
|
||||
{
|
||||
$this->driverFactories[$driverFactory->getDriverName()] = $driverFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function load(ContainerBuilder $container, array $config)
|
||||
{
|
||||
if (isset($config['mink_loader'])) {
|
||||
$basePath = $container->getParameter('paths.base');
|
||||
|
||||
if (file_exists($basePath.DIRECTORY_SEPARATOR.$config['mink_loader'])) {
|
||||
require($basePath.DIRECTORY_SEPARATOR.$config['mink_loader']);
|
||||
} else {
|
||||
require($config['mink_loader']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->loadMink($container);
|
||||
$this->loadContextInitializer($container);
|
||||
$this->loadSelectorsHandler($container);
|
||||
$this->loadSessions($container, $config);
|
||||
$this->loadSessionsListener($container);
|
||||
|
||||
if ($config['show_auto']) {
|
||||
$this->loadFailureShowListener($container);
|
||||
}
|
||||
|
||||
unset($config['sessions']);
|
||||
|
||||
$container->setParameter('mink.parameters', $config);
|
||||
$container->setParameter('mink.base_url', $config['base_url']);
|
||||
$container->setParameter('mink.browser_name', $config['browser_name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function configure(ArrayNodeDefinition $builder)
|
||||
{
|
||||
// Rewrite keys to define a shortcut way without allowing conflicts with real keys
|
||||
$renamedKeys = array_diff(
|
||||
array_keys($this->driverFactories),
|
||||
array('mink_loader', 'base_url', 'files_path', 'show_auto', 'show_cmd', 'show_tmp_dir', 'default_session', 'javascript_session', 'browser_name', 'sessions')
|
||||
);
|
||||
|
||||
$builder
|
||||
->beforeNormalization()
|
||||
->always()
|
||||
->then(function ($v) use ($renamedKeys) {
|
||||
foreach ($renamedKeys as $driverType) {
|
||||
if (!array_key_exists($driverType, $v) || isset($v['sessions'][$driverType])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$v['sessions'][$driverType][$driverType] = $v[$driverType];
|
||||
unset($v[$driverType]);
|
||||
}
|
||||
|
||||
return $v;
|
||||
})
|
||||
->end()
|
||||
->addDefaultsIfNotSet()
|
||||
->children()
|
||||
->scalarNode('mink_loader')->defaultNull()->end()
|
||||
->scalarNode('base_url')->defaultNull()->end()
|
||||
->scalarNode('files_path')->defaultNull()->end()
|
||||
->booleanNode('show_auto')->defaultFalse()->end()
|
||||
->scalarNode('show_cmd')->defaultNull()->end()
|
||||
->scalarNode('show_tmp_dir')->defaultValue(sys_get_temp_dir())->end()
|
||||
->scalarNode('default_session')->defaultNull()->info('Defaults to the first non-javascript session if any, or the first session otherwise')->end()
|
||||
->scalarNode('javascript_session')->defaultNull()->info('Defaults to the first javascript session if any')->end()
|
||||
->scalarNode('browser_name')->defaultValue('firefox')->end()
|
||||
->end()
|
||||
->end();
|
||||
|
||||
/** @var ArrayNodeDefinition $sessionsBuilder */
|
||||
$sessionsBuilder = $builder
|
||||
->children()
|
||||
->arrayNode('sessions')
|
||||
->isRequired()
|
||||
->requiresAtLeastOneElement()
|
||||
->useAttributeAsKey('name')
|
||||
->prototype('array')
|
||||
;
|
||||
|
||||
foreach ($this->driverFactories as $factory) {
|
||||
$factoryNode = $sessionsBuilder->children()->arrayNode($factory->getDriverName())->canBeUnset();
|
||||
|
||||
$factory->configure($factoryNode);
|
||||
}
|
||||
|
||||
$sessionsBuilder
|
||||
->validate()
|
||||
->ifTrue(function ($v) {return count($v) > 1;})
|
||||
->thenInvalid('You cannot set multiple driver types for the same session')
|
||||
->end()
|
||||
->validate()
|
||||
->ifTrue(function ($v) {return count($v) === 0;})
|
||||
->thenInvalid('You must set a driver definition for the session.')
|
||||
->end()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getConfigKey()
|
||||
{
|
||||
return 'mink';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function initialize(ExtensionManager $extensionManager)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->processSelectors($container);
|
||||
}
|
||||
|
||||
private function loadMink(ContainerBuilder $container)
|
||||
{
|
||||
$container->setDefinition(self::MINK_ID, new Definition('Behat\Mink\Mink'));
|
||||
}
|
||||
|
||||
private function loadContextInitializer(ContainerBuilder $container)
|
||||
{
|
||||
$definition = new Definition('Behat\MinkExtension\Context\Initializer\MinkAwareInitializer', array(
|
||||
new Reference(self::MINK_ID),
|
||||
'%mink.parameters%',
|
||||
));
|
||||
$definition->addTag(ContextExtension::INITIALIZER_TAG, array('priority' => 0));
|
||||
$container->setDefinition('mink.context_initializer', $definition);
|
||||
}
|
||||
|
||||
private function loadSelectorsHandler(ContainerBuilder $container)
|
||||
{
|
||||
$container->setDefinition(self::SELECTORS_HANDLER_ID, new Definition('Behat\Mink\Selector\SelectorsHandler'));
|
||||
|
||||
$cssSelectorDefinition = new Definition('Behat\Mink\Selector\CssSelector');
|
||||
$cssSelectorDefinition->addTag(self::SELECTOR_TAG, array('alias' => 'css'));
|
||||
$container->setDefinition(self::SELECTOR_TAG . '.css', $cssSelectorDefinition);
|
||||
|
||||
$namedSelectorDefinition = new Definition('Behat\Mink\Selector\NamedSelector');
|
||||
$namedSelectorDefinition->addTag(self::SELECTOR_TAG, array('alias' => 'named'));
|
||||
$container->setDefinition(self::SELECTOR_TAG . '.named', $namedSelectorDefinition);
|
||||
}
|
||||
|
||||
private function loadSessions(ContainerBuilder $container, array $config)
|
||||
{
|
||||
$defaultSession = $config['default_session'];
|
||||
$javascriptSession = $config['javascript_session'];
|
||||
$javascriptSessions = $nonJavascriptSessions = array();
|
||||
|
||||
$minkDefinition = $container->getDefinition(self::MINK_ID);
|
||||
|
||||
foreach ($config['sessions'] as $name => $session) {
|
||||
$driver = key($session);
|
||||
$factory = $this->driverFactories[$driver];
|
||||
|
||||
$definition = new Definition('Behat\Mink\Session', array(
|
||||
$factory->buildDriver($session[$driver]),
|
||||
new Reference(self::SELECTORS_HANDLER_ID),
|
||||
));
|
||||
$minkDefinition->addMethodCall('registerSession', array($name, $definition));
|
||||
|
||||
if ($factory->supportsJavascript()) {
|
||||
$javascriptSessions[] = $name;
|
||||
} else {
|
||||
$nonJavascriptSessions[] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
if (null === $javascriptSession && !empty($javascriptSessions)) {
|
||||
$javascriptSession = $javascriptSessions[0];
|
||||
} elseif (null !== $javascriptSession && !in_array($javascriptSession, $javascriptSessions)) {
|
||||
throw new InvalidConfigurationException(sprintf(
|
||||
'The javascript session must be one of the enabled javascript sessions (%s), but got %s',
|
||||
json_encode($javascriptSessions),
|
||||
$javascriptSession
|
||||
));
|
||||
}
|
||||
|
||||
if (null === $defaultSession) {
|
||||
$defaultSession = !empty($nonJavascriptSessions) ? $nonJavascriptSessions[0] : $javascriptSessions[0];
|
||||
} elseif (!isset($config['sessions'][$defaultSession])) {
|
||||
throw new InvalidConfigurationException(sprintf('The default session must be one of the enabled sessions, but got %s', $defaultSession));
|
||||
}
|
||||
|
||||
$container->setParameter('mink.default_session', $defaultSession);
|
||||
$container->setParameter('mink.javascript_session', $javascriptSession);
|
||||
$container->setParameter('mink.available_javascript_sessions', $javascriptSessions);
|
||||
}
|
||||
|
||||
private function loadSessionsListener(ContainerBuilder $container)
|
||||
{
|
||||
$definition = new Definition('Behat\MinkExtension\Listener\SessionsListener', array(
|
||||
new Reference(self::MINK_ID),
|
||||
'%mink.default_session%',
|
||||
'%mink.javascript_session%',
|
||||
'%mink.available_javascript_sessions%',
|
||||
));
|
||||
$definition->addTag(EventDispatcherExtension::SUBSCRIBER_TAG, array('priority' => 0));
|
||||
$container->setDefinition('mink.listener.sessions', $definition);
|
||||
}
|
||||
|
||||
private function loadFailureShowListener(ContainerBuilder $container)
|
||||
{
|
||||
$definition = new Definition('Behat\MinkExtension\Listener\FailureShowListener', array(
|
||||
new Reference(self::MINK_ID),
|
||||
'%mink.parameters%',
|
||||
));
|
||||
$definition->addTag(EventDispatcherExtension::SUBSCRIBER_TAG, array('priority' => 0));
|
||||
$container->setDefinition('mink.listener.failure_show', $definition);
|
||||
}
|
||||
|
||||
private function processSelectors(ContainerBuilder $container)
|
||||
{
|
||||
$handlerDefinition = $container->getDefinition(self::SELECTORS_HANDLER_ID);
|
||||
|
||||
foreach ($container->findTaggedServiceIds(self::SELECTOR_TAG) as $id => $tags) {
|
||||
foreach ($tags as $tag) {
|
||||
if (!isset($tag['alias'])) {
|
||||
throw new ProcessingException(sprintf(
|
||||
'All `%s` tags should have an `alias` attribute, but `%s` service has none.',
|
||||
$tag,
|
||||
$id
|
||||
));
|
||||
}
|
||||
$handlerDefinition->addMethodCall(
|
||||
'registerSelector', array($tag['alias'], new Reference($id))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user