<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.sandbox.joomla.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=FrankyD</id>
	<title>Joomla! Documentation - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.sandbox.joomla.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=FrankyD"/>
	<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/Special:Contributions/FrankyD"/>
	<updated>2026-05-13T18:36:22Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186615</id>
		<title>Testing Joomla Extensions with Codeception</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186615"/>
		<updated>2015-05-30T21:17:07Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: /* Getting started from scratch: what you need to download and install */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;nowiki&amp;gt;Note: this page is under construction&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What is Codeception? ==&lt;br /&gt;
Codeception PHP Testing Framework is designed to work just out of the box. This means its installation requires minimal steps and no external dependencies preinstalled (except PHP, of course). Only one configuration step should be taken and you are ready to test your web application from an eye of actual user.&lt;br /&gt;
&lt;br /&gt;
See the following video of codeception in action testing Joomla: &lt;br /&gt;
&lt;br /&gt;
{{#widget:YouTube|id=Vc1BJNnhsFM}}&lt;br /&gt;
&lt;br /&gt;
Codeception provides possibilities to do Unit Testing or to Test APIs, however this page is focused in &#039;&#039;&#039;System Testing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Why Use Codeception? ==&lt;br /&gt;
&#039;&#039;Why use Codeception when we already have Selenium IDE?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Codeception works great with Selenium. But with Codeception you can write your tests in PHP. The main reason is: Selenium IDE tests are tightly bound to XPath locators. If you ever change anything in layout tests will fall. Codeception locators are more stable. You can use names, labels, button names and CSS to match elements on page. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features&#039;&#039;&#039;&lt;br /&gt;
* Selenium WebDriver integration&lt;br /&gt;
* Elements matched by name, CSS, XPath&lt;br /&gt;
* PageObjects and StepObjects included&lt;br /&gt;
* Powered by PHPUnit&lt;br /&gt;
* Data Cleanup&lt;br /&gt;
* Parallel Execution of tests&lt;br /&gt;
* BDD-style readable tests&lt;br /&gt;
&lt;br /&gt;
== Architecture of a test ==&lt;br /&gt;
The testing framework is built on the three layered testing architecture&lt;br /&gt;
&lt;br /&gt;
=== Scenarios (Cept Class) ===&lt;br /&gt;
Cept or Test, it is the main class which contains steps of execution for the tests, Cept Class will call Step Class functions which will indirectly make use of page objects to perform operations&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I = new AcceptanceTester($scenario);&lt;br /&gt;
$I-&amp;gt;wantTo(&#039;Install Joomla CMS&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;http://localhost/installation/index.php&#039;);&lt;br /&gt;
// I Wait for the text Main Configuration, meaning that the page is loaded&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;Language Selector&#039;]);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;English (United Kingdom)&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Site Name&#039;, &#039;weblinks&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Description&#039;, &#039;Site for testing Weblinks component&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Email&#039;, $cfg[&#039;Admin email&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Username&#039;, $cfg[&#039;username&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Confirm Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;click(&#039;Next&#039;);&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page Objects ===&lt;br /&gt;
Each page on your application has a class which we call page objects, each page class will have information about the URL, fields, Text present on the page. We use the best possible selector for any field on the page.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginManagerPage&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * @var string Url of the page&lt;br /&gt;
	 */&lt;br /&gt;
	public static $URL = &#039;/administrator/index.php&#039;;&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Array of Page elements indexed by descriptive name or label&lt;br /&gt;
	 *&lt;br /&gt;
	 * @var array&lt;br /&gt;
	 */&lt;br /&gt;
	public static $elements = array(&lt;br /&gt;
		&#039;username&#039; =&amp;gt; &amp;quot;#mod-login-username&amp;quot;,&lt;br /&gt;
		&#039;password&#039; =&amp;gt; &amp;quot;#mod-login-password&amp;quot;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Naming convention for Page Objects ====&lt;br /&gt;
When this document is created Codeception 2.0 was not having a PSR-4 compatible autoloader. Therefore we are creating a convention so with the future Codeception 2.1 with PSR-4 compatible autoloader (https://github.com/Codeception/Codeception/pull/1228) we are creating a naming convention for Pages so it will cost us a small effort to move to autoloaded classes in the future.&lt;br /&gt;
&lt;br /&gt;
The naming convention works as follows:&lt;br /&gt;
&lt;br /&gt;
 APPLICATION (for example Joomla, Patchtester, Weblinks or your Extension name)&lt;br /&gt;
 + CLIENT (in Joomla we use it for defining if is Installation, Administrator or Frontend&lt;br /&gt;
 + CLIENT PART (In Joomla we use it following the menu are were it belongs: Components, Menus, System,...)&lt;br /&gt;
 + PAGE NAME (The Page name) &lt;br /&gt;
 + Page&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
 JoomlaAdministratorLoginPage&lt;br /&gt;
 JoomlaAdministratorSystemGlobalconfigurationPage&lt;br /&gt;
 JoomlaInstallationConfigurationPage&lt;br /&gt;
&lt;br /&gt;
And they are located with a folder estructure similar to:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_pages_folder_structure.png|framed|center|Folder estructure for Pages in System Tests]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remind that in Codeception 2.0 you need to specify each folder in the acceptance/_bootstrap.php file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
// Here you can initialize variables that will be available to your tests&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/installation&#039;);&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/administrator&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#PageObjects&lt;br /&gt;
&lt;br /&gt;
=== Step Objects ===&lt;br /&gt;
Step Objects are classes which contains steps which are to be executed on the application to perform certain operations, step objects make use of page objects to perform these actions.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginSteps extends \AcceptanceTester&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * Function to execute an Admin Login for Joomla 3&lt;br /&gt;
	 *&lt;br /&gt;
	 * @return void&lt;br /&gt;
	 */&lt;br /&gt;
	public function doAdministratorLogin($user, $password)&lt;br /&gt;
	{&lt;br /&gt;
		$I = $this;&lt;br /&gt;
		$I-&amp;gt;amOnPage(\JoomlaAdministratorLoginPage::$URL);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;username&#039;], $user);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;password&#039;], $password);&lt;br /&gt;
		$I-&amp;gt;click(&#039;Log in&#039;);&lt;br /&gt;
		$I-&amp;gt;see(&#039;Category Manager&#039;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#StepObjects&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Joomla Browser Module ===&lt;br /&gt;
The Joomla Browser is a Codeception Module that incorporates general functions to your tests like:&lt;br /&gt;
- do administrator login&lt;br /&gt;
- install joomla&lt;br /&gt;
- install extension&lt;br /&gt;
- ...&lt;br /&gt;
&lt;br /&gt;
Find details about it at: https://github.com/joomla-projects/joomla-browser#table-of-contents&lt;br /&gt;
&lt;br /&gt;
== Getting started from scratch: what you need to download and install ==&lt;br /&gt;
To get the test environment running you need to have several components installed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Very important:&#039;&#039;&#039; The downloaded GIT directory must be inside your htdocs folder of your local web-server. Otherwise the test will not work! The files from the &#039;weblinks&#039; folder must be loadable via your local web-server with your browser.&lt;br /&gt;
&lt;br /&gt;
=== local webserver ===&lt;br /&gt;
If you do not already have a local test server running you may want to check out:&lt;br /&gt;
https://www.mamp.info/&lt;br /&gt;
https://www.apachefriends.org/&lt;br /&gt;
http://www.ampps.com/&lt;br /&gt;
&lt;br /&gt;
If you are not familiar with a local web-server, learn that first before you advance futher. &lt;br /&gt;
&lt;br /&gt;
===Wget===&lt;br /&gt;
Wget is a command line program that retrieves content from web servers. For our purposes it is used to get selenium (browser test environment). See wikipedia: https://en.wikipedia.org/wiki/Wget&lt;br /&gt;
====Wget on Mac====&lt;br /&gt;
For Mac Users Homebrew (package manager for OS X) is a very easy way to get wget running. Download Homebrew at: http://brew.sh/ &lt;br /&gt;
After installation run the following command in your terminal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
brew install wget&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Java Runtime Environment (JRE) ===&lt;br /&gt;
The JRE has to be installed, so the tests will be executable. You find the recent versions at the Oracle Website.&lt;br /&gt;
In end of May 2015 this is: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html&lt;br /&gt;
later on that link could be obsolete and should be changed if there is a newer version out.&lt;br /&gt;
&lt;br /&gt;
Newer Mac OS Versions are not shipped any more with the JRE, so they have to download that too.&lt;br /&gt;
&lt;br /&gt;
=== Firefox ===&lt;br /&gt;
Selenium is testing in the browser Firefox. The selenium version is not that quick with the updates, as the Firefox browser, if the test is not executable, then it can be that you manually have to install an older version of Firefox.&lt;br /&gt;
Sadly that can be a try and error thing. To get older versions of Firefox: https://ftp.mozilla.org/pub/mozilla.org/firefox/releases/ here you will find many folders. Just try the first one that came before the Firefox version that you have been using (and that did not work). In the version folders you will find folders for all the different operating systems.&lt;br /&gt;
&lt;br /&gt;
‎&lt;br /&gt;
&lt;br /&gt;
=== configure test system variables ===&lt;br /&gt;
&lt;br /&gt;
[[File:Acceptance.suite.dist.yml rename.png|thumbnail|left|Screenshot of file structure]]&lt;br /&gt;
&lt;br /&gt;
In your the folder that you installed, downloaded, pulled (git) the project, you have to rename the &amp;quot;&#039;&#039;acceptance.suite.dist.yml&#039;&#039;&amp;quot; file to &amp;quot;&#039;&#039;acceptance.suite.yml&#039;&#039;&amp;quot; and configure the parameters to your system variables.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
   config:&lt;br /&gt;
        JoomlaBrowser:&lt;br /&gt;
            url: &#039;http://localhost/tests/joomla-cms3&#039;&lt;br /&gt;
            # the url that points to the joomla installation at /tests/system/joomla-cms&lt;br /&gt;
            browser: &#039;firefox&#039;&lt;br /&gt;
            window_size: 1024x768&lt;br /&gt;
    [...]&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
[[File:Run Command vendor bin robo test-acceptance.png|thumbnail|test:acceptance]]&lt;br /&gt;
Once your machine is able to run tests (see &#039;&#039;The Joomla Browser Module&#039;&#039;), you are able to start working.&lt;br /&gt;
&lt;br /&gt;
Check the contents of the /tests/ folder in weblinks and try to understand the structure of the tests.&lt;br /&gt;
For each function you have a directory and sometimes a configuration file, both will have the corresponding name.&lt;br /&gt;
* FunctionName.yml - these files contain configurations for the function folders&lt;br /&gt;
* FunctionName - contains the &#039;&#039;FunctionName&#039;&#039; test&lt;br /&gt;
* joomla-cms3 - contains the latest Joomla! installation&lt;br /&gt;
&lt;br /&gt;
After that check the tasks are at: https://github.com/joomla-extensions/weblinks/issues/47&lt;br /&gt;
&lt;br /&gt;
== The principles for writing a test: Readability and Performance ==&lt;br /&gt;
In Joomla we give priority to Readability over Performance, even when performance is a must.&lt;br /&gt;
&lt;br /&gt;
To explain that let me show an example: Let&#039;s say that we want to fill a field Username in a login form. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;administrator/index.php&amp;quot; method=&amp;quot;post&amp;quot; id=&amp;quot;form-login&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;username_field&amp;quot;&amp;gt;Username&amp;lt;/label&amp;gt;&lt;br /&gt;
  &amp;lt;input name=&amp;quot;username_field&amp;quot; tabindex=&amp;quot;1&amp;quot; id=&amp;quot;username_field&amp;quot; type=&amp;quot;text&amp;quot; size=&amp;quot;15&amp;quot; /&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the most performant way to fill that form field would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;#username_field&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And usually we would move that to a page object element ending in:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(\LoginPage::$username, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However Codeception is a smart framework and it adds some magic to it&#039;s methods (see: https://github.com/Codeception/Codeception/blob/2.0/src/Codeception/Module/WebDriver.php#L511-L513). It allows me to write more readable tests (keeping performance hight). &lt;br /&gt;
&lt;br /&gt;
If we do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Username&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Codeception will be smart and will search first in the page if there is any &amp;quot;LABEL&amp;quot; called Username. That is a fast operation, so performance will be affected just a little. And instead we have written less code than in previous examples.&lt;br /&gt;
&lt;br /&gt;
Note: sometimes this tricks are not always possible, labels are not always there or there are some elements hidden that shows and hides depending on a Javascript. All these special cases would require a Page element.&lt;br /&gt;
&lt;br /&gt;
Still there is a definitive method of using locators that made them readable and performant called: strict Locators see [[Testing_Joomla_Extensions_with_Codeception#Writting_reliable_locators]].&lt;br /&gt;
&lt;br /&gt;
With them we do: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField([&#039;id&#039; =&amp;gt; &#039;username_field&#039;], &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In conclusion we have more readable tests and less code to maintain while keeping performance. That is a win!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setting Up Codeception ==&lt;br /&gt;
=== setting up the repository ===&lt;br /&gt;
&#039;&#039;&#039;clone the directory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Fork [https://github.com/joomla-projects/com_localise com_localise]&lt;br /&gt;
# &lt;br /&gt;
# Git clone git@github.com:*your-github-profile-name*/com_localise.git&lt;br /&gt;
&lt;br /&gt;
=== Testing with Codeception ===&lt;br /&gt;
&lt;br /&gt;
There are two ways to get and run codeception, via PHAR or via Composer. Using &#039;&#039;&#039;Composer is recommended&#039;&#039;&#039; (because we are using in some tests the Codeception 2.1 development version not available in the composer.phar).&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Using Composer&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    You need to have Composer in your system, if not download it from here: https://getcomposer.org/&lt;br /&gt;
&lt;br /&gt;
    Step 1: composer update&lt;br /&gt;
&lt;br /&gt;
    Step 2: run Codeception by doing: php vendor/bin/codecept build&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Codeception.phar&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    Linux Machine  : wget http://codeception.com/codecept.phar&lt;br /&gt;
&lt;br /&gt;
    Windows Machine: Download from [http://codeception.com/install codecept.phar]&lt;br /&gt;
&lt;br /&gt;
    Step1 : php ./codecept.phar build&lt;br /&gt;
&lt;br /&gt;
=== Running the Test ===&lt;br /&gt;
Run Selenium server&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Download&lt;br /&gt;
curl -O http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&lt;br /&gt;
# And start the Selenium Server&lt;br /&gt;
java -Xms40m -Xmx256m -jar /Applications/XAMPP/xamppfiles/htdocs/selenium/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Rename tests/acceptance.suite.dist.yml to tests/acceptance.suite.yml&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 1: Modify the configuration at tests/acceptance.suite.yml to fit your server details.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 2: php codecept.phar run&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
with --steps to see a step-by-step report on the performed actions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --steps&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with --html. This command will run all tests for all suites, displaying the steps, and building HTML and XML reports. Reports will be store in tests/_output/ directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --html&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To activate the debug mode in Codeception just add the parameter --debug when you run the tests:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run acceptance --debug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Best Practices at Testing ==&lt;br /&gt;
=== Writting reliable locators ===&lt;br /&gt;
Writing good locators can be tricky. The Mozilla team has written an excellent guide titled [https://blog.mozilla.org/webqa/2013/09/26/writing-reliable-locators-for-selenium-and-webdriver-tests/ Writing reliable locators for Selenium and WebDriver tests].&lt;br /&gt;
&lt;br /&gt;
If the locator is an array, it should have a single element, with the key signifying the locator type (`id`, `name`, `css`, `xpath`, `link`, or `class`) and the value being the locator itself. This is called a &amp;quot;strict&amp;quot; locator. Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* [&#039;id&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div id=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;name&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div name=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;css&#039; =&amp;gt; &#039;input[type=input][value=foo]&#039;] matches `&amp;lt;input type=&amp;quot;input&amp;quot; value=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;xpath&#039; =&amp;gt; &amp;quot;//input[@type=&#039;submit&#039;][contains(@value, &#039;foo&#039;)]&amp;quot;] matches `&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;foobar&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;link&#039; =&amp;gt; &#039;Click here&#039;] matches `&amp;lt;a href=&amp;quot;google.com&amp;quot;&amp;gt;Click here&amp;lt;/a&amp;gt;`&lt;br /&gt;
* [&#039;class&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div class=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
=== How to use URLs ===&lt;br /&gt;
Codeception documentation suggests to use URL&#039;s as properties of a Page Object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(JoomlaInstallationConfigurationPage::$URL);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of hardcoding the url in the test:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The pros of this approach is:&lt;br /&gt;
- first way is more readable for non developers. &lt;br /&gt;
- it helps to make tests more maintenable in the case of a url change in the system&lt;br /&gt;
&lt;br /&gt;
However in joomla a change in an url is rare, and if it happens changing it will just be a Find&amp;amp;Replace task. I Joomla test we want to have the benefit of both, the url and a representative name that describes the page where we are going. That will make our tests more readable. Thus, we will write the urls the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amGoingTo(&#039;go to Create New Banner page at Joomla Administrator&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Working with Hidden Elements ===&lt;br /&gt;
Selenium can&#039;t interact with elements that are not visible:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;http://www.joomla.org&amp;quot; style=&amp;quot;display: none;&amp;quot; id=&amp;quot;joomla_site&amp;quot;&amp;gt;go to joomla&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case you can&#039;t do:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually this happens when you need to wait for a Javascript animation that end up showing that element, so in this case you will need to do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForElementVisible(&#039;#joomla_site&#039;);&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== When do not use contains ===&lt;br /&gt;
We do not recommend to use the function contains on XPath because is not specific and can create false positives at tests.&lt;br /&gt;
See: https://github.com/joomla-projects/GSOC-Webdriver_system_tests_for_CMS/pull/99#issuecomment-69004191&lt;br /&gt;
=== Always add Strict Locators to your tests ===&lt;br /&gt;
Performance in tests is very important. You can reduce dramatically the time spent on a test with just adding a few extra locators. For example, the following code pertains to a test:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// see($text, $selector = null)&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the previous code we are not facilitating the &amp;quot;Selector&amp;quot; so Codeception will have to search for the element in all the HTML. Doing this instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the tests went from: Time: 1.17 minutes&lt;br /&gt;
to: Time: 49.18 seconds&lt;br /&gt;
&lt;br /&gt;
You can see this video of a real example: http://www.youtube.com/watch?v=0JCv0BR2yZY&lt;br /&gt;
&lt;br /&gt;
Losing 30 seconds in every Assertion can delay your tests dramatically. Therefore, remind always to add xPath locators to all your Assertions.&lt;br /&gt;
[[Category:Automated Testing]]&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;see ====&lt;br /&gt;
Do not use &#039;&#039;see&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;waitForText ====&lt;br /&gt;
Do not use &#039;&#039;waitForText&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;, 10, [&#039;css&#039; =&amp;gt; &#039;h3&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Incase of an element has multiple css classes, When Using CSS Locators make sure you use more specific class as locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert-success&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
A page could have mutiple elements which can have &#039;&#039;alert&#039;&#039; css class associated, hence being more specific helps.&lt;br /&gt;
&lt;br /&gt;
==== How much time should I wait for an Element or Text? ====&lt;br /&gt;
You may have noticed that the second parameter in the I waitForText is an integer that represents how much &amp;quot;time to wait&amp;quot; in seconds:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;a text to wait for&#039;, 10, [&#039;...&#039; =&amp;gt; &#039;...&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But, how much time is the right time to wait for a text?&lt;br /&gt;
&lt;br /&gt;
PHP maximum execution time before returning a Fatal Error for timeout is set by default to 30 seconds. We suggest to set it for 10 seconds. A waitForText over 10 seconds will definitely mean that something is not performing well.&lt;br /&gt;
&lt;br /&gt;
=== Quote and Double Quotes in Compex XPaths ===&lt;br /&gt;
Sometimes you will have to write XPaths that looks like:&lt;br /&gt;
&lt;br /&gt;
 //button[@onclick=&#039;Joomla.submitbutton(&amp;quot;config.save.application.apply&amp;quot;)&#039;]&lt;br /&gt;
&lt;br /&gt;
When moved to a Page Object you will probably will face this situation:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_error_escaping_quotes_on_xpaths.png|framed|center|Typical issue when you write a long XPath in a Page object]]&lt;br /&gt;
&lt;br /&gt;
To avoid it remind to escape the quotes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
// Right&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=\&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)\&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Generating txt/html scenarios===&lt;br /&gt;
Codeception allows you to generate user-friendly text scenarios from scenario-driven from Cest and Cept php test (see http://codeception.com/docs/reference/Commands#GenerateScenarios).&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t use double quotes, use single quotes instead===&lt;br /&gt;
Do not use double quotes (&amp;quot;) for surrounding strings:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &amp;quot;&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;&amp;quot;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you use single quotes instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Congratulations! Joomla! is now installed.&#039;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will get the right expected result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Congratulations! Joomla! is now installed.&#039;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The reason of not being able to use double quotes is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;br /&gt;
&lt;br /&gt;
===Do not leave spaces between parameters in Cepts===&lt;br /&gt;
See the two lines:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
// Good&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;,10,&#039;h3&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Main Configuration&#039;,&amp;quot; 10&amp;quot;,&amp;quot; &#039;h3&#039;&lt;br /&gt;
&lt;br /&gt;
The reason that you are asked to not add spaces between parameters is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186614</id>
		<title>Testing Joomla Extensions with Codeception</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186614"/>
		<updated>2015-05-30T21:07:39Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: /* Getting started from scratch: what you need to download and install */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;nowiki&amp;gt;Note: this page is under construction&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What is Codeception? ==&lt;br /&gt;
Codeception PHP Testing Framework is designed to work just out of the box. This means its installation requires minimal steps and no external dependencies preinstalled (except PHP, of course). Only one configuration step should be taken and you are ready to test your web application from an eye of actual user.&lt;br /&gt;
&lt;br /&gt;
See the following video of codeception in action testing Joomla: &lt;br /&gt;
&lt;br /&gt;
{{#widget:YouTube|id=Vc1BJNnhsFM}}&lt;br /&gt;
&lt;br /&gt;
Codeception provides possibilities to do Unit Testing or to Test APIs, however this page is focused in &#039;&#039;&#039;System Testing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Why Use Codeception? ==&lt;br /&gt;
&#039;&#039;Why use Codeception when we already have Selenium IDE?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Codeception works great with Selenium. But with Codeception you can write your tests in PHP. The main reason is: Selenium IDE tests are tightly bound to XPath locators. If you ever change anything in layout tests will fall. Codeception locators are more stable. You can use names, labels, button names and CSS to match elements on page. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features&#039;&#039;&#039;&lt;br /&gt;
* Selenium WebDriver integration&lt;br /&gt;
* Elements matched by name, CSS, XPath&lt;br /&gt;
* PageObjects and StepObjects included&lt;br /&gt;
* Powered by PHPUnit&lt;br /&gt;
* Data Cleanup&lt;br /&gt;
* Parallel Execution of tests&lt;br /&gt;
* BDD-style readable tests&lt;br /&gt;
&lt;br /&gt;
== Architecture of a test ==&lt;br /&gt;
The testing framework is built on the three layered testing architecture&lt;br /&gt;
&lt;br /&gt;
=== Scenarios (Cept Class) ===&lt;br /&gt;
Cept or Test, it is the main class which contains steps of execution for the tests, Cept Class will call Step Class functions which will indirectly make use of page objects to perform operations&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I = new AcceptanceTester($scenario);&lt;br /&gt;
$I-&amp;gt;wantTo(&#039;Install Joomla CMS&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;http://localhost/installation/index.php&#039;);&lt;br /&gt;
// I Wait for the text Main Configuration, meaning that the page is loaded&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;Language Selector&#039;]);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;English (United Kingdom)&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Site Name&#039;, &#039;weblinks&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Description&#039;, &#039;Site for testing Weblinks component&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Email&#039;, $cfg[&#039;Admin email&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Username&#039;, $cfg[&#039;username&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Confirm Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;click(&#039;Next&#039;);&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page Objects ===&lt;br /&gt;
Each page on your application has a class which we call page objects, each page class will have information about the URL, fields, Text present on the page. We use the best possible selector for any field on the page.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginManagerPage&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * @var string Url of the page&lt;br /&gt;
	 */&lt;br /&gt;
	public static $URL = &#039;/administrator/index.php&#039;;&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Array of Page elements indexed by descriptive name or label&lt;br /&gt;
	 *&lt;br /&gt;
	 * @var array&lt;br /&gt;
	 */&lt;br /&gt;
	public static $elements = array(&lt;br /&gt;
		&#039;username&#039; =&amp;gt; &amp;quot;#mod-login-username&amp;quot;,&lt;br /&gt;
		&#039;password&#039; =&amp;gt; &amp;quot;#mod-login-password&amp;quot;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Naming convention for Page Objects ====&lt;br /&gt;
When this document is created Codeception 2.0 was not having a PSR-4 compatible autoloader. Therefore we are creating a convention so with the future Codeception 2.1 with PSR-4 compatible autoloader (https://github.com/Codeception/Codeception/pull/1228) we are creating a naming convention for Pages so it will cost us a small effort to move to autoloaded classes in the future.&lt;br /&gt;
&lt;br /&gt;
The naming convention works as follows:&lt;br /&gt;
&lt;br /&gt;
 APPLICATION (for example Joomla, Patchtester, Weblinks or your Extension name)&lt;br /&gt;
 + CLIENT (in Joomla we use it for defining if is Installation, Administrator or Frontend&lt;br /&gt;
 + CLIENT PART (In Joomla we use it following the menu are were it belongs: Components, Menus, System,...)&lt;br /&gt;
 + PAGE NAME (The Page name) &lt;br /&gt;
 + Page&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
 JoomlaAdministratorLoginPage&lt;br /&gt;
 JoomlaAdministratorSystemGlobalconfigurationPage&lt;br /&gt;
 JoomlaInstallationConfigurationPage&lt;br /&gt;
&lt;br /&gt;
And they are located with a folder estructure similar to:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_pages_folder_structure.png|framed|center|Folder estructure for Pages in System Tests]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remind that in Codeception 2.0 you need to specify each folder in the acceptance/_bootstrap.php file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
// Here you can initialize variables that will be available to your tests&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/installation&#039;);&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/administrator&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#PageObjects&lt;br /&gt;
&lt;br /&gt;
=== Step Objects ===&lt;br /&gt;
Step Objects are classes which contains steps which are to be executed on the application to perform certain operations, step objects make use of page objects to perform these actions.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginSteps extends \AcceptanceTester&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * Function to execute an Admin Login for Joomla 3&lt;br /&gt;
	 *&lt;br /&gt;
	 * @return void&lt;br /&gt;
	 */&lt;br /&gt;
	public function doAdministratorLogin($user, $password)&lt;br /&gt;
	{&lt;br /&gt;
		$I = $this;&lt;br /&gt;
		$I-&amp;gt;amOnPage(\JoomlaAdministratorLoginPage::$URL);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;username&#039;], $user);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;password&#039;], $password);&lt;br /&gt;
		$I-&amp;gt;click(&#039;Log in&#039;);&lt;br /&gt;
		$I-&amp;gt;see(&#039;Category Manager&#039;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#StepObjects&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Joomla Browser Module ===&lt;br /&gt;
The Joomla Browser is a Codeception Module that incorporates general functions to your tests like:&lt;br /&gt;
- do administrator login&lt;br /&gt;
- install joomla&lt;br /&gt;
- install extension&lt;br /&gt;
- ...&lt;br /&gt;
&lt;br /&gt;
Find details about it at: https://github.com/joomla-projects/joomla-browser#table-of-contents&lt;br /&gt;
&lt;br /&gt;
== Getting started from scratch: what you need to download and install ==&lt;br /&gt;
To get the test environment running you need to have several components installed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Very important:&#039;&#039;&#039; The downloaded GIT directory must be inside your htdocs folder of your local web-server. Otherwise the test will not work! The files from the &#039;weblinks&#039; folder must be loadable via your local web-server.&lt;br /&gt;
&lt;br /&gt;
=== local webserver ===&lt;br /&gt;
If you do not already have a local test server running you may want to check out:&lt;br /&gt;
https://www.mamp.info/&lt;br /&gt;
https://www.apachefriends.org/&lt;br /&gt;
http://www.ampps.com/&lt;br /&gt;
&lt;br /&gt;
If you are not familiar with a local web-server, learn that first before you advance futher. &lt;br /&gt;
&lt;br /&gt;
===Wget===&lt;br /&gt;
Wget is a command line program that retrieves content from web servers. For our purposes it is used to get selenium (browser test environment). See wikipedia: https://en.wikipedia.org/wiki/Wget&lt;br /&gt;
====Wget on Mac====&lt;br /&gt;
For Mac Users Homebrew (package manager for OS X) is a very easy way to get wget running. Download Homebrew at: http://brew.sh/ &lt;br /&gt;
After installation run the following command in your terminal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
brew install wget&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Java Runtime Environment (JRE) ===&lt;br /&gt;
The JRE has to be installed, so the tests will be executable. You find the recent versions at the Oracle Website.&lt;br /&gt;
In end of May 2015 this is: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html&lt;br /&gt;
later on that link could be obsolete and should be changed if there is a newer version out.&lt;br /&gt;
&lt;br /&gt;
Newer Mac OS Versions are not shipped any more with the JRE, so they have to download that too.&lt;br /&gt;
&lt;br /&gt;
=== Firefox ===&lt;br /&gt;
Selenium is testing in the browser Firefox. The selenium version is not that quick with the updates, as the Firefox browser, if the test is not executable, then it can be that you manually have to install an older version of Firefox.&lt;br /&gt;
Sadly that can be a try and error thing. To get older versions of Firefox: https://ftp.mozilla.org/pub/mozilla.org/firefox/releases/ here you will find many folders. Just try the first one that came before the Firefox version that you have been using (and that did not work). In the version folders you will find folders for all the different operating systems.&lt;br /&gt;
&lt;br /&gt;
‎&lt;br /&gt;
&lt;br /&gt;
=== configure test system variables ===&lt;br /&gt;
&lt;br /&gt;
[[File:Acceptance.suite.dist.yml rename.png|thumbnail|left|Screenshot of file structure]]&lt;br /&gt;
&lt;br /&gt;
In your the folder that you installed, downloaded, pulled (git) the project, you have to rename the &amp;quot;&#039;&#039;acceptance.suite.dist.yml&#039;&#039;&amp;quot; file to &amp;quot;&#039;&#039;acceptance.suite.yml&#039;&#039;&amp;quot; and configure the parameters to your system variables.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
   config:&lt;br /&gt;
        JoomlaBrowser:&lt;br /&gt;
            url: &#039;http://localhost/tests/joomla-cms3&#039;&lt;br /&gt;
            # the url that points to the joomla installation at /tests/system/joomla-cms&lt;br /&gt;
            browser: &#039;firefox&#039;&lt;br /&gt;
            window_size: 1024x768&lt;br /&gt;
    [...]&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
[[File:Run Command vendor bin robo test-acceptance.png|thumbnail|test:acceptance]]&lt;br /&gt;
Once your machine is able to run tests (see &#039;&#039;The Joomla Browser Module&#039;&#039;), you are able to start working.&lt;br /&gt;
&lt;br /&gt;
Check the contents of the /tests/ folder in weblinks and try to understand the structure of the tests.&lt;br /&gt;
For each function you have a directory and sometimes a configuration file, both will have the corresponding name.&lt;br /&gt;
* FunctionName.yml - these files contain configurations for the function folders&lt;br /&gt;
* FunctionName - contains the &#039;&#039;FunctionName&#039;&#039; test&lt;br /&gt;
* joomla-cms3 - contains the latest Joomla! installation&lt;br /&gt;
&lt;br /&gt;
After that check the tasks are at: https://github.com/joomla-extensions/weblinks/issues/47&lt;br /&gt;
&lt;br /&gt;
== The principles for writing a test: Readability and Performance ==&lt;br /&gt;
In Joomla we give priority to Readability over Performance, even when performance is a must.&lt;br /&gt;
&lt;br /&gt;
To explain that let me show an example: Let&#039;s say that we want to fill a field Username in a login form. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;administrator/index.php&amp;quot; method=&amp;quot;post&amp;quot; id=&amp;quot;form-login&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;username_field&amp;quot;&amp;gt;Username&amp;lt;/label&amp;gt;&lt;br /&gt;
  &amp;lt;input name=&amp;quot;username_field&amp;quot; tabindex=&amp;quot;1&amp;quot; id=&amp;quot;username_field&amp;quot; type=&amp;quot;text&amp;quot; size=&amp;quot;15&amp;quot; /&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the most performant way to fill that form field would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;#username_field&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And usually we would move that to a page object element ending in:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(\LoginPage::$username, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However Codeception is a smart framework and it adds some magic to it&#039;s methods (see: https://github.com/Codeception/Codeception/blob/2.0/src/Codeception/Module/WebDriver.php#L511-L513). It allows me to write more readable tests (keeping performance hight). &lt;br /&gt;
&lt;br /&gt;
If we do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Username&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Codeception will be smart and will search first in the page if there is any &amp;quot;LABEL&amp;quot; called Username. That is a fast operation, so performance will be affected just a little. And instead we have written less code than in previous examples.&lt;br /&gt;
&lt;br /&gt;
Note: sometimes this tricks are not always possible, labels are not always there or there are some elements hidden that shows and hides depending on a Javascript. All these special cases would require a Page element.&lt;br /&gt;
&lt;br /&gt;
Still there is a definitive method of using locators that made them readable and performant called: strict Locators see [[Testing_Joomla_Extensions_with_Codeception#Writting_reliable_locators]].&lt;br /&gt;
&lt;br /&gt;
With them we do: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField([&#039;id&#039; =&amp;gt; &#039;username_field&#039;], &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In conclusion we have more readable tests and less code to maintain while keeping performance. That is a win!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setting Up Codeception ==&lt;br /&gt;
=== setting up the repository ===&lt;br /&gt;
&#039;&#039;&#039;clone the directory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Fork [https://github.com/joomla-projects/com_localise com_localise]&lt;br /&gt;
# &lt;br /&gt;
# Git clone git@github.com:*your-github-profile-name*/com_localise.git&lt;br /&gt;
&lt;br /&gt;
=== Testing with Codeception ===&lt;br /&gt;
&lt;br /&gt;
There are two ways to get and run codeception, via PHAR or via Composer. Using &#039;&#039;&#039;Composer is recommended&#039;&#039;&#039; (because we are using in some tests the Codeception 2.1 development version not available in the composer.phar).&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Using Composer&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    You need to have Composer in your system, if not download it from here: https://getcomposer.org/&lt;br /&gt;
&lt;br /&gt;
    Step 1: composer update&lt;br /&gt;
&lt;br /&gt;
    Step 2: run Codeception by doing: php vendor/bin/codecept build&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Codeception.phar&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    Linux Machine  : wget http://codeception.com/codecept.phar&lt;br /&gt;
&lt;br /&gt;
    Windows Machine: Download from [http://codeception.com/install codecept.phar]&lt;br /&gt;
&lt;br /&gt;
    Step1 : php ./codecept.phar build&lt;br /&gt;
&lt;br /&gt;
=== Running the Test ===&lt;br /&gt;
Run Selenium server&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Download&lt;br /&gt;
curl -O http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&lt;br /&gt;
# And start the Selenium Server&lt;br /&gt;
java -Xms40m -Xmx256m -jar /Applications/XAMPP/xamppfiles/htdocs/selenium/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Rename tests/acceptance.suite.dist.yml to tests/acceptance.suite.yml&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 1: Modify the configuration at tests/acceptance.suite.yml to fit your server details.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 2: php codecept.phar run&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
with --steps to see a step-by-step report on the performed actions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --steps&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with --html. This command will run all tests for all suites, displaying the steps, and building HTML and XML reports. Reports will be store in tests/_output/ directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --html&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To activate the debug mode in Codeception just add the parameter --debug when you run the tests:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run acceptance --debug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Best Practices at Testing ==&lt;br /&gt;
=== Writting reliable locators ===&lt;br /&gt;
Writing good locators can be tricky. The Mozilla team has written an excellent guide titled [https://blog.mozilla.org/webqa/2013/09/26/writing-reliable-locators-for-selenium-and-webdriver-tests/ Writing reliable locators for Selenium and WebDriver tests].&lt;br /&gt;
&lt;br /&gt;
If the locator is an array, it should have a single element, with the key signifying the locator type (`id`, `name`, `css`, `xpath`, `link`, or `class`) and the value being the locator itself. This is called a &amp;quot;strict&amp;quot; locator. Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* [&#039;id&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div id=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;name&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div name=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;css&#039; =&amp;gt; &#039;input[type=input][value=foo]&#039;] matches `&amp;lt;input type=&amp;quot;input&amp;quot; value=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;xpath&#039; =&amp;gt; &amp;quot;//input[@type=&#039;submit&#039;][contains(@value, &#039;foo&#039;)]&amp;quot;] matches `&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;foobar&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;link&#039; =&amp;gt; &#039;Click here&#039;] matches `&amp;lt;a href=&amp;quot;google.com&amp;quot;&amp;gt;Click here&amp;lt;/a&amp;gt;`&lt;br /&gt;
* [&#039;class&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div class=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
=== How to use URLs ===&lt;br /&gt;
Codeception documentation suggests to use URL&#039;s as properties of a Page Object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(JoomlaInstallationConfigurationPage::$URL);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of hardcoding the url in the test:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The pros of this approach is:&lt;br /&gt;
- first way is more readable for non developers. &lt;br /&gt;
- it helps to make tests more maintenable in the case of a url change in the system&lt;br /&gt;
&lt;br /&gt;
However in joomla a change in an url is rare, and if it happens changing it will just be a Find&amp;amp;Replace task. I Joomla test we want to have the benefit of both, the url and a representative name that describes the page where we are going. That will make our tests more readable. Thus, we will write the urls the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amGoingTo(&#039;go to Create New Banner page at Joomla Administrator&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Working with Hidden Elements ===&lt;br /&gt;
Selenium can&#039;t interact with elements that are not visible:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;http://www.joomla.org&amp;quot; style=&amp;quot;display: none;&amp;quot; id=&amp;quot;joomla_site&amp;quot;&amp;gt;go to joomla&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case you can&#039;t do:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually this happens when you need to wait for a Javascript animation that end up showing that element, so in this case you will need to do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForElementVisible(&#039;#joomla_site&#039;);&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== When do not use contains ===&lt;br /&gt;
We do not recommend to use the function contains on XPath because is not specific and can create false positives at tests.&lt;br /&gt;
See: https://github.com/joomla-projects/GSOC-Webdriver_system_tests_for_CMS/pull/99#issuecomment-69004191&lt;br /&gt;
=== Always add Strict Locators to your tests ===&lt;br /&gt;
Performance in tests is very important. You can reduce dramatically the time spent on a test with just adding a few extra locators. For example, the following code pertains to a test:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// see($text, $selector = null)&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the previous code we are not facilitating the &amp;quot;Selector&amp;quot; so Codeception will have to search for the element in all the HTML. Doing this instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the tests went from: Time: 1.17 minutes&lt;br /&gt;
to: Time: 49.18 seconds&lt;br /&gt;
&lt;br /&gt;
You can see this video of a real example: http://www.youtube.com/watch?v=0JCv0BR2yZY&lt;br /&gt;
&lt;br /&gt;
Losing 30 seconds in every Assertion can delay your tests dramatically. Therefore, remind always to add xPath locators to all your Assertions.&lt;br /&gt;
[[Category:Automated Testing]]&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;see ====&lt;br /&gt;
Do not use &#039;&#039;see&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;waitForText ====&lt;br /&gt;
Do not use &#039;&#039;waitForText&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;, 10, [&#039;css&#039; =&amp;gt; &#039;h3&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Incase of an element has multiple css classes, When Using CSS Locators make sure you use more specific class as locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert-success&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
A page could have mutiple elements which can have &#039;&#039;alert&#039;&#039; css class associated, hence being more specific helps.&lt;br /&gt;
&lt;br /&gt;
==== How much time should I wait for an Element or Text? ====&lt;br /&gt;
You may have noticed that the second parameter in the I waitForText is an integer that represents how much &amp;quot;time to wait&amp;quot; in seconds:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;a text to wait for&#039;, 10, [&#039;...&#039; =&amp;gt; &#039;...&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But, how much time is the right time to wait for a text?&lt;br /&gt;
&lt;br /&gt;
PHP maximum execution time before returning a Fatal Error for timeout is set by default to 30 seconds. We suggest to set it for 10 seconds. A waitForText over 10 seconds will definitely mean that something is not performing well.&lt;br /&gt;
&lt;br /&gt;
=== Quote and Double Quotes in Compex XPaths ===&lt;br /&gt;
Sometimes you will have to write XPaths that looks like:&lt;br /&gt;
&lt;br /&gt;
 //button[@onclick=&#039;Joomla.submitbutton(&amp;quot;config.save.application.apply&amp;quot;)&#039;]&lt;br /&gt;
&lt;br /&gt;
When moved to a Page Object you will probably will face this situation:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_error_escaping_quotes_on_xpaths.png|framed|center|Typical issue when you write a long XPath in a Page object]]&lt;br /&gt;
&lt;br /&gt;
To avoid it remind to escape the quotes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
// Right&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=\&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)\&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Generating txt/html scenarios===&lt;br /&gt;
Codeception allows you to generate user-friendly text scenarios from scenario-driven from Cest and Cept php test (see http://codeception.com/docs/reference/Commands#GenerateScenarios).&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t use double quotes, use single quotes instead===&lt;br /&gt;
Do not use double quotes (&amp;quot;) for surrounding strings:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &amp;quot;&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;&amp;quot;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you use single quotes instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Congratulations! Joomla! is now installed.&#039;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will get the right expected result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Congratulations! Joomla! is now installed.&#039;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The reason of not being able to use double quotes is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;br /&gt;
&lt;br /&gt;
===Do not leave spaces between parameters in Cepts===&lt;br /&gt;
See the two lines:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
// Good&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;,10,&#039;h3&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Main Configuration&#039;,&amp;quot; 10&amp;quot;,&amp;quot; &#039;h3&#039;&lt;br /&gt;
&lt;br /&gt;
The reason that you are asked to not add spaces between parameters is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186613</id>
		<title>Testing Joomla Extensions with Codeception</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186613"/>
		<updated>2015-05-30T17:51:46Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;nowiki&amp;gt;Note: this page is under construction&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What is Codeception? ==&lt;br /&gt;
Codeception PHP Testing Framework is designed to work just out of the box. This means its installation requires minimal steps and no external dependencies preinstalled (except PHP, of course). Only one configuration step should be taken and you are ready to test your web application from an eye of actual user.&lt;br /&gt;
&lt;br /&gt;
See the following video of codeception in action testing Joomla: &lt;br /&gt;
&lt;br /&gt;
{{#widget:YouTube|id=Vc1BJNnhsFM}}&lt;br /&gt;
&lt;br /&gt;
Codeception provides possibilities to do Unit Testing or to Test APIs, however this page is focused in &#039;&#039;&#039;System Testing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Why Use Codeception? ==&lt;br /&gt;
&#039;&#039;Why use Codeception when we already have Selenium IDE?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Codeception works great with Selenium. But with Codeception you can write your tests in PHP. The main reason is: Selenium IDE tests are tightly bound to XPath locators. If you ever change anything in layout tests will fall. Codeception locators are more stable. You can use names, labels, button names and CSS to match elements on page. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features&#039;&#039;&#039;&lt;br /&gt;
* Selenium WebDriver integration&lt;br /&gt;
* Elements matched by name, CSS, XPath&lt;br /&gt;
* PageObjects and StepObjects included&lt;br /&gt;
* Powered by PHPUnit&lt;br /&gt;
* Data Cleanup&lt;br /&gt;
* Parallel Execution of tests&lt;br /&gt;
* BDD-style readable tests&lt;br /&gt;
&lt;br /&gt;
== Architecture of a test ==&lt;br /&gt;
The testing framework is built on the three layered testing architecture&lt;br /&gt;
&lt;br /&gt;
=== Scenarios (Cept Class) ===&lt;br /&gt;
Cept or Test, it is the main class which contains steps of execution for the tests, Cept Class will call Step Class functions which will indirectly make use of page objects to perform operations&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I = new AcceptanceTester($scenario);&lt;br /&gt;
$I-&amp;gt;wantTo(&#039;Install Joomla CMS&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;http://localhost/installation/index.php&#039;);&lt;br /&gt;
// I Wait for the text Main Configuration, meaning that the page is loaded&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;Language Selector&#039;]);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;English (United Kingdom)&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Site Name&#039;, &#039;weblinks&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Description&#039;, &#039;Site for testing Weblinks component&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Email&#039;, $cfg[&#039;Admin email&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Username&#039;, $cfg[&#039;username&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Confirm Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;click(&#039;Next&#039;);&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page Objects ===&lt;br /&gt;
Each page on your application has a class which we call page objects, each page class will have information about the URL, fields, Text present on the page. We use the best possible selector for any field on the page.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginManagerPage&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * @var string Url of the page&lt;br /&gt;
	 */&lt;br /&gt;
	public static $URL = &#039;/administrator/index.php&#039;;&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Array of Page elements indexed by descriptive name or label&lt;br /&gt;
	 *&lt;br /&gt;
	 * @var array&lt;br /&gt;
	 */&lt;br /&gt;
	public static $elements = array(&lt;br /&gt;
		&#039;username&#039; =&amp;gt; &amp;quot;#mod-login-username&amp;quot;,&lt;br /&gt;
		&#039;password&#039; =&amp;gt; &amp;quot;#mod-login-password&amp;quot;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Naming convention for Page Objects ====&lt;br /&gt;
When this document is created Codeception 2.0 was not having a PSR-4 compatible autoloader. Therefore we are creating a convention so with the future Codeception 2.1 with PSR-4 compatible autoloader (https://github.com/Codeception/Codeception/pull/1228) we are creating a naming convention for Pages so it will cost us a small effort to move to autoloaded classes in the future.&lt;br /&gt;
&lt;br /&gt;
The naming convention works as follows:&lt;br /&gt;
&lt;br /&gt;
 APPLICATION (for example Joomla, Patchtester, Weblinks or your Extension name)&lt;br /&gt;
 + CLIENT (in Joomla we use it for defining if is Installation, Administrator or Frontend&lt;br /&gt;
 + CLIENT PART (In Joomla we use it following the menu are were it belongs: Components, Menus, System,...)&lt;br /&gt;
 + PAGE NAME (The Page name) &lt;br /&gt;
 + Page&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
 JoomlaAdministratorLoginPage&lt;br /&gt;
 JoomlaAdministratorSystemGlobalconfigurationPage&lt;br /&gt;
 JoomlaInstallationConfigurationPage&lt;br /&gt;
&lt;br /&gt;
And they are located with a folder estructure similar to:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_pages_folder_structure.png|framed|center|Folder estructure for Pages in System Tests]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remind that in Codeception 2.0 you need to specify each folder in the acceptance/_bootstrap.php file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
// Here you can initialize variables that will be available to your tests&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/installation&#039;);&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/administrator&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#PageObjects&lt;br /&gt;
&lt;br /&gt;
=== Step Objects ===&lt;br /&gt;
Step Objects are classes which contains steps which are to be executed on the application to perform certain operations, step objects make use of page objects to perform these actions.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginSteps extends \AcceptanceTester&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * Function to execute an Admin Login for Joomla 3&lt;br /&gt;
	 *&lt;br /&gt;
	 * @return void&lt;br /&gt;
	 */&lt;br /&gt;
	public function doAdministratorLogin($user, $password)&lt;br /&gt;
	{&lt;br /&gt;
		$I = $this;&lt;br /&gt;
		$I-&amp;gt;amOnPage(\JoomlaAdministratorLoginPage::$URL);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;username&#039;], $user);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;password&#039;], $password);&lt;br /&gt;
		$I-&amp;gt;click(&#039;Log in&#039;);&lt;br /&gt;
		$I-&amp;gt;see(&#039;Category Manager&#039;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#StepObjects&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Joomla Browser Module ===&lt;br /&gt;
The Joomla Browser is a Codeception Module that incorporates general functions to your tests like:&lt;br /&gt;
- do administrator login&lt;br /&gt;
- install joomla&lt;br /&gt;
- install extension&lt;br /&gt;
- ...&lt;br /&gt;
&lt;br /&gt;
Find details about it at: https://github.com/joomla-projects/joomla-browser#table-of-contents&lt;br /&gt;
&lt;br /&gt;
== Getting started from scratch: what you need to download and install ==&lt;br /&gt;
To get the test environment running you need to have several components installed.&lt;br /&gt;
&lt;br /&gt;
=== local webserver ===&lt;br /&gt;
If you do not already have a local test server running you may want to check out:&lt;br /&gt;
https://www.mamp.info/&lt;br /&gt;
https://www.apachefriends.org/&lt;br /&gt;
http://www.ampps.com/&lt;br /&gt;
&lt;br /&gt;
If you are not familiar with a local web-server, learn that first before you advance futher. &lt;br /&gt;
&lt;br /&gt;
===Wget===&lt;br /&gt;
Wget is a command line program that retrieves content from web servers. For our purposes it is used to get selenium (browser test environment). See wikipedia: https://en.wikipedia.org/wiki/Wget&lt;br /&gt;
====Wget on Mac====&lt;br /&gt;
For Mac Users Homebrew (package manager for OS X) is a very easy way to get wget running. Download Homebrew at: http://brew.sh/ &lt;br /&gt;
After installation run the following command in your terminal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
brew install wget&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Java Runtime Environment (JRE) ===&lt;br /&gt;
The JRE has to be installed, so the tests will be executable. You find the recent versions at the Oracle Website.&lt;br /&gt;
In end of May 2015 this is: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html&lt;br /&gt;
later on that link could be obsolete and should be changed if there is a newer version out.&lt;br /&gt;
&lt;br /&gt;
Newer Mac OS Versions are not shipped any more with the JRE, so they have to download that too.&lt;br /&gt;
&lt;br /&gt;
=== Firefox ===&lt;br /&gt;
Selenium is testing in the browser Firefox. The selenium version is not that quick with the updates, as the Firefox browser, if the test is not executable, then it can be that you manually have to install an older version of Firefox.&lt;br /&gt;
Sadly that can be a try and error thing. To get older versions of Firefox: https://ftp.mozilla.org/pub/mozilla.org/firefox/releases/ here you will find many folders. Just try the first one that came before the Firefox version that you have been using (and that did not work). In the version folders you will find folders for all the different operating systems.&lt;br /&gt;
&lt;br /&gt;
‎&lt;br /&gt;
&lt;br /&gt;
=== configure test system variables ===&lt;br /&gt;
&lt;br /&gt;
[[File:Acceptance.suite.dist.yml rename.png|thumbnail|left|Screenshot of file structure]]&lt;br /&gt;
&lt;br /&gt;
In your the folder that you installed, downloaded, pulled (git) the project, you have to rename the &amp;quot;&#039;&#039;acceptance.suite.dist.yml&#039;&#039;&amp;quot; file to &amp;quot;&#039;&#039;acceptance.suite.yml&#039;&#039;&amp;quot; and configure the parameters to your system variables.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
   config:&lt;br /&gt;
        JoomlaBrowser:&lt;br /&gt;
            url: &#039;http://localhost/tests/joomla-cms3&#039;&lt;br /&gt;
            # the url that points to the joomla installation at /tests/system/joomla-cms&lt;br /&gt;
            browser: &#039;firefox&#039;&lt;br /&gt;
            window_size: 1024x768&lt;br /&gt;
    [...]&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
[[File:Run Command vendor bin robo test-acceptance.png|thumbnail|test:acceptance]]&lt;br /&gt;
Once your machine is able to run tests (see &#039;&#039;The Joomla Browser Module&#039;&#039;), you are able to start working.&lt;br /&gt;
&lt;br /&gt;
Check the contents of the /tests/ folder in weblinks and try to understand the structure of the tests.&lt;br /&gt;
For each function you have a directory and sometimes a configuration file, both will have the corresponding name.&lt;br /&gt;
* FunctionName.yml - these files contain configurations for the function folders&lt;br /&gt;
* FunctionName - contains the &#039;&#039;FunctionName&#039;&#039; test&lt;br /&gt;
* joomla-cms3 - contains the latest Joomla! installation&lt;br /&gt;
&lt;br /&gt;
After that check the tasks are at: https://github.com/joomla-extensions/weblinks/issues/47&lt;br /&gt;
&lt;br /&gt;
== The principles for writing a test: Readability and Performance ==&lt;br /&gt;
In Joomla we give priority to Readability over Performance, even when performance is a must.&lt;br /&gt;
&lt;br /&gt;
To explain that let me show an example: Let&#039;s say that we want to fill a field Username in a login form. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;administrator/index.php&amp;quot; method=&amp;quot;post&amp;quot; id=&amp;quot;form-login&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;username_field&amp;quot;&amp;gt;Username&amp;lt;/label&amp;gt;&lt;br /&gt;
  &amp;lt;input name=&amp;quot;username_field&amp;quot; tabindex=&amp;quot;1&amp;quot; id=&amp;quot;username_field&amp;quot; type=&amp;quot;text&amp;quot; size=&amp;quot;15&amp;quot; /&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the most performant way to fill that form field would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;#username_field&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And usually we would move that to a page object element ending in:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(\LoginPage::$username, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However Codeception is a smart framework and it adds some magic to it&#039;s methods (see: https://github.com/Codeception/Codeception/blob/2.0/src/Codeception/Module/WebDriver.php#L511-L513). It allows me to write more readable tests (keeping performance hight). &lt;br /&gt;
&lt;br /&gt;
If we do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Username&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Codeception will be smart and will search first in the page if there is any &amp;quot;LABEL&amp;quot; called Username. That is a fast operation, so performance will be affected just a little. And instead we have written less code than in previous examples.&lt;br /&gt;
&lt;br /&gt;
Note: sometimes this tricks are not always possible, labels are not always there or there are some elements hidden that shows and hides depending on a Javascript. All these special cases would require a Page element.&lt;br /&gt;
&lt;br /&gt;
Still there is a definitive method of using locators that made them readable and performant called: strict Locators see [[Testing_Joomla_Extensions_with_Codeception#Writting_reliable_locators]].&lt;br /&gt;
&lt;br /&gt;
With them we do: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField([&#039;id&#039; =&amp;gt; &#039;username_field&#039;], &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In conclusion we have more readable tests and less code to maintain while keeping performance. That is a win!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setting Up Codeception ==&lt;br /&gt;
=== setting up the repository ===&lt;br /&gt;
&#039;&#039;&#039;clone the directory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Fork [https://github.com/joomla-projects/com_localise com_localise]&lt;br /&gt;
# &lt;br /&gt;
# Git clone git@github.com:*your-github-profile-name*/com_localise.git&lt;br /&gt;
&lt;br /&gt;
=== Testing with Codeception ===&lt;br /&gt;
&lt;br /&gt;
There are two ways to get and run codeception, via PHAR or via Composer. Using &#039;&#039;&#039;Composer is recommended&#039;&#039;&#039; (because we are using in some tests the Codeception 2.1 development version not available in the composer.phar).&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Using Composer&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    You need to have Composer in your system, if not download it from here: https://getcomposer.org/&lt;br /&gt;
&lt;br /&gt;
    Step 1: composer update&lt;br /&gt;
&lt;br /&gt;
    Step 2: run Codeception by doing: php vendor/bin/codecept build&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Codeception.phar&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    Linux Machine  : wget http://codeception.com/codecept.phar&lt;br /&gt;
&lt;br /&gt;
    Windows Machine: Download from [http://codeception.com/install codecept.phar]&lt;br /&gt;
&lt;br /&gt;
    Step1 : php ./codecept.phar build&lt;br /&gt;
&lt;br /&gt;
=== Running the Test ===&lt;br /&gt;
Run Selenium server&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Download&lt;br /&gt;
curl -O http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&lt;br /&gt;
# And start the Selenium Server&lt;br /&gt;
java -Xms40m -Xmx256m -jar /Applications/XAMPP/xamppfiles/htdocs/selenium/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Rename tests/acceptance.suite.dist.yml to tests/acceptance.suite.yml&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 1: Modify the configuration at tests/acceptance.suite.yml to fit your server details.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 2: php codecept.phar run&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
with --steps to see a step-by-step report on the performed actions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --steps&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with --html. This command will run all tests for all suites, displaying the steps, and building HTML and XML reports. Reports will be store in tests/_output/ directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --html&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To activate the debug mode in Codeception just add the parameter --debug when you run the tests:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run acceptance --debug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Best Practices at Testing ==&lt;br /&gt;
=== Writting reliable locators ===&lt;br /&gt;
Writing good locators can be tricky. The Mozilla team has written an excellent guide titled [https://blog.mozilla.org/webqa/2013/09/26/writing-reliable-locators-for-selenium-and-webdriver-tests/ Writing reliable locators for Selenium and WebDriver tests].&lt;br /&gt;
&lt;br /&gt;
If the locator is an array, it should have a single element, with the key signifying the locator type (`id`, `name`, `css`, `xpath`, `link`, or `class`) and the value being the locator itself. This is called a &amp;quot;strict&amp;quot; locator. Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* [&#039;id&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div id=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;name&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div name=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;css&#039; =&amp;gt; &#039;input[type=input][value=foo]&#039;] matches `&amp;lt;input type=&amp;quot;input&amp;quot; value=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;xpath&#039; =&amp;gt; &amp;quot;//input[@type=&#039;submit&#039;][contains(@value, &#039;foo&#039;)]&amp;quot;] matches `&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;foobar&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;link&#039; =&amp;gt; &#039;Click here&#039;] matches `&amp;lt;a href=&amp;quot;google.com&amp;quot;&amp;gt;Click here&amp;lt;/a&amp;gt;`&lt;br /&gt;
* [&#039;class&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div class=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
=== How to use URLs ===&lt;br /&gt;
Codeception documentation suggests to use URL&#039;s as properties of a Page Object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(JoomlaInstallationConfigurationPage::$URL);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of hardcoding the url in the test:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The pros of this approach is:&lt;br /&gt;
- first way is more readable for non developers. &lt;br /&gt;
- it helps to make tests more maintenable in the case of a url change in the system&lt;br /&gt;
&lt;br /&gt;
However in joomla a change in an url is rare, and if it happens changing it will just be a Find&amp;amp;Replace task. I Joomla test we want to have the benefit of both, the url and a representative name that describes the page where we are going. That will make our tests more readable. Thus, we will write the urls the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amGoingTo(&#039;go to Create New Banner page at Joomla Administrator&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Working with Hidden Elements ===&lt;br /&gt;
Selenium can&#039;t interact with elements that are not visible:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;http://www.joomla.org&amp;quot; style=&amp;quot;display: none;&amp;quot; id=&amp;quot;joomla_site&amp;quot;&amp;gt;go to joomla&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case you can&#039;t do:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually this happens when you need to wait for a Javascript animation that end up showing that element, so in this case you will need to do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForElementVisible(&#039;#joomla_site&#039;);&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== When do not use contains ===&lt;br /&gt;
We do not recommend to use the function contains on XPath because is not specific and can create false positives at tests.&lt;br /&gt;
See: https://github.com/joomla-projects/GSOC-Webdriver_system_tests_for_CMS/pull/99#issuecomment-69004191&lt;br /&gt;
=== Always add Strict Locators to your tests ===&lt;br /&gt;
Performance in tests is very important. You can reduce dramatically the time spent on a test with just adding a few extra locators. For example, the following code pertains to a test:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// see($text, $selector = null)&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the previous code we are not facilitating the &amp;quot;Selector&amp;quot; so Codeception will have to search for the element in all the HTML. Doing this instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the tests went from: Time: 1.17 minutes&lt;br /&gt;
to: Time: 49.18 seconds&lt;br /&gt;
&lt;br /&gt;
You can see this video of a real example: http://www.youtube.com/watch?v=0JCv0BR2yZY&lt;br /&gt;
&lt;br /&gt;
Losing 30 seconds in every Assertion can delay your tests dramatically. Therefore, remind always to add xPath locators to all your Assertions.&lt;br /&gt;
[[Category:Automated Testing]]&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;see ====&lt;br /&gt;
Do not use &#039;&#039;see&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;waitForText ====&lt;br /&gt;
Do not use &#039;&#039;waitForText&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;, 10, [&#039;css&#039; =&amp;gt; &#039;h3&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Incase of an element has multiple css classes, When Using CSS Locators make sure you use more specific class as locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert-success&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
A page could have mutiple elements which can have &#039;&#039;alert&#039;&#039; css class associated, hence being more specific helps.&lt;br /&gt;
&lt;br /&gt;
==== How much time should I wait for an Element or Text? ====&lt;br /&gt;
You may have noticed that the second parameter in the I waitForText is an integer that represents how much &amp;quot;time to wait&amp;quot; in seconds:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;a text to wait for&#039;, 10, [&#039;...&#039; =&amp;gt; &#039;...&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But, how much time is the right time to wait for a text?&lt;br /&gt;
&lt;br /&gt;
PHP maximum execution time before returning a Fatal Error for timeout is set by default to 30 seconds. We suggest to set it for 10 seconds. A waitForText over 10 seconds will definitely mean that something is not performing well.&lt;br /&gt;
&lt;br /&gt;
=== Quote and Double Quotes in Compex XPaths ===&lt;br /&gt;
Sometimes you will have to write XPaths that looks like:&lt;br /&gt;
&lt;br /&gt;
 //button[@onclick=&#039;Joomla.submitbutton(&amp;quot;config.save.application.apply&amp;quot;)&#039;]&lt;br /&gt;
&lt;br /&gt;
When moved to a Page Object you will probably will face this situation:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_error_escaping_quotes_on_xpaths.png|framed|center|Typical issue when you write a long XPath in a Page object]]&lt;br /&gt;
&lt;br /&gt;
To avoid it remind to escape the quotes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
// Right&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=\&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)\&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Generating txt/html scenarios===&lt;br /&gt;
Codeception allows you to generate user-friendly text scenarios from scenario-driven from Cest and Cept php test (see http://codeception.com/docs/reference/Commands#GenerateScenarios).&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t use double quotes, use single quotes instead===&lt;br /&gt;
Do not use double quotes (&amp;quot;) for surrounding strings:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &amp;quot;&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;&amp;quot;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you use single quotes instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Congratulations! Joomla! is now installed.&#039;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will get the right expected result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Congratulations! Joomla! is now installed.&#039;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The reason of not being able to use double quotes is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;br /&gt;
&lt;br /&gt;
===Do not leave spaces between parameters in Cepts===&lt;br /&gt;
See the two lines:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
// Good&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;,10,&#039;h3&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Main Configuration&#039;,&amp;quot; 10&amp;quot;,&amp;quot; &#039;h3&#039;&lt;br /&gt;
&lt;br /&gt;
The reason that you are asked to not add spaces between parameters is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186612</id>
		<title>Testing Joomla Extensions with Codeception</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186612"/>
		<updated>2015-05-30T17:47:32Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: /* then run the first test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;nowiki&amp;gt;Note: this page is under construction&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What is Codeception? ==&lt;br /&gt;
Codeception PHP Testing Framework is designed to work just out of the box. This means its installation requires minimal steps and no external dependencies preinstalled (except PHP, of course). Only one configuration step should be taken and you are ready to test your web application from an eye of actual user.&lt;br /&gt;
&lt;br /&gt;
See the following video of codeception in action testing Joomla: &lt;br /&gt;
&lt;br /&gt;
{{#widget:YouTube|id=Vc1BJNnhsFM}}&lt;br /&gt;
&lt;br /&gt;
Codeception provides possibilities to do Unit Testing or to Test APIs, however this page is focused in &#039;&#039;&#039;System Testing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Why Use Codeception? ==&lt;br /&gt;
&#039;&#039;Why use Codeception when we already have Selenium IDE?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Codeception works great with Selenium. But with Codeception you can write your tests in PHP. The main reason is: Selenium IDE tests are tightly bound to XPath locators. If you ever change anything in layout tests will fall. Codeception locators are more stable. You can use names, labels, button names and CSS to match elements on page. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features&#039;&#039;&#039;&lt;br /&gt;
* Selenium WebDriver integration&lt;br /&gt;
* Elements matched by name, CSS, XPath&lt;br /&gt;
* PageObjects and StepObjects included&lt;br /&gt;
* Powered by PHPUnit&lt;br /&gt;
* Data Cleanup&lt;br /&gt;
* Parallel Execution of tests&lt;br /&gt;
* BDD-style readable tests&lt;br /&gt;
&lt;br /&gt;
== Architecture of a test ==&lt;br /&gt;
The testing framework is built on the three layered testing architecture&lt;br /&gt;
&lt;br /&gt;
=== Scenarios (Cept Class) ===&lt;br /&gt;
Cept or Test, it is the main class which contains steps of execution for the tests, Cept Class will call Step Class functions which will indirectly make use of page objects to perform operations&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I = new AcceptanceTester($scenario);&lt;br /&gt;
$I-&amp;gt;wantTo(&#039;Install Joomla CMS&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;http://localhost/installation/index.php&#039;);&lt;br /&gt;
// I Wait for the text Main Configuration, meaning that the page is loaded&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;Language Selector&#039;]);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;English (United Kingdom)&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Site Name&#039;, &#039;weblinks&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Description&#039;, &#039;Site for testing Weblinks component&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Email&#039;, $cfg[&#039;Admin email&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Username&#039;, $cfg[&#039;username&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Confirm Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;click(&#039;Next&#039;);&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page Objects ===&lt;br /&gt;
Each page on your application has a class which we call page objects, each page class will have information about the URL, fields, Text present on the page. We use the best possible selector for any field on the page.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginManagerPage&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * @var string Url of the page&lt;br /&gt;
	 */&lt;br /&gt;
	public static $URL = &#039;/administrator/index.php&#039;;&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Array of Page elements indexed by descriptive name or label&lt;br /&gt;
	 *&lt;br /&gt;
	 * @var array&lt;br /&gt;
	 */&lt;br /&gt;
	public static $elements = array(&lt;br /&gt;
		&#039;username&#039; =&amp;gt; &amp;quot;#mod-login-username&amp;quot;,&lt;br /&gt;
		&#039;password&#039; =&amp;gt; &amp;quot;#mod-login-password&amp;quot;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Naming convention for Page Objects ====&lt;br /&gt;
When this document is created Codeception 2.0 was not having a PSR-4 compatible autoloader. Therefore we are creating a convention so with the future Codeception 2.1 with PSR-4 compatible autoloader (https://github.com/Codeception/Codeception/pull/1228) we are creating a naming convention for Pages so it will cost us a small effort to move to autoloaded classes in the future.&lt;br /&gt;
&lt;br /&gt;
The naming convention works as follows:&lt;br /&gt;
&lt;br /&gt;
 APPLICATION (for example Joomla, Patchtester, Weblinks or your Extension name)&lt;br /&gt;
 + CLIENT (in Joomla we use it for defining if is Installation, Administrator or Frontend&lt;br /&gt;
 + CLIENT PART (In Joomla we use it following the menu are were it belongs: Components, Menus, System,...)&lt;br /&gt;
 + PAGE NAME (The Page name) &lt;br /&gt;
 + Page&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
 JoomlaAdministratorLoginPage&lt;br /&gt;
 JoomlaAdministratorSystemGlobalconfigurationPage&lt;br /&gt;
 JoomlaInstallationConfigurationPage&lt;br /&gt;
&lt;br /&gt;
And they are located with a folder estructure similar to:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_pages_folder_structure.png|framed|center|Folder estructure for Pages in System Tests]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remind that in Codeception 2.0 you need to specify each folder in the acceptance/_bootstrap.php file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
// Here you can initialize variables that will be available to your tests&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/installation&#039;);&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/administrator&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#PageObjects&lt;br /&gt;
&lt;br /&gt;
=== Step Objects ===&lt;br /&gt;
Step Objects are classes which contains steps which are to be executed on the application to perform certain operations, step objects make use of page objects to perform these actions.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginSteps extends \AcceptanceTester&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * Function to execute an Admin Login for Joomla 3&lt;br /&gt;
	 *&lt;br /&gt;
	 * @return void&lt;br /&gt;
	 */&lt;br /&gt;
	public function doAdministratorLogin($user, $password)&lt;br /&gt;
	{&lt;br /&gt;
		$I = $this;&lt;br /&gt;
		$I-&amp;gt;amOnPage(\JoomlaAdministratorLoginPage::$URL);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;username&#039;], $user);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;password&#039;], $password);&lt;br /&gt;
		$I-&amp;gt;click(&#039;Log in&#039;);&lt;br /&gt;
		$I-&amp;gt;see(&#039;Category Manager&#039;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#StepObjects&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Joomla Browser Module ===&lt;br /&gt;
The Joomla Browser is a Codeception Module that incorporates general functions to your tests like:&lt;br /&gt;
- do administrator login&lt;br /&gt;
- install joomla&lt;br /&gt;
- install extension&lt;br /&gt;
- ...&lt;br /&gt;
&lt;br /&gt;
Find details about it at: https://github.com/joomla-projects/joomla-browser#table-of-contents&lt;br /&gt;
&lt;br /&gt;
== Getting started from scratch: what you need to download and install ==&lt;br /&gt;
To get the test environment running you need to have several components installed.&lt;br /&gt;
&lt;br /&gt;
=== local webserver ===&lt;br /&gt;
If you do not already have a local test server running you may want to check out:&lt;br /&gt;
https://www.mamp.info/&lt;br /&gt;
https://www.apachefriends.org/&lt;br /&gt;
http://www.ampps.com/&lt;br /&gt;
&lt;br /&gt;
If you are not familiar with a local web-server, learn that first before you advance futher. &lt;br /&gt;
&lt;br /&gt;
===Wget===&lt;br /&gt;
Wget is a command line program that retrieves content from web servers. For our purposes it is used to get selenium (browser test environment). See wikipedia: https://en.wikipedia.org/wiki/Wget&lt;br /&gt;
====Wget on Mac====&lt;br /&gt;
For Mac Users Homebrew (package manager for OS X) is a very easy way to get wget running. Download Homebrew at: http://brew.sh/ &lt;br /&gt;
After installation run the following command in your terminal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
brew install wget&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Java Runtime Environment (JRE) ===&lt;br /&gt;
The JRE has to be installed, so the tests will be executable. You find the recent versions at the Oracle Website.&lt;br /&gt;
In end of May 2015 this is: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html&lt;br /&gt;
later on that link could be obsolete and should be changed if there is a newer version out.&lt;br /&gt;
&lt;br /&gt;
Newer Mac OS Versions are not shipped any more with the JRE, so they have to download that too.&lt;br /&gt;
&lt;br /&gt;
=== Firefox ===&lt;br /&gt;
Selenium is testing in the browser Firefox. The selenium version is not that quick with the updates, as the Firefox browser, if the test is not executable, then it can be that you manually have to install an older version of Firefox.&lt;br /&gt;
Sadly that can be a try and error thing. To get older versions of Firefox: https://ftp.mozilla.org/pub/mozilla.org/firefox/releases/ here you will find many folders. Just try the first one that came before the Firefox version that you have been using (and that did not work). In the version folders you will find folders for all the different operating systems.&lt;br /&gt;
&lt;br /&gt;
‎&lt;br /&gt;
&lt;br /&gt;
=== configure test system variables ===&lt;br /&gt;
&lt;br /&gt;
[[File:Acceptance.suite.dist.yml rename.png|thumbnail|left|Screenshot of file structure]]&lt;br /&gt;
&lt;br /&gt;
In your the folder that you installed, downloaded, pulled (git) the project, you have to rename the &amp;quot;&#039;&#039;acceptance.suite.dist.yml&#039;&#039;&amp;quot; file to &amp;quot;&#039;&#039;acceptance.suite.yml&#039;&#039;&amp;quot; and configure the parameters to your system variables.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
   config:&lt;br /&gt;
        JoomlaBrowser:&lt;br /&gt;
            url: &#039;http://localhost/tests/joomla-cms3&#039;&lt;br /&gt;
            # the url that points to the joomla installation at /tests/system/joomla-cms&lt;br /&gt;
            browser: &#039;firefox&#039;&lt;br /&gt;
            window_size: 1024x768&lt;br /&gt;
    [...]&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== then run the first test ===&lt;br /&gt;
[[File:Run Command vendor bin robo test-acceptance.png|thumbnail|left|test:acceptance]]&lt;br /&gt;
Once your machine is able to run tests (see &#039;&#039;The Joomla Browser Module&#039;&#039;), you are able to start working.&lt;br /&gt;
&lt;br /&gt;
==== after a successful test ====&lt;br /&gt;
Check the contents of the /tests/ folder in weblinks and try to understand the structure of the tests.&lt;br /&gt;
For each function you have a directory and sometimes a configuration file, both will have the corresponding name.&lt;br /&gt;
* FunctionName.yml - these files contain configurations for the function folders&lt;br /&gt;
* FunctionName - contains the &#039;&#039;FunctionName&#039;&#039; test&lt;br /&gt;
* joomla-cms3 - contains the latest Joomla! installation&lt;br /&gt;
&lt;br /&gt;
After that check the tasks are at: https://github.com/joomla-extensions/weblinks/issues/47&lt;br /&gt;
&lt;br /&gt;
== The principles for writing a test: Readability and Performance ==&lt;br /&gt;
In Joomla we give priority to Readability over Performance, even when performance is a must.&lt;br /&gt;
&lt;br /&gt;
To explain that let me show an example: Let&#039;s say that we want to fill a field Username in a login form. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;administrator/index.php&amp;quot; method=&amp;quot;post&amp;quot; id=&amp;quot;form-login&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;username_field&amp;quot;&amp;gt;Username&amp;lt;/label&amp;gt;&lt;br /&gt;
  &amp;lt;input name=&amp;quot;username_field&amp;quot; tabindex=&amp;quot;1&amp;quot; id=&amp;quot;username_field&amp;quot; type=&amp;quot;text&amp;quot; size=&amp;quot;15&amp;quot; /&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the most performant way to fill that form field would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;#username_field&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And usually we would move that to a page object element ending in:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(\LoginPage::$username, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However Codeception is a smart framework and it adds some magic to it&#039;s methods (see: https://github.com/Codeception/Codeception/blob/2.0/src/Codeception/Module/WebDriver.php#L511-L513). It allows me to write more readable tests (keeping performance hight). &lt;br /&gt;
&lt;br /&gt;
If we do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Username&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Codeception will be smart and will search first in the page if there is any &amp;quot;LABEL&amp;quot; called Username. That is a fast operation, so performance will be affected just a little. And instead we have written less code than in previous examples.&lt;br /&gt;
&lt;br /&gt;
Note: sometimes this tricks are not always possible, labels are not always there or there are some elements hidden that shows and hides depending on a Javascript. All these special cases would require a Page element.&lt;br /&gt;
&lt;br /&gt;
Still there is a definitive method of using locators that made them readable and performant called: strict Locators see [[Testing_Joomla_Extensions_with_Codeception#Writting_reliable_locators]].&lt;br /&gt;
&lt;br /&gt;
With them we do: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField([&#039;id&#039; =&amp;gt; &#039;username_field&#039;], &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In conclusion we have more readable tests and less code to maintain while keeping performance. That is a win!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setting Up Codeception ==&lt;br /&gt;
=== setting up the repository ===&lt;br /&gt;
&#039;&#039;&#039;clone the directory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Fork [https://github.com/joomla-projects/com_localise com_localise]&lt;br /&gt;
# &lt;br /&gt;
# Git clone git@github.com:*your-github-profile-name*/com_localise.git&lt;br /&gt;
&lt;br /&gt;
=== Testing with Codeception ===&lt;br /&gt;
&lt;br /&gt;
There are two ways to get and run codeception, via PHAR or via Composer. Using &#039;&#039;&#039;Composer is recommended&#039;&#039;&#039; (because we are using in some tests the Codeception 2.1 development version not available in the composer.phar).&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Using Composer&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    You need to have Composer in your system, if not download it from here: https://getcomposer.org/&lt;br /&gt;
&lt;br /&gt;
    Step 1: composer update&lt;br /&gt;
&lt;br /&gt;
    Step 2: run Codeception by doing: php vendor/bin/codecept build&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Codeception.phar&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    Linux Machine  : wget http://codeception.com/codecept.phar&lt;br /&gt;
&lt;br /&gt;
    Windows Machine: Download from [http://codeception.com/install codecept.phar]&lt;br /&gt;
&lt;br /&gt;
    Step1 : php ./codecept.phar build&lt;br /&gt;
&lt;br /&gt;
=== Running the Test ===&lt;br /&gt;
Run Selenium server&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Download&lt;br /&gt;
curl -O http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&lt;br /&gt;
# And start the Selenium Server&lt;br /&gt;
java -Xms40m -Xmx256m -jar /Applications/XAMPP/xamppfiles/htdocs/selenium/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Rename tests/acceptance.suite.dist.yml to tests/acceptance.suite.yml&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 1: Modify the configuration at tests/acceptance.suite.yml to fit your server details.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 2: php codecept.phar run&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
with --steps to see a step-by-step report on the performed actions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --steps&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with --html. This command will run all tests for all suites, displaying the steps, and building HTML and XML reports. Reports will be store in tests/_output/ directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --html&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To activate the debug mode in Codeception just add the parameter --debug when you run the tests:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run acceptance --debug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Best Practices at Testing ==&lt;br /&gt;
=== Writting reliable locators ===&lt;br /&gt;
Writing good locators can be tricky. The Mozilla team has written an excellent guide titled [https://blog.mozilla.org/webqa/2013/09/26/writing-reliable-locators-for-selenium-and-webdriver-tests/ Writing reliable locators for Selenium and WebDriver tests].&lt;br /&gt;
&lt;br /&gt;
If the locator is an array, it should have a single element, with the key signifying the locator type (`id`, `name`, `css`, `xpath`, `link`, or `class`) and the value being the locator itself. This is called a &amp;quot;strict&amp;quot; locator. Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* [&#039;id&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div id=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;name&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div name=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;css&#039; =&amp;gt; &#039;input[type=input][value=foo]&#039;] matches `&amp;lt;input type=&amp;quot;input&amp;quot; value=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;xpath&#039; =&amp;gt; &amp;quot;//input[@type=&#039;submit&#039;][contains(@value, &#039;foo&#039;)]&amp;quot;] matches `&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;foobar&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;link&#039; =&amp;gt; &#039;Click here&#039;] matches `&amp;lt;a href=&amp;quot;google.com&amp;quot;&amp;gt;Click here&amp;lt;/a&amp;gt;`&lt;br /&gt;
* [&#039;class&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div class=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
=== How to use URLs ===&lt;br /&gt;
Codeception documentation suggests to use URL&#039;s as properties of a Page Object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(JoomlaInstallationConfigurationPage::$URL);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of hardcoding the url in the test:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The pros of this approach is:&lt;br /&gt;
- first way is more readable for non developers. &lt;br /&gt;
- it helps to make tests more maintenable in the case of a url change in the system&lt;br /&gt;
&lt;br /&gt;
However in joomla a change in an url is rare, and if it happens changing it will just be a Find&amp;amp;Replace task. I Joomla test we want to have the benefit of both, the url and a representative name that describes the page where we are going. That will make our tests more readable. Thus, we will write the urls the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amGoingTo(&#039;go to Create New Banner page at Joomla Administrator&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Working with Hidden Elements ===&lt;br /&gt;
Selenium can&#039;t interact with elements that are not visible:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;http://www.joomla.org&amp;quot; style=&amp;quot;display: none;&amp;quot; id=&amp;quot;joomla_site&amp;quot;&amp;gt;go to joomla&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case you can&#039;t do:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually this happens when you need to wait for a Javascript animation that end up showing that element, so in this case you will need to do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForElementVisible(&#039;#joomla_site&#039;);&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== When do not use contains ===&lt;br /&gt;
We do not recommend to use the function contains on XPath because is not specific and can create false positives at tests.&lt;br /&gt;
See: https://github.com/joomla-projects/GSOC-Webdriver_system_tests_for_CMS/pull/99#issuecomment-69004191&lt;br /&gt;
=== Always add Strict Locators to your tests ===&lt;br /&gt;
Performance in tests is very important. You can reduce dramatically the time spent on a test with just adding a few extra locators. For example, the following code pertains to a test:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// see($text, $selector = null)&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the previous code we are not facilitating the &amp;quot;Selector&amp;quot; so Codeception will have to search for the element in all the HTML. Doing this instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the tests went from: Time: 1.17 minutes&lt;br /&gt;
to: Time: 49.18 seconds&lt;br /&gt;
&lt;br /&gt;
You can see this video of a real example: http://www.youtube.com/watch?v=0JCv0BR2yZY&lt;br /&gt;
&lt;br /&gt;
Losing 30 seconds in every Assertion can delay your tests dramatically. Therefore, remind always to add xPath locators to all your Assertions.&lt;br /&gt;
[[Category:Automated Testing]]&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;see ====&lt;br /&gt;
Do not use &#039;&#039;see&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;waitForText ====&lt;br /&gt;
Do not use &#039;&#039;waitForText&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;, 10, [&#039;css&#039; =&amp;gt; &#039;h3&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Incase of an element has multiple css classes, When Using CSS Locators make sure you use more specific class as locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert-success&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
A page could have mutiple elements which can have &#039;&#039;alert&#039;&#039; css class associated, hence being more specific helps.&lt;br /&gt;
&lt;br /&gt;
==== How much time should I wait for an Element or Text? ====&lt;br /&gt;
You may have noticed that the second parameter in the I waitForText is an integer that represents how much &amp;quot;time to wait&amp;quot; in seconds:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;a text to wait for&#039;, 10, [&#039;...&#039; =&amp;gt; &#039;...&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But, how much time is the right time to wait for a text?&lt;br /&gt;
&lt;br /&gt;
PHP maximum execution time before returning a Fatal Error for timeout is set by default to 30 seconds. We suggest to set it for 10 seconds. A waitForText over 10 seconds will definitely mean that something is not performing well.&lt;br /&gt;
&lt;br /&gt;
=== Quote and Double Quotes in Compex XPaths ===&lt;br /&gt;
Sometimes you will have to write XPaths that looks like:&lt;br /&gt;
&lt;br /&gt;
 //button[@onclick=&#039;Joomla.submitbutton(&amp;quot;config.save.application.apply&amp;quot;)&#039;]&lt;br /&gt;
&lt;br /&gt;
When moved to a Page Object you will probably will face this situation:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_error_escaping_quotes_on_xpaths.png|framed|center|Typical issue when you write a long XPath in a Page object]]&lt;br /&gt;
&lt;br /&gt;
To avoid it remind to escape the quotes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
// Right&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=\&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)\&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Generating txt/html scenarios===&lt;br /&gt;
Codeception allows you to generate user-friendly text scenarios from scenario-driven from Cest and Cept php test (see http://codeception.com/docs/reference/Commands#GenerateScenarios).&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t use double quotes, use single quotes instead===&lt;br /&gt;
Do not use double quotes (&amp;quot;) for surrounding strings:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &amp;quot;&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;&amp;quot;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you use single quotes instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Congratulations! Joomla! is now installed.&#039;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will get the right expected result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Congratulations! Joomla! is now installed.&#039;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The reason of not being able to use double quotes is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;br /&gt;
&lt;br /&gt;
===Do not leave spaces between parameters in Cepts===&lt;br /&gt;
See the two lines:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
// Good&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;,10,&#039;h3&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Main Configuration&#039;,&amp;quot; 10&amp;quot;,&amp;quot; &#039;h3&#039;&lt;br /&gt;
&lt;br /&gt;
The reason that you are asked to not add spaces between parameters is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186611</id>
		<title>Testing Joomla Extensions with Codeception</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186611"/>
		<updated>2015-05-30T17:32:11Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: /* then run the first test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;nowiki&amp;gt;Note: this page is under construction&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What is Codeception? ==&lt;br /&gt;
Codeception PHP Testing Framework is designed to work just out of the box. This means its installation requires minimal steps and no external dependencies preinstalled (except PHP, of course). Only one configuration step should be taken and you are ready to test your web application from an eye of actual user.&lt;br /&gt;
&lt;br /&gt;
See the following video of codeception in action testing Joomla: &lt;br /&gt;
&lt;br /&gt;
{{#widget:YouTube|id=Vc1BJNnhsFM}}&lt;br /&gt;
&lt;br /&gt;
Codeception provides possibilities to do Unit Testing or to Test APIs, however this page is focused in &#039;&#039;&#039;System Testing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Why Use Codeception? ==&lt;br /&gt;
&#039;&#039;Why use Codeception when we already have Selenium IDE?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Codeception works great with Selenium. But with Codeception you can write your tests in PHP. The main reason is: Selenium IDE tests are tightly bound to XPath locators. If you ever change anything in layout tests will fall. Codeception locators are more stable. You can use names, labels, button names and CSS to match elements on page. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features&#039;&#039;&#039;&lt;br /&gt;
* Selenium WebDriver integration&lt;br /&gt;
* Elements matched by name, CSS, XPath&lt;br /&gt;
* PageObjects and StepObjects included&lt;br /&gt;
* Powered by PHPUnit&lt;br /&gt;
* Data Cleanup&lt;br /&gt;
* Parallel Execution of tests&lt;br /&gt;
* BDD-style readable tests&lt;br /&gt;
&lt;br /&gt;
== Architecture of a test ==&lt;br /&gt;
The testing framework is built on the three layered testing architecture&lt;br /&gt;
&lt;br /&gt;
=== Scenarios (Cept Class) ===&lt;br /&gt;
Cept or Test, it is the main class which contains steps of execution for the tests, Cept Class will call Step Class functions which will indirectly make use of page objects to perform operations&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I = new AcceptanceTester($scenario);&lt;br /&gt;
$I-&amp;gt;wantTo(&#039;Install Joomla CMS&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;http://localhost/installation/index.php&#039;);&lt;br /&gt;
// I Wait for the text Main Configuration, meaning that the page is loaded&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;Language Selector&#039;]);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;English (United Kingdom)&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Site Name&#039;, &#039;weblinks&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Description&#039;, &#039;Site for testing Weblinks component&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Email&#039;, $cfg[&#039;Admin email&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Username&#039;, $cfg[&#039;username&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Confirm Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;click(&#039;Next&#039;);&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page Objects ===&lt;br /&gt;
Each page on your application has a class which we call page objects, each page class will have information about the URL, fields, Text present on the page. We use the best possible selector for any field on the page.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginManagerPage&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * @var string Url of the page&lt;br /&gt;
	 */&lt;br /&gt;
	public static $URL = &#039;/administrator/index.php&#039;;&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Array of Page elements indexed by descriptive name or label&lt;br /&gt;
	 *&lt;br /&gt;
	 * @var array&lt;br /&gt;
	 */&lt;br /&gt;
	public static $elements = array(&lt;br /&gt;
		&#039;username&#039; =&amp;gt; &amp;quot;#mod-login-username&amp;quot;,&lt;br /&gt;
		&#039;password&#039; =&amp;gt; &amp;quot;#mod-login-password&amp;quot;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Naming convention for Page Objects ====&lt;br /&gt;
When this document is created Codeception 2.0 was not having a PSR-4 compatible autoloader. Therefore we are creating a convention so with the future Codeception 2.1 with PSR-4 compatible autoloader (https://github.com/Codeception/Codeception/pull/1228) we are creating a naming convention for Pages so it will cost us a small effort to move to autoloaded classes in the future.&lt;br /&gt;
&lt;br /&gt;
The naming convention works as follows:&lt;br /&gt;
&lt;br /&gt;
 APPLICATION (for example Joomla, Patchtester, Weblinks or your Extension name)&lt;br /&gt;
 + CLIENT (in Joomla we use it for defining if is Installation, Administrator or Frontend&lt;br /&gt;
 + CLIENT PART (In Joomla we use it following the menu are were it belongs: Components, Menus, System,...)&lt;br /&gt;
 + PAGE NAME (The Page name) &lt;br /&gt;
 + Page&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
 JoomlaAdministratorLoginPage&lt;br /&gt;
 JoomlaAdministratorSystemGlobalconfigurationPage&lt;br /&gt;
 JoomlaInstallationConfigurationPage&lt;br /&gt;
&lt;br /&gt;
And they are located with a folder estructure similar to:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_pages_folder_structure.png|framed|center|Folder estructure for Pages in System Tests]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remind that in Codeception 2.0 you need to specify each folder in the acceptance/_bootstrap.php file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
// Here you can initialize variables that will be available to your tests&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/installation&#039;);&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/administrator&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#PageObjects&lt;br /&gt;
&lt;br /&gt;
=== Step Objects ===&lt;br /&gt;
Step Objects are classes which contains steps which are to be executed on the application to perform certain operations, step objects make use of page objects to perform these actions.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginSteps extends \AcceptanceTester&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * Function to execute an Admin Login for Joomla 3&lt;br /&gt;
	 *&lt;br /&gt;
	 * @return void&lt;br /&gt;
	 */&lt;br /&gt;
	public function doAdministratorLogin($user, $password)&lt;br /&gt;
	{&lt;br /&gt;
		$I = $this;&lt;br /&gt;
		$I-&amp;gt;amOnPage(\JoomlaAdministratorLoginPage::$URL);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;username&#039;], $user);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;password&#039;], $password);&lt;br /&gt;
		$I-&amp;gt;click(&#039;Log in&#039;);&lt;br /&gt;
		$I-&amp;gt;see(&#039;Category Manager&#039;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#StepObjects&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Joomla Browser Module ===&lt;br /&gt;
The Joomla Browser is a Codeception Module that incorporates general functions to your tests like:&lt;br /&gt;
- do administrator login&lt;br /&gt;
- install joomla&lt;br /&gt;
- install extension&lt;br /&gt;
- ...&lt;br /&gt;
&lt;br /&gt;
Find details about it at: https://github.com/joomla-projects/joomla-browser#table-of-contents&lt;br /&gt;
&lt;br /&gt;
== Getting started from scratch: what you need to download and install ==&lt;br /&gt;
To get the test environment running you need to have several components installed.&lt;br /&gt;
&lt;br /&gt;
=== local webserver ===&lt;br /&gt;
If you do not already have a local test server running you may want to check out:&lt;br /&gt;
https://www.mamp.info/&lt;br /&gt;
https://www.apachefriends.org/&lt;br /&gt;
http://www.ampps.com/&lt;br /&gt;
&lt;br /&gt;
If you are not familiar with a local web-server, learn that first before you advance futher. &lt;br /&gt;
&lt;br /&gt;
===Wget===&lt;br /&gt;
Wget is a command line program that retrieves content from web servers. For our purposes it is used to get selenium (browser test environment). See wikipedia: https://en.wikipedia.org/wiki/Wget&lt;br /&gt;
====Wget on Mac====&lt;br /&gt;
For Mac Users Homebrew (package manager for OS X) is a very easy way to get wget running. Download Homebrew at: http://brew.sh/ &lt;br /&gt;
After installation run the following command in your terminal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
brew install wget&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Java Runtime Environment (JRE) ===&lt;br /&gt;
The JRE has to be installed, so the tests will be executable. You find the recent versions at the Oracle Website.&lt;br /&gt;
In end of May 2015 this is: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html&lt;br /&gt;
later on that link could be obsolete and should be changed if there is a newer version out.&lt;br /&gt;
&lt;br /&gt;
Newer Mac OS Versions are not shipped any more with the JRE, so they have to download that too.&lt;br /&gt;
&lt;br /&gt;
=== Firefox ===&lt;br /&gt;
Selenium is testing in the browser Firefox. The selenium version is not that quick with the updates, as the Firefox browser, if the test is not executable, then it can be that you manually have to install an older version of Firefox.&lt;br /&gt;
Sadly that can be a try and error thing. To get older versions of Firefox: https://ftp.mozilla.org/pub/mozilla.org/firefox/releases/ here you will find many folders. Just try the first one that came before the Firefox version that you have been using (and that did not work). In the version folders you will find folders for all the different operating systems.&lt;br /&gt;
&lt;br /&gt;
‎&lt;br /&gt;
&lt;br /&gt;
=== configure test system variables ===&lt;br /&gt;
&lt;br /&gt;
[[File:Acceptance.suite.dist.yml rename.png|thumbnail|left|Screenshot of file structure]]&lt;br /&gt;
&lt;br /&gt;
In your the folder that you installed, downloaded, pulled (git) the project, you have to rename the &amp;quot;&#039;&#039;acceptance.suite.dist.yml&#039;&#039;&amp;quot; file to &amp;quot;&#039;&#039;acceptance.suite.yml&#039;&#039;&amp;quot; and configure the parameters to your system variables.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
   config:&lt;br /&gt;
        JoomlaBrowser:&lt;br /&gt;
            url: &#039;http://localhost/tests/joomla-cms3&#039;&lt;br /&gt;
            # the url that points to the joomla installation at /tests/system/joomla-cms&lt;br /&gt;
            browser: &#039;firefox&#039;&lt;br /&gt;
            window_size: 1024x768&lt;br /&gt;
    [...]&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== then run the first test ===&lt;br /&gt;
[[File:Run Command vendor bin robo test-acceptance.png|thumbnail|left|test:acceptance]]&lt;br /&gt;
Once your machine is able to run tests (see &#039;&#039;The Joomla Browser Module&#039;&#039;), you are able to start working. Check the contents of the /tests/ folder in weblinks and try to understand the structure of the tests.&lt;br /&gt;
&lt;br /&gt;
After that check the tasks are at: https://github.com/joomla-extensions/weblinks/issues/47&lt;br /&gt;
&lt;br /&gt;
== The principles for writing a test: Readability and Performance ==&lt;br /&gt;
In Joomla we give priority to Readability over Performance, even when performance is a must.&lt;br /&gt;
&lt;br /&gt;
To explain that let me show an example: Let&#039;s say that we want to fill a field Username in a login form. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;administrator/index.php&amp;quot; method=&amp;quot;post&amp;quot; id=&amp;quot;form-login&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;username_field&amp;quot;&amp;gt;Username&amp;lt;/label&amp;gt;&lt;br /&gt;
  &amp;lt;input name=&amp;quot;username_field&amp;quot; tabindex=&amp;quot;1&amp;quot; id=&amp;quot;username_field&amp;quot; type=&amp;quot;text&amp;quot; size=&amp;quot;15&amp;quot; /&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the most performant way to fill that form field would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;#username_field&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And usually we would move that to a page object element ending in:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(\LoginPage::$username, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However Codeception is a smart framework and it adds some magic to it&#039;s methods (see: https://github.com/Codeception/Codeception/blob/2.0/src/Codeception/Module/WebDriver.php#L511-L513). It allows me to write more readable tests (keeping performance hight). &lt;br /&gt;
&lt;br /&gt;
If we do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Username&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Codeception will be smart and will search first in the page if there is any &amp;quot;LABEL&amp;quot; called Username. That is a fast operation, so performance will be affected just a little. And instead we have written less code than in previous examples.&lt;br /&gt;
&lt;br /&gt;
Note: sometimes this tricks are not always possible, labels are not always there or there are some elements hidden that shows and hides depending on a Javascript. All these special cases would require a Page element.&lt;br /&gt;
&lt;br /&gt;
Still there is a definitive method of using locators that made them readable and performant called: strict Locators see [[Testing_Joomla_Extensions_with_Codeception#Writting_reliable_locators]].&lt;br /&gt;
&lt;br /&gt;
With them we do: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField([&#039;id&#039; =&amp;gt; &#039;username_field&#039;], &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In conclusion we have more readable tests and less code to maintain while keeping performance. That is a win!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setting Up Codeception ==&lt;br /&gt;
=== setting up the repository ===&lt;br /&gt;
&#039;&#039;&#039;clone the directory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Fork [https://github.com/joomla-projects/com_localise com_localise]&lt;br /&gt;
# &lt;br /&gt;
# Git clone git@github.com:*your-github-profile-name*/com_localise.git&lt;br /&gt;
&lt;br /&gt;
=== Testing with Codeception ===&lt;br /&gt;
&lt;br /&gt;
There are two ways to get and run codeception, via PHAR or via Composer. Using &#039;&#039;&#039;Composer is recommended&#039;&#039;&#039; (because we are using in some tests the Codeception 2.1 development version not available in the composer.phar).&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Using Composer&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    You need to have Composer in your system, if not download it from here: https://getcomposer.org/&lt;br /&gt;
&lt;br /&gt;
    Step 1: composer update&lt;br /&gt;
&lt;br /&gt;
    Step 2: run Codeception by doing: php vendor/bin/codecept build&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Codeception.phar&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    Linux Machine  : wget http://codeception.com/codecept.phar&lt;br /&gt;
&lt;br /&gt;
    Windows Machine: Download from [http://codeception.com/install codecept.phar]&lt;br /&gt;
&lt;br /&gt;
    Step1 : php ./codecept.phar build&lt;br /&gt;
&lt;br /&gt;
=== Running the Test ===&lt;br /&gt;
Run Selenium server&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Download&lt;br /&gt;
curl -O http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&lt;br /&gt;
# And start the Selenium Server&lt;br /&gt;
java -Xms40m -Xmx256m -jar /Applications/XAMPP/xamppfiles/htdocs/selenium/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Rename tests/acceptance.suite.dist.yml to tests/acceptance.suite.yml&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 1: Modify the configuration at tests/acceptance.suite.yml to fit your server details.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 2: php codecept.phar run&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
with --steps to see a step-by-step report on the performed actions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --steps&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with --html. This command will run all tests for all suites, displaying the steps, and building HTML and XML reports. Reports will be store in tests/_output/ directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --html&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To activate the debug mode in Codeception just add the parameter --debug when you run the tests:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run acceptance --debug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Best Practices at Testing ==&lt;br /&gt;
=== Writting reliable locators ===&lt;br /&gt;
Writing good locators can be tricky. The Mozilla team has written an excellent guide titled [https://blog.mozilla.org/webqa/2013/09/26/writing-reliable-locators-for-selenium-and-webdriver-tests/ Writing reliable locators for Selenium and WebDriver tests].&lt;br /&gt;
&lt;br /&gt;
If the locator is an array, it should have a single element, with the key signifying the locator type (`id`, `name`, `css`, `xpath`, `link`, or `class`) and the value being the locator itself. This is called a &amp;quot;strict&amp;quot; locator. Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* [&#039;id&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div id=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;name&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div name=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;css&#039; =&amp;gt; &#039;input[type=input][value=foo]&#039;] matches `&amp;lt;input type=&amp;quot;input&amp;quot; value=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;xpath&#039; =&amp;gt; &amp;quot;//input[@type=&#039;submit&#039;][contains(@value, &#039;foo&#039;)]&amp;quot;] matches `&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;foobar&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;link&#039; =&amp;gt; &#039;Click here&#039;] matches `&amp;lt;a href=&amp;quot;google.com&amp;quot;&amp;gt;Click here&amp;lt;/a&amp;gt;`&lt;br /&gt;
* [&#039;class&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div class=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
=== How to use URLs ===&lt;br /&gt;
Codeception documentation suggests to use URL&#039;s as properties of a Page Object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(JoomlaInstallationConfigurationPage::$URL);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of hardcoding the url in the test:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The pros of this approach is:&lt;br /&gt;
- first way is more readable for non developers. &lt;br /&gt;
- it helps to make tests more maintenable in the case of a url change in the system&lt;br /&gt;
&lt;br /&gt;
However in joomla a change in an url is rare, and if it happens changing it will just be a Find&amp;amp;Replace task. I Joomla test we want to have the benefit of both, the url and a representative name that describes the page where we are going. That will make our tests more readable. Thus, we will write the urls the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amGoingTo(&#039;go to Create New Banner page at Joomla Administrator&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Working with Hidden Elements ===&lt;br /&gt;
Selenium can&#039;t interact with elements that are not visible:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;http://www.joomla.org&amp;quot; style=&amp;quot;display: none;&amp;quot; id=&amp;quot;joomla_site&amp;quot;&amp;gt;go to joomla&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case you can&#039;t do:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually this happens when you need to wait for a Javascript animation that end up showing that element, so in this case you will need to do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForElementVisible(&#039;#joomla_site&#039;);&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== When do not use contains ===&lt;br /&gt;
We do not recommend to use the function contains on XPath because is not specific and can create false positives at tests.&lt;br /&gt;
See: https://github.com/joomla-projects/GSOC-Webdriver_system_tests_for_CMS/pull/99#issuecomment-69004191&lt;br /&gt;
=== Always add Strict Locators to your tests ===&lt;br /&gt;
Performance in tests is very important. You can reduce dramatically the time spent on a test with just adding a few extra locators. For example, the following code pertains to a test:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// see($text, $selector = null)&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the previous code we are not facilitating the &amp;quot;Selector&amp;quot; so Codeception will have to search for the element in all the HTML. Doing this instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the tests went from: Time: 1.17 minutes&lt;br /&gt;
to: Time: 49.18 seconds&lt;br /&gt;
&lt;br /&gt;
You can see this video of a real example: http://www.youtube.com/watch?v=0JCv0BR2yZY&lt;br /&gt;
&lt;br /&gt;
Losing 30 seconds in every Assertion can delay your tests dramatically. Therefore, remind always to add xPath locators to all your Assertions.&lt;br /&gt;
[[Category:Automated Testing]]&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;see ====&lt;br /&gt;
Do not use &#039;&#039;see&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;waitForText ====&lt;br /&gt;
Do not use &#039;&#039;waitForText&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;, 10, [&#039;css&#039; =&amp;gt; &#039;h3&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Incase of an element has multiple css classes, When Using CSS Locators make sure you use more specific class as locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert-success&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
A page could have mutiple elements which can have &#039;&#039;alert&#039;&#039; css class associated, hence being more specific helps.&lt;br /&gt;
&lt;br /&gt;
==== How much time should I wait for an Element or Text? ====&lt;br /&gt;
You may have noticed that the second parameter in the I waitForText is an integer that represents how much &amp;quot;time to wait&amp;quot; in seconds:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;a text to wait for&#039;, 10, [&#039;...&#039; =&amp;gt; &#039;...&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But, how much time is the right time to wait for a text?&lt;br /&gt;
&lt;br /&gt;
PHP maximum execution time before returning a Fatal Error for timeout is set by default to 30 seconds. We suggest to set it for 10 seconds. A waitForText over 10 seconds will definitely mean that something is not performing well.&lt;br /&gt;
&lt;br /&gt;
=== Quote and Double Quotes in Compex XPaths ===&lt;br /&gt;
Sometimes you will have to write XPaths that looks like:&lt;br /&gt;
&lt;br /&gt;
 //button[@onclick=&#039;Joomla.submitbutton(&amp;quot;config.save.application.apply&amp;quot;)&#039;]&lt;br /&gt;
&lt;br /&gt;
When moved to a Page Object you will probably will face this situation:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_error_escaping_quotes_on_xpaths.png|framed|center|Typical issue when you write a long XPath in a Page object]]&lt;br /&gt;
&lt;br /&gt;
To avoid it remind to escape the quotes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
// Right&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=\&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)\&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Generating txt/html scenarios===&lt;br /&gt;
Codeception allows you to generate user-friendly text scenarios from scenario-driven from Cest and Cept php test (see http://codeception.com/docs/reference/Commands#GenerateScenarios).&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t use double quotes, use single quotes instead===&lt;br /&gt;
Do not use double quotes (&amp;quot;) for surrounding strings:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &amp;quot;&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;&amp;quot;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you use single quotes instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Congratulations! Joomla! is now installed.&#039;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will get the right expected result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Congratulations! Joomla! is now installed.&#039;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The reason of not being able to use double quotes is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;br /&gt;
&lt;br /&gt;
===Do not leave spaces between parameters in Cepts===&lt;br /&gt;
See the two lines:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
// Good&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;,10,&#039;h3&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Main Configuration&#039;,&amp;quot; 10&amp;quot;,&amp;quot; &#039;h3&#039;&lt;br /&gt;
&lt;br /&gt;
The reason that you are asked to not add spaces between parameters is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=File:Run_Command_vendor_bin_robo_test-acceptance.png&amp;diff=186610</id>
		<title>File:Run Command vendor bin robo test-acceptance.png</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=File:Run_Command_vendor_bin_robo_test-acceptance.png&amp;diff=186610"/>
		<updated>2015-05-30T17:29:30Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Screenshot from the terminal doing a vendor/bin/robo test:acceptance&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Screenshot from the terminal doing a vendor/bin/robo test:acceptance&lt;br /&gt;
== Licensing ==&lt;br /&gt;
{{JEDL}}&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186603</id>
		<title>Testing Joomla Extensions with Codeception</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186603"/>
		<updated>2015-05-30T17:13:32Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: /* configure test system variables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;nowiki&amp;gt;Note: this page is under construction&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What is Codeception? ==&lt;br /&gt;
Codeception PHP Testing Framework is designed to work just out of the box. This means its installation requires minimal steps and no external dependencies preinstalled (except PHP, of course). Only one configuration step should be taken and you are ready to test your web application from an eye of actual user.&lt;br /&gt;
&lt;br /&gt;
See the following video of codeception in action testing Joomla: &lt;br /&gt;
&lt;br /&gt;
{{#widget:YouTube|id=Vc1BJNnhsFM}}&lt;br /&gt;
&lt;br /&gt;
Codeception provides possibilities to do Unit Testing or to Test APIs, however this page is focused in &#039;&#039;&#039;System Testing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Why Use Codeception? ==&lt;br /&gt;
&#039;&#039;Why use Codeception when we already have Selenium IDE?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Codeception works great with Selenium. But with Codeception you can write your tests in PHP. The main reason is: Selenium IDE tests are tightly bound to XPath locators. If you ever change anything in layout tests will fall. Codeception locators are more stable. You can use names, labels, button names and CSS to match elements on page. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features&#039;&#039;&#039;&lt;br /&gt;
* Selenium WebDriver integration&lt;br /&gt;
* Elements matched by name, CSS, XPath&lt;br /&gt;
* PageObjects and StepObjects included&lt;br /&gt;
* Powered by PHPUnit&lt;br /&gt;
* Data Cleanup&lt;br /&gt;
* Parallel Execution of tests&lt;br /&gt;
* BDD-style readable tests&lt;br /&gt;
&lt;br /&gt;
== Architecture of a test ==&lt;br /&gt;
The testing framework is built on the three layered testing architecture&lt;br /&gt;
&lt;br /&gt;
=== Scenarios (Cept Class) ===&lt;br /&gt;
Cept or Test, it is the main class which contains steps of execution for the tests, Cept Class will call Step Class functions which will indirectly make use of page objects to perform operations&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I = new AcceptanceTester($scenario);&lt;br /&gt;
$I-&amp;gt;wantTo(&#039;Install Joomla CMS&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;http://localhost/installation/index.php&#039;);&lt;br /&gt;
// I Wait for the text Main Configuration, meaning that the page is loaded&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;Language Selector&#039;]);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;English (United Kingdom)&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Site Name&#039;, &#039;weblinks&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Description&#039;, &#039;Site for testing Weblinks component&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Email&#039;, $cfg[&#039;Admin email&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Username&#039;, $cfg[&#039;username&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Confirm Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;click(&#039;Next&#039;);&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page Objects ===&lt;br /&gt;
Each page on your application has a class which we call page objects, each page class will have information about the URL, fields, Text present on the page. We use the best possible selector for any field on the page.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginManagerPage&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * @var string Url of the page&lt;br /&gt;
	 */&lt;br /&gt;
	public static $URL = &#039;/administrator/index.php&#039;;&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Array of Page elements indexed by descriptive name or label&lt;br /&gt;
	 *&lt;br /&gt;
	 * @var array&lt;br /&gt;
	 */&lt;br /&gt;
	public static $elements = array(&lt;br /&gt;
		&#039;username&#039; =&amp;gt; &amp;quot;#mod-login-username&amp;quot;,&lt;br /&gt;
		&#039;password&#039; =&amp;gt; &amp;quot;#mod-login-password&amp;quot;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Naming convention for Page Objects ====&lt;br /&gt;
When this document is created Codeception 2.0 was not having a PSR-4 compatible autoloader. Therefore we are creating a convention so with the future Codeception 2.1 with PSR-4 compatible autoloader (https://github.com/Codeception/Codeception/pull/1228) we are creating a naming convention for Pages so it will cost us a small effort to move to autoloaded classes in the future.&lt;br /&gt;
&lt;br /&gt;
The naming convention works as follows:&lt;br /&gt;
&lt;br /&gt;
 APPLICATION (for example Joomla, Patchtester, Weblinks or your Extension name)&lt;br /&gt;
 + CLIENT (in Joomla we use it for defining if is Installation, Administrator or Frontend&lt;br /&gt;
 + CLIENT PART (In Joomla we use it following the menu are were it belongs: Components, Menus, System,...)&lt;br /&gt;
 + PAGE NAME (The Page name) &lt;br /&gt;
 + Page&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
 JoomlaAdministratorLoginPage&lt;br /&gt;
 JoomlaAdministratorSystemGlobalconfigurationPage&lt;br /&gt;
 JoomlaInstallationConfigurationPage&lt;br /&gt;
&lt;br /&gt;
And they are located with a folder estructure similar to:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_pages_folder_structure.png|framed|center|Folder estructure for Pages in System Tests]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remind that in Codeception 2.0 you need to specify each folder in the acceptance/_bootstrap.php file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
// Here you can initialize variables that will be available to your tests&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/installation&#039;);&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/administrator&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#PageObjects&lt;br /&gt;
&lt;br /&gt;
=== Step Objects ===&lt;br /&gt;
Step Objects are classes which contains steps which are to be executed on the application to perform certain operations, step objects make use of page objects to perform these actions.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginSteps extends \AcceptanceTester&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * Function to execute an Admin Login for Joomla 3&lt;br /&gt;
	 *&lt;br /&gt;
	 * @return void&lt;br /&gt;
	 */&lt;br /&gt;
	public function doAdministratorLogin($user, $password)&lt;br /&gt;
	{&lt;br /&gt;
		$I = $this;&lt;br /&gt;
		$I-&amp;gt;amOnPage(\JoomlaAdministratorLoginPage::$URL);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;username&#039;], $user);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;password&#039;], $password);&lt;br /&gt;
		$I-&amp;gt;click(&#039;Log in&#039;);&lt;br /&gt;
		$I-&amp;gt;see(&#039;Category Manager&#039;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#StepObjects&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Joomla Browser Module ===&lt;br /&gt;
The Joomla Browser is a Codeception Module that incorporates general functions to your tests like:&lt;br /&gt;
- do administrator login&lt;br /&gt;
- install joomla&lt;br /&gt;
- install extension&lt;br /&gt;
- ...&lt;br /&gt;
&lt;br /&gt;
Find details about it at: https://github.com/joomla-projects/joomla-browser#table-of-contents&lt;br /&gt;
&lt;br /&gt;
== Getting started from scratch: what you need to download and install ==&lt;br /&gt;
To get the test environment running you need to have several components installed.&lt;br /&gt;
&lt;br /&gt;
=== local webserver ===&lt;br /&gt;
If you do not already have a local test server running you may want to check out:&lt;br /&gt;
https://www.mamp.info/&lt;br /&gt;
https://www.apachefriends.org/&lt;br /&gt;
http://www.ampps.com/&lt;br /&gt;
&lt;br /&gt;
If you are not familiar with a local web-server, learn that first before you advance futher. &lt;br /&gt;
&lt;br /&gt;
===Wget===&lt;br /&gt;
Wget is a command line program that retrieves content from web servers. For our purposes it is used to get selenium (browser test environment). See wikipedia: https://en.wikipedia.org/wiki/Wget&lt;br /&gt;
====Wget on Mac====&lt;br /&gt;
For Mac Users Homebrew (package manager for OS X) is a very easy way to get wget running. Download Homebrew at: http://brew.sh/ &lt;br /&gt;
After installation run the following command in your terminal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
brew install wget&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Java Runtime Environment (JRE) ===&lt;br /&gt;
The JRE has to be installed, so the tests will be executable. You find the recent versions at the Oracle Website.&lt;br /&gt;
In end of May 2015 this is: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html&lt;br /&gt;
later on that link could be obsolete and should be changed if there is a newer version out.&lt;br /&gt;
&lt;br /&gt;
Newer Mac OS Versions are not shipped any more with the JRE, so they have to download that too.&lt;br /&gt;
&lt;br /&gt;
=== Firefox ===&lt;br /&gt;
Selenium is testing in the browser Firefox. The selenium version is not that quick with the updates, as the Firefox browser, if the test is not executable, then it can be that you manually have to install an older version of Firefox.&lt;br /&gt;
Sadly that can be a try and error thing. To get older versions of Firefox: https://ftp.mozilla.org/pub/mozilla.org/firefox/releases/ here you will find many folders. Just try the first one that came before the Firefox version that you have been using (and that did not work). In the version folders you will find folders for all the different operating systems.&lt;br /&gt;
&lt;br /&gt;
‎&lt;br /&gt;
&lt;br /&gt;
=== configure test system variables ===&lt;br /&gt;
&lt;br /&gt;
[[File:Acceptance.suite.dist.yml rename.png|thumbnail|left|Screenshot of file structure]]&lt;br /&gt;
&lt;br /&gt;
In your the folder that you installed, downloaded, pulled (git) the project, you have to rename the &amp;quot;&#039;&#039;acceptance.suite.dist.yml&#039;&#039;&amp;quot; file to &amp;quot;&#039;&#039;acceptance.suite.yml&#039;&#039;&amp;quot; and configure the parameters to your system variables.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
   config:&lt;br /&gt;
        JoomlaBrowser:&lt;br /&gt;
            url: &#039;http://localhost/tests/joomla-cms3&#039;&lt;br /&gt;
            # the url that points to the joomla installation at /tests/system/joomla-cms&lt;br /&gt;
            browser: &#039;firefox&#039;&lt;br /&gt;
            window_size: 1024x768&lt;br /&gt;
    [...]&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== then run the first test ===&lt;br /&gt;
Once your machine is able to run tests (see &#039;&#039;The Joomla Browser Module&#039;&#039;), you are able to start working. Check the contents of the /tests/ folder in weblinks and try to understand the structure of the tests. After that check&lt;br /&gt;
the tasks are at: https://github.com/joomla-extensions/weblinks/issues/47 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The principles for writing a test: Readability and Performance ==&lt;br /&gt;
In Joomla we give priority to Readability over Performance, even when performance is a must.&lt;br /&gt;
&lt;br /&gt;
To explain that let me show an example: Let&#039;s say that we want to fill a field Username in a login form. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;administrator/index.php&amp;quot; method=&amp;quot;post&amp;quot; id=&amp;quot;form-login&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;username_field&amp;quot;&amp;gt;Username&amp;lt;/label&amp;gt;&lt;br /&gt;
  &amp;lt;input name=&amp;quot;username_field&amp;quot; tabindex=&amp;quot;1&amp;quot; id=&amp;quot;username_field&amp;quot; type=&amp;quot;text&amp;quot; size=&amp;quot;15&amp;quot; /&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the most performant way to fill that form field would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;#username_field&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And usually we would move that to a page object element ending in:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(\LoginPage::$username, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However Codeception is a smart framework and it adds some magic to it&#039;s methods (see: https://github.com/Codeception/Codeception/blob/2.0/src/Codeception/Module/WebDriver.php#L511-L513). It allows me to write more readable tests (keeping performance hight). &lt;br /&gt;
&lt;br /&gt;
If we do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Username&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Codeception will be smart and will search first in the page if there is any &amp;quot;LABEL&amp;quot; called Username. That is a fast operation, so performance will be affected just a little. And instead we have written less code than in previous examples.&lt;br /&gt;
&lt;br /&gt;
Note: sometimes this tricks are not always possible, labels are not always there or there are some elements hidden that shows and hides depending on a Javascript. All these special cases would require a Page element.&lt;br /&gt;
&lt;br /&gt;
Still there is a definitive method of using locators that made them readable and performant called: strict Locators see [[Testing_Joomla_Extensions_with_Codeception#Writting_reliable_locators]].&lt;br /&gt;
&lt;br /&gt;
With them we do: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField([&#039;id&#039; =&amp;gt; &#039;username_field&#039;], &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In conclusion we have more readable tests and less code to maintain while keeping performance. That is a win!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setting Up Codeception ==&lt;br /&gt;
=== setting up the repository ===&lt;br /&gt;
&#039;&#039;&#039;clone the directory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Fork [https://github.com/joomla-projects/com_localise com_localise]&lt;br /&gt;
# &lt;br /&gt;
# Git clone git@github.com:*your-github-profile-name*/com_localise.git&lt;br /&gt;
&lt;br /&gt;
=== Testing with Codeception ===&lt;br /&gt;
&lt;br /&gt;
There are two ways to get and run codeception, via PHAR or via Composer. Using &#039;&#039;&#039;Composer is recommended&#039;&#039;&#039; (because we are using in some tests the Codeception 2.1 development version not available in the composer.phar).&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Using Composer&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    You need to have Composer in your system, if not download it from here: https://getcomposer.org/&lt;br /&gt;
&lt;br /&gt;
    Step 1: composer update&lt;br /&gt;
&lt;br /&gt;
    Step 2: run Codeception by doing: php vendor/bin/codecept build&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Codeception.phar&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    Linux Machine  : wget http://codeception.com/codecept.phar&lt;br /&gt;
&lt;br /&gt;
    Windows Machine: Download from [http://codeception.com/install codecept.phar]&lt;br /&gt;
&lt;br /&gt;
    Step1 : php ./codecept.phar build&lt;br /&gt;
&lt;br /&gt;
=== Running the Test ===&lt;br /&gt;
Run Selenium server&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Download&lt;br /&gt;
curl -O http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&lt;br /&gt;
# And start the Selenium Server&lt;br /&gt;
java -Xms40m -Xmx256m -jar /Applications/XAMPP/xamppfiles/htdocs/selenium/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Rename tests/acceptance.suite.dist.yml to tests/acceptance.suite.yml&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 1: Modify the configuration at tests/acceptance.suite.yml to fit your server details.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 2: php codecept.phar run&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
with --steps to see a step-by-step report on the performed actions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --steps&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with --html. This command will run all tests for all suites, displaying the steps, and building HTML and XML reports. Reports will be store in tests/_output/ directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --html&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To activate the debug mode in Codeception just add the parameter --debug when you run the tests:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run acceptance --debug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Best Practices at Testing ==&lt;br /&gt;
=== Writting reliable locators ===&lt;br /&gt;
Writing good locators can be tricky. The Mozilla team has written an excellent guide titled [https://blog.mozilla.org/webqa/2013/09/26/writing-reliable-locators-for-selenium-and-webdriver-tests/ Writing reliable locators for Selenium and WebDriver tests].&lt;br /&gt;
&lt;br /&gt;
If the locator is an array, it should have a single element, with the key signifying the locator type (`id`, `name`, `css`, `xpath`, `link`, or `class`) and the value being the locator itself. This is called a &amp;quot;strict&amp;quot; locator. Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* [&#039;id&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div id=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;name&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div name=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;css&#039; =&amp;gt; &#039;input[type=input][value=foo]&#039;] matches `&amp;lt;input type=&amp;quot;input&amp;quot; value=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;xpath&#039; =&amp;gt; &amp;quot;//input[@type=&#039;submit&#039;][contains(@value, &#039;foo&#039;)]&amp;quot;] matches `&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;foobar&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;link&#039; =&amp;gt; &#039;Click here&#039;] matches `&amp;lt;a href=&amp;quot;google.com&amp;quot;&amp;gt;Click here&amp;lt;/a&amp;gt;`&lt;br /&gt;
* [&#039;class&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div class=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
=== How to use URLs ===&lt;br /&gt;
Codeception documentation suggests to use URL&#039;s as properties of a Page Object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(JoomlaInstallationConfigurationPage::$URL);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of hardcoding the url in the test:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The pros of this approach is:&lt;br /&gt;
- first way is more readable for non developers. &lt;br /&gt;
- it helps to make tests more maintenable in the case of a url change in the system&lt;br /&gt;
&lt;br /&gt;
However in joomla a change in an url is rare, and if it happens changing it will just be a Find&amp;amp;Replace task. I Joomla test we want to have the benefit of both, the url and a representative name that describes the page where we are going. That will make our tests more readable. Thus, we will write the urls the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amGoingTo(&#039;go to Create New Banner page at Joomla Administrator&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Working with Hidden Elements ===&lt;br /&gt;
Selenium can&#039;t interact with elements that are not visible:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;http://www.joomla.org&amp;quot; style=&amp;quot;display: none;&amp;quot; id=&amp;quot;joomla_site&amp;quot;&amp;gt;go to joomla&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case you can&#039;t do:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually this happens when you need to wait for a Javascript animation that end up showing that element, so in this case you will need to do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForElementVisible(&#039;#joomla_site&#039;);&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== When do not use contains ===&lt;br /&gt;
We do not recommend to use the function contains on XPath because is not specific and can create false positives at tests.&lt;br /&gt;
See: https://github.com/joomla-projects/GSOC-Webdriver_system_tests_for_CMS/pull/99#issuecomment-69004191&lt;br /&gt;
=== Always add Strict Locators to your tests ===&lt;br /&gt;
Performance in tests is very important. You can reduce dramatically the time spent on a test with just adding a few extra locators. For example, the following code pertains to a test:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// see($text, $selector = null)&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the previous code we are not facilitating the &amp;quot;Selector&amp;quot; so Codeception will have to search for the element in all the HTML. Doing this instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the tests went from: Time: 1.17 minutes&lt;br /&gt;
to: Time: 49.18 seconds&lt;br /&gt;
&lt;br /&gt;
You can see this video of a real example: http://www.youtube.com/watch?v=0JCv0BR2yZY&lt;br /&gt;
&lt;br /&gt;
Losing 30 seconds in every Assertion can delay your tests dramatically. Therefore, remind always to add xPath locators to all your Assertions.&lt;br /&gt;
[[Category:Automated Testing]]&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;see ====&lt;br /&gt;
Do not use &#039;&#039;see&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;waitForText ====&lt;br /&gt;
Do not use &#039;&#039;waitForText&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;, 10, [&#039;css&#039; =&amp;gt; &#039;h3&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Incase of an element has multiple css classes, When Using CSS Locators make sure you use more specific class as locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert-success&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
A page could have mutiple elements which can have &#039;&#039;alert&#039;&#039; css class associated, hence being more specific helps.&lt;br /&gt;
&lt;br /&gt;
==== How much time should I wait for an Element or Text? ====&lt;br /&gt;
You may have noticed that the second parameter in the I waitForText is an integer that represents how much &amp;quot;time to wait&amp;quot; in seconds:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;a text to wait for&#039;, 10, [&#039;...&#039; =&amp;gt; &#039;...&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But, how much time is the right time to wait for a text?&lt;br /&gt;
&lt;br /&gt;
PHP maximum execution time before returning a Fatal Error for timeout is set by default to 30 seconds. We suggest to set it for 10 seconds. A waitForText over 10 seconds will definitely mean that something is not performing well.&lt;br /&gt;
&lt;br /&gt;
=== Quote and Double Quotes in Compex XPaths ===&lt;br /&gt;
Sometimes you will have to write XPaths that looks like:&lt;br /&gt;
&lt;br /&gt;
 //button[@onclick=&#039;Joomla.submitbutton(&amp;quot;config.save.application.apply&amp;quot;)&#039;]&lt;br /&gt;
&lt;br /&gt;
When moved to a Page Object you will probably will face this situation:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_error_escaping_quotes_on_xpaths.png|framed|center|Typical issue when you write a long XPath in a Page object]]&lt;br /&gt;
&lt;br /&gt;
To avoid it remind to escape the quotes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
// Right&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=\&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)\&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Generating txt/html scenarios===&lt;br /&gt;
Codeception allows you to generate user-friendly text scenarios from scenario-driven from Cest and Cept php test (see http://codeception.com/docs/reference/Commands#GenerateScenarios).&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t use double quotes, use single quotes instead===&lt;br /&gt;
Do not use double quotes (&amp;quot;) for surrounding strings:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &amp;quot;&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;&amp;quot;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you use single quotes instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Congratulations! Joomla! is now installed.&#039;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will get the right expected result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Congratulations! Joomla! is now installed.&#039;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The reason of not being able to use double quotes is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;br /&gt;
&lt;br /&gt;
===Do not leave spaces between parameters in Cepts===&lt;br /&gt;
See the two lines:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
// Good&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;,10,&#039;h3&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Main Configuration&#039;,&amp;quot; 10&amp;quot;,&amp;quot; &#039;h3&#039;&lt;br /&gt;
&lt;br /&gt;
The reason that you are asked to not add spaces between parameters is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186596</id>
		<title>Testing Joomla Extensions with Codeception</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186596"/>
		<updated>2015-05-30T16:57:35Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: /* configure test system variables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;nowiki&amp;gt;Note: this page is under construction&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What is Codeception? ==&lt;br /&gt;
Codeception PHP Testing Framework is designed to work just out of the box. This means its installation requires minimal steps and no external dependencies preinstalled (except PHP, of course). Only one configuration step should be taken and you are ready to test your web application from an eye of actual user.&lt;br /&gt;
&lt;br /&gt;
See the following video of codeception in action testing Joomla: &lt;br /&gt;
&lt;br /&gt;
{{#widget:YouTube|id=Vc1BJNnhsFM}}&lt;br /&gt;
&lt;br /&gt;
Codeception provides possibilities to do Unit Testing or to Test APIs, however this page is focused in &#039;&#039;&#039;System Testing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Why Use Codeception? ==&lt;br /&gt;
&#039;&#039;Why use Codeception when we already have Selenium IDE?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Codeception works great with Selenium. But with Codeception you can write your tests in PHP. The main reason is: Selenium IDE tests are tightly bound to XPath locators. If you ever change anything in layout tests will fall. Codeception locators are more stable. You can use names, labels, button names and CSS to match elements on page. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features&#039;&#039;&#039;&lt;br /&gt;
* Selenium WebDriver integration&lt;br /&gt;
* Elements matched by name, CSS, XPath&lt;br /&gt;
* PageObjects and StepObjects included&lt;br /&gt;
* Powered by PHPUnit&lt;br /&gt;
* Data Cleanup&lt;br /&gt;
* Parallel Execution of tests&lt;br /&gt;
* BDD-style readable tests&lt;br /&gt;
&lt;br /&gt;
== Architecture of a test ==&lt;br /&gt;
The testing framework is built on the three layered testing architecture&lt;br /&gt;
&lt;br /&gt;
=== Scenarios (Cept Class) ===&lt;br /&gt;
Cept or Test, it is the main class which contains steps of execution for the tests, Cept Class will call Step Class functions which will indirectly make use of page objects to perform operations&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I = new AcceptanceTester($scenario);&lt;br /&gt;
$I-&amp;gt;wantTo(&#039;Install Joomla CMS&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;http://localhost/installation/index.php&#039;);&lt;br /&gt;
// I Wait for the text Main Configuration, meaning that the page is loaded&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;Language Selector&#039;]);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;English (United Kingdom)&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Site Name&#039;, &#039;weblinks&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Description&#039;, &#039;Site for testing Weblinks component&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Email&#039;, $cfg[&#039;Admin email&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Username&#039;, $cfg[&#039;username&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Confirm Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;click(&#039;Next&#039;);&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page Objects ===&lt;br /&gt;
Each page on your application has a class which we call page objects, each page class will have information about the URL, fields, Text present on the page. We use the best possible selector for any field on the page.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginManagerPage&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * @var string Url of the page&lt;br /&gt;
	 */&lt;br /&gt;
	public static $URL = &#039;/administrator/index.php&#039;;&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Array of Page elements indexed by descriptive name or label&lt;br /&gt;
	 *&lt;br /&gt;
	 * @var array&lt;br /&gt;
	 */&lt;br /&gt;
	public static $elements = array(&lt;br /&gt;
		&#039;username&#039; =&amp;gt; &amp;quot;#mod-login-username&amp;quot;,&lt;br /&gt;
		&#039;password&#039; =&amp;gt; &amp;quot;#mod-login-password&amp;quot;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Naming convention for Page Objects ====&lt;br /&gt;
When this document is created Codeception 2.0 was not having a PSR-4 compatible autoloader. Therefore we are creating a convention so with the future Codeception 2.1 with PSR-4 compatible autoloader (https://github.com/Codeception/Codeception/pull/1228) we are creating a naming convention for Pages so it will cost us a small effort to move to autoloaded classes in the future.&lt;br /&gt;
&lt;br /&gt;
The naming convention works as follows:&lt;br /&gt;
&lt;br /&gt;
 APPLICATION (for example Joomla, Patchtester, Weblinks or your Extension name)&lt;br /&gt;
 + CLIENT (in Joomla we use it for defining if is Installation, Administrator or Frontend&lt;br /&gt;
 + CLIENT PART (In Joomla we use it following the menu are were it belongs: Components, Menus, System,...)&lt;br /&gt;
 + PAGE NAME (The Page name) &lt;br /&gt;
 + Page&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
 JoomlaAdministratorLoginPage&lt;br /&gt;
 JoomlaAdministratorSystemGlobalconfigurationPage&lt;br /&gt;
 JoomlaInstallationConfigurationPage&lt;br /&gt;
&lt;br /&gt;
And they are located with a folder estructure similar to:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_pages_folder_structure.png|framed|center|Folder estructure for Pages in System Tests]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remind that in Codeception 2.0 you need to specify each folder in the acceptance/_bootstrap.php file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
// Here you can initialize variables that will be available to your tests&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/installation&#039;);&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/administrator&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#PageObjects&lt;br /&gt;
&lt;br /&gt;
=== Step Objects ===&lt;br /&gt;
Step Objects are classes which contains steps which are to be executed on the application to perform certain operations, step objects make use of page objects to perform these actions.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginSteps extends \AcceptanceTester&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * Function to execute an Admin Login for Joomla 3&lt;br /&gt;
	 *&lt;br /&gt;
	 * @return void&lt;br /&gt;
	 */&lt;br /&gt;
	public function doAdministratorLogin($user, $password)&lt;br /&gt;
	{&lt;br /&gt;
		$I = $this;&lt;br /&gt;
		$I-&amp;gt;amOnPage(\JoomlaAdministratorLoginPage::$URL);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;username&#039;], $user);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;password&#039;], $password);&lt;br /&gt;
		$I-&amp;gt;click(&#039;Log in&#039;);&lt;br /&gt;
		$I-&amp;gt;see(&#039;Category Manager&#039;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#StepObjects&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Joomla Browser Module ===&lt;br /&gt;
The Joomla Browser is a Codeception Module that incorporates general functions to your tests like:&lt;br /&gt;
- do administrator login&lt;br /&gt;
- install joomla&lt;br /&gt;
- install extension&lt;br /&gt;
- ...&lt;br /&gt;
&lt;br /&gt;
Find details about it at: https://github.com/joomla-projects/joomla-browser#table-of-contents&lt;br /&gt;
&lt;br /&gt;
== Getting started from scratch: what you need to download and install ==&lt;br /&gt;
To get the test environment running you need to have several components installed.&lt;br /&gt;
&lt;br /&gt;
=== local webserver ===&lt;br /&gt;
If you do not already have a local test server running you may want to check out:&lt;br /&gt;
https://www.mamp.info/&lt;br /&gt;
https://www.apachefriends.org/&lt;br /&gt;
http://www.ampps.com/&lt;br /&gt;
&lt;br /&gt;
If you are not familiar with a local web-server, learn that first before you advance futher. &lt;br /&gt;
&lt;br /&gt;
===Wget===&lt;br /&gt;
Wget is a command line program that retrieves content from web servers. For our purposes it is used to get selenium (browser test environment). See wikipedia: https://en.wikipedia.org/wiki/Wget&lt;br /&gt;
====Wget on Mac====&lt;br /&gt;
For Mac Users Homebrew (package manager for OS X) is a very easy way to get wget running. Download Homebrew at: http://brew.sh/ &lt;br /&gt;
After installation run the following command in your terminal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
brew install wget&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Java Runtime Environment (JRE) ===&lt;br /&gt;
The JRE has to be installed, so the tests will be executable. You find the recent versions at the Oracle Website.&lt;br /&gt;
In end of May 2015 this is: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html&lt;br /&gt;
later on that link could be obsolete and should be changed if there is a newer version out.&lt;br /&gt;
&lt;br /&gt;
Newer Mac OS Versions are not shipped any more with the JRE, so they have to download that too.&lt;br /&gt;
&lt;br /&gt;
=== Firefox ===&lt;br /&gt;
Selenium is testing in the browser Firefox. The selenium version is not that quick with the updates, as the Firefox browser, if the test is not executable, then it can be that you manually have to install an older version of Firefox.&lt;br /&gt;
Sadly that can be a try and error thing. To get older versions of Firefox: https://ftp.mozilla.org/pub/mozilla.org/firefox/releases/ here you will find many folders. Just try the first one that came before the Firefox version that you have been using (and that did not work). In the version folders you will find folders for all the different operating systems.&lt;br /&gt;
&lt;br /&gt;
‎&lt;br /&gt;
&lt;br /&gt;
=== configure test system variables ===&lt;br /&gt;
&lt;br /&gt;
[[File:Acceptance.suite.dist.yml rename.png|thumbnail|right|Screenshot of file structure]]&lt;br /&gt;
&lt;br /&gt;
In your the folder that you installed, downloaded, pulled (git) the project, you have to rename the &amp;quot;&#039;&#039;acceptance.suite.dist.yml&#039;&#039;&amp;quot; file to &amp;quot;&#039;&#039;acceptance.suite.yml&#039;&#039;&amp;quot; and configure the parameters to your system variables.&lt;br /&gt;
&lt;br /&gt;
=== then run the first test ===&lt;br /&gt;
Once your machine is able to run tests (see &#039;&#039;The Joomla Browser Module&#039;&#039;), you are able to start working. Check the contents of the /tests/ folder in weblinks and try to understand the structure of the tests. After that check&lt;br /&gt;
the tasks are at: https://github.com/joomla-extensions/weblinks/issues/47 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The principles for writing a test: Readability and Performance ==&lt;br /&gt;
In Joomla we give priority to Readability over Performance, even when performance is a must.&lt;br /&gt;
&lt;br /&gt;
To explain that let me show an example: Let&#039;s say that we want to fill a field Username in a login form. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;administrator/index.php&amp;quot; method=&amp;quot;post&amp;quot; id=&amp;quot;form-login&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;username_field&amp;quot;&amp;gt;Username&amp;lt;/label&amp;gt;&lt;br /&gt;
  &amp;lt;input name=&amp;quot;username_field&amp;quot; tabindex=&amp;quot;1&amp;quot; id=&amp;quot;username_field&amp;quot; type=&amp;quot;text&amp;quot; size=&amp;quot;15&amp;quot; /&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the most performant way to fill that form field would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;#username_field&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And usually we would move that to a page object element ending in:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(\LoginPage::$username, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However Codeception is a smart framework and it adds some magic to it&#039;s methods (see: https://github.com/Codeception/Codeception/blob/2.0/src/Codeception/Module/WebDriver.php#L511-L513). It allows me to write more readable tests (keeping performance hight). &lt;br /&gt;
&lt;br /&gt;
If we do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Username&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Codeception will be smart and will search first in the page if there is any &amp;quot;LABEL&amp;quot; called Username. That is a fast operation, so performance will be affected just a little. And instead we have written less code than in previous examples.&lt;br /&gt;
&lt;br /&gt;
Note: sometimes this tricks are not always possible, labels are not always there or there are some elements hidden that shows and hides depending on a Javascript. All these special cases would require a Page element.&lt;br /&gt;
&lt;br /&gt;
Still there is a definitive method of using locators that made them readable and performant called: strict Locators see [[Testing_Joomla_Extensions_with_Codeception#Writting_reliable_locators]].&lt;br /&gt;
&lt;br /&gt;
With them we do: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField([&#039;id&#039; =&amp;gt; &#039;username_field&#039;], &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In conclusion we have more readable tests and less code to maintain while keeping performance. That is a win!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setting Up Codeception ==&lt;br /&gt;
=== setting up the repository ===&lt;br /&gt;
&#039;&#039;&#039;clone the directory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Fork [https://github.com/joomla-projects/com_localise com_localise]&lt;br /&gt;
# &lt;br /&gt;
# Git clone git@github.com:*your-github-profile-name*/com_localise.git&lt;br /&gt;
&lt;br /&gt;
=== Testing with Codeception ===&lt;br /&gt;
&lt;br /&gt;
There are two ways to get and run codeception, via PHAR or via Composer. Using &#039;&#039;&#039;Composer is recommended&#039;&#039;&#039; (because we are using in some tests the Codeception 2.1 development version not available in the composer.phar).&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Using Composer&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    You need to have Composer in your system, if not download it from here: https://getcomposer.org/&lt;br /&gt;
&lt;br /&gt;
    Step 1: composer update&lt;br /&gt;
&lt;br /&gt;
    Step 2: run Codeception by doing: php vendor/bin/codecept build&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Codeception.phar&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    Linux Machine  : wget http://codeception.com/codecept.phar&lt;br /&gt;
&lt;br /&gt;
    Windows Machine: Download from [http://codeception.com/install codecept.phar]&lt;br /&gt;
&lt;br /&gt;
    Step1 : php ./codecept.phar build&lt;br /&gt;
&lt;br /&gt;
=== Running the Test ===&lt;br /&gt;
Run Selenium server&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Download&lt;br /&gt;
curl -O http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&lt;br /&gt;
# And start the Selenium Server&lt;br /&gt;
java -Xms40m -Xmx256m -jar /Applications/XAMPP/xamppfiles/htdocs/selenium/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Rename tests/acceptance.suite.dist.yml to tests/acceptance.suite.yml&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 1: Modify the configuration at tests/acceptance.suite.yml to fit your server details.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 2: php codecept.phar run&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
with --steps to see a step-by-step report on the performed actions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --steps&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with --html. This command will run all tests for all suites, displaying the steps, and building HTML and XML reports. Reports will be store in tests/_output/ directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --html&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To activate the debug mode in Codeception just add the parameter --debug when you run the tests:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run acceptance --debug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Best Practices at Testing ==&lt;br /&gt;
=== Writting reliable locators ===&lt;br /&gt;
Writing good locators can be tricky. The Mozilla team has written an excellent guide titled [https://blog.mozilla.org/webqa/2013/09/26/writing-reliable-locators-for-selenium-and-webdriver-tests/ Writing reliable locators for Selenium and WebDriver tests].&lt;br /&gt;
&lt;br /&gt;
If the locator is an array, it should have a single element, with the key signifying the locator type (`id`, `name`, `css`, `xpath`, `link`, or `class`) and the value being the locator itself. This is called a &amp;quot;strict&amp;quot; locator. Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* [&#039;id&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div id=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;name&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div name=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;css&#039; =&amp;gt; &#039;input[type=input][value=foo]&#039;] matches `&amp;lt;input type=&amp;quot;input&amp;quot; value=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;xpath&#039; =&amp;gt; &amp;quot;//input[@type=&#039;submit&#039;][contains(@value, &#039;foo&#039;)]&amp;quot;] matches `&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;foobar&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;link&#039; =&amp;gt; &#039;Click here&#039;] matches `&amp;lt;a href=&amp;quot;google.com&amp;quot;&amp;gt;Click here&amp;lt;/a&amp;gt;`&lt;br /&gt;
* [&#039;class&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div class=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
=== How to use URLs ===&lt;br /&gt;
Codeception documentation suggests to use URL&#039;s as properties of a Page Object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(JoomlaInstallationConfigurationPage::$URL);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of hardcoding the url in the test:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The pros of this approach is:&lt;br /&gt;
- first way is more readable for non developers. &lt;br /&gt;
- it helps to make tests more maintenable in the case of a url change in the system&lt;br /&gt;
&lt;br /&gt;
However in joomla a change in an url is rare, and if it happens changing it will just be a Find&amp;amp;Replace task. I Joomla test we want to have the benefit of both, the url and a representative name that describes the page where we are going. That will make our tests more readable. Thus, we will write the urls the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amGoingTo(&#039;go to Create New Banner page at Joomla Administrator&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Working with Hidden Elements ===&lt;br /&gt;
Selenium can&#039;t interact with elements that are not visible:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;http://www.joomla.org&amp;quot; style=&amp;quot;display: none;&amp;quot; id=&amp;quot;joomla_site&amp;quot;&amp;gt;go to joomla&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case you can&#039;t do:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually this happens when you need to wait for a Javascript animation that end up showing that element, so in this case you will need to do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForElementVisible(&#039;#joomla_site&#039;);&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== When do not use contains ===&lt;br /&gt;
We do not recommend to use the function contains on XPath because is not specific and can create false positives at tests.&lt;br /&gt;
See: https://github.com/joomla-projects/GSOC-Webdriver_system_tests_for_CMS/pull/99#issuecomment-69004191&lt;br /&gt;
=== Always add Strict Locators to your tests ===&lt;br /&gt;
Performance in tests is very important. You can reduce dramatically the time spent on a test with just adding a few extra locators. For example, the following code pertains to a test:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// see($text, $selector = null)&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the previous code we are not facilitating the &amp;quot;Selector&amp;quot; so Codeception will have to search for the element in all the HTML. Doing this instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the tests went from: Time: 1.17 minutes&lt;br /&gt;
to: Time: 49.18 seconds&lt;br /&gt;
&lt;br /&gt;
You can see this video of a real example: http://www.youtube.com/watch?v=0JCv0BR2yZY&lt;br /&gt;
&lt;br /&gt;
Losing 30 seconds in every Assertion can delay your tests dramatically. Therefore, remind always to add xPath locators to all your Assertions.&lt;br /&gt;
[[Category:Automated Testing]]&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;see ====&lt;br /&gt;
Do not use &#039;&#039;see&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;waitForText ====&lt;br /&gt;
Do not use &#039;&#039;waitForText&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;, 10, [&#039;css&#039; =&amp;gt; &#039;h3&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Incase of an element has multiple css classes, When Using CSS Locators make sure you use more specific class as locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert-success&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
A page could have mutiple elements which can have &#039;&#039;alert&#039;&#039; css class associated, hence being more specific helps.&lt;br /&gt;
&lt;br /&gt;
==== How much time should I wait for an Element or Text? ====&lt;br /&gt;
You may have noticed that the second parameter in the I waitForText is an integer that represents how much &amp;quot;time to wait&amp;quot; in seconds:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;a text to wait for&#039;, 10, [&#039;...&#039; =&amp;gt; &#039;...&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But, how much time is the right time to wait for a text?&lt;br /&gt;
&lt;br /&gt;
PHP maximum execution time before returning a Fatal Error for timeout is set by default to 30 seconds. We suggest to set it for 10 seconds. A waitForText over 10 seconds will definitely mean that something is not performing well.&lt;br /&gt;
&lt;br /&gt;
=== Quote and Double Quotes in Compex XPaths ===&lt;br /&gt;
Sometimes you will have to write XPaths that looks like:&lt;br /&gt;
&lt;br /&gt;
 //button[@onclick=&#039;Joomla.submitbutton(&amp;quot;config.save.application.apply&amp;quot;)&#039;]&lt;br /&gt;
&lt;br /&gt;
When moved to a Page Object you will probably will face this situation:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_error_escaping_quotes_on_xpaths.png|framed|center|Typical issue when you write a long XPath in a Page object]]&lt;br /&gt;
&lt;br /&gt;
To avoid it remind to escape the quotes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
// Right&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=\&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)\&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Generating txt/html scenarios===&lt;br /&gt;
Codeception allows you to generate user-friendly text scenarios from scenario-driven from Cest and Cept php test (see http://codeception.com/docs/reference/Commands#GenerateScenarios).&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t use double quotes, use single quotes instead===&lt;br /&gt;
Do not use double quotes (&amp;quot;) for surrounding strings:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &amp;quot;&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;&amp;quot;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you use single quotes instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Congratulations! Joomla! is now installed.&#039;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will get the right expected result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Congratulations! Joomla! is now installed.&#039;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The reason of not being able to use double quotes is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;br /&gt;
&lt;br /&gt;
===Do not leave spaces between parameters in Cepts===&lt;br /&gt;
See the two lines:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
// Good&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;,10,&#039;h3&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Main Configuration&#039;,&amp;quot; 10&amp;quot;,&amp;quot; &#039;h3&#039;&lt;br /&gt;
&lt;br /&gt;
The reason that you are asked to not add spaces between parameters is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186593</id>
		<title>Testing Joomla Extensions with Codeception</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186593"/>
		<updated>2015-05-30T16:56:22Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: /* Firefox */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;nowiki&amp;gt;Note: this page is under construction&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What is Codeception? ==&lt;br /&gt;
Codeception PHP Testing Framework is designed to work just out of the box. This means its installation requires minimal steps and no external dependencies preinstalled (except PHP, of course). Only one configuration step should be taken and you are ready to test your web application from an eye of actual user.&lt;br /&gt;
&lt;br /&gt;
See the following video of codeception in action testing Joomla: &lt;br /&gt;
&lt;br /&gt;
{{#widget:YouTube|id=Vc1BJNnhsFM}}&lt;br /&gt;
&lt;br /&gt;
Codeception provides possibilities to do Unit Testing or to Test APIs, however this page is focused in &#039;&#039;&#039;System Testing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Why Use Codeception? ==&lt;br /&gt;
&#039;&#039;Why use Codeception when we already have Selenium IDE?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Codeception works great with Selenium. But with Codeception you can write your tests in PHP. The main reason is: Selenium IDE tests are tightly bound to XPath locators. If you ever change anything in layout tests will fall. Codeception locators are more stable. You can use names, labels, button names and CSS to match elements on page. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features&#039;&#039;&#039;&lt;br /&gt;
* Selenium WebDriver integration&lt;br /&gt;
* Elements matched by name, CSS, XPath&lt;br /&gt;
* PageObjects and StepObjects included&lt;br /&gt;
* Powered by PHPUnit&lt;br /&gt;
* Data Cleanup&lt;br /&gt;
* Parallel Execution of tests&lt;br /&gt;
* BDD-style readable tests&lt;br /&gt;
&lt;br /&gt;
== Architecture of a test ==&lt;br /&gt;
The testing framework is built on the three layered testing architecture&lt;br /&gt;
&lt;br /&gt;
=== Scenarios (Cept Class) ===&lt;br /&gt;
Cept or Test, it is the main class which contains steps of execution for the tests, Cept Class will call Step Class functions which will indirectly make use of page objects to perform operations&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I = new AcceptanceTester($scenario);&lt;br /&gt;
$I-&amp;gt;wantTo(&#039;Install Joomla CMS&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;http://localhost/installation/index.php&#039;);&lt;br /&gt;
// I Wait for the text Main Configuration, meaning that the page is loaded&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;Language Selector&#039;]);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;English (United Kingdom)&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Site Name&#039;, &#039;weblinks&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Description&#039;, &#039;Site for testing Weblinks component&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Email&#039;, $cfg[&#039;Admin email&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Username&#039;, $cfg[&#039;username&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Confirm Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;click(&#039;Next&#039;);&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page Objects ===&lt;br /&gt;
Each page on your application has a class which we call page objects, each page class will have information about the URL, fields, Text present on the page. We use the best possible selector for any field on the page.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginManagerPage&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * @var string Url of the page&lt;br /&gt;
	 */&lt;br /&gt;
	public static $URL = &#039;/administrator/index.php&#039;;&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Array of Page elements indexed by descriptive name or label&lt;br /&gt;
	 *&lt;br /&gt;
	 * @var array&lt;br /&gt;
	 */&lt;br /&gt;
	public static $elements = array(&lt;br /&gt;
		&#039;username&#039; =&amp;gt; &amp;quot;#mod-login-username&amp;quot;,&lt;br /&gt;
		&#039;password&#039; =&amp;gt; &amp;quot;#mod-login-password&amp;quot;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Naming convention for Page Objects ====&lt;br /&gt;
When this document is created Codeception 2.0 was not having a PSR-4 compatible autoloader. Therefore we are creating a convention so with the future Codeception 2.1 with PSR-4 compatible autoloader (https://github.com/Codeception/Codeception/pull/1228) we are creating a naming convention for Pages so it will cost us a small effort to move to autoloaded classes in the future.&lt;br /&gt;
&lt;br /&gt;
The naming convention works as follows:&lt;br /&gt;
&lt;br /&gt;
 APPLICATION (for example Joomla, Patchtester, Weblinks or your Extension name)&lt;br /&gt;
 + CLIENT (in Joomla we use it for defining if is Installation, Administrator or Frontend&lt;br /&gt;
 + CLIENT PART (In Joomla we use it following the menu are were it belongs: Components, Menus, System,...)&lt;br /&gt;
 + PAGE NAME (The Page name) &lt;br /&gt;
 + Page&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
 JoomlaAdministratorLoginPage&lt;br /&gt;
 JoomlaAdministratorSystemGlobalconfigurationPage&lt;br /&gt;
 JoomlaInstallationConfigurationPage&lt;br /&gt;
&lt;br /&gt;
And they are located with a folder estructure similar to:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_pages_folder_structure.png|framed|center|Folder estructure for Pages in System Tests]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remind that in Codeception 2.0 you need to specify each folder in the acceptance/_bootstrap.php file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
// Here you can initialize variables that will be available to your tests&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/installation&#039;);&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/administrator&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#PageObjects&lt;br /&gt;
&lt;br /&gt;
=== Step Objects ===&lt;br /&gt;
Step Objects are classes which contains steps which are to be executed on the application to perform certain operations, step objects make use of page objects to perform these actions.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginSteps extends \AcceptanceTester&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * Function to execute an Admin Login for Joomla 3&lt;br /&gt;
	 *&lt;br /&gt;
	 * @return void&lt;br /&gt;
	 */&lt;br /&gt;
	public function doAdministratorLogin($user, $password)&lt;br /&gt;
	{&lt;br /&gt;
		$I = $this;&lt;br /&gt;
		$I-&amp;gt;amOnPage(\JoomlaAdministratorLoginPage::$URL);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;username&#039;], $user);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;password&#039;], $password);&lt;br /&gt;
		$I-&amp;gt;click(&#039;Log in&#039;);&lt;br /&gt;
		$I-&amp;gt;see(&#039;Category Manager&#039;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#StepObjects&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Joomla Browser Module ===&lt;br /&gt;
The Joomla Browser is a Codeception Module that incorporates general functions to your tests like:&lt;br /&gt;
- do administrator login&lt;br /&gt;
- install joomla&lt;br /&gt;
- install extension&lt;br /&gt;
- ...&lt;br /&gt;
&lt;br /&gt;
Find details about it at: https://github.com/joomla-projects/joomla-browser#table-of-contents&lt;br /&gt;
&lt;br /&gt;
== Getting started from scratch: what you need to download and install ==&lt;br /&gt;
To get the test environment running you need to have several components installed.&lt;br /&gt;
&lt;br /&gt;
=== local webserver ===&lt;br /&gt;
If you do not already have a local test server running you may want to check out:&lt;br /&gt;
https://www.mamp.info/&lt;br /&gt;
https://www.apachefriends.org/&lt;br /&gt;
http://www.ampps.com/&lt;br /&gt;
&lt;br /&gt;
If you are not familiar with a local web-server, learn that first before you advance futher. &lt;br /&gt;
&lt;br /&gt;
===Wget===&lt;br /&gt;
Wget is a command line program that retrieves content from web servers. For our purposes it is used to get selenium (browser test environment). See wikipedia: https://en.wikipedia.org/wiki/Wget&lt;br /&gt;
====Wget on Mac====&lt;br /&gt;
For Mac Users Homebrew (package manager for OS X) is a very easy way to get wget running. Download Homebrew at: http://brew.sh/ &lt;br /&gt;
After installation run the following command in your terminal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
brew install wget&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Java Runtime Environment (JRE) ===&lt;br /&gt;
The JRE has to be installed, so the tests will be executable. You find the recent versions at the Oracle Website.&lt;br /&gt;
In end of May 2015 this is: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html&lt;br /&gt;
later on that link could be obsolete and should be changed if there is a newer version out.&lt;br /&gt;
&lt;br /&gt;
Newer Mac OS Versions are not shipped any more with the JRE, so they have to download that too.&lt;br /&gt;
&lt;br /&gt;
=== Firefox ===&lt;br /&gt;
Selenium is testing in the browser Firefox. The selenium version is not that quick with the updates, as the Firefox browser, if the test is not executable, then it can be that you manually have to install an older version of Firefox.&lt;br /&gt;
Sadly that can be a try and error thing. To get older versions of Firefox: https://ftp.mozilla.org/pub/mozilla.org/firefox/releases/ here you will find many folders. Just try the first one that came before the Firefox version that you have been using (and that did not work). In the version folders you will find folders for all the different operating systems.&lt;br /&gt;
&lt;br /&gt;
‎&lt;br /&gt;
&lt;br /&gt;
=== configure test system variables ===&lt;br /&gt;
In your the folder that you installed, downloaded, pulled (git) the project, you have to rename the &amp;quot;&#039;&#039;acceptance.suite.dist.yml&#039;&#039;&amp;quot; file to &amp;quot;&#039;&#039;acceptance.suite.yml&#039;&#039;&amp;quot; and configure the parameters to your system variables.&lt;br /&gt;
&lt;br /&gt;
=== then run the first test ===&lt;br /&gt;
Once your machine is able to run tests (see &#039;&#039;The Joomla Browser Module&#039;&#039;), you are able to start working. Check the contents of the /tests/ folder in weblinks and try to understand the structure of the tests. After that check&lt;br /&gt;
the tasks are at: https://github.com/joomla-extensions/weblinks/issues/47 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The principles for writing a test: Readability and Performance ==&lt;br /&gt;
In Joomla we give priority to Readability over Performance, even when performance is a must.&lt;br /&gt;
&lt;br /&gt;
To explain that let me show an example: Let&#039;s say that we want to fill a field Username in a login form. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;administrator/index.php&amp;quot; method=&amp;quot;post&amp;quot; id=&amp;quot;form-login&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;username_field&amp;quot;&amp;gt;Username&amp;lt;/label&amp;gt;&lt;br /&gt;
  &amp;lt;input name=&amp;quot;username_field&amp;quot; tabindex=&amp;quot;1&amp;quot; id=&amp;quot;username_field&amp;quot; type=&amp;quot;text&amp;quot; size=&amp;quot;15&amp;quot; /&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the most performant way to fill that form field would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;#username_field&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And usually we would move that to a page object element ending in:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(\LoginPage::$username, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However Codeception is a smart framework and it adds some magic to it&#039;s methods (see: https://github.com/Codeception/Codeception/blob/2.0/src/Codeception/Module/WebDriver.php#L511-L513). It allows me to write more readable tests (keeping performance hight). &lt;br /&gt;
&lt;br /&gt;
If we do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Username&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Codeception will be smart and will search first in the page if there is any &amp;quot;LABEL&amp;quot; called Username. That is a fast operation, so performance will be affected just a little. And instead we have written less code than in previous examples.&lt;br /&gt;
&lt;br /&gt;
Note: sometimes this tricks are not always possible, labels are not always there or there are some elements hidden that shows and hides depending on a Javascript. All these special cases would require a Page element.&lt;br /&gt;
&lt;br /&gt;
Still there is a definitive method of using locators that made them readable and performant called: strict Locators see [[Testing_Joomla_Extensions_with_Codeception#Writting_reliable_locators]].&lt;br /&gt;
&lt;br /&gt;
With them we do: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField([&#039;id&#039; =&amp;gt; &#039;username_field&#039;], &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In conclusion we have more readable tests and less code to maintain while keeping performance. That is a win!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setting Up Codeception ==&lt;br /&gt;
=== setting up the repository ===&lt;br /&gt;
&#039;&#039;&#039;clone the directory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Fork [https://github.com/joomla-projects/com_localise com_localise]&lt;br /&gt;
# &lt;br /&gt;
# Git clone git@github.com:*your-github-profile-name*/com_localise.git&lt;br /&gt;
&lt;br /&gt;
=== Testing with Codeception ===&lt;br /&gt;
&lt;br /&gt;
There are two ways to get and run codeception, via PHAR or via Composer. Using &#039;&#039;&#039;Composer is recommended&#039;&#039;&#039; (because we are using in some tests the Codeception 2.1 development version not available in the composer.phar).&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Using Composer&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    You need to have Composer in your system, if not download it from here: https://getcomposer.org/&lt;br /&gt;
&lt;br /&gt;
    Step 1: composer update&lt;br /&gt;
&lt;br /&gt;
    Step 2: run Codeception by doing: php vendor/bin/codecept build&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Codeception.phar&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    Linux Machine  : wget http://codeception.com/codecept.phar&lt;br /&gt;
&lt;br /&gt;
    Windows Machine: Download from [http://codeception.com/install codecept.phar]&lt;br /&gt;
&lt;br /&gt;
    Step1 : php ./codecept.phar build&lt;br /&gt;
&lt;br /&gt;
=== Running the Test ===&lt;br /&gt;
Run Selenium server&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Download&lt;br /&gt;
curl -O http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&lt;br /&gt;
# And start the Selenium Server&lt;br /&gt;
java -Xms40m -Xmx256m -jar /Applications/XAMPP/xamppfiles/htdocs/selenium/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Rename tests/acceptance.suite.dist.yml to tests/acceptance.suite.yml&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 1: Modify the configuration at tests/acceptance.suite.yml to fit your server details.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 2: php codecept.phar run&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
with --steps to see a step-by-step report on the performed actions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --steps&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with --html. This command will run all tests for all suites, displaying the steps, and building HTML and XML reports. Reports will be store in tests/_output/ directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --html&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To activate the debug mode in Codeception just add the parameter --debug when you run the tests:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run acceptance --debug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Best Practices at Testing ==&lt;br /&gt;
=== Writting reliable locators ===&lt;br /&gt;
Writing good locators can be tricky. The Mozilla team has written an excellent guide titled [https://blog.mozilla.org/webqa/2013/09/26/writing-reliable-locators-for-selenium-and-webdriver-tests/ Writing reliable locators for Selenium and WebDriver tests].&lt;br /&gt;
&lt;br /&gt;
If the locator is an array, it should have a single element, with the key signifying the locator type (`id`, `name`, `css`, `xpath`, `link`, or `class`) and the value being the locator itself. This is called a &amp;quot;strict&amp;quot; locator. Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* [&#039;id&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div id=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;name&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div name=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;css&#039; =&amp;gt; &#039;input[type=input][value=foo]&#039;] matches `&amp;lt;input type=&amp;quot;input&amp;quot; value=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;xpath&#039; =&amp;gt; &amp;quot;//input[@type=&#039;submit&#039;][contains(@value, &#039;foo&#039;)]&amp;quot;] matches `&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;foobar&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;link&#039; =&amp;gt; &#039;Click here&#039;] matches `&amp;lt;a href=&amp;quot;google.com&amp;quot;&amp;gt;Click here&amp;lt;/a&amp;gt;`&lt;br /&gt;
* [&#039;class&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div class=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
=== How to use URLs ===&lt;br /&gt;
Codeception documentation suggests to use URL&#039;s as properties of a Page Object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(JoomlaInstallationConfigurationPage::$URL);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of hardcoding the url in the test:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The pros of this approach is:&lt;br /&gt;
- first way is more readable for non developers. &lt;br /&gt;
- it helps to make tests more maintenable in the case of a url change in the system&lt;br /&gt;
&lt;br /&gt;
However in joomla a change in an url is rare, and if it happens changing it will just be a Find&amp;amp;Replace task. I Joomla test we want to have the benefit of both, the url and a representative name that describes the page where we are going. That will make our tests more readable. Thus, we will write the urls the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amGoingTo(&#039;go to Create New Banner page at Joomla Administrator&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Working with Hidden Elements ===&lt;br /&gt;
Selenium can&#039;t interact with elements that are not visible:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;http://www.joomla.org&amp;quot; style=&amp;quot;display: none;&amp;quot; id=&amp;quot;joomla_site&amp;quot;&amp;gt;go to joomla&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case you can&#039;t do:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually this happens when you need to wait for a Javascript animation that end up showing that element, so in this case you will need to do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForElementVisible(&#039;#joomla_site&#039;);&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== When do not use contains ===&lt;br /&gt;
We do not recommend to use the function contains on XPath because is not specific and can create false positives at tests.&lt;br /&gt;
See: https://github.com/joomla-projects/GSOC-Webdriver_system_tests_for_CMS/pull/99#issuecomment-69004191&lt;br /&gt;
=== Always add Strict Locators to your tests ===&lt;br /&gt;
Performance in tests is very important. You can reduce dramatically the time spent on a test with just adding a few extra locators. For example, the following code pertains to a test:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// see($text, $selector = null)&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the previous code we are not facilitating the &amp;quot;Selector&amp;quot; so Codeception will have to search for the element in all the HTML. Doing this instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the tests went from: Time: 1.17 minutes&lt;br /&gt;
to: Time: 49.18 seconds&lt;br /&gt;
&lt;br /&gt;
You can see this video of a real example: http://www.youtube.com/watch?v=0JCv0BR2yZY&lt;br /&gt;
&lt;br /&gt;
Losing 30 seconds in every Assertion can delay your tests dramatically. Therefore, remind always to add xPath locators to all your Assertions.&lt;br /&gt;
[[Category:Automated Testing]]&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;see ====&lt;br /&gt;
Do not use &#039;&#039;see&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;waitForText ====&lt;br /&gt;
Do not use &#039;&#039;waitForText&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;, 10, [&#039;css&#039; =&amp;gt; &#039;h3&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Incase of an element has multiple css classes, When Using CSS Locators make sure you use more specific class as locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert-success&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
A page could have mutiple elements which can have &#039;&#039;alert&#039;&#039; css class associated, hence being more specific helps.&lt;br /&gt;
&lt;br /&gt;
==== How much time should I wait for an Element or Text? ====&lt;br /&gt;
You may have noticed that the second parameter in the I waitForText is an integer that represents how much &amp;quot;time to wait&amp;quot; in seconds:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;a text to wait for&#039;, 10, [&#039;...&#039; =&amp;gt; &#039;...&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But, how much time is the right time to wait for a text?&lt;br /&gt;
&lt;br /&gt;
PHP maximum execution time before returning a Fatal Error for timeout is set by default to 30 seconds. We suggest to set it for 10 seconds. A waitForText over 10 seconds will definitely mean that something is not performing well.&lt;br /&gt;
&lt;br /&gt;
=== Quote and Double Quotes in Compex XPaths ===&lt;br /&gt;
Sometimes you will have to write XPaths that looks like:&lt;br /&gt;
&lt;br /&gt;
 //button[@onclick=&#039;Joomla.submitbutton(&amp;quot;config.save.application.apply&amp;quot;)&#039;]&lt;br /&gt;
&lt;br /&gt;
When moved to a Page Object you will probably will face this situation:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_error_escaping_quotes_on_xpaths.png|framed|center|Typical issue when you write a long XPath in a Page object]]&lt;br /&gt;
&lt;br /&gt;
To avoid it remind to escape the quotes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
// Right&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=\&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)\&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Generating txt/html scenarios===&lt;br /&gt;
Codeception allows you to generate user-friendly text scenarios from scenario-driven from Cest and Cept php test (see http://codeception.com/docs/reference/Commands#GenerateScenarios).&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t use double quotes, use single quotes instead===&lt;br /&gt;
Do not use double quotes (&amp;quot;) for surrounding strings:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &amp;quot;&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;&amp;quot;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you use single quotes instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Congratulations! Joomla! is now installed.&#039;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will get the right expected result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Congratulations! Joomla! is now installed.&#039;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The reason of not being able to use double quotes is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;br /&gt;
&lt;br /&gt;
===Do not leave spaces between parameters in Cepts===&lt;br /&gt;
See the two lines:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
// Good&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;,10,&#039;h3&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Main Configuration&#039;,&amp;quot; 10&amp;quot;,&amp;quot; &#039;h3&#039;&lt;br /&gt;
&lt;br /&gt;
The reason that you are asked to not add spaces between parameters is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186588</id>
		<title>Testing Joomla Extensions with Codeception</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186588"/>
		<updated>2015-05-30T16:52:07Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: /* configure test system variables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;nowiki&amp;gt;Note: this page is under construction&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What is Codeception? ==&lt;br /&gt;
Codeception PHP Testing Framework is designed to work just out of the box. This means its installation requires minimal steps and no external dependencies preinstalled (except PHP, of course). Only one configuration step should be taken and you are ready to test your web application from an eye of actual user.&lt;br /&gt;
&lt;br /&gt;
See the following video of codeception in action testing Joomla: &lt;br /&gt;
&lt;br /&gt;
{{#widget:YouTube|id=Vc1BJNnhsFM}}&lt;br /&gt;
&lt;br /&gt;
Codeception provides possibilities to do Unit Testing or to Test APIs, however this page is focused in &#039;&#039;&#039;System Testing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Why Use Codeception? ==&lt;br /&gt;
&#039;&#039;Why use Codeception when we already have Selenium IDE?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Codeception works great with Selenium. But with Codeception you can write your tests in PHP. The main reason is: Selenium IDE tests are tightly bound to XPath locators. If you ever change anything in layout tests will fall. Codeception locators are more stable. You can use names, labels, button names and CSS to match elements on page. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features&#039;&#039;&#039;&lt;br /&gt;
* Selenium WebDriver integration&lt;br /&gt;
* Elements matched by name, CSS, XPath&lt;br /&gt;
* PageObjects and StepObjects included&lt;br /&gt;
* Powered by PHPUnit&lt;br /&gt;
* Data Cleanup&lt;br /&gt;
* Parallel Execution of tests&lt;br /&gt;
* BDD-style readable tests&lt;br /&gt;
&lt;br /&gt;
== Architecture of a test ==&lt;br /&gt;
The testing framework is built on the three layered testing architecture&lt;br /&gt;
&lt;br /&gt;
=== Scenarios (Cept Class) ===&lt;br /&gt;
Cept or Test, it is the main class which contains steps of execution for the tests, Cept Class will call Step Class functions which will indirectly make use of page objects to perform operations&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I = new AcceptanceTester($scenario);&lt;br /&gt;
$I-&amp;gt;wantTo(&#039;Install Joomla CMS&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;http://localhost/installation/index.php&#039;);&lt;br /&gt;
// I Wait for the text Main Configuration, meaning that the page is loaded&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;Language Selector&#039;]);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;English (United Kingdom)&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Site Name&#039;, &#039;weblinks&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Description&#039;, &#039;Site for testing Weblinks component&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Email&#039;, $cfg[&#039;Admin email&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Username&#039;, $cfg[&#039;username&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Confirm Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;click(&#039;Next&#039;);&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page Objects ===&lt;br /&gt;
Each page on your application has a class which we call page objects, each page class will have information about the URL, fields, Text present on the page. We use the best possible selector for any field on the page.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginManagerPage&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * @var string Url of the page&lt;br /&gt;
	 */&lt;br /&gt;
	public static $URL = &#039;/administrator/index.php&#039;;&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Array of Page elements indexed by descriptive name or label&lt;br /&gt;
	 *&lt;br /&gt;
	 * @var array&lt;br /&gt;
	 */&lt;br /&gt;
	public static $elements = array(&lt;br /&gt;
		&#039;username&#039; =&amp;gt; &amp;quot;#mod-login-username&amp;quot;,&lt;br /&gt;
		&#039;password&#039; =&amp;gt; &amp;quot;#mod-login-password&amp;quot;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Naming convention for Page Objects ====&lt;br /&gt;
When this document is created Codeception 2.0 was not having a PSR-4 compatible autoloader. Therefore we are creating a convention so with the future Codeception 2.1 with PSR-4 compatible autoloader (https://github.com/Codeception/Codeception/pull/1228) we are creating a naming convention for Pages so it will cost us a small effort to move to autoloaded classes in the future.&lt;br /&gt;
&lt;br /&gt;
The naming convention works as follows:&lt;br /&gt;
&lt;br /&gt;
 APPLICATION (for example Joomla, Patchtester, Weblinks or your Extension name)&lt;br /&gt;
 + CLIENT (in Joomla we use it for defining if is Installation, Administrator or Frontend&lt;br /&gt;
 + CLIENT PART (In Joomla we use it following the menu are were it belongs: Components, Menus, System,...)&lt;br /&gt;
 + PAGE NAME (The Page name) &lt;br /&gt;
 + Page&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
 JoomlaAdministratorLoginPage&lt;br /&gt;
 JoomlaAdministratorSystemGlobalconfigurationPage&lt;br /&gt;
 JoomlaInstallationConfigurationPage&lt;br /&gt;
&lt;br /&gt;
And they are located with a folder estructure similar to:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_pages_folder_structure.png|framed|center|Folder estructure for Pages in System Tests]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remind that in Codeception 2.0 you need to specify each folder in the acceptance/_bootstrap.php file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
// Here you can initialize variables that will be available to your tests&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/installation&#039;);&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/administrator&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#PageObjects&lt;br /&gt;
&lt;br /&gt;
=== Step Objects ===&lt;br /&gt;
Step Objects are classes which contains steps which are to be executed on the application to perform certain operations, step objects make use of page objects to perform these actions.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginSteps extends \AcceptanceTester&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * Function to execute an Admin Login for Joomla 3&lt;br /&gt;
	 *&lt;br /&gt;
	 * @return void&lt;br /&gt;
	 */&lt;br /&gt;
	public function doAdministratorLogin($user, $password)&lt;br /&gt;
	{&lt;br /&gt;
		$I = $this;&lt;br /&gt;
		$I-&amp;gt;amOnPage(\JoomlaAdministratorLoginPage::$URL);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;username&#039;], $user);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;password&#039;], $password);&lt;br /&gt;
		$I-&amp;gt;click(&#039;Log in&#039;);&lt;br /&gt;
		$I-&amp;gt;see(&#039;Category Manager&#039;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#StepObjects&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Joomla Browser Module ===&lt;br /&gt;
The Joomla Browser is a Codeception Module that incorporates general functions to your tests like:&lt;br /&gt;
- do administrator login&lt;br /&gt;
- install joomla&lt;br /&gt;
- install extension&lt;br /&gt;
- ...&lt;br /&gt;
&lt;br /&gt;
Find details about it at: https://github.com/joomla-projects/joomla-browser#table-of-contents&lt;br /&gt;
&lt;br /&gt;
== Getting started from scratch: what you need to download and install ==&lt;br /&gt;
To get the test environment running you need to have several components installed.&lt;br /&gt;
&lt;br /&gt;
=== local webserver ===&lt;br /&gt;
If you do not already have a local test server running you may want to check out:&lt;br /&gt;
https://www.mamp.info/&lt;br /&gt;
https://www.apachefriends.org/&lt;br /&gt;
http://www.ampps.com/&lt;br /&gt;
&lt;br /&gt;
If you are not familiar with a local web-server, learn that first before you advance futher. &lt;br /&gt;
&lt;br /&gt;
===Wget===&lt;br /&gt;
Wget is a command line program that retrieves content from web servers. For our purposes it is used to get selenium (browser test environment). See wikipedia: https://en.wikipedia.org/wiki/Wget&lt;br /&gt;
====Wget on Mac====&lt;br /&gt;
For Mac Users Homebrew (package manager for OS X) is a very easy way to get wget running. Download Homebrew at: http://brew.sh/ &lt;br /&gt;
After installation run the following command in your terminal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
brew install wget&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Java Runtime Environment (JRE) ===&lt;br /&gt;
The JRE has to be installed, so the tests will be executable. You find the recent versions at the Oracle Website.&lt;br /&gt;
In end of May 2015 this is: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html&lt;br /&gt;
later on that link could be obsolete and should be changed if there is a newer version out.&lt;br /&gt;
&lt;br /&gt;
Newer Mac OS Versions are not shipped any more with the JRE, so they have to download that too.&lt;br /&gt;
&lt;br /&gt;
=== Firefox ===&lt;br /&gt;
Selenium is testing in the browser Firefox. The selenium version is not that quick with the updates, as the Firefox browser, if the test is not executable, then it can be that you manually have to install an older version of Firefox.&lt;br /&gt;
Sadly that can be a try and error thing. To get older versions of Firefox: https://ftp.mozilla.org/pub/mozilla.org/firefox/releases/ here you will find many folders. Just try the first one that came before the Firefox version that you have been using (and that did not work). In the version folders you will find folders for all the different operating systems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Acceptance.suite.dist.yml rename.png|thumbnail|left|Screenshot of file structure]]&lt;br /&gt;
=== configure test system variables ===&lt;br /&gt;
In your the folder that you installed, downloaded, pulled (git) the project, you have to rename the &amp;quot;&#039;&#039;acceptance.suite.dist.yml&#039;&#039;&amp;quot; file to &amp;quot;&#039;&#039;acceptance.suite.yml&#039;&#039;&amp;quot; and configure the parameters to your system variables.&lt;br /&gt;
&lt;br /&gt;
=== then run the first test ===&lt;br /&gt;
Once your machine is able to run tests (see &#039;&#039;The Joomla Browser Module&#039;&#039;), you are able to start working. Check the contents of the /tests/ folder in weblinks and try to understand the structure of the tests. After that check&lt;br /&gt;
the tasks are at: https://github.com/joomla-extensions/weblinks/issues/47 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The principles for writing a test: Readability and Performance ==&lt;br /&gt;
In Joomla we give priority to Readability over Performance, even when performance is a must.&lt;br /&gt;
&lt;br /&gt;
To explain that let me show an example: Let&#039;s say that we want to fill a field Username in a login form. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;administrator/index.php&amp;quot; method=&amp;quot;post&amp;quot; id=&amp;quot;form-login&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;username_field&amp;quot;&amp;gt;Username&amp;lt;/label&amp;gt;&lt;br /&gt;
  &amp;lt;input name=&amp;quot;username_field&amp;quot; tabindex=&amp;quot;1&amp;quot; id=&amp;quot;username_field&amp;quot; type=&amp;quot;text&amp;quot; size=&amp;quot;15&amp;quot; /&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the most performant way to fill that form field would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;#username_field&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And usually we would move that to a page object element ending in:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(\LoginPage::$username, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However Codeception is a smart framework and it adds some magic to it&#039;s methods (see: https://github.com/Codeception/Codeception/blob/2.0/src/Codeception/Module/WebDriver.php#L511-L513). It allows me to write more readable tests (keeping performance hight). &lt;br /&gt;
&lt;br /&gt;
If we do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Username&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Codeception will be smart and will search first in the page if there is any &amp;quot;LABEL&amp;quot; called Username. That is a fast operation, so performance will be affected just a little. And instead we have written less code than in previous examples.&lt;br /&gt;
&lt;br /&gt;
Note: sometimes this tricks are not always possible, labels are not always there or there are some elements hidden that shows and hides depending on a Javascript. All these special cases would require a Page element.&lt;br /&gt;
&lt;br /&gt;
Still there is a definitive method of using locators that made them readable and performant called: strict Locators see [[Testing_Joomla_Extensions_with_Codeception#Writting_reliable_locators]].&lt;br /&gt;
&lt;br /&gt;
With them we do: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField([&#039;id&#039; =&amp;gt; &#039;username_field&#039;], &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In conclusion we have more readable tests and less code to maintain while keeping performance. That is a win!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setting Up Codeception ==&lt;br /&gt;
=== setting up the repository ===&lt;br /&gt;
&#039;&#039;&#039;clone the directory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Fork [https://github.com/joomla-projects/com_localise com_localise]&lt;br /&gt;
# &lt;br /&gt;
# Git clone git@github.com:*your-github-profile-name*/com_localise.git&lt;br /&gt;
&lt;br /&gt;
=== Testing with Codeception ===&lt;br /&gt;
&lt;br /&gt;
There are two ways to get and run codeception, via PHAR or via Composer. Using &#039;&#039;&#039;Composer is recommended&#039;&#039;&#039; (because we are using in some tests the Codeception 2.1 development version not available in the composer.phar).&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Using Composer&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    You need to have Composer in your system, if not download it from here: https://getcomposer.org/&lt;br /&gt;
&lt;br /&gt;
    Step 1: composer update&lt;br /&gt;
&lt;br /&gt;
    Step 2: run Codeception by doing: php vendor/bin/codecept build&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Codeception.phar&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    Linux Machine  : wget http://codeception.com/codecept.phar&lt;br /&gt;
&lt;br /&gt;
    Windows Machine: Download from [http://codeception.com/install codecept.phar]&lt;br /&gt;
&lt;br /&gt;
    Step1 : php ./codecept.phar build&lt;br /&gt;
&lt;br /&gt;
=== Running the Test ===&lt;br /&gt;
Run Selenium server&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Download&lt;br /&gt;
curl -O http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&lt;br /&gt;
# And start the Selenium Server&lt;br /&gt;
java -Xms40m -Xmx256m -jar /Applications/XAMPP/xamppfiles/htdocs/selenium/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Rename tests/acceptance.suite.dist.yml to tests/acceptance.suite.yml&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 1: Modify the configuration at tests/acceptance.suite.yml to fit your server details.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 2: php codecept.phar run&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
with --steps to see a step-by-step report on the performed actions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --steps&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with --html. This command will run all tests for all suites, displaying the steps, and building HTML and XML reports. Reports will be store in tests/_output/ directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --html&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To activate the debug mode in Codeception just add the parameter --debug when you run the tests:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run acceptance --debug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Best Practices at Testing ==&lt;br /&gt;
=== Writting reliable locators ===&lt;br /&gt;
Writing good locators can be tricky. The Mozilla team has written an excellent guide titled [https://blog.mozilla.org/webqa/2013/09/26/writing-reliable-locators-for-selenium-and-webdriver-tests/ Writing reliable locators for Selenium and WebDriver tests].&lt;br /&gt;
&lt;br /&gt;
If the locator is an array, it should have a single element, with the key signifying the locator type (`id`, `name`, `css`, `xpath`, `link`, or `class`) and the value being the locator itself. This is called a &amp;quot;strict&amp;quot; locator. Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* [&#039;id&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div id=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;name&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div name=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;css&#039; =&amp;gt; &#039;input[type=input][value=foo]&#039;] matches `&amp;lt;input type=&amp;quot;input&amp;quot; value=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;xpath&#039; =&amp;gt; &amp;quot;//input[@type=&#039;submit&#039;][contains(@value, &#039;foo&#039;)]&amp;quot;] matches `&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;foobar&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;link&#039; =&amp;gt; &#039;Click here&#039;] matches `&amp;lt;a href=&amp;quot;google.com&amp;quot;&amp;gt;Click here&amp;lt;/a&amp;gt;`&lt;br /&gt;
* [&#039;class&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div class=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
=== How to use URLs ===&lt;br /&gt;
Codeception documentation suggests to use URL&#039;s as properties of a Page Object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(JoomlaInstallationConfigurationPage::$URL);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of hardcoding the url in the test:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The pros of this approach is:&lt;br /&gt;
- first way is more readable for non developers. &lt;br /&gt;
- it helps to make tests more maintenable in the case of a url change in the system&lt;br /&gt;
&lt;br /&gt;
However in joomla a change in an url is rare, and if it happens changing it will just be a Find&amp;amp;Replace task. I Joomla test we want to have the benefit of both, the url and a representative name that describes the page where we are going. That will make our tests more readable. Thus, we will write the urls the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amGoingTo(&#039;go to Create New Banner page at Joomla Administrator&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Working with Hidden Elements ===&lt;br /&gt;
Selenium can&#039;t interact with elements that are not visible:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;http://www.joomla.org&amp;quot; style=&amp;quot;display: none;&amp;quot; id=&amp;quot;joomla_site&amp;quot;&amp;gt;go to joomla&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case you can&#039;t do:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually this happens when you need to wait for a Javascript animation that end up showing that element, so in this case you will need to do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForElementVisible(&#039;#joomla_site&#039;);&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== When do not use contains ===&lt;br /&gt;
We do not recommend to use the function contains on XPath because is not specific and can create false positives at tests.&lt;br /&gt;
See: https://github.com/joomla-projects/GSOC-Webdriver_system_tests_for_CMS/pull/99#issuecomment-69004191&lt;br /&gt;
=== Always add Strict Locators to your tests ===&lt;br /&gt;
Performance in tests is very important. You can reduce dramatically the time spent on a test with just adding a few extra locators. For example, the following code pertains to a test:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// see($text, $selector = null)&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the previous code we are not facilitating the &amp;quot;Selector&amp;quot; so Codeception will have to search for the element in all the HTML. Doing this instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the tests went from: Time: 1.17 minutes&lt;br /&gt;
to: Time: 49.18 seconds&lt;br /&gt;
&lt;br /&gt;
You can see this video of a real example: http://www.youtube.com/watch?v=0JCv0BR2yZY&lt;br /&gt;
&lt;br /&gt;
Losing 30 seconds in every Assertion can delay your tests dramatically. Therefore, remind always to add xPath locators to all your Assertions.&lt;br /&gt;
[[Category:Automated Testing]]&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;see ====&lt;br /&gt;
Do not use &#039;&#039;see&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;waitForText ====&lt;br /&gt;
Do not use &#039;&#039;waitForText&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;, 10, [&#039;css&#039; =&amp;gt; &#039;h3&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Incase of an element has multiple css classes, When Using CSS Locators make sure you use more specific class as locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert-success&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
A page could have mutiple elements which can have &#039;&#039;alert&#039;&#039; css class associated, hence being more specific helps.&lt;br /&gt;
&lt;br /&gt;
==== How much time should I wait for an Element or Text? ====&lt;br /&gt;
You may have noticed that the second parameter in the I waitForText is an integer that represents how much &amp;quot;time to wait&amp;quot; in seconds:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;a text to wait for&#039;, 10, [&#039;...&#039; =&amp;gt; &#039;...&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But, how much time is the right time to wait for a text?&lt;br /&gt;
&lt;br /&gt;
PHP maximum execution time before returning a Fatal Error for timeout is set by default to 30 seconds. We suggest to set it for 10 seconds. A waitForText over 10 seconds will definitely mean that something is not performing well.&lt;br /&gt;
&lt;br /&gt;
=== Quote and Double Quotes in Compex XPaths ===&lt;br /&gt;
Sometimes you will have to write XPaths that looks like:&lt;br /&gt;
&lt;br /&gt;
 //button[@onclick=&#039;Joomla.submitbutton(&amp;quot;config.save.application.apply&amp;quot;)&#039;]&lt;br /&gt;
&lt;br /&gt;
When moved to a Page Object you will probably will face this situation:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_error_escaping_quotes_on_xpaths.png|framed|center|Typical issue when you write a long XPath in a Page object]]&lt;br /&gt;
&lt;br /&gt;
To avoid it remind to escape the quotes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
// Right&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=\&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)\&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Generating txt/html scenarios===&lt;br /&gt;
Codeception allows you to generate user-friendly text scenarios from scenario-driven from Cest and Cept php test (see http://codeception.com/docs/reference/Commands#GenerateScenarios).&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t use double quotes, use single quotes instead===&lt;br /&gt;
Do not use double quotes (&amp;quot;) for surrounding strings:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &amp;quot;&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;&amp;quot;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you use single quotes instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Congratulations! Joomla! is now installed.&#039;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will get the right expected result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Congratulations! Joomla! is now installed.&#039;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The reason of not being able to use double quotes is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;br /&gt;
&lt;br /&gt;
===Do not leave spaces between parameters in Cepts===&lt;br /&gt;
See the two lines:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
// Good&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;,10,&#039;h3&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Main Configuration&#039;,&amp;quot; 10&amp;quot;,&amp;quot; &#039;h3&#039;&lt;br /&gt;
&lt;br /&gt;
The reason that you are asked to not add spaces between parameters is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186585</id>
		<title>Testing Joomla Extensions with Codeception</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186585"/>
		<updated>2015-05-30T16:50:01Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: /* configure test system variables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;nowiki&amp;gt;Note: this page is under construction&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What is Codeception? ==&lt;br /&gt;
Codeception PHP Testing Framework is designed to work just out of the box. This means its installation requires minimal steps and no external dependencies preinstalled (except PHP, of course). Only one configuration step should be taken and you are ready to test your web application from an eye of actual user.&lt;br /&gt;
&lt;br /&gt;
See the following video of codeception in action testing Joomla: &lt;br /&gt;
&lt;br /&gt;
{{#widget:YouTube|id=Vc1BJNnhsFM}}&lt;br /&gt;
&lt;br /&gt;
Codeception provides possibilities to do Unit Testing or to Test APIs, however this page is focused in &#039;&#039;&#039;System Testing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Why Use Codeception? ==&lt;br /&gt;
&#039;&#039;Why use Codeception when we already have Selenium IDE?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Codeception works great with Selenium. But with Codeception you can write your tests in PHP. The main reason is: Selenium IDE tests are tightly bound to XPath locators. If you ever change anything in layout tests will fall. Codeception locators are more stable. You can use names, labels, button names and CSS to match elements on page. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features&#039;&#039;&#039;&lt;br /&gt;
* Selenium WebDriver integration&lt;br /&gt;
* Elements matched by name, CSS, XPath&lt;br /&gt;
* PageObjects and StepObjects included&lt;br /&gt;
* Powered by PHPUnit&lt;br /&gt;
* Data Cleanup&lt;br /&gt;
* Parallel Execution of tests&lt;br /&gt;
* BDD-style readable tests&lt;br /&gt;
&lt;br /&gt;
== Architecture of a test ==&lt;br /&gt;
The testing framework is built on the three layered testing architecture&lt;br /&gt;
&lt;br /&gt;
=== Scenarios (Cept Class) ===&lt;br /&gt;
Cept or Test, it is the main class which contains steps of execution for the tests, Cept Class will call Step Class functions which will indirectly make use of page objects to perform operations&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I = new AcceptanceTester($scenario);&lt;br /&gt;
$I-&amp;gt;wantTo(&#039;Install Joomla CMS&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;http://localhost/installation/index.php&#039;);&lt;br /&gt;
// I Wait for the text Main Configuration, meaning that the page is loaded&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;Language Selector&#039;]);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;English (United Kingdom)&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Site Name&#039;, &#039;weblinks&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Description&#039;, &#039;Site for testing Weblinks component&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Email&#039;, $cfg[&#039;Admin email&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Username&#039;, $cfg[&#039;username&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Confirm Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;click(&#039;Next&#039;);&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page Objects ===&lt;br /&gt;
Each page on your application has a class which we call page objects, each page class will have information about the URL, fields, Text present on the page. We use the best possible selector for any field on the page.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginManagerPage&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * @var string Url of the page&lt;br /&gt;
	 */&lt;br /&gt;
	public static $URL = &#039;/administrator/index.php&#039;;&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Array of Page elements indexed by descriptive name or label&lt;br /&gt;
	 *&lt;br /&gt;
	 * @var array&lt;br /&gt;
	 */&lt;br /&gt;
	public static $elements = array(&lt;br /&gt;
		&#039;username&#039; =&amp;gt; &amp;quot;#mod-login-username&amp;quot;,&lt;br /&gt;
		&#039;password&#039; =&amp;gt; &amp;quot;#mod-login-password&amp;quot;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Naming convention for Page Objects ====&lt;br /&gt;
When this document is created Codeception 2.0 was not having a PSR-4 compatible autoloader. Therefore we are creating a convention so with the future Codeception 2.1 with PSR-4 compatible autoloader (https://github.com/Codeception/Codeception/pull/1228) we are creating a naming convention for Pages so it will cost us a small effort to move to autoloaded classes in the future.&lt;br /&gt;
&lt;br /&gt;
The naming convention works as follows:&lt;br /&gt;
&lt;br /&gt;
 APPLICATION (for example Joomla, Patchtester, Weblinks or your Extension name)&lt;br /&gt;
 + CLIENT (in Joomla we use it for defining if is Installation, Administrator or Frontend&lt;br /&gt;
 + CLIENT PART (In Joomla we use it following the menu are were it belongs: Components, Menus, System,...)&lt;br /&gt;
 + PAGE NAME (The Page name) &lt;br /&gt;
 + Page&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
 JoomlaAdministratorLoginPage&lt;br /&gt;
 JoomlaAdministratorSystemGlobalconfigurationPage&lt;br /&gt;
 JoomlaInstallationConfigurationPage&lt;br /&gt;
&lt;br /&gt;
And they are located with a folder estructure similar to:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_pages_folder_structure.png|framed|center|Folder estructure for Pages in System Tests]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remind that in Codeception 2.0 you need to specify each folder in the acceptance/_bootstrap.php file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
// Here you can initialize variables that will be available to your tests&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/installation&#039;);&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/administrator&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#PageObjects&lt;br /&gt;
&lt;br /&gt;
=== Step Objects ===&lt;br /&gt;
Step Objects are classes which contains steps which are to be executed on the application to perform certain operations, step objects make use of page objects to perform these actions.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginSteps extends \AcceptanceTester&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * Function to execute an Admin Login for Joomla 3&lt;br /&gt;
	 *&lt;br /&gt;
	 * @return void&lt;br /&gt;
	 */&lt;br /&gt;
	public function doAdministratorLogin($user, $password)&lt;br /&gt;
	{&lt;br /&gt;
		$I = $this;&lt;br /&gt;
		$I-&amp;gt;amOnPage(\JoomlaAdministratorLoginPage::$URL);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;username&#039;], $user);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;password&#039;], $password);&lt;br /&gt;
		$I-&amp;gt;click(&#039;Log in&#039;);&lt;br /&gt;
		$I-&amp;gt;see(&#039;Category Manager&#039;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#StepObjects&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Joomla Browser Module ===&lt;br /&gt;
The Joomla Browser is a Codeception Module that incorporates general functions to your tests like:&lt;br /&gt;
- do administrator login&lt;br /&gt;
- install joomla&lt;br /&gt;
- install extension&lt;br /&gt;
- ...&lt;br /&gt;
&lt;br /&gt;
Find details about it at: https://github.com/joomla-projects/joomla-browser#table-of-contents&lt;br /&gt;
&lt;br /&gt;
== Getting started from scratch: what you need to download and install ==&lt;br /&gt;
To get the test environment running you need to have several components installed.&lt;br /&gt;
&lt;br /&gt;
=== local webserver ===&lt;br /&gt;
If you do not already have a local test server running you may want to check out:&lt;br /&gt;
https://www.mamp.info/&lt;br /&gt;
https://www.apachefriends.org/&lt;br /&gt;
http://www.ampps.com/&lt;br /&gt;
&lt;br /&gt;
If you are not familiar with a local web-server, learn that first before you advance futher. &lt;br /&gt;
&lt;br /&gt;
===Wget===&lt;br /&gt;
Wget is a command line program that retrieves content from web servers. For our purposes it is used to get selenium (browser test environment). See wikipedia: https://en.wikipedia.org/wiki/Wget&lt;br /&gt;
====Wget on Mac====&lt;br /&gt;
For Mac Users Homebrew (package manager for OS X) is a very easy way to get wget running. Download Homebrew at: http://brew.sh/ &lt;br /&gt;
After installation run the following command in your terminal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
brew install wget&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Java Runtime Environment (JRE) ===&lt;br /&gt;
The JRE has to be installed, so the tests will be executable. You find the recent versions at the Oracle Website.&lt;br /&gt;
In end of May 2015 this is: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html&lt;br /&gt;
later on that link could be obsolete and should be changed if there is a newer version out.&lt;br /&gt;
&lt;br /&gt;
Newer Mac OS Versions are not shipped any more with the JRE, so they have to download that too.&lt;br /&gt;
&lt;br /&gt;
=== Firefox ===&lt;br /&gt;
Selenium is testing in the browser Firefox. The selenium version is not that quick with the updates, as the Firefox browser, if the test is not executable, then it can be that you manually have to install an older version of Firefox.&lt;br /&gt;
Sadly that can be a try and error thing. To get older versions of Firefox: https://ftp.mozilla.org/pub/mozilla.org/firefox/releases/ here you will find many folders. Just try the first one that came before the Firefox version that you have been using (and that did not work). In the version folders you will find folders for all the different operating systems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== configure test system variables ===&lt;br /&gt;
[[File:Acceptance.suite.dist.yml rename.png|thumbnail|left|Screenshot of file structure]]&lt;br /&gt;
In your the folder that you installed, downloaded, pulled (git) the project, you have to rename the &amp;quot;&#039;&#039;acceptance.suite.dist.yml&#039;&#039;&amp;quot; file to &amp;quot;&#039;&#039;acceptance.suite.yml&#039;&#039;&amp;quot; and configure the parameters to your system variables.&lt;br /&gt;
&lt;br /&gt;
=== then run the first test ===&lt;br /&gt;
Once your machine is able to run tests (see &#039;&#039;The Joomla Browser Module&#039;&#039;), you are able to start working. Check the contents of the /tests/ folder in weblinks and try to understand the structure of the tests. After that check&lt;br /&gt;
the tasks are at: https://github.com/joomla-extensions/weblinks/issues/47 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The principles for writing a test: Readability and Performance ==&lt;br /&gt;
In Joomla we give priority to Readability over Performance, even when performance is a must.&lt;br /&gt;
&lt;br /&gt;
To explain that let me show an example: Let&#039;s say that we want to fill a field Username in a login form. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;administrator/index.php&amp;quot; method=&amp;quot;post&amp;quot; id=&amp;quot;form-login&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;username_field&amp;quot;&amp;gt;Username&amp;lt;/label&amp;gt;&lt;br /&gt;
  &amp;lt;input name=&amp;quot;username_field&amp;quot; tabindex=&amp;quot;1&amp;quot; id=&amp;quot;username_field&amp;quot; type=&amp;quot;text&amp;quot; size=&amp;quot;15&amp;quot; /&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the most performant way to fill that form field would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;#username_field&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And usually we would move that to a page object element ending in:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(\LoginPage::$username, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However Codeception is a smart framework and it adds some magic to it&#039;s methods (see: https://github.com/Codeception/Codeception/blob/2.0/src/Codeception/Module/WebDriver.php#L511-L513). It allows me to write more readable tests (keeping performance hight). &lt;br /&gt;
&lt;br /&gt;
If we do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Username&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Codeception will be smart and will search first in the page if there is any &amp;quot;LABEL&amp;quot; called Username. That is a fast operation, so performance will be affected just a little. And instead we have written less code than in previous examples.&lt;br /&gt;
&lt;br /&gt;
Note: sometimes this tricks are not always possible, labels are not always there or there are some elements hidden that shows and hides depending on a Javascript. All these special cases would require a Page element.&lt;br /&gt;
&lt;br /&gt;
Still there is a definitive method of using locators that made them readable and performant called: strict Locators see [[Testing_Joomla_Extensions_with_Codeception#Writting_reliable_locators]].&lt;br /&gt;
&lt;br /&gt;
With them we do: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField([&#039;id&#039; =&amp;gt; &#039;username_field&#039;], &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In conclusion we have more readable tests and less code to maintain while keeping performance. That is a win!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setting Up Codeception ==&lt;br /&gt;
=== setting up the repository ===&lt;br /&gt;
&#039;&#039;&#039;clone the directory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Fork [https://github.com/joomla-projects/com_localise com_localise]&lt;br /&gt;
# &lt;br /&gt;
# Git clone git@github.com:*your-github-profile-name*/com_localise.git&lt;br /&gt;
&lt;br /&gt;
=== Testing with Codeception ===&lt;br /&gt;
&lt;br /&gt;
There are two ways to get and run codeception, via PHAR or via Composer. Using &#039;&#039;&#039;Composer is recommended&#039;&#039;&#039; (because we are using in some tests the Codeception 2.1 development version not available in the composer.phar).&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Using Composer&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    You need to have Composer in your system, if not download it from here: https://getcomposer.org/&lt;br /&gt;
&lt;br /&gt;
    Step 1: composer update&lt;br /&gt;
&lt;br /&gt;
    Step 2: run Codeception by doing: php vendor/bin/codecept build&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Codeception.phar&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    Linux Machine  : wget http://codeception.com/codecept.phar&lt;br /&gt;
&lt;br /&gt;
    Windows Machine: Download from [http://codeception.com/install codecept.phar]&lt;br /&gt;
&lt;br /&gt;
    Step1 : php ./codecept.phar build&lt;br /&gt;
&lt;br /&gt;
=== Running the Test ===&lt;br /&gt;
Run Selenium server&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Download&lt;br /&gt;
curl -O http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&lt;br /&gt;
# And start the Selenium Server&lt;br /&gt;
java -Xms40m -Xmx256m -jar /Applications/XAMPP/xamppfiles/htdocs/selenium/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Rename tests/acceptance.suite.dist.yml to tests/acceptance.suite.yml&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 1: Modify the configuration at tests/acceptance.suite.yml to fit your server details.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 2: php codecept.phar run&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
with --steps to see a step-by-step report on the performed actions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --steps&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with --html. This command will run all tests for all suites, displaying the steps, and building HTML and XML reports. Reports will be store in tests/_output/ directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --html&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To activate the debug mode in Codeception just add the parameter --debug when you run the tests:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run acceptance --debug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Best Practices at Testing ==&lt;br /&gt;
=== Writting reliable locators ===&lt;br /&gt;
Writing good locators can be tricky. The Mozilla team has written an excellent guide titled [https://blog.mozilla.org/webqa/2013/09/26/writing-reliable-locators-for-selenium-and-webdriver-tests/ Writing reliable locators for Selenium and WebDriver tests].&lt;br /&gt;
&lt;br /&gt;
If the locator is an array, it should have a single element, with the key signifying the locator type (`id`, `name`, `css`, `xpath`, `link`, or `class`) and the value being the locator itself. This is called a &amp;quot;strict&amp;quot; locator. Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* [&#039;id&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div id=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;name&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div name=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;css&#039; =&amp;gt; &#039;input[type=input][value=foo]&#039;] matches `&amp;lt;input type=&amp;quot;input&amp;quot; value=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;xpath&#039; =&amp;gt; &amp;quot;//input[@type=&#039;submit&#039;][contains(@value, &#039;foo&#039;)]&amp;quot;] matches `&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;foobar&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;link&#039; =&amp;gt; &#039;Click here&#039;] matches `&amp;lt;a href=&amp;quot;google.com&amp;quot;&amp;gt;Click here&amp;lt;/a&amp;gt;`&lt;br /&gt;
* [&#039;class&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div class=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
=== How to use URLs ===&lt;br /&gt;
Codeception documentation suggests to use URL&#039;s as properties of a Page Object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(JoomlaInstallationConfigurationPage::$URL);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of hardcoding the url in the test:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The pros of this approach is:&lt;br /&gt;
- first way is more readable for non developers. &lt;br /&gt;
- it helps to make tests more maintenable in the case of a url change in the system&lt;br /&gt;
&lt;br /&gt;
However in joomla a change in an url is rare, and if it happens changing it will just be a Find&amp;amp;Replace task. I Joomla test we want to have the benefit of both, the url and a representative name that describes the page where we are going. That will make our tests more readable. Thus, we will write the urls the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amGoingTo(&#039;go to Create New Banner page at Joomla Administrator&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Working with Hidden Elements ===&lt;br /&gt;
Selenium can&#039;t interact with elements that are not visible:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;http://www.joomla.org&amp;quot; style=&amp;quot;display: none;&amp;quot; id=&amp;quot;joomla_site&amp;quot;&amp;gt;go to joomla&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case you can&#039;t do:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually this happens when you need to wait for a Javascript animation that end up showing that element, so in this case you will need to do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForElementVisible(&#039;#joomla_site&#039;);&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== When do not use contains ===&lt;br /&gt;
We do not recommend to use the function contains on XPath because is not specific and can create false positives at tests.&lt;br /&gt;
See: https://github.com/joomla-projects/GSOC-Webdriver_system_tests_for_CMS/pull/99#issuecomment-69004191&lt;br /&gt;
=== Always add Strict Locators to your tests ===&lt;br /&gt;
Performance in tests is very important. You can reduce dramatically the time spent on a test with just adding a few extra locators. For example, the following code pertains to a test:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// see($text, $selector = null)&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the previous code we are not facilitating the &amp;quot;Selector&amp;quot; so Codeception will have to search for the element in all the HTML. Doing this instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the tests went from: Time: 1.17 minutes&lt;br /&gt;
to: Time: 49.18 seconds&lt;br /&gt;
&lt;br /&gt;
You can see this video of a real example: http://www.youtube.com/watch?v=0JCv0BR2yZY&lt;br /&gt;
&lt;br /&gt;
Losing 30 seconds in every Assertion can delay your tests dramatically. Therefore, remind always to add xPath locators to all your Assertions.&lt;br /&gt;
[[Category:Automated Testing]]&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;see ====&lt;br /&gt;
Do not use &#039;&#039;see&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;waitForText ====&lt;br /&gt;
Do not use &#039;&#039;waitForText&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;, 10, [&#039;css&#039; =&amp;gt; &#039;h3&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Incase of an element has multiple css classes, When Using CSS Locators make sure you use more specific class as locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert-success&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
A page could have mutiple elements which can have &#039;&#039;alert&#039;&#039; css class associated, hence being more specific helps.&lt;br /&gt;
&lt;br /&gt;
==== How much time should I wait for an Element or Text? ====&lt;br /&gt;
You may have noticed that the second parameter in the I waitForText is an integer that represents how much &amp;quot;time to wait&amp;quot; in seconds:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;a text to wait for&#039;, 10, [&#039;...&#039; =&amp;gt; &#039;...&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But, how much time is the right time to wait for a text?&lt;br /&gt;
&lt;br /&gt;
PHP maximum execution time before returning a Fatal Error for timeout is set by default to 30 seconds. We suggest to set it for 10 seconds. A waitForText over 10 seconds will definitely mean that something is not performing well.&lt;br /&gt;
&lt;br /&gt;
=== Quote and Double Quotes in Compex XPaths ===&lt;br /&gt;
Sometimes you will have to write XPaths that looks like:&lt;br /&gt;
&lt;br /&gt;
 //button[@onclick=&#039;Joomla.submitbutton(&amp;quot;config.save.application.apply&amp;quot;)&#039;]&lt;br /&gt;
&lt;br /&gt;
When moved to a Page Object you will probably will face this situation:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_error_escaping_quotes_on_xpaths.png|framed|center|Typical issue when you write a long XPath in a Page object]]&lt;br /&gt;
&lt;br /&gt;
To avoid it remind to escape the quotes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
// Right&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=\&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)\&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Generating txt/html scenarios===&lt;br /&gt;
Codeception allows you to generate user-friendly text scenarios from scenario-driven from Cest and Cept php test (see http://codeception.com/docs/reference/Commands#GenerateScenarios).&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t use double quotes, use single quotes instead===&lt;br /&gt;
Do not use double quotes (&amp;quot;) for surrounding strings:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &amp;quot;&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;&amp;quot;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you use single quotes instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Congratulations! Joomla! is now installed.&#039;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will get the right expected result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Congratulations! Joomla! is now installed.&#039;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The reason of not being able to use double quotes is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;br /&gt;
&lt;br /&gt;
===Do not leave spaces between parameters in Cepts===&lt;br /&gt;
See the two lines:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
// Good&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;,10,&#039;h3&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Main Configuration&#039;,&amp;quot; 10&amp;quot;,&amp;quot; &#039;h3&#039;&lt;br /&gt;
&lt;br /&gt;
The reason that you are asked to not add spaces between parameters is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=File:Acceptance.suite.dist.yml_rename.png&amp;diff=186584</id>
		<title>File:Acceptance.suite.dist.yml rename.png</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=File:Acceptance.suite.dist.yml_rename.png&amp;diff=186584"/>
		<updated>2015-05-30T16:48:18Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: FrankyD uploaded a new version of &amp;amp;quot;File:Acceptance.suite.dist.yml rename.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Screenshot of rename the &amp;quot;acceptance.suite.dist.yml&amp;quot; file to &amp;quot;acceptance.suite.yml&amp;quot; and configure the parameters to your system variables&lt;br /&gt;
== Licensing ==&lt;br /&gt;
{{JEDL}}&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=File:Acceptance.suite.dist.yml_rename.png&amp;diff=186581</id>
		<title>File:Acceptance.suite.dist.yml rename.png</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=File:Acceptance.suite.dist.yml_rename.png&amp;diff=186581"/>
		<updated>2015-05-30T16:45:52Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Screenshot of rename the &amp;quot;acceptance.suite.dist.yml&amp;quot; file to &amp;quot;acceptance.suite.yml&amp;quot; and configure the parameters to your system variables&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Screenshot of rename the &amp;quot;acceptance.suite.dist.yml&amp;quot; file to &amp;quot;acceptance.suite.yml&amp;quot; and configure the parameters to your system variables&lt;br /&gt;
== Licensing ==&lt;br /&gt;
{{JEDL}}&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186558</id>
		<title>Testing Joomla Extensions with Codeception</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186558"/>
		<updated>2015-05-30T16:33:23Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;nowiki&amp;gt;Note: this page is under construction&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What is Codeception? ==&lt;br /&gt;
Codeception PHP Testing Framework is designed to work just out of the box. This means its installation requires minimal steps and no external dependencies preinstalled (except PHP, of course). Only one configuration step should be taken and you are ready to test your web application from an eye of actual user.&lt;br /&gt;
&lt;br /&gt;
See the following video of codeception in action testing Joomla: &lt;br /&gt;
&lt;br /&gt;
{{#widget:YouTube|id=Vc1BJNnhsFM}}&lt;br /&gt;
&lt;br /&gt;
Codeception provides possibilities to do Unit Testing or to Test APIs, however this page is focused in &#039;&#039;&#039;System Testing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Why Use Codeception? ==&lt;br /&gt;
&#039;&#039;Why use Codeception when we already have Selenium IDE?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Codeception works great with Selenium. But with Codeception you can write your tests in PHP. The main reason is: Selenium IDE tests are tightly bound to XPath locators. If you ever change anything in layout tests will fall. Codeception locators are more stable. You can use names, labels, button names and CSS to match elements on page. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features&#039;&#039;&#039;&lt;br /&gt;
* Selenium WebDriver integration&lt;br /&gt;
* Elements matched by name, CSS, XPath&lt;br /&gt;
* PageObjects and StepObjects included&lt;br /&gt;
* Powered by PHPUnit&lt;br /&gt;
* Data Cleanup&lt;br /&gt;
* Parallel Execution of tests&lt;br /&gt;
* BDD-style readable tests&lt;br /&gt;
&lt;br /&gt;
== Architecture of a test ==&lt;br /&gt;
The testing framework is built on the three layered testing architecture&lt;br /&gt;
&lt;br /&gt;
=== Scenarios (Cept Class) ===&lt;br /&gt;
Cept or Test, it is the main class which contains steps of execution for the tests, Cept Class will call Step Class functions which will indirectly make use of page objects to perform operations&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I = new AcceptanceTester($scenario);&lt;br /&gt;
$I-&amp;gt;wantTo(&#039;Install Joomla CMS&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;http://localhost/installation/index.php&#039;);&lt;br /&gt;
// I Wait for the text Main Configuration, meaning that the page is loaded&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;Language Selector&#039;]);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;English (United Kingdom)&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Site Name&#039;, &#039;weblinks&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Description&#039;, &#039;Site for testing Weblinks component&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Email&#039;, $cfg[&#039;Admin email&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Username&#039;, $cfg[&#039;username&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Confirm Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;click(&#039;Next&#039;);&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page Objects ===&lt;br /&gt;
Each page on your application has a class which we call page objects, each page class will have information about the URL, fields, Text present on the page. We use the best possible selector for any field on the page.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginManagerPage&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * @var string Url of the page&lt;br /&gt;
	 */&lt;br /&gt;
	public static $URL = &#039;/administrator/index.php&#039;;&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Array of Page elements indexed by descriptive name or label&lt;br /&gt;
	 *&lt;br /&gt;
	 * @var array&lt;br /&gt;
	 */&lt;br /&gt;
	public static $elements = array(&lt;br /&gt;
		&#039;username&#039; =&amp;gt; &amp;quot;#mod-login-username&amp;quot;,&lt;br /&gt;
		&#039;password&#039; =&amp;gt; &amp;quot;#mod-login-password&amp;quot;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Naming convention for Page Objects ====&lt;br /&gt;
When this document is created Codeception 2.0 was not having a PSR-4 compatible autoloader. Therefore we are creating a convention so with the future Codeception 2.1 with PSR-4 compatible autoloader (https://github.com/Codeception/Codeception/pull/1228) we are creating a naming convention for Pages so it will cost us a small effort to move to autoloaded classes in the future.&lt;br /&gt;
&lt;br /&gt;
The naming convention works as follows:&lt;br /&gt;
&lt;br /&gt;
 APPLICATION (for example Joomla, Patchtester, Weblinks or your Extension name)&lt;br /&gt;
 + CLIENT (in Joomla we use it for defining if is Installation, Administrator or Frontend&lt;br /&gt;
 + CLIENT PART (In Joomla we use it following the menu are were it belongs: Components, Menus, System,...)&lt;br /&gt;
 + PAGE NAME (The Page name) &lt;br /&gt;
 + Page&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
 JoomlaAdministratorLoginPage&lt;br /&gt;
 JoomlaAdministratorSystemGlobalconfigurationPage&lt;br /&gt;
 JoomlaInstallationConfigurationPage&lt;br /&gt;
&lt;br /&gt;
And they are located with a folder estructure similar to:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_pages_folder_structure.png|framed|center|Folder estructure for Pages in System Tests]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remind that in Codeception 2.0 you need to specify each folder in the acceptance/_bootstrap.php file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
// Here you can initialize variables that will be available to your tests&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/installation&#039;);&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/administrator&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#PageObjects&lt;br /&gt;
&lt;br /&gt;
=== Step Objects ===&lt;br /&gt;
Step Objects are classes which contains steps which are to be executed on the application to perform certain operations, step objects make use of page objects to perform these actions.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginSteps extends \AcceptanceTester&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * Function to execute an Admin Login for Joomla 3&lt;br /&gt;
	 *&lt;br /&gt;
	 * @return void&lt;br /&gt;
	 */&lt;br /&gt;
	public function doAdministratorLogin($user, $password)&lt;br /&gt;
	{&lt;br /&gt;
		$I = $this;&lt;br /&gt;
		$I-&amp;gt;amOnPage(\JoomlaAdministratorLoginPage::$URL);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;username&#039;], $user);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;password&#039;], $password);&lt;br /&gt;
		$I-&amp;gt;click(&#039;Log in&#039;);&lt;br /&gt;
		$I-&amp;gt;see(&#039;Category Manager&#039;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#StepObjects&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Joomla Browser Module ===&lt;br /&gt;
The Joomla Browser is a Codeception Module that incorporates general functions to your tests like:&lt;br /&gt;
- do administrator login&lt;br /&gt;
- install joomla&lt;br /&gt;
- install extension&lt;br /&gt;
- ...&lt;br /&gt;
&lt;br /&gt;
Find details about it at: https://github.com/joomla-projects/joomla-browser#table-of-contents&lt;br /&gt;
&lt;br /&gt;
== Getting started from scratch: what you need to download and install ==&lt;br /&gt;
To get the test environment running you need to have several components installed.&lt;br /&gt;
&lt;br /&gt;
=== local webserver ===&lt;br /&gt;
If you do not already have a local test server running you may want to check out:&lt;br /&gt;
https://www.mamp.info/&lt;br /&gt;
https://www.apachefriends.org/&lt;br /&gt;
http://www.ampps.com/&lt;br /&gt;
&lt;br /&gt;
If you are not familiar with a local web-server, learn that first before you advance futher. &lt;br /&gt;
&lt;br /&gt;
===Wget===&lt;br /&gt;
Wget is a command line program that retrieves content from web servers. For our purposes it is used to get selenium (browser test environment). See wikipedia: https://en.wikipedia.org/wiki/Wget&lt;br /&gt;
====Wget on Mac====&lt;br /&gt;
For Mac Users Homebrew (package manager for OS X) is a very easy way to get wget running. Download Homebrew at: http://brew.sh/ &lt;br /&gt;
After installation run the following command in your terminal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
brew install wget&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Java Runtime Environment (JRE) ===&lt;br /&gt;
The JRE has to be installed, so the tests will be executable. You find the recent versions at the Oracle Website.&lt;br /&gt;
In end of May 2015 this is: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html&lt;br /&gt;
later on that link could be obsolete and should be changed if there is a newer version out.&lt;br /&gt;
&lt;br /&gt;
Newer Mac OS Versions are not shipped any more with the JRE, so they have to download that too.&lt;br /&gt;
&lt;br /&gt;
=== Firefox ===&lt;br /&gt;
Selenium is testing in the browser Firefox. The selenium version is not that quick with the updates, as the Firefox browser, if the test is not executable, then it can be that you manually have to install an older version of Firefox.&lt;br /&gt;
Sadly that can be a try and error thing. To get older versions of Firefox: https://ftp.mozilla.org/pub/mozilla.org/firefox/releases/ here you will find many folders. Just try the first one that came before the Firefox version that you have been using (and that did not work). In the version folders you will find folders for all the different operating systems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== configure test system variables ===&lt;br /&gt;
In your the folder that you installed, downloaded, pulled (git) the project, you have to rename the &amp;quot;&#039;&#039;acceptance.suite.dist.yml&#039;&#039;&amp;quot; file to &amp;quot;&#039;&#039;acceptance.suite.yml&#039;&#039;&amp;quot; and configure the parameters to your system variables.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== then run the first test ===&lt;br /&gt;
Once your machine is able to run tests (see &#039;&#039;The Joomla Browser Module&#039;&#039;), you are able to start working. Check the contents of the /tests/ folder in weblinks and try to understand the structure of the tests. After that check&lt;br /&gt;
the tasks are at: https://github.com/joomla-extensions/weblinks/issues/47 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The principles for writing a test: Readability and Performance ==&lt;br /&gt;
In Joomla we give priority to Readability over Performance, even when performance is a must.&lt;br /&gt;
&lt;br /&gt;
To explain that let me show an example: Let&#039;s say that we want to fill a field Username in a login form. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;administrator/index.php&amp;quot; method=&amp;quot;post&amp;quot; id=&amp;quot;form-login&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;username_field&amp;quot;&amp;gt;Username&amp;lt;/label&amp;gt;&lt;br /&gt;
  &amp;lt;input name=&amp;quot;username_field&amp;quot; tabindex=&amp;quot;1&amp;quot; id=&amp;quot;username_field&amp;quot; type=&amp;quot;text&amp;quot; size=&amp;quot;15&amp;quot; /&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the most performant way to fill that form field would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;#username_field&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And usually we would move that to a page object element ending in:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(\LoginPage::$username, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However Codeception is a smart framework and it adds some magic to it&#039;s methods (see: https://github.com/Codeception/Codeception/blob/2.0/src/Codeception/Module/WebDriver.php#L511-L513). It allows me to write more readable tests (keeping performance hight). &lt;br /&gt;
&lt;br /&gt;
If we do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Username&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Codeception will be smart and will search first in the page if there is any &amp;quot;LABEL&amp;quot; called Username. That is a fast operation, so performance will be affected just a little. And instead we have written less code than in previous examples.&lt;br /&gt;
&lt;br /&gt;
Note: sometimes this tricks are not always possible, labels are not always there or there are some elements hidden that shows and hides depending on a Javascript. All these special cases would require a Page element.&lt;br /&gt;
&lt;br /&gt;
Still there is a definitive method of using locators that made them readable and performant called: strict Locators see [[Testing_Joomla_Extensions_with_Codeception#Writting_reliable_locators]].&lt;br /&gt;
&lt;br /&gt;
With them we do: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField([&#039;id&#039; =&amp;gt; &#039;username_field&#039;], &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In conclusion we have more readable tests and less code to maintain while keeping performance. That is a win!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setting Up Codeception ==&lt;br /&gt;
=== setting up the repository ===&lt;br /&gt;
&#039;&#039;&#039;clone the directory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Fork [https://github.com/joomla-projects/com_localise com_localise]&lt;br /&gt;
# &lt;br /&gt;
# Git clone git@github.com:*your-github-profile-name*/com_localise.git&lt;br /&gt;
&lt;br /&gt;
=== Testing with Codeception ===&lt;br /&gt;
&lt;br /&gt;
There are two ways to get and run codeception, via PHAR or via Composer. Using &#039;&#039;&#039;Composer is recommended&#039;&#039;&#039; (because we are using in some tests the Codeception 2.1 development version not available in the composer.phar).&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Using Composer&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    You need to have Composer in your system, if not download it from here: https://getcomposer.org/&lt;br /&gt;
&lt;br /&gt;
    Step 1: composer update&lt;br /&gt;
&lt;br /&gt;
    Step 2: run Codeception by doing: php vendor/bin/codecept build&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Codeception.phar&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    Linux Machine  : wget http://codeception.com/codecept.phar&lt;br /&gt;
&lt;br /&gt;
    Windows Machine: Download from [http://codeception.com/install codecept.phar]&lt;br /&gt;
&lt;br /&gt;
    Step1 : php ./codecept.phar build&lt;br /&gt;
&lt;br /&gt;
=== Running the Test ===&lt;br /&gt;
Run Selenium server&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Download&lt;br /&gt;
curl -O http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&lt;br /&gt;
# And start the Selenium Server&lt;br /&gt;
java -Xms40m -Xmx256m -jar /Applications/XAMPP/xamppfiles/htdocs/selenium/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Rename tests/acceptance.suite.dist.yml to tests/acceptance.suite.yml&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 1: Modify the configuration at tests/acceptance.suite.yml to fit your server details.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 2: php codecept.phar run&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
with --steps to see a step-by-step report on the performed actions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --steps&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with --html. This command will run all tests for all suites, displaying the steps, and building HTML and XML reports. Reports will be store in tests/_output/ directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --html&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To activate the debug mode in Codeception just add the parameter --debug when you run the tests:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run acceptance --debug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Best Practices at Testing ==&lt;br /&gt;
=== Writting reliable locators ===&lt;br /&gt;
Writing good locators can be tricky. The Mozilla team has written an excellent guide titled [https://blog.mozilla.org/webqa/2013/09/26/writing-reliable-locators-for-selenium-and-webdriver-tests/ Writing reliable locators for Selenium and WebDriver tests].&lt;br /&gt;
&lt;br /&gt;
If the locator is an array, it should have a single element, with the key signifying the locator type (`id`, `name`, `css`, `xpath`, `link`, or `class`) and the value being the locator itself. This is called a &amp;quot;strict&amp;quot; locator. Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* [&#039;id&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div id=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;name&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div name=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;css&#039; =&amp;gt; &#039;input[type=input][value=foo]&#039;] matches `&amp;lt;input type=&amp;quot;input&amp;quot; value=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;xpath&#039; =&amp;gt; &amp;quot;//input[@type=&#039;submit&#039;][contains(@value, &#039;foo&#039;)]&amp;quot;] matches `&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;foobar&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;link&#039; =&amp;gt; &#039;Click here&#039;] matches `&amp;lt;a href=&amp;quot;google.com&amp;quot;&amp;gt;Click here&amp;lt;/a&amp;gt;`&lt;br /&gt;
* [&#039;class&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div class=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
=== How to use URLs ===&lt;br /&gt;
Codeception documentation suggests to use URL&#039;s as properties of a Page Object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(JoomlaInstallationConfigurationPage::$URL);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of hardcoding the url in the test:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The pros of this approach is:&lt;br /&gt;
- first way is more readable for non developers. &lt;br /&gt;
- it helps to make tests more maintenable in the case of a url change in the system&lt;br /&gt;
&lt;br /&gt;
However in joomla a change in an url is rare, and if it happens changing it will just be a Find&amp;amp;Replace task. I Joomla test we want to have the benefit of both, the url and a representative name that describes the page where we are going. That will make our tests more readable. Thus, we will write the urls the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amGoingTo(&#039;go to Create New Banner page at Joomla Administrator&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Working with Hidden Elements ===&lt;br /&gt;
Selenium can&#039;t interact with elements that are not visible:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;http://www.joomla.org&amp;quot; style=&amp;quot;display: none;&amp;quot; id=&amp;quot;joomla_site&amp;quot;&amp;gt;go to joomla&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case you can&#039;t do:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually this happens when you need to wait for a Javascript animation that end up showing that element, so in this case you will need to do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForElementVisible(&#039;#joomla_site&#039;);&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== When do not use contains ===&lt;br /&gt;
We do not recommend to use the function contains on XPath because is not specific and can create false positives at tests.&lt;br /&gt;
See: https://github.com/joomla-projects/GSOC-Webdriver_system_tests_for_CMS/pull/99#issuecomment-69004191&lt;br /&gt;
=== Always add Strict Locators to your tests ===&lt;br /&gt;
Performance in tests is very important. You can reduce dramatically the time spent on a test with just adding a few extra locators. For example, the following code pertains to a test:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// see($text, $selector = null)&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the previous code we are not facilitating the &amp;quot;Selector&amp;quot; so Codeception will have to search for the element in all the HTML. Doing this instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the tests went from: Time: 1.17 minutes&lt;br /&gt;
to: Time: 49.18 seconds&lt;br /&gt;
&lt;br /&gt;
You can see this video of a real example: http://www.youtube.com/watch?v=0JCv0BR2yZY&lt;br /&gt;
&lt;br /&gt;
Losing 30 seconds in every Assertion can delay your tests dramatically. Therefore, remind always to add xPath locators to all your Assertions.&lt;br /&gt;
[[Category:Automated Testing]]&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;see ====&lt;br /&gt;
Do not use &#039;&#039;see&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;waitForText ====&lt;br /&gt;
Do not use &#039;&#039;waitForText&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;, 10, [&#039;css&#039; =&amp;gt; &#039;h3&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Incase of an element has multiple css classes, When Using CSS Locators make sure you use more specific class as locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert-success&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
A page could have mutiple elements which can have &#039;&#039;alert&#039;&#039; css class associated, hence being more specific helps.&lt;br /&gt;
&lt;br /&gt;
==== How much time should I wait for an Element or Text? ====&lt;br /&gt;
You may have noticed that the second parameter in the I waitForText is an integer that represents how much &amp;quot;time to wait&amp;quot; in seconds:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;a text to wait for&#039;, 10, [&#039;...&#039; =&amp;gt; &#039;...&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But, how much time is the right time to wait for a text?&lt;br /&gt;
&lt;br /&gt;
PHP maximum execution time before returning a Fatal Error for timeout is set by default to 30 seconds. We suggest to set it for 10 seconds. A waitForText over 10 seconds will definitely mean that something is not performing well.&lt;br /&gt;
&lt;br /&gt;
=== Quote and Double Quotes in Compex XPaths ===&lt;br /&gt;
Sometimes you will have to write XPaths that looks like:&lt;br /&gt;
&lt;br /&gt;
 //button[@onclick=&#039;Joomla.submitbutton(&amp;quot;config.save.application.apply&amp;quot;)&#039;]&lt;br /&gt;
&lt;br /&gt;
When moved to a Page Object you will probably will face this situation:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_error_escaping_quotes_on_xpaths.png|framed|center|Typical issue when you write a long XPath in a Page object]]&lt;br /&gt;
&lt;br /&gt;
To avoid it remind to escape the quotes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
// Right&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=\&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)\&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Generating txt/html scenarios===&lt;br /&gt;
Codeception allows you to generate user-friendly text scenarios from scenario-driven from Cest and Cept php test (see http://codeception.com/docs/reference/Commands#GenerateScenarios).&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t use double quotes, use single quotes instead===&lt;br /&gt;
Do not use double quotes (&amp;quot;) for surrounding strings:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &amp;quot;&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;&amp;quot;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you use single quotes instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Congratulations! Joomla! is now installed.&#039;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will get the right expected result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Congratulations! Joomla! is now installed.&#039;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The reason of not being able to use double quotes is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;br /&gt;
&lt;br /&gt;
===Do not leave spaces between parameters in Cepts===&lt;br /&gt;
See the two lines:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
// Good&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;,10,&#039;h3&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Main Configuration&#039;,&amp;quot; 10&amp;quot;,&amp;quot; &#039;h3&#039;&lt;br /&gt;
&lt;br /&gt;
The reason that you are asked to not add spaces between parameters is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186491</id>
		<title>Testing Joomla Extensions with Codeception</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla_Extensions_with_Codeception&amp;diff=186491"/>
		<updated>2015-05-30T16:12:08Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Added how to start section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;nowiki&amp;gt;Note: this page is under construction&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What is Codeception? ==&lt;br /&gt;
Codeception PHP Testing Framework is designed to work just out of the box. This means its installation requires minimal steps and no external dependencies preinstalled (except PHP, of course). Only one configuration step should be taken and you are ready to test your web application from an eye of actual user.&lt;br /&gt;
&lt;br /&gt;
See the following video of codeception in action testing Joomla: &lt;br /&gt;
&lt;br /&gt;
{{#widget:YouTube|id=Vc1BJNnhsFM}}&lt;br /&gt;
&lt;br /&gt;
Codeception provides possibilities to do Unit Testing or to Test APIs, however this page is focused in &#039;&#039;&#039;System Testing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Why Use Codeception? ==&lt;br /&gt;
&#039;&#039;Why use Codeception when we already have Selenium IDE?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Codeception works great with Selenium. But with Codeception you can write your tests in PHP. The main reason is: Selenium IDE tests are tightly bound to XPath locators. If you ever change anything in layout tests will fall. Codeception locators are more stable. You can use names, labels, button names and CSS to match elements on page. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features&#039;&#039;&#039;&lt;br /&gt;
* Selenium WebDriver integration&lt;br /&gt;
* Elements matched by name, CSS, XPath&lt;br /&gt;
* PageObjects and StepObjects included&lt;br /&gt;
* Powered by PHPUnit&lt;br /&gt;
* Data Cleanup&lt;br /&gt;
* Parallel Execution of tests&lt;br /&gt;
* BDD-style readable tests&lt;br /&gt;
&lt;br /&gt;
== Architecture of a test ==&lt;br /&gt;
The testing framework is built on the three layered testing architecture&lt;br /&gt;
&lt;br /&gt;
=== Scenarios (Cept Class) ===&lt;br /&gt;
Cept or Test, it is the main class which contains steps of execution for the tests, Cept Class will call Step Class functions which will indirectly make use of page objects to perform operations&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I = new AcceptanceTester($scenario);&lt;br /&gt;
$I-&amp;gt;wantTo(&#039;Install Joomla CMS&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;http://localhost/installation/index.php&#039;);&lt;br /&gt;
// I Wait for the text Main Configuration, meaning that the page is loaded&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;Language Selector&#039;]);&lt;br /&gt;
$I-&amp;gt;click(JoomlaInstallationConfigurationPage::$elements[&#039;English (United Kingdom)&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Site Name&#039;, &#039;weblinks&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Description&#039;, &#039;Site for testing Weblinks component&#039;);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Email&#039;, $cfg[&#039;Admin email&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Username&#039;, $cfg[&#039;username&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Confirm Admin Password&#039;, $cfg[&#039;password&#039;]);&lt;br /&gt;
$I-&amp;gt;click(&#039;Next&#039;);&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Page Objects ===&lt;br /&gt;
Each page on your application has a class which we call page objects, each page class will have information about the URL, fields, Text present on the page. We use the best possible selector for any field on the page.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginManagerPage&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * @var string Url of the page&lt;br /&gt;
	 */&lt;br /&gt;
	public static $URL = &#039;/administrator/index.php&#039;;&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Array of Page elements indexed by descriptive name or label&lt;br /&gt;
	 *&lt;br /&gt;
	 * @var array&lt;br /&gt;
	 */&lt;br /&gt;
	public static $elements = array(&lt;br /&gt;
		&#039;username&#039; =&amp;gt; &amp;quot;#mod-login-username&amp;quot;,&lt;br /&gt;
		&#039;password&#039; =&amp;gt; &amp;quot;#mod-login-password&amp;quot;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Naming convention for Page Objects ====&lt;br /&gt;
When this document is created Codeception 2.0 was not having a PSR-4 compatible autoloader. Therefore we are creating a convention so with the future Codeception 2.1 with PSR-4 compatible autoloader (https://github.com/Codeception/Codeception/pull/1228) we are creating a naming convention for Pages so it will cost us a small effort to move to autoloaded classes in the future.&lt;br /&gt;
&lt;br /&gt;
The naming convention works as follows:&lt;br /&gt;
&lt;br /&gt;
 APPLICATION (for example Joomla, Patchtester, Weblinks or your Extension name)&lt;br /&gt;
 + CLIENT (in Joomla we use it for defining if is Installation, Administrator or Frontend&lt;br /&gt;
 + CLIENT PART (In Joomla we use it following the menu are were it belongs: Components, Menus, System,...)&lt;br /&gt;
 + PAGE NAME (The Page name) &lt;br /&gt;
 + Page&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
 JoomlaAdministratorLoginPage&lt;br /&gt;
 JoomlaAdministratorSystemGlobalconfigurationPage&lt;br /&gt;
 JoomlaInstallationConfigurationPage&lt;br /&gt;
&lt;br /&gt;
And they are located with a folder estructure similar to:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_pages_folder_structure.png|framed|center|Folder estructure for Pages in System Tests]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remind that in Codeception 2.0 you need to specify each folder in the acceptance/_bootstrap.php file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
// Here you can initialize variables that will be available to your tests&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/installation&#039;);&lt;br /&gt;
\Codeception\Util\Autoload::registerSuffix(&#039;Page&#039;, __DIR__.DIRECTORY_SEPARATOR.&#039;_pages/joomla/administrator&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Documentation ====&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#PageObjects&lt;br /&gt;
&lt;br /&gt;
=== Step Objects ===&lt;br /&gt;
Step Objects are classes which contains steps which are to be executed on the application to perform certain operations, step objects make use of page objects to perform these actions.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class JoomlaAdministratorLoginSteps extends \AcceptanceTester&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * Function to execute an Admin Login for Joomla 3&lt;br /&gt;
	 *&lt;br /&gt;
	 * @return void&lt;br /&gt;
	 */&lt;br /&gt;
	public function doAdministratorLogin($user, $password)&lt;br /&gt;
	{&lt;br /&gt;
		$I = $this;&lt;br /&gt;
		$I-&amp;gt;amOnPage(\JoomlaAdministratorLoginPage::$URL);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;username&#039;], $user);&lt;br /&gt;
		$I-&amp;gt;fillField(\JoomlaAdministratorLoginPage::$elements[&#039;password&#039;], $password);&lt;br /&gt;
		$I-&amp;gt;click(&#039;Log in&#039;);&lt;br /&gt;
		$I-&amp;gt;see(&#039;Category Manager&#039;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More info: http://codeception.com/docs/07-AdvancedUsage#StepObjects&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Joomla Browser Module ===&lt;br /&gt;
The Joomla Browser is a Codeception Module that incorporates general functions to your tests like:&lt;br /&gt;
- do administrator login&lt;br /&gt;
- install joomla&lt;br /&gt;
- install extension&lt;br /&gt;
- ...&lt;br /&gt;
&lt;br /&gt;
Find details about it at: https://github.com/joomla-projects/joomla-browser#table-of-contents&lt;br /&gt;
&lt;br /&gt;
== Getting started from scratch: what you need to download and install ==&lt;br /&gt;
To get the test environment running you need to have several components installed.&lt;br /&gt;
===Wget===&lt;br /&gt;
Wget is a command line program that retrieves content from web servers. For our purposes it is used to get selenium (browser test environment). See wikipedia: https://en.wikipedia.org/wiki/Wget&lt;br /&gt;
====Wget on Mac====&lt;br /&gt;
For Mac Users Homebrew (package manager for OS X) is a very easy way to get wget running. Download Homebrew at: http://brew.sh/ &lt;br /&gt;
After installation run the following command in your terminal&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
brew install wget&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Java Runtime Environment (JRE) ===&lt;br /&gt;
The JRE has to be installed, so the tests will be executable. You find the recent versions at the Oracle Website.&lt;br /&gt;
In end of May 2015 this is: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html&lt;br /&gt;
later on that link could be obsolete and should be changed if there is a newer version out.&lt;br /&gt;
&lt;br /&gt;
Newer Mac OS Versions are not shipped any more with the JRE, so they have to download that too.&lt;br /&gt;
&lt;br /&gt;
=== Firefox ===&lt;br /&gt;
Selenium is testing in the browser Firefox. The selenium version is not that quick with the updates, as the Firefox browser, if the test is not executable, then it can be that you manually have to install an older version of Firefox.&lt;br /&gt;
Sadly that can be a try and error thing. To get older versions of Firefox: https://ftp.mozilla.org/pub/mozilla.org/firefox/releases/ here you will find many folders. Just try the first one that came before the Firefox version that you have been using (and that did not work). In the version folders you will find folders for all the different operating systems.&lt;br /&gt;
&lt;br /&gt;
=== then run the first test ===&lt;br /&gt;
Once your machine is able to run tests (see &#039;&#039;The Joomla Browser Module&#039;&#039;), you are able to start working. Check the contents of the /tests/ folder in weblinks and try to understand the structure of the tests. After that check&lt;br /&gt;
the tasks are at: https://github.com/joomla-extensions/weblinks/issues/47 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The principles for writing a test: Readability and Performance ==&lt;br /&gt;
In Joomla we give priority to Readability over Performance, even when performance is a must.&lt;br /&gt;
&lt;br /&gt;
To explain that let me show an example: Let&#039;s say that we want to fill a field Username in a login form. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;administrator/index.php&amp;quot; method=&amp;quot;post&amp;quot; id=&amp;quot;form-login&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;username_field&amp;quot;&amp;gt;Username&amp;lt;/label&amp;gt;&lt;br /&gt;
  &amp;lt;input name=&amp;quot;username_field&amp;quot; tabindex=&amp;quot;1&amp;quot; id=&amp;quot;username_field&amp;quot; type=&amp;quot;text&amp;quot; size=&amp;quot;15&amp;quot; /&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the most performant way to fill that form field would be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;#username_field&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And usually we would move that to a page object element ending in:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(\LoginPage::$username, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However Codeception is a smart framework and it adds some magic to it&#039;s methods (see: https://github.com/Codeception/Codeception/blob/2.0/src/Codeception/Module/WebDriver.php#L511-L513). It allows me to write more readable tests (keeping performance hight). &lt;br /&gt;
&lt;br /&gt;
If we do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField(&#039;Username&#039;, &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Codeception will be smart and will search first in the page if there is any &amp;quot;LABEL&amp;quot; called Username. That is a fast operation, so performance will be affected just a little. And instead we have written less code than in previous examples.&lt;br /&gt;
&lt;br /&gt;
Note: sometimes this tricks are not always possible, labels are not always there or there are some elements hidden that shows and hides depending on a Javascript. All these special cases would require a Page element.&lt;br /&gt;
&lt;br /&gt;
Still there is a definitive method of using locators that made them readable and performant called: strict Locators see [[Testing_Joomla_Extensions_with_Codeception#Writting_reliable_locators]].&lt;br /&gt;
&lt;br /&gt;
With them we do: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;fillField([&#039;id&#039; =&amp;gt; &#039;username_field&#039;], &#039;Mark&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In conclusion we have more readable tests and less code to maintain while keeping performance. That is a win!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setting Up Codeception ==&lt;br /&gt;
=== setting up the repository ===&lt;br /&gt;
&#039;&#039;&#039;clone the directory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Fork [https://github.com/joomla-projects/com_localise com_localise]&lt;br /&gt;
# &lt;br /&gt;
# Git clone git@github.com:*your-github-profile-name*/com_localise.git&lt;br /&gt;
&lt;br /&gt;
=== Testing with Codeception ===&lt;br /&gt;
&lt;br /&gt;
There are two ways to get and run codeception, via PHAR or via Composer. Using &#039;&#039;&#039;Composer is recommended&#039;&#039;&#039; (because we are using in some tests the Codeception 2.1 development version not available in the composer.phar).&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Using Composer&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    You need to have Composer in your system, if not download it from here: https://getcomposer.org/&lt;br /&gt;
&lt;br /&gt;
    Step 1: composer update&lt;br /&gt;
&lt;br /&gt;
    Step 2: run Codeception by doing: php vendor/bin/codecept build&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Codeception.phar&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
    Linux Machine  : wget http://codeception.com/codecept.phar&lt;br /&gt;
&lt;br /&gt;
    Windows Machine: Download from [http://codeception.com/install codecept.phar]&lt;br /&gt;
&lt;br /&gt;
    Step1 : php ./codecept.phar build&lt;br /&gt;
&lt;br /&gt;
=== Running the Test ===&lt;br /&gt;
Run Selenium server&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Download&lt;br /&gt;
curl -O http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&lt;br /&gt;
# And start the Selenium Server&lt;br /&gt;
java -Xms40m -Xmx256m -jar /Applications/XAMPP/xamppfiles/htdocs/selenium/selenium-server-standalone-2.45.0.jar&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Rename tests/acceptance.suite.dist.yml to tests/acceptance.suite.yml&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 1: Modify the configuration at tests/acceptance.suite.yml to fit your server details.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Step 2: php codecept.phar run&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
with --steps to see a step-by-step report on the performed actions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --steps&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with --html. This command will run all tests for all suites, displaying the steps, and building HTML and XML reports. Reports will be store in tests/_output/ directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run --html&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To activate the debug mode in Codeception just add the parameter --debug when you run the tests:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
php vendor/bin/codecept run acceptance --debug&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Best Practices at Testing ==&lt;br /&gt;
=== Writting reliable locators ===&lt;br /&gt;
Writing good locators can be tricky. The Mozilla team has written an excellent guide titled [https://blog.mozilla.org/webqa/2013/09/26/writing-reliable-locators-for-selenium-and-webdriver-tests/ Writing reliable locators for Selenium and WebDriver tests].&lt;br /&gt;
&lt;br /&gt;
If the locator is an array, it should have a single element, with the key signifying the locator type (`id`, `name`, `css`, `xpath`, `link`, or `class`) and the value being the locator itself. This is called a &amp;quot;strict&amp;quot; locator. Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
* [&#039;id&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div id=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;name&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div name=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;css&#039; =&amp;gt; &#039;input[type=input][value=foo]&#039;] matches `&amp;lt;input type=&amp;quot;input&amp;quot; value=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;xpath&#039; =&amp;gt; &amp;quot;//input[@type=&#039;submit&#039;][contains(@value, &#039;foo&#039;)]&amp;quot;] matches `&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;foobar&amp;quot;&amp;gt;`&lt;br /&gt;
* [&#039;link&#039; =&amp;gt; &#039;Click here&#039;] matches `&amp;lt;a href=&amp;quot;google.com&amp;quot;&amp;gt;Click here&amp;lt;/a&amp;gt;`&lt;br /&gt;
* [&#039;class&#039; =&amp;gt; &#039;foo&#039;] matches `&amp;lt;div class=&amp;quot;foo&amp;quot;&amp;gt;`&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
=== How to use URLs ===&lt;br /&gt;
Codeception documentation suggests to use URL&#039;s as properties of a Page Object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(JoomlaInstallationConfigurationPage::$URL);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of hardcoding the url in the test:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The pros of this approach is:&lt;br /&gt;
- first way is more readable for non developers. &lt;br /&gt;
- it helps to make tests more maintenable in the case of a url change in the system&lt;br /&gt;
&lt;br /&gt;
However in joomla a change in an url is rare, and if it happens changing it will just be a Find&amp;amp;Replace task. I Joomla test we want to have the benefit of both, the url and a representative name that describes the page where we are going. That will make our tests more readable. Thus, we will write the urls the following way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;amGoingTo(&#039;go to Create New Banner page at Joomla Administrator&#039;);&lt;br /&gt;
$I-&amp;gt;amOnPage(&#039;/administrator/index.php?option=com_banners&amp;amp;view...&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Working with Hidden Elements ===&lt;br /&gt;
Selenium can&#039;t interact with elements that are not visible:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;http://www.joomla.org&amp;quot; style=&amp;quot;display: none;&amp;quot; id=&amp;quot;joomla_site&amp;quot;&amp;gt;go to joomla&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this case you can&#039;t do:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually this happens when you need to wait for a Javascript animation that end up showing that element, so in this case you will need to do this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForElementVisible(&#039;#joomla_site&#039;);&lt;br /&gt;
$I-&amp;gt;click(&#039;go to joomla&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== When do not use contains ===&lt;br /&gt;
We do not recommend to use the function contains on XPath because is not specific and can create false positives at tests.&lt;br /&gt;
See: https://github.com/joomla-projects/GSOC-Webdriver_system_tests_for_CMS/pull/99#issuecomment-69004191&lt;br /&gt;
=== Always add Strict Locators to your tests ===&lt;br /&gt;
Performance in tests is very important. You can reduce dramatically the time spent on a test with just adding a few extra locators. For example, the following code pertains to a test:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// see($text, $selector = null)&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the previous code we are not facilitating the &amp;quot;Selector&amp;quot; so Codeception will have to search for the element in all the HTML. Doing this instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the tests went from: Time: 1.17 minutes&lt;br /&gt;
to: Time: 49.18 seconds&lt;br /&gt;
&lt;br /&gt;
You can see this video of a real example: http://www.youtube.com/watch?v=0JCv0BR2yZY&lt;br /&gt;
&lt;br /&gt;
Losing 30 seconds in every Assertion can delay your tests dramatically. Therefore, remind always to add xPath locators to all your Assertions.&lt;br /&gt;
[[Category:Automated Testing]]&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;see ====&lt;br /&gt;
Do not use &#039;&#039;see&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;see(&#039;Your article has been published&#039;, [&#039;id&#039; =&amp;gt; &#039;messages&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using locators in $I-&amp;gt;waitForText ====&lt;br /&gt;
Do not use &#039;&#039;waitForText&#039;&#039; without locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Finalisation&#039;, 10, [&#039;css&#039; =&amp;gt; &#039;h3&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Incase of an element has multiple css classes, When Using CSS Locators make sure you use more specific class as locator:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Right:&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Item Succesfully Created&#039;, 10, [&#039;class&#039; =&amp;gt; &#039;alert-success&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
A page could have mutiple elements which can have &#039;&#039;alert&#039;&#039; css class associated, hence being more specific helps.&lt;br /&gt;
&lt;br /&gt;
==== How much time should I wait for an Element or Text? ====&lt;br /&gt;
You may have noticed that the second parameter in the I waitForText is an integer that represents how much &amp;quot;time to wait&amp;quot; in seconds:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;a text to wait for&#039;, 10, [&#039;...&#039; =&amp;gt; &#039;...&#039;]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But, how much time is the right time to wait for a text?&lt;br /&gt;
&lt;br /&gt;
PHP maximum execution time before returning a Fatal Error for timeout is set by default to 30 seconds. We suggest to set it for 10 seconds. A waitForText over 10 seconds will definitely mean that something is not performing well.&lt;br /&gt;
&lt;br /&gt;
=== Quote and Double Quotes in Compex XPaths ===&lt;br /&gt;
Sometimes you will have to write XPaths that looks like:&lt;br /&gt;
&lt;br /&gt;
 //button[@onclick=&#039;Joomla.submitbutton(&amp;quot;config.save.application.apply&amp;quot;)&#039;]&lt;br /&gt;
&lt;br /&gt;
When moved to a Page Object you will probably will face this situation:&lt;br /&gt;
&lt;br /&gt;
[[File:System_tests_error_escaping_quotes_on_xpaths.png|framed|center|Typical issue when you write a long XPath in a Page object]]&lt;br /&gt;
&lt;br /&gt;
To avoid it remind to escape the quotes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
// Right&lt;br /&gt;
public static $elements = array(&lt;br /&gt;
   &#039;Save&#039; =&amp;gt; &amp;quot;//button[@onclick=\&amp;quot;Joomla.submitbutton(&#039;config.save.application.apply&#039;)\&amp;quot;]&amp;quot;&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Generating txt/html scenarios===&lt;br /&gt;
Codeception allows you to generate user-friendly text scenarios from scenario-driven from Cest and Cept php test (see http://codeception.com/docs/reference/Commands#GenerateScenarios).&lt;br /&gt;
&lt;br /&gt;
===Don&#039;t use double quotes, use single quotes instead===&lt;br /&gt;
Do not use double quotes (&amp;quot;) for surrounding strings:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &amp;quot;&amp;quot;Congratulations! Joomla! is now installed.&amp;quot;&amp;quot;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If you use single quotes instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Congratulations! Joomla! is now installed.&#039;, 30);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will get the right expected result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Congratulations! Joomla! is now installed.&#039;,&amp;quot; 30&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The reason of not being able to use double quotes is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;br /&gt;
&lt;br /&gt;
===Do not leave spaces between parameters in Cepts===&lt;br /&gt;
See the two lines:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Wrong&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;, 10, &#039;h3&#039;);&lt;br /&gt;
// Good&lt;br /&gt;
$I-&amp;gt;waitForText(&#039;Main Configuration&#039;,10,&#039;h3&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do, when you [[Testing_Joomla_Extensions_with_Codeception#Generating_txt.2Fhtml_scenarios|generate the scenarios]] you will get this bad result:&lt;br /&gt;
&lt;br /&gt;
 I wait for text &#039;Main Configuration&#039;,&amp;quot; 10&amp;quot;,&amp;quot; &#039;h3&#039;&lt;br /&gt;
&lt;br /&gt;
The reason that you are asked to not add spaces between parameters is due to a bug in Codeception humanize funtions, see issue: https://github.com/Codeception/Codeception/issues/1847&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135271</id>
		<title>Why Migrate/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135271"/>
		<updated>2014-11-25T14:57:55Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
Kannst Du Dich nicht entscheiden, ob Du migrieren solltest, oder nicht? Letztendlich läuft doch alles. Warum jetzt etwas daran rütteln? Irgendwoher hast Du auf jeden Fall von der Notwendigkeit einer Migration zu einer neueren Version gehört und bist so hier gelandet. Du bist her an der richtigen Adresse. Hier die Gründe, warum Du den Sprung jetzt wagen sollest!&lt;br /&gt;
 &lt;br /&gt;
==Warum sollte ich Migrieren?==&lt;br /&gt;
&lt;br /&gt;
Eine Joomla! Migration is eine gute Gelegenheit:&lt;br /&gt;
&lt;br /&gt;
* Die Website-Ziele und deren Zweck zu überdenken&lt;br /&gt;
* Mit „tollen“ neuen Ideen aufzuräumen, die nie umgesetzt wurden&lt;br /&gt;
alle externen Komponenten aufzulisten und die zu deinstallieren, die man nicht braucht&lt;br /&gt;
* neue Funktionalitäten auf der Website zu implementieren&lt;br /&gt;
* um das Design und die Menüführung zu überarbeiten&lt;br /&gt;
* die Barrierefreiheit für Besuchern mit Wahrnehmungsbehinderungen zu verbessern&lt;br /&gt;
* die Seite „mobilfreundlich“ zu machen, so das diese auch mit Smartphones und Tablets gut navigiert werden kann&lt;br /&gt;
* die Suchmaschinenoptimierung zu verbessern&lt;br /&gt;
* die Funktionalität einiger Dritt-Hersteller Komponenten durch die neuen Kernfunktionen zu ersetzen&lt;br /&gt;
* die Sicherheit seines Systems zu erhöhen, weil man überall die neueste Software einsetzt&lt;br /&gt;
&lt;br /&gt;
===Neue Funktionen und Verbesserung der Bedienerfreundlichkeit===&lt;br /&gt;
In einem neuen Lebenszyklus von Joomla! werden typischerweise auch neue Funktionen etabliert und die Benutzung ist vereinfacht worden. Manchmal kann man sich so extra Komponenten von Dritt-Herstellern sparen und auf Joomla! eigene Funktionen zurückgreifen. Lies mehr darüber in Joomla! 3 neue Funktionen.&lt;br /&gt;
&lt;br /&gt;
Technologie Weiterentwicklung &lt;br /&gt;
Es wurden weitreichende Veränderungen vorgenommen! In Haupt-Veröffentlichungen von Joomla! wurden weitreichende Veränderungen an der Struktur vorgenommen, so das eine „Migration“ nötig wird, da es mit einem einfachen Update nicht getan ist. Die allgemeine Weiterentwicklung betrifft auch die MySQL und PHP Versionen, auf welchen die Systeme laufen sollen. Dieser technische Fortschritt zwingt alle Content Management System (CMS) sich auch zu anzupassen.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
When a CMS changes its structure, a migration is required. The old version is no longer supported. This creates potential problems with security as security patches are discontinued and older versions of Joomla are not maintained. &lt;br /&gt;
&lt;br /&gt;
Many hosts don’t want older software scripts (Joomla is a script - all third-party extensions are scripts) running on their servers because security is compromised as software ages. They have to update their servers to remain secure. More and more older versions of Joomla cease functioning because of server upgrades on the part of the host.&lt;br /&gt;
&lt;br /&gt;
== Migration is like moving to a new house or a remodel ==&lt;br /&gt;
 &lt;br /&gt;
You can think of migration like moving from one home to a new home. You filter through your belongings and furniture and pack the important pieces to take with you. You discard lingering trash or eliminate items you no longer need. Once you get into your new home, you may find you need to acquire some new pieces of furniture or fixtures to make your new home operate smoothly.&lt;br /&gt;
 &lt;br /&gt;
Same with migration. You are deciding what to take with you and what to get rid of on your site. What stays? What goes?&lt;br /&gt;
 &lt;br /&gt;
When you move to a new house, you may have the skills and expertise to move the entire household yourself or you may need to get some help moving (not everyone can move a piano). You may only need your own two hands and a few boxes. Alternatively, you may need a moving service with a gigantic truck and a lot of helpers. Same is true with migrating from one life cycle of Joomla to another.&lt;br /&gt;
&lt;br /&gt;
Take the Self Assessment to determine if you can/should perform the migration yourself or if maybe you should get some help. If you have the skills to migrate the site yourself, continue to the Planning phase of the migration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Migration_Step_by_Step_Self_Assessment|Self Assessment|class=expand success}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Planning_for_Migration|Migration Planning|class=expand}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Migration]]&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/5/de&amp;diff=135270</id>
		<title>Translations:Why Migrate/5/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/5/de&amp;diff=135270"/>
		<updated>2014-11-25T14:57:55Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Neue Funktionen und Verbesserung der Bedienerfreundlichkeit===&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135269</id>
		<title>Why Migrate/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135269"/>
		<updated>2014-11-25T14:57:39Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
Kannst Du Dich nicht entscheiden, ob Du migrieren solltest, oder nicht? Letztendlich läuft doch alles. Warum jetzt etwas daran rütteln? Irgendwoher hast Du auf jeden Fall von der Notwendigkeit einer Migration zu einer neueren Version gehört und bist so hier gelandet. Du bist her an der richtigen Adresse. Hier die Gründe, warum Du den Sprung jetzt wagen sollest!&lt;br /&gt;
 &lt;br /&gt;
==Warum sollte ich Migrieren?==&lt;br /&gt;
&lt;br /&gt;
Eine Joomla! Migration is eine gute Gelegenheit:&lt;br /&gt;
&lt;br /&gt;
* Die Website-Ziele und deren Zweck zu überdenken&lt;br /&gt;
* Mit „tollen“ neuen Ideen aufzuräumen, die nie umgesetzt wurden&lt;br /&gt;
alle externen Komponenten aufzulisten und die zu deinstallieren, die man nicht braucht&lt;br /&gt;
* neue Funktionalitäten auf der Website zu implementieren&lt;br /&gt;
* um das Design und die Menüführung zu überarbeiten&lt;br /&gt;
* die Barrierefreiheit für Besuchern mit Wahrnehmungsbehinderungen zu verbessern&lt;br /&gt;
* die Seite „mobilfreundlich“ zu machen, so das diese auch mit Smartphones und Tablets gut navigiert werden kann&lt;br /&gt;
* die Suchmaschinenoptimierung zu verbessern&lt;br /&gt;
* die Funktionalität einiger Dritt-Hersteller Komponenten durch die neuen Kernfunktionen zu ersetzen&lt;br /&gt;
* die Sicherheit seines Systems zu erhöhen, weil man überall die neueste Software einsetzt&lt;br /&gt;
&lt;br /&gt;
Neue Funktionen und Verbesserung der Bedienerfreundlichkeit&lt;br /&gt;
In einem neuen Lebenszyklus von Joomla! werden typischerweise auch neue Funktionen etabliert und die Benutzung ist vereinfacht worden. Manchmal kann man sich so extra Komponenten von Dritt-Herstellern sparen und auf Joomla! eigene Funktionen zurückgreifen. Lies mehr darüber in Joomla! 3 neue Funktionen.&lt;br /&gt;
&lt;br /&gt;
Technologie Weiterentwicklung &lt;br /&gt;
Es wurden weitreichende Veränderungen vorgenommen! In Haupt-Veröffentlichungen von Joomla! wurden weitreichende Veränderungen an der Struktur vorgenommen, so das eine „Migration“ nötig wird, da es mit einem einfachen Update nicht getan ist. Die allgemeine Weiterentwicklung betrifft auch die MySQL und PHP Versionen, auf welchen die Systeme laufen sollen. Dieser technische Fortschritt zwingt alle Content Management System (CMS) sich auch zu anzupassen.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
When a CMS changes its structure, a migration is required. The old version is no longer supported. This creates potential problems with security as security patches are discontinued and older versions of Joomla are not maintained. &lt;br /&gt;
&lt;br /&gt;
Many hosts don’t want older software scripts (Joomla is a script - all third-party extensions are scripts) running on their servers because security is compromised as software ages. They have to update their servers to remain secure. More and more older versions of Joomla cease functioning because of server upgrades on the part of the host.&lt;br /&gt;
&lt;br /&gt;
== Migration is like moving to a new house or a remodel ==&lt;br /&gt;
 &lt;br /&gt;
You can think of migration like moving from one home to a new home. You filter through your belongings and furniture and pack the important pieces to take with you. You discard lingering trash or eliminate items you no longer need. Once you get into your new home, you may find you need to acquire some new pieces of furniture or fixtures to make your new home operate smoothly.&lt;br /&gt;
 &lt;br /&gt;
Same with migration. You are deciding what to take with you and what to get rid of on your site. What stays? What goes?&lt;br /&gt;
 &lt;br /&gt;
When you move to a new house, you may have the skills and expertise to move the entire household yourself or you may need to get some help moving (not everyone can move a piano). You may only need your own two hands and a few boxes. Alternatively, you may need a moving service with a gigantic truck and a lot of helpers. Same is true with migrating from one life cycle of Joomla to another.&lt;br /&gt;
&lt;br /&gt;
Take the Self Assessment to determine if you can/should perform the migration yourself or if maybe you should get some help. If you have the skills to migrate the site yourself, continue to the Planning phase of the migration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Migration_Step_by_Step_Self_Assessment|Self Assessment|class=expand success}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Planning_for_Migration|Migration Planning|class=expand}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Migration]]&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/2/de&amp;diff=135268</id>
		<title>Translations:Why Migrate/2/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/2/de&amp;diff=135268"/>
		<updated>2014-11-25T14:57:39Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Warum sollte ich Migrieren?==&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135265</id>
		<title>Why Migrate/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135265"/>
		<updated>2014-11-25T14:56:00Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Created page with &amp;quot;Es wurden weitreichende Veränderungen vorgenommen! In Haupt-Veröffentlichungen von Joomla! wurden weitreichende Veränderungen an der Struktur vorgenommen, so das eine „Mi...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
Kannst Du Dich nicht entscheiden, ob Du migrieren solltest, oder nicht? Letztendlich läuft doch alles. Warum jetzt etwas daran rütteln? Irgendwoher hast Du auf jeden Fall von der Notwendigkeit einer Migration zu einer neueren Version gehört und bist so hier gelandet. Du bist her an der richtigen Adresse. Hier die Gründe, warum Du den Sprung jetzt wagen sollest!&lt;br /&gt;
 &lt;br /&gt;
Warum sollte ich Migrieren?&lt;br /&gt;
&lt;br /&gt;
Eine Joomla! Migration is eine gute Gelegenheit:&lt;br /&gt;
&lt;br /&gt;
* Die Website-Ziele und deren Zweck zu überdenken&lt;br /&gt;
* Mit „tollen“ neuen Ideen aufzuräumen, die nie umgesetzt wurden&lt;br /&gt;
alle externen Komponenten aufzulisten und die zu deinstallieren, die man nicht braucht&lt;br /&gt;
* neue Funktionalitäten auf der Website zu implementieren&lt;br /&gt;
* um das Design und die Menüführung zu überarbeiten&lt;br /&gt;
* die Barrierefreiheit für Besuchern mit Wahrnehmungsbehinderungen zu verbessern&lt;br /&gt;
* die Seite „mobilfreundlich“ zu machen, so das diese auch mit Smartphones und Tablets gut navigiert werden kann&lt;br /&gt;
* die Suchmaschinenoptimierung zu verbessern&lt;br /&gt;
* die Funktionalität einiger Dritt-Hersteller Komponenten durch die neuen Kernfunktionen zu ersetzen&lt;br /&gt;
* die Sicherheit seines Systems zu erhöhen, weil man überall die neueste Software einsetzt&lt;br /&gt;
&lt;br /&gt;
Neue Funktionen und Verbesserung der Bedienerfreundlichkeit&lt;br /&gt;
In einem neuen Lebenszyklus von Joomla! werden typischerweise auch neue Funktionen etabliert und die Benutzung ist vereinfacht worden. Manchmal kann man sich so extra Komponenten von Dritt-Herstellern sparen und auf Joomla! eigene Funktionen zurückgreifen. Lies mehr darüber in Joomla! 3 neue Funktionen.&lt;br /&gt;
&lt;br /&gt;
Technologie Weiterentwicklung &lt;br /&gt;
Es wurden weitreichende Veränderungen vorgenommen! In Haupt-Veröffentlichungen von Joomla! wurden weitreichende Veränderungen an der Struktur vorgenommen, so das eine „Migration“ nötig wird, da es mit einem einfachen Update nicht getan ist. Die allgemeine Weiterentwicklung betrifft auch die MySQL und PHP Versionen, auf welchen die Systeme laufen sollen. Dieser technische Fortschritt zwingt alle Content Management System (CMS) sich auch zu anzupassen.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
When a CMS changes its structure, a migration is required. The old version is no longer supported. This creates potential problems with security as security patches are discontinued and older versions of Joomla are not maintained. &lt;br /&gt;
&lt;br /&gt;
Many hosts don’t want older software scripts (Joomla is a script - all third-party extensions are scripts) running on their servers because security is compromised as software ages. They have to update their servers to remain secure. More and more older versions of Joomla cease functioning because of server upgrades on the part of the host.&lt;br /&gt;
&lt;br /&gt;
== Migration is like moving to a new house or a remodel ==&lt;br /&gt;
 &lt;br /&gt;
You can think of migration like moving from one home to a new home. You filter through your belongings and furniture and pack the important pieces to take with you. You discard lingering trash or eliminate items you no longer need. Once you get into your new home, you may find you need to acquire some new pieces of furniture or fixtures to make your new home operate smoothly.&lt;br /&gt;
 &lt;br /&gt;
Same with migration. You are deciding what to take with you and what to get rid of on your site. What stays? What goes?&lt;br /&gt;
 &lt;br /&gt;
When you move to a new house, you may have the skills and expertise to move the entire household yourself or you may need to get some help moving (not everyone can move a piano). You may only need your own two hands and a few boxes. Alternatively, you may need a moving service with a gigantic truck and a lot of helpers. Same is true with migrating from one life cycle of Joomla to another.&lt;br /&gt;
&lt;br /&gt;
Take the Self Assessment to determine if you can/should perform the migration yourself or if maybe you should get some help. If you have the skills to migrate the site yourself, continue to the Planning phase of the migration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Migration_Step_by_Step_Self_Assessment|Self Assessment|class=expand success}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Planning_for_Migration|Migration Planning|class=expand}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Migration]]&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/8/de&amp;diff=135264</id>
		<title>Translations:Why Migrate/8/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/8/de&amp;diff=135264"/>
		<updated>2014-11-25T14:56:00Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Created page with &amp;quot;Es wurden weitreichende Veränderungen vorgenommen! In Haupt-Veröffentlichungen von Joomla! wurden weitreichende Veränderungen an der Struktur vorgenommen, so das eine „Mi...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Es wurden weitreichende Veränderungen vorgenommen! In Haupt-Veröffentlichungen von Joomla! wurden weitreichende Veränderungen an der Struktur vorgenommen, so das eine „Migration“ nötig wird, da es mit einem einfachen Update nicht getan ist. Die allgemeine Weiterentwicklung betrifft auch die MySQL und PHP Versionen, auf welchen die Systeme laufen sollen. Dieser technische Fortschritt zwingt alle Content Management System (CMS) sich auch zu anzupassen.&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135263</id>
		<title>Why Migrate/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135263"/>
		<updated>2014-11-25T14:55:52Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Created page with &amp;quot;Technologie Weiterentwicklung&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
Kannst Du Dich nicht entscheiden, ob Du migrieren solltest, oder nicht? Letztendlich läuft doch alles. Warum jetzt etwas daran rütteln? Irgendwoher hast Du auf jeden Fall von der Notwendigkeit einer Migration zu einer neueren Version gehört und bist so hier gelandet. Du bist her an der richtigen Adresse. Hier die Gründe, warum Du den Sprung jetzt wagen sollest!&lt;br /&gt;
 &lt;br /&gt;
Warum sollte ich Migrieren?&lt;br /&gt;
&lt;br /&gt;
Eine Joomla! Migration is eine gute Gelegenheit:&lt;br /&gt;
&lt;br /&gt;
* Die Website-Ziele und deren Zweck zu überdenken&lt;br /&gt;
* Mit „tollen“ neuen Ideen aufzuräumen, die nie umgesetzt wurden&lt;br /&gt;
alle externen Komponenten aufzulisten und die zu deinstallieren, die man nicht braucht&lt;br /&gt;
* neue Funktionalitäten auf der Website zu implementieren&lt;br /&gt;
* um das Design und die Menüführung zu überarbeiten&lt;br /&gt;
* die Barrierefreiheit für Besuchern mit Wahrnehmungsbehinderungen zu verbessern&lt;br /&gt;
* die Seite „mobilfreundlich“ zu machen, so das diese auch mit Smartphones und Tablets gut navigiert werden kann&lt;br /&gt;
* die Suchmaschinenoptimierung zu verbessern&lt;br /&gt;
* die Funktionalität einiger Dritt-Hersteller Komponenten durch die neuen Kernfunktionen zu ersetzen&lt;br /&gt;
* die Sicherheit seines Systems zu erhöhen, weil man überall die neueste Software einsetzt&lt;br /&gt;
&lt;br /&gt;
Neue Funktionen und Verbesserung der Bedienerfreundlichkeit&lt;br /&gt;
In einem neuen Lebenszyklus von Joomla! werden typischerweise auch neue Funktionen etabliert und die Benutzung ist vereinfacht worden. Manchmal kann man sich so extra Komponenten von Dritt-Herstellern sparen und auf Joomla! eigene Funktionen zurückgreifen. Lies mehr darüber in Joomla! 3 neue Funktionen.&lt;br /&gt;
&lt;br /&gt;
Technologie Weiterentwicklung &lt;br /&gt;
Significant changes have taken place! Major releases of Joomla have restructured the data and require a “migration” as opposed to an update or upgrade. Technology changes have also been made within the versions of PHP and MySQL running on your hosts server. These changes force all content management system (CMS) technology to change with it.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
When a CMS changes its structure, a migration is required. The old version is no longer supported. This creates potential problems with security as security patches are discontinued and older versions of Joomla are not maintained. &lt;br /&gt;
&lt;br /&gt;
Many hosts don’t want older software scripts (Joomla is a script - all third-party extensions are scripts) running on their servers because security is compromised as software ages. They have to update their servers to remain secure. More and more older versions of Joomla cease functioning because of server upgrades on the part of the host.&lt;br /&gt;
&lt;br /&gt;
== Migration is like moving to a new house or a remodel ==&lt;br /&gt;
 &lt;br /&gt;
You can think of migration like moving from one home to a new home. You filter through your belongings and furniture and pack the important pieces to take with you. You discard lingering trash or eliminate items you no longer need. Once you get into your new home, you may find you need to acquire some new pieces of furniture or fixtures to make your new home operate smoothly.&lt;br /&gt;
 &lt;br /&gt;
Same with migration. You are deciding what to take with you and what to get rid of on your site. What stays? What goes?&lt;br /&gt;
 &lt;br /&gt;
When you move to a new house, you may have the skills and expertise to move the entire household yourself or you may need to get some help moving (not everyone can move a piano). You may only need your own two hands and a few boxes. Alternatively, you may need a moving service with a gigantic truck and a lot of helpers. Same is true with migrating from one life cycle of Joomla to another.&lt;br /&gt;
&lt;br /&gt;
Take the Self Assessment to determine if you can/should perform the migration yourself or if maybe you should get some help. If you have the skills to migrate the site yourself, continue to the Planning phase of the migration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Migration_Step_by_Step_Self_Assessment|Self Assessment|class=expand success}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Planning_for_Migration|Migration Planning|class=expand}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Migration]]&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/7/de&amp;diff=135262</id>
		<title>Translations:Why Migrate/7/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/7/de&amp;diff=135262"/>
		<updated>2014-11-25T14:55:52Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Created page with &amp;quot;Technologie Weiterentwicklung&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Technologie Weiterentwicklung&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135261</id>
		<title>Why Migrate/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135261"/>
		<updated>2014-11-25T14:55:47Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Created page with &amp;quot;In einem neuen Lebenszyklus von Joomla! werden typischerweise auch neue Funktionen etabliert und die Benutzung ist vereinfacht worden. Manchmal kann man sich so extra Komponen...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
Kannst Du Dich nicht entscheiden, ob Du migrieren solltest, oder nicht? Letztendlich läuft doch alles. Warum jetzt etwas daran rütteln? Irgendwoher hast Du auf jeden Fall von der Notwendigkeit einer Migration zu einer neueren Version gehört und bist so hier gelandet. Du bist her an der richtigen Adresse. Hier die Gründe, warum Du den Sprung jetzt wagen sollest!&lt;br /&gt;
 &lt;br /&gt;
Warum sollte ich Migrieren?&lt;br /&gt;
&lt;br /&gt;
Eine Joomla! Migration is eine gute Gelegenheit:&lt;br /&gt;
&lt;br /&gt;
* Die Website-Ziele und deren Zweck zu überdenken&lt;br /&gt;
* Mit „tollen“ neuen Ideen aufzuräumen, die nie umgesetzt wurden&lt;br /&gt;
alle externen Komponenten aufzulisten und die zu deinstallieren, die man nicht braucht&lt;br /&gt;
* neue Funktionalitäten auf der Website zu implementieren&lt;br /&gt;
* um das Design und die Menüführung zu überarbeiten&lt;br /&gt;
* die Barrierefreiheit für Besuchern mit Wahrnehmungsbehinderungen zu verbessern&lt;br /&gt;
* die Seite „mobilfreundlich“ zu machen, so das diese auch mit Smartphones und Tablets gut navigiert werden kann&lt;br /&gt;
* die Suchmaschinenoptimierung zu verbessern&lt;br /&gt;
* die Funktionalität einiger Dritt-Hersteller Komponenten durch die neuen Kernfunktionen zu ersetzen&lt;br /&gt;
* die Sicherheit seines Systems zu erhöhen, weil man überall die neueste Software einsetzt&lt;br /&gt;
&lt;br /&gt;
Neue Funktionen und Verbesserung der Bedienerfreundlichkeit&lt;br /&gt;
In einem neuen Lebenszyklus von Joomla! werden typischerweise auch neue Funktionen etabliert und die Benutzung ist vereinfacht worden. Manchmal kann man sich so extra Komponenten von Dritt-Herstellern sparen und auf Joomla! eigene Funktionen zurückgreifen. Lies mehr darüber in Joomla! 3 neue Funktionen.&lt;br /&gt;
&lt;br /&gt;
=== Technology Changes === &lt;br /&gt;
Significant changes have taken place! Major releases of Joomla have restructured the data and require a “migration” as opposed to an update or upgrade. Technology changes have also been made within the versions of PHP and MySQL running on your hosts server. These changes force all content management system (CMS) technology to change with it.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
When a CMS changes its structure, a migration is required. The old version is no longer supported. This creates potential problems with security as security patches are discontinued and older versions of Joomla are not maintained. &lt;br /&gt;
&lt;br /&gt;
Many hosts don’t want older software scripts (Joomla is a script - all third-party extensions are scripts) running on their servers because security is compromised as software ages. They have to update their servers to remain secure. More and more older versions of Joomla cease functioning because of server upgrades on the part of the host.&lt;br /&gt;
&lt;br /&gt;
== Migration is like moving to a new house or a remodel ==&lt;br /&gt;
 &lt;br /&gt;
You can think of migration like moving from one home to a new home. You filter through your belongings and furniture and pack the important pieces to take with you. You discard lingering trash or eliminate items you no longer need. Once you get into your new home, you may find you need to acquire some new pieces of furniture or fixtures to make your new home operate smoothly.&lt;br /&gt;
 &lt;br /&gt;
Same with migration. You are deciding what to take with you and what to get rid of on your site. What stays? What goes?&lt;br /&gt;
 &lt;br /&gt;
When you move to a new house, you may have the skills and expertise to move the entire household yourself or you may need to get some help moving (not everyone can move a piano). You may only need your own two hands and a few boxes. Alternatively, you may need a moving service with a gigantic truck and a lot of helpers. Same is true with migrating from one life cycle of Joomla to another.&lt;br /&gt;
&lt;br /&gt;
Take the Self Assessment to determine if you can/should perform the migration yourself or if maybe you should get some help. If you have the skills to migrate the site yourself, continue to the Planning phase of the migration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Migration_Step_by_Step_Self_Assessment|Self Assessment|class=expand success}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Planning_for_Migration|Migration Planning|class=expand}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Migration]]&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/6/de&amp;diff=135260</id>
		<title>Translations:Why Migrate/6/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/6/de&amp;diff=135260"/>
		<updated>2014-11-25T14:55:47Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Created page with &amp;quot;In einem neuen Lebenszyklus von Joomla! werden typischerweise auch neue Funktionen etabliert und die Benutzung ist vereinfacht worden. Manchmal kann man sich so extra Komponen...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In einem neuen Lebenszyklus von Joomla! werden typischerweise auch neue Funktionen etabliert und die Benutzung ist vereinfacht worden. Manchmal kann man sich so extra Komponenten von Dritt-Herstellern sparen und auf Joomla! eigene Funktionen zurückgreifen. Lies mehr darüber in Joomla! 3 neue Funktionen.&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135259</id>
		<title>Why Migrate/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135259"/>
		<updated>2014-11-25T14:55:35Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Created page with &amp;quot;Neue Funktionen und Verbesserung der Bedienerfreundlichkeit&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
Kannst Du Dich nicht entscheiden, ob Du migrieren solltest, oder nicht? Letztendlich läuft doch alles. Warum jetzt etwas daran rütteln? Irgendwoher hast Du auf jeden Fall von der Notwendigkeit einer Migration zu einer neueren Version gehört und bist so hier gelandet. Du bist her an der richtigen Adresse. Hier die Gründe, warum Du den Sprung jetzt wagen sollest!&lt;br /&gt;
 &lt;br /&gt;
Warum sollte ich Migrieren?&lt;br /&gt;
&lt;br /&gt;
Eine Joomla! Migration is eine gute Gelegenheit:&lt;br /&gt;
&lt;br /&gt;
* Die Website-Ziele und deren Zweck zu überdenken&lt;br /&gt;
* Mit „tollen“ neuen Ideen aufzuräumen, die nie umgesetzt wurden&lt;br /&gt;
alle externen Komponenten aufzulisten und die zu deinstallieren, die man nicht braucht&lt;br /&gt;
* neue Funktionalitäten auf der Website zu implementieren&lt;br /&gt;
* um das Design und die Menüführung zu überarbeiten&lt;br /&gt;
* die Barrierefreiheit für Besuchern mit Wahrnehmungsbehinderungen zu verbessern&lt;br /&gt;
* die Seite „mobilfreundlich“ zu machen, so das diese auch mit Smartphones und Tablets gut navigiert werden kann&lt;br /&gt;
* die Suchmaschinenoptimierung zu verbessern&lt;br /&gt;
* die Funktionalität einiger Dritt-Hersteller Komponenten durch die neuen Kernfunktionen zu ersetzen&lt;br /&gt;
* die Sicherheit seines Systems zu erhöhen, weil man überall die neueste Software einsetzt&lt;br /&gt;
&lt;br /&gt;
Neue Funktionen und Verbesserung der Bedienerfreundlichkeit&lt;br /&gt;
Typically new life cycles of Joomla include new features and usability enhancements. These sometimes can eliminate the need of a third-party extension and enable the increased use of Joomla core components. Read more about features [http://www.joomla.org/3/en Joomla 3 features].&lt;br /&gt;
&lt;br /&gt;
=== Technology Changes === &lt;br /&gt;
Significant changes have taken place! Major releases of Joomla have restructured the data and require a “migration” as opposed to an update or upgrade. Technology changes have also been made within the versions of PHP and MySQL running on your hosts server. These changes force all content management system (CMS) technology to change with it.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
When a CMS changes its structure, a migration is required. The old version is no longer supported. This creates potential problems with security as security patches are discontinued and older versions of Joomla are not maintained. &lt;br /&gt;
&lt;br /&gt;
Many hosts don’t want older software scripts (Joomla is a script - all third-party extensions are scripts) running on their servers because security is compromised as software ages. They have to update their servers to remain secure. More and more older versions of Joomla cease functioning because of server upgrades on the part of the host.&lt;br /&gt;
&lt;br /&gt;
== Migration is like moving to a new house or a remodel ==&lt;br /&gt;
 &lt;br /&gt;
You can think of migration like moving from one home to a new home. You filter through your belongings and furniture and pack the important pieces to take with you. You discard lingering trash or eliminate items you no longer need. Once you get into your new home, you may find you need to acquire some new pieces of furniture or fixtures to make your new home operate smoothly.&lt;br /&gt;
 &lt;br /&gt;
Same with migration. You are deciding what to take with you and what to get rid of on your site. What stays? What goes?&lt;br /&gt;
 &lt;br /&gt;
When you move to a new house, you may have the skills and expertise to move the entire household yourself or you may need to get some help moving (not everyone can move a piano). You may only need your own two hands and a few boxes. Alternatively, you may need a moving service with a gigantic truck and a lot of helpers. Same is true with migrating from one life cycle of Joomla to another.&lt;br /&gt;
&lt;br /&gt;
Take the Self Assessment to determine if you can/should perform the migration yourself or if maybe you should get some help. If you have the skills to migrate the site yourself, continue to the Planning phase of the migration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Migration_Step_by_Step_Self_Assessment|Self Assessment|class=expand success}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Planning_for_Migration|Migration Planning|class=expand}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Migration]]&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/5/de&amp;diff=135258</id>
		<title>Translations:Why Migrate/5/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/5/de&amp;diff=135258"/>
		<updated>2014-11-25T14:55:35Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Created page with &amp;quot;Neue Funktionen und Verbesserung der Bedienerfreundlichkeit&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Neue Funktionen und Verbesserung der Bedienerfreundlichkeit&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135257</id>
		<title>Why Migrate/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135257"/>
		<updated>2014-11-25T14:55:29Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Created page with &amp;quot;* Die Website-Ziele und deren Zweck zu überdenken * Mit „tollen“ neuen Ideen aufzuräumen, die nie umgesetzt wurden alle externen Komponenten aufzulisten und die zu deins...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
Kannst Du Dich nicht entscheiden, ob Du migrieren solltest, oder nicht? Letztendlich läuft doch alles. Warum jetzt etwas daran rütteln? Irgendwoher hast Du auf jeden Fall von der Notwendigkeit einer Migration zu einer neueren Version gehört und bist so hier gelandet. Du bist her an der richtigen Adresse. Hier die Gründe, warum Du den Sprung jetzt wagen sollest!&lt;br /&gt;
 &lt;br /&gt;
Warum sollte ich Migrieren?&lt;br /&gt;
&lt;br /&gt;
Eine Joomla! Migration is eine gute Gelegenheit:&lt;br /&gt;
&lt;br /&gt;
* Die Website-Ziele und deren Zweck zu überdenken&lt;br /&gt;
* Mit „tollen“ neuen Ideen aufzuräumen, die nie umgesetzt wurden&lt;br /&gt;
alle externen Komponenten aufzulisten und die zu deinstallieren, die man nicht braucht&lt;br /&gt;
* neue Funktionalitäten auf der Website zu implementieren&lt;br /&gt;
* um das Design und die Menüführung zu überarbeiten&lt;br /&gt;
* die Barrierefreiheit für Besuchern mit Wahrnehmungsbehinderungen zu verbessern&lt;br /&gt;
* die Seite „mobilfreundlich“ zu machen, so das diese auch mit Smartphones und Tablets gut navigiert werden kann&lt;br /&gt;
* die Suchmaschinenoptimierung zu verbessern&lt;br /&gt;
* die Funktionalität einiger Dritt-Hersteller Komponenten durch die neuen Kernfunktionen zu ersetzen&lt;br /&gt;
* die Sicherheit seines Systems zu erhöhen, weil man überall die neueste Software einsetzt&lt;br /&gt;
&lt;br /&gt;
=== Features and usability enhancements ===&lt;br /&gt;
Typically new life cycles of Joomla include new features and usability enhancements. These sometimes can eliminate the need of a third-party extension and enable the increased use of Joomla core components. Read more about features [http://www.joomla.org/3/en Joomla 3 features].&lt;br /&gt;
&lt;br /&gt;
=== Technology Changes === &lt;br /&gt;
Significant changes have taken place! Major releases of Joomla have restructured the data and require a “migration” as opposed to an update or upgrade. Technology changes have also been made within the versions of PHP and MySQL running on your hosts server. These changes force all content management system (CMS) technology to change with it.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
When a CMS changes its structure, a migration is required. The old version is no longer supported. This creates potential problems with security as security patches are discontinued and older versions of Joomla are not maintained. &lt;br /&gt;
&lt;br /&gt;
Many hosts don’t want older software scripts (Joomla is a script - all third-party extensions are scripts) running on their servers because security is compromised as software ages. They have to update their servers to remain secure. More and more older versions of Joomla cease functioning because of server upgrades on the part of the host.&lt;br /&gt;
&lt;br /&gt;
== Migration is like moving to a new house or a remodel ==&lt;br /&gt;
 &lt;br /&gt;
You can think of migration like moving from one home to a new home. You filter through your belongings and furniture and pack the important pieces to take with you. You discard lingering trash or eliminate items you no longer need. Once you get into your new home, you may find you need to acquire some new pieces of furniture or fixtures to make your new home operate smoothly.&lt;br /&gt;
 &lt;br /&gt;
Same with migration. You are deciding what to take with you and what to get rid of on your site. What stays? What goes?&lt;br /&gt;
 &lt;br /&gt;
When you move to a new house, you may have the skills and expertise to move the entire household yourself or you may need to get some help moving (not everyone can move a piano). You may only need your own two hands and a few boxes. Alternatively, you may need a moving service with a gigantic truck and a lot of helpers. Same is true with migrating from one life cycle of Joomla to another.&lt;br /&gt;
&lt;br /&gt;
Take the Self Assessment to determine if you can/should perform the migration yourself or if maybe you should get some help. If you have the skills to migrate the site yourself, continue to the Planning phase of the migration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Migration_Step_by_Step_Self_Assessment|Self Assessment|class=expand success}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Planning_for_Migration|Migration Planning|class=expand}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Migration]]&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/4/de&amp;diff=135256</id>
		<title>Translations:Why Migrate/4/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/4/de&amp;diff=135256"/>
		<updated>2014-11-25T14:55:29Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Created page with &amp;quot;* Die Website-Ziele und deren Zweck zu überdenken * Mit „tollen“ neuen Ideen aufzuräumen, die nie umgesetzt wurden alle externen Komponenten aufzulisten und die zu deins...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Die Website-Ziele und deren Zweck zu überdenken&lt;br /&gt;
* Mit „tollen“ neuen Ideen aufzuräumen, die nie umgesetzt wurden&lt;br /&gt;
alle externen Komponenten aufzulisten und die zu deinstallieren, die man nicht braucht&lt;br /&gt;
* neue Funktionalitäten auf der Website zu implementieren&lt;br /&gt;
* um das Design und die Menüführung zu überarbeiten&lt;br /&gt;
* die Barrierefreiheit für Besuchern mit Wahrnehmungsbehinderungen zu verbessern&lt;br /&gt;
* die Seite „mobilfreundlich“ zu machen, so das diese auch mit Smartphones und Tablets gut navigiert werden kann&lt;br /&gt;
* die Suchmaschinenoptimierung zu verbessern&lt;br /&gt;
* die Funktionalität einiger Dritt-Hersteller Komponenten durch die neuen Kernfunktionen zu ersetzen&lt;br /&gt;
* die Sicherheit seines Systems zu erhöhen, weil man überall die neueste Software einsetzt&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135254</id>
		<title>Why Migrate/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135254"/>
		<updated>2014-11-25T14:54:38Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Created page with &amp;quot;Eine Joomla! Migration is eine gute Gelegenheit:&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
Kannst Du Dich nicht entscheiden, ob Du migrieren solltest, oder nicht? Letztendlich läuft doch alles. Warum jetzt etwas daran rütteln? Irgendwoher hast Du auf jeden Fall von der Notwendigkeit einer Migration zu einer neueren Version gehört und bist so hier gelandet. Du bist her an der richtigen Adresse. Hier die Gründe, warum Du den Sprung jetzt wagen sollest!&lt;br /&gt;
 &lt;br /&gt;
Warum sollte ich Migrieren?&lt;br /&gt;
&lt;br /&gt;
Eine Joomla! Migration is eine gute Gelegenheit:&lt;br /&gt;
&lt;br /&gt;
* Revisit site goals and rethink its purpose&lt;br /&gt;
* Clean up “great ideas” that never saw the light of day&lt;br /&gt;
* Inventory third-party extensions that may have been installed but not used&lt;br /&gt;
* Simplify and clean up old articles, menus and other content&lt;br /&gt;
* Create new functionality on the site&lt;br /&gt;
* Change design and navigation&lt;br /&gt;
* Add accessibility to disabled visitors&lt;br /&gt;
* Make the site mobile-friendly&lt;br /&gt;
* Improve search engine optimization&lt;br /&gt;
* Utilize new features you may have been using third-party extensions for&lt;br /&gt;
* Insure your data against security breaches by having all the latest software&lt;br /&gt;
&lt;br /&gt;
=== Features and usability enhancements ===&lt;br /&gt;
Typically new life cycles of Joomla include new features and usability enhancements. These sometimes can eliminate the need of a third-party extension and enable the increased use of Joomla core components. Read more about features [http://www.joomla.org/3/en Joomla 3 features].&lt;br /&gt;
&lt;br /&gt;
=== Technology Changes === &lt;br /&gt;
Significant changes have taken place! Major releases of Joomla have restructured the data and require a “migration” as opposed to an update or upgrade. Technology changes have also been made within the versions of PHP and MySQL running on your hosts server. These changes force all content management system (CMS) technology to change with it.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
When a CMS changes its structure, a migration is required. The old version is no longer supported. This creates potential problems with security as security patches are discontinued and older versions of Joomla are not maintained. &lt;br /&gt;
&lt;br /&gt;
Many hosts don’t want older software scripts (Joomla is a script - all third-party extensions are scripts) running on their servers because security is compromised as software ages. They have to update their servers to remain secure. More and more older versions of Joomla cease functioning because of server upgrades on the part of the host.&lt;br /&gt;
&lt;br /&gt;
== Migration is like moving to a new house or a remodel ==&lt;br /&gt;
 &lt;br /&gt;
You can think of migration like moving from one home to a new home. You filter through your belongings and furniture and pack the important pieces to take with you. You discard lingering trash or eliminate items you no longer need. Once you get into your new home, you may find you need to acquire some new pieces of furniture or fixtures to make your new home operate smoothly.&lt;br /&gt;
 &lt;br /&gt;
Same with migration. You are deciding what to take with you and what to get rid of on your site. What stays? What goes?&lt;br /&gt;
 &lt;br /&gt;
When you move to a new house, you may have the skills and expertise to move the entire household yourself or you may need to get some help moving (not everyone can move a piano). You may only need your own two hands and a few boxes. Alternatively, you may need a moving service with a gigantic truck and a lot of helpers. Same is true with migrating from one life cycle of Joomla to another.&lt;br /&gt;
&lt;br /&gt;
Take the Self Assessment to determine if you can/should perform the migration yourself or if maybe you should get some help. If you have the skills to migrate the site yourself, continue to the Planning phase of the migration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Migration_Step_by_Step_Self_Assessment|Self Assessment|class=expand success}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Planning_for_Migration|Migration Planning|class=expand}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Migration]]&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/3/de&amp;diff=135253</id>
		<title>Translations:Why Migrate/3/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/3/de&amp;diff=135253"/>
		<updated>2014-11-25T14:54:37Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Created page with &amp;quot;Eine Joomla! Migration is eine gute Gelegenheit:&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Eine Joomla! Migration is eine gute Gelegenheit:&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135251</id>
		<title>Why Migrate/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135251"/>
		<updated>2014-11-25T14:54:27Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Created page with &amp;quot;Warum sollte ich Migrieren?&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
Kannst Du Dich nicht entscheiden, ob Du migrieren solltest, oder nicht? Letztendlich läuft doch alles. Warum jetzt etwas daran rütteln? Irgendwoher hast Du auf jeden Fall von der Notwendigkeit einer Migration zu einer neueren Version gehört und bist so hier gelandet. Du bist her an der richtigen Adresse. Hier die Gründe, warum Du den Sprung jetzt wagen sollest!&lt;br /&gt;
 &lt;br /&gt;
Warum sollte ich Migrieren?&lt;br /&gt;
&lt;br /&gt;
A Joomla! migration gives everyone a new opportunity to:&lt;br /&gt;
&lt;br /&gt;
* Revisit site goals and rethink its purpose&lt;br /&gt;
* Clean up “great ideas” that never saw the light of day&lt;br /&gt;
* Inventory third-party extensions that may have been installed but not used&lt;br /&gt;
* Simplify and clean up old articles, menus and other content&lt;br /&gt;
* Create new functionality on the site&lt;br /&gt;
* Change design and navigation&lt;br /&gt;
* Add accessibility to disabled visitors&lt;br /&gt;
* Make the site mobile-friendly&lt;br /&gt;
* Improve search engine optimization&lt;br /&gt;
* Utilize new features you may have been using third-party extensions for&lt;br /&gt;
* Insure your data against security breaches by having all the latest software&lt;br /&gt;
&lt;br /&gt;
=== Features and usability enhancements ===&lt;br /&gt;
Typically new life cycles of Joomla include new features and usability enhancements. These sometimes can eliminate the need of a third-party extension and enable the increased use of Joomla core components. Read more about features [http://www.joomla.org/3/en Joomla 3 features].&lt;br /&gt;
&lt;br /&gt;
=== Technology Changes === &lt;br /&gt;
Significant changes have taken place! Major releases of Joomla have restructured the data and require a “migration” as opposed to an update or upgrade. Technology changes have also been made within the versions of PHP and MySQL running on your hosts server. These changes force all content management system (CMS) technology to change with it.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
When a CMS changes its structure, a migration is required. The old version is no longer supported. This creates potential problems with security as security patches are discontinued and older versions of Joomla are not maintained. &lt;br /&gt;
&lt;br /&gt;
Many hosts don’t want older software scripts (Joomla is a script - all third-party extensions are scripts) running on their servers because security is compromised as software ages. They have to update their servers to remain secure. More and more older versions of Joomla cease functioning because of server upgrades on the part of the host.&lt;br /&gt;
&lt;br /&gt;
== Migration is like moving to a new house or a remodel ==&lt;br /&gt;
 &lt;br /&gt;
You can think of migration like moving from one home to a new home. You filter through your belongings and furniture and pack the important pieces to take with you. You discard lingering trash or eliminate items you no longer need. Once you get into your new home, you may find you need to acquire some new pieces of furniture or fixtures to make your new home operate smoothly.&lt;br /&gt;
 &lt;br /&gt;
Same with migration. You are deciding what to take with you and what to get rid of on your site. What stays? What goes?&lt;br /&gt;
 &lt;br /&gt;
When you move to a new house, you may have the skills and expertise to move the entire household yourself or you may need to get some help moving (not everyone can move a piano). You may only need your own two hands and a few boxes. Alternatively, you may need a moving service with a gigantic truck and a lot of helpers. Same is true with migrating from one life cycle of Joomla to another.&lt;br /&gt;
&lt;br /&gt;
Take the Self Assessment to determine if you can/should perform the migration yourself or if maybe you should get some help. If you have the skills to migrate the site yourself, continue to the Planning phase of the migration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Migration_Step_by_Step_Self_Assessment|Self Assessment|class=expand success}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Planning_for_Migration|Migration Planning|class=expand}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Migration]]&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/2/de&amp;diff=135250</id>
		<title>Translations:Why Migrate/2/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/2/de&amp;diff=135250"/>
		<updated>2014-11-25T14:54:27Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Created page with &amp;quot;Warum sollte ich Migrieren?&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Warum sollte ich Migrieren?&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135249</id>
		<title>Why Migrate/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135249"/>
		<updated>2014-11-25T14:54:15Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Created page with &amp;quot;Kannst Du Dich nicht entscheiden, ob Du migrieren solltest, oder nicht? Letztendlich läuft doch alles. Warum jetzt etwas daran rütteln? Irgendwoher hast Du auf jeden Fall vo...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
Kannst Du Dich nicht entscheiden, ob Du migrieren solltest, oder nicht? Letztendlich läuft doch alles. Warum jetzt etwas daran rütteln? Irgendwoher hast Du auf jeden Fall von der Notwendigkeit einer Migration zu einer neueren Version gehört und bist so hier gelandet. Du bist her an der richtigen Adresse. Hier die Gründe, warum Du den Sprung jetzt wagen sollest!&lt;br /&gt;
 &lt;br /&gt;
==Why should I migrate?==&lt;br /&gt;
&lt;br /&gt;
A Joomla! migration gives everyone a new opportunity to:&lt;br /&gt;
&lt;br /&gt;
* Revisit site goals and rethink its purpose&lt;br /&gt;
* Clean up “great ideas” that never saw the light of day&lt;br /&gt;
* Inventory third-party extensions that may have been installed but not used&lt;br /&gt;
* Simplify and clean up old articles, menus and other content&lt;br /&gt;
* Create new functionality on the site&lt;br /&gt;
* Change design and navigation&lt;br /&gt;
* Add accessibility to disabled visitors&lt;br /&gt;
* Make the site mobile-friendly&lt;br /&gt;
* Improve search engine optimization&lt;br /&gt;
* Utilize new features you may have been using third-party extensions for&lt;br /&gt;
* Insure your data against security breaches by having all the latest software&lt;br /&gt;
&lt;br /&gt;
=== Features and usability enhancements ===&lt;br /&gt;
Typically new life cycles of Joomla include new features and usability enhancements. These sometimes can eliminate the need of a third-party extension and enable the increased use of Joomla core components. Read more about features [http://www.joomla.org/3/en Joomla 3 features].&lt;br /&gt;
&lt;br /&gt;
=== Technology Changes === &lt;br /&gt;
Significant changes have taken place! Major releases of Joomla have restructured the data and require a “migration” as opposed to an update or upgrade. Technology changes have also been made within the versions of PHP and MySQL running on your hosts server. These changes force all content management system (CMS) technology to change with it.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
When a CMS changes its structure, a migration is required. The old version is no longer supported. This creates potential problems with security as security patches are discontinued and older versions of Joomla are not maintained. &lt;br /&gt;
&lt;br /&gt;
Many hosts don’t want older software scripts (Joomla is a script - all third-party extensions are scripts) running on their servers because security is compromised as software ages. They have to update their servers to remain secure. More and more older versions of Joomla cease functioning because of server upgrades on the part of the host.&lt;br /&gt;
&lt;br /&gt;
== Migration is like moving to a new house or a remodel ==&lt;br /&gt;
 &lt;br /&gt;
You can think of migration like moving from one home to a new home. You filter through your belongings and furniture and pack the important pieces to take with you. You discard lingering trash or eliminate items you no longer need. Once you get into your new home, you may find you need to acquire some new pieces of furniture or fixtures to make your new home operate smoothly.&lt;br /&gt;
 &lt;br /&gt;
Same with migration. You are deciding what to take with you and what to get rid of on your site. What stays? What goes?&lt;br /&gt;
 &lt;br /&gt;
When you move to a new house, you may have the skills and expertise to move the entire household yourself or you may need to get some help moving (not everyone can move a piano). You may only need your own two hands and a few boxes. Alternatively, you may need a moving service with a gigantic truck and a lot of helpers. Same is true with migrating from one life cycle of Joomla to another.&lt;br /&gt;
&lt;br /&gt;
Take the Self Assessment to determine if you can/should perform the migration yourself or if maybe you should get some help. If you have the skills to migrate the site yourself, continue to the Planning phase of the migration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Migration_Step_by_Step_Self_Assessment|Self Assessment|class=expand success}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Planning_for_Migration|Migration Planning|class=expand}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Migration]]&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/1/de&amp;diff=135248</id>
		<title>Translations:Why Migrate/1/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/1/de&amp;diff=135248"/>
		<updated>2014-11-25T14:54:15Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Created page with &amp;quot;Kannst Du Dich nicht entscheiden, ob Du migrieren solltest, oder nicht? Letztendlich läuft doch alles. Warum jetzt etwas daran rütteln? Irgendwoher hast Du auf jeden Fall vo...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Kannst Du Dich nicht entscheiden, ob Du migrieren solltest, oder nicht? Letztendlich läuft doch alles. Warum jetzt etwas daran rütteln? Irgendwoher hast Du auf jeden Fall von der Notwendigkeit einer Migration zu einer neueren Version gehört und bist so hier gelandet. Du bist her an der richtigen Adresse. Hier die Gründe, warum Du den Sprung jetzt wagen sollest!&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135247</id>
		<title>Why Migrate/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Why_Migrate/de&amp;diff=135247"/>
		<updated>2014-11-25T14:53:55Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Created page with &amp;quot;Warum Migrieren&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
Undecided if you should migrate or not? After all, your site is running fine. Why rock the boat? Somehow you’ve heard/learned that you need to migrate to a newer life cycle or version and landed here. You’ve come to the right place. Here are all the reasons to take the plunge!&lt;br /&gt;
 &lt;br /&gt;
==Why should I migrate?==&lt;br /&gt;
&lt;br /&gt;
A Joomla! migration gives everyone a new opportunity to:&lt;br /&gt;
&lt;br /&gt;
* Revisit site goals and rethink its purpose&lt;br /&gt;
* Clean up “great ideas” that never saw the light of day&lt;br /&gt;
* Inventory third-party extensions that may have been installed but not used&lt;br /&gt;
* Simplify and clean up old articles, menus and other content&lt;br /&gt;
* Create new functionality on the site&lt;br /&gt;
* Change design and navigation&lt;br /&gt;
* Add accessibility to disabled visitors&lt;br /&gt;
* Make the site mobile-friendly&lt;br /&gt;
* Improve search engine optimization&lt;br /&gt;
* Utilize new features you may have been using third-party extensions for&lt;br /&gt;
* Insure your data against security breaches by having all the latest software&lt;br /&gt;
&lt;br /&gt;
=== Features and usability enhancements ===&lt;br /&gt;
Typically new life cycles of Joomla include new features and usability enhancements. These sometimes can eliminate the need of a third-party extension and enable the increased use of Joomla core components. Read more about features [http://www.joomla.org/3/en Joomla 3 features].&lt;br /&gt;
&lt;br /&gt;
=== Technology Changes === &lt;br /&gt;
Significant changes have taken place! Major releases of Joomla have restructured the data and require a “migration” as opposed to an update or upgrade. Technology changes have also been made within the versions of PHP and MySQL running on your hosts server. These changes force all content management system (CMS) technology to change with it.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
When a CMS changes its structure, a migration is required. The old version is no longer supported. This creates potential problems with security as security patches are discontinued and older versions of Joomla are not maintained. &lt;br /&gt;
&lt;br /&gt;
Many hosts don’t want older software scripts (Joomla is a script - all third-party extensions are scripts) running on their servers because security is compromised as software ages. They have to update their servers to remain secure. More and more older versions of Joomla cease functioning because of server upgrades on the part of the host.&lt;br /&gt;
&lt;br /&gt;
== Migration is like moving to a new house or a remodel ==&lt;br /&gt;
 &lt;br /&gt;
You can think of migration like moving from one home to a new home. You filter through your belongings and furniture and pack the important pieces to take with you. You discard lingering trash or eliminate items you no longer need. Once you get into your new home, you may find you need to acquire some new pieces of furniture or fixtures to make your new home operate smoothly.&lt;br /&gt;
 &lt;br /&gt;
Same with migration. You are deciding what to take with you and what to get rid of on your site. What stays? What goes?&lt;br /&gt;
 &lt;br /&gt;
When you move to a new house, you may have the skills and expertise to move the entire household yourself or you may need to get some help moving (not everyone can move a piano). You may only need your own two hands and a few boxes. Alternatively, you may need a moving service with a gigantic truck and a lot of helpers. Same is true with migrating from one life cycle of Joomla to another.&lt;br /&gt;
&lt;br /&gt;
Take the Self Assessment to determine if you can/should perform the migration yourself or if maybe you should get some help. If you have the skills to migrate the site yourself, continue to the Planning phase of the migration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Migration_Step_by_Step_Self_Assessment|Self Assessment|class=expand success}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;large-6 columns&amp;quot;&amp;gt;{{Basic button|S:MyLanguage/Planning_for_Migration|Migration Planning|class=expand}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Migration]]&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/Page_display_title/de&amp;diff=135246</id>
		<title>Translations:Why Migrate/Page display title/de</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Translations:Why_Migrate/Page_display_title/de&amp;diff=135246"/>
		<updated>2014-11-25T14:53:54Z</updated>

		<summary type="html">&lt;p&gt;FrankyD: Created page with &amp;quot;Warum Migrieren&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Warum Migrieren&lt;/div&gt;</summary>
		<author><name>FrankyD</name></author>
	</entry>
</feed>