From 6cf6ab2e2df7f00e82d80d1e094a0454139ce68f Mon Sep 17 00:00:00 2001 From: Lev Lazinskiy Date: Wed, 8 Jun 2016 18:40:41 -0700 Subject: Add phpunit-selenium to composer depenendencies --- composer.json | 3 ++- composer.lock | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 2f6bec91..85fdb5ad 100644 --- a/composer.json +++ b/composer.json @@ -52,6 +52,7 @@ "require-dev" : { "symfony/yaml" : "2.1", "symfony/stopwatch" : "~2.6", - "phpunit/phpunit" : "4.8.*" + "phpunit/phpunit" : "4.8.*", + "phpunit/phpunit-selenium": "^2.0" } } diff --git a/composer.lock b/composer.lock index 783d54cc..e0177ed5 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "60ac519d67728cc5b125f77048d2e0c0", - "content-hash": "3dfc055d11c8010e9b16fb7df58c0f94", + "hash": "2de2026649db7bc41653bef80f974c6a", + "content-hash": "ea8ef74f1f1cf53b9f96b7609d756873", "packages": [ { "name": "christian-riesen/base32", @@ -1397,6 +1397,70 @@ ], "time": "2015-10-02 06:51:40" }, + { + "name": "phpunit/phpunit-selenium", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/giorgiosironi/phpunit-selenium.git", + "reference": "2bad798ec0daf20d2854400e3bc5329ee0a7b2d1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/giorgiosironi/phpunit-selenium/zipball/2bad798ec0daf20d2854400e3bc5329ee0a7b2d1", + "reference": "2bad798ec0daf20d2854400e3bc5329ee0a7b2d1", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-dom": "*", + "php": ">=5.3.3", + "phpunit/phpunit": "~4.8", + "sebastian/comparator": "~1.0" + }, + "require-dev": { + "phing/phing": "2.*" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHPUnit/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Giorgio Sironi", + "email": "info@giorgiosironi.com", + "role": "developer" + }, + { + "name": "Ivan Kurnosov", + "email": "zerkms@zerkms.com", + "role": "developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "original developer" + } + ], + "description": "Selenium Server integration for PHPUnit", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "phpunit", + "selenium", + "testing", + "xunit" + ], + "time": "2016-03-01 10:33:56" + }, { "name": "sebastian/comparator", "version": "1.2.0", -- cgit v1.2.3 From e20527fbc20df5c2bd1c0c5a0ecbdf0404c8d4e8 Mon Sep 17 00:00:00 2001 From: Lev Lazinskiy Date: Wed, 8 Jun 2016 18:41:34 -0700 Subject: Add test-browser to Make This allows you to run selenium acceptance tests with `make test-browser` --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index c789e15d..6ffba241 100644 --- a/Makefile +++ b/Makefile @@ -57,6 +57,9 @@ test-postgres: unittest: test-sqlite test-mysql test-postgres +test-browser: + @ phpunit -c tests/acceptance.xml + sql: @ pg_dump --schema-only --no-owner --no-privileges --quote-all-identifiers -n public --file app/Schema/Sql/postgres.sql kanboard @ pg_dump -d kanboard --column-inserts --data-only --table settings >> app/Schema/Sql/postgres.sql -- cgit v1.2.3 From 216a8c66471c323cab4ea32cc4cdb0a5027ba6ff Mon Sep 17 00:00:00 2001 From: Lev Lazinskiy Date: Wed, 8 Jun 2016 18:57:27 -0700 Subject: Added acceptance tests documentation --- doc/tests.markdown | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/doc/tests.markdown b/doc/tests.markdown index b2d95491..5e3d71d2 100644 --- a/doc/tests.markdown +++ b/doc/tests.markdown @@ -12,6 +12,8 @@ Requirements - PHP cli - PHPUnit installed - Mysql and Postgresql (optional) +- Selenium (optional) +- Firefox (optional) Unit Tests ---------- @@ -83,6 +85,11 @@ From your Kanboard directory, run the command `phpunit -c tests/units.postgres.x Integration Tests ----------------- +Acceptance tests (also known as end-to-end tests and sometimes functional tests) allow us to test the actual functionality of the browser using Selenium and PHPUnit. + +The PHPUnit config file is `tests/acceptance.xml`. +From your Kanboard directory, run the command `phpunit -c tests/units.sqlite.xml`. + Actually only the API calls are tested. Real HTTP calls are made with those tests. @@ -116,6 +123,30 @@ Time: 1.18 minutes, Memory: 14.75Mb OK (135 tests, 526 assertions) ``` +Acceptance Tests +----------------- + +Acceptance tests (also sometimes known as end-to-end tests, and functional tests) test the actual functionality of the UI in a browser using Selenium. + +In order to run these tests you must have [Selenium Standalone Server](http://www.seleniumhq.org/download/) installed, and a compatible version of Firefox. + +The PHPUnit config file is `tests/acceptance.xml`. +With Selenium and the Kanboard app running, from your Kanboard directory, run the command `make test-browser`. This will initiate the testing suite and you will see Firefox open automatically and perform the actions specified in the acceptance tests. + +Example: + +```bash +$ make test-browser +PHPUnit 4.8.26 by Sebastian Bergmann and contributors. + +.. + +Time: 5.59 seconds, Memory: 5.25MB + +OK (2 tests, 5 assertions) +``` + + Continuous Integration with Travis-CI ------------------------------------- -- cgit v1.2.3 From 7464607195bb84b2a7b6f1e2ad3b208fe37dc336 Mon Sep 17 00:00:00 2001 From: Lev Lazinskiy Date: Wed, 8 Jun 2016 19:02:46 -0700 Subject: Add acceptance tests Basic Framework for working with Selenium with PHPUnit and Firefox. Future acceptance tests just need to extend Base.php and implement various flows that we wish to test. --- tests/acceptance.xml | 13 +++++ tests/acceptance/Base.php | 18 ++++++ tests/acceptance/UserAuthenticationTest.php | 86 +++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 tests/acceptance.xml create mode 100644 tests/acceptance/Base.php create mode 100644 tests/acceptance/UserAuthenticationTest.php diff --git a/tests/acceptance.xml b/tests/acceptance.xml new file mode 100644 index 00000000..a161f9ec --- /dev/null +++ b/tests/acceptance.xml @@ -0,0 +1,13 @@ + + + + acceptance + + + + + + + + + diff --git a/tests/acceptance/Base.php b/tests/acceptance/Base.php new file mode 100644 index 00000000..e8684a9b --- /dev/null +++ b/tests/acceptance/Base.php @@ -0,0 +1,18 @@ +setHost(SELENIUM_HOST); + $this->setPort((integer) SELENIUM_PORT); + $this->setBrowserUrl(KANBOARD_APP_URL); + $this->setBrowser(DEFAULT_BROWSER); + } + + public function tearDown() + { + $this->stop(); + } +} diff --git a/tests/acceptance/UserAuthenticationTest.php b/tests/acceptance/UserAuthenticationTest.php new file mode 100644 index 00000000..3313e050 --- /dev/null +++ b/tests/acceptance/UserAuthenticationTest.php @@ -0,0 +1,86 @@ + 'admin', + 'password' => 'admin', + ] + ]; + + return $inputs; + } + + public function invalidLoginInputsProvider() + { + $inputs[] = [ + [ + 'username' => 'wrong_username', + 'password' => 'wrong_password', + ] + ]; + + return $inputs; + } + + /** + * @dataProvider validLoginInputsProvider + */ + public function testValidLogin(array $inputs) + { + $this->url('/'); + $this->assertContains('Login', $this->title()); + + $form = $this->byTag('form'); + foreach ($inputs as $input => $value) { + $form->byName($input)->value($value); + } + $form->submit(); + + $content = $this->byClassName('sidebar')->text(); + $this->assertContains($inputs['username'], $content); + } + + /** + * @dataProvider invalidLoginInputsProvider + */ + public function testInvalidLogin(array $inputs) + { + $this->url('/'); + + // Test wrong username with correct password + $form = $this->byTag('form'); + $form->byName('username')->value($inputs['username']); + $form->byName('password')->value('admin'); + $form->submit(); + + $content = $this->byTag('body')->text(); + $this->assertContains('Bad username or password', $content); + + // Test wrong password with correct username + $form = $this->byTag('form'); + $form->byName('username')->value('admin'); + $form->byName('password')->value($inputs['password']); + $form->submit(); + + $content = $this->byTag('body')->text(); + $this->assertContains('Bad username or password', $content); + + // Test wrong username and password + $form = $this->byTag('form'); + $form->byName('username')->value($inputs['username']); + $form->byName('password')->value($inputs['password']); + $form->submit(); + + $content = $this->byTag('body')->text(); + $this->assertContains('Bad username or password', $content); + + + } +} -- cgit v1.2.3