From ad6f6181d92c880535dfdf9846d5c3ef0945dba7 Mon Sep 17 00:00:00 2001 From: Gabriel Silva Date: Tue, 29 Mar 2016 19:49:13 -0300 Subject: [PATCH 1/2] Behave acceptance tests - Sign up - Sign in - Edit profile Signed-off-by: Gabriel Silva Signed-off-by: Italo Paiva Signed-off-by: Emiliemorais Signed-off-by: Matheus S. Pereira Signed-off-by: Caique Pereira Signed-off-by: Matheus S. Pereira --- colab/settings.py | 1 + features/environment.py | 19 +++++++ features/home_redirect.feature | 1 + features/profile_edition.feature | 79 +++++++++++++++++++++++++ features/steps/home.py | 9 --- features/steps/user_steps.py | 40 +++++++++++++ features/steps/web_steps.py | 54 ++++++++++++++++++ features/user_sign_in.feature | 98 ++++++++++++++++++++++++++++++++ features/user_sign_up.feature | 57 +++++++++++++++++++ setup.py | 6 +- vagrant/centos.sh | 3 + vagrant/ubuntu.sh | 4 ++ 12 files changed, 360 insertions(+), 11 deletions(-) create mode 100644 features/environment.py create mode 100644 features/profile_edition.feature delete mode 100644 features/steps/home.py create mode 100644 features/steps/user_steps.py create mode 100644 features/steps/web_steps.py create mode 100644 features/user_sign_in.feature create mode 100644 features/user_sign_up.feature diff --git a/colab/settings.py b/colab/settings.py index e4bf25a6..47768cd7 100644 --- a/colab/settings.py +++ b/colab/settings.py @@ -58,6 +58,7 @@ 'haystack', 'hitcounter', 'taggit', + 'behave_django', # Own apps 'colab', diff --git a/features/environment.py b/features/environment.py new file mode 100644 index 00000000..ec491a11 --- /dev/null +++ b/features/environment.py @@ -0,0 +1,19 @@ +from selenium import webdriver +from django.conf import settings + + +def before_all(context): + # Otherwise the ManifestStaticFilesStorage will use hashed names + settings.DEBUG = True + +def before_feature(context, feature): + if 'selenium' in feature.tags: + context.driver = webdriver.Firefox() + context.driver.set_window_size(1000, 600) + context.driver.implicitly_wait(5) + else: + context.driver = webdriver.PhantomJS() + + +def after_feature(context, feature): + context.driver.quit() diff --git a/features/home_redirect.feature b/features/home_redirect.feature index d9b7c45f..eca97306 100644 --- a/features/home_redirect.feature +++ b/features/home_redirect.feature @@ -1,4 +1,5 @@ +@selenium Feature: Home redirect In order to be able to choose the home page As a developer diff --git a/features/profile_edition.feature b/features/profile_edition.feature new file mode 100644 index 00000000..2863b83f --- /dev/null +++ b/features/profile_edition.feature @@ -0,0 +1,79 @@ +@selenium +Feature: User Profile Edition + In order to update my personal information + As an User + I want to be able to edit my profile + + Background: + Given I am logged in as "john" + + Scenario: Edit profile without required information + When I open the user menu + When I click in "My Profile" + When I click in "Edit Profile" + When I fill " " in "id_first_name" field + When I fill " " in "id_last_name" field + When I click in "Update" button + Then The field "id_first_name" should have an error + Then The field "id_last_name" should have an error + + Scenario: Edit profile with valid information + When I open the user menu + When I click in "My Profile" + When I click in "Edit Profile" + When I fill "John" in "id_first_name" field + When I fill "McClaine" in "id_last_name" field + When I fill "Die Hard" in "id_institution" field + When I fill "police officer" in "id_role" field + When I fill "diehard.com" in "id_webpage" field + When I fill "I am tough." in "id_bio" field + When I click in "Update" button + Then I should see "John McClaine" in "user-profile" + Then I should see "Die Hard" in "user-profile" + Then I should see "police officer" in "user-profile" + Then I should see "I am tough." in "user-profile" + When I click in "Edit Profile" + Then I should see "diehard.com" in "id_webpage" + + Scenario: Change password with wrong current password + When I open the user menu + When I click in "My Profile" + When I click in "Edit Profile" + When I click in "Change Password" + When I fill "wrong" in "id_old_password" field + When I fill "newpassword" in "id_new_password1" field + When I fill "newpassword" in "id_new_password2" field + When I click in "Change my password" button + Then The field "id_old_password" should have an error + + Scenario: Change password with wrong password confirmation + When I open the user menu + When I click in "My Profile" + When I click in "Edit Profile" + When I click in "Change Password" + When I fill "john" in "id_old_password" field + When I fill "newpassword" in "id_new_password1" field + When I fill "differentpassword" in "id_new_password2" field + When I click in "Change my password" button + Then The field "id_new_password2" should have an error + + Scenario: Change password with success + When I open the user menu + When I click in "My Profile" + When I click in "Edit Profile" + When I click in "Change Password" + When I fill "john" in "id_old_password" field + When I fill "newpassword" in "id_new_password1" field + When I fill "newpassword" in "id_new_password2" field + When I click in "Change my password" button + When I open the user menu + When I click in "My Profile" + When I open the user menu + When I click in "Logout" + When I click in "Acesso " + When I click in "Login" + When I fill "john" in "id_username" field + When I fill "newpassword" in "id_password" field + When I click in "Acesso " + When I click in "Login" button + Then The browser URL should be "/dashboard" \ No newline at end of file diff --git a/features/steps/home.py b/features/steps/home.py deleted file mode 100644 index 5896f0fc..00000000 --- a/features/steps/home.py +++ /dev/null @@ -1,9 +0,0 @@ - - -@when(u'I access the URL "{url}"') -def step_impl(context, url): - context.response = context.test.client.get(url) - -@then(u'The browser URL should be "{url}"') -def step_impl(context, url): - context.test.assertRedirects(context.response, url, status_code=301) diff --git a/features/steps/user_steps.py b/features/steps/user_steps.py new file mode 100644 index 00000000..d981c647 --- /dev/null +++ b/features/steps/user_steps.py @@ -0,0 +1,40 @@ +from colab.accounts.models import User +from behave import given, when + + +@given(u'The user "{username}" with the password "{password}" is "{status}"') +def create_user(context, username, password, status): + user = User() + user.username = username + user.set_password(password) + user.email = "usertest@colab.com.br" + user.id = 1 + user.twitter = "usertestcolab" + user.facebook = "usertestcolab" + user.first_name = "USERtestCoLaB" + user.last_name = "COLAB" + user.needs_update = False + if status == "active": + user.is_active = True + else: + user.is_active = False + user.save() + + +@given(u'I am logged in as "{username}"') +def step_impl(context, username): + context.execute_steps(''' + When I access the URL "/" + When I click in "Acesso " + When I click in "Login" + Given The user "%s" with the password "%s" is "%s" + When I fill "%s" in "id_username" field + When I fill "%s" in "id_password" field + When I click in "Login" button + ''' % (username, username, 'active', username, username)) + + +@when(u'I open the user menu') +def step_impl(context): + dropdown = context.driver.find_element_by_id('user-menu') + dropdown.find_element_by_xpath('.//a').click() diff --git a/features/steps/web_steps.py b/features/steps/web_steps.py new file mode 100644 index 00000000..4f232da2 --- /dev/null +++ b/features/steps/web_steps.py @@ -0,0 +1,54 @@ +from selenium.webdriver.common.keys import Keys +from behave import when, then + + +@when(u'I access the URL "{url}"') +def step_impl(context, url): + context.driver.get(context.base_url + "/") + + +@when(u'I click in "{link}"') +def step_impl(context, link): + context.driver.find_element_by_xpath("//a[contains(., '%s')]" % link).click() + + +@when(u'I click in "{button_value}" button') +def step_impl(context, button_value): + context.driver.find_element_by_xpath( + "//input[@value='%s']|//button[.='%s']" % + (button_value, button_value)).click() + + +@when(u'I fill "{text}" in "{field_id}" field') +def step_impl(context, text, field_id): + field = context.driver.find_element_by_id(field_id) + field.clear() + field.send_keys(text) + + +@when(u'I fill "{text}" in "{field_id}" field and hit enter') +def step_impl(context, text, field_id): + field = context.driver.find_element_by_id(field_id) + field.clear() + field.send_keys(text) + field.send_keys(Keys.RETURN) + + +@then(u'The field "{field_id}" should have an error') +def step_impl(context, field_id): + field = context.driver.find_element_by_id(field_id) + container = field.find_element_by_xpath('..') + classes = container.get_attribute('class') + assert 'has-error' in classes + + +@then(u'I should see "{content}" in "{element_id}"') +def step_impl(context, content, element_id): + element = context.driver.find_element_by_id(element_id) + assert (content in element.text) or \ + (content in element.get_attribute("value")) + + +@then(u'The browser URL should be "{url}"') +def step_impl(context, url): + assert context.driver.current_url.endswith(url) diff --git a/features/user_sign_in.feature b/features/user_sign_in.feature new file mode 100644 index 00000000..de1cbbcd --- /dev/null +++ b/features/user_sign_in.feature @@ -0,0 +1,98 @@ + +@selenium +Feature: User sign in + In order to be able to access the system funcionalities + As an User + I want to be able to sign in + + # Valid scenarios + + Scenario: Clicking the login button and displaying login page + When I access the URL "/" + When I click in "Acesso " + When I click in "Login" + Then The browser URL should be "/account/login" + + Scenario: Sign in with a valid user + Given The user "colabtest" with the password "colabtest" is "active" + When I access the URL "/" + When I click in "Acesso " + When I click in "Login" + When I fill "colabtest" in "id_username" field + When I fill "colabtest" in "id_password" field + When I click in "Login" button + Then The browser URL should be "/dashboard" + + Scenario: Sign in with a valid user by hitting ENTER + Given The user "colabtest" with the password "colabtest" is "active" + When I access the URL "/" + When I click in "Acesso " + When I click in "Login" + When I fill "colabtest" in "id_username" field + When I fill "colabtest" in "id_password" field and hit enter + Then The browser URL should be "/dashboard" + + Scenario: Sign in with a valid user and displaying user profile + Given The user "colabtest" with the password "colabtest" is "active" + When I access the URL "/" + When I click in "Acesso " + When I click in "Login" + When I fill "colabtest" in "id_username" field + When I fill "colabtest" in "id_password" field + When I click in "Login" button + Then The browser URL should be "/dashboard" + When I open the user menu + Then I should see "USERtestCoLaB COLAB" in "user-menu" + Then I should see "usertest@colab.com.br" in "user-menu" + + + # Invalid scenarios + + Scenario: Sign in with an unregistered user + When I access the URL "/" + When I click in "Acesso " + When I click in "Login" + When I fill "unregistered" in "id_username" field + When I fill "any" in "id_password" field + When I click in "Login" button + Then The browser URL should be "/account/login" + Then I should see "Please correct the error below and try again" in "main-content" + + Scenario: Sign in with a inactive user + Given The user "colabtest" with the password "colabtest" is "inactive" + When I access the URL "/" + When I click in "Acesso " + When I click in "Login" + When I fill "colabtest" in "id_username" field + When I fill "colabtest" in "id_password" field + When I click in "Login" button + Then The browser URL should be "/account/login" + Then I should see "This account is inactive" in "main-content" + + Scenario: Sign in with no user information given + When I access the URL "/" + When I click in "Acesso " + When I click in "Login" + When I click in "Login" button + Then The browser URL should be "/account/login" + Then The field "id_username" should have an error + Then The field "id_password" should have an error + + Scenario: Sign in with no password given + When I access the URL "/" + When I click in "Acesso " + When I click in "Login" + When I fill "colabtest" in "id_username" field + When I click in "Login" button + Then The browser URL should be "/account/login" + Then The field "id_password" should have an error + + Scenario: Sign in with no username given + When I access the URL "/" + When I click in "Acesso " + When I click in "Login" + When I fill "colabtest" in "id_password" field + When I click in "Login" button + Then The browser URL should be "/account/login" + Then The field "id_username" should have an error + diff --git a/features/user_sign_up.feature b/features/user_sign_up.feature new file mode 100644 index 00000000..4fa7d616 --- /dev/null +++ b/features/user_sign_up.feature @@ -0,0 +1,57 @@ +@selenium +Feature: User Sign Up + In order to use the system + As an User + I want to be able to sign up + + Scenario: Sign up with no information + When I access the URL "/" + When I click in "Acesso " + When I click in "Register" + When I click in "Register" button + Then The field "id_username" should have an error + Then The field "id_first_name" should have an error + Then The field "id_last_name" should have an error + Then The field "id_email" should have an error + Then The field "id_password1" should have an error + Then The field "id_password2" should have an error + + Scenario: Sign up with all required information + When I access the URL "/" + When I click in "Acesso " + When I click in "Register" + When I fill "johndiehard" in "id_username" field + When I fill "John" in "id_first_name" field + When I fill "McClane" in "id_last_name" field + When I fill "john@email.com" in "id_email" field + When I fill "100guns100" in "id_password1" field + When I fill "100guns100" in "id_password2" field + When I click in "Register" button + Then The browser URL should be "/account/johndiehard" + Then I should see "John McClane" in "user-profile" + + Scenario: Sign up with invalid email + When I access the URL "/" + When I click in "Acesso " + When I click in "Register" + When I fill "johndiehard" in "id_username" field + When I fill "John" in "id_first_name" field + When I fill "McClane" in "id_last_name" field + When I fill "john@email" in "id_email" field + When I fill "100guns100" in "id_password1" field + When I fill "100guns100" in "id_password2" field + When I click in "Register" button + Then The field "id_email" should have an error + + Scenario: Sign up with different passwords + When I access the URL "/" + When I click in "Acesso " + When I click in "Register" + When I fill "johndiehard" in "id_username" field + When I fill "John" in "id_first_name" field + When I fill "McClane" in "id_last_name" field + When I fill "john@email.com" in "id_email" field + When I fill "100guns100" in "id_password1" field + When I fill "100guns999" in "id_password2" field + When I click in "Register" button + Then The field "id_password2" should have an error diff --git a/setup.py b/setup.py index 8cb9f428..afc212bd 100644 --- a/setup.py +++ b/setup.py @@ -17,6 +17,10 @@ # Async Signals 'celery[redis]>=3.1.2', + # Acceptance tests + 'selenium>=2.53.1', + 'behave_django>=0.3.0', + ### Move out of colab (as plugins): # Deps for super_archives @@ -32,8 +36,6 @@ 'coveralls>=0.5', 'flake8>=2.3.0', 'mock==1.0.1', - 'behave>= 1.2.0', - 'behave_django>=0.2.2', ] diff --git a/vagrant/centos.sh b/vagrant/centos.sh index e477896d..973ff73e 100755 --- a/vagrant/centos.sh +++ b/vagrant/centos.sh @@ -24,6 +24,9 @@ yum -y groupinstall "Development tools" yum install -y git unzip gettext libxml2-devel libxslt-devel openssl-devel libffi-devel python-devel python-pip python-virtualenvwrapper redis +### Acceptance Tests dependencies + +yum install -y Xvfb firefox ### Init Redis systemctl enable redis diff --git a/vagrant/ubuntu.sh b/vagrant/ubuntu.sh index f145a588..8c451697 100755 --- a/vagrant/ubuntu.sh +++ b/vagrant/ubuntu.sh @@ -6,3 +6,7 @@ set -ex apt-get update apt-get install curl git unzip build-essential gettext libxml2-dev libxslt1-dev libssl-dev libffi-dev python-dev virtualenvwrapper python-pip redis-server -y + +### Acceptance Tests dependencies + +apt-get install xvfb firefox -y \ No newline at end of file From 145a411b9ae02865c309d0ca7a7c354e30fa194d Mon Sep 17 00:00:00 2001 From: Italo Paiva Date: Tue, 5 Apr 2016 17:57:43 -0300 Subject: [PATCH 2/2] Adding the process to run acceptance tests to the README Signed-off-by: Emiliemorais Signed-off-by: Italo Paiva --- .travis.yml | 10 +++++-- README.rst | 49 ++++++++++++++++++++++++++++++++ colab/settings.py | 1 - features/environment.py | 14 ++------- features/home_redirect.feature | 1 - features/profile_edition.feature | 4 +-- features/steps/user_steps.py | 2 -- features/steps/web_steps.py | 3 +- features/user_sign_in.feature | 1 - features/user_sign_up.feature | 2 +- 10 files changed, 65 insertions(+), 22 deletions(-) diff --git a/.travis.yml b/.travis.yml index 01d28440..2dd25a06 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,17 +5,23 @@ sudo: false python: - "2.7" +addons: + apt: + packages: + - xvfb + - firefox + env: global: - COLAB_SETTINGS=tests/colab_settings.py install: - - pip install coveralls flake8 behave behave_django + - pip install coveralls flake8 behave behave_django selenium - pip install . script: - python setup.py test - - colab-admin behave + - xvfb-run -a colab-admin behave --format=progress - flake8 colab after_success: diff --git a/README.rst b/README.rst index 14682e69..6e8ba39e 100644 --- a/README.rst +++ b/README.rst @@ -129,3 +129,52 @@ Follow the steps below: .. code-block:: python setup.py test + +How to run Acceptance Tests +--------------------------- + +Follow the steps below to run the acceptance tests. + +1- Log in virtual machine: + +1.1 - To run without opening a graphic interface + +.. code-block:: + + vagrant ssh + +1.2 - To run opening a graphic interface + +.. code-block:: + + vagrant ssh -- -X + +2- Use colab virtualenv: + +.. code-block:: + + workon colab + +3- Enter into colab source code directory: + +.. code-block:: + + cd /vagrant + +4- Run all the acceptance tests with: + +.. code-block:: + + COLAB_SETTINGS=tests/colab_settings.py colab-admin behave + +4.1 To run without opening a browser: +.. code-block:: + + COLAB_SETTINGS=tests/colab_settings.py xvfb-run -a colab-admin behave + +4.2 To run a specific feature: + +.. code-block:: + + COLAB_SETTINGS=tests/colab_settings.py colab-admin behave /path/to/features/file.feature + diff --git a/colab/settings.py b/colab/settings.py index 47768cd7..e4bf25a6 100644 --- a/colab/settings.py +++ b/colab/settings.py @@ -58,7 +58,6 @@ 'haystack', 'hitcounter', 'taggit', - 'behave_django', # Own apps 'colab', diff --git a/features/environment.py b/features/environment.py index ec491a11..ce081d4f 100644 --- a/features/environment.py +++ b/features/environment.py @@ -1,18 +1,10 @@ from selenium import webdriver -from django.conf import settings -def before_all(context): - # Otherwise the ManifestStaticFilesStorage will use hashed names - settings.DEBUG = True - def before_feature(context, feature): - if 'selenium' in feature.tags: - context.driver = webdriver.Firefox() - context.driver.set_window_size(1000, 600) - context.driver.implicitly_wait(5) - else: - context.driver = webdriver.PhantomJS() + context.driver = webdriver.Firefox() + context.driver.set_window_size(1000, 600) + context.driver.implicitly_wait(5) def after_feature(context, feature): diff --git a/features/home_redirect.feature b/features/home_redirect.feature index eca97306..d9b7c45f 100644 --- a/features/home_redirect.feature +++ b/features/home_redirect.feature @@ -1,5 +1,4 @@ -@selenium Feature: Home redirect In order to be able to choose the home page As a developer diff --git a/features/profile_edition.feature b/features/profile_edition.feature index 2863b83f..41c1d827 100644 --- a/features/profile_edition.feature +++ b/features/profile_edition.feature @@ -1,4 +1,4 @@ -@selenium + Feature: User Profile Edition In order to update my personal information As an User @@ -76,4 +76,4 @@ Feature: User Profile Edition When I fill "newpassword" in "id_password" field When I click in "Acesso " When I click in "Login" button - Then The browser URL should be "/dashboard" \ No newline at end of file + Then The browser URL should be "/dashboard" diff --git a/features/steps/user_steps.py b/features/steps/user_steps.py index d981c647..961fe065 100644 --- a/features/steps/user_steps.py +++ b/features/steps/user_steps.py @@ -9,8 +9,6 @@ def create_user(context, username, password, status): user.set_password(password) user.email = "usertest@colab.com.br" user.id = 1 - user.twitter = "usertestcolab" - user.facebook = "usertestcolab" user.first_name = "USERtestCoLaB" user.last_name = "COLAB" user.needs_update = False diff --git a/features/steps/web_steps.py b/features/steps/web_steps.py index 4f232da2..ea92a9cf 100644 --- a/features/steps/web_steps.py +++ b/features/steps/web_steps.py @@ -9,7 +9,8 @@ def step_impl(context, url): @when(u'I click in "{link}"') def step_impl(context, link): - context.driver.find_element_by_xpath("//a[contains(., '%s')]" % link).click() + context.driver.find_element_by_xpath("//a[contains(., '%s')]" % + link).click() @when(u'I click in "{button_value}" button') diff --git a/features/user_sign_in.feature b/features/user_sign_in.feature index de1cbbcd..cb082761 100644 --- a/features/user_sign_in.feature +++ b/features/user_sign_in.feature @@ -1,5 +1,4 @@ -@selenium Feature: User sign in In order to be able to access the system funcionalities As an User diff --git a/features/user_sign_up.feature b/features/user_sign_up.feature index 4fa7d616..ee59afa4 100644 --- a/features/user_sign_up.feature +++ b/features/user_sign_up.feature @@ -1,4 +1,4 @@ -@selenium + Feature: User Sign Up In order to use the system As an User