Commit 4ddb9a01 by Jesse Zoldak

[WIP] Improvements to acceptance test field logic

parent de0b01ce
...@@ -16,17 +16,24 @@ class FieldsMixin(object): ...@@ -16,17 +16,24 @@ class FieldsMixin(object):
""" """
Return field with field_id. Return field with field_id.
""" """
assert False, "Why am I here?"
query = self.q(css='.u-field-{}'.format(field_id)) query = self.q(css='.u-field-{}'.format(field_id))
return query.text[0] if query.present else None return query.text[0] if query.present else None
def wait_for_field(self, field_id): def wait_for_field(self, field_id):
"""Wait for a field to appear in DOM.
Args:
field_id (str): The ID of the field, used in locating it via css
Returns:
None
Raises:
BrokenPromise: If the field is not present in the DOM before the default timeout
""" """
Wait for a field to appear in DOM. field_css = '.u-field-{}'.format(field_id)
""" self.wait_for_element_presence(field_css, 'Field {} is present in the DOM'.format(field_id))
EmptyPromise(
lambda: self.field(field_id) is not None,
"Field with id \"{0}\" is in DOM.".format(field_id)
).fulfill()
def mode_for_field(self, field_id): def mode_for_field(self, field_id):
""" """
...@@ -39,8 +46,8 @@ class FieldsMixin(object): ...@@ -39,8 +46,8 @@ class FieldsMixin(object):
query = self.q(css='.u-field-{}'.format(field_id)) query = self.q(css='.u-field-{}'.format(field_id))
if not query.present: # if not query.present:
return None # return None
field_classes = query.attrs('class')[0].split() field_classes = query.attrs('class')[0].split()
...@@ -124,19 +131,18 @@ class FieldsMixin(object): ...@@ -124,19 +131,18 @@ class FieldsMixin(object):
""" """
Make a field editable. Make a field editable.
""" """
query = self.q(css='.u-field-{}'.format(field_id)) self.wait_for_field(field_id)
field_mode = self.mode_for_field(field_id)
if not query.present:
return None
field_classes = query.attrs('class')[0].split()
if 'mode-placeholder' in field_classes or 'mode-display' in field_classes: if field_mode in ['placeholder', 'display']:
if field_id == 'bio': if field_id == 'bio':
self.q(css='.u-field-bio > .wrapper-u-field').first.click() self.q(css='.u-field-bio > .wrapper-u-field').first.click()
else: else:
self.q(css='.u-field-{}'.format(field_id)).first.click() self.q(css='.u-field-{}'.format(field_id)).first.click()
# Verify that the class changed to mode-edit
self.wait_for(lambda: self.mode_for_field(field_id) == 'edit', 'Field {} is editable'.format(field_id))
def value_for_readonly_field(self, field_id): def value_for_readonly_field(self, field_id):
""" """
Return the value in a readonly field. Return the value in a readonly field.
...@@ -155,10 +161,8 @@ class FieldsMixin(object): ...@@ -155,10 +161,8 @@ class FieldsMixin(object):
""" """
self.wait_for_field(field_id) self.wait_for_field(field_id)
query = self.q(css='.u-field-{} input'.format(field_id)) field_css = '.u-field-{} input'.format(field_id)
if not query.present: query = self.q(css=field_css)
return None
if value is not None: if value is not None:
current_value = query.attrs('value')[0] current_value = query.attrs('value')[0]
query.results[0].send_keys(u'\ue003' * len(current_value)) # Delete existing value. query.results[0].send_keys(u'\ue003' * len(current_value)) # Delete existing value.
...@@ -171,13 +175,15 @@ class FieldsMixin(object): ...@@ -171,13 +175,15 @@ class FieldsMixin(object):
""" """
Set the value of a textarea field. Set the value of a textarea field.
""" """
assert False, "Cannot set value for textarea"
self.wait_for_field(field_id) self.wait_for_field(field_id)
self.make_field_editable(field_id) self.make_field_editable(field_id)
field_selector = '.u-field-{} textarea'.format(field_id) field_selector = '.u-field-{} textarea'.format(field_id)
self.wait_for_element_presence(field_selector, 'Editable textarea is present.') self.wait_for_element_presence(field_selector, 'Editable textarea is present.')
query = self.q(css=field_selector) query = self.q(css=field_selector).first
query.click()
query.fill(value) query.fill(value)
query.results[0].send_keys(u'\ue004') # Focus Out using TAB query.results[0].send_keys(u'\ue004') # Focus Out using TAB
...@@ -186,8 +192,6 @@ class FieldsMixin(object): ...@@ -186,8 +192,6 @@ class FieldsMixin(object):
Return value of field in `display` or `placeholder` mode. Return value of field in `display` or `placeholder` mode.
""" """
self.wait_for_field(field_id) self.wait_for_field(field_id)
self.wait_for_ajax()
return self.q(css='.u-field-{} .u-field-value .u-field-value-readonly'.format(field_id)).text[0] return self.q(css='.u-field-{} .u-field-value .u-field-value-readonly'.format(field_id)).text[0]
def value_for_dropdown_field(self, field_id, value=None): def value_for_dropdown_field(self, field_id, value=None):
...@@ -197,12 +201,10 @@ class FieldsMixin(object): ...@@ -197,12 +201,10 @@ class FieldsMixin(object):
assert False, "This test uses value_for_dropdown_field" assert False, "This test uses value_for_dropdown_field"
self.wait_for_field(field_id) self.wait_for_field(field_id)
self.make_field_editable(field_id) self.make_field_editable(field_id)
query = self.q(css='.u-field-{} select'.format(field_id)) field_css = '.u-field-{} select'.format(field_id)
if not query.present: query = self.q(css=field_css)
return None
if value is not None: if value is not None:
select_option_by_text(query, value) select_option_by_text(query, value)
......
...@@ -21,6 +21,7 @@ from pymongo import MongoClient, ASCENDING ...@@ -21,6 +21,7 @@ from pymongo import MongoClient, ASCENDING
from openedx.core.lib.tests.assertions.events import assert_event_matches, is_matching_event, EventMatchTolerates from openedx.core.lib.tests.assertions.events import assert_event_matches, is_matching_event, EventMatchTolerates
from xmodule.partitions.partitions import UserPartition from xmodule.partitions.partitions import UserPartition
from xmodule.partitions.tests.test_partitions import MockUserPartitionScheme from xmodule.partitions.tests.test_partitions import MockUserPartitionScheme
from selenium.common.exceptions import StaleElementReferenceException
from selenium.webdriver.support.select import Select from selenium.webdriver.support.select import Select
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support import expected_conditions as EC
...@@ -201,18 +202,36 @@ def enable_css_animations(page): ...@@ -201,18 +202,36 @@ def enable_css_animations(page):
def select_option_by_text(select_browser_query, option_text): def select_option_by_text(select_browser_query, option_text):
""" """
Chooses an option within a select by text (helper method for Select's select_by_visible_text method). Chooses an option within a select by text (helper method for Select's select_by_visible_text method).
Wrap this in a Promise to prevent a StaleElementReferenceException
from being raised while the DOM is still being rewritten
""" """
select = Select(select_browser_query.first.results[0]) def select_option(query, value):
select.select_by_visible_text(option_text) try:
select = Select(query.first.results[0])
select.select_by_visible_text(value)
return True
except StaleElementReferenceException:
return False
EmptyPromise(lambda: select_option(select_browser_query, option_text), 'Selected option {}'.format(option_text)).fulfill()
def get_selected_option_text(select_browser_query): def get_selected_option_text(select_browser_query):
""" """
Returns the text value for the first selected option within a select. Returns the text value for the first selected option within a select.
Wrap this in a Promise to prevent a StaleElementReferenceException
from being raised while the DOM is still being rewritten
""" """
select = Select(select_browser_query.first.results[0]) def get_option(query):
return select.first_selected_option.text try:
select = Select(select_browser_query.first.results[0])
return (True, select.first_selected_option.text)
except StaleElementReferenceException:
return (False, None)
text = Promise(lambda: get_option(select_browser_query), 'Retrieved selected option text').fulfill()
return text
def get_options(select_browser_query): def get_options(select_browser_query):
""" """
......
...@@ -328,18 +328,18 @@ class OwnLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest): ...@@ -328,18 +328,18 @@ class OwnLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest):
self.assertEqual(profile_page.get_non_editable_mode_value(field_id), displayed_value) self.assertEqual(profile_page.get_non_editable_mode_value(field_id), displayed_value)
self.assertTrue(profile_page.mode_for_field(field_id), mode) self.assertTrue(profile_page.mode_for_field(field_id), mode)
def _test_textarea_field(self, profile_page, field_id, new_value, displayed_value, mode): def _test_textarea_field(self, profile_page, field_id, new_value, expected_value, mode):
""" """
Test behaviour of a textarea field. Test behaviour of a textarea field.
""" """
profile_page.set_value_for_textarea_field(field_id, new_value) profile_page.set_value_for_textarea_field(field_id, new_value)
self.assertEqual(profile_page.get_non_editable_mode_value(field_id), displayed_value) self.assertEqual(profile_page.get_non_editable_mode_value(field_id), expected_value)
self.assertTrue(profile_page.mode_for_field(field_id), mode) self.assertTrue(profile_page.mode_for_field(field_id), mode)
self.browser.refresh() self.browser.refresh()
profile_page.wait_for_page() profile_page.wait_for_page()
self.assertEqual(profile_page.get_non_editable_mode_value(field_id), displayed_value) self.assertEqual(profile_page.get_non_editable_mode_value(field_id), expected_value)
self.assertTrue(profile_page.mode_for_field(field_id), mode) self.assertTrue(profile_page.mode_for_field(field_id), mode)
def test_country_field(self): def test_country_field(self):
......
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