Merge pull request #137 from stof/saucelabs_capabilities

Refactored the handling of Selenium2 capabilities
This commit is contained in:
Konstantin Kudryashov
2014-04-27 11:02:37 +01:00
8 changed files with 308 additions and 169 deletions

View File

@@ -230,7 +230,7 @@ the following parameters to avoid the validation error triggered by Guzzle :
my_session:
selenium2: ~
* ``SaucelabsDriver`` - special flavor of the Selenium2Driver configured to use the
* ``SauceLabsDriver`` - special flavor of the Selenium2Driver configured to use the
selenium2 hosted installation of saucelabs.com. In order to use it, modify your
``behat.yml`` profile:
@@ -241,7 +241,20 @@ the following parameters to avoid the validation error triggered by Guzzle :
Behat\MinkExtension\Extension:
sessions:
my_session:
saucelabs: ~
sauce_labs: ~
* ``BrowserStackDriver`` - special flavor of the Selenium2Driver configured to use the
selenium2 hosted installation of browserstack.com. In order to use it, modify your
``behat.yml`` profile:
.. code-block:: yaml
default:
extensions:
Behat\MinkExtension\Extension:
sessions:
my_session:
browser_stack: ~
* ``SeleniumDriver`` - javascript driver. In order to use it, modify your ``behat.yml``
profile:

View File

@@ -0,0 +1,24 @@
<?php
namespace spec\Behat\MinkExtension\ServiceContainer\Driver;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class BrowserStackFactorySpec extends ObjectBehavior
{
function it_is_a_driver_factory()
{
$this->shouldHaveType('Behat\MinkExtension\ServiceContainer\Driver\DriverFactory');
}
function it_is_named_browser_stack()
{
$this->getDriverName()->shouldReturn('browser_stack');
}
function it_supports_javascript()
{
$this->supportsJavascript()->shouldBe(true);
}
}

View File

@@ -4,16 +4,16 @@ namespace spec\Behat\MinkExtension\ServiceContainer\Driver;
use PhpSpec\ObjectBehavior;
class SaucelabsFactorySpec extends ObjectBehavior
class SauceLabsFactorySpec extends ObjectBehavior
{
function it_is_a_driver_factory()
{
$this->shouldHaveType('Behat\MinkExtension\ServiceContainer\Driver\DriverFactory');
}
function it_is_named_saucelabs()
function it_is_named_sauce_labs()
{
$this->getDriverName()->shouldReturn('saucelabs');
$this->getDriverName()->shouldReturn('sauce_labs');
}
function it_supports_javascript()

View File

@@ -11,10 +11,11 @@
namespace Behat\MinkExtension;
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\SauceLabsFactory;
use Behat\MinkExtension\ServiceContainer\Driver\Selenium2Factory;
use Behat\MinkExtension\ServiceContainer\Driver\SeleniumFactory;
use Behat\MinkExtension\ServiceContainer\Driver\ZombieFactory;
@@ -51,7 +52,8 @@ class Extension implements ExtensionInterface
$this->registerDriverFactory(new SahiFactory());
$this->registerDriverFactory(new SeleniumFactory());
$this->registerDriverFactory(new Selenium2Factory());
$this->registerDriverFactory(new SaucelabsFactory());
$this->registerDriverFactory(new SauceLabsFactory());
$this->registerDriverFactory(new BrowserStackFactory());
$this->registerDriverFactory(new ZombieFactory());
}

View File

@@ -0,0 +1,80 @@
<?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\Driver;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
class BrowserStackFactory extends Selenium2Factory
{
/**
* {@inheritdoc}
*/
public function getDriverName()
{
return 'browser_stack';
}
/**
* {@inheritdoc}
*/
public function configure(ArrayNodeDefinition $builder)
{
$builder
->children()
->scalarNode('username')->defaultValue(getenv('BROWSERSTACK_USERNAME'))->end()
->scalarNode('access_key')->defaultValue(getenv('BROWSERSTACK_ACCESS_KEY'))->end()
->scalarNode('browser')->defaultValue('firefox')->end()
->append($this->getCapabilitiesNode())
->end()
;
}
/**
* {@inheritdoc}
*/
public function buildDriver(array $config)
{
$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());
}
$config['capabilities'] = $capabilities;
$config['wd_host'] = sprintf('%s:%s@hub.browserstack.com/wd/hub', $config['username'], $config['access_key']);
return parent::buildDriver($config);
}
protected function getCapabilitiesNode()
{
$node = parent::getCapabilitiesNode();
$node
->children()
->scalarNode('name')->defaultValue('Behat feature suite')->end()
->scalarNode('project')->end()
->scalarNode('resolution')->end()
->scalarNode('build')->info('will be set automatically based on the TRAVIS_JOB_NUMBER environment variable if available')->end()
->scalarNode('os')->end()
->scalarNode('os_version')->end()
->scalarNode('device')->end()
->booleanNode('browserstack-debug')->end()
->booleanNode('browserstack-tunnel')->end()
->end()
;
return $node;
}
}

