Initial commit

This commit is contained in:
2022-11-21 09:47:28 +01:00
commit 76cec83d26
11652 changed files with 1980467 additions and 0 deletions

View File

@ -0,0 +1,90 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for creating and deleting databases
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumCreateDropDatabaseTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumCreateDropDatabaseTest extends PMA_SeleniumBase
{
/**
* Setup the browser environment to run the selenium test case
*
* @return void
*/
public function setUp()
{
parent::setUp();
/* TODO: For now this tests needs superuser for deleting database */
$this->skipIfNotSuperUser();
}
/**
* Creates a database and drops it
*
* @return void
*
* @group large
*/
public function testCreateDropDatabase()
{
$this->login();
$this->_dropDatabase();
$this->waitForElement('byLinkText', "Databases")->click();
$this->waitForElementNotPresent('byCssSelector', 'div#loading_parent');
$element = $this->waitForElement('byId', 'text_create_db');
$element->clear();
$element->value($this->database_name);
$this->byId("buttonGo")->click();
$element = $this->waitForElement(
"byCssSelector", "span.ajax_notification div.success"
);
$this->_dropDatabase();
}
/**
* Drops a database, called after testCreateDropDatabase
*
* @return void
*/
private function _dropDatabase()
{
$this->gotoHomepage();
$this->byLinkText("Databases")->click();
$this->waitForElementNotPresent('byCssSelector', 'div#loading_parent');
$this->byCssSelector(
"input[name='selected_dbs[]'][value='" . $this->database_name . "']"
)->click();
$this->byCssSelector("button.mult_submit")->click();
$this->byCssSelector("span.ui-button-text:nth-child(1)")->click();
$this->waitForElementNotPresent(
"byCssSelector",
"input[name='selected_dbs[]'][value='" . $this->database_name . "']"
);
$this->waitForElement(
"byCssSelector", "span.ajax_notification div.success"
);
}
}

View File

@ -0,0 +1,105 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for user related tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumCreateRemoveUserTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumCreateRemoveUserTest extends PMA_SeleniumBase
{
/**
* Username for the user
*
* @access private
* @var string
*/
private $_txtUsername;
/**
* Password for the user
*
* @access private
* @var string
*/
private $_txtPassword;
/**
* Setup the browser environment to run the selenium test case
*
* @return void
*/
public function setUp()
{
parent::setUp();
$this->skipIfNotSuperUser();
$this->_txtUsername = 'pma_user';
$this->_txtPassword = 'abc_123';
}
/**
* Creates and removes a user
*
* @return void
*
* @group large
*/
public function testCreateRemoveUser()
{
$this->login();
$this->waitForElement('byLinkText', "Users")->click();
$link = $this->waitForElement("byId", "add_user_anchor");
$link->click();
$userField = $this->waitForElement("byName", "username");
$userField->value($this->_txtUsername);
$select = $this->select($this->byId("select_pred_hostname"));
$select->selectOptionByLabel("Local");
$this->byId("button_generate_password")->click();
$this->assertNotEquals("", $this->byId("text_pma_pw")->value());
$this->assertNotEquals("", $this->byId("text_pma_pw2")->value());
$this->assertNotEquals("", $this->byId("generated_pw")->value());
$this->byId("text_pma_pw")->value($this->_txtPassword);
$this->byId("text_pma_pw2")->value($this->_txtPassword);
$this->byId("createdb-1")->click();
$this->byId("createdb-2")->click();
$this->byId("addUsersForm_checkall")->click();
$this->byName("adduser_submit")->click();
$success = $this->waitForElement("byCssSelector", "div.success");
$this->assertContains('You have added a new user', $success->text());
$this->waitForElement('byLinkText', "Users")->click();
$el = $this->waitForElement("byId", "usersForm");
$temp = $this->_txtUsername . "&amp;#27;localhost";
$this->byXPath(
"(//input[@name='selected_usr[]'])[@value='" . $temp . "']"
)->click();
$this->byId("checkbox_drop_users_db")->click();
$this->byId("buttonGo")->click();
$this->waitForElement("byCssSelector", "button.confirmOK")->click();
$this->acceptAlert();
$success = $this->waitForElement("byCssSelector", "div.success");
$this->assertContains(
'The selected users have been deleted',
$success->text()
);
}
}

View File

@ -0,0 +1,212 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for table related tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumDbEventsTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumDbEventsTest extends PMA_SeleniumBase
{
/**
* Setup the browser environment to run the selenium test case
*
* @return void
*/
public function setUp()
{
parent::setUp();
$this->dbQuery(
"CREATE TABLE `test_table` ("
. " `id` int(11) NOT NULL AUTO_INCREMENT,"
. " `val` int(11) NOT NULL,"
. " PRIMARY KEY (`id`)"
. ")"
);
$this->dbQuery(
"INSERT INTO `test_table` (val) VALUES (2);"
);
}
/**
* setUp function that can use the selenium session (called before each test)
*
* @return void
*/
public function setUpPage()
{
$this->login();
$this->waitForElement('byLinkText', $this->database_name)->click();
$this->waitForElement(
"byXPath", "//a[contains(., 'test_table')]"
);
$this->expandMore();
}
/**
* Creates procedure for tests
*
* @return void
*/
private function _eventSQL()
{
$start = date('Y-m-d H:i:s', strtotime('-1 day'));
$end = date('Y-m-d H:i:s', strtotime('+1 day'));
$this->dbQuery(
"CREATE EVENT `test_event` ON SCHEDULE EVERY 2 MINUTE_SECOND STARTS "
. "'$start' ENDS '$end' ON COMPLETION NOT PRESERVE ENABLE "
. "DO UPDATE `" . $this->database_name
. "`.`test_table` SET val = val + 1"
);
}
/**
* Create an event
*
* @return void
*
* @group large
*/
public function testAddEvent()
{
$ele = $this->waitForElement("byPartialLinkText", "Events");
$ele->click();
$ele = $this->waitForElement("byLinkText", "Add event");
$ele->click();
$this->waitForElement("byClassName", "rte_form");
$this->byName("item_name")->value("test_event");
$this->select($this->byName("item_type"))
->selectOptionByLabel("RECURRING");
$this->byName("item_interval_value")->value("1");
$this->select($this->byName("item_interval_field"))
->selectOptionByLabel("MINUTE_SECOND");
$this->byName("item_starts")
->value(date('Y-m-d H:i:s', strtotime('-1 day')));
$this->byName("item_ends")
->value(date('Y-m-d H:i:s', strtotime('+1 day')));
$proc = "UPDATE " . $this->database_name . ".`test_table` SET val=val+1";
$this->typeInTextArea($proc);
$this->byXPath("//button[contains(., 'Go')]")->click();
$ele = $this->waitForElement(
"byXPath",
"//div[@class='success' and contains(., "
. "'Event `test_event` has been created')]"
);
$this->assertTrue(
$this->isElementPresent(
'byXPath',
"//td[contains(., 'test_event')]"
)
);
$result = $this->dbQuery(
"SHOW EVENTS WHERE Db='" . $this->database_name
. "' AND Name='test_event'"
);
$this->assertEquals(1, $result->num_rows);
usleep(2200000);
$result = $this->dbQuery(
"SELECT val FROM `" . $this->database_name . "`.`test_table`"
);
$row = $result->fetch_assoc();
$this->assertGreaterThan(2, $row['val']);
}
/**
* Test for editing events
*
* @return void
*
* @group large
*/
public function testEditEvents()
{
$this->_eventSQL();
$ele = $this->waitForElement("byPartialLinkText", "Events");
$ele->click();
$this->waitForElement(
"byXPath",
"//legend[contains(., 'Events')]"
);
$this->byLinkText("Edit")->click();
$this->waitForElement("byClassName", "rte_form");
$this->byName("item_interval_value")->clear();
$this->byName("item_interval_value")->value("1");
$this->typeInTextArea("00");
$this->byXPath("//button[contains(., 'Go')]")->click();
$ele = $this->waitForElement(
"byXPath",
"//div[@class='success' and contains(., "
. "'Event `test_event` has been modified')]"
);
usleep(2000000);
$result = $this->dbQuery(
"SELECT val FROM `" . $this->database_name . "`.`test_table`"
);
$row = $result->fetch_assoc();
$this->assertGreaterThan(100, $row['val']);
}
/**
* Test for dropping event
*
* @return void
*
* @group large
*/
public function testDropEvent()
{
$this->_eventSQL();
$this->waitForElement("byPartialLinkText", "Events")->click();
$this->waitForElement(
"byXPath",
"//legend[contains(., 'Events')]"
);
$this->byLinkText("Drop")->click();
$this->waitForElement(
"byXPath", "//button[contains(., 'OK')]"
)->click();
$this->waitForElement("byId", "nothing2display");
usleep(1000000);
$result = $this->dbQuery(
"SHOW EVENTS WHERE Db='" . $this->database_name
. "' AND Name='test_event'"
);
$this->assertEquals(0, $result->num_rows);
}
}

View File

