From d2dd9bdce7d1f48b790884b1ef1e5dc833fd1c5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Doursenaud?= <rdoursenaud@gpcsolutions.fr> Date: Sat, 23 Jul 2016 13:33:04 +0200 Subject: [PATCH] New: Installation process functional test --- composer.json | 3 +- test/phpunit/functional/InstallTest.php | 210 ++++++++++++++++++ test/phpunit/functional/README.md | 77 +++++++ .../functional/DolibarrInstallTest.php | 33 --- 4 files changed, 289 insertions(+), 34 deletions(-) create mode 100644 test/phpunit/functional/InstallTest.php create mode 100644 test/phpunit/functional/README.md delete mode 100644 test/phpunit/zenfusion/functional/DolibarrInstallTest.php diff --git a/composer.json b/composer.json index fb3109fbc40..87f9822f376 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,8 @@ "jakub-onderka/php-parallel-lint": "^0", "jakub-onderka/php-console-highlighter": "^0", "phpunit/phpunit": "^4", - "squizlabs/php_codesniffer": "^2" + "squizlabs/php_codesniffer": "^2", + "phpunit/phpunit-selenium": "^2" }, "suggest": { "ext-mysqlnd": "To use with MySQL or MariaDB", diff --git a/test/phpunit/functional/InstallTest.php b/test/phpunit/functional/InstallTest.php new file mode 100644 index 00000000000..534d1d602c0 --- /dev/null +++ b/test/phpunit/functional/InstallTest.php @@ -0,0 +1,210 @@ +<?php + +/* Copyright (C) 2016 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr> + * + * Install functional test using PHPUnit's Selenium + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * Class InstallTest + */ +class InstallTest extends PHPUnit_Extensions_Selenium2TestCase +{ + protected static $url = 'https://dev.dolibarr.org'; + protected static $db_name = 'dolibarr_test'; + protected static $db_host = 'localhost'; + protected static $db_admin_user = 'root'; + protected static $db_admin_pass = ''; + protected static $db_user = 'dolibarr'; + protected static $db_pass = 'dolibarr'; + protected static $dol_admin_user = 'admin'; + protected static $dol_admin_pass = 'admin'; + + public static $browsers = array( + array( + 'browser' => 'chrome', + 'browserName' => 'chrome', + 'sessionStrategy' => 'shared', + 'desiredCapabilities' => array() + ) + ); + + public static function setUpBeforeClass() + { + // Make sure we backup and remove the configuration file to force new install. + @rename('htdocs/conf/conf.php', sys_get_temp_dir() . '/conf.php'); + + // Start without a database + self::dropTestDatabase(); + + // Run the tests in the same window + self::shareSession(true); + } + + protected static function dropTestDatabase() + { + $mysqli = new mysqli(self::$db_host, self::$db_admin_user, self::$db_admin_pass); + $mysqli->query("DROP DATABASE " . self::$db_name); + } + + public static function tearDownAfterClass() + { + // Remove the generated configuration and restore the backed up file. + @unlink('htdocs/conf/conf.php'); + @rename(sys_get_temp_dir() . '/conf.php', 'htdocs/conf/conf.php'); + + // Cleanup test database + self::dropTestDatabase(); + } + + public function setUp() + { + // Populating the database can take quite long. + $this->setSeleniumServerRequestsTimeout(120000); + $this->setBrowserUrl(self::$url); + } + + public function testInstallRedirect() + { + $this->url('/'); + $this->assertContains('/install/index.php', $this->url()); + } + + public function testInstallPageTitle() + { + $this->assertContains('Dolibarr', $this->title()); + } + + public function testInstallProcess() + { + // FIXME: the button itself should have an ID + $this->byId('nextbutton')->byTag('input')->click(); + $this->assertContains('/install/check.php', $this->url()); + } + + public function testCheckPage() + { + $unavailable_choices = $this->byId('navail_choices'); + $show_hide_choices = $this->byId('AShowChoices')->byTag('a'); + $this->assertFalse($unavailable_choices->displayed()); + // FIXME: the link itself should have an ID + $show_hide_choices->click(); + $this->assertTrue($unavailable_choices->displayed()); + $show_hide_choices->click(); + $this->assertFalse($unavailable_choices->displayed()); + $this->byClassName('button')->click(); + $this->assertContains('/install/fileconf.php', $this->url()); + } + + public function testForm() + { + $this->assertFalse($this->byClassName('hideroot')->displayed()); + $this->assertTrue($this->byClassName('hidesqlite')->displayed()); + + // FIXME: This element should have an ID + $this->assertFalse($this->byName('main_force_https')->selected()); + $this->byName('main_force_https')->click(); + + $this->assertEquals('dolibarr', $this->byId('db_name')->value()); + $this->byId('db_name')->clear(); + $this->byId('db_name')->value(self::$db_name); + + $this->assertEquals('mysqli', $this->byId('db_type')->value()); + + // FIXME: This element should have an ID + $this->assertEquals('localhost', $this->byName('db_host')->value()); + + $this->assertEquals(3306, $this->byId('db_port')->value()); + + $this->assertEquals('llx_', $this->byId('db_prefix')->value()); + + $this->byId('db_create_database')->click(); + $this->assertTrue($this->byClassName('hideroot')->displayed()); + $this->byId('db_create_database')->click(); + $this->assertFalse($this->byClassName('hideroot')->displayed()); + + $this->byId('db_user')->value(self::$db_user); + + $this->byId('db_pass')->value(self::$db_pass); + + $this->byId('db_create_user')->click(); + $this->assertTrue($this->byClassName('hideroot')->displayed()); + $this->byId('db_create_user')->click(); + $this->assertFalse($this->byClassName('hideroot')->displayed()); + + $this->byId('db_create_database')->click(); + $this->byId('db_create_user')->click(); + $this->assertTrue($this->byClassName('hideroot')->displayed()); + + $this->byId('db_user_root')->value('root'); + $this->byId('db_pass_root')->value(''); + } + + public function testFormSubmit() + { + $this->byName('forminstall')->submit(); + $this->assertContains('/install/step1.php', $this->url()); + } + + public function testStep1() + { + $this->assertFalse($this->byId('pleasewait')->displayed()); + $start = new DateTimeImmutable(); + // FIXME: the button itself should have an ID + $this->byId('nextbutton')->byTag('input')->click(); + $time = $start->diff(new DateTimeImmutable()); + echo "\nPopulating the database took " . $time->format("%s seconds.\n"); + $this->assertContains('/install/step2.php', $this->url()); + } + + public function testStep2() + { + $this->byName('forminstall')->submit(); + $this->assertContains('/install/step4.php', $this->url()); + } + + // There is no step 3 + + public function testStep4() + { + // FIXME: should have an ID + $this->byName('login')->value(self::$dol_admin_user); + // FIXME: should have an ID + $this->byName('pass')->value('admin'); + // FIXME: should have an ID + $this->byName('pass_verif')->value(self::$dol_admin_pass); + // FIXME: the button itself should have an ID + $this->byId('nextbutton')->byTag('input')->click(); + $this->assertContains('/install/step5.php', $this->url()); + } + + public function testStep5() + { + // FIXME: this button should have an ID + $this->byTag('a')->click(); + $this->assertContains('/admin/index.php', $this->url()); + } + + public function testFirstLogin() + { + $this->assertEquals('login', $this->byTag('form')->attribute('id')); + $this->assertEquals(self::$dol_admin_user, $this->byId('username')->value()); + $this->byId('password')->value(self::$dol_admin_pass); + // FIXME: login button should have an ID + $this->byId('login')->submit(); + $this->assertEquals('mainbody', $this->byTag('body')->attribute('id')); + } +} diff --git a/test/phpunit/functional/README.md b/test/phpunit/functional/README.md new file mode 100644 index 00000000000..21380100605 --- /dev/null +++ b/test/phpunit/functional/README.md @@ -0,0 +1,77 @@ +Functional tests for Dolibarr +============================= +A.k.a. end-to-end or acceptance tests. + +Prerequisites +------------- + +### Web server + +Any web server compatible with Dolibarr will do. + +For the full test, it should be configured for serving Dolibarr's htdocs directory at `https://dev.dolibarr.org` with SSL/TLS enabled. + +If you want to test at another address and/or without SSL/TLS, you will have to alter the test configuration. + +### Database server + +#### MySQL or MariaDB. + +Running on localhost with the root user without password. + +The database used for the test is `dolibarr_test`. + +**WARNING:** +This database will be dropped before and after the test. +Make sure you don't hold any valuable information in it! + +A user called `dolibarr` with a password `dolibarr` will be created as part of the test. + +You can alter the test configuration to use another host, users and/or database. + +#### Other + +Unsupported at the moment. +Patches welcome. + +### Browser automation + +#### Server + +[Selenium](http://www.seleniumhq.org/) + +#### Driver + +##### Firefox + +Unsupported at the moment. + +I can't get the new [marionette](https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/WebDriver) [webdriver](https://github.com/mozilla/geckodriver/releases) to work on my workstation. +Patches welcome. + +##### Chrome +[Google Chrome](https://www.google.com/chrome) +[ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver) + +### Test runner +We leverage PHPUnit's selenium integration to run the tests. + +You can install it using composer. +``` +composer --dev require phpunit/phpunit-selenium +``` + +Configuration +------------- + +There is only one test at the moment. +Edit the test file — the configuration values are declared at the top of the class. + +Usage +----- + +Make sure your servers (web, database and browser automation) are started. + +Then from Dolibarr's root directory, run: + +```htdocs/includes/bin/phpunit test/phpunit/functional``` diff --git a/test/phpunit/zenfusion/functional/DolibarrInstallTest.php b/test/phpunit/zenfusion/functional/DolibarrInstallTest.php deleted file mode 100644 index 5fcb37fdb63..00000000000 --- a/test/phpunit/zenfusion/functional/DolibarrInstallTest.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php - -class ZenFusionInstallTest extends PHPUnit_Extensions_Selenium2TestCase -{ - public function setUp() - { - $this->setHost('localhost'); - $this->setPort(4444); - $this->setBrowserUrl('http://dev.zenfusion.fr'); - $this->setBrowser('chrome'); - } - - public function setUpPage() - { - $this->url('/'); - } - - public function testInstallRedirect() - { - $this->assertContains('/install/index.php', $this->url()); - } - - public function testInstallPageTitle() - { - $this->assertContains('Dolibarr', $this->title()); - } - - public function testInstallProcess() - { - $this->byName('forminstall')->submit(); - $this->assertContains('/install/check.php', $this->url()); - } -} -- GitLab