API & Client - replace testcafe with selenium for e2e tests

This commit is contained in:
Sam
2020-09-13 21:39:44 +02:00
parent f626559e5e
commit 1ad847c857
12 changed files with 481 additions and 5 deletions

0
e2e/__init__.py Normal file
View File

38
e2e/test_activities.py Normal file
View File

@ -0,0 +1,38 @@
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select, WebDriverWait
from .utils import TEST_URL, register_valid_user
class TestActivity:
def test_user_can_add_activity_without_gpx(self, selenium):
register_valid_user(selenium)
nav_items = selenium.find_elements_by_class_name('nav-item')
nav_items[3].click()
selenium.implicitly_wait(1)
radio_buttons = selenium.find_elements_by_class_name(
'add-activity-radio'
)
radio_buttons[1].click()
selenium.find_element_by_name('title').send_keys('Activity title')
select = Select(selenium.find_element_by_name('sport_id'))
select.select_by_index(1)
selenium.find_element_by_name('activity_date').send_keys('2018-12-20')
selenium.find_element_by_name('activity_time').send_keys('14:05')
selenium.find_element_by_name('duration').send_keys('01:00:00')
selenium.find_element_by_name('distance').send_keys('10')
selenium.find_element_by_class_name('btn-primary').click()
WebDriverWait(selenium, 10).until(
EC.url_changes(f"{TEST_URL}/activities/add")
)
activity_details = selenium.find_element_by_class_name(
'activity-details'
).text
assert 'Duration: 1:00:00' in activity_details
assert 'Distance: 10 km' in activity_details
assert 'Average speed: 10 km/h' in activity_details
assert 'Max. speed: 10 km/h' in activity_details

17
e2e/test_index.py Normal file
View File

@ -0,0 +1,17 @@
from .utils import TEST_URL
class TestIndex:
def test_title_contains_fittrackee(self, selenium):
selenium.get(TEST_URL)
assert 'FitTrackee' in selenium.title
def test_navbar_contains_all_links(self, selenium):
selenium.get(TEST_URL)
nav = selenium.find_element_by_tag_name('nav').text
assert "FitTrackee" in nav
assert "Dashboard" in nav
assert "Login" in nav
assert "Register" in nav
assert "en" in nav

40
e2e/test_login.py Normal file
View File

@ -0,0 +1,40 @@
from .utils import TEST_URL, assert_navbar, login_valid_user
URL = f'{TEST_URL}/login'
class TestLogin:
def test_navbar_contains_login(self, selenium):
selenium.get(URL)
nav = selenium.find_element_by_tag_name('nav').text
assert 'Login' in nav
def test_h1_contains_login(self, selenium):
selenium.get(URL)
title = selenium.find_element_by_tag_name('h1').text
assert 'Login' in title
def test_it_displays_login_form(self, selenium):
selenium.get(URL)
inputs = selenium.find_elements_by_tag_name('input')
assert len(inputs) == 3
assert inputs[0].get_attribute('name') == 'email'
assert inputs[0].get_attribute('type') == 'email'
assert inputs[1].get_attribute('name') == 'password'
assert inputs[1].get_attribute('type') == 'password'
assert inputs[2].get_attribute('name') == ''
assert inputs[2].get_attribute('type') == 'submit'
def test_user_can_log_in(self, selenium):
user = {
'username': 'admin',
'email': 'admin@example.com',
'password': 'mpwoadmin',
}
login_valid_user(selenium, user)
assert_navbar(selenium, user)

19
e2e/test_logout.py Normal file
View File

@ -0,0 +1,19 @@
from .utils import register_valid_user
class TestLogout:
def test_user_can_log_out(self, selenium):
user = register_valid_user(selenium)
nav_items = selenium.find_elements_by_class_name('nav-item')
nav_items[5].click()
selenium.implicitly_wait(1)
nav = selenium.find_element_by_tag_name('nav').text
assert 'Register' in nav
assert 'Login' in nav
assert user['username'] not in nav
assert 'Logout' not in nav
message = selenium.find_element_by_class_name('card-body').text
assert 'You are now logged out. Click here to log back in.' in message

20
e2e/test_profile.py Normal file
View File

@ -0,0 +1,20 @@
from .utils import TEST_URL, register_valid_user
URL = f'{TEST_URL}/profile'
class TestProfile:
def test_it_displays_user_profile(self, selenium):
user = register_valid_user(selenium)
selenium.get(URL)
assert 'Profile' in selenium.find_element_by_tag_name('h1').text
assert (
user['username']
in selenium.find_element_by_class_name('userName').text
)
assert (
user['username']
in selenium.find_element_by_class_name('userName').text
)

141
e2e/test_registration.py Normal file
View File

