diff --git a/common/test/acceptance/pages/lms/fields.py b/common/test/acceptance/pages/lms/fields.py index 338daa1d51..24e028dfa6 100644 --- a/common/test/acceptance/pages/lms/fields.py +++ b/common/test/acceptance/pages/lms/fields.py @@ -192,7 +192,7 @@ class FieldsMixin(object): 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, focus_out=False): """ Get or set the value in a dropdown field. """ @@ -205,7 +205,7 @@ class FieldsMixin(object): return None if value is not None: - select_option_by_text(query, value) + select_option_by_text(query, value, focus_out) if self.mode_for_field(field_id) == 'edit': return get_selected_option_text(query) diff --git a/common/test/acceptance/pages/lms/learner_profile.py b/common/test/acceptance/pages/lms/learner_profile.py index 48ae348828..5edc33c8e6 100644 --- a/common/test/acceptance/pages/lms/learner_profile.py +++ b/common/test/acceptance/pages/lms/learner_profile.py @@ -8,10 +8,12 @@ from bok_choy.page_object import PageObject from common.test.acceptance.pages.lms.fields import FieldsMixin from bok_choy.promise import EmptyPromise from common.test.acceptance.pages.lms.instructor_dashboard import InstructorDashboardPage +from common.test.acceptance.tests.helpers import select_option_by_value from selenium.webdriver import ActionChains PROFILE_VISIBILITY_SELECTOR = '#u-field-select-account_privacy option[value="{}"]' +PROFILE_VISIBILITY_INPUT = '#u-field-select-account_privacy' FIELD_ICONS = { 'country': 'fa-map-marker', 'language_proficiencies': 'fa-comment', @@ -146,7 +148,8 @@ class LearnerProfilePage(FieldsMixin, PageObject): self.wait_for_element_visibility('select#u-field-select-account_privacy', 'Privacy dropdown is visible') if privacy != self.privacy: - self.q(css=PROFILE_VISIBILITY_SELECTOR.format(privacy)).first.click() + query = self.q(css=PROFILE_VISIBILITY_INPUT) + select_option_by_value(query, privacy, focus_out=True) EmptyPromise(lambda: privacy == self.privacy, 'Privacy is set to {}'.format(privacy)).fulfill() self.wait_for_ajax() diff --git a/common/test/acceptance/tests/helpers.py b/common/test/acceptance/tests/helpers.py index c329e8b60f..647d56c576 100644 --- a/common/test/acceptance/tests/helpers.py +++ b/common/test/acceptance/tests/helpers.py @@ -26,6 +26,7 @@ from openedx.core.lib.tests.assertions.events import assert_event_matches, is_ma from xmodule.partitions.partitions import UserPartition from xmodule.partitions.tests.test_partitions import MockUserPartitionScheme from selenium.common.exceptions import StaleElementReferenceException +from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.select import Select from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC @@ -213,7 +214,7 @@ 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, focus_out=False): """ Chooses an option within a select by text (helper method for Select's select_by_visible_text method). @@ -225,6 +226,8 @@ def select_option_by_text(select_browser_query, option_text): try: select = Select(query.first.results[0]) select.select_by_visible_text(value) + if focus_out: + query.first.results[0].send_keys(Keys.TAB) return True except StaleElementReferenceException: return False @@ -267,7 +270,7 @@ def generate_course_key(org, number, run): return CourseLocator(org, number, run, deprecated=(default_store == 'draft')) -def select_option_by_value(browser_query, value): +def select_option_by_value(browser_query, value, focus_out=False): """ Selects a html select element by matching value attribute """ @@ -288,9 +291,10 @@ def select_option_by_value(browser_query, value): if not opt.is_selected(): all_options_selected = False opt.click() - # if value is not an option choice then it should return false if all_options_selected and not has_option: all_options_selected = False + if focus_out: + browser_query.first.results[0].send_keys(Keys.TAB) return all_options_selected # Make sure specified option is actually selected diff --git a/common/test/acceptance/tests/lms/test_account_settings.py b/common/test/acceptance/tests/lms/test_account_settings.py index 136222fb01..ff5f0992a9 100644 --- a/common/test/acceptance/tests/lms/test_account_settings.py +++ b/common/test/acceptance/tests/lms/test_account_settings.py @@ -226,10 +226,13 @@ class AccountSettingsPageTest(AccountSettingsTestMixin, AcceptanceTest): 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) + self.assertEqual(self.account_settings_page.value_for_dropdown_field(field_id, focus_out=True), 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.assertEqual( + self.account_settings_page.value_for_dropdown_field(field_id, new_value, focus_out=True), + new_value + ) # An XHR request is made when changing the field self.account_settings_page.wait_for_ajax() if reloads_on_save: @@ -237,7 +240,7 @@ class AccountSettingsPageTest(AccountSettingsTestMixin, AcceptanceTest): else: self.browser.refresh() self.account_settings_page.wait_for_page() - self.assertEqual(self.account_settings_page.value_for_dropdown_field(field_id), new_value) + self.assertEqual(self.account_settings_page.value_for_dropdown_field(field_id, focus_out=True), new_value) def _test_link_field(self, field_id, title, link_title, field_type, success_message): """ @@ -387,7 +390,7 @@ class AccountSettingsPageTest(AccountSettingsTestMixin, AcceptanceTest): Test behaviour of "Year of Birth" field. """ # Note that when we clear the year_of_birth here we're firing an event. - self.assertEqual(self.account_settings_page.value_for_dropdown_field('year_of_birth', ''), '') + self.assertEqual(self.account_settings_page.value_for_dropdown_field('year_of_birth', '', focus_out=True), '') expected_events = [ self.expected_settings_changed_event('year_of_birth', None, 1980), diff --git a/common/test/acceptance/tests/lms/test_learner_profile.py b/common/test/acceptance/tests/lms/test_learner_profile.py index 06fa5b56b5..a721221228 100644 --- a/common/test/acceptance/tests/lms/test_learner_profile.py +++ b/common/test/acceptance/tests/lms/test_learner_profile.py @@ -44,8 +44,8 @@ class LearnerProfileTestMixin(EventsTestMixin): """ Fill in the public profile fields of a user. """ - profile_page.value_for_dropdown_field('language_proficiencies', 'English') - profile_page.value_for_dropdown_field('country', 'United Arab Emirates') + profile_page.value_for_dropdown_field('language_proficiencies', 'English', focus_out=True) + profile_page.value_for_dropdown_field('country', 'United Arab Emirates', focus_out=True) profile_page.set_value_for_textarea_field('bio', 'Nothing Special') # Waits here for text to appear/save on bio field profile_page.wait_for_ajax() @@ -91,7 +91,7 @@ class LearnerProfileTestMixin(EventsTestMixin): account_settings_page.visit() account_settings_page.wait_for_page() self.assertEqual( - account_settings_page.value_for_dropdown_field('year_of_birth', str(birth_year)), + account_settings_page.value_for_dropdown_field('year_of_birth', str(birth_year), focus_out=True), str(birth_year) ) @@ -322,7 +322,7 @@ class OwnLearnerProfilePageTest(LearnerProfileTestMixin, AcceptanceTest): """ Test behaviour of a dropdown field. """ - profile_page.value_for_dropdown_field(field_id, new_value) + profile_page.value_for_dropdown_field(field_id, new_value, focus_out=True) self.assertEqual(profile_page.get_non_editable_mode_value(field_id), displayed_value) self.assertTrue(profile_page.mode_for_field(field_id), mode) diff --git a/lms/static/js/spec/student_account/account_settings_fields_spec.js b/lms/static/js/spec/student_account/account_settings_fields_spec.js index 727a033d48..165e80a66c 100644 --- a/lms/static/js/spec/student_account/account_settings_fields_spec.js +++ b/lms/static/js/spec/student_account/account_settings_fields_spec.js @@ -86,6 +86,7 @@ define(['backbone', // change country countryView.$(baseSelector).val(countryChange[countryData.valueAttribute]).change(); + countryView.$(baseSelector).focusout(); FieldViewsSpecHelpers.expectAjaxRequestWithData(requests, countryChange); AjaxHelpers.respondWithJson(requests, {success: 'true'}); @@ -106,6 +107,7 @@ define(['backbone', // select time zone option from option timeZoneView.$(baseSelector).val(timeZoneChange[timeZoneData.valueAttribute]).change(); + timeZoneView.$(baseSelector).focusout(); FieldViewsSpecHelpers.expectAjaxRequestWithData(requests, timeZoneChange); AjaxHelpers.respondWithJson(requests, {success: 'true'}); timeZoneView.render(); @@ -130,6 +132,7 @@ define(['backbone', var data = {'language': FieldViewsSpecHelpers.SELECT_OPTIONS[2][0]}; view.$(selector).val(data[fieldData.valueAttribute]).change(); + view.$(selector).focusout(); FieldViewsSpecHelpers.expectAjaxRequestWithData(requests, data); AjaxHelpers.respondWithNoContent(requests); @@ -144,6 +147,7 @@ define(['backbone', data = {'language': FieldViewsSpecHelpers.SELECT_OPTIONS[1][0]}; view.$(selector).val(data[fieldData.valueAttribute]).change(); + view.$(selector).focusout(); FieldViewsSpecHelpers.expectAjaxRequestWithData(requests, data); AjaxHelpers.respondWithNoContent(requests); @@ -177,6 +181,7 @@ define(['backbone', var data = {'language_proficiencies': [{'code': FieldViewsSpecHelpers.SELECT_OPTIONS[1][0]}]}; view.$(selector).val(FieldViewsSpecHelpers.SELECT_OPTIONS[1][0]).change(); + view.$(selector).focusout(); FieldViewsSpecHelpers.expectAjaxRequestWithData(requests, data); AjaxHelpers.respondWithNoContent(requests); }); diff --git a/lms/static/js/spec/views/fields_helpers.js b/lms/static/js/spec/views/fields_helpers.js index 3d4e6eef21..c27849726f 100644 --- a/lms/static/js/spec/views/fields_helpers.js +++ b/lms/static/js/spec/views/fields_helpers.js @@ -184,6 +184,7 @@ define(['backbone', } view.$(data.valueInputSelector).val(data.validValue).change(); + view.$(data.valueInputSelector).focusout(); // When the value in the field is changed expect(view.fieldValue()).toBe(data.validValue); expectMessageContains(view, view.indicators.inProgress); @@ -203,6 +204,7 @@ define(['backbone', } view.$(data.valueInputSelector).val(data.invalidValue1).change(); + view.$(data.valueInputSelector).focusout(); request_data[data.valueAttribute] = data.invalidValue1; AjaxHelpers.expectJsonRequest( requests, 'PATCH', url, request_data @@ -214,6 +216,7 @@ define(['backbone', expect(view.el).toHaveClass('mode-edit'); view.$(data.valueInputSelector).val(data.invalidValue2).change(); + view.$(data.valueInputSelector).focusout(); request_data[data.valueAttribute] = data.invalidValue2; AjaxHelpers.expectJsonRequest( requests, 'PATCH', url, request_data @@ -225,6 +228,7 @@ define(['backbone', expect(view.el).toHaveClass('mode-edit'); view.$(data.valueInputSelector).val('').change(); + view.$(data.valueInputSelector).focusout(); // When the value in the field is changed expect(view.fieldValue()).toBe(data.defaultValue); request_data[data.valueAttribute] = data.defaultValue; diff --git a/lms/static/js/spec/views/fields_spec.js b/lms/static/js/spec/views/fields_spec.js index 9c525ded96..8ecb48782a 100644 --- a/lms/static/js/spec/views/fields_spec.js +++ b/lms/static/js/spec/views/fields_spec.js @@ -231,6 +231,7 @@ define(['backbone', 'jquery', 'underscore', 'edx-ui-toolkit/js/utils/spec-helper } expect(view.$(dropdownSelectClass).length).toBe(1); view.$(dropdownSelectClass).val(FieldViewsSpecHelpers.SELECT_OPTIONS[0]).change(); + view.$(dropdownSelectClass).focusout(); expect(view.fieldValue()).toBe(FieldViewsSpecHelpers.SELECT_OPTIONS[0][0]); AjaxHelpers.respondWithNoContent(requests); diff --git a/lms/static/js/views/fields.js b/lms/static/js/views/fields.js index 10faf94f42..6f87581da3 100644 --- a/lms/static/js/views/fields.js +++ b/lms/static/js/views/fields.js @@ -364,7 +364,6 @@ events: { 'click': 'startEditing', - 'change select': 'finishEditing', 'focusout select': 'finishEditing' },