@ -0,0 +1,128 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for table related tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumDbOperationsTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumDbOperationsTest extends PMA_SeleniumBase
{
/**
* setUp function that can use the selenium session (called before each test)
*
* @return void
*/
public function setUpPage()
{
$this->login();
$this->waitForElement('byLinkText', $this->database_name)->click();
$this->waitForElement("byLinkText", "Structure");
$this->expandMore();
$this->waitForElement("byLinkText", "Operations")->click();
$this->waitForElement(
"byXPath", "//legend[contains(., 'Rename database to')]"
);
}
/**
* Test for adding database comment
*
* @return void
*
* @group large
*/
public function testDbComment()
{
$this->skipIfNotPMADB();
$this->byName("comment")->value("comment_foobar");
$this->byCssSelector(
"form#formDatabaseComment input[type='submit']"
)->click();
$this->assertNotNull(
$this->waitForElement(
"byXPath",
"//span[@id='span_table_comment' and contains(., 'comment_foobar')]"
)
);
}
/**
* Test for renaming database
*
* @return void
*
* @group large
*/
public function testRenameDB()
{
$new_db_name = $this->database_name . 'rename';
$this->byCssSelector("form#rename_db_form input[name=newname]")
->value($new_db_name);
$this->byCssSelector("form#rename_db_form input[type='submit']")->click();
$this->waitForElement(
"byXPath", "//button[contains(., 'OK')]"
)->click();
$this->waitForElement(
"byXPath",
"//a[@class='item' and contains(., 'Database: $new_db_name')]"
);
$result = $this->dbQuery(
"SHOW DATABASES LIKE '$new_db_name';"
);
$this->assertEquals(1, $result->num_rows);
$result = $this->dbQuery(
"SHOW DATABASES LIKE '" . $this->database_name . "';"
);
$this->assertEquals(0, $result->num_rows);
$this->database_name = $new_db_name;
}
/**
* Test for copying database
*
* @return void
*
* @group large
*/
public function testCopyDb()
{
$new_db_name = $this->database_name . 'copy';
$this->byCssSelector("form#copy_db_form input[name=newname]")
->value($new_db_name);
$this->byCssSelector("form#copy_db_form input[type='submit']")->click();
$this->waitForElement(
"byXPath",
"//div[@class='success' and contains(., 'Database "
. $this->database_name
. " has been copied to $new_db_name')]"
);
$result = $this->dbQuery(
"SHOW DATABASES LIKE '$new_db_name';"
);
$this->assertEquals(1, $result->num_rows);
$this->dbQuery("DROP DATABASE $new_db_name");
}
}

View File

@ -0,0 +1,211 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for table related tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumDbProceduresTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumDbProceduresTest extends PMA_SeleniumBase
{
/**
* Setup the browser environment to run the selenium test case
*
* @return void
*/
public function setUp()
{
parent::setUp();
$this->dbQuery(
"CREATE TABLE `test_table` ("
. " `id` int(11) NOT NULL AUTO_INCREMENT,"
. " `name` varchar(20) NOT NULL,"
. " `datetimefield` datetime NOT NULL,"
. " PRIMARY KEY (`id`)"
. ")"
);
}
/**
* setUp function that can use the selenium session (called before each test)
*
* @return void
*/
public function setUpPage()
{
$this->login();
$this->waitForElement('byLinkText', $this->database_name)->click();
$this->waitForElement(
"byXPath", "//a[contains(., 'test_table')]"
);
$this->expandMore();
}
/**
* Creates procedure for tests
*
* @return void
*/
private function _procedureSQL()
{
$this->dbQuery(
"CREATE PROCEDURE `test_procedure`(IN `inp` VARCHAR(10), OUT `outp` INT)"
. " NOT DETERMINISTIC READS SQL DATA SQL SECURITY DEFINER SELECT char_"
. "length(inp) + count(*) FROM test_table INTO outp"
);
}
/**
* Create a procedure
*
* @return void
*
* @group large
*/
public function testAddProcedure()
{
$ele = $this->waitForElement("byPartialLinkText", "Routines");
$ele->click();
$ele = $this->waitForElement("byLinkText", "Add routine");
$ele->click();
$this->waitForElement("byClassName", "rte_form");
$this->byName("item_name")->value("test_procedure");
$this->byName("item_param_name[0]")->value("inp");
$this->select(
$this->byName("item_param_type[0]")
)->selectOptionByLabel("VARCHAR");
$this->byName("item_param_length[0]")->value("10");
$this->byCssSelector("input[value='Add parameter']")->click();
$this->select(
$this->byName("item_param_dir[1]")
)->selectOptionByLabel("OUT");
$ele = $this->waitForElement("byName", "item_param_name[1]");
$ele->value("outp");
$proc = "SELECT char_length(inp) + count(*) FROM test_table INTO outp";
$this->typeInTextArea($proc);
$this->select(
$this->byName("item_sqldataaccess")
)->selectOptionByLabel("READS SQL DATA");
$this->byXPath("//button[contains(., 'Go')]")->click();
$ele = $this->waitForElement(
"byXPath",
"//div[@class='success' and contains(., "
. "'Routine `test_procedure` has been created')]"
);
$result = $this->dbQuery(
"SHOW PROCEDURE STATUS WHERE Db='" . $this->database_name . "'"
);
$this->assertEquals(1, $result->num_rows);
$this->_executeProcedure("abcabcabcabcabcabcabc", 10);
}
/**
* Test for editing procedure
*
* @return void
*
* @group large
*/
public function testEditProcedure()
{
$this->_procedureSQL();
$ele = $this->waitForElement("byPartialLinkText", "Routines");
$ele->click();
$this->waitForElement(
"byXPath",
"//legend[contains(., 'Routines')]"
);
$this->byLinkText("Edit")->click();
$this->waitForElement("byClassName", "rte_form");
$this->byName("item_param_length[0]")->clear();
$this->byName("item_param_length[0]")->value("12");
$this->byXPath("//button[contains(., 'Go')]")->click();
$ele = $this->waitForElement(
"byXPath",
"//div[@class='success' and contains(., "
. "'Routine `test_procedure` has been modified')]"
);
$this->_executeProcedure("abcabcabcabcabcabcabc", 12);
}
/**
* Test for dropping procedure
*
* @return void
*
* @group large
*/
public function testDropProcedure()
{
$this->_procedureSQL();
$ele = $this->waitForElement("byPartialLinkText", "Routines");
$ele->click();
$this->waitForElement(
"byXPath",
"//legend[contains(., 'Routines')]"
);
$this->byLinkText("Drop")->click();
$this->waitForElement(
"byXPath", "//button[contains(., 'OK')]"
)->click();
$this->waitForElement("byId", "nothing2display");
usleep(1000000);
$result = $this->dbQuery(
"SHOW PROCEDURE STATUS WHERE Db='" . $this->database_name . "'"
);
$this->assertEquals(0, $result->num_rows);
}
/**
* Execute procedure
*
* @param string $text String to pass as inp param
* @param int $length Expected output length
*
* @return void
*/
private function _executeProcedure($text, $length)
{
$this->waitForElement("byLinkText", "Execute")->click();
$this->waitForElement("byName", "params[inp]")->value($text);
$this->byCssSelector("div.ui-dialog-buttonset button:nth-child(1)")->click();
$this->waitForElement(
"byCssSelector",
"span#PMA_slidingMessage table tbody"
);
$head = $this->byCssSelector("span#PMA_slidingMessage table tbody")->text();
$this->assertEquals("outp\n$length", $head);
}
}

View File

@ -0,0 +1,119 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for table related tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumDbStructureTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumDbStructureTest extends PMA_SeleniumBase
{
/**
* Setup the browser environment to run the selenium test case
*
* @return void
*/
public function setUp()
{
parent::setUp();
$this->dbQuery(
"CREATE TABLE `test_table` ("
. " `id` int(11) NOT NULL AUTO_INCREMENT,"
. " `val` int(11) NOT NULL,"
. " PRIMARY KEY (`id`)"
. ")"
);
$this->dbQuery(
"CREATE TABLE `test_table2` ("
. " `id` int(11) NOT NULL AUTO_INCREMENT,"
. " `val` int(11) NOT NULL,"
. " PRIMARY KEY (`id`)"
. ")"
);
$this->dbQuery(
"INSERT INTO `test_table` (val) VALUES (2);"
);
}
/**
* setUp function that can use the selenium session (called before each test)
*
* @return void
*/
public function setUpPage()
{
$this->login();
$this->waitForElement('byLinkText', $this->database_name)->click();
$this->waitForElement(
'byCssSelector',
'li.last.table'
);
$this->waitForElement(
"byXPath", "//a[contains(., 'test_table')]"
);
}
/**
* Test for truncating a table
*
* @return void
*
* @group large
*/
public function testTruncateTable()
{
$this->byXPath("(//a[contains(., 'Empty')])[1]")->click();
$this->waitForElement(
"byXPath",
"//button[contains(., 'OK')]"
)->click();
$this->assertNotNull(
$this->waitForElement(
"byXPath",
"//div[@class='success' and contains(., "
. "'MySQL returned an empty result')]"
)
);
$result = $this->dbQuery("SELECT count(*) as c FROM test_table");
$row = $result->fetch_assoc();
$this->assertEquals(0, $row['c']);
}
/**
* Tests for dropping multiple tables
*
* @return void
*
* @group large
*/
public function testDropMultipleTables()
{
$this->byCssSelector("label[for='tablesForm_checkall']")->click();
$this->select($this->byName("submit_mult"))
->selectOptionByLabel("Drop");
$this->waitForElement("byId", "buttonYes")
->click();
$this->waitForElement(
"byXPath",
"//p[contains(., 'No tables found in database')]"
);
$result = $this->dbQuery("SHOW TABLES;");
$this->assertEquals(0, $result->num_rows);
}
}

View File

