From a2a1f8d7ed2911c2a4bab05ae599a80ed690c9c4 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Wed, 30 Jan 2013 11:50:52 +0100 Subject: Added automated in-browser tests (PHPUnit + Selenium Web Driver) --- tests/Selenium/Addressbook/Addressbook.php | 21 ++++ tests/Selenium/Addressbook/Import.php | 29 +++++ tests/Selenium/Login.php | 21 ++++ tests/Selenium/Logout.php | 20 ++++ tests/Selenium/Mail/CheckRecent.php | 14 +++ tests/Selenium/Mail/Compose.php | 25 ++++ tests/Selenium/Mail/Getunread.php | 13 +++ tests/Selenium/Mail/List.php | 25 ++++ tests/Selenium/Mail/Mail.php | 23 ++++ tests/Selenium/Settings/About.php | 14 +++ tests/Selenium/Settings/Folders.php | 20 ++++ tests/Selenium/Settings/Identities.php | 19 +++ tests/Selenium/Settings/Settings.php | 17 +++ tests/Selenium/bootstrap.php | 181 +++++++++++++++++++++++++++++ tests/Selenium/phpunit.xml | 21 ++++ 15 files changed, 463 insertions(+) create mode 100644 tests/Selenium/Addressbook/Addressbook.php create mode 100644 tests/Selenium/Addressbook/Import.php create mode 100644 tests/Selenium/Login.php create mode 100644 tests/Selenium/Logout.php create mode 100644 tests/Selenium/Mail/CheckRecent.php create mode 100644 tests/Selenium/Mail/Compose.php create mode 100644 tests/Selenium/Mail/Getunread.php create mode 100644 tests/Selenium/Mail/List.php create mode 100644 tests/Selenium/Mail/Mail.php create mode 100644 tests/Selenium/Settings/About.php create mode 100644 tests/Selenium/Settings/Folders.php create mode 100644 tests/Selenium/Settings/Identities.php create mode 100644 tests/Selenium/Settings/Settings.php create mode 100644 tests/Selenium/bootstrap.php create mode 100644 tests/Selenium/phpunit.xml (limited to 'tests') 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 @@ +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 @@ +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 @@ +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 @@ +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 @@ +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 @@ +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 @@ +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 @@ +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 @@ +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 @@ +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 @@ +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 @@ +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 @@ +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 @@ + | + | Author: Aleksander Machniak | + +-----------------------------------------------------------------------+ +*/ + +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 @@ + + + + Login.php + Addressbook/Addressbook.php + Addressbook/Import.php + Mail/Mail.php + Mail/CheckRecent.php + Mail/Compose.php + Mail/Getunread.php + Mail/List.php + Settings/About.php + Settings/Folders.php + Settings/Identities.php + Settings/Settings.php + Logout.php + + + -- cgit v1.2.3