View File

@@ -0,0 +1,101 @@
<?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\Driver;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
class SauceLabsFactory extends Selenium2Factory
{
/**
* {@inheritdoc}
*/
public function getDriverName()
{
return 'sauce_labs';
}
/**
* {@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()
->append($this->getCapabilitiesNode())
->end()
;
}
/**
* {@inheritdoc}
*/
public function buildDriver(array $config)
{
$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';
}
$config['capabilities'] = $capabilities;
$config['wd_host'] = sprintf('%s:%s@%s/wd/hub', $config['username'], $config['access_key'], $host);
return parent::buildDriver($config);
}
protected function getCapabilitiesNode()
{
$node = parent::getCapabilitiesNode();
$node
->children()
->scalarNode('name')->defaultValue('Behat feature suite')->end()
->scalarNode('platform')->defaultValue('Linux')->end()
->scalarNode('selenium-version')->defaultValue('2.31.0')->end()
->scalarNode('max-duration')->defaultValue('300')->end()
->scalarNode('command-timeout')->end()
->scalarNode('idle-timeout')->end()
->scalarNode('build')->info('will be set automatically based on the TRAVIS_JOB_NUMBER environment variable if available')->end()
->arrayNode('custom-data')
->useAttributeAsKey('')
->prototype('variable')->end()
->end()
->scalarNode('screen-resolution')->end()
->scalarNode('tunnel-identifier')->end()
->arrayNode('prerun')
->children()
->scalarNode('executable')->isRequired()->end()
->arrayNode('args')->prototype('scalar')->end()->end()
->booleanNode('background')->defaultFalse()->end()
->end()
->end()
->booleanNode('record-video')->end()
->booleanNode('record-screenshots')->end()
->booleanNode('capture-html')->end()
->booleanNode('disable-popup-handler')->end()
->end()
;
return $node;
}
}

View File

@@ -1,92 +0,0 @@
<?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\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),
));
}
}

View File

@@ -39,72 +39,7 @@ class Selenium2Factory implements DriverFactory
$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()
->append($this->getCapabilitiesNode())
->scalarNode('wd_host')->defaultValue('http://localhost:4444/wd/hub')->end()
->end()
;
@@ -116,15 +51,91 @@ class Selenium2Factory implements DriverFactory
public function buildDriver(array $config)
{
if (!class_exists('Behat\Mink\Driver\Selenium2Driver')) {
throw new \RuntimeException(
'Install MinkSelenium2Driver in order to use selenium2 driver.'
);
throw new \RuntimeException(sprintf(
'Install MinkSelenium2Driver in order to use %s driver.',
$this->getDriverName()
));
}
$extraCapabilities = $config['capabilities']['extra_capabilities'];
unset($config['capabilities']['extra_capabilities']);
return new Definition('Behat\Mink\Driver\Selenium2Driver', array(
$config['browser'],
$config['capabilities'],
array_replace($extraCapabilities, $config['capabilities']),
$config['wd_host'],
));
}
protected function getCapabilitiesNode()
{
$node = new ArrayNodeDefinition('capabilities');
$node
->addDefaultsIfNotSet()
->normalizeKeys(false)
->children()
->scalarNode('browserName')->defaultValue('firefox')->end()
->scalarNode('version')->defaultValue('21')->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 feature suite')->end()
->scalarNode('deviceOrientation')->defaultValue('portrait')->end()
->scalarNode('deviceType')->defaultValue('tablet')->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()
->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()
->arrayNode('extra_capabilities')
->info('Custom capabilities merged with the known ones')
->normalizeKeys(false)
->useAttributeAsKey('name')
->prototype('variable')->end()
->end()
->end();
return $node;
}
}