@ -0,0 +1,205 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for table related tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumDbTriggersTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumDbTriggersTest extends PMA_SeleniumBase
{
/**
* Setup the browser environment to run the selenium test case
*
* @return void
*/
public function setUp()
{
parent::setUp();
$this->dbQuery(
"CREATE TABLE `test_table` ("
. " `id` int(11) NOT NULL AUTO_INCREMENT,"
. " `val` int(11) NOT NULL,"
. " PRIMARY KEY (`id`)"
. ")"
);
$this->dbQuery(
"CREATE TABLE `test_table2` ("
. " `id` int(11) NOT NULL AUTO_INCREMENT,"
. " `val` int(11) NOT NULL,"
. " PRIMARY KEY (`id`)"
. ")"
);
$this->dbQuery(
"INSERT INTO `test_table2` (val) VALUES (2);"
);
}
/**
* setUp function that can use the selenium session (called before each test)
*
* @return void
*/
public function setUpPage()
{
$this->login();
$this->waitForElement('byLinkText', $this->database_name)->click();
$this->waitForElement(
"byXPath", "//a[contains(., 'test_table')]"
);
$this->expandMore();
}
/**
* Creates procedure for tests
*
* @return void
*/
private function _triggerSQL()
{
$this->dbQuery(
"CREATE TRIGGER `test_trigger` "
. "AFTER INSERT ON `test_table` FOR EACH ROW"
. " UPDATE `" . $this->database_name
. "`.`test_table2` SET val = val + 1"
);
}
/**
* Create a Trigger
*
* @return void
*
* @group large
*/
public function testAddTrigger()
{
$ele = $this->waitForElement("byPartialLinkText", "Triggers");
$ele->click();
$ele = $this->waitForElement("byLinkText", "Add trigger");
$ele->click();
$this->waitForElement("byClassName", "rte_form");
$this->byName("item_name")->value("test_trigger");
$this->select($this->byName("item_table"))
->selectOptionByLabel("test_table");
$this->select($this->byName("item_timing"))
->selectOptionByLabel("AFTER");
$this->select($this->byName("item_event"))
->selectOptionByLabel("INSERT");
$proc = "UPDATE " . $this->database_name . ".`test_table2` SET val=val+1";
$this->typeInTextArea($proc);
$this->byXPath("//button[contains(., 'Go')]")->click();
$ele = $this->waitForElement(
"byXPath",
"//div[@class='success' and contains(., "
. "'Trigger `test_trigger` has been created')]"
);
$this->assertTrue(
$this->isElementPresent(
'byXPath',
"//td[contains(., 'test_trigger')]"
)
);
$result = $this->dbQuery(
"SHOW TRIGGERS FROM `" . $this->database_name . "`;"
);
$this->assertEquals(1, $result->num_rows);
// test trigger
$this->dbQuery("INSERT INTO `test_table` (val) VALUES (1);");
$result = $this->dbQuery("SELECT val FROM `test_table2`;");
$row = $result->fetch_assoc();
$this->assertEquals(3, $row['val']);
}
/**
* Test for editing Triggers
*
* @return void
*
* @group large
*/
public function testEditTriggers()
{
$this->_triggerSQL();
$ele = $this->waitForElement("byPartialLinkText", "Triggers");
$ele->click();
$this->waitForElement(
"byXPath",
"//legend[contains(., 'Triggers')]"
);
$this->byLinkText("Edit")->click();
$this->waitForElement("byClassName", "rte_form");
$this->typeInTextArea("0");
$this->byXPath("//button[contains(., 'Go')]")->click();
$ele = $this->waitForElement(
"byXPath",
"//div[@class='success' and contains(., "
. "'Trigger `test_trigger` has been modified')]"
);
// test trigger
$this->dbQuery("INSERT INTO `test_table` (val) VALUES (1);");
$result = $this->dbQuery("SELECT val FROM `test_table2`;");
$row = $result->fetch_assoc();
$this->assertEquals(12, $row['val']);
}
/**
* Test for dropping Trigger
*
* @return void
*
* @group large
*/
public function testDropTrigger()
{
$this->_triggerSQL();
$ele = $this->waitForElement("byPartialLinkText", "Triggers");
$ele->click();
$this->waitForElement(
"byXPath",
"//legend[contains(., 'Triggers')]"
);
$this->byLinkText("Drop")->click();
$this->waitForElement(
"byXPath", "//button[contains(., 'OK')]"
)->click();
$this->waitForElement("byId", "nothing2display");
$result = $this->dbQuery(
"SHOW TRIGGERS FROM `" . $this->database_name . "`;"
);
$this->assertEquals(0, $result->num_rows);
}
}

View File

@ -0,0 +1,208 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for export related tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumExportTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumExportTest extends PMA_SeleniumBase
{
/**
* Setup the browser environment to run the selenium test case
*
* @return void
*/
public function setUp()
{
parent::setUp();
$this->dbQuery(
"CREATE TABLE `test_table` ("
. " `id` int(11) NOT NULL AUTO_INCREMENT,"
. " `val` int(11) NOT NULL,"
. " PRIMARY KEY (`id`)"
. ")"
);
$this->dbQuery(
"INSERT INTO `test_table` (val) VALUES (2);"
);
}
/**
* setUp function that can use the selenium session (called before each test)
*
* @return void
*/
public function setUpPage()
{
$this->login();
}
/**
* Test for server level export
*
* @param string $plugin Export format
* @param array $expected Array of expected strings
*
* @return void
* @dataProvider exportDataProvider
*
* @group large
*/
public function testServerImport($plugin, $expected)
{
$text = $this->_doExport('server', $plugin);
foreach ($expected as $str) {
$this->assertContains($str, $text);
}
}
/**
* Test for db level export
*
* @param string $plugin Export format
* @param array $expected Array of expected strings
*
* @return void
* @dataProvider exportDataProvider
*
* @group large
*/
public function testDbExport($plugin, $expected)
{
$this->waitForElement("byLinkText", $this->database_name)->click();
$this->waitForElement(
"byXPath",
"//a[@class='item' and contains(., 'Database: "
. $this->database_name . "')]"
);
$text = $this->_doExport('db', $plugin);
foreach ($expected as $str) {
$this->assertContains($str, $text);
}
}
/**
* Test for table level export
*
* @param string $plugin Export format
* @param array $expected Array of expected strings
*
* @return void
* @dataProvider exportDataProvider
*
* @group large
*/
public function testTableExport($plugin, $expected)
{
$this->dbQuery("INSERT INTO `test_table` (val) VALUES (3);");
$this->navigateTable('test_table');
$text = $this->_doExport('table', $plugin);
foreach ($expected as $str) {
$this->assertContains($str, $text);
}
}
/**
* Data provider for testServerExport
*
* @return array Test cases data
*/
public function exportDataProvider()
{
return array(
array(
'CSV',
array('"1","2"')
),
array(
'SQL',
array(
"CREATE TABLE IF NOT EXISTS `test_table`",
"INSERT INTO `test_table` (`id`, `val`) VALUES",
"(1, 2);"
)
),
array(
'JSON',
array('[{"id":"1","val":"2"}]')
)
);
}
/**
* Function that goes to the import page, uploads a file and submit form
*
* @param string $type level: server, db or import
* @param string $plugin format: csv, json, etc
*
* @return string export string
*/
private function _doExport($type, $plugin)
{
$this->expandMore();
$this->waitForElement('byLinkText', "Export")->click();
$this->sleep();
$this->waitForElement("byId", "quick_or_custom");
/*
* FIXME: There should be better way to wait for javascript to be executed
*/
$this->sleep();
$this->byCssSelector("label[for=radio_custom_export]")->click();
if ($type == 'server') {
$this->byLinkText('Unselect all')->click();
$this->byCssSelector(
"option[value=" . $this->database_name . "]"
)->click();
}
if ($type == 'table') {
$this->byCssSelector("label[for=radio_allrows_0]")->click();
$this->sleep();
$this->byName("limit_to")->clear();
$this->byName("limit_to")->value("1");
}
$this->select($this->byId("plugins"))->selectOptionByLabel($plugin);
$this->byCssSelector("label[for=radio_view_as_text]")->click();
if ($plugin == "SQL") {
$this->byCssSelector(
"label[for=radio_sql_structure_or_data_structure_and_data]"
)->click();
if ($type != "table") {
$this->byCssSelector(
"label[for=checkbox_sql_create_database]"
)->click();
}
}
$this->byId("buttonGo")->click();
$text = $this->waitForElement("byId", "textSQLDUMP")->text();
return $text;
}
}

View File

@ -0,0 +1,121 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for import related tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumImportTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumImportTest extends PMA_SeleniumBase
{
/**
* setUp function that can use the selenium session (called before each test)
*
* @return void
*/
public function setUpPage()
{
$this->login();
}
/**
* Test for server level import
*
* @return void
*
* @group large
*/
public function testServerImport()
{
$this->_doImport('server');
$result = $this->dbQuery("SHOW DATABASES LIKE 'test_import%'");
$this->assertGreaterThanOrEqual(2, $result->num_rows);
// clear db
$this->dbQuery("DROP DATABASE test_import1");
$this->dbQuery("DROP DATABASE test_import2");
}
/**
* Test for db level import
*
* @return void
*
* @group large
*/
public function testDbImport()
{
$this->dbQuery("CREATE DATABASE " . $this->database_name);
$this->waitForElement("byLinkText", $this->database_name)->click();
$this->waitForElement(
"byXPath",
"//a[@class='item' and contains(., 'Database: "
. $this->database_name . "')]"
);
$this->_doImport("db");
$this->dbQuery("USE " . $this->database_name);
$result = $this->dbQuery("SHOW TABLES");
$this->assertEquals(1, $result->num_rows);
}
/**
* Test for table level import
*
* @return void
*
* @group large
*/
public function testTableImport()
{
// setup the db
$this->dbQuery("CREATE DATABASE " . $this->database_name);
$this->dbQuery("USE " . $this->database_name);
$this->dbQuery(
"CREATE TABLE IF NOT EXISTS `test_table` (`val` int(11) NOT NULL)"
);
$this->navigateTable('test_table');
$this->_doImport("table");
$result = $this->dbQuery("SELECT * FROM test_table");
$this->assertEquals(2, $result->num_rows);
}
/**
* Function that goes to the import page, uploads a file and submit form
*
* @param string $type level: server, db or import
*
* @return void
*/
private function _doImport($type)
{
/* FIXME: Need to implement file upload compatible with remote Selenium */
$this->markTestIncomplete(
'File uploading not yet implemented in Selenium test'
);
$this->waitForElement('byLinkText', "Import")->click();
$ele = $this->waitForElement("byId", "input_import_file");
$ele->value(
dirname(__FILE__) . "/../test_data/" . $type . "_import.sql"
);
$this->byId("buttonGo")->click();
$this->waitForElement(
"byXPath",
"//div[@class='success' and contains(., 'Import has been successfully')]"
);
}
}

View File

@ -0,0 +1,51 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for login related tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumLoginTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumLoginTest extends PMA_SeleniumBase
{
/**
* Test for successful login
*
* @return void
*
* @group large
*/
public function testSuccessfulLogin()
{
$this->logOutIfLoggedIn();
$this->login();
$this->waitForElement("byXPath", "//*[@id=\"serverinfo\"]");
$this->assertTrue($this->isSuccessLogin());
$this->logOutIfLoggedIn();
}
/**
* Test for unsuccessful login
*
* @return void
*
* @group large
*/
public function testLoginWithWrongPassword()
{
$this->logOutIfLoggedIn();
$this->login("Admin", "Admin");
$this->waitForElement("byCssSelector", "div.error");
$this->assertTrue($this->isUnsuccessLogin());
}
}

