From 3ee16c4b871e5c39140f4c02db912507bed5c39f Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Sat, 11 Jan 2014 00:04:23 +0100 Subject: [PATCH 1/4] Refactored the configuration of sessions The configuration now makes sessions a first-class citizen instead of being centered around drivers. This allows defining several session based on the same driver type. Instead of allowing other extensions to register their own sessions to add new drivers, they can now register a DriverFactory in the MinkExtension during the extension initialization to make a new driver type available. --- behat.yml.dist | 4 +- doc/index.rst | 137 ++++-- .../Listener/SessionsListenerSpec.php | 12 +- .../Driver/GoutteFactorySpec.php | 24 + .../Driver/SahiFactorySpec.php | 24 + .../Driver/SaucelabsFactorySpec.php | 24 + .../Driver/Selenium2FactorySpec.php | 24 + .../Driver/SeleniumFactorySpec.php | 24 + .../Driver/ZombieFactorySpec.php | 24 + src/Behat/MinkExtension/Extension.php | 435 ++++-------------- .../Listener/SessionsListener.php | 26 +- .../ServiceContainer/Driver/DriverFactory.php | 52 +++ .../ServiceContainer/Driver/GoutteFactory.php | 89 ++++ .../ServiceContainer/Driver/SahiFactory.php | 74 +++ .../Driver/SaucelabsFactory.php | 92 ++++ .../Driver/Selenium2Factory.php | 130 ++++++ .../Driver/SeleniumFactory.php | 68 +++ .../ServiceContainer/Driver/ZombieFactory.php | 79 ++++ 18 files changed, 943 insertions(+), 399 deletions(-) create mode 100644 spec/Behat/MinkExtension/ServiceContainer/Driver/GoutteFactorySpec.php create mode 100644 spec/Behat/MinkExtension/ServiceContainer/Driver/SahiFactorySpec.php create mode 100644 spec/Behat/MinkExtension/ServiceContainer/Driver/SaucelabsFactorySpec.php create mode 100644 spec/Behat/MinkExtension/ServiceContainer/Driver/Selenium2FactorySpec.php create mode 100644 spec/Behat/MinkExtension/ServiceContainer/Driver/SeleniumFactorySpec.php create mode 100644 spec/Behat/MinkExtension/ServiceContainer/Driver/ZombieFactorySpec.php create mode 100644 src/Behat/MinkExtension/ServiceContainer/Driver/DriverFactory.php create mode 100644 src/Behat/MinkExtension/ServiceContainer/Driver/GoutteFactory.php create mode 100644 src/Behat/MinkExtension/ServiceContainer/Driver/SahiFactory.php create mode 100644 src/Behat/MinkExtension/ServiceContainer/Driver/SaucelabsFactory.php create mode 100644 src/Behat/MinkExtension/ServiceContainer/Driver/Selenium2Factory.php create mode 100644 src/Behat/MinkExtension/ServiceContainer/Driver/SeleniumFactory.php create mode 100644 src/Behat/MinkExtension/ServiceContainer/Driver/ZombieFactory.php diff --git a/behat.yml.dist b/behat.yml.dist index e6e546c..6f3e7a7 100644 --- a/behat.yml.dist +++ b/behat.yml.dist @@ -6,4 +6,6 @@ default: extensions: Behat\MinkExtension\Extension: base_url: http://en.wikipedia.org/ - goutte: ~ + sessions: + default: + goutte: ~ diff --git a/doc/index.rst b/doc/index.rst index 62d535c..b335a29 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -60,7 +60,9 @@ The easiest way to keep your suite updated is to use `Composer beConstructedWith($mink, array('default_session' => 'goutte', 'javascript_session' => 'selenium2')); + $this->beConstructedWith($mink, 'goutte', 'selenium2'); $event->getFeature()->willReturn($feature); $event->getScenario()->willReturn($scenario); @@ -54,6 +55,15 @@ class SessionsListenerSpec extends ObjectBehavior $this->prepareDefaultMinkSession($event); } + function it_fails_when_the_javascript_session_is_used_but_not_defined($event, $mink, $feature) + { + $this->beConstructedWith($mink, 'goutte', null); + $feature->getTags()->willReturn(array('javascript')); + + $this->shouldThrow(new ProcessingException('The @javascript tag cannot be used without enabling a javascript session')) + ->duringPrepareDefaultMinkSession($event); + } + function it_switches_to_a_named_session($event, $mink, $scenario) { $scenario->getTags()->willReturn(array('mink:test')); diff --git a/spec/Behat/MinkExtension/ServiceContainer/Driver/GoutteFactorySpec.php b/spec/Behat/MinkExtension/ServiceContainer/Driver/GoutteFactorySpec.php new file mode 100644 index 0000000..9b27f62 --- /dev/null +++ b/spec/Behat/MinkExtension/ServiceContainer/Driver/GoutteFactorySpec.php @@ -0,0 +1,24 @@ +shouldHaveType('Behat\MinkExtension\ServiceContainer\Driver\DriverFactory'); + } + + function it_is_named_goutte() + { + $this->getDriverName()->shouldReturn('goutte'); + } + + function it_does_not_support_javascript() + { + $this->supportsJavascript()->shouldBe(false); + } +} diff --git a/spec/Behat/MinkExtension/ServiceContainer/Driver/SahiFactorySpec.php b/spec/Behat/MinkExtension/ServiceContainer/Driver/SahiFactorySpec.php new file mode 100644 index 0000000..62550f2 --- /dev/null +++ b/spec/Behat/MinkExtension/ServiceContainer/Driver/SahiFactorySpec.php @@ -0,0 +1,24 @@ +shouldHaveType('Behat\MinkExtension\ServiceContainer\Driver\DriverFactory'); + } + + function it_is_named_sahi() + { + $this->getDriverName()->shouldReturn('sahi'); + } + + function it_supports_javascript() + { + $this->supportsJavascript()->shouldBe(true); + } +} diff --git a/spec/Behat/MinkExtension/ServiceContainer/Driver/SaucelabsFactorySpec.php b/spec/Behat/MinkExtension/ServiceContainer/Driver/SaucelabsFactorySpec.php new file mode 100644 index 0000000..05922c3 --- /dev/null +++ b/spec/Behat/MinkExtension/ServiceContainer/Driver/SaucelabsFactorySpec.php @@ -0,0 +1,24 @@ +shouldHaveType('Behat\MinkExtension\ServiceContainer\Driver\DriverFactory'); + } + + function it_is_named_saucelabs() + { + $this->getDriverName()->shouldReturn('saucelabs'); + } + + function it_supports_javascript() + { + $this->supportsJavascript()->shouldBe(true); + } +} diff --git a/spec/Behat/MinkExtension/ServiceContainer/Driver/Selenium2FactorySpec.php b/spec/Behat/MinkExtension/ServiceContainer/Driver/Selenium2FactorySpec.php new file mode 100644 index 0000000..60e4199 --- /dev/null +++ b/spec/Behat/MinkExtension/ServiceContainer/Driver/Selenium2FactorySpec.php @@ -0,0 +1,24 @@ +shouldHaveType('Behat\MinkExtension\ServiceContainer\Driver\DriverFactory'); + } + + function it_is_named_selenium2() + { + $this->getDriverName()->shouldReturn('selenium2'); + } + + function it_supports_javascript() + { + $this->supportsJavascript()->shouldBe(true); + } +} diff --git a/spec/Behat/MinkExtension/ServiceContainer/Driver/SeleniumFactorySpec.php b/spec/Behat/MinkExtension/ServiceContainer/Driver/SeleniumFactorySpec.php new file mode 100644 index 0000000..4de8c85 --- /dev/null +++ b/spec/Behat/MinkExtension/ServiceContainer/Driver/SeleniumFactorySpec.php @@ -0,0 +1,24 @@ +shouldHaveType('Behat\MinkExtension\ServiceContainer\Driver\DriverFactory'); + } + + function it_is_named_selenium() + { + $this->getDriverName()->shouldReturn('selenium'); + } + + function it_supports_javascript() + { + $this->supportsJavascript()->shouldBe(true); + } +} diff --git a/spec/Behat/MinkExtension/ServiceContainer/Driver/ZombieFactorySpec.php b/spec/Behat/MinkExtension/ServiceContainer/Driver/ZombieFactorySpec.php new file mode 100644 index 0000000..6f1f219 --- /dev/null +++ b/spec/Behat/MinkExtension/ServiceContainer/Driver/ZombieFactorySpec.php @@ -0,0 +1,24 @@ +shouldHaveType('Behat\MinkExtension\ServiceContainer\Driver\DriverFactory'); + } + + function it_is_named_zombie() + { + $this->getDriverName()->shouldReturn('zombie'); + } + + function it_supports_javascript() + { + $this->supportsJavascript()->shouldBe(true); + } +} diff --git a/src/Behat/MinkExtension/Extension.php b/src/Behat/MinkExtension/Extension.php index aa23317..99261e8 100644 --- a/src/Behat/MinkExtension/Extension.php +++ b/src/Behat/MinkExtension/Extension.php @@ -11,6 +11,13 @@ namespace Behat\MinkExtension; use Behat\Behat\Context\ServiceContainer\ContextExtension; +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; @@ -30,9 +37,28 @@ class Extension implements ExtensionInterface const MINK_ID = 'mink'; const SELECTORS_HANDLER_ID = 'mink.selectors_handler'; - const SESSION_TAG = 'mink.session'; 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 ZombieFactory()); + } + + public function registerDriverFactory(DriverFactory $driverFactory) + { + $this->driverFactories[$driverFactory->getDriverName()] = $driverFactory; + } + /** * {@inheritDoc} */ @@ -51,41 +77,17 @@ class Extension implements ExtensionInterface $this->loadMink($container); $this->loadContextInitializer($container); $this->loadSelectorsHandler($container); + $this->loadSessions($container, $config); $this->loadSessionsListener($container); if ($config['show_auto']) { $this->loadFailureShowListener($container); } - if (isset($config['goutte'])) { - $this->loadGoutteSession($container, $config['goutte']); - unset($config['goutte']); - } - if (isset($config['sahi'])) { - $this->loadSahiSession($container, $config['sahi']); - unset($config['sahi']); - } - if (isset($config['zombie'])) { - $this->loadZombieSession($container, $config['zombie']); - unset($config['zombie']); - } - if (isset($config['selenium'])) { - $this->loadSeleniumSession($container, $config['selenium']); - unset($config['zombie']); - } - if (isset($config['selenium2'])) { - $this->loadSelenium2Session($container, $config['selenium2']); - unset($config['selenium2']); - } - if (isset($config['saucelabs'])) { - $this->loadSaucelabsSession($container, $config['saucelabs']); - unset($config['saucelabs']); - } + unset($config['sessions']); $container->setParameter('mink.parameters', $config); $container->setParameter('mink.base_url', $config['base_url']); - $container->setParameter('mink.default_session', $config['default_session']); - $container->setParameter('mink.javascript_session', $config['javascript_session']); $container->setParameter('mink.browser_name', $config['browser_name']); } @@ -103,151 +105,38 @@ class Extension implements ExtensionInterface ->booleanNode('show_auto')->defaultFalse()->end() ->scalarNode('show_cmd')->defaultNull()->end() ->scalarNode('show_tmp_dir')->defaultValue(sys_get_temp_dir())->end() - ->scalarNode('default_session')->defaultValue('goutte')->end() - ->scalarNode('javascript_session')->defaultValue('selenium2')->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() - ->arrayNode('goutte') - ->children() - ->arrayNode('server_parameters') - ->useAttributeAsKey('key') - ->prototype('variable')->end() - ->end() - ->arrayNode('guzzle_parameters') - ->useAttributeAsKey('key') - ->prototype('variable')->end() - ->validate() - ->always() - ->then(function ($v) { - $v['redirect.disable'] = true; - - return $v; - }) - ->end() - ->end() - ->end() - ->end() - ->arrayNode('sahi') - ->children() - ->scalarNode('sid')->defaultNull()->end() - ->scalarNode('host')->defaultValue('localhost')->end() - ->scalarNode('port')->defaultValue(9999)->end() - ->scalarNode('browser')->defaultNull()->end() - ->scalarNode('limit')->defaultValue(600)->end() - ->end() - ->end() - ->arrayNode('zombie') - ->children() - ->scalarNode('host')->defaultValue('127.0.0.1')->end() - ->scalarNode('port')->defaultValue(8124)->end() - ->booleanNode('auto_server')->defaultValue(true)->end() - ->scalarNode('node_bin')->defaultValue('node')->end() - ->scalarNode('server_path')->defaultNull()->end() - ->scalarNode('threshold')->defaultValue(2000000)->end() - ->scalarNode('node_modules_path')->defaultValue('')->end() - ->end() - ->end() - ->arrayNode('selenium') - ->children() - ->scalarNode('host')->defaultValue('127.0.0.1')->end() - ->scalarNode('port')->defaultValue(4444)->end() - ->scalarNode('browser')->defaultValue('*%mink.browser_name%')->end() - ->end() - ->end() - ->arrayNode('selenium2') - ->children() - ->scalarNode('browser')->defaultValue('%mink.browser_name%')->end() - ->arrayNode('capabilities') - ->addDefaultsIfNotSet() - ->normalizeKeys(false) - ->children() - ->scalarNode('browserName')->defaultValue('firefox')->end() - ->scalarNode('version')->defaultValue('9')->end() - ->scalarNode('platform')->defaultValue('ANY')->end() - ->scalarNode('browserVersion')->defaultValue('9')->end() - ->scalarNode('browser')->defaultValue('firefox')->end() - ->scalarNode('ignoreZoomSetting')->defaultValue('false')->end() - ->scalarNode('name')->defaultValue('Behat Test')->end() - ->scalarNode('deviceOrientation')->defaultValue('portrait')->end() - ->scalarNode('deviceType')->defaultValue('tablet')->end() - ->scalarNode('selenium-version')->defaultValue('2.31.0')->end() - ->scalarNode('max-duration')->defaultValue('300')->end() - ->booleanNode('javascriptEnabled')->end() - ->booleanNode('databaseEnabled')->end() - ->booleanNode('locationContextEnabled')->end() - ->booleanNode('applicationCacheEnabled')->end() - ->booleanNode('browserConnectionEnabled')->end() - ->booleanNode('webStorageEnabled')->end() - ->booleanNode('rotatable')->end() - ->booleanNode('acceptSslCerts')->end() - ->booleanNode('nativeEvents')->end() - ->booleanNode('passed')->end() - ->booleanNode('record-video')->end() - ->booleanNode('record-screenshots')->end() - ->booleanNode('capture-html')->end() - ->booleanNode('disable-popup-handler')->end() - ->arrayNode('proxy') - ->children() - ->scalarNode('proxyType')->end() - ->scalarNode('proxyAuthconfigUrl')->end() - ->scalarNode('ftpProxy')->end() - ->scalarNode('httpProxy')->end() - ->scalarNode('sslProxy')->end() - ->end() - ->validate() - ->ifTrue(function ($v) { - return empty($v); - }) - ->thenUnset() - ->end() - ->end() - ->arrayNode('firefox') - ->children() - ->scalarNode('profile') - ->validate() - ->ifTrue(function ($v) { - return !file_exists($v); - }) - ->thenInvalid('Cannot find profile zip file %s') - ->end() - ->end() - ->scalarNode('binary')->end() - ->end() - ->end() - ->arrayNode('chrome') - ->children() - ->arrayNode('switches')->prototype('scalar')->end()->end() - ->scalarNode('binary')->end() - ->arrayNode('extensions')->prototype('scalar')->end()->end() - ->end() - ->end() - ->end() - ->end() - ->scalarNode('wd_host')->defaultValue('http://localhost:4444/wd/hub')->end() - ->end() - ->end() - ->arrayNode('saucelabs') - ->children() - ->scalarNode('username')->defaultValue(getenv('SAUCE_USERNAME'))->end() - ->scalarNode('access_key')->defaultValue(getenv('SAUCE_ACCESS_KEY'))->end() - ->booleanNode('connect')->defaultFalse()->end() - ->scalarNode('browser')->defaultValue('firefox')->end() - ->arrayNode('capabilities') - ->addDefaultsIfNotSet() - ->normalizeKeys(false) - ->children() - ->scalarNode('name')->defaultValue('Behat feature suite')->end() - ->scalarNode('platform')->defaultValue('Linux')->end() - ->scalarNode('version')->defaultValue('21')->end() - ->scalarNode('selenium-version')->defaultValue('2.31.0')->end() - ->scalarNode('max-duration')->defaultValue('300')->end() - ->scalarNode('deviceType')->defaultNull()->end() - ->scalarNode('deviceOrientation')->defaultNull()->end() - ->end() - ->end() - ->end() - ->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() + ; } /** @@ -270,7 +159,6 @@ class Extension implements ExtensionInterface */ public function process(ContainerBuilder $container) { - $this->processSessions($container); $this->processSelectors($container); } @@ -302,11 +190,49 @@ class Extension implements ExtensionInterface $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]; + } + + if (null === $defaultSession) { + $defaultSession = !empty($nonJavascriptSessions) ? $nonJavascriptSessions[0] : $javascriptSessions[0]; + } + + $container->setParameter('mink.default_session', $defaultSession); + $container->setParameter('mink.javascript_session', $javascriptSession); + } + private function loadSessionsListener(ContainerBuilder $container) { $definition = new Definition('Behat\MinkExtension\Listener\SessionsListener', array( new Reference(self::MINK_ID), - '%mink.parameters%', + '%mink.default_session%', + '%mink.javascript_session%', )); $definition->addTag(EventDispatcherExtension::SUBSCRIBER_TAG, array('priority' => 0)); $container->setDefinition('mink.listener.sessions', $definition); @@ -322,173 +248,6 @@ class Extension implements ExtensionInterface $container->setDefinition('mink.listener.failure_show', $definition); } - private function loadGoutteSession(ContainerBuilder $container, array $config) - { - if (!class_exists('Behat\Mink\Driver\GoutteDriver')) { - throw new \RuntimeException( - 'Install MinkGoutteDriver in order to activate goutte session.' - ); - } - - $clientDefinition = new Definition('Behat\Mink\Driver\Goutte\Client', array( - $config['server_parameters'], - )); - $clientDefinition->addMethodCall('setClient', array( - new Definition('Guzzle\Http\Client', array( - null, - $config['guzzle_parameters'], - )), - )); - - $driverDefinition = new Definition('Behat\Mink\Driver\GoutteDriver', array( - $clientDefinition, - )); - $this->loadSession($container, $driverDefinition, 'goutte'); - } - - private function loadSahiSession(ContainerBuilder $container, array $config) - { - if (!class_exists('Behat\Mink\Driver\SahiDriver')) { - throw new \RuntimeException( - 'Install MinkSahiDriver in order to activate sahi session.' - ); - } - - $driverDefinition = new Definition('Behat\Mink\Driver\SahiDriver', array( - '%mink.browser_name%', - new Definition('Behat\SahiClient\Client', array( - new Definition('Behat\SahiClient\Connection', array( - $config['sid'], - $config['host'], - $config['port'], - $config['browser'], - $config['limit'], - )), - )), - )); - $this->loadSession($container, $driverDefinition, 'sahi'); - } - - private function loadZombieSession(ContainerBuilder $container, array $config) - { - if (!class_exists('Behat\Mink\Driver\ZombieDriver')) { - throw new \RuntimeException( - 'Install MinkZombieDriver in order to activate zombie session.' - ); - } - - $driverDefinition = new Definition('Behat\Mink\Driver\ZombieDriver', array( - new Definition('Behat\Mink\Driver\NodeJS\Server\ZombieServer', array( - $config['host'], - $config['port'], - $config['node_bin'], - $config['server_path'], - $config['threshold'], - $config['node_modules_path'], - )), - new Definition('Behat\Mink\Driver\NodeJS\Connection', array( - $config['host'], - $config['port'], - )), - $config['auto_server'], - )); - $this->loadSession($container, $driverDefinition, 'zombie'); - } - - private function loadSeleniumSession(ContainerBuilder $container, array $config) - { - if (!class_exists('Behat\Mink\Driver\SeleniumDriver')) { - throw new \RuntimeException( - 'Install MinkSeleniumDriver in order to activate selenium session.' - ); - } - - $driverDefinition = new Definition('Behat\Mink\Driver\SeleniumDriver', array( - $config['browser'], - '%mink.base_url%', - new Definition('Selenium\Client', array( - $config['host'], - $config['port'], - )), - )); - $this->loadSession($container, $driverDefinition, 'selenium'); - } - - private function loadSelenium2Session(ContainerBuilder $container, array $config) - { - if (!class_exists('Behat\Mink\Driver\Selenium2Driver')) { - throw new \RuntimeException( - 'Install MinkSelenium2Driver in order to activate selenium2 session.' - ); - } - - $driverDefinition = new Definition('Behat\Mink\Driver\Selenium2Driver', array( - $config['browser'], - $config['capabilities'], - $config['wd_host'], - )); - $this->loadSession($container, $driverDefinition, 'selenium2'); - } - - private function loadSaucelabsSession(ContainerBuilder $container, array $config) - { - if (!class_exists('Behat\Mink\Driver\Selenium2Driver')) { - throw new \RuntimeException( - 'Install MinkSelenium2Driver in order to activate saucelabs session.' - ); - } - $capabilities = $config['capabilities']; - $capabilities['tags'] = array(php_uname('n'), 'PHP '.phpversion()); - - if (getenv('TRAVIS_JOB_NUMBER')) { - $capabilities['tunnel-identifier'] = getenv('TRAVIS_JOB_NUMBER'); - $capabilities['build'] = getenv('TRAVIS_BUILD_NUMBER'); - $capabilities['tags'] = array('Travis-CI', 'PHP '.phpversion()); - } - - $host = 'ondemand.saucelabs.com'; - if ($config['connect']) { - $host = 'localhost:4445'; - } - - $driverDefinition = new Definition('Behat\Mink\Driver\Selenium2Driver', array( - $config['browser'], - $capabilities, - sprintf('%s:%s@%s/wd/hub', $config['username'], $config['access_key'], $host), - )); - $this->loadSession($container, $driverDefinition, 'saucelabs'); - } - - private function loadSession(ContainerBuilder $container, Definition $driverDefinition, $alias) - { - $definition = new Definition('Behat\Mink\Session', array( - $driverDefinition, - new Reference(self::SELECTORS_HANDLER_ID), - )); - $definition->addTag(self::SESSION_TAG, array('alias' => $alias)); - $container->setDefinition(self::SESSION_TAG . '.' . $alias, $definition); - } - - private function processSessions(ContainerBuilder $container) - { - $handlerDefinition = $container->getDefinition(self::MINK_ID); - - foreach ($container->findTaggedServiceIds(self::SESSION_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( - 'registerSession', array($tag['alias'], new Reference($id)) - ); - } - } - } - private function processSelectors(ContainerBuilder $container) { $handlerDefinition = $container->getDefinition(self::SELECTORS_HANDLER_ID); diff --git a/src/Behat/MinkExtension/Listener/SessionsListener.php b/src/Behat/MinkExtension/Listener/SessionsListener.php index 0a56886..9c9d08a 100644 --- a/src/Behat/MinkExtension/Listener/SessionsListener.php +++ b/src/Behat/MinkExtension/Listener/SessionsListener.php @@ -14,6 +14,7 @@ use Behat\Behat\Tester\Event\AbstractScenarioTested; use Behat\Behat\Tester\Event\ExampleTested; use Behat\Behat\Tester\Event\ScenarioTested; use Behat\Mink\Mink; +use Behat\Testwork\ServiceContainer\Exception\ProcessingException; use Behat\Testwork\Tester\Event\ExerciseCompleted; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -26,18 +27,21 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; class SessionsListener implements EventSubscriberInterface { private $mink; - private $parameters; + private $defaultSession; + private $javascriptSession; /** * Initializes initializer. * - * @param Mink $mink - * @param array $parameters + * @param Mink $mink + * @param string $defaultSession + * @param string|null $javascriptSession */ - public function __construct(Mink $mink, array $parameters) + public function __construct(Mink $mink, $defaultSession, $javascriptSession) { - $this->mink = $mink; - $this->parameters = $parameters; + $this->mink = $mink; + $this->defaultSession = $defaultSession; + $this->javascriptSession = $javascriptSession; } /** @@ -64,16 +68,22 @@ class SessionsListener implements EventSubscriberInterface * instead of just soft-resetting them * * @param AbstractScenarioTested $event + * + * @throws ProcessingException when the @javascript tag is used without a javascript session */ public function prepareDefaultMinkSession(AbstractScenarioTested $event) { $scenario = $event->getScenario(); $feature = $event->getFeature(); - $session = $this->parameters['default_session']; + $session = $this->defaultSession; foreach (array_merge($feature->getTags(), $scenario->getTags()) as $tag) { if ('javascript' === $tag) { - $session = $this->parameters['javascript_session']; + if (null === $this->javascriptSession) { + throw new ProcessingException('The @javascript tag cannot be used without enabling a javascript session'); + } + + $session = $this->javascriptSession; } elseif (preg_match('/^mink\:(.+)/', $tag, $matches)) { $session = $matches[1]; } diff --git a/src/Behat/MinkExtension/ServiceContainer/Driver/DriverFactory.php b/src/Behat/MinkExtension/ServiceContainer/Driver/DriverFactory.php new file mode 100644 index 0000000..b2adf83 --- /dev/null +++ b/src/Behat/MinkExtension/ServiceContainer/Driver/DriverFactory.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Behat\MinkExtension\ServiceContainer\Driver; + +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\DependencyInjection\Definition; + +/** + * @author Christophe Coevoet + */ +interface DriverFactory +{ + /** + * Gets the name of the driver being configured. + * + * This will be the key of the configuration for the driver. + * + * @return string + */ + public function getDriverName(); + + /** + * Defines whether a session using this driver is eligible as default javascript session + * + * @return boolean + */ + public function supportsJavascript(); + + /** + * Setups configuration for the driver factory. + * + * @param ArrayNodeDefinition $builder + */ + public function configure(ArrayNodeDefinition $builder); + + /** + * Builds the service definition for the driver. + * + * @param array $config + * + * @return Definition + */ + public function buildDriver(array $config); +} diff --git a/src/Behat/MinkExtension/ServiceContainer/Driver/GoutteFactory.php b/src/Behat/MinkExtension/ServiceContainer/Driver/GoutteFactory.php new file mode 100644 index 0000000..e29b484 --- /dev/null +++ b/src/Behat/MinkExtension/ServiceContainer/Driver/GoutteFactory.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Behat\MinkExtension\ServiceContainer\Driver; + +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\DependencyInjection\Definition; + +/** + * @author Christophe Coevoet + */ +class GoutteFactory implements DriverFactory +{ + /** + * {@inheritdoc} + */ + public function getDriverName() + { + return 'goutte'; + } + + /** + * {@inheritdoc} + */ + public function supportsJavascript() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function configure(ArrayNodeDefinition $builder) + { + $builder + ->children() + ->arrayNode('server_parameters') + ->useAttributeAsKey('key') + ->prototype('variable')->end() + ->end() + ->arrayNode('guzzle_parameters') + ->useAttributeAsKey('key') + ->prototype('variable')->end() + ->validate() + ->always() + ->then(function ($v) { + $v['redirect.disable'] = true; + + return $v; + }) + ->end() + ->end() + ->end() + ; + } + + /** + * {@inheritdoc} + */ + public function buildDriver(array $config) + { + if (!class_exists('Behat\Mink\Driver\GoutteDriver')) { + throw new \RuntimeException( + 'Install MinkGoutteDriver in order to use goutte driver.' + ); + } + + $clientDefinition = new Definition('Behat\Mink\Driver\Goutte\Client', array( + $config['server_parameters'], + )); + $clientDefinition->addMethodCall('setClient', array( + new Definition('Guzzle\Http\Client', array( + null, + $config['guzzle_parameters'], + )), + )); + + return new Definition('Behat\Mink\Driver\GoutteDriver', array( + $clientDefinition, + )); + } +} diff --git a/src/Behat/MinkExtension/ServiceContainer/Driver/SahiFactory.php b/src/Behat/MinkExtension/ServiceContainer/Driver/SahiFactory.php new file mode 100644 index 0000000..860f3cf --- /dev/null +++ b/src/Behat/MinkExtension/ServiceContainer/Driver/SahiFactory.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Behat\MinkExtension\ServiceContainer\Driver; + +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\DependencyInjection\Definition; + +class SahiFactory implements DriverFactory +{ + /** + * {@inheritdoc} + */ + public function getDriverName() + { + return 'sahi'; + } + + /** + * {@inheritdoc} + */ + public function supportsJavascript() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function configure(ArrayNodeDefinition $builder) + { + $builder + ->children() + ->scalarNode('sid')->defaultNull()->end() + ->scalarNode('host')->defaultValue('localhost')->end() + ->scalarNode('port')->defaultValue(9999)->end() + ->scalarNode('browser')->defaultNull()->end() + ->scalarNode('limit')->defaultValue(600)->end() + ->end() + ; + } + + /** + * {@inheritdoc} + */ + public function buildDriver(array $config) + { + if (!class_exists('Behat\Mink\Driver\SahiDriver')) { + throw new \RuntimeException( + 'Install MinkSahiDriver in order to use sahi driver.' + ); + } + + return new Definition('Behat\Mink\Driver\SahiDriver', array( + '%mink.browser_name%', + new Definition('Behat\SahiClient\Client', array( + new Definition('Behat\SahiClient\Connection', array( + $config['sid'], + $config['host'], + $config['port'], + $config['browser'], + $config['limit'], + )), + )), + )); + } +} diff --git a/src/Behat/MinkExtension/ServiceContainer/Driver/SaucelabsFactory.php b/src/Behat/MinkExtension/ServiceContainer/Driver/SaucelabsFactory.php new file mode 100644 index 0000000..ace030e --- /dev/null +++ b/src/Behat/MinkExtension/ServiceContainer/Driver/SaucelabsFactory.php @@ -0,0 +1,92 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Behat\MinkExtension\ServiceContainer\Driver; + +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\DependencyInjection\Definition; + +class SaucelabsFactory implements DriverFactory +{ + /** + * {@inheritdoc} + */ + public function getDriverName() + { + return 'saucelabs'; + } + + /** + * {@inheritdoc} + */ + public function supportsJavascript() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function configure(ArrayNodeDefinition $builder) + { + $builder + ->children() + ->scalarNode('username')->defaultValue(getenv('SAUCE_USERNAME'))->end() + ->scalarNode('access_key')->defaultValue(getenv('SAUCE_ACCESS_KEY'))->end() + ->booleanNode('connect')->defaultFalse()->end() + ->scalarNode('browser')->defaultValue('firefox')->end() + ->arrayNode('capabilities') + ->addDefaultsIfNotSet() + ->normalizeKeys(false) + ->children() + ->scalarNode('name')->defaultValue('Behat feature suite')->end() + ->scalarNode('platform')->defaultValue('Linux')->end() + ->scalarNode('version')->defaultValue('21')->end() + ->scalarNode('selenium-version')->defaultValue('2.31.0')->end() + ->scalarNode('max-duration')->defaultValue('300')->end() + ->scalarNode('deviceType')->defaultNull()->end() + ->scalarNode('deviceOrientation')->defaultNull()->end() + ->end() + ->end() + ->end() + ; + } + + /** + * {@inheritdoc} + */ + public function buildDriver(array $config) + { + if (!class_exists('Behat\Mink\Driver\Selenium2Driver')) { + throw new \RuntimeException( + 'Install MinkSelenium2Driver in order to use saucelabs driver.' + ); + } + $capabilities = $config['capabilities']; + $capabilities['tags'] = array(php_uname('n'), 'PHP '.phpversion()); + + if (getenv('TRAVIS_JOB_NUMBER')) { + $capabilities['tunnel-identifier'] = getenv('TRAVIS_JOB_NUMBER'); + $capabilities['build'] = getenv('TRAVIS_BUILD_NUMBER'); + $capabilities['tags'] = array('Travis-CI', 'PHP '.phpversion()); + } + + $host = 'ondemand.saucelabs.com'; + if ($config['connect']) { + $host = 'localhost:4445'; + } + + return new Definition('Behat\Mink\Driver\Selenium2Driver', array( + $config['browser'], + $capabilities, + sprintf('%s:%s@%s/wd/hub', $config['username'], $config['access_key'], $host), + )); + } +} diff --git a/src/Behat/MinkExtension/ServiceContainer/Driver/Selenium2Factory.php b/src/Behat/MinkExtension/ServiceContainer/Driver/Selenium2Factory.php new file mode 100644 index 0000000..8a0d5b4 --- /dev/null +++ b/src/Behat/MinkExtension/ServiceContainer/Driver/Selenium2Factory.php @@ -0,0 +1,130 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Behat\MinkExtension\ServiceContainer\Driver; + +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\DependencyInjection\Definition; + +class Selenium2Factory implements DriverFactory +{ + /** + * {@inheritdoc} + */ + public function getDriverName() + { + return 'selenium2'; + } + + /** + * {@inheritdoc} + */ + public function supportsJavascript() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function configure(ArrayNodeDefinition $builder) + { + $builder + ->children() + ->scalarNode('browser')->defaultValue('%mink.browser_name%')->end() + ->arrayNode('capabilities') + ->addDefaultsIfNotSet() + ->normalizeKeys(false) + ->children() + ->scalarNode('browserName')->defaultValue('firefox')->end() + ->scalarNode('version')->defaultValue('9')->end() + ->scalarNode('platform')->defaultValue('ANY')->end() + ->scalarNode('browserVersion')->defaultValue('9')->end() + ->scalarNode('browser')->defaultValue('firefox')->end() + ->scalarNode('ignoreZoomSetting')->defaultValue('false')->end() + ->scalarNode('name')->defaultValue('Behat Test')->end() + ->scalarNode('deviceOrientation')->defaultValue('portrait')->end() + ->scalarNode('deviceType')->defaultValue('tablet')->end() + ->scalarNode('selenium-version')->defaultValue('2.31.0')->end() + ->scalarNode('max-duration')->defaultValue('300')->end() + ->booleanNode('javascriptEnabled')->end() + ->booleanNode('databaseEnabled')->end() + ->booleanNode('locationContextEnabled')->end() + ->booleanNode('applicationCacheEnabled')->end() + ->booleanNode('browserConnectionEnabled')->end() + ->booleanNode('webStorageEnabled')->end() + ->booleanNode('rotatable')->end() + ->booleanNode('acceptSslCerts')->end() + ->booleanNode('nativeEvents')->end() + ->booleanNode('passed')->end() + ->booleanNode('record-video')->end() + ->booleanNode('record-screenshots')->end() + ->booleanNode('capture-html')->end() + ->booleanNode('disable-popup-handler')->end() + ->arrayNode('proxy') + ->children() + ->scalarNode('proxyType')->end() + ->scalarNode('proxyAuthconfigUrl')->end() + ->scalarNode('ftpProxy')->end() + ->scalarNode('httpProxy')->end() + ->scalarNode('sslProxy')->end() + ->end() + ->validate() + ->ifTrue(function ($v) { + return empty($v); + }) + ->thenUnset() + ->end() + ->end() + ->arrayNode('firefox') + ->children() + ->scalarNode('profile') + ->validate() + ->ifTrue(function ($v) { + return !file_exists($v); + }) + ->thenInvalid('Cannot find profile zip file %s') + ->end() + ->end() + ->scalarNode('binary')->end() + ->end() + ->end() + ->arrayNode('chrome') + ->children() + ->arrayNode('switches')->prototype('scalar')->end()->end() + ->scalarNode('binary')->end() + ->arrayNode('extensions')->prototype('scalar')->end()->end() + ->end() + ->end() + ->end() + ->end() + ->scalarNode('wd_host')->defaultValue('http://localhost:4444/wd/hub')->end() + ->end() + ; + } + + /** + * {@inheritdoc} + */ + public function buildDriver(array $config) + { + if (!class_exists('Behat\Mink\Driver\Selenium2Driver')) { + throw new \RuntimeException( + 'Install MinkSelenium2Driver in order to use selenium2 driver.' + ); + } + + return new Definition('Behat\Mink\Driver\Selenium2Driver', array( + $config['browser'], + $config['capabilities'], + $config['wd_host'], + )); + } +} diff --git a/src/Behat/MinkExtension/ServiceContainer/Driver/SeleniumFactory.php b/src/Behat/MinkExtension/ServiceContainer/Driver/SeleniumFactory.php new file mode 100644 index 0000000..03fb9a5 --- /dev/null +++ b/src/Behat/MinkExtension/ServiceContainer/Driver/SeleniumFactory.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Behat\MinkExtension\ServiceContainer\Driver; + +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\DependencyInjection\Definition; + +class SeleniumFactory implements DriverFactory +{ + /** + * {@inheritdoc} + */ + public function getDriverName() + { + return 'selenium'; + } + + /** + * {@inheritdoc} + */ + public function supportsJavascript() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function configure(ArrayNodeDefinition $builder) + { + $builder + ->children() + ->scalarNode('host')->defaultValue('127.0.0.1')->end() + ->scalarNode('port')->defaultValue(4444)->end() + ->scalarNode('browser')->defaultValue('*%mink.browser_name%')->end() + ->end() + ; + } + + /** + * {@inheritdoc} + */ + public function buildDriver(array $config) + { + if (!class_exists('Behat\Mink\Driver\SeleniumDriver')) { + throw new \RuntimeException( + 'Install MinkSeleniumDriver in order to activate selenium session.' + ); + } + + return new Definition('Behat\Mink\Driver\SeleniumDriver', array( + $config['browser'], + '%mink.base_url%', + new Definition('Selenium\Client', array( + $config['host'], + $config['port'], + )), + )); + } +} diff --git a/src/Behat/MinkExtension/ServiceContainer/Driver/ZombieFactory.php b/src/Behat/MinkExtension/ServiceContainer/Driver/ZombieFactory.php new file mode 100644 index 0000000..59cb5df --- /dev/null +++ b/src/Behat/MinkExtension/ServiceContainer/Driver/ZombieFactory.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Behat\MinkExtension\ServiceContainer\Driver; + +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\DependencyInjection\Definition; + +class ZombieFactory implements DriverFactory +{ + /** + * {@inheritdoc} + */ + public function getDriverName() + { + return 'zombie'; + } + + /** + * {@inheritdoc} + */ + public function supportsJavascript() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function configure(ArrayNodeDefinition $builder) + { + $builder + ->children() + ->scalarNode('host')->defaultValue('127.0.0.1')->end() + ->scalarNode('port')->defaultValue(8124)->end() + ->booleanNode('auto_server')->defaultTrue()->end() + ->scalarNode('node_bin')->defaultValue('node')->end() + ->scalarNode('server_path')->defaultNull()->end() + ->scalarNode('threshold')->defaultValue(2000000)->end() + ->scalarNode('node_modules_path')->defaultValue('')->end() + ->end() + ; + } + + /** + * {@inheritdoc} + */ + public function buildDriver(array $config) + { + if (!class_exists('Behat\Mink\Driver\ZombieDriver')) { + throw new \RuntimeException( + 'Install MinkZombieDriver in order to use zombie driver.' + ); + } + + return new Definition('Behat\Mink\Driver\ZombieDriver', array( + new Definition('Behat\Mink\Driver\NodeJS\Server\ZombieServer', array( + $config['host'], + $config['port'], + $config['node_bin'], + $config['server_path'], + $config['threshold'], + $config['node_modules_path'], + )), + new Definition('Behat\Mink\Driver\NodeJS\Connection', array( + $config['host'], + $config['port'], + )), + $config['auto_server'], + )); + } +} From 58ca78aa59b4f69d0ce6e5d1b5491906b1c1aaf8 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Sat, 11 Jan 2014 00:27:14 +0100 Subject: [PATCH 2/4] Added some validation of the default session and javascript session --- src/Behat/MinkExtension/Extension.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Behat/MinkExtension/Extension.php b/src/Behat/MinkExtension/Extension.php index 99261e8..a62dda2 100644 --- a/src/Behat/MinkExtension/Extension.php +++ b/src/Behat/MinkExtension/Extension.php @@ -23,6 +23,7 @@ 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; @@ -217,10 +218,18 @@ class Extension implements ExtensionInterface 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); From 794ea867eacde3732a34a088f8d06b878f9911a5 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Sat, 11 Jan 2014 01:04:54 +0100 Subject: [PATCH 3/4] Removed unused use statements --- .../MinkExtension/ServiceContainer/Driver/GoutteFactorySpec.php | 1 - .../MinkExtension/ServiceContainer/Driver/SahiFactorySpec.php | 1 - .../ServiceContainer/Driver/SaucelabsFactorySpec.php | 1 - .../ServiceContainer/Driver/Selenium2FactorySpec.php | 1 - .../ServiceContainer/Driver/SeleniumFactorySpec.php | 1 - .../MinkExtension/ServiceContainer/Driver/ZombieFactorySpec.php | 1 - 6 files changed, 6 deletions(-) diff --git a/spec/Behat/MinkExtension/ServiceContainer/Driver/GoutteFactorySpec.php b/spec/Behat/MinkExtension/ServiceContainer/Driver/GoutteFactorySpec.php index 9b27f62..484e6e7 100644 --- a/spec/Behat/MinkExtension/ServiceContainer/Driver/GoutteFactorySpec.php +++ b/spec/Behat/MinkExtension/ServiceContainer/Driver/GoutteFactorySpec.php @@ -3,7 +3,6 @@ namespace spec\Behat\MinkExtension\ServiceContainer\Driver; use PhpSpec\ObjectBehavior; -use Prophecy\Argument; class GoutteFactorySpec extends ObjectBehavior { diff --git a/spec/Behat/MinkExtension/ServiceContainer/Driver/SahiFactorySpec.php b/spec/Behat/MinkExtension/ServiceContainer/Driver/SahiFactorySpec.php index 62550f2..abdb7d5 100644 --- a/spec/Behat/MinkExtension/ServiceContainer/Driver/SahiFactorySpec.php +++ b/spec/Behat/MinkExtension/ServiceContainer/Driver/SahiFactorySpec.php @@ -3,7 +3,6 @@ namespace spec\Behat\MinkExtension\ServiceContainer\Driver; use PhpSpec\ObjectBehavior; -use Prophecy\Argument; class SahiFactorySpec extends ObjectBehavior { diff --git a/spec/Behat/MinkExtension/ServiceContainer/Driver/SaucelabsFactorySpec.php b/spec/Behat/MinkExtension/ServiceContainer/Driver/SaucelabsFactorySpec.php index 05922c3..eedfcd3 100644 --- a/spec/Behat/MinkExtension/ServiceContainer/Driver/SaucelabsFactorySpec.php +++ b/spec/Behat/MinkExtension/ServiceContainer/Driver/SaucelabsFactorySpec.php @@ -3,7 +3,6 @@ namespace spec\Behat\MinkExtension\ServiceContainer\Driver; use PhpSpec\ObjectBehavior; -use Prophecy\Argument; class SaucelabsFactorySpec extends ObjectBehavior { diff --git a/spec/Behat/MinkExtension/ServiceContainer/Driver/Selenium2FactorySpec.php b/spec/Behat/MinkExtension/ServiceContainer/Driver/Selenium2FactorySpec.php index 60e4199..5ec5c16 100644 --- a/spec/Behat/MinkExtension/ServiceContainer/Driver/Selenium2FactorySpec.php +++ b/spec/Behat/MinkExtension/ServiceContainer/Driver/Selenium2FactorySpec.php @@ -3,7 +3,6 @@ namespace spec\Behat\MinkExtension\ServiceContainer\Driver; use PhpSpec\ObjectBehavior; -use Prophecy\Argument; class Selenium2FactorySpec extends ObjectBehavior { diff --git a/spec/Behat/MinkExtension/ServiceContainer/Driver/SeleniumFactorySpec.php b/spec/Behat/MinkExtension/ServiceContainer/Driver/SeleniumFactorySpec.php index 4de8c85..a1fb505 100644 --- a/spec/Behat/MinkExtension/ServiceContainer/Driver/SeleniumFactorySpec.php +++ b/spec/Behat/MinkExtension/ServiceContainer/Driver/SeleniumFactorySpec.php @@ -3,7 +3,6 @@ namespace spec\Behat\MinkExtension\ServiceContainer\Driver; use PhpSpec\ObjectBehavior; -use Prophecy\Argument; class SeleniumFactorySpec extends ObjectBehavior { diff --git a/spec/Behat/MinkExtension/ServiceContainer/Driver/ZombieFactorySpec.php b/spec/Behat/MinkExtension/ServiceContainer/Driver/ZombieFactorySpec.php index 6f1f219..f0e0445 100644 --- a/spec/Behat/MinkExtension/ServiceContainer/Driver/ZombieFactorySpec.php +++ b/spec/Behat/MinkExtension/ServiceContainer/Driver/ZombieFactorySpec.php @@ -3,7 +3,6 @@ namespace spec\Behat\MinkExtension\ServiceContainer\Driver; use PhpSpec\ObjectBehavior; -use Prophecy\Argument; class ZombieFactorySpec extends ObjectBehavior { From e569fd7bc1af69c4546677a55a3d6ec5268a1c5a Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Sat, 11 Jan 2014 00:13:31 +0100 Subject: [PATCH 4/4] Added a shortcut syntax for the configuration of sessions --- src/Behat/MinkExtension/Extension.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/Behat/MinkExtension/Extension.php b/src/Behat/MinkExtension/Extension.php index a62dda2..a2fba1f 100644 --- a/src/Behat/MinkExtension/Extension.php +++ b/src/Behat/MinkExtension/Extension.php @@ -97,7 +97,28 @@ class Extension implements ExtensionInterface */ 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()