@ -0,0 +1,141 @@
from .utils import (
TEST_URL,
assert_navbar,
random_string,
register,
register_valid_user,
)
URL = f'{TEST_URL}/register'
class TestRegistration:
def test_it_displays_registration_form(self, selenium):
selenium.get(URL)
selenium.implicitly_wait(1)
inputs = selenium.find_elements_by_tag_name('input')
assert len(inputs) == 5
assert inputs[0].get_attribute('name') == 'username'
assert inputs[0].get_attribute('type') == 'text'
assert inputs[1].get_attribute('name') == 'email'
assert inputs[1].get_attribute('type') == 'email'
assert inputs[2].get_attribute('name') == 'password'
assert inputs[2].get_attribute('type') == 'password'
assert inputs[3].get_attribute('name') == 'password_conf'
assert inputs[3].get_attribute('type') == 'password'
assert inputs[4].get_attribute('name') == ''
assert inputs[4].get_attribute('type') == 'submit'
def test_user_can_register(self, selenium):
user = register_valid_user(selenium)
assert_navbar(selenium, user)
def test_user_can_not_register_with_invalid_email(self, selenium):
user_name = random_string()
user_infos = {
'username': user_name,
'email': user_name,
'password': 'p@ssw0rd',
'password_conf': 'p@ssw0rd',
}
register(selenium, user_infos)
assert selenium.current_url == URL
nav = selenium.find_element_by_tag_name('nav').text
assert 'Register' in nav
assert 'Login' in nav
def test_user_can_not_register_if_username_is_already_taken(
self, selenium
):
user_name = random_string()
user_infos = {
'username': 'admin',
'email': f'{user_name}@example.com',
'password': 'p@ssw0rd',
'password_conf': 'p@ssw0rd',
}
register(selenium, user_infos)
assert selenium.current_url == URL
errors = selenium.find_element_by_tag_name('code').text
assert 'Sorry. That user already exists.' in errors
def test_user_can_not_register_if_email_is_already_taken(self, selenium):
user_name = random_string()
user_infos = {
'username': user_name,
'email': 'admin@example.com',
'password': 'p@ssw0rd',
'password_conf': 'p@ssw0rd',
}
register(selenium, user_infos)
assert selenium.current_url == URL
errors = selenium.find_element_by_tag_name('code').text
assert 'Sorry. That user already exists.' in errors
def test_user_can_not_register_if_username_is_too_short(self, selenium):
user_name = random_string(2)
user_infos = {
'username': user_name,
'email': 'admin@example.com',
'password': 'p@ssw0rd',
'password_conf': 'p@ssw0rd',
}
register(selenium, user_infos)
assert selenium.current_url == URL
errors = selenium.find_element_by_tag_name('code').text
assert '3 to 12 characters required for username.' in errors
def test_user_can_not_register_if_username_is_too_long(self, selenium):
user_name = random_string(13)
user_infos = {
'username': user_name,
'email': 'admin@example.com',
'password': 'p@ssw0rd',
'password_conf': 'p@ssw0rd',
}
register(selenium, user_infos)
assert selenium.current_url == URL
errors = selenium.find_element_by_tag_name('code').text
assert '3 to 12 characters required for username.' in errors
def test_it_displays_error_if_passwords_do_not_match(self, selenium):
user_name = random_string()
user_infos = {
'username': user_name,
'email': f'{user_name}@example.com',
'password': 'p@ssw0rd',
'password_conf': 'password',
}
register(selenium, user_infos)
assert selenium.current_url == URL
errors = selenium.find_element_by_tag_name('code').text
assert 'Password and password confirmation don\'t match' in errors
def test_it_displays_error_if_password_is_too_short(self, selenium):
user_name = random_string()
user_infos = {
'username': user_name,
'email': f'{user_name}@example.com',
'password': 'p@ss',
'password_conf': 'p@ss',
}
register(selenium, user_infos)
assert selenium.current_url == URL
errors = selenium.find_element_by_tag_name('code').text
assert '8 characters required for password.' in errors

73
e2e/utils.py Normal file
View File

@ -0,0 +1,73 @@
import os
import random
import string
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
TEST_APP_URL = os.getenv('TEST_APP_URL')
TEST_CLIENT_URL = os.getenv('TEST_CLIENT_URL')
E2E_ARGS = os.getenv('E2E_ARGS')
TEST_URL = TEST_CLIENT_URL if E2E_ARGS == 'client' else TEST_APP_URL
def random_string(length=8):
return ''.join(random.choice(string.ascii_letters) for x in range(length))
def register(selenium, user):
selenium.get(f'{TEST_URL}/register')
selenium.implicitly_wait(1)
username = selenium.find_element_by_name('username')
username.send_keys(user.get('username'))
email = selenium.find_element_by_name('email')
email.send_keys(user.get('email'))
password = selenium.find_element_by_name('password')
password.send_keys(user.get('password'))
password_conf = selenium.find_element_by_name('password_conf')
password_conf.send_keys(user.get('password_conf'))
submit_button = selenium.find_element_by_class_name('btn')
submit_button.click()
def login(selenium, user):
selenium.get(f'{TEST_URL}/login')
selenium.implicitly_wait(1)
email = selenium.find_element_by_name('email')
email.send_keys(user.get('email'))
password = selenium.find_element_by_name('password')
password.send_keys(user.get('password'))
submit_button = selenium.find_element_by_class_name('btn')
submit_button.click()
def register_valid_user(selenium):
user_name = random_string()
user = {
'username': user_name,
'email': f'{user_name}@example.com',
'password': 'p@ssw0rd',
'password_conf': 'p@ssw0rd',
}
register(selenium, user)
WebDriverWait(selenium, 10).until(EC.url_changes(f"{TEST_URL}/register"))
return user
def login_valid_user(selenium, user):
login(selenium, user)
WebDriverWait(selenium, 10).until(EC.url_changes(f"{TEST_URL}/login"))
return user
def assert_navbar(selenium, user):
nav = selenium.find_element_by_tag_name('nav').text
assert 'Register' not in nav
assert 'Login' not in nav
assert 'Dashboard' in nav
assert 'Workouts' in nav
assert 'Statistics' in nav
assert 'Add workout' in nav
assert user['username'] in nav
assert 'Logout' in nav
assert 'en' in nav