View File

@ -0,0 +1,168 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for normalization
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PMA_SeleniumNormalizationTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumNormalizationTest extends PMA_SeleniumBase
{
/**
* Setup the browser environment to run the selenium test case
*
* @return void
*/
public function setUp()
{
parent::setUp();
$this->dbQuery(
"CREATE TABLE `test_table` ("
. " `id` int(11) NOT NULL AUTO_INCREMENT,"
. " `val` int(11) NOT NULL,"
. " `val2` varchar(64) NOT NULL,"
. "PRIMARY KEY(id)"
. ")"
);
}
/**
* setUp function that can use the selenium session
*
* @return void
*/
public function setUpPage()
{
$this->login();
$this->navigateTable('test_table');
$this->waitForElement(
"byXPath",
"(//a[contains(., 'Structure')])"
)->click();
$this->waitForElement("byId", "tablestructure");
$this->byLinkText('Improve table structure')->click();
$this->waitForElement("byId", "normalizeTable");
}
/**
* Test for normalization to 1NF
*
* @return void
*
* @group large
*/
public function testNormalizationTo1NF()
{
$this->assertTrue(
$this->isElementPresent('byCssSelector', 'fieldset')
);
$this->assertEquals(
"First step of normalization (1NF)",
$this->byCssSelector('label[for=normalizeTo_1nf]')->text()
);
$this->assertTrue(
$this->isElementPresent(
'byCssSelector', 'input[id=normalizeTo_1nf][type=radio]:checked'
)
);
$this->byCssSelector('input[name=submit_normalize]')->click();
$this->waitForElement('byId', 'mainContent');
$this->_test1NFSteps();
}
/**
* assertions in 1NF steps 1.1, 1.2, 1.3
*
* @return void
*/
private function _test1NFSteps()
{
$this->assertEquals(
"First step of normalization (1NF)",
$this->byCssSelector('#page_content h3')->text()
);
$this->assertTrue(
$this->isElementPresent(
'byCssSelector', '#mainContent h4'
)
);
$this->assertTrue(
$this->isElementPresent(
'byCssSelector', '#mainContent #newCols'
)
);
$this->assertTrue(
$this->isElementPresent(
'byCssSelector', '.tblFooters'
)
);
$this->assertTrue(
$this->isElementPresent(
'byCssSelector', '#selectNonAtomicCol option[value=val2]'
)
);
$this->assertFalse(
$this->isElementPresent(
'byCssSelector', '#selectNonAtomicCol option[value=val]'
)
);
$this->assertTrue(
$this->isElementPresent(
'byCssSelector', '#selectNonAtomicCol option[value=no_such_col]'
)
);
$this->select(
$this->byId('selectNonAtomicCol')
)->selectOptionByValue('no_such_col');
$this->waitForElement(
"byXPath",
"//legend[contains(., 'Step 1.2 Have a primary key')]"
);
$text = $this->byCssSelector("#mainContent h4")->text();
$this->assertContains("Primary key already exists.", $text);
$this->waitForElement(
"byXPath",
"//legend[contains(., 'Step 1.3 Move repeating groups')]"
);
$this->byCssSelector('input[value="No repeating group"]')->click();
$this->waitForElement(
"byXPath",
"//legend[contains(., 'Step 1.4 Remove redundant columns')]"
);
$this->assertTrue(
$this->isElementPresent(
'byCssSelector', '#mainContent #extra'
)
);
$this->assertTrue(
$this->isElementPresent(
'byCssSelector', '#extra input[value=val2][type=checkbox]'
)
);
$this->assertTrue(
$this->isElementPresent(
'byCssSelector', '#extra input[value=id][type=checkbox]'
)
);
$this->byCssSelector('#extra input[value=val][type=checkbox]')->click();
$this->byCssSelector("#removeRedundant")->click();
$this->waitForElement(
"byXPath",
"//legend[contains(., 'End of step')]"
);
$this->assertContains(
"The first step of normalization is complete for table 'test_table'.",
$this->byCssSelector("#mainContent h4")->text()
);
}
}

View File

@ -0,0 +1,73 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for privilege related tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumPrivilegesTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumPrivilegesTest extends PMA_SeleniumBase
{
/**
* Tests the changing of the password
*
* @return void
*
* @group large
*/
public function testChangePassword()
{
$this->login();
$this->waitForElement('byLinkText', "Change password")->click();
$e = $this->waitForElement("byId", "change_password_anchor");
try {
$ele = $this->waitForElement("byId", "text_pma_pw");
$this->assertEquals("", $ele->value());
} catch (PHPUnit_Framework_AssertionFailedError $e) {
array_push($this->verificationErrors, $e->toString());
}
try {
$ele = $this->waitForElement("byId", "text_pma_pw2");
$this->assertEquals("", $ele->value());
} catch (PHPUnit_Framework_AssertionFailedError $e) {
array_push($this->verificationErrors, $e->toString());
}
try {
$ele = $this->waitForElement("byId", "generated_pw");
$this->assertEquals("", $ele->value());
} catch (PHPUnit_Framework_AssertionFailedError $e) {
array_push($this->verificationErrors, $e->toString());
}
$this->byId("button_generate_password")->click();
$this->assertNotEquals("", $this->byId("text_pma_pw")->value());
$this->assertNotEquals("", $this->byId("text_pma_pw2")->value());
$this->assertNotEquals("", $this->byId("generated_pw")->value());
if ($GLOBALS['TESTSUITE_PASSWORD'] != "") {
$this->byId("text_pma_pw")->clear();
$this->byId("text_pma_pw2")->clear();
$this->byId("text_pma_pw")->value($GLOBALS['TESTSUITE_PASSWORD']);
$this->byId("text_pma_pw2")->value($GLOBALS['TESTSUITE_PASSWORD']);
} else {
$this->byId("nopass_1")->click();
}
$this->byCssSelector("span.ui-button-text:nth-child(1)")->click();
$ele = $this->waitForElement("byCssSelector", "div.success");
$this->assertEquals(
"The profile has been updated.",
$ele->text()
);
}
}

View File

@ -0,0 +1,134 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for settings related tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumServerSettingsTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumSettingsTest extends PMA_SeleniumBase
{
/**
* setUp function that can use the selenium session (called before each test)
*
* @return void
*/
public function setUpPage()
{
$this->login();
$this->expandMore();
$this->waitForElement("byLinkText", "Settings")->click();
$this->waitForElement(
"byXPath", "//a[@class='tabactive' and contains(., 'Settings')]"
);
$this->sleep();
}
/**
* Saves config and asserts correct message.
*
* @return void
*/
private function _saveConfig()
{
$this->byName("submit_save")->click();
$this->sleep();
$this->waitForElement(
"byXPath",
"//div[@class='success' and contains(., 'Configuration has been saved')]"
);
}
/**
* Tests whether hiding a database works or not
*
* @return void
*
* @group large
*/
public function testHideDatabase()
{
/* FIXME: This test fails even though it is same as testHideLogo */
$this->markTestIncomplete('Currently broken');
$this->byLinkText("Features")->click();
$this->waitForElement("byName", "Servers-1-hide_db")
->value($this->database_name);
$this->_saveConfig();
$this->assertFalse(
$this->isElementPresent("byLinkText", $this->database_name)
);
$this->waitForElement("byName", "Servers-1-hide_db")->clear();
$this->_saveConfig();
$this->assertTrue(
$this->isElementPresent("byLinkText", $this->database_name)
);
}
/**
* Tests whether the various settings tabs are displayed when clicked
*
* @return void
*
* @group large
*/
public function testSettingsTabsAreDisplayed()
{
$this->byLinkText("SQL queries")->click();
$this->waitForElement('byClassName', 'tabs');
$this->byLinkText("SQL Query box")->click();
$this->assertTrue(
$this->byId("Sql_box")->displayed()
);
$this->assertFalse(
$this->byId("Sql_queries")->displayed()
);
$this->byCssSelector("a[href='#Sql_queries']")->click();
$this->assertFalse(
$this->byId("Sql_box")->displayed()
);
$this->assertTrue(
$this->byId("Sql_queries")->displayed()
);
}
/**
* Tests if hiding the logo works or not
*
* @return void
*
* @group large
*/
public function testHideLogo()
{
$this->byLinkText("Navigation panel")->click();
$this->waitForElement("byName", "NavigationDisplayLogo")
->click();
$this->_saveConfig();
$this->assertFalse(
$this->isElementPresent("byId", "imgpmalogo")
);
$this->byCssSelector("a[href='#NavigationDisplayLogo']")->click();
$this->_saveConfig();
$this->assertTrue(
$this->isElementPresent("byId", "imgpmalogo")
);
}
}

View File

