Commit 229a37b9 by Usman Khalid Committed by Andy Armstrong

Bokchoy tests for account settings page.

TNL-1499
parent 9c2d1871
"""
Base class for account settings page.
"""
from . import BASE_URL
from bok_choy.page_object import PageObject
from bok_choy.promise import EmptyPromise
from .fields import FieldsMixin
class AccountSettingsPage(FieldsMixin, PageObject):
"""
Tests for Account Settings Page.
"""
url = "{base}/{settings}".format(base=BASE_URL, settings='account/settings')
def is_browser_on_page(self):
return 'Account Settings' in self.browser.title
def sections_structure(self):
"""
Return list of section titles and field titles for each section.
Example: [
{
'title': 'Section Title'
'fields': ['Field 1 title', 'Field 2 title',...]
},
...
]
"""
self.wait_for_ajax()
structure = []
sections = self.q(css='.section')
for section in sections:
section_title_element = section.find_element_by_class_name('section-header')
field_title_elements = section.find_elements_by_class_name('u-field-title')
structure.append({
'title': section_title_element.text,
'fields': [element.text for element in field_title_elements],
})
return structure
def _is_loading_in_progress(self):
"""
Check if loading indicator is visible.
"""
query = self.q(css='.ui-loading-indicator')
return query.present and 'is-hidden' not in query.attrs('class')[0].split()
def wait_for_loading_indicator(self):
"""
Wait for loading indicator to become visible.
"""
EmptyPromise(self._is_loading_in_progress, "Loading is in progress.").fulfill()
......@@ -183,3 +183,22 @@ class DashboardPage(PageObject):
def get_course_social_sharing_widget(self, widget_name):
""" Retrieves the specified social sharing widget by its classification """
return self.q(css='a.action-{}'.format(widget_name))
def click_username_dropdown(self):
"""
Click username dropdown.
"""
self.q(css='.dropdown').first.click()
@property
def username_dropdown_link_text(self):
"""
Return list username dropdown links.
"""
return self.q(css='.dropdown-menu li a').text
def click_account_settings_link(self):
"""
Click on `Account Settings` link.
"""
self.q(css='.dropdown-menu li a').first.click()
# -*- coding: utf-8 -*-
"""
Mixins for fields.
"""
from bok_choy.promise import EmptyPromise
from ...tests.helpers import get_selected_option_text, select_option_by_text
class FieldsMixin(object):
"""
Methods for testing fields in pages.
"""
def field(self, field_id):
"""
Return field with field_id.
"""
self.wait_for_ajax()
query = self.q(css='.u-field-{}'.format(field_id))
return query.text[0] if query.present else None
def wait_for_field(self, field_id):
"""
Wait for a field to appear in DOM.
"""
EmptyPromise(
lambda: self.field(field_id) is not None,
"Field with id \"{0}\" is in DOM.".format(field_id)
).fulfill()
def title_for_field(self, field_id):
"""
Return the title of a field.
"""
self.wait_for_field(field_id)
query = self.q(css='.u-field-{} .u-field-title'.format(field_id))
return query.text[0] if query.present else None
def message_for_field(self, field_id):
"""
Return the current message in a field.
"""
self.wait_for_field(field_id)
query = self.q(css='.u-field-{} .u-field-message'.format(field_id))
return query.text[0] if query.present else None
def wait_for_messsage(self, field_id, message):
"""
Wait for a message to appear in a field.
"""
EmptyPromise(
lambda: message in (self.message_for_field(field_id) or ''),
"Messsage \"{0}\" is visible.".format(message)
).fulfill()
def indicator_for_field(self, field_id):
"""
Return the name of the current indicator in a field.
"""
self.wait_for_field(field_id)
query = self.q(css='.u-field-{} .u-field-message i'.format(field_id))
return [
class_name for class_name
in query.attrs('class')[0].split(' ')
if class_name.startswith('message')
][0].partition('-')[2] if query.present else None
def wait_for_indicator(self, field_id, indicator):
"""
Wait for an indicator to appear in a field.
"""
EmptyPromise(
lambda: indicator == self.indicator_for_field(field_id),
"Indicator \"{0}\" is visible.".format(self.indicator_for_field(field_id))
).fulfill()
def value_for_readonly_field(self, field_id):
"""
Return the value in a readonly field.
"""
self.wait_for_field(field_id)
return self.value_for_text_field(field_id)
def value_for_text_field(self, field_id, value=None):
"""
Get or set the value of a text field.
"""
self.wait_for_field(field_id)
query = self.q(css='.u-field-{} input'.format(field_id))
if not query.present:
return None
if value is not None:
current_value = query.attrs('value')[0]
query.results[0].send_keys(u'\ue003' * len(current_value)) # Delete existing value.
query.results[0].send_keys(value) # Input new value
query.results[0].send_keys(u'\ue007') # Press Enter
return query.attrs('value')[0]
def value_for_dropdown_field(self, field_id, value=None):
"""
Get or set the value in a dropdown field.
"""
self.wait_for_field(field_id)
query = self.q(css='.u-field-{} select'.format(field_id))
if not query.present:
return None
if value is not None:
select_option_by_text(query, value)
return get_selected_option_text(query)
def link_title_for_link_field(self, field_id):
"""
Return the title of the link in a link field.
"""
self.wait_for_field(field_id)
query = self.q(css='.u-field-{} a'.format(field_id))
return query.text[0] if query.present else None
def click_on_link_in_link_field(self, field_id):
"""
Click the link in a link field.
"""
self.wait_for_field(field_id)
query = self.q(css='.u-field-{} a'.format(field_id))
if query.present:
query.first.click()
# -*- coding: utf-8 -*-
"""
End-to-end tests for the Account Settings page.
"""
from unittest import skip
from bok_choy.web_app_test import WebAppTest
from ...pages.lms.account_settings import AccountSettingsPage
from ...pages.lms.auto_auth import AutoAuthPage
from ...pages.lms.dashboard import DashboardPage
class AccountSettingsPageTest(WebAppTest):
"""
Tests that verify behaviour of the Account Settings page.
"""
SUCCESS_MESSAGE = 'Your changes have been saved.'
USERNAME = "test"
PASSWORD = "testpass"
EMAIL = "test@example.com"
def setUp(self):
"""
Initialize account and pages.
"""
super(AccountSettingsPageTest, self).setUp()
AutoAuthPage(self.browser, username=self.USERNAME, password=self.PASSWORD, email=self.EMAIL).visit()
self.account_settings_page = AccountSettingsPage(self.browser)
self.account_settings_page.visit()
def test_link_on_dashboard_works(self):
"""
Scenario: Verify that account settings link is present in dashboard
page and we can use it to navigate to the page.
"""
dashboard_page = DashboardPage(self.browser)
dashboard_page.visit()
dashboard_page.click_username_dropdown()
self.assertIn('Account Settings', dashboard_page.username_dropdown_link_text)
dashboard_page.click_account_settings_link()
def test_all_sections_and_fields_are_present(self):
"""
Scenario: Verify that all sections and fields are present on the page.
"""
expected_sections_structure = [
{
'title': 'Basic Account Information (required)',
'fields': [
'Username',
'Full Name',
'Email Address',
'Password',
'Language',
]
},
{
'title': 'Additional Information (optional)',
'fields': [
'Education Completed',
'Gender',
'Year of Birth',
'Country or Region',
'Preferred Language',
]
},
{
'title': 'Connected Accounts',
'fields': [
'Facebook',
'Google',
]
}
]
self.assertEqual(self.account_settings_page.sections_structure(), expected_sections_structure)
def _test_readonly_field(self, field_id, title, value):
"""
Test behavior of a readonly field.
"""
self.assertEqual(self.account_settings_page.title_for_field(field_id), title)
self.assertEqual(self.account_settings_page.value_for_readonly_field(field_id), value)
def _test_text_field(
self, field_id, title, initial_value, new_invalid_value, new_valid_values, success_message=SUCCESS_MESSAGE,
assert_after_reload=True
):
"""
Test behaviour of a text field.
"""
self.assertEqual(self.account_settings_page.title_for_field(field_id), title)
self.assertEqual(self.account_settings_page.value_for_text_field(field_id), initial_value)
self.assertEqual(
self.account_settings_page.value_for_text_field(field_id, new_invalid_value), new_invalid_value
)
self.account_settings_page.wait_for_indicator(field_id, 'validation-error')
self.browser.refresh()
self.assertNotEqual(self.account_settings_page.value_for_text_field(field_id), new_invalid_value)
for new_value in new_valid_values:
self.assertEqual(self.account_settings_page.value_for_text_field(field_id, new_value), new_value)
self.account_settings_page.wait_for_messsage(field_id, success_message)
if assert_after_reload:
self.browser.refresh()
self.assertEqual(self.account_settings_page.value_for_text_field(field_id), new_value)
def _test_dropdown_field(
self, field_id, title, initial_value, new_values, success_message=SUCCESS_MESSAGE, reloads_on_save=False
):
"""
Test behaviour of a dropdown field.
"""
self.assertEqual(self.account_settings_page.title_for_field(field_id), title)
self.assertEqual(self.account_settings_page.value_for_dropdown_field(field_id), initial_value)
for new_value in new_values:
self.assertEqual(self.account_settings_page.value_for_dropdown_field(field_id, new_value), new_value)
self.account_settings_page.wait_for_messsage(field_id, success_message)
if reloads_on_save:
self.account_settings_page.wait_for_loading_indicator()
else:
self.browser.refresh()
self.assertEqual(self.account_settings_page.value_for_dropdown_field(field_id), new_value)
def _test_link_field(self, field_id, title, link_title, success_message):
"""
Test behaviour a link field.
"""
self.assertEqual(self.account_settings_page.title_for_field(field_id), title)
self.assertEqual(self.account_settings_page.link_title_for_link_field(field_id), link_title)
self.account_settings_page.click_on_link_in_link_field(field_id)
self.account_settings_page.wait_for_messsage(field_id, success_message)
def test_username_field(self):
"""
Test behaviour of "Username" field.
"""
self._test_readonly_field(
'username',
'Username',
self.USERNAME,
)
def test_full_name_field(self):
"""
Test behaviour of "Full Name" field.
"""
self._test_text_field(
u'name',
u'Full Name',
self.USERNAME,
u'@',
[u'another name', self.USERNAME],
)
def test_email_field(self):
"""
Test behaviour of "Email" field.
"""
self._test_text_field(
u'email',
u'Email Address',
self.EMAIL,
u'@',
[u'me@here.com', u'you@there.com'],
success_message='Click the link in the message to update your email address.',
assert_after_reload=False
)
def test_password_field(self):
"""
Test behaviour of "Password" field.
"""
self._test_link_field(
u'password',
u'Password',
u'Reset Password',
success_message='Click the link in the message to reset your password.',
)
@skip(
'On bokchoy test servers, language changes take a few reloads to fully realize '
'which means we can no longer reliably match the strings in the html in other tests.'
)
def test_language_field(self):
"""
Test behaviour of "Language" field.
"""
self._test_dropdown_field(
u'pref-lang',
u'Language',
u'English',
[u'Dummy Language (Esperanto)', u'English'],
reloads_on_save=True,
)
def test_education_completed_field(self):
"""
Test behaviour of "Education Completed" field.
"""
self._test_dropdown_field(
u'level_of_education',
u'Education Completed',
u'',
[u'Bachelor\'s degree', u''],
)
def test_gender_field(self):
"""
Test behaviour of "Gender" field.
"""
self._test_dropdown_field(
u'gender',
u'Gender',
u'',
[u'Female', u''],
)
def test_year_of_birth_field(self):
"""
Test behaviour of "Year of Birth" field.
"""
self._test_dropdown_field(
u'year_of_birth',
u'Year of Birth',
u'',
[u'1980', u''],
)
def test_country_field(self):
"""
Test behaviour of "Country or Region" field.
"""
self._test_dropdown_field(
u'country',
u'Country or Region',
u'',
[u'Pakistan', u''],
)
def test_prefered_language_field(self):
"""
Test behaviour of "Preferred Language" field.
"""
self._test_dropdown_field(
u'language_proficiencies',
u'Preferred Language',
u'',
[u'Pushto', u''],
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment