diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 9960530d05..e1811afe7c 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -21,6 +21,8 @@ + + diff --git a/test/selenium/PmaSeleniumCreateDropDatabaseTest.php b/test/selenium/PmaSeleniumCreateDropDatabaseTest.php index 8911404883..e35ababc0e 100644 --- a/test/selenium/PmaSeleniumCreateDropDatabaseTest.php +++ b/test/selenium/PmaSeleniumCreateDropDatabaseTest.php @@ -1,7 +1,7 @@ setBrowser(Helper::getBrowserString()); $this->setBrowserUrl(TESTSUITE_PHPMYADMIN_HOST . TESTSUITE_PHPMYADMIN_URL); + $this->_seleniumTasks = new PmaSeleniumTestCase($this); } /** @@ -36,19 +51,35 @@ class PmaSeleniumCreateDropDatabaseTest extends PHPUnit_Extensions_SeleniumTestC */ public function testCreateDropDatabase() { - $log = new PmaSeleniumTestCase($this); - $dbname = 'pma_testdb' . time(); - $log->login(TESTSUITE_USER, TESTSUITE_PASSWORD); + $this->_dbname = 'pma_testdb' . time(); + $this->_seleniumTasks->login(TESTSUITE_USER, TESTSUITE_PASSWORD); $this->click("link=Databases"); $this->waitForElementPresent("id=text_create_db"); - $this->type("id=text_create_db", $dbname); + $this->type("id=text_create_db", $this->_dbname); $this->click("id=buttonGo"); - $this->waitForElementPresent("css=span.ajax_notification"); + $this->waitForElementPresent("css=span.ajax_notification div.success"); $this->assertElementPresent("css=span.ajax_notification div.success"); - $this->click("css=input[name='selected_dbs[]'][value='" . $dbname . "']"); + $this->_dropDatabase(); + } + + /** + * Drops a database, called after testCreateDropDatabase + * + * @return void + */ + private function _dropDatabase() + { + $this->_seleniumTasks->gotoHomepage(); + $this->click("css=ul#topmenu a:contains('Databases')"); + $this->waitForElementNotPresent('css=div#loading_parent'); + $this->click( + "css=input[name='selected_dbs[]'][value='" . $this->_dbname . "']" + ); $this->click("css=button.mult_submit"); $this->click("css=button:contains('OK')"); - $this->waitForElementPresent("css=span.ajax_notification"); + $this->waitForElementNotPresent( + "css=input[name='selected_dbs[]'][value='" . $this->_dbname . "']" + ); $this->assertElementPresent("css=span.ajax_notification div.success"); } } diff --git a/test/selenium/PmaSeleniumTablesBrowseDataTest.php b/test/selenium/PmaSeleniumTablesBrowseDataTest.php new file mode 100644 index 0000000000..d59fa1848d --- /dev/null +++ b/test/selenium/PmaSeleniumTablesBrowseDataTest.php @@ -0,0 +1,320 @@ +setBrowser(Helper::getBrowserString()); + $this->setBrowserUrl(TESTSUITE_PHPMYADMIN_HOST . TESTSUITE_PHPMYADMIN_URL); + $this->start(); + $this->_seleniumTasks = new PmaSeleniumTestCase($this); + $this->_seleniumTasks->dbConnect(); + $this->_dbname = 'pma_db_' . time(); + $this->_seleniumTasks->dbQuery('CREATE DATABASE ' . $this->_dbname); + $this->_seleniumTasks->dbQuery('USE ' . $this->_dbname); + $this->_seleniumTasks->dbQuery( + "CREATE TABLE `test_table` (" + . " `id` int(11) NOT NULL AUTO_INCREMENT," + . " `name` varchar(20) NOT NULL," + . " `datetimefield` datetime NOT NULL," + . " PRIMARY KEY (`id`)" + . ")" + ); + $this->_seleniumTasks->dbQuery( + "INSERT INTO `test_table` (`id`, `name`, `datetimefield`) VALUES" + . " (1, 'abcd', '2011-01-20 02:00:02')," + . " (2, 'foo', '2010-01-20 02:00:02')," + . " (3, 'Abcd', '2012-01-20 02:00:02')" + ); + $this->_seleniumTasks->login(TESTSUITE_USER, TESTSUITE_PASSWORD); + $this->click('link='. $this->_dbname.''); + $this->waitForElementPresent("link=test_table"); + $this->click("link=Browse"); + $this->waitForElementPresent("id=table_results"); + } + + /** + * Test sorting of records in browse table + * + * @return void + */ + public function testSortRecords() + { + // case 1 + $this->click("link=name"); + $this->waitForElementNotPresent("id=loading_parent"); + usleep(100); + + $this->assertEquals( + $this->getTable("table_results.1.4"), + "1" + ); + + $this->assertEquals( + $this->getTable("table_results.2.4"), + "3" + ); + + $this->assertEquals( + $this->getTable("table_results.3.4"), + "2" + ); + + // case 2 + $this->click("link=name"); + $this->waitForElementNotPresent("id=loading_parent"); + usleep(100); + + $this->assertEquals( + $this->getTable("table_results.1.4"), + "2" + ); + + $this->assertEquals( + $this->getTable("table_results.2.4"), + "1" + ); + + $this->assertEquals( + $this->getTable("table_results.3.4"), + "3" + ); + + // case 2 + $this->click("link=datetimefield"); + $this->waitForElementNotPresent("id=loading_parent"); + usleep(100); + + $this->assertEquals( + $this->getTable("table_results.1.4"), + "3" + ); + + $this->assertEquals( + $this->getTable("table_results.2.4"), + "1" + ); + + $this->assertEquals( + $this->getTable("table_results.3.4"), + "2" + ); + + // case 4 + $this->click("link=datetimefield"); + $this->waitForElementNotPresent("id=loading_parent"); + usleep(100); + + $this->assertEquals( + $this->getTable("table_results.1.4"), + "2" + ); + + $this->assertEquals( + $this->getTable("table_results.2.4"), + "1" + ); + + $this->assertEquals( + $this->getTable("table_results.3.4"), + "3" + ); + } + + /** + * Test Edit Record + * + * @return void + */ + public function testChangeRecords() + { + $this->click("css=table#table_results tr:eq(2) td:eq(1) a"); + $this->waitForElementPresent("css=form#insertForm"); + + $this->assertEquals( + $this->getValue("id=field_1_3"), + "2" + ); + + $this->assertEquals( + $this->getValue("id=field_2_3"), + "foo" + ); + + $this->assertEquals( + $this->getValue("id=field_3_3"), + "2010-01-20 02:00:02" + ); + + $this->type("id=field_2_3", "foobar"); + $this->type("id=field_3_3", "2009-01-20 02:00:02"); + + $this->click("id=buttonYes"); + $this->waitForElementPresent("css=div.success:contains('1 row affected')"); + + $this->assertEquals( + $this->getTable("table_results.2.5"), + "foobar" + ); + + $this->assertEquals( + $this->getTable("table_results.2.6"), + "2009-01-20 02:00:02" + ); + } + + /** + * Test edit record by double click + * + * @return void + */ + public function testChangeRecordsByDoubleClick() + { + $this->doubleClick("css=table#table_results tr:eq(1) td:eq(5)"); + + $this->assertEquals( + $this->getText("css=textarea.edit_box:first"), + "abcd" + ); + + $this->type("css=textarea.edit_box:first", "abcde"); + $this->keyPressNative(10); + + $this->waitForElementPresent("css=div.success:contains('1 row affected')"); + + $this->assertEquals( + $this->getTable("table_results.1.5"), + "abcde" + ); + } + + /** + * Test copy and insert record + * + * @return void + */ + public function testCopyRecords() + { + $this->click("css=table#table_results tr:eq(3) td:eq(2) a"); + $this->waitForElementPresent("css=form#insertForm"); + + $this->assertEquals( + $this->getValue("id=field_2_3"), + "Abcd" + ); + + $this->assertEquals( + $this->getValue("id=field_3_3"), + "2012-01-20 02:00:02" + ); + + $this->type("id=field_2_3", "ABCDEFG"); + $this->type("id=field_3_3", "2012-01-20 02:05:02"); + + $this->click("id=buttonYes"); + $this->waitForElementPresent("css=div.success:contains('1 row inserted')"); + + $this->assertEquals( + $this->getTable("table_results.4.5"), + "ABCDEFG" + ); + + $this->assertEquals( + $this->getTable("table_results.4.6"), + "2012-01-20 02:05:02" + ); + } + + /** + * Test search table + * + * @return void + */ + public function testSearchRecords() + { + $this->click("link=Search"); + $this->waitForElementPresent("css=form#tbl_search_form"); + + $this->type("id=fieldID_1", "abcd"); + $this->select("name=criteriaColumnOperators[1]", "LIKE %...%"); + + $this->click("name=submit"); + $this->waitForElementPresent("css=div.success:contains('Showing rows')"); + + $this->assertEquals( + $this->getTable("table_results.1.4"), + "1" + ); + + $this->assertEquals( + $this->getTable("table_results.2.4"), + "3" + ); + } + + /** + * Test delete multiple records + * + * @return void + */ + public function testDeleteRecords() + { + $this->click("id=id_rows_to_delete1_left"); + $this->click("id=id_rows_to_delete2_left"); + + $this->click("css=button[value=delete]"); + $this->waitForElementPresent("css=fieldset.confirmation"); + + $this->click("id=buttonYes"); + $this->waitForElementPresent("css=div.success:contains('Showing rows')"); + + $this->assertElementNotPresent("table#table_results tr:eq(2)"); + $this->assertTextNotPresent("foobar"); + + } + + /** + * Teardown for test cases (drops database) + * + * @return void + */ + public function tearDown() + { + $this->_seleniumTasks->dbQuery('DROP DATABASE ' . $this->_dbname); + } +} diff --git a/test/selenium/PmaSeleniumTablesInsertDataTest.php b/test/selenium/PmaSeleniumTablesInsertDataTest.php new file mode 100644 index 0000000000..aea8b653db --- /dev/null +++ b/test/selenium/PmaSeleniumTablesInsertDataTest.php @@ -0,0 +1,148 @@ +setBrowser(Helper::getBrowserString()); + $this->setBrowserUrl(TESTSUITE_PHPMYADMIN_HOST . TESTSUITE_PHPMYADMIN_URL); + $this->start(); + $this->_seleniumTasks = new PmaSeleniumTestCase($this); + $this->_seleniumTasks->dbConnect(); + $this->_dbname = 'pma_db_' . time(); + $this->_seleniumTasks->dbQuery('CREATE DATABASE ' . $this->_dbname); + $this->_seleniumTasks->dbQuery('USE ' . $this->_dbname); + $this->_seleniumTasks->dbQuery( + "CREATE TABLE `test_table` (" + . " `id` int(11) NOT NULL AUTO_INCREMENT," + . " `name` varchar(20) NOT NULL," + . " `datetimefield` datetime NOT NULL," + . " PRIMARY KEY (`id`)" + . ")" + ); + $this->_seleniumTasks->login(TESTSUITE_USER, TESTSUITE_PASSWORD); + $this->click('link='. $this->_dbname.''); + $this->waitForElementPresent("link=test_table"); + } + + /** + * Insert data into table + * + * @return void + */ + public function testAddData() + { + $this->click("link=Insert"); + $this->waitForElementPresent("css=form#insertForm"); + + $this->type("id=field_1_3", "1"); + $this->type("id=field_2_3", "abcd"); + $this->type("id=field_3_3", "2011-01-20 02:00:02"); + $this->type("id=field_5_3", "foo"); + $this->type("id=field_6_3", "2010-01-20 02:00:02"); + + $this->select("name=after_insert", "Insert another new row"); + + // post + $this->click("id=buttonYes"); + $this->waitForElementPresent("css=div.success:contains('2 rows inserted')"); + + $this->type("id=field_2_3", "Abcd"); + $this->type("id=field_3_3", "2012-01-20 02:00:02"); + + // post + $this->click("css=table.insertRowTable:first input[value=Go]"); + $this->waitForElementPresent("css=div.success:contains('1 row inserted')"); + $this->_assertDataPresent(); + } + + private function _assertDataPresent() + { + $this->click("link=Browse"); + $this->waitForElementPresent("id=table_results"); + + $this->assertEquals( + $this->getTable("table_results.1.4"), + "1" + ); + + $this->assertEquals( + $this->getTable("table_results.1.5"), + "abcd" + ); + + $this->assertEquals( + $this->getTable("table_results.1.6"), + "2011-01-20 02:00:02" + ); + + $this->assertEquals( + $this->getTable("table_results.2.4"), + "2" + ); + + $this->assertEquals( + $this->getTable("table_results.2.5"), + "foo" + ); + + $this->assertEquals( + $this->getTable("table_results.2.6"), + "2010-01-20 02:00:02" + ); + + $this->assertEquals( + $this->getTable("table_results.3.4"), + "3" + ); + + $this->assertEquals( + $this->getTable("table_results.3.5"), + "Abcd" + ); + + $this->assertEquals( + $this->getTable("table_results.3.6"), + "2012-01-20 02:00:02" + ); + } + public function tearDown() + { + $this->_seleniumTasks->dbQuery('DROP DATABASE ' . $this->_dbname); + } +} diff --git a/test/selenium/PmaSeleniumTablesTest.php b/test/selenium/PmaSeleniumTablesTest.php new file mode 100644 index 0000000000..30c4d383e5 --- /dev/null +++ b/test/selenium/PmaSeleniumTablesTest.php @@ -0,0 +1,186 @@ +setBrowser(Helper::getBrowserString()); + $this->setBrowserUrl(TESTSUITE_PHPMYADMIN_HOST . TESTSUITE_PHPMYADMIN_URL); + $this->_seleniumTasks = new PmaSeleniumTestCase($this); + $this->_seleniumTasks->dbConnect(); + $this->_dbname = 'pma_db_' . time(); + $this->_seleniumTasks->dbQuery('CREATE DATABASE ' . $this->_dbname); + } + + /** + * Creates a table + * + * @return void + */ + public function testCreateTable() + { + $this->_seleniumTasks->login(TESTSUITE_USER, TESTSUITE_PASSWORD); + $this->click('link='. $this->_dbname.''); + $this->waitForElementPresent('id=create_table_form_minimal'); + $this->type( + "css=form#create_table_form_minimal input[name=\"table\"]", + "test_table" + ); + $this->type("name=num_fields", "4"); + $this->click('css=input[value="Go"]'); + $this->waitForElementPresent('name=do_save_data'); + + // column details + $column_text_details = array( + "field_0_1" => "test_id", + "field_0_3" => "14", + "field_0_10" => "comm1", + "field_1_1" => "test_column", + "field_1_3" => "10", + "field_1_10" => "comm2", + ); + + foreach ($column_text_details as $field => $val) { + $this->type("id=" . $field, $val); + } + + $column_dropdown_details = array( + "field_0_6" => "UNSIGNED", + "field_0_8" => "PRIMARY", + "field_1_2" => "VARCHAR", + "field_1_5" => "utf8_general_ci", + "field_1_4" => "As defined:" + ); + + foreach ($column_dropdown_details as $selector => $value) { + $this->select("id=" . $selector, $value); + } + + $this->type("name=field_default_value[1]", "def"); + $this->click("id=field_0_9"); // auto increment + $this->click("id=field_1_7"); // null + + // post + $this->click("name=do_save_data"); + $this->waitForElementPresent("link=test_table"); + + $this->_tableStructureAssertions(); + } + + /** + * Make assertions for table structure + * + * @return void + */ + private function _tableStructureAssertions() + { + // go to structure page + $this->click("css=a:contains(\"Structure\"):eq(1)"); + $this->waitForElementPresent("id=tablestructure"); + + // make assertions for first row + $this->assertElementContainsText( + 'css=label[for=checkbox_row_1]', + "test_id" + ); + + $this->assertEquals( + $this->getTable("tablestructure.1.3"), + "int(14)" + ); + + $this->assertEquals( + $this->getTable("tablestructure.1.5"), + "UNSIGNED" + ); + + $this->assertEquals( + $this->getTable("tablestructure.1.6"), + "No" + ); + + $this->assertEquals( + $this->getTable("tablestructure.1.7"), + "None" + ); + + $this->assertEquals( + $this->getTable("tablestructure.1.8"), + "AUTO_INCREMENT" + ); + + $this->assertElementNotPresent( + 'css=ul.table-structure-actions:eq(0) li.primary a' + ); + + // make assertions for second row + $this->assertElementContainsText( + 'css=label[for=checkbox_row_2]', + "test_column" + ); + + $this->assertEquals( + $this->getTable("tablestructure.2.3"), + "varchar(10)" + ); + + $this->assertEquals( + $this->getTable("tablestructure.2.4"), + "utf8_general_ci" + ); + + $this->assertEquals( + $this->getTable("tablestructure.2.6"), + "Yes" + ); + + $this->assertEquals( + $this->getTable("tablestructure.2.7"), + "def" + ); + + $this->assertElementPresent( + 'css=ul.table-structure-actions:eq(1) li.primary a' + ); + } + + public function tearDown() + { + $this->_seleniumTasks->dbQuery('DROP DATABASE ' . $this->_dbname); + } +} diff --git a/test/selenium/PmaSeleniumTestCase.php b/test/selenium/PmaSeleniumTestCase.php index f85f24b20a..3c0943f2ba 100644 --- a/test/selenium/PmaSeleniumTestCase.php +++ b/test/selenium/PmaSeleniumTestCase.php @@ -55,6 +55,14 @@ class PmaSeleniumTestCase */ private $_config; + /** + * mysqli object + * + * @access private + * @var object + */ + private $_mysqli; + /** * constructor * @@ -67,6 +75,7 @@ class PmaSeleniumTestCase $this->_btnLogin = 'input_go'; $this->_config = new TestConfig(); $this->_selenium = $selenium; + $this->_mysqli = null; } /** @@ -82,8 +91,8 @@ class PmaSeleniumTestCase $this->_selenium->open($this->_config->getLoginURL()); $this->_selenium->type($this->_txtUsername, $username); $this->_selenium->type($this->_txtPassword, $password); - $this->_selenium->click($this->_btnLogin); - $this->_selenium->waitForPageToLoad($this->_config->getTimeoutValue()); + $this->_selenium->clickAndWait($this->_btnLogin); + //$this->_selenium->waitForPageToLoad($this->_config->getTimeoutValue()); } /** @@ -113,5 +122,55 @@ class PmaSeleniumTestCase return false; } } + + /** + * Used to go to the homepage + * + * @return void + */ + public function gotoHomepage() + { + $this->_selenium->click("css=div#serverinfo a:contains('Server:')"); + $this->_selenium->waitForElementNotPresent('css=div#loading_parent'); + } + + /** + * Establishes a connection with the local database + * + * @return void + */ + public function dbConnect() + { + if ($this->_mysqli === null) { + list($user, $pass) = $this->_config->getDBCredentials(); + + $this->_mysqli = new mysqli( + "localhost", $user, $pass + ); + + if ($this->_mysqli->connect_errno) { + throw new Exception( + 'Failed to connect to MySQL (' . $this->_mysqli->error . ')' + ); + } + } + } + + /** + * Executes a database query + * + * @param string $query SQL Query to be executed + * + * @return void + */ + public function dbQuery($query) + { + if ($this->_mysqli === null) { + throw new Exception( + 'MySQL not connected' + ); + } + $this->_mysqli->query($query); + } } ?> diff --git a/test/selenium/TestConfig.php b/test/selenium/TestConfig.php index 5801685f57..a7a76b734e 100644 --- a/test/selenium/TestConfig.php +++ b/test/selenium/TestConfig.php @@ -29,6 +29,8 @@ class TestConfig */ private $_timeoutValue; + private $_dbCredentials; + /** * Creates a new class instance * @@ -45,6 +47,10 @@ class TestConfig $this->setTimeoutValue($searchNode->getAttribute('timeout')); } $this->setLoginURL(TESTSUITE_PHPMYADMIN_HOST . TESTSUITE_PHPMYADMIN_URL); + $this->setDBCredentials( + TESTSUITE_MYSQL_USER, + TESTSUITE_MYSQL_PASSWORD + ); } /** @@ -112,5 +118,28 @@ class TestConfig { return $this->currentBrowser; } + + /** + * Sets database credentials + * + * @param string $user DB User + * @param string $pass DB Password + * + * @return void + */ + public function setDBCredentials($user, $pass) + { + $this->_dbCredentials = array($user, $pass); + } + + /** + * Return database credentials + * + * @return array DB user and pass + */ + public function getDBCredentials() + { + return $this->_dbCredentials; + } } ?>