@ -0,0 +1,344 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for table related tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumTableBrowseTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumTableBrowseTest extends PMA_SeleniumBase
{
/**
* Setup the browser environment to run the selenium test case
*
* @return void
*/
public function setUp()
{
parent::setUp();
$this->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->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')"
);
}
/**
* setUp function that can use the selenium session (called before each test)
*
* @return void
*/
public function setUpPage()
{
$this->login();
$this->navigateTable('test_table');
}
/**
* Test sorting of records in browse table
*
* @return void
*
* @group large
*/
public function testSortRecords()
{
/* TODO: needs to be fixed */
$this->markTestIncomplete(
'Does not work with multi column sorting.'
);
// case 1
$this->byLinkText("name")->click();
$this->waitForElementNotPresent("byId", "loading_parent");
$this->sleep();
$this->assertEquals(
"1",
$this->getCellByTableClass('table_results', 1, 5)
);
$this->assertEquals(
"3",
$this->getCellByTableClass('table_results', 2, 5)
);
$this->assertEquals(
"2",
$this->getCellByTableClass('table_results', 3, 5)
);
// case 2
$this->byLinkText("name")->click();
$this->waitForElementNotPresent("byId", "loading_parent");
$this->sleep();
$this->assertEquals(
"2",
$this->getCellByTableClass('table_results', 1, 5)
);
$this->assertEquals(
"1",
$this->getCellByTableClass('table_results', 2, 5)
);
$this->assertEquals(
"3",
$this->getCellByTableClass('table_results', 3, 5)
);
// case 2
$this->byLinkText("datetimefield")->click();
$this->waitForElementNotPresent("byId", "loading_parent");
$this->sleep();
$this->assertEquals(
"3",
$this->getCellByTableClass('table_results', 1, 5)
);
$this->assertEquals(
"1",
$this->getCellByTableClass('table_results', 2, 5)
);
$this->assertEquals(
"2",
$this->getCellByTableClass('table_results', 3, 5)
);
// case 4
$this->byLinkText("datetimefield")->click();
$this->waitForElementNotPresent("byId", "loading_parent");
$this->sleep();
$this->assertEquals(
"2",
$this->getCellByTableClass('table_results', 1, 5)
);
$this->assertEquals(
"1",
$this->getCellByTableClass('table_results', 2, 5)
);
$this->assertEquals(
"3",
$this->getCellByTableClass('table_results', 3, 5)
);
}
/**
* Test Edit Record
*
* @return void
*
* @group large
*/
public function testChangeRecords()
{
$this->sleep();
$this->byCssSelector(
"table.table_results tbody tr:nth-child(2) td:nth-child(2) a"
)->click();
$this->sleep();
/* TODO: this occasionally fails, so there is probably something wrong */
$this->waitForElement("byId", "insertForm");
$this->assertEquals(
"2",
$this->byId("field_1_3")->value()
);
$this->assertEquals(
"foo",
$this->byId("field_2_3")->value()
);
$this->assertEquals(
"2010-01-20 02:00:02",
$this->byId("field_3_3")->value()
);
$this->byId("field_2_3")->clear();
$this->byId("field_2_3")->value("foobar");
$this->byId("field_3_3")->clear();
$this->byId("field_3_3")->value("2009-01-20 02:00:02");
$this->byId("buttonYes")->click();
$success = $this->waitForElement("byClassName", "success");
$this->assertContains("1 row affected", $success->text());
$this->assertEquals(
"foobar",
$this->getCellByTableClass('table_results', 2, 6)
);
$this->assertEquals(
"2009-01-20 02:00:02",
$this->getCellByTableClass('table_results', 2, 7)
);
}
/**
* Test edit record by double click
*
* @return void
*
* @group large
*/
public function testChangeRecordsByDoubleClick()
{
$element = $this->byCssSelector(
"table.table_results tbody tr:nth-child(1) td:nth-child(6)"
);
$this->moveto($element);
$this->doubleclick();
$this->assertEquals(
$this->byCssSelector("textarea.edit_box")->value(),
"abcd"
);
$this->byCssSelector("textarea.edit_box")->clear();
$this->byCssSelector("textarea.edit_box")->value("abcde");
$this->keys(PHPUnit_Extensions_Selenium2TestCase_Keys::RETURN_);
$success = $this->waitForElement(
"byCssSelector", "span.ajax_notification div.success"
);
$this->assertContains("1 row affected", $success->text());
$this->assertEquals(
"abcde",
$this->getCellByTableClass('table_results', 1, 6)
);
}
/**
* Test copy and insert record
*
* @return void
*
* @group large
*/
public function testCopyRecords()
{
$this->byCssSelector(
"table.table_results tbody tr:nth-child(3) td:nth-child(3) a"
)->click();
/* TODO: this occasionally fails, so there is probably something wrong */
$this->waitForElement("byId", "insertForm");
$this->assertEquals(
"Abcd",
$this->byId("field_2_3")->value()
);
$this->assertEquals(
"2012-01-20 02:00:02",
$this->byId("field_3_3")->value()
);
$this->byId("field_2_3")->clear();
$this->byId("field_2_3")->value("ABCDEFG");
$this->byId("field_3_3")->clear();
$this->byId("field_3_3")->value("2012-01-20 02:05:02");
$this->byId("buttonYes")->click();
$success = $this->waitForElement("byClassName", "success");
$this->assertContains("1 row inserted", $success->text());
$this->assertEquals(
"ABCDEFG",
$this->getCellByTableClass('table_results', 4, 6)
);
$this->assertEquals(
"2012-01-20 02:05:02",
$this->getCellByTableClass('table_results', 4, 7)
);
}
/**
* Test search table
*
* @return void
*
* @group large
*/
public function testSearchRecords()
{
$this->expandMore();
$this->byLinkText("Search")->click();
$this->waitForElement("byId", "tbl_search_form");
$this->byId("fieldID_1")->value("abcd");
$select = $this->select($this->byName("criteriaColumnOperators[1]"));
$select->selectOptionByLabel("LIKE %...%");
$this->byName("submit")->click();
$success = $this->waitForElement("byClassName", "success");
$this->assertContains("Showing rows", $success->text());
$this->assertEquals(
"1",
$this->getCellByTableClass('table_results', 1, 5)
);
$this->assertEquals(
"3",
$this->getCellByTableClass('table_results', 2, 5)
);
}
/**
* Test delete multiple records
*
* @return void
*
* @group large
*/
public function testDeleteRecords()
{
$this->byId("id_rows_to_delete1_left")->click();
$this->byId("id_rows_to_delete2_left")->click();
$this->byCssSelector("button[value=delete]")->click();
$this->waitForElement("byCssSelector", "fieldset.confirmation");
$this->byId("buttonYes")->click();
$success = $this->waitForElement("byClassName", "success");
$this->assertContains("Showing rows", $success->text());
$this->assertFalse(
$this->isElementPresent(
"byCssSelector", "table.table_results tbody tr:nth-child(2)"
)
);
}
}

View File

@ -0,0 +1,162 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for table related tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumTableCreateTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumTableCreateTest extends PMA_SeleniumBase
{
/**
* Creates a table
*
* @return void
*
* @group large
*/
public function testCreateTable()
{
$this->login();
$this->waitForElement('byLinkText', $this->database_name)->click();
$this->waitForElement('byId', 'create_table_form_minimal');
$this->byCssSelector(
"form#create_table_form_minimal input[name=table]"
)->value("test_table");
$this->byName("num_fields")->value("4");
$this->byCssSelector('input[value=Go]')->click();
$this->waitForElement('byName', '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->byId($field)->value($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) {
$sel = $this->select($this->byId($selector));
$sel->selectOptionByLabel($value);
}
$this->byName("field_default_value[1]")->value("def");
$this->byId("field_0_9")->click(); // auto increment
$this->byId("field_1_7")->click(); // null
// post
$this->byName("do_save_data")->click();
$this->waitForElement("byLinkText", "test_table");
$this->_tableStructureAssertions();
}
/**
* Make assertions for table structure
*
* @return void
*/
private function _tableStructureAssertions()
{
// go to structure page
$this->byLinkText("Structure")->click();
$this->waitForElement("byId", "tablestructure");
// make assertions for first row
$this->assertContains(
"test_id",
$this->byCssSelector('label[for=checkbox_row_1]')->text()
);
$this->assertEquals(
"int(14)",
$this->getCellByTableId('tablestructure', 1, 4)
);
$this->assertEquals(
"UNSIGNED",
$this->getCellByTableId('tablestructure', 1, 6)
);
$this->assertEquals(
"No",
$this->getCellByTableId('tablestructure', 1, 7)
);
$this->assertEquals(
"None",
$this->getCellByTableId('tablestructure', 1, 8)
);
$this->assertEquals(
"AUTO_INCREMENT",
$this->getCellByTableId('tablestructure', 1, 9)
);
$this->assertFalse(
$this->isElementPresent(
'byCssSelector',
'table#tablestructure tbody tr:nth-child(1) "
. "ul.table-structure-actions li.primary a'
)
);
// make assertions for second row
$this->assertContains(
"test_column",
$this->byCssSelector('label[for=checkbox_row_2]')->text()
);
$this->assertEquals(
"varchar(10)",
$this->getCellByTableId('tablestructure', 2, 4)
);
$this->assertEquals(
"utf8_general_ci",
$this->getCellByTableId('tablestructure', 2, 5)
);
$this->assertEquals(
"Yes",
$this->getCellByTableId('tablestructure', 2, 7)
);
$this->assertEquals(
"def",
$this->getCellByTableId('tablestructure', 2, 8)
);
$this->assertFalse(
$this->isElementPresent(
'byCssSelector',
'css=ul.table-structure-actions:nth-child(2) li.primary a'
)
);
}
}

View File

