summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Machniak <alec@alec.pl>2013-01-30 11:50:52 +0100
committerAleksander Machniak <alec@alec.pl>2013-01-30 11:50:52 +0100
commita2a1f8d7ed2911c2a4bab05ae599a80ed690c9c4 (patch)
tree7d672ba4833b53c0d24e51985f15a81fa8d1b8b7
parentcbaf7a2fb001fb52c32c1d30e46d52d29b420350 (diff)
Added automated in-browser tests (PHPUnit + Selenium Web Driver)
-rw-r--r--tests/Selenium/Addressbook/Addressbook.php21
-rw-r--r--tests/Selenium/Addressbook/Import.php29
-rw-r--r--tests/Selenium/Login.php21
-rw-r--r--tests/Selenium/Logout.php20
-rw-r--r--tests/Selenium/Mail/CheckRecent.php14
-rw-r--r--tests/Selenium/Mail/Compose.php25
-rw-r--r--tests/Selenium/Mail/Getunread.php13
-rw-r--r--tests/Selenium/Mail/List.php25
-rw-r--r--tests/Selenium/Mail/Mail.php23
-rw-r--r--tests/Selenium/Settings/About.php14
-rw-r--r--tests/Selenium/Settings/Folders.php20
-rw-r--r--tests/Selenium/Settings/Identities.php19
-rw-r--r--tests/Selenium/Settings/Settings.php17
-rw-r--r--tests/Selenium/bootstrap.php181
-rw-r--r--tests/Selenium/phpunit.xml21
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>