diff --git a/src/JoomlaBrowser.php b/src/JoomlaBrowser.php
index 512f5c0..448968e 100644
--- a/src/JoomlaBrowser.php
+++ b/src/JoomlaBrowser.php
@@ -8,7 +8,11 @@
namespace Codeception\Module;
+use Codeception\Module\Locators\Locators;
use Codeception\Module\WebDriver;
+use Codeception\Lib\ModuleContainer;
+
+const TIMEOUT = 60;
/**
* Joomla Browser class to perform test suits for Joomla.
@@ -20,7 +24,8 @@ class JoomlaBrowser extends WebDriver
/**
* The module required fields, to be set in the suite .yml configuration file.
*
- * @var array
+ * @var array
+ * @since 3.0.0
*/
protected $requiredFields = array(
'url',
@@ -38,6 +43,63 @@ class JoomlaBrowser extends WebDriver
'language'
);
+ /**
+ * The locator
+ *
+ * @var Codeception\Module\Locators\Locators
+ * @since 3.7.4.2
+ */
+ protected $locator;
+
+ /**
+ * Module constructor.
+ *
+ * Requires module container (to provide access between modules of suite) and config.
+ *
+ * @param ModuleContainer $moduleContainer The module container
+ * @param array $config The optional config
+ *
+ * @since 3.7.4.2
+ */
+ public function __construct(ModuleContainer $moduleContainer, $config = null)
+ {
+ parent::__construct($moduleContainer, $config);
+
+ // Instantiate the locator
+ $this->instantiateLocator();
+ }
+
+ /**
+ * Function to instantiate the Locator Class, In case of a custom Template,
+ * path to the custom Template Locator could be passed in Acceptance.suite.yml file
+ *
+ * for example: If the Class is present at _support/Page/Acceptance folder, simple add a new Parameter in acceptance.suite.yml file
+ *
+ * locator class: 'Page\Acceptance\Bootstrap2TemplateLocators'
+ *
+ * Locator could be set to null like this
+ *
+ * locator class: null
+ *
+ * When set to null, Joomla Browser will use the custom Locators present inside Locators.php
+ *
+ * @return void
+ *
+ * @since 3.0.0
+ */
+ protected function instantiateLocator()
+ {
+ if (empty($this->config['locator class']))
+ {
+ $this->locator = new Locators;
+
+ return;
+ }
+
+ $class = $this->config['locator class'];
+ $this->locator = new $class;
+ }
+
/**
* Function to Do Admin Login In Joomla!
*
@@ -45,11 +107,10 @@ class JoomlaBrowser extends WebDriver
* @param string|null $password Optional password. If not passed the one in acceptance.suite.yml will be used
*
* @return void
+ * @since 3.0.0
*/
public function doAdministratorLogin($user = null, $password = null)
{
- $I = $this;
-
if (is_null($user))
{
$user = $this->config['username'];
@@ -61,18 +122,18 @@ public function doAdministratorLogin($user = null, $password = null)
}
$this->debug('I open Joomla Administrator Login Page');
- $I->amOnPage('/administrator/index.php');
- $I->waitForElement(['id' => 'mod-login-username'], 60);
+ $this->amOnPage($this->locator->adminLoginPageUrl);
+ $this->waitForElement($this->locator->adminLoginUserName, TIMEOUT);
$this->debug('Fill Username Text Field');
- $I->fillField(['id' => 'mod-login-username'], $user);
+ $this->fillField($this->locator->adminLoginUserName, $user);
$this->debug('Fill Password Text Field');
- $I->fillField(['id' => 'mod-login-password'], $password);
+ $this->fillField($this->locator->adminLoginPassword, $password);
// @todo: update login button in joomla login screen to make this xPath more friendly
$this->debug('I click Login button');
- $I->click(['xpath' => "//button[contains(normalize-space(), 'Log in')]"]);
+ $this->click($this->locator->adminLoginButton);
$this->debug('I wait to see Administrator Control Panel');
- $I->waitForText('Control Panel', 4, ['css' => 'h1.page-title']);
+ $this->waitForText('Control Panel', 4, $this->locator->controlPanelLocator);
}
/**
@@ -82,11 +143,10 @@ public function doAdministratorLogin($user = null, $password = null)
* @param string|null $password Optional password. If not passed the one in acceptance.suite.yml will be used
*
* @return void
+ * @since 3.0.0
*/
public function doFrontEndLogin($user = null, $password = null)
{
- $I = $this;
-
if (is_null($user))
{
$user = $this->config['username'];
@@ -98,148 +158,146 @@ public function doFrontEndLogin($user = null, $password = null)
}
$this->debug('I open Joomla Frontend Login Page');
- $I->amOnPage('/index.php?option=com_users&view=login');
+ $this->amOnPage($this->locator->frontEndLoginUrl);
$this->debug('Fill Username Text Field');
- $I->fillField(['id' => 'username'], $user);
+ $this->fillField($this->locator->loginUserName, $user);
$this->debug('Fill Password Text Field');
- $I->fillField(['id' => 'password'], $password);
+ $this->fillField($this->locator->loginPassword, $password);
// @todo: update login button in joomla login screen to make this xPath more friendly
$this->debug('I click Login button');
- $I->click(['xpath' => "//div[@class='login']/form/fieldset/div[4]/div/button"]);
+ $this->click($this->locator->loginButton);
$this->debug('I wait to see Frontend Member Profile Form with the Logout button in the module');
- $I->waitForElement(['xpath' => "//form[@id='login-form']/div[@class='logout-button']"], 60);
+
+ $this->waitForElement($this->locator->frontEndLoginSuccess, TIMEOUT);
}
/**
* Function to Do frontend Logout in Joomla!
*
* @return void
+ *
+ * @since 3.0.0
*/
public function doFrontendLogout()
{
- $I = $this;
$this->debug('I open Joomla Frontend Login Page');
- $I->amOnPage('/index.php?option=com_users&view=login');
+ $this->amOnPage($this->locator->frontEndLoginUrl);
$this->debug('I click Logout button');
- $I->click(['xpath' => "//div[@class='logout']//button[contains(text(), 'Log out')]"]);
- $I->amOnPage('/index.php?option=com_users&view=login');
+ $this->click($this->locator->frontEndLogoutButton);
+ $this->amOnPage('/index.php?option=com_users&view=login');
$this->debug('I wait to see Login form');
- $I->waitForElement(['xpath' => "//div[@class='login']//button[contains(text(), 'Log in')]"], 30);
- $I->seeElement(['xpath' => "//div[@class='login']//button[contains(text(), 'Log in')]"]);
+ $this->waitForElement($this->locator->frontEndLoginForm, 30);
+ $this->seeElement($this->locator->frontEndLoginForm);
}
/**
* Installs Joomla
*
* @return void
+ * @since 3.0.0
*/
public function installJoomla()
{
- $I = $this;
-
- // Install Joomla CMS');
-
$this->debug('I open Joomla Installation Configuration Page');
- $I->amOnPage('/installation/index.php');
+ $this->amOnPage('/installation/index.php');
$this->debug('I check that FTP tab is not present in installation. Otherwise it means that I have not enough '
- . 'permissions to install joomla and execution will be stoped');
- $I->dontSeeElement(['id' => 'ftp']);
+ . 'permissions to install joomla and execution will be stoped');
+ $this->dontSeeElement(['id' => 'ftp']);
// I Wait for the text Main Configuration, meaning that the page is loaded
$this->debug('I wait for Main Configuration');
- $I->waitForElement('#jform_language', 10);
- $I->debug('Wait for chosen to render the Languages list field');
- $I->wait(2);
- $I->debug('I select dk-DK as installation language');
+ $this->waitForElement('#jform_language', 10);
+ $this->debug('Wait for chosen to render the Languages list field');
+ $this->wait(2);
+ $this->debug('I select dk-DK as installation language');
// Select a random language to force reloading of the lang strings after selecting English
- $I->selectOptionInChosenWithTextField('#jform_language', 'Spanish (Español)');
- $I->waitForText('Configuración principal', 60, 'h3');
+ $this->selectOptionInChosenWithTextField('#jform_language', 'Spanish (Español)');
+ $this->waitForText('Configuración principal', TIMEOUT, 'h3');
// Wait for chosen to render the field
- $I->debug('I select en-GB as installation language');
- $I->debug('Wait for chosen to render the Languages list field');
- $I->wait(2);
- $I->selectOptionInChosenWithTextField('#jform_language', 'English (United Kingdom)');
- $I->waitForText('Main Configuration', 60, 'h3');
+ $this->debug('I select en-GB as installation language');
+ $this->debug('Wait for chosen to render the Languages list field');
+ $this->wait(2);
+ $this->selectOptionInChosenWithTextField('#jform_language', 'English (United Kingdom)');
+ $this->waitForText('Main Configuration', TIMEOUT, 'h3');
$this->debug('I fill Site Name');
- $I->fillField(['id' => 'jform_site_name'], 'Joomla CMS test');
+ $this->fillField(['id' => 'jform_site_name'], 'Joomla CMS test');
$this->debug('I fill Site Description');
- $I->fillField(['id' => 'jform_site_metadesc'], 'Site for testing Joomla CMS');
+ $this->fillField(['id' => 'jform_site_metadesc'], 'Site for testing Joomla CMS');
// I get the configuration from acceptance.suite.yml (see: tests/_support/acceptancehelper.php)
$this->debug('I fill Admin Email');
- $I->fillField(['id' => 'jform_admin_email'], $this->config['admin email']);
+ $this->fillField(['id' => 'jform_admin_email'], $this->config['admin email']);
$this->debug('I fill Admin Username');
- $I->fillField(['id' => 'jform_admin_user'], $this->config['username']);
+ $this->fillField(['id' => 'jform_admin_user'], $this->config['username']);
$this->debug('I fill Admin Password');
- $I->fillField(['id' => 'jform_admin_password'], $this->config['password']);
+ $this->fillField(['id' => 'jform_admin_password'], $this->config['password']);
$this->debug('I fill Admin Password Confirmation');
- $I->fillField(['id' => 'jform_admin_password2'], $this->config['password']);
+ $this->fillField(['id' => 'jform_admin_password2'], $this->config['password']);
$this->debug('I click Site Offline: no');
// ['No Site Offline']
- $I->click(['xpath' => "//fieldset[@id='jform_site_offline']/label[@for='jform_site_offline1']"]);
+ $this->click(['xpath' => "//fieldset[@id='jform_site_offline']/label[@for='jform_site_offline1']"]);
$this->debug('I click Next');
- $I->click(['link' => 'Next']);
+ $this->click(['link' => 'Next']);
$this->debug('I Fill the form for creating the Joomla site Database');
- $I->waitForText('Database Configuration', 60, ['css' => 'h3']);
+ $this->waitForText('Database Configuration', TIMEOUT, ['css' => 'h3']);
$this->debug('I select MySQLi');
- $I->selectOption(['id' => 'jform_db_type'], $this->config['database type']);
+ $this->selectOption(['id' => 'jform_db_type'], $this->config['database type']);
$this->debug('I fill Database Host');
- $I->fillField(['id' => 'jform_db_host'], $this->config['database host']);
+ $this->fillField(['id' => 'jform_db_host'], $this->config['database host']);
$this->debug('I fill Database User');
- $I->fillField(['id' => 'jform_db_user'], $this->config['database user']);
+ $this->fillField(['id' => 'jform_db_user'], $this->config['database user']);
$this->debug('I fill Database Password');
- $I->fillField(['id' => 'jform_db_pass'], $this->config['database password']);
+ $this->fillField(['id' => 'jform_db_pass'], $this->config['database password']);
$this->debug('I fill Database Name');
- $I->fillField(['id' => 'jform_db_name'], $this->config['database name']);
+ $this->fillField(['id' => 'jform_db_name'], $this->config['database name']);
$this->debug('I fill Database Prefix');
- $I->fillField(['id' => 'jform_db_prefix'], $this->config['database prefix']);
+ $this->fillField(['id' => 'jform_db_prefix'], $this->config['database prefix']);
$this->debug('I click Remove Old Database ');
- $I->selectOptionInRadioField('Old Database Process', 'Remove');
+ $this->selectOptionInRadioField('Old Database Process', 'Remove');
$this->debug('I click Next');
- $I->click(['link' => 'Next']);
+ $this->click(['link' => 'Next']);
$this->debug('I wait Joomla to remove the old database if exist');
- $I->wait(1);
- $I->waitForElementVisible(['id' => 'jform_sample_file-lbl'], 30);
+ $this->wait(1);
+ $this->waitForElementVisible(['id' => 'jform_sample_file-lbl'], 30);
$this->debug('I install joomla with or without sample data');
- $I->waitForText('Finalisation', 60, ['xpath' => '//h3']);
+ $this->waitForText('Finalisation', TIMEOUT, ['xpath' => '//h3']);
// @todo: installation of sample data needs to be created
// No sample data
- $I->selectOption(['id' => 'jform_sample_file'], ['id' => 'jform_sample_file0']);
- $I->click(['link' => 'Install']);
+ $this->selectOption(['id' => 'jform_sample_file'], ['id' => 'jform_sample_file0']);
+ $this->click(['link' => 'Install']);
// Wait while Joomla gets installed
$this->debug('I wait for Joomla being installed');
- $I->waitForText('Congratulations! Joomla! is now installed.', 60, ['xpath' => '//h3']);
+ $this->waitForText('Congratulations! Joomla! is now installed.', TIMEOUT, ['xpath' => '//h3']);
}
/**
* Install Joomla removing the Installation folder at the end of the execution
*
* @return void
+ * @since 3.0.0
*/
public function installJoomlaRemovingInstallationFolder()
{
- $I = $this;
-
- $I->installJoomla();
+ $this->installJoomla();
$this->debug('Removing Installation Folder');
- $I->click(['xpath' => "//input[@value='Remove installation folder']"]);
+ $this->click(['xpath' => "//input[@value='Remove installation folder']"]);
- $I->debug('I wait for Removing Installation Folder button to become disabled');
- $I->waitForJS("return jQuery('form#adminForm input[name=instDefault]').attr('disabled') == 'disabled';", 60);
+ $this->debug('I wait for Removing Installation Folder button to become disabled');
+ $this->waitForJS("return jQuery('form#adminForm input[name=instDefault]').attr('disabled') == 'disabled';", TIMEOUT);
- $I->debug('Joomla is now installed');
- $I->see('Congratulations! Joomla! is now installed.', ['xpath' => '//h3']);
+ $this->debug('Joomla is now installed');
+ $this->see('Congratulations! Joomla! is now installed.', ['xpath' => '//h3']);
}
/**
@@ -247,9 +305,10 @@ public function installJoomlaRemovingInstallationFolder()
*
* @param array $languages Array containing the language names to be installed
*
- * @example: $I->installJoomlaMultilingualSite(['Spanish', 'French']);
+ * @example: $this->installJoomlaMultilingualSite(['Spanish', 'French']);
*
* @return void
+ * @since 3.0.0
*/
public function installJoomlaMultilingualSite($languages = array())
{
@@ -259,61 +318,60 @@ public function installJoomlaMultilingualSite($languages = array())
$languages[] = 'French';
}
- $I = $this;
-
- $I->installJoomla();
+ $this->installJoomla();
$this->debug('I go to Install Languages page');
- $I->click(['id' => 'instLangs']);
- $I->waitForText('Install Language packages', 60, ['xpath' => '//h3']);
+ $this->click(['id' => 'instLangs']);
+ $this->waitForText('Install Language packages', TIMEOUT, ['xpath' => '//h3']);
foreach ($languages as $language)
{
- $I->debug('I mark the checkbox of the language: ' . $language);
- $I->click(['xpath' => "//label[contains(text()[normalize-space()], '$language')]"]);
+ $this->debug('I mark the checkbox of the language: ' . $language);
+ $this->click(['xpath' => "//label[contains(text()[normalize-space()], '$language')]"]);
}
- $I->click(['link' => 'Next']);
- $I->waitForText('Multilingual', 60, ['xpath' => '//h3']);
- $I->selectOptionInRadioField('Activate the multilingual feature', 'Yes');
- $I->waitForElementVisible(['id' => 'jform_activatePluginLanguageCode-lbl']);
- $I->selectOptionInRadioField('Install localised content', 'Yes');
- $I->selectOptionInRadioField('Enable the language code plugin', 'Yes');
- $I->click(['link' => 'Next']);
+ $this->click(['link' => 'Next']);
+ $this->waitForText('Multilingual', TIMEOUT, ['xpath' => '//h3']);
+ $this->selectOptionInRadioField('Activate the multilingual feature', 'Yes');
+ $this->waitForElementVisible(['id' => 'jform_activatePluginLanguageCode-lbl']);
+ $this->selectOptionInRadioField('Install localised content', 'Yes');
+ $this->selectOptionInRadioField('Enable the language code plugin', 'Yes');
+ $this->click(['link' => 'Next']);
- $I->waitForText('Congratulations! Joomla! is now installed.', 60, ['xpath' => '//h3']);
+ $this->waitForText('Congratulations! Joomla! is now installed.', TIMEOUT, ['xpath' => '//h3']);
$this->debug('Removing Installation Folder');
- $I->click(['xpath' => "//input[@value='Remove installation folder']"]);
+ $this->click(['xpath' => "//input[@value='Remove installation folder']"]);
// @todo https://github.com/joomla-projects/joomla-browser/issues/45
- $I->wait(2);
+ $this->wait(2);
$this->debug('Joomla is now installed');
- $I->see('Congratulations! Joomla! is now installed.', ['xpath' => '//h3']);
+ $this->see('Congratulations! Joomla! is now installed.', ['xpath' => '//h3']);
}
/**
- * Sets in Adminitrator->Global Configuration the Error reporting to Development
+ * Sets in Administrator->Global Configuration the Error reporting to Development
* {@internal doAdminLogin() before}
*
* @return void
+ *
+ * @since 3.0.0
*/
public function setErrorReportingToDevelopment()
{
- $I = $this;
$this->debug('I open Joomla Global Configuration Page');
- $I->amOnPage('/administrator/index.php?option=com_config');
+ $this->amOnPage('/administrator/index.php?option=com_config');
$this->debug('I wait for Global Configuration title');
- $I->waitForText('Global Configuration', 60, ['css' => '.page-title']);
+ $this->waitForText('Global Configuration', TIMEOUT, ['css' => '.page-title']);
$this->debug('I open the Server Tab');
- $I->click(['link' => 'Server']);
+ $this->click(['link' => 'Server']);
$this->debug('I wait for error reporting dropdown');
- $I->selectOptionInChosen('Error Reporting', 'Development');
+ $this->selectOptionInChosen('Error Reporting', 'Development');
$this->debug('I click on save');
- $I->click(['xpath' => "//div[@id='toolbar-apply']//button"]);
+ $this->click(['xpath' => "//div[@id='toolbar-apply']//button"]);
$this->debug('I wait for global configuration being saved');
- $I->waitForText('Global Configuration', 60, ['css' => '.page-title']);
- $I->see('Configuration saved.', ['id' => 'system-message-container']);
+ $this->waitForText('Global Configuration', TIMEOUT, ['css' => '.page-title']);
+ $this->see('Configuration saved.', ['id' => 'system-message-container']);
}
/**
@@ -326,7 +384,9 @@ public function setErrorReportingToDevelopment()
*
* @deprecated since Joomla 3.4.4-dev. Use installExtensionFromFolder($path, $type = 'Extension') instead.
*
- * @return void
+ * @return void
+ *
+ * @since 3.0.0
*/
public function installExtensionFromDirectory($path, $type = 'Extension')
{
@@ -343,17 +403,19 @@ public function installExtensionFromDirectory($path, $type = 'Extension')
* {@internal doAdminLogin() before}
*
* @return void
+ *
+ * @since 3.0.0
*/
public function installExtensionFromFolder($path, $type = 'Extension')
{
- $I = $this;
- $I->amOnPage('/administrator/index.php?option=com_installer');
- $I->waitForText('Extensions: Install', '30', ['css' => 'H1']);
- $I->click(['link' => 'Install from Folder']);
+
+ $this->amOnPage('/administrator/index.php?option=com_installer');
+ $this->waitForText('Extensions: Install', '30', ['css' => 'H1']);
+ $this->click(['link' => 'Install from Folder']);
$this->debug('I enter the Path');
- $I->fillField(['id' => 'install_directory'], $path);
- $I->click(['id' => 'installbutton_directory']);
- $I->waitForText('was successful', '60', ['id' => 'system-message-container']);
+ $this->fillField(['id' => 'install_directory'], $path);
+ $this->click(['id' => 'installbutton_directory']);
+ $this->waitForText('was successful', 'TIMEOUT', ['id' => 'system-message-container']);
$this->debug("$type successfully installed from $path");
}
@@ -366,17 +428,18 @@ public function installExtensionFromFolder($path, $type = 'Extension')
* {@internal doAdminLogin() before}
*
* @return void
+ *
+ * @since 3.0.0
*/
public function installExtensionFromUrl($url, $type = 'Extension')
{
- $I = $this;
- $I->amOnPage('/administrator/index.php?option=com_installer');
- $I->waitForText('Extensions: Install', '30', ['css' => 'H1']);
- $I->click(['link' => 'Install from URL']);
+ $this->amOnPage('/administrator/index.php?option=com_installer');
+ $this->waitForText('Extensions: Install', '30', ['css' => 'H1']);
+ $this->click(['link' => 'Install from URL']);
$this->debug('I enter the url');
- $I->fillField(['id' => 'install_url'], $url);
- $I->click(['id' => 'installbutton_url']);
- $I->waitForText('was successful', '30', ['id' => 'system-message-container']);
+ $this->fillField(['id' => 'install_url'], $url);
+ $this->click(['id' => 'installbutton_url']);
+ $this->waitForText('was successful', '30', ['id' => 'system-message-container']);
if ($type == 'Extension')
{
@@ -402,23 +465,23 @@ public function installExtensionFromUrl($url, $type = 'Extension')
* {@internal doAdminLogin() before}
*
* @return void
+ *
+ * @since 3.0.0
*/
public function checkForPhpNoticesOrWarnings($page = null)
{
- $I = $this;
-
if ($page)
{
- $I->amOnPage($page);
+ $this->amOnPage($page);
}
- $I->dontSeeInPageSource('Notice:');
- $I->dontSeeInPageSource('Notice:');
- $I->dontSeeInPageSource('Warning:');
- $I->dontSeeInPageSource('Warning:');
- $I->dontSeeInPageSource('Strict standards:');
- $I->dontSeeInPageSource('Strict standards:');
- $I->dontSeeInPageSource('The requested page can\'t be found');
+ $this->dontSeeInPageSource('Notice:');
+ $this->dontSeeInPageSource('Notice:');
+ $this->dontSeeInPageSource('Warning:');
+ $this->dontSeeInPageSource('Warning:');
+ $this->dontSeeInPageSource('Strict standards:');
+ $this->dontSeeInPageSource('Strict standards:');
+ $this->dontSeeInPageSource('The requested page can\'t be found');
}
/**
@@ -428,15 +491,17 @@ public function checkForPhpNoticesOrWarnings($page = null)
* @param string $option The text in the