@ -0,0 +1,153 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for table related tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumTableInsertTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumTableInsertTest extends PMA_SeleniumBase
{
/**
* Setup the browser environment to run the selenium t
* est case
*
* @return void
*/
public function setUp()
{
parent::setUp();
$this->dbQuery(
"CREATE TABLE `test_table` ("
. " `id` int(11) NOT NULL AUTO_INCREMENT,"
. " `name` varchar(20) NOT NULL,"
. " `datetimefield` datetime NOT NULL,"
. " PRIMARY KEY (`id`)"
. ")"
);
}
/**
* setUp function that can use the selenium session (called before each test)
*
* @return void
*/
public function setUpPage()
{
$this->login();
$this->navigateTable('test_table');
}
/**
* Insert data into table
*
* @return void
*
* @group large
*/
public function testAddData()
{
if (mb_strtolower($this->getBrowser()) == 'safari') {
/* TODO: this should be fixed, but the cause is unclear to me */
$this->markTestIncomplete('Fails with Safari');
}
$this->expandMore();
$this->byLinkText("Insert")->click();
$this->waitForElement("byId", "insertForm");
$this->byId("field_1_3")->value("1");
$this->byId("field_2_3")->value("abcd");
$this->byId("field_3_3")->value("2011-01-20 02:00:02");
$this->byId("field_5_3")->value("foo");
$this->byId("field_6_3")->value("2010-01-20 02:00:02");
$select = $this->select($this->byName("after_insert"));
$select->selectOptionByLabel("Insert another new row");
// post
$this->byId("buttonYes")->click();
$ele = $this->waitForElement("byClassName", "success");
$this->assertContains("2 rows inserted", $ele->text());
$this->byId("field_2_3")->value("Abcd");
$this->byId("field_3_3")->value("2012-01-20 02:00:02");
// post
$this->byCssSelector(
"input[value=Go]"
)->click();
$this->waitForElementNotPresent("byId", "loading_parent");
$ele = $this->waitForElement("byClassName", "success");
$this->assertContains("1 row inserted", $ele->text());
$this->_assertDataPresent();
}
/**
* Assert various data present in results table
*
* @return void
*/
private function _assertDataPresent()
{
$this->byLinkText("Browse")->click();
$this->waitForElement("byId", "table_results");
$this->assertEquals(
"1",
$this->getCellByTableClass('table_results', 1, 5)
);
$this->assertEquals(
"abcd",
$this->getCellByTableClass('table_results', 1, 6)
);
$this->assertEquals(
"2011-01-20 02:00:02",
$this->getCellByTableClass('table_results', 1, 7)
);
$this->assertEquals(
"2",
$this->getCellByTableClass('table_results', 2, 5)
);
$this->assertEquals(
"foo",
$this->getCellByTableClass('table_results', 2, 6)
);
$this->assertEquals(
"2010-01-20 02:00:02",
$this->getCellByTableClass('table_results', 2, 7)
);
$this->assertEquals(
"4",
$this->getCellByTableClass('table_results', 3, 5)
);
$this->assertEquals(
"Abcd",
$this->getCellByTableClass('table_results', 3, 6)
);
$this->assertEquals(
"2012-01-20 02:00:02",
$this->getCellByTableClass('table_results', 3, 7)
);
}
}

View File

@ -0,0 +1,247 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for table related tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumTableOperationsTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumTableOperationsTest extends PMA_SeleniumBase
{
/**
* Setup the browser environment to run the selenium test case
*
* @return void
*/
public function setUp()
{
parent::setUp();
$this->dbQuery(
"CREATE TABLE `test_table` ("
. " `id` int(11) NOT NULL AUTO_INCREMENT,"
. " `val` int(11) NOT NULL,"
. " `val2` int(11) NOT NULL,"
. " PRIMARY KEY (`id`)"
. ")"
);
$this->dbQuery("INSERT INTO test_table (val) VALUES (22)");
$this->dbQuery("INSERT INTO test_table (val) VALUES (33)");
}
/**
* setUp function that can use the selenium session (called before each test)
*
* @return void
*/
public function setUpPage()
{
$this->login();
$this->navigateTable('test_table');
$this->expandMore();
$this->byXPath("//a[contains(., 'Operations')]")->click();
$this->sleep();
$this->waitForElement(
"byXPath",
"//legend[contains(., 'Table maintenance')]"
);
}
/**
* Test for changing a table order
*
* @return void
*
* @group large
*/
public function testChangeTableOrder()
{
/* FIXME: Need to create table which will allow this */
$this->markTestIncomplete(
'Changing order is not supported for some tables.'
);
$this->select($this->byName("order_field"))
->selectOptionByLabel("val");
$this->byId("order_order_desc")->click();
$this->byCssSelector(
"form#alterTableOrderby input[type='submit']"
)->click();
$this->waitForElement(
"byXPath",
"//div[@class='success' and "
. "contains(., 'Your SQL query has been executed successfully')]"
);
$this->byLinkText("Browse")->click();
$this->waitForElement("byId", "table_results");
$this->assertEquals(
"2",
$this->getCellByTableClass('table_results', 1, 5)
);
}
/**
* Test for moving a table
*
* @return void
*
* @group large
*/
public function testMoveTable()
{
$this->byCssSelector("form#moveTableForm input[name='new_name']")
->value("2");
$this->byCssSelector("form#moveTableForm input[type='submit']")->click();
$this->waitForElement(
"byXPath",
"//div[@class='success' and "
. "contains(., 'Table `" . $this->database_name
. "`.`test_table` has been "
. "moved to `" . $this->database_name . "`.`test_table2`.')]"
);
$result = $this->dbQuery("SHOW TABLES");
$row = $result->fetch_assoc();
$this->assertEquals(
"test_table2",
$row["Tables_in_" . $this->database_name]
);
}
/**
* Test for renaming a table
*
* @return void
*
* @group large
*/
public function testRenameTable()
{
$this->byCssSelector("form#tableOptionsForm input[name='new_name']")
->value("2");
$this->byName("comment")->value("foobar");
$this->byCssSelector("form#tableOptionsForm input[type='submit']")->click();
$this->waitForElement(
"byXPath",
"//div[@class='success' and "
. "contains(., 'Table test_table has been renamed to test_table2')]"
);
$this->assertNotNull(
$this->waitForElement(
"byXPath",
"//span[@id='span_table_comment' and contains(., 'foobar')]"
)
);
$result = $this->dbQuery("SHOW TABLES");
$row = $result->fetch_assoc();
$this->assertEquals(
"test_table2",
$row["Tables_in_" . $this->database_name]
);
}
/**
* Test for copying a table
*
* @return void
*
* @group large
*/
public function testCopyTable()
{
$this->byCssSelector("form#copyTable input[name='new_name']")->value("2");
$this->byCssSelector("label[for='what_data']")->click();
$this->byCssSelector("form#copyTable input[type='submit']")->click();
$this->waitForElement(
"byXPath",
"//div[@class='success' and "
. "contains(., 'Table `" . $this->database_name
. "`.`test_table` has been "
. "copied to `" . $this->database_name . "`.`test_table2`.')]"
);
$result = $this->dbQuery("SELECT COUNT(*) as c FROM test_table2");
$row = $result->fetch_assoc();
$this->assertEquals(
2,
$row["c"]
);
}
/**
* Test for truncating a table
*
* @return void
*
* @group large
*/
public function testTruncateTable()
{
$this->byId("truncate_tbl_anchor")->click();
$this->byXPath("//button[contains(., 'OK')]")->click();
$this->waitForElement(
"byXPath",
"//div[@class='success' and "
. "contains(., 'MySQL returned an empty result set')]"
);
$result = $this->dbQuery("SELECT COUNT(*) as c FROM test_table");
$row = $result->fetch_assoc();
$this->assertEquals(
0,
$row["c"]
);
}
/**
* Test for dropping a table
*
* @return void
*
* @group large
*/
public function testDropTable()
{
$this->byId("drop_tbl_anchor")->click();
$this->byXPath("//button[contains(., 'OK')]")->click();
$this->waitForElement(
"byXPath",
"//div[@class='success' and "
. "contains(., 'MySQL returned an empty result set')]"
);
$this->waitForElement(
"byXPath",
"//a[@class='tabactive' and contains(., 'Structure')]"
);
$result = $this->dbQuery("SHOW TABLES");
$this->assertEquals(
0,
$result->num_rows
);
}
}

View File

@ -0,0 +1,160 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for table related tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumTableStructureTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumTableStructureTest extends PMA_SeleniumBase
{
/**
* Setup the browser environment to run the selenium test case
*
* @return void
*/
public function setUp()
{
parent::setUp();
$this->dbQuery(
"CREATE TABLE `test_table` ("
. " `id` int(11) NOT NULL AUTO_INCREMENT,"
. " `val` int(11) NOT NULL,"
. " `val2` int(11) NOT NULL,"
. " PRIMARY KEY (`id`)"
. ")"
);
}
/**
* setUp function that can use the selenium session (called before each test)
*
* @return void
*/
public function setUpPage()
{
$this->login();
$this->waitForElement('byLinkText', $this->database_name)->click();
$this->navigateTable('test_table');
$this->waitForElement(
"byXPath",
"(//a[contains(., 'Structure')])"
)->click();
$this->waitForElement("byId", "tablestructure");
}
/**
* Test for adding a new column
*
* @return void
*
* @group large
*/
public function testAddColumn()
{
$this->byCssSelector("label[for='field_where_after']")->click();
$this->byCssSelector("input[value='Go']")->click();
$this->waitForElement("byClassName", "append_fields_form");
$this->byId("field_0_1")->value('val3');
$this->byCssSelector("input[name='do_save_data']")->click();
$this->waitForElement(
"byXPath",
"//div[@class='success' and contains(., "
. "'Table test_table has been altered successfully')]"
);
$this->byLinkText("Structure")->click();
$this->waitForElement("byId", "tablestructure");
$this->assertEquals(
"val3",
$this->byCssSelector('label[for=checkbox_row_2]')->text()
);
$this->assertEquals(
"int(11)",
$this->getCellByTableId('tablestructure', 2, 4)
);
}
/**
* Test for changing a column
*
* @return void
*
* @group large
*/
public function testChangeColumn()
{
$this->byXPath("(//a[contains(., 'Change')])[2]")->click();
$this->waitForElement("byClassName", "append_fields_form");
$this->assertEquals("val", $this->byId("field_0_1")->value());
$this->byId("field_0_1")->clear();
$this->byId("field_0_1")->value('val3');
$this->byCssSelector("input[name='do_save_data']")->click();
$this->waitForElement(
"byXPath",
"//div[@class='success' and contains(., "
. "'Table test_table has been altered successfully')]"
);
$this->byLinkText("Structure")->click();
$this->waitForElement("byId", "tablestructure");
$this->assertEquals(
"val3",
$this->byCssSelector('label[for=checkbox_row_2]')->text()
);
}
/**
* Test for dropping columns
*
* @return void
*
* @group large
*/
public function testDropColumns()
{
$this->byCssSelector('label[for=checkbox_row_2]')->click();
$this->byCssSelector('label[for=checkbox_row_3]')->click();
$this->byXPath(
"//button[@class='mult_submit' and contains(., 'Drop')]"
)->click();
$this->waitForElement(
"byCssSelector", "input[id='buttonYes']"
)->click();
$this->waitForElement(
"byXPath",
"//div[@class='success' and contains(., "
. "'Your SQL query has been executed successfully')]"
);
$this->assertFalse(
$this->isElementPresent(
'byCssSelector', 'label[for=checkbox_row_2]'
)
);
}
}

