├── .gitignore ├── init.php ├── composer.json └── src └── Phase2 └── Behat └── SauceExtension ├── services └── services.xml ├── Extension.php ├── Compiler └── EnvironmentLoaderPass.php └── Formatter └── JenkinsFormatter.php /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | -------------------------------------------------------------------------------- /init.php: -------------------------------------------------------------------------------- 1 | =2.4.3, <2.5.0" 6 | }, 7 | "authors": [ 8 | { 9 | "name": "Roger López", 10 | "email": "rlopez@phase2technology.com" 11 | } 12 | ], 13 | "autoload": { 14 | "psr-0": { "Phase2\\Behat\\SauceExtension": "src/" } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Phase2/Behat/SauceExtension/services/services.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | Phase2\Behat\SauceExtension\Formatter\JenkinsFormatter 8 | sauce-jenkins 9 | Prints Sauce job ID for use with the Sauce OnDemand Jenkins plugin. 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Phase2/Behat/SauceExtension/Extension.php: -------------------------------------------------------------------------------- 1 | load('services.xml'); 25 | } 26 | 27 | /** 28 | * Returns compiler passes used by this extension. 29 | * 30 | * @return array 31 | */ 32 | public function getCompilerPasses() 33 | { 34 | return array( 35 | new Compiler\EnvironmentLoaderPass(), 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Phase2/Behat/SauceExtension/Compiler/EnvironmentLoaderPass.php: -------------------------------------------------------------------------------- 1 | setParameter('behat.mink.selenium2.wd_host', sprintf("http://%s:%s@%s:%d/wd/hub", 25 | getenv('SAUCE_USER_NAME'), 26 | getenv('SAUCE_API_KEY'), 27 | getenv('SELENIUM_HOST'), 28 | getenv('SELENIUM_PORT'))); 29 | } 30 | 31 | // Generate the browser capabilities from SELENIUM_DRIVER env variable if available. 32 | if ($driver = getenv('SELENIUM_DRIVER')) { 33 | // sauce-ondemand:?os=Linux&browser=firefox&browser-version=10 34 | $uri = parse_url($driver); 35 | if ($uri['scheme'] == 'sauce-ondemand') { 36 | $params = array(); 37 | parse_str($uri['query'], $params); 38 | 39 | // Fill in the right capabilities. 40 | $container->setParameter('behat.mink.selenium2.capabilities', array( 41 | 'version' => $params['browser-version'], 42 | 'platform' => $params['os'], 43 | )); 44 | 45 | // Set the browser name. 46 | $container->setParameter('behat.mink.selenium2.browser', $params['browser']); 47 | } 48 | } 49 | // Otherwise, generate the browser capabilities from other env variables if available. 50 | elseif ($browser = getenv('SELENIUM_BROWSER')) { 51 | // Fill in the right capabilities. 52 | $container->setParameter('behat.mink.selenium2.capabilities', array( 53 | 'version' => getenv('SELENIUM_VERSION'), 54 | 'platform' => getenv('SELENIUM_PLATFORM'), 55 | )); 56 | 57 | // Set the browser name. 58 | $container->setParameter('behat.mink.selenium2.browser', $browser); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Phase2/Behat/SauceExtension/Formatter/JenkinsFormatter.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class JenkinsFormatter extends ConsoleFormatter 18 | { 19 | /** 20 | * The detected job id. 21 | */ 22 | private $jobId = 0; 23 | 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | protected function getDefaultParameters() 28 | { 29 | return array(); 30 | } 31 | 32 | /** 33 | * Returns an array of event names this subscriber wants to listen to. 34 | * 35 | * The array keys are event names and the value can be: 36 | * 37 | * * The method name to call (priority defaults to 0) 38 | * * An array composed of the method name to call and the priority 39 | * * An array of arrays composed of the method names to call and respective 40 | * priorities, or 0 if unset 41 | * 42 | * For instance: 43 | * 44 | * * array('eventName' => 'methodName') 45 | * * array('eventName' => array('methodName', $priority)) 46 | * * array('eventName' => array(array('methodName1', $priority), array('methodName2')) 47 | * 48 | * @return array The event names to listen to 49 | */ 50 | public static function getSubscribedEvents() 51 | { 52 | return array( 53 | 'afterScenario' => array('findId', -10), 54 | 'afterOutline' => array('findId', -10), 55 | 'afterSuite' => 'afterSuite', 56 | ); 57 | } 58 | 59 | /** 60 | * Find the job ID from the context. 61 | * 62 | * @param ScenarioEvent|OutlineEvent $event 63 | */ 64 | public function findId($event) 65 | { 66 | if (empty($this->jobId)) { 67 | $scenario = $event instanceof ScenarioEvent ? $event->getScenario() : $event->getOutline(); 68 | $context = $event->getContext(); 69 | $url = $context->getSession()->getDriver()->getWebDriverSession()->getUrl(); 70 | $parts = explode('/', $url); 71 | $this->jobId = array_pop($parts); 72 | } 73 | } 74 | 75 | /** 76 | * Listens to "suite.after" event. 77 | * 78 | * @param SuiteEvent $event 79 | */ 80 | public function afterSuite(SuiteEvent $event) 81 | { 82 | $this->writeln( 83 | sprintf( 84 | "{+comment} SauceOnDemandSessionID=%s job-name=%s{-comment}", 85 | $this->jobId, 86 | (($name = getenv('BUILD_TAG')) ? $name : 'Behat') 87 | ) 88 | ); 89 | } 90 | } 91 | --------------------------------------------------------------------------------