Thomas Bruederli
2014-04-21 d220ebd708a6893fdb68b8548a30990d99ca1c02
commit | author | age
a2a1f8 1 <?php
AM 2
3 /*
4  +-----------------------------------------------------------------------+
5  | tests/Selenium/bootstrap.php                                          |
6  |                                                                       |
7  | This file is part of the Roundcube Webmail client                     |
d220eb 8  | Copyright (C) 2009-2014, The Roundcube Dev Team                       |
a2a1f8 9  |                                                                       |
AM 10  | Licensed under the GNU General Public License version 3 or            |
11  | any later version with exceptions for skins & plugins.                |
12  | See the README file for a full license statement.                     |
13  |                                                                       |
14  | PURPOSE:                                                              |
15  |   Environment initialization script for unit tests                    |
16  +-----------------------------------------------------------------------+
17  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
18  | Author: Aleksander Machniak <alec@alec.pl>                            |
19  +-----------------------------------------------------------------------+
20 */
21
22 if (php_sapi_name() != 'cli')
23   die("Not in shell mode (php-cli)");
24
25 if (!defined('INSTALL_PATH')) define('INSTALL_PATH', realpath(dirname(__FILE__) . '/../../') . '/' );
26
27 define('TESTS_DIR', dirname(__FILE__) . '/');
28
29 if (@is_dir(TESTS_DIR . 'config')) {
deb2b8 30     define('RCUBE_CONFIG_DIR', TESTS_DIR . 'config');
a2a1f8 31 }
AM 32
33 require_once(INSTALL_PATH . 'program/include/iniset.php');
34
35 // Extend include path so some plugin test won't fail
36 $include_path = ini_get('include_path') . PATH_SEPARATOR . TESTS_DIR . '..';
37 if (set_include_path($include_path) === false) {
38     die("Fatal error: ini_set/set_include_path does not work.");
39 }
40
d220eb 41 $rcmail = rcmail::get_instance('test');
a2a1f8 42
AM 43 define('TESTS_URL',     $rcmail->config->get('tests_url'));
44 define('TESTS_BROWSER', $rcmail->config->get('tests_browser', 'firefox'));
45 define('TESTS_USER',    $rcmail->config->get('tests_username'));
46 define('TESTS_PASS',    $rcmail->config->get('tests_password'));
47 define('TESTS_SLEEP',   $rcmail->config->get('tests_sleep', 5));
48
49 PHPUnit_Extensions_Selenium2TestCase::shareSession(true);
50
d220eb 51
TB 52 /**
53  * satisfy PHPUnit
54  */
55 class bootstrap
56 {
57     /**
58      * Wipe and re-initialize (mysql) database
59      */
60     public static function init_db()
61     {
62         $rcmail = rcmail::get_instance();
63
64         // drop all existing tables first
65         $db = $rcmail->get_dbh();
66         $db->query("SET FOREIGN_KEY_CHECKS=0");
67         $sql_res = $db->query("SHOW TABLES");
68         while ($sql_arr = $db->fetch_array($sql_res)) {
69             $table = reset($sql_arr);
70             $db->query("DROP TABLE $table");
71         }
72
73         // init database with schema
74         $dsn = parse_url($rcmail->config->get('db_dsnw'));
75         $db_name = trim($dsn['path'], '/');
76
77         if ($dsn['scheme'] == 'mysql' || $dsn['scheme'] == 'mysqli') {
78             system(sprintf('cat %s %s | mysql -h %s -u %s --password=%s %s',
79                 realpath(INSTALL_PATH . '/SQL/mysql.initial.sql'),
80                 realpath(TESTS_DIR . '/Selenium/data/mysql.sql'),
81                 escapeshellarg($dsn['host']),
82                 escapeshellarg($dsn['user']),
83                 escapeshellarg($dsn['pass']),
84                 escapeshellarg($db_name)
85             ));
86         }
87     }
88
89     /**
90      * Wipe the configured IMAP account and fill with test data
91      */
92     public static function init_imap()
93     {
94         if (!TESTS_USER)
95             return false;
96
97         // TBD.
98     }
99 }
100
a2a1f8 101 // @TODO: make sure mailbox has some content (always the same) or is empty
846669 102 // @TODO: plugins: enable all?
a2a1f8 103
AM 104 /**
105  * Base class for all tests in this directory
106  */
107 class Selenium_Test extends PHPUnit_Extensions_Selenium2TestCase
108 {
109     protected function setUp()
110     {
111         $this->setBrowser(TESTS_BROWSER);
846669 112
AM 113         // Set root to our index.html, for better performance
114         // See https://github.com/sebastianbergmann/phpunit-selenium/issues/217
d220eb 115         $baseurl = preg_replace('!/index(-.+)?\.php^!', '', TESTS_URL);
TB 116         $this->setBrowserUrl($baseurl . '/tests/Selenium');
a2a1f8 117     }
AM 118
119     protected function login()
120     {
121         $this->go('mail');
122
123         $user_input = $this->byCssSelector('form input[name="_user"]');
124         $pass_input = $this->byCssSelector('form input[name="_pass"]');
125         $submit     = $this->byCssSelector('form input[type="submit"]');
126
127         $user_input->value(TESTS_USER);
128         $pass_input->value(TESTS_PASS);
129
130         // submit login form
131         $submit->click();
132
133         // wait after successful login
134         sleep(TESTS_SLEEP);
135     }
136
137     protected function go($task = 'mail', $action = null)
138     {
d220eb 139         $this->url(TESTS_URL . '?_task=' . $task);
a2a1f8 140
AM 141         // wait for interface load (initial ajax requests, etc.)
142         sleep(TESTS_SLEEP);
143
144         if ($action) {
145             $this->click_button($action);
146
147             sleep(TESTS_SLEEP);
148         }
149     }
150
151     protected function get_env()
152     {
153         return $this->execute(array(
154             'script' => 'return rcmail.env;',
155             'args' => array(),
156         ));
157     }
158
159     protected function get_buttons($action)
160     {
161         $buttons = $this->execute(array(
162             'script' => "return rcmail.buttons['$action'];",
163             'args' => array(),
164         ));
165
166         if (is_array($buttons)) {
167             foreach ($buttons as $idx => $button) {
168                 $buttons[$idx] = $button['id'];
169             }
170         }
171
172         return (array) $buttons;
173     }
174
175     protected function get_objects()
176     {
177         return $this->execute(array(
178             'script' => "var i,r = []; for (i in rcmail.gui_objects) r.push(i); return r;",
179             'args' => array(),
180         ));
181     }
182
183     protected function click_button($action)
184     {
185         $buttons = $this->get_buttons($action);
186         $id      = array_shift($buttons);
187
188         // this doesn't work for me
189         $this->byId($id)->click();
190     }
191
192     protected function ajaxResponse($action, $script = '', $button = false)
193     {
194         if (!$script && !$button) {
195             $script = "rcmail.command('$action')";
196         }
197
198         $script = 
199         "if (!window.test_ajax_response) {
200             window.test_ajax_response_object = {};
201             function test_ajax_response(response)
202             {
203                 if (response.response && response.response.action) {
204                     window.test_ajax_response_object[response.response.action] = response.response;
205                 }
206             }
207             rcmail.addEventListener('responsebefore', test_ajax_response);
208         }
209         window.test_ajax_response_object['$action'] = null;
210         $script;
211         ";
212
213         // run request
214         $this->execute(array(
215             'script' => $script,
216             'args' => array(),
217         ));
218
219         if ($button) {
220             $this->click_button($action);
221         }
222
223         // wait
224         sleep(TESTS_SLEEP);
225
226         // get response
227         $response = $this->execute(array(
228             'script' => "return window.test_ajax_response_object['$action'];",
229             'args' => array(),
230         ));
231
232         return $response;
233     }
234 }