View File

@ -0,0 +1,266 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for tracking related tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumTrackingTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumTrackingTest extends PMA_SeleniumBase
{
/**
* Setup the browser environment to run the selenium test case
*
* @return void
*/
public function setUp()
{
parent::setUp();
$this->dbQuery(
"CREATE TABLE `test_table` ("
. " `id` int(11) NOT NULL AUTO_INCREMENT,"
. " `val` int(11) NOT NULL,"
. " PRIMARY KEY (`id`)"
. ")"
);
$this->dbQuery(
"CREATE TABLE `test_table_2` ("
. " `id` int(11) NOT NULL AUTO_INCREMENT,"
. " `val` int(11) NOT NULL,"
. " PRIMARY KEY (`id`)"
. ")"
);
$this->dbQuery(
"INSERT INTO `test_table` (val) VALUES (2), (3);"
);
}
/**
* setUp function that can use the selenium session (called before each test)
*
* @return void
*/
public function setUpPage()
{
$this->login();
$this->skipIfNotPMADB();
$this->waitForElement('byLinkText', $this->database_name)->click();
$this->waitForElement(
"byXPath",
"//a[@class='item' and contains(., 'Database: "
. $this->database_name . "')]"
);
$this->expandMore();
$this->byLinkText("Tracking")->click();
$this->waitForElement("byLinkText", "Track table");
$this->byXPath("(//a[contains(., 'Track table')])[1]")->click();
$this->waitForElement("byName", "delete")->click();
$this->byCssSelector("input[value='Create version']")->click();
$this->waitForElement("byId", "versions");
}
/**
* Tests basic tracking functionality
*
* @return void
*
* @group large
*/
public function testTrackingData()
{
$this->_executeSqlAndReturnToTableTracking();
$this->byLinkText("Tracking report")->click();
$this->waitForElement(
"byXPath",
"//h3[contains(., 'Tracking report')]"
);
$this->assertContains(
"DROP TABLE IF EXISTS `test_table`",
$this->getCellByTableId('ddl_versions', 1, 4)
);
$this->assertContains(
"CREATE TABLE `test_table` (",
$this->getCellByTableId('ddl_versions', 2, 4)
);
$this->assertContains(
"UPDATE test_table SET val = val + 1",
$this->getCellByTableId('dml_versions', 1, 4)
);
$this->assertNotContains(
"DELETE FROM test_table WHERE val = 3",
$this->byId("dml_versions")->text()
);
// only structure
$this->select($this->byName("logtype"))
->selectOptionByLabel("Structure only");
$this->byCssSelector("input[value='Go']")->click();
$this->waitForElementNotPresent("byId", "loading_parent");
$this->assertFalse(
$this->isElementPresent("byId", "dml_versions")
);
$this->assertContains(
"DROP TABLE IF EXISTS `test_table`",
$this->getCellByTableId('ddl_versions', 1, 4)
);
$this->assertContains(
"CREATE TABLE `test_table` (",
$this->getCellByTableId('ddl_versions', 2, 4)
);
// only data
$this->select($this->byName("logtype"))
->selectOptionByLabel("Data only");
$this->byCssSelector("input[value='Go']")->click();
$this->waitForElementNotPresent("byId", "loading_parent");
$this->assertFalse(
$this->isElementPresent("byId", "ddl_versions")
);
$this->assertContains(
"UPDATE test_table SET val = val + 1",
$this->getCellByTableId('dml_versions', 1, 4)
);
$this->assertNotContains(
"DELETE FROM test_table WHERE val = 3",
$this->byId("dml_versions")->text()
);
}
/**
* Tests deactivation of tracking
*
* @return void
*
* @group large
*/
public function testDeactivateTracking()
{
$this->byCssSelector("input[value='Deactivate now']")->click();
$this->waitForElement(
"byCssSelector", "input[value='Activate now']"
);
$this->_executeSqlAndReturnToTableTracking();
$this->assertFalse(
$this->isElementPresent("byId", "dml_versions")
);
}
/**
* Tests dropping a tracking
*
* @return void
*
* @group large
*/
public function testDropTracking()
{
$this->byLinkText("Database: " . $this->database_name)->click();
$this->waitForElement("byCssSelector", "table.data");
usleep(1000000);
$this->expandMore();
$this->byLinkText("Tracking")->click();
$this->waitForElement("byId", "versions");
$this->byLinkText("Drop")->click();
$this->waitForElement(
"byXPath",
"//button[contains(., 'OK')]"
)->click();
$this->waitForElement(
"byXPath",
"//div[@class='success' and contains(., "
. "'Your SQL query has been executed')]"
);
$this->assertContains(
"test_table",
$this->getCellByTableId('noversions', 1, 1)
);
$this->assertContains(
"test_table_2",
$this->getCellByTableId('noversions', 2, 1)
);
}
/**
* Tests structure snapshot of a tracking
*
* @return void
*
* @group large
*/
public function testStructureSnapshot()
{
$this->byLinkText("Structure snapshot")->click();
$this->waitForElement("byId", "tablestructure");
$this->assertContains(
"id",
$this->getCellByTableId('tablestructure', 1, 1)
);
$this->assertContains(
"val",
$this->getCellByTableId('tablestructure', 2, 1)
);
$this->assertContains(
"PRIMARY",
$this->getCellByTableId('tablestructure_indexes', 1, 1)
);
$this->assertContains(
"id",
$this->getCellByTableId('tablestructure_indexes', 1, 5)
);
}
/**
* Goes to SQL tab, executes queries, returns to tracking page
*
* @return void
*/
private function _executeSqlAndReturnToTableTracking()
{
$this->byLinkText("SQL")->click();
$this->waitForElement("byId", "queryfieldscontainer");
$this->typeInTextArea(
";UPDATE test_table SET val = val + 1; "
. "DELETE FROM test_table WHERE val = 3"
);
$this->byCssSelector("input[value='Go']")->click();
$this->waitForElement("byClassName", "success");
$this->expandMore();
$this->byLinkText("Tracking")->click();
$this->waitForElement("byId", "versions");
}
}

View File

@ -0,0 +1,39 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Selenium TestCase for SQL query window related tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
require_once 'TestBase.php';
/**
* PmaSeleniumXSSTest class
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
class PMA_SeleniumXSSTest extends PMA_SeleniumBase
{
/**
* Tests the SQL query tab with a null query
*
* @return void
*
* @group large
*/
public function testQueryTabWithNullValue()
{
if (mb_strtolower($this->getBrowser()) == 'safari') {
$this->markTestSkipped('Alerts not supported on Safari browser.');
}
$this->login();
$this->waitForElement('byLinkText', "SQL")->click();
$this->waitForElement("byId", "queryboxf");
$this->byId("button_submit_query")->click();
$this->assertEquals("Missing value in the form!", $this->alertText());
}
}

View File

