Update to selenium_v3.0.1.2 (#291)

* Update selenium to v3.0.1.2
* Code style
* JoomlaBrowser to v3.6.5.1
This commit is contained in:
Astrid 2017-01-12 21:22:50 +01:00 committed by Yves Hoppe
parent bf25b8e764
commit 572eebbfc4
4 changed files with 264 additions and 48 deletions

View File

@ -5,7 +5,11 @@
* Download robo.phar from http://robo.li/robo.phar and type in the root of the repo: $ php robo.phar * Download robo.phar from http://robo.li/robo.phar and type in the root of the repo: $ php robo.phar
* Or do: $ composer update, and afterwards you will be able to execute robo like $ php vendor/bin/robo * Or do: $ composer update, and afterwards you will be able to execute robo like $ php vendor/bin/robo
* *
* @see http://robo.li/ * @package Joomla.Site
* @subpackage RoboFile
*
* @copyright Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/ */
require_once 'vendor/autoload.php'; require_once 'vendor/autoload.php';
@ -15,6 +19,13 @@ if (!defined('JPATH_BASE'))
define('JPATH_BASE', __DIR__); define('JPATH_BASE', __DIR__);
} }
/**
* Modern php task runner for Joomla! Browser Automated Tests execution
*
* @package RoboFile
*
* @since 1.0
*/
class RoboFile extends \Robo\Tasks class RoboFile extends \Robo\Tasks
{ {
// Load tasks from composer, see composer.json // Load tasks from composer, see composer.json
@ -42,6 +53,12 @@ class RoboFile extends \Robo\Tasks
*/ */
private $cmsPath = ''; private $cmsPath = '';
/**
* @var array | null
* @since version
*/
private $suiteConfig;
/** /**
* Constructor * Constructor
*/ */
@ -66,9 +83,9 @@ class RoboFile extends \Robo\Tasks
{ {
if ($this->isWindows()) if ($this->isWindows())
{ {
// check wehter git.exe or git as command should be used, // Check wehter git.exe or git as command should be used,
// as on window both is possible // As on window both is possible
if(!$this->_exec('git.exe --version')->getMessage()) if (!$this->_exec('git.exe --version')->getMessage())
{ {
return ''; return '';
} }
@ -77,15 +94,17 @@ class RoboFile extends \Robo\Tasks
return '.exe'; return '.exe';
} }
} }
return ''; return '';
} }
/** /**
* Executes all the Selenium System Tests in a suite on your machine * Executes all the Selenium System Tests in a suite on your machine
* *
* @param array $opts Array of configuration options: * @param array $opts Array of configuration options:
* - 'use-htaccess': renames and enable embedded Joomla .htaccess file * - 'use-htaccess': renames and enable embedded Joomla .htaccess file
* - 'env': set a specific environment to get configuration from * - 'env': set a specific environment to get configuration from
*
* @return mixed * @return mixed
*/ */
public function runTests($opts = ['use-htaccess' => false, 'env' => 'desktop']) public function runTests($opts = ['use-htaccess' => false, 'env' => 'desktop'])
@ -129,7 +148,7 @@ class RoboFile extends \Robo\Tasks
->stopOnFail(); ->stopOnFail();
/* /*
// Uncomment this lines if you need to debug selenium errors Uncomment this lines if you need to debug selenium errors
$seleniumErrors = file_get_contents('selenium.log'); $seleniumErrors = file_get_contents('selenium.log');
if ($seleniumErrors) { if ($seleniumErrors) {
$this->say('Printing Selenium Log files'); $this->say('Printing Selenium Log files');
@ -143,9 +162,8 @@ class RoboFile extends \Robo\Tasks
/** /**
* Executes a specific Selenium System Tests in your machine * Executes a specific Selenium System Tests in your machine
* *
* @param string $seleniumPath Optional path to selenium-standalone-server-x.jar * @param string $pathToTestFile Optional name of the test to be run
* @param string $pathToTestFile Optional name of the test to be run * @param string $suite Optional name of the suite containing the tests, Acceptance by default.
* @param string $suite Optional name of the suite containing the tests, Acceptance by default.
* *
* @return mixed * @return mixed
*/ */
@ -193,26 +211,28 @@ class RoboFile extends \Robo\Tasks
$pathToTestFile = 'tests/' . $suite . '/' . $test; $pathToTestFile = 'tests/' . $suite . '/' . $test;
//loading the class to display the methods in the class // Loading the class to display the methods in the class
require 'tests/' . $suite . '/' . $test; require 'tests/' . $suite . '/' . $test;
//logic to fetch the class name from the file name // Logic to fetch the class name from the file name
$fileName = explode("/", $test); $fileName = explode("/", $test);
$className = explode(".", $fileName[1]); $className = explode(".", $fileName[1]);
//if the selected file is cest only than we will give the option to execute individual methods, we don't need this in cept file // If the selected file is cest only than we will give the option to execute individual methods, we don't need this in cept file
$i = 1; $i = 1;
if (strripos($className[0], 'cest')) if (strripos($className[0], 'cest'))
{ {
$class_methods = get_class_methods($className[0]); $class_methods = get_class_methods($className[0]);
$this->say('[' . $i . '] ' . 'All'); $this->say('[' . $i . '] ' . 'All');
$methods[$i] = 'All'; $methods[$i] = 'All';
$i++; $i++;
foreach ($class_methods as $method_name) foreach ($class_methods as $method_name)
{ {
$reflect = new ReflectionMethod($className[0], $method_name); $reflect = new ReflectionMethod($className[0], $method_name);
if(!$reflect->isConstructor())
if (!$reflect->isConstructor())
{ {
if ($reflect->isPublic()) if ($reflect->isPublic())
{ {
@ -222,12 +242,13 @@ class RoboFile extends \Robo\Tasks
} }
} }
} }
$this->say(''); $this->say('');
$methodNumber = $this->ask('Please choose the method in the test that you would want to run...'); $methodNumber = $this->ask('Please choose the method in the test that you would want to run...');
$method = $methods[$methodNumber]; $method = $methods[$methodNumber];
} }
if(isset($method) && $method != 'All') if (isset($method) && $method != 'All')
{ {
$pathToTestFile = $pathToTestFile . ':' . $method; $pathToTestFile = $pathToTestFile . ':' . $method;
} }
@ -243,23 +264,28 @@ class RoboFile extends \Robo\Tasks
/** /**
* Run the specified checker tool. Valid options are phpmd, phpcs, phpcpd * Run the specified checker tool. Valid options are phpmd, phpcs, phpcpd
* *
* @param string $tool * @param string $tool The tool
* *
* @return bool * @return bool
*/ */
public function runChecker($tool = null) public function runChecker($tool = null)
{ {
if ($tool === null) { if ($tool === null)
{
$this->say('You have to specify a tool name as argument. Valid tools are phpmd, phpcs, phpcpd.'); $this->say('You have to specify a tool name as argument. Valid tools are phpmd, phpcs, phpcpd.');
return false; return false;
} }
if (!in_array($tool, array('phpmd', 'phpcs', 'phpcpd') )) { if (!in_array($tool, array('phpmd', 'phpcs', 'phpcpd')))
{
$this->say('The tool you required is not known. Valid tools are phpmd, phpcs, phpcpd.'); $this->say('The tool you required is not known. Valid tools are phpmd, phpcs, phpcpd.');
return false; return false;
} }
switch ($tool) { switch ($tool)
{
case 'phpmd': case 'phpmd':
return $this->runPhpmd(); return $this->runPhpmd();
@ -275,12 +301,15 @@ class RoboFile extends \Robo\Tasks
* Creates a testing Joomla site for running the tests (use it before run:test) * Creates a testing Joomla site for running the tests (use it before run:test)
* *
* @param bool $use_htaccess (1/0) Rename and enable embedded Joomla .htaccess file * @param bool $use_htaccess (1/0) Rename and enable embedded Joomla .htaccess file
*
* @return bool
*/ */
public function createTestingSite($use_htaccess = false) public function createTestingSite($use_htaccess = false)
{ {
if (!empty($this->configuration->skipClone)) if (!empty($this->configuration->skipClone))
{ {
$this->say('Reusing Joomla CMS site already present at ' . $this->cmsPath); $this->say('Reusing Joomla CMS site already present at ' . $this->cmsPath);
return; return;
} }
@ -348,13 +377,16 @@ class RoboFile extends \Robo\Tasks
if (!file_exists($configurationFile)) if (!file_exists($configurationFile))
{ {
$this->say("No local configuration file"); $this->say("No local configuration file");
return null; return null;
} }
$configuration = parse_ini_file($configurationFile); $configuration = parse_ini_file($configurationFile);
if ($configuration === false) if ($configuration === false)
{ {
$this->say('Local configuration file is empty or wrong (check is it in correct .ini format'); $this->say('Local configuration file is empty or wrong (check is it in correct .ini format');
return null; return null;
} }
@ -398,6 +430,7 @@ class RoboFile extends \Robo\Tasks
if (!file_exists(dirname($this->configuration->cmsPath))) if (!file_exists(dirname($this->configuration->cmsPath)))
{ {
$this->say("Cms path written in local configuration does not exists or is not readable"); $this->say("Cms path written in local configuration does not exists or is not readable");
return 'tests/joomla'; return 'tests/joomla';
} }
@ -411,18 +444,19 @@ class RoboFile extends \Robo\Tasks
*/ */
public function runSelenium() public function runSelenium()
{ {
if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') if (!$this->isWindows())
{ {
$this->_exec("vendor/bin/selenium-server-standalone >> selenium.log 2>&1 &"); $this->_exec("vendor/bin/selenium-server-standalone " . $this->getWebDriver() . ' >> selenium.log 2>&1 &');
} }
else else
{ {
$this->_exec("START java.exe -jar .\\vendor\\joomla-projects\\selenium-server-standalone\\bin\\selenium-server-standalone.jar"); $this->_exec('START java.exe -jar' . $this->getWebDriver() .
' vendor\joomla-projects\selenium-server-standalone\bin\selenium-server-standalone.jar ');
} }
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') if ($this->isWindows())
{ {
sleep(10); sleep(3);
} }
else else
{ {
@ -458,6 +492,8 @@ class RoboFile extends \Robo\Tasks
* *
* @param string $host Web host of the remote server. * @param string $host Web host of the remote server.
* @param string $port Server port. * @param string $port Server port.
*
* @return void
*/ */
public function killSelenium($host = 'localhost', $port = '4444') public function killSelenium($host = 'localhost', $port = '4444')
{ {
@ -467,6 +503,8 @@ class RoboFile extends \Robo\Tasks
/** /**
* Run the phpmd tool * Run the phpmd tool
*
* @return void
*/ */
private function runPhpmd() private function runPhpmd()
{ {
@ -475,6 +513,8 @@ class RoboFile extends \Robo\Tasks
/** /**
* Run the phpcs tool * Run the phpcs tool
*
* @return void
*/ */
private function runPhpcs() private function runPhpcs()
{ {
@ -483,6 +523,8 @@ class RoboFile extends \Robo\Tasks
/** /**
* Run the phpcpd tool * Run the phpcpd tool
*
* @return void
*/ */
private function runPhpcpd() private function runPhpcpd()
{ {
@ -508,6 +550,8 @@ class RoboFile extends \Robo\Tasks
/** /**
* Executes all unit tests * Executes all unit tests
*
* @return void
*/ */
public function runUnit() public function runUnit()
{ {
@ -536,6 +580,107 @@ class RoboFile extends \Robo\Tasks
$this->_copy('jorobo.dist.ini', 'jorobo.ini'); $this->_copy('jorobo.dist.ini', 'jorobo.ini');
} }
(new \Joomla\Jorobo\Tasks\CopyrightHeader())->run(); (new \Joomla\Jorobo\Tasks\CopyrightHeader)->run();
}
/**
* Detect the correct driver for selenium
*
* @return string the webdriver string to use with selenium
*
* @since version
*/
public function getWebdriver()
{
$suiteConfig = $this->getSuiteConfig();
$codeceptMainConfig = \Codeception\Configuration::config();
$browser = $suiteConfig['modules']['config']['JoomlaBrowser']['browser'];
if ($browser == 'chrome')
{
$driver['type'] = 'webdriver.chrome.driver';
}
elseif ($browser == 'firefox')
{
$driver['type'] = 'webdriver.gecko.driver';
}
elseif ($browser == 'MicrosoftEdge')
{
$driver['type'] = 'webdriver.edge.driver';
// Check if we are using Windows Insider builds
if ($suiteConfig['modules']['config']['AcceptanceHelper']['MicrosoftEdgeInsiders'])
{
$browser = 'MicrosoftEdgeInsiders';
}
}
elseif ($browser == 'internet explorer')
{
$driver['type'] = 'webdriver.ie.driver';
}
// Check if we have a path for this browser and OS in the codeception settings
if (isset($codeceptMainConfig['webdrivers'][$browser][$this->getOs()]))
{
$driverPath = $codeceptMainConfig['webdrivers'][$browser][$this->getOs()];
}
else
{
$this->yell(
print_r($codeceptMainConfig) .
'No driver for your browser. Check your browser in acceptance.suite.yml and the webDrivers in codeception.yml');
// We can't do anything without a driver, exit
exit(1);
}
$driver['path'] = $driverPath;
return '-D' . implode('=', $driver);
}
/**
* Get the suite configuration
*
* @param string $suite The suite
*
* @return array
*/
private function getSuiteConfig($suite = 'acceptance')
{
if (!$this->suiteConfig)
{
$this->suiteConfig = Symfony\Component\Yaml\Yaml::parse(file_get_contents("tests/{$suite}.suite.yml"));
}
return $this->suiteConfig;
}
/**
* Return the os name
*
* @return string
*
* @since version
*/
private function getOs()
{
$os = php_uname('s');
if (strpos(strtolower($os), 'windows') !== false)
{
$os = 'windows';
}
// Who have thought that Mac is actually Darwin???
elseif (strpos(strtolower($os), 'darwin') !== false)
{
$os = 'mac';
}
else
{
$os = 'linux';
}
return $os;
} }
} }

View File

@ -8,3 +8,18 @@ settings:
bootstrap: _bootstrap.php bootstrap: _bootstrap.php
colors: true colors: true
memory_limit: 1024M memory_limit: 1024M
webdrivers:
firefox:
windows: vendor\joomla-projects\selenium-server-standalone\bin\webdrivers\gecko\geckodriver64.exe
mac: vendor/joomla-projects/selenium-server-standalone/bin/webdrivers/gecko/geckodriver_mac
linux: vendor/joomla-projects/selenium-server-standalone/bin/webdrivers/gecko/geckodriver_linux_64
chrome:
windows: vendor\joomla-projects\selenium-server-standalone\bin\webdrivers\chrome\chromedriver.exe
mac: vendor/joomla-projects/selenium-server-standalone/bin/webdrivers/chrome/chromedriver_mac
linux: vendor/joomla-projects/selenium-server-standalone/bin/webdrivers/chrome/chromedriver_linux_64
internet explorer:
windows: vendor\joomla-projects\selenium-server-standalone\bin\webdrivers\internet-explorer32\IEDriverServer.exe
MicrosoftEdge:
windows: vendor\joomla-projects\selenium-server-standalone\bin\webdrivers\edge\MicrosoftWebDriver.exe
MicrosoftEdgeInsiders:
windows: vendor\joomla-projects\selenium-server-standalone\bin\webdrivers\edge-insiders\MicrosoftWebDriver.exe

View File

@ -12,10 +12,10 @@
}, },
"require-dev": { "require-dev": {
"codeception/codeception": "^2.2", "codeception/codeception": "^2.2",
"joomla-projects/joomla-browser": "v3.6.0.1", "joomla-projects/joomla-browser": "v3.6.5.1",
"composition/robo": "~1", "composition/robo": "~1",
"joomla-projects/robo": "~0", "joomla-projects/robo": "~0",
"joomla-projects/selenium-server-standalone": "v2.53.1", "joomla-projects/selenium-server-standalone": "v3.0.1.2",
"fzaninotto/faker": "^1.6", "fzaninotto/faker": "^1.6",
"joomla-projects/jorobo": "~0.6", "joomla-projects/jorobo": "~0.6",
"Behat/Gherkin": "^4.4.1" "Behat/Gherkin": "^4.4.1"

View File

@ -7,8 +7,20 @@
* @license GNU General Public License version 2 or later; see LICENSE.txt * @license GNU General Public License version 2 or later; see LICENSE.txt
*/ */
/**
* Acceptance cest object class for admin steps
*
* @package Administrator
*
* @since 1.0
*/
class AdministratorWeblinksCest class AdministratorWeblinksCest
{ {
/**
* User constructor.
*
* @since version
*/
public function __construct() public function __construct()
{ {
$this->faker = Faker\Factory::create(); $this->faker = Faker\Factory::create();
@ -16,6 +28,15 @@ class AdministratorWeblinksCest
$this->url = $this->faker->url(); $this->url = $this->faker->url();
} }
/**
* Method to verify available tabs
*
* @param string $I The weblink object
*
* @since version
*
* @return void
*/
public function administratorVerifyAvailableTabs(\Step\Acceptance\weblink $I) public function administratorVerifyAvailableTabs(\Step\Acceptance\weblink $I)
{ {
$I->am('Administrator'); $I->am('Administrator');
@ -31,6 +52,15 @@ class AdministratorWeblinksCest
$I->verifyAvailableTabs(['New Web Link', 'Images', 'Publishing', 'Options', 'Metadata']); $I->verifyAvailableTabs(['New Web Link', 'Images', 'Publishing', 'Options', 'Metadata']);
} }
/**
* Method to create weblink
*
* @param string $I The weblink object
*
* @since version
*
* @return void
*/
public function administratorCreateWeblink(\Step\Acceptance\weblink $I) public function administratorCreateWeblink(\Step\Acceptance\weblink $I)
{ {
$I->am('Administrator'); $I->am('Administrator');
@ -58,7 +88,15 @@ class AdministratorWeblinksCest
} }
/** /**
* Method to trash weblink
*
* @param string $I The weblink object
*
* @since version
*
* @depends administratorCreateWeblink * @depends administratorCreateWeblink
*
* @return void
*/ */
public function administratorTrashWeblink(AcceptanceTester $I) public function administratorTrashWeblink(AcceptanceTester $I)
{ {
@ -69,24 +107,32 @@ class AdministratorWeblinksCest
$I->amGoingTo('Navigate to Weblinks page in /administrator/'); $I->amGoingTo('Navigate to Weblinks page in /administrator/');
$I->amOnPage('administrator/index.php?option=com_weblinks'); $I->amOnPage('administrator/index.php?option=com_weblinks');
$I->waitForText('Web Links','30',['css' => 'h1']); $I->waitForText('Web Links', '30', ['css' => 'h1']);
$I->expectTo('see weblinks page'); $I->expectTo('see weblinks page');
$I->amGoingTo('Search the just saved weblink'); $I->amGoingTo('Search the just saved weblink');
$I->searchForItem($this->title); $I->searchForItem($this->title);
$I->waitForText('Web Links','30',['css' => 'h1']); $I->waitForText('Web Links', '30', ['css' => 'h1']);
$I->amGoingTo('Delete the just saved weblink'); $I->amGoingTo('Delete the just saved weblink');
$I->checkAllResults(); $I->checkAllResults();
$I->clickToolbarButton('Trash'); $I->clickToolbarButton('Trash');
$I->waitForText('Web Links','30',['css' => 'h1']); $I->waitForText('Web Links', '30', ['css' => 'h1']);
$I->expectTo('see a success message and the weblink removed from the list'); $I->expectTo('see a success message and the weblink removed from the list');
$I->see('Web link successfully trashed',['id' => 'system-message-container']); $I->see('Web link successfully trashed', ['id' => 'system-message-container']);
$I->cantSee($this->title,['id' => 'weblinkList']); $I->cantSee($this->title, ['id' => 'weblinkList']);
} }
/** /**
* @depends administratorTrashWeblink * Method to delete weblink
*
* @param string $I The weblink object
*
* @since version
*
* @depends administratorCreateWeblink
*
* @return void
*/ */
public function administratorDeleteWeblink(AcceptanceTester $I) public function administratorDeleteWeblink(AcceptanceTester $I)
{ {
@ -97,44 +143,54 @@ class AdministratorWeblinksCest
$I->amGoingTo('Navigate to Weblinks page in /administrator/'); $I->amGoingTo('Navigate to Weblinks page in /administrator/');
$I->amOnPage('administrator/index.php?option=com_weblinks'); $I->amOnPage('administrator/index.php?option=com_weblinks');
$I->waitForText('Web Links','30',['css' => 'h1']); $I->waitForText('Web Links', '30', ['css' => 'h1']);
$I->expectTo('see weblinks page'); $I->expectTo('see weblinks page');
$I->click('Search Tools'); $I->click('Search Tools');
$I->wait(2); $I->wait(2);
$I->selectOptionInChosenById('filter_published', 'Trashed'); $I->selectOptionInChosenById('filter_published', 'Trashed');
$I->amGoingTo('Search the just saved weblink'); $I->amGoingTo('Search the just saved weblink');
$I->searchForItem($this->title); $I->searchForItem($this->title);
$I->waitForText('Web Links','30',['css' => 'h1']); $I->waitForText('Web Links', '30', ['css' => 'h1']);
$I->amGoingTo('Delete the just saved weblink'); $I->amGoingTo('Delete the just saved weblink');
$I->checkAllResults(); $I->checkAllResults();
$I->click(['xpath'=> '//div[@id="toolbar-delete"]/button']); $I->click(['xpath' => '//div[@id="toolbar-delete"]/button']);
$I->acceptPopup(); $I->acceptPopup();
$I->waitForText('Web Links','30',['css' => 'h1']); $I->waitForText('Web Links', '30', ['css' => 'h1']);
$I->expectTo('see a success message and the weblink removed from the list'); $I->expectTo('see a success message and the weblink removed from the list');
$I->see('1 web link successfully deleted.',['id' => 'system-message-container']); $I->see('1 web link successfully deleted.', ['id' => 'system-message-container']);
$I->cantSee($this->title,['id' => 'weblinkList']); $I->cantSee($this->title, ['id' => 'weblinkList']);
} }
/**
* Method to delete weblink
*
* @param string $I The weblink object
*
* @since version
*
* @depends administratorCreateWeblink
*
* @return void
*/
public function administratorCreateWeblinkWithoutTitleFails(AcceptanceTester $I) public function administratorCreateWeblinkWithoutTitleFails(AcceptanceTester $I)
{ {
$I->am('Administrator'); $I->am('Administrator');
$I->wantToTest('Weblink creation without title fails in /administrator/'); $I->wantToTest('Weblink creation without title fails in /administrator/');
$I->doAdministratorLogin(); $I->doAdministratorLogin();
$I->amGoingTo('Navigate to Weblinks page in /administrator/'); $I->amGoingTo('Navigate to Weblinks page in /administrator/');
$I->amOnPage('administrator/index.php?option=com_weblinks'); $I->amOnPage('administrator/index.php?option=com_weblinks');
$I->waitForText('Web Links','30',['css' => 'h1']); $I->waitForText('Web Links', '30', ['css' => 'h1']);
$I->expectTo('see weblinks page'); $I->expectTo('see weblinks page');
$I->checkForPhpNoticesOrWarnings(); $I->checkForPhpNoticesOrWarnings();
$I->amGoingTo('try to save a weblink with empty title and it should fail'); $I->amGoingTo('try to save a weblink with empty title and it should fail');
$I->click(['xpath'=> "//button[@onclick=\"Joomla.submitbutton('weblink.add')\"]"]); $I->click(['xpath' => "//div[@id='toolbar-new']//button"]);
$I->waitForText('Web Link: New','30',['css' => 'h1']); $I->waitForText('Web Link: New', '30', ['css' => 'h1']);
$I->click(['xpath'=> "//button[@onclick=\"Joomla.submitbutton('weblink.apply')\"]"]); $I->click(['xpath' => "//div[@id='toolbar-apply']//button"]);
$I->expectTo('see an error when trying to save a weblink without title and without URL'); $I->expectTo('see an error when trying to save a weblink without title and without URL');
$I->see('Invalid field: Title',['id' => 'system-message-container']); $I->see('Invalid field: Title', ['id' => 'system-message-container']);
$I->see('Invalid field: URL',['id' => 'system-message-container']); $I->see('Invalid field: URL', ['id' => 'system-message-container']);
} }
} }