diff options
author | Aleksander Machniak <alec@alec.pl> | 2013-01-30 11:50:52 +0100 |
---|---|---|
committer | Aleksander Machniak <alec@alec.pl> | 2013-01-30 11:50:52 +0100 |
commit | a2a1f8d7ed2911c2a4bab05ae599a80ed690c9c4 (patch) | |
tree | 7d672ba4833b53c0d24e51985f15a81fa8d1b8b7 | |
parent | cbaf7a2fb001fb52c32c1d30e46d52d29b420350 (diff) |
Added automated in-browser tests (PHPUnit + Selenium Web Driver)
-rw-r--r-- | tests/Selenium/Addressbook/Addressbook.php | 21 | ||||
-rw-r--r-- | tests/Selenium/Addressbook/Import.php | 29 | ||||
-rw-r--r-- | tests/Selenium/Login.php | 21 | ||||
-rw-r--r-- | tests/Selenium/Logout.php | 20 | ||||
-rw-r--r-- | tests/Selenium/Mail/CheckRecent.php | 14 | ||||
-rw-r--r-- | tests/Selenium/Mail/Compose.php | 25 | ||||
-rw-r--r-- | tests/Selenium/Mail/Getunread.php | 13 | ||||
-rw-r--r-- | tests/Selenium/Mail/List.php | 25 | ||||
-rw-r--r-- | tests/Selenium/Mail/Mail.php | 23 | ||||
-rw-r--r-- | tests/Selenium/Settings/About.php | 14 | ||||
-rw-r--r-- | tests/Selenium/Settings/Folders.php | 20 | ||||
-rw-r--r-- | tests/Selenium/Settings/Identities.php | 19 | ||||
-rw-r--r-- | tests/Selenium/Settings/Settings.php | 17 | ||||
-rw-r--r-- | tests/Selenium/bootstrap.php | 181 | ||||
-rw-r--r-- | tests/Selenium/phpunit.xml | 21 |
15 files changed, 463 insertions, 0 deletions
diff --git a/tests/Selenium/Addressbook/Addressbook.php b/tests/Selenium/Addressbook/Addressbook.php new file mode 100644 index 000000000..9a22b6e13 --- /dev/null +++ b/tests/Selenium/Addressbook/Addressbook.php @@ -0,0 +1,21 @@ +<?php + +class Selenium_Addressbook_Addressbook extends Selenium_Test +{ + public function testAddressbook() + { + $this->go('addressbook'); + + // check task + $env = $this->get_env(); + $this->assertEquals('addressbook', $env['task']); + + $objects = $this->get_objects(); + + // these objects should be there always + $this->assertContains('qsearchbox', $objects); + $this->assertContains('folderlist', $objects); + $this->assertContains('contactslist', $objects); + $this->assertContains('countdisplay', $objects); + } +} diff --git a/tests/Selenium/Addressbook/Import.php b/tests/Selenium/Addressbook/Import.php new file mode 100644 index 000000000..13d81740f --- /dev/null +++ b/tests/Selenium/Addressbook/Import.php @@ -0,0 +1,29 @@ +<?php + +class Selenium_Addressbook_Import extends Selenium_Test +{ + public function testImport() + { + $this->go('addressbook', 'import'); + + // check task and action + $env = $this->get_env(); + $this->assertEquals('addressbook', $env['task']); + $this->assertEquals('import', $env['action']); + + $objects = $this->get_objects(); + + // these objects should be there always + $this->assertContains('importform', $objects); + } + + public function testImport2() + { + $this->go('addressbook', 'import'); + + $objects = $this->get_objects(); + + // these objects should be there always + $this->assertContains('importform', $objects); + } +} diff --git a/tests/Selenium/Login.php b/tests/Selenium/Login.php new file mode 100644 index 000000000..a3f0ab6b4 --- /dev/null +++ b/tests/Selenium/Login.php @@ -0,0 +1,21 @@ +<?php + +class Selenium_Login extends Selenium_Test +{ + public function testLogin() + { + // first test, we're already on the login page + $this->url(TESTS_URL); + + // task should be set to 'login' + $env = $this->get_env(); + $this->assertEquals('login', $env['task']); + + // test valid login + $this->login(); + + // task should be set to 'mail' now + $env = $this->get_env(); + $this->assertEquals('mail', $env['task']); + } +} diff --git a/tests/Selenium/Logout.php b/tests/Selenium/Logout.php new file mode 100644 index 000000000..95eeda57c --- /dev/null +++ b/tests/Selenium/Logout.php @@ -0,0 +1,20 @@ +<?php + +class Selenium_Logout extends Selenium_Test +{ + public function testLogout() + { + $this->go('mail'); + + $this->click_button('logout'); + + sleep(TESTS_SLEEP); + + // task should be set to 'login' + $env = $this->get_env(); + $this->assertEquals('login', $env['task']); + + // form should exist + $user_input = $this->byCssSelector('form input[name="_user"]'); + } +} diff --git a/tests/Selenium/Mail/CheckRecent.php b/tests/Selenium/Mail/CheckRecent.php new file mode 100644 index 000000000..865421c2d --- /dev/null +++ b/tests/Selenium/Mail/CheckRecent.php @@ -0,0 +1,14 @@ +<?php + +class Selenium_Mail_CheckRecent extends Selenium_Test +{ + public function testCheckRecent() + { + $this->go('mail'); + + $res = $this->ajaxResponse('check-recent', "rcmail.command('checkmail')"); + + $this->assertEquals('check-recent', $res['action']); + $this->assertRegExp('/this\.set_unread_count/', $res['exec']); + } +} diff --git a/tests/Selenium/Mail/Compose.php b/tests/Selenium/Mail/Compose.php new file mode 100644 index 000000000..e707ef17d --- /dev/null +++ b/tests/Selenium/Mail/Compose.php @@ -0,0 +1,25 @@ +<?php + +class Selenium_Mail_Compose extends Selenium_Test +{ + public function testCompose() + { + $this->go('mail', 'compose'); + + // check task and action + $env = $this->get_env(); + $this->assertEquals('mail', $env['task']); + $this->assertEquals('compose', $env['action']); + + $objects = $this->get_objects(); + + // these objects should be there always + $this->assertContains('qsearchbox', $objects); + $this->assertContains('addressbookslist', $objects); + $this->assertContains('contactslist', $objects); + $this->assertContains('messageform', $objects); + $this->assertContains('attachmentlist', $objects); + $this->assertContains('filedrop', $objects); + $this->assertContains('uploadform', $objects); + } +} diff --git a/tests/Selenium/Mail/Getunread.php b/tests/Selenium/Mail/Getunread.php new file mode 100644 index 000000000..d6362f2f4 --- /dev/null +++ b/tests/Selenium/Mail/Getunread.php @@ -0,0 +1,13 @@ +<?php + +class Selenium_Mail_Getunread extends Selenium_Test +{ + public function testGetunread() + { + $this->go('mail'); + + $res = $this->ajaxResponse('getunread', "rcmail.http_request('getunread')"); + + $this->assertEquals('getunread', $res['action']); + } +} diff --git a/tests/Selenium/Mail/List.php b/tests/Selenium/Mail/List.php new file mode 100644 index 000000000..7574c1801 --- /dev/null +++ b/tests/Selenium/Mail/List.php @@ -0,0 +1,25 @@ +<?php + +class Selenium_Mail_List extends Selenium_Test +{ + public function testCheckRecent() + { + $this->go('mail'); + + $res = $this->ajaxResponse('list', "rcmail.command('list')"); + + $this->assertEquals('list', $res['action']); + $this->assertRegExp('/this\.set_pagetitle/', $res['exec']); + $this->assertRegExp('/this\.set_unread_count/', $res['exec']); + $this->assertRegExp('/this\.set_rowcount/', $res['exec']); + $this->assertRegExp('/this\.set_message_coltypes/', $res['exec']); +// $this->assertRegExp('/this\.add_message_row/', $res['exec']); + + $this->assertContains('current_page', $res['env']); + $this->assertContains('exists', $res['env']); + $this->assertContains('pagecount', $res['env']); + $this->assertContains('pagesize', $res['env']); + $this->assertContains('messagecount', $res['env']); + $this->assertContains('mailbox', $res['env']); + } +} diff --git a/tests/Selenium/Mail/Mail.php b/tests/Selenium/Mail/Mail.php new file mode 100644 index 000000000..98413787b --- /dev/null +++ b/tests/Selenium/Mail/Mail.php @@ -0,0 +1,23 @@ +<?php + +class Selenium_Mail_Mail extends Selenium_Test +{ + public function testMail() + { + $this->go('mail'); + + // check task + $env = $this->get_env(); + $this->assertEquals('mail', $env['task']); + + $objects = $this->get_objects(); + + // these objects should be there always + $this->assertContains('qsearchbox', $objects); + $this->assertContains('mailboxlist', $objects); + $this->assertContains('messagelist', $objects); + $this->assertContains('quotadisplay', $objects); + $this->assertContains('search_filter', $objects); + $this->assertContains('countdisplay', $objects); + } +} diff --git a/tests/Selenium/Settings/About.php b/tests/Selenium/Settings/About.php new file mode 100644 index 000000000..9a6c31d4b --- /dev/null +++ b/tests/Selenium/Settings/About.php @@ -0,0 +1,14 @@ +<?php + +class Selenium_Settings_About extends Selenium_Test +{ + public function testAbout() + { + $this->url(TESTS_URL . '/?_task=settings&_action=about'); + + // check task and action + $env = $this->get_env(); + $this->assertEquals('settings', $env['task']); + $this->assertEquals('about', $env['action']); + } +} diff --git a/tests/Selenium/Settings/Folders.php b/tests/Selenium/Settings/Folders.php new file mode 100644 index 000000000..fa64e45d6 --- /dev/null +++ b/tests/Selenium/Settings/Folders.php @@ -0,0 +1,20 @@ +<?php + +class Selenium_Settings_Folders extends Selenium_Test +{ + public function testFolders() + { + $this->go('settings', 'folders'); + + // task should be set to 'settings' and action to 'folders' + $env = $this->get_env(); + $this->assertEquals('settings', $env['task']); + $this->assertEquals('folders', $env['action']); + + $objects = $this->get_objects(); + + // these objects should be there always + $this->assertContains('quotadisplay', $objects); + $this->assertContains('subscriptionlist', $objects); + } +} diff --git a/tests/Selenium/Settings/Identities.php b/tests/Selenium/Settings/Identities.php new file mode 100644 index 000000000..869018b09 --- /dev/null +++ b/tests/Selenium/Settings/Identities.php @@ -0,0 +1,19 @@ +<?php + +class Selenium_Settings_Identities extends Selenium_Test +{ + public function testIdentities() + { + $this->go('settings', 'identities'); + + // check task and action + $env = $this->get_env(); + $this->assertEquals('settings', $env['task']); + $this->assertEquals('identities', $env['action']); + + $objects = $this->get_objects(); + + // these objects should be there always + $this->assertContains('identitieslist', $objects); + } +} diff --git a/tests/Selenium/Settings/Settings.php b/tests/Selenium/Settings/Settings.php new file mode 100644 index 000000000..08d8339f1 --- /dev/null +++ b/tests/Selenium/Settings/Settings.php @@ -0,0 +1,17 @@ +<?php + +class Selenium_Settings_Settings extends Selenium_Test +{ + public function testSettings() + { + $this->go('settings'); + + // task should be set to 'settings' + $env = $this->get_env(); + $this->assertEquals('settings', $env['task']); + + $objects = $this->get_objects(); + + $this->assertContains('sectionslist', $objects); + } +} diff --git a/tests/Selenium/bootstrap.php b/tests/Selenium/bootstrap.php new file mode 100644 index 000000000..0f7eed0d9 --- /dev/null +++ b/tests/Selenium/bootstrap.php @@ -0,0 +1,181 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | tests/Selenium/bootstrap.php | + | | + | This file is part of the Roundcube Webmail client | + | Copyright (C) 2009-2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + | PURPOSE: | + | Environment initialization script for unit tests | + +-----------------------------------------------------------------------+ + | Author: Thomas Bruederli <roundcube@gmail.com> | + | Author: Aleksander Machniak <alec@alec.pl> | + +-----------------------------------------------------------------------+ +*/ + +if (php_sapi_name() != 'cli') + die("Not in shell mode (php-cli)"); + +if (!defined('INSTALL_PATH')) define('INSTALL_PATH', realpath(dirname(__FILE__) . '/../../') . '/' ); + +define('TESTS_DIR', dirname(__FILE__) . '/'); + +if (@is_dir(TESTS_DIR . 'config')) { + define('RCMAIL_CONFIG_DIR', TESTS_DIR . 'config'); +} + +require_once(INSTALL_PATH . 'program/include/iniset.php'); + +// Extend include path so some plugin test won't fail +$include_path = ini_get('include_path') . PATH_SEPARATOR . TESTS_DIR . '..'; +if (set_include_path($include_path) === false) { + die("Fatal error: ini_set/set_include_path does not work."); +} + +$rcmail = rcube::get_instance(); + +define('TESTS_URL', $rcmail->config->get('tests_url')); +define('TESTS_BROWSER', $rcmail->config->get('tests_browser', 'firefox')); +define('TESTS_USER', $rcmail->config->get('tests_username')); +define('TESTS_PASS', $rcmail->config->get('tests_password')); +define('TESTS_SLEEP', $rcmail->config->get('tests_sleep', 5)); + +PHPUnit_Extensions_Selenium2TestCase::shareSession(true); + +// @TODO: remove user record from DB before running tests +// @TODO: make sure mailbox has some content (always the same) or is empty + +/** + * Base class for all tests in this directory + */ +class Selenium_Test extends PHPUnit_Extensions_Selenium2TestCase +{ + protected function setUp() + { +// $this->rc = rcube::get_instance(); + $this->setBrowser(TESTS_BROWSER); + $this->setBrowserUrl(TESTS_URL); + } + + protected function login() + { + $this->go('mail'); + + $user_input = $this->byCssSelector('form input[name="_user"]'); + $pass_input = $this->byCssSelector('form input[name="_pass"]'); + $submit = $this->byCssSelector('form input[type="submit"]'); + + $user_input->value(TESTS_USER); + $pass_input->value(TESTS_PASS); + + // submit login form + $submit->click(); + + // wait after successful login + sleep(TESTS_SLEEP); + } + + protected function go($task = 'mail', $action = null) + { + $this->url(TESTS_URL . '/?_task=' . $task); + + // wait for interface load (initial ajax requests, etc.) + sleep(TESTS_SLEEP); + + if ($action) { + $this->click_button($action); + + sleep(TESTS_SLEEP); + } + } + + protected function get_env() + { + return $this->execute(array( + 'script' => 'return rcmail.env;', + 'args' => array(), + )); + } + + protected function get_buttons($action) + { + $buttons = $this->execute(array( + 'script' => "return rcmail.buttons['$action'];", + 'args' => array(), + )); + + if (is_array($buttons)) { + foreach ($buttons as $idx => $button) { + $buttons[$idx] = $button['id']; + } + } + + return (array) $buttons; + } + + protected function get_objects() + { + return $this->execute(array( + 'script' => "var i,r = []; for (i in rcmail.gui_objects) r.push(i); return r;", + 'args' => array(), + )); + } + + protected function click_button($action) + { + $buttons = $this->get_buttons($action); + $id = array_shift($buttons); + + // this doesn't work for me + $this->byId($id)->click(); + } + + protected function ajaxResponse($action, $script = '', $button = false) + { + if (!$script && !$button) { + $script = "rcmail.command('$action')"; + } + + $script = + "if (!window.test_ajax_response) { + window.test_ajax_response_object = {}; + function test_ajax_response(response) + { + if (response.response && response.response.action) { + window.test_ajax_response_object[response.response.action] = response.response; + } + } + rcmail.addEventListener('responsebefore', test_ajax_response); + } + window.test_ajax_response_object['$action'] = null; + $script; + "; + + // run request + $this->execute(array( + 'script' => $script, + 'args' => array(), + )); + + if ($button) { + $this->click_button($action); + } + + // wait + sleep(TESTS_SLEEP); + + // get response + $response = $this->execute(array( + 'script' => "return window.test_ajax_response_object['$action'];", + 'args' => array(), + )); + + return $response; + } +} diff --git a/tests/Selenium/phpunit.xml b/tests/Selenium/phpunit.xml new file mode 100644 index 000000000..b5835cf74 --- /dev/null +++ b/tests/Selenium/phpunit.xml @@ -0,0 +1,21 @@ +<phpunit backupGlobals="false" + bootstrap="bootstrap.php" + colors="true"> + <testsuites> + <testsuite name="All Tests"> + <file>Login.php</file><!-- Login.php test must be first --> + <file>Addressbook/Addressbook.php</file> + <file>Addressbook/Import.php</file> + <file>Mail/Mail.php</file> + <file>Mail/CheckRecent.php</file> + <file>Mail/Compose.php</file> + <file>Mail/Getunread.php</file> + <file>Mail/List.php</file> + <file>Settings/About.php</file> + <file>Settings/Folders.php</file> + <file>Settings/Identities.php</file> + <file>Settings/Settings.php</file> + <file>Logout.php</file><!-- Logout.php test must be last --> + </testsuite> + </testsuites> +</phpunit> |