@ -0,0 +1,615 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Base class for Selenium tests
*
* @package PhpMyAdmin-test
* @subpackage Selenium
*/
/**
* Base class for Selenium tests.
*
* @package PhpMyAdmin-test
* @subpackage Selenium
* @group selenium
*/
abstract class PMA_SeleniumBase extends PHPUnit_Extensions_Selenium2TestCase
{
/**
* mysqli object
*
* @access private
* @var mysqli
*/
private $_mysqli;
/**
* Name of database for the test
*
* @access public
* @var string
*/
public $database_name;
/**
* Whether Selenium testing should be enabled.
*
* @access private
* @var boolean
*/
private static $_selenium_enabled = false;
/**
* Lists browsers to test
*
* @return Array of browsers to test
*/
public static function browsers()
{
if (! empty($GLOBALS['TESTSUITE_BROWSERSTACK_USER'])
&& ! empty($GLOBALS['TESTSUITE_BROWSERSTACK_KEY'])
) {
/* BrowserStack integration */
self::$_selenium_enabled = true;
$strategy = 'shared';
$build_local = false;
$build_id = 'Manual';
$project_name = 'phpMyAdmin';
if (getenv('BUILD_TAG')) {
$build_id = getenv('BUILD_TAG');
$strategy = 'isolated';
$project_name = 'phpMyAdmin (Jenkins)';
} elseif (getenv('TRAVIS_JOB_NUMBER')) {
$build_id = 'travis-' . getenv('TRAVIS_JOB_NUMBER');
$build_local = true;
$strategy = 'isolated';
$project_name = 'phpMyAdmin (Travis)';
}
$capabilities = array(
'browserstack.user' => $GLOBALS['TESTSUITE_BROWSERSTACK_USER'],
'browserstack.key' => $GLOBALS['TESTSUITE_BROWSERSTACK_KEY'],
'browserstack.debug' => false,
'project' => $project_name,
'build' => $build_id,
);
if ($build_local) {
$capabilities['browserstack.local'] = $build_local;
$capabilities['browserstack.localIdentifier'] = $build_id;
$capabilities['browserstack.debug'] = true;
}
$result = array();
$result[] = array(
'browserName' => 'chrome',
'host' => 'hub.browserstack.com',
'port' => 80,
'timeout' => 30000,
'sessionStrategy' => $strategy,
'desiredCapabilities' => $capabilities,
);
/* Only one browser for continuous integration for speed */
if (empty($GLOBALS['TESTSUITE_FULL'])) {
return $result;
}
/*
$result[] = array(
'browserName' => 'Safari',
'host' => 'hub.browserstack.com',
'port' => 80,
'timeout' => 30000,
'sessionStrategy' => $strategy,
'desiredCapabilities' => array_merge(
$capabilities,
array(
'os' => 'OS X',
'os_version' => 'Mavericks',
)
)
);
*/
$result[] = array(
'browserName' => 'firefox',
'host' => 'hub.browserstack.com',
'port' => 80,
'timeout' => 30000,
'sessionStrategy' => $strategy,
'desiredCapabilities' => $capabilities,
);
/* TODO: testing is MSIE is currently broken, so disabled
$result[] = array(
'browserName' => 'internet explorer',
'host' => 'hub.browserstack.com',
'port' => 80,
'timeout' => 30000,
'sessionStrategy' => $strategy,
'desiredCapabilities' => array_merge(
$capabilities,
array(
'os' => 'windows',
'os_version' => '7',
)
)
);
*/
return $result;
} elseif (! empty($GLOBALS['TESTSUITE_SELENIUM_HOST'])) {
self::$_selenium_enabled = true;
return array(
array(
'browserName' => $GLOBALS['TESTSUITE_SELENIUM_BROWSER'],
'host' => $GLOBALS['TESTSUITE_SELENIUM_HOST'],
'port' => intval($GLOBALS['TESTSUITE_SELENIUM_PORT']),
)
);
} else {
return array();
}
}
/**
* Configures the selenium and database link.
*
* @return void
*
* @throws Exception
*/
protected function setUp()
{
if (! self::$_selenium_enabled) {
$this->markTestSkipped('Selenium testing not configured.');
}
$caps = $this->getDesiredCapabilities();
$this->setDesiredCapabilities(
array_merge(
$caps,
array('name' => get_class($this) . '__' . $this->getName())
)
);
parent::setUp();
$this->setBrowserUrl($GLOBALS['TESTSUITE_URL']);
$this->_mysqli = new mysqli(
$GLOBALS['TESTSUITE_SERVER'],
$GLOBALS['TESTSUITE_USER'],
$GLOBALS['TESTSUITE_PASSWORD']
);
if ($this->_mysqli->connect_errno) {
throw new Exception(
'Failed to connect to MySQL (' . $this->_mysqli->error . ')'
);
}
$this->database_name = $GLOBALS['TESTSUITE_DATABASE']
. mb_substr(md5(rand()), 0, 7);
$this->dbQuery(
'CREATE DATABASE IF NOT EXISTS ' . $this->database_name
);
$this->dbQuery(
'USE ' . $this->database_name
);
}
/**
* Checks whether user is a superuser.
*
* @return boolean
*/
protected function isSuperUser()
{
$result = $this->dbQuery('SELECT COUNT(*) FROM mysql.user');
if ($result !== false) {
$result->free();
return true;
}
return false;
}
/**
* Skips test if test user is not a superuser.
*
* @return void
*/
protected function skipIfNotSuperUser()
{
if (! $this->isSuperUser()) {
$this->markTestSkipped('Test user is not a superuser.');
}
}
/**
* Skips test if pmadb is not configured.
*
* @return void
*/
protected function skipIfNotPMADB()
{
$this->url('chk_rel.php');
if ($this->isElementPresent("byXPath", "//*[@color=\"red\"]")) {
$this->markTestSkipped(
'The phpMyAdmin configuration storage is not working.'
);
}
}
/**
* Tear Down function for test cases
*
* @return void
*/
public function tearDown()
{
if ($this->_mysqli != null) {
$this->dbQuery('DROP DATABASE IF EXISTS ' . $this->database_name);
$this->_mysqli->close();
$this->_mysqli = null;
}
}
/**
* perform a login
*
* @param string $username Username
* @param string $password Password
*
* @return void
*/
public function login($username = '', $password = '')
{
if ($username == '') {
$username = $GLOBALS['TESTSUITE_USER'];
}
if ($password == '') {
$password = $GLOBALS['TESTSUITE_PASSWORD'];
}
$this->url('');
$this->waitForElementNotPresent('byId', 'cfs-style');
/* Return if already logged in */
if ($this->isSuccessLogin()) {
return;
}
$usernameField = $this->waitForElement('byId', 'input_username');
$usernameField->value($username);
$passwordField = $this->byId('input_password');
$passwordField->value($password);
$this->byId('input_go')->click();
}
/**
* Checks whether the login is successful
*
* @return boolean
*/
public function isSuccessLogin()
{
if ($this->isElementPresent("byXPath", "//*[@id=\"serverinfo\"]")) {
return true;
} else {
return false;
}
}
/**
* Checks whether the login is unsuccessful
*
* @return boolean
*/
public function isUnsuccessLogin()
{
if ($this->isElementPresent("byCssSelector", "div.error")) {
return true;
} else {
return false;
}
}
/**
* Used to go to the homepage
*
* @return void
*/
public function gotoHomepage()
{
$e = $this->byPartialLinkText("Server: ");
$e->click();
$this->waitForElementNotPresent('byCssSelector', 'div#loading_parent');
}
/**
* Executes a database query
*
* @param string $query SQL Query to be executed
*
* @return void|boolean|mysqli_result
*
* @throws Exception
*/
public function dbQuery($query)
{
return $this->_mysqli->query($query);
}
/**
* Check if user is logged in to phpmyadmin
*
* @return boolean Where or not user is logged in
*/
public function isLoggedIn()
{
return $this->isElementPresent(
'byXPath', '//*[@id="serverinfo"]/a[1]'
);
}
/**
* Perform a logout, if logged in
*
* @return void
*/
public function logOutIfLoggedIn()
{
if ($this->isLoggedIn()) {
$this->byCssSelector("img.icon.ic_s_loggoff")->click();
}
}
/**
* Wait for an element to be present on the page
*
* @param string $func Locate using - byCss, byXPath, etc
* @param string $arg Selector
*
* @return PHPUnit_Extensions_Selenium2TestCase_Element Element waited for
*/
public function waitForElement($func, $arg)
{
$this->timeouts()->implicitWait(10000);
$element = call_user_func_array(
array($this, $func), array($arg)
);
$this->timeouts()->implicitWait(0);
return $element;
}
/**
* Wait for an element to disappear
*
* @param string $func Locate using - byCss, byXPath, etc
* @param string $arg Selector
*
* @return bool Whether or not the element disappeared
*/
public function waitForElementNotPresent($func, $arg)
{
while (true) {
if (!$this->isElementPresent($func, $arg)) {
return true;
}
usleep(5000);
}
}
/**
* Sleeps while waiting for browser to perform an action.
*
* @todo This method should not be used, but rather there would be
* explicit waiting for some elements.
*
* @return void
*/
public function sleep()
{
usleep(5000);
}
/**
* Check if element is present or not
*
* @param string $func Locate using - byCss, byXPath, etc
* @param string $arg Selector
*
* @return bool Whether or not the element is present
*/
public function isElementPresent($func, $arg)
{
try {
$element = call_user_func_array(
array($this, $func), array($arg)
);
} catch (PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
// Element not present
return false;
} catch (InvalidArgumentException $e) {
// Element not present
return false;
}
// Element Present
return true;
}
/**
* Get table cell data by the ID of the table
*
* @param string $tableID Table identifier
* @param int $row Table row
* @param int $column Table column
*
* @return text Data from the particular table cell
*/
public function getCellByTableId($tableID, $row, $column)
{
$sel = "table#{$tableID} tbody tr:nth-child({$row}) "
. "td:nth-child({$column})";
$element = $this->byCssSelector(
$sel
);
return $element->text();
}
/**
* Get table cell data by the class attribute of the table
*
* @param string $tableClass Class of the table
* @param int $row Table row
* @param int $column Table column
*
* @return text Data from the particular table cell
*/
public function getCellByTableClass($tableClass, $row, $column)
{
$sel = "table.{$tableClass} tbody tr:nth-child({$row}) "
. "td:nth-child({$column})";
$element = $this->byCssSelector(
$sel
);
return $element->text();
}
/**
* Wrapper around keys method to not use it on not supported
* browsers.
*
* @param string $text Keys to send
*
* @return void
*/
public function keys($text)
{
/**
* Not supported in Safari Webdriver, see
* https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/4136
*/
if (mb_strtolower($this->getBrowser()) == 'safari') {
$this->markTestSkipped('Can not send keys to Safari browser.');
}
parent::keys($text);
}
/**
* Wrapper around moveto method to not use it on not supported
* browsers.
*
* @param object $element element
*
* @return void
*/
public function moveto($element)
{
/**
* Not supported in Safari Webdriver, see
* https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/4136
*/
if (mb_strtolower($this->getBrowser()) == 'safari') {
$this->markTestSkipped('MoveTo not supported on Safari browser.');
}
parent::moveto($element);
}
/**
* Wrapper around alertText method to not use it on not supported
* browsers.
*
* @return mixed
*/
public function alertText()
{
/**
* Not supported in Safari Webdriver, see
* https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/4136
*/
if (mb_strtolower($this->getBrowser()) == 'safari') {
$this->markTestSkipped('Alerts not supported on Safari browser.');
}
return parent::alertText();
}
/**
* Type text in textarea (CodeMirror enabled)
*
* @param string $text Text to type
*
* @return void
*/
public function typeInTextArea($text)
{
/**
* Firefox needs some escaping of a text, see
* https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/1723
*/
if (mb_strtolower($this->getBrowser()) == 'firefox') {
$text = str_replace(
"(",
PHPUnit_Extensions_Selenium2TestCase_Keys::SHIFT
. PHPUnit_Extensions_Selenium2TestCase_Keys::NUMPAD9
. PHPUnit_Extensions_Selenium2TestCase_Keys::NULL,
$text
);
}
$this->byClassName("CodeMirror-scroll")->click();
$this->keys($text);
}
/**
* Kills the More link in the menu
*
* @return void
*/
public function expandMore()
{
try {
$this->waitForElement('byCssSelector', 'li.submenu > a');
} catch (PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
return;
}
/* We need to resize to ensure it fits into accessible area */
$this->execute(
array(
'script' => "$('#topmenu').css('font-size', '50%');"
. "$(window).resize()",
'args' => array()
)
);
$this->sleep();
}
/**
* Navigates browser to a table page.
*
* @param string $table Name of table
*
* @return void
*/
public function navigateTable($table)
{
// go to database page
$this->waitForElement("byLinkText", $this->database_name)->click();
/* Wait for loading and expanding tree */
$this->waitForElement(
'byCssSelector',
'li.last.table'
);
/* TODO: Timing issue of expanding navigation tree */
$this->sleep();
// go to table page
$this->waitForElement(
"byXPath",
"//*[@id='pma_navigation_tree_content']//a[contains(., '$table')]"
)->click();
// Wait for it to load
$this->waitForElement(
"byXPath",
"//a[@class='tabactive' and contains(., 'Browse')]"
);
}
}