-
+

Loading

diff --git a/common/test/acceptance/pages/studio/settings_group_configurations.py b/common/test/acceptance/pages/studio/settings_group_configurations.py index eb98c4dac8..83eee7387e 100644 --- a/common/test/acceptance/pages/studio/settings_group_configurations.py +++ b/common/test/acceptance/pages/studio/settings_group_configurations.py @@ -12,6 +12,8 @@ class GroupConfigurationsPage(CoursePage): """ url_path = "group_configurations" + experiment_groups_css = ".experiment-groups" + content_groups_css = ".content-groups" def is_browser_on_page(self): """ @@ -30,26 +32,72 @@ class GroupConfigurationsPage(CoursePage): return True @property - def group_configurations(self): + def experiment_group_configurations(self): """ - Return list of the group configurations for the course. + Return list of the experiment group configurations for the course. """ - css = '.group-configurations-list-item' - return [GroupConfiguration(self, index) for index in xrange(len(self.q(css=css)))] + return self._get_groups(self.experiment_groups_css) - def create(self): + @property + def content_groups(self): + """ + Return list of the content groups for the course. + """ + return self._get_groups(self.content_groups_css) + + def _get_groups(self, prefix): + """ + Return list of the group-configurations-list-item's of specified type for the course. + """ + css = prefix + ' .group-configurations-list-item' + return [GroupConfiguration(self, prefix, index) for index in xrange(len(self.q(css=css)))] + + def create_experiment_group_configuration(self): """ Creates new group configuration. """ - self.q(css=".experiment-groups .new-button").first.click() + self.q(css=self.experiment_groups_css + " .new-button").first.click() + + def create_first_content_group(self): + """ + Creates new content group when there are none initially defined. + """ + self.q(css=self.content_groups_css + " .new-button").first.click() + + def add_content_group(self): + """ + Creates new content group when at least one already exists + """ + self.q(css=self.content_groups_css + " .action-add").first.click() @property - def no_group_configuration_message_is_present(self): - return self.q(css='.wrapper-content .experiment-groups .no-group-configurations-content').present + def no_experiment_groups_message_is_present(self): + return self._no_content_message(self.experiment_groups_css).present @property - def no_group_configuration_message_text(self): - return self.q(css='.wrapper-content .experiment-groups .no-group-configurations-content').text[0] + def no_content_groups_message_is_present(self): + return self._no_content_message(self.content_groups_css).present + + @property + def no_experiment_groups_message_text(self): + return self._no_content_message(self.experiment_groups_css).text[0] + + @property + def no_content_groups_message_text(self): + return self._no_content_message(self.content_groups_css).text[0] + + def _no_content_message(self, prefix): + """ + Returns the message about "no content" for the specified type. + """ + return self.q(css='.wrapper-content ' + prefix + ' .no-group-configurations-content') + + @property + def experiment_group_sections_present(self): + """ + Returns whether or not anything related to content experiments is present. + """ + return self.q(css=self.experiment_groups_css).present or self.q(css=".experiment-groups-doc").present class GroupConfiguration(object): @@ -57,9 +105,9 @@ class GroupConfiguration(object): Group Configuration wrapper. """ - def __init__(self, page, index): + def __init__(self, page, prefix, index): self.page = page - self.SELECTOR = '.group-configurations-list-item-{}'.format(index) + self.SELECTOR = prefix + ' .group-configurations-list-item-{}'.format(index) self.index = index def get_selector(self, css=''): diff --git a/common/test/acceptance/tests/studio/test_studio_settings.py b/common/test/acceptance/tests/studio/test_studio_settings.py index 51c98961a3..72f22fe407 100644 --- a/common/test/acceptance/tests/studio/test_studio_settings.py +++ b/common/test/acceptance/tests/studio/test_studio_settings.py @@ -7,6 +7,127 @@ from nose.plugins.attrib import attr from base_studio_test import StudioCourseTest from ...pages.studio.settings_advanced import AdvancedSettingsPage +from ...pages.studio.settings_group_configurations import GroupConfigurationsPage + + +@attr('shard_1') +class ContentGroupConfigurationTest(StudioCourseTest): + """ + Tests for content groups in the Group Configurations Page. + There are tests for the experiment groups in test_studio_split_test. + """ + def setUp(self): + super(ContentGroupConfigurationTest, self).setUp() + self.group_configurations_page = GroupConfigurationsPage( + self.browser, + self.course_info['org'], + self.course_info['number'], + self.course_info['run'] + ) + + def create_and_verify_content_group(self, name, existing_groups): + """ + Creates a new content group and verifies that it was properly created. + """ + self.assertEqual(existing_groups, len(self.group_configurations_page.content_groups)) + if existing_groups == 0: + self.group_configurations_page.create_first_content_group() + else: + self.group_configurations_page.add_content_group() + config = self.group_configurations_page.content_groups[existing_groups] + config.name = name + # Save the content group + self.assertEqual(config.get_text('.action-primary'), "Create") + self.assertTrue(config.delete_button_is_absent) + config.save() + self.assertIn(name, config.name) + return config + + def test_no_content_groups_by_default(self): + """ + Scenario: Ensure that message telling me to create a new content group is + shown when no content groups exist. + Given I have a course without content groups + When I go to the Group Configuration page in Studio + Then I see "You have not created any content groups yet." message + """ + self.group_configurations_page.visit() + self.assertTrue(self.group_configurations_page.no_content_groups_message_is_present) + self.assertIn( + "You have not created any content groups yet.", + self.group_configurations_page.no_content_groups_message_text + ) + + def test_can_create_and_edit_content_groups(self): + """ + Scenario: Ensure that the content groups can be created and edited correctly. + Given I have a course without content groups + When I click button 'Add your first Content Group' + And I set new the name and click the button 'Create' + Then I see the new content is added and has correct data + And I click 'New Content Group' button + And I set the name and click the button 'Create' + Then I see the second content group is added and has correct data + When I edit the second content group + And I change the name and click the button 'Save' + Then I see the second content group is saved successfully and has the new name + """ + self.group_configurations_page.visit() + self.create_and_verify_content_group("New Content Group", 0) + second_config = self.create_and_verify_content_group("Second Content Group", 1) + + # Edit the second content group + second_config.edit() + second_config.name = "Updated Second Content Group" + self.assertEqual(second_config.get_text('.action-primary'), "Save") + second_config.save() + + self.assertIn("Updated Second Content Group", second_config.name) + + def test_cannot_delete_content_group(self): + """ + Scenario: Delete is not currently supported for content groups. + Given I have a course without content groups + When I create a content group + Then there is no delete button + """ + self.group_configurations_page.visit() + config = self.create_and_verify_content_group("New Content Group", 0) + self.assertTrue(config.delete_button_is_absent) + + def test_must_supply_name(self): + """ + Scenario: Ensure that validation of the content group works correctly. + Given I have a course without content groups + And I create new content group without specifying a name click the button 'Create' + Then I see error message "Content Group name is required." + When I set a name and click the button 'Create' + Then I see the content group is saved successfully + """ + self.group_configurations_page.visit() + self.group_configurations_page.create_first_content_group() + config = self.group_configurations_page.content_groups[0] + config.save() + self.assertEqual(config.mode, 'edit') + self.assertEqual("Group name is required", config.validation_message) + config.name = "Content Group Name" + config.save() + self.assertIn("Content Group Name", config.name) + + def test_can_cancel_creation_of_content_group(self): + """ + Scenario: Ensure that creation of a content group can be canceled correctly. + Given I have a course without content groups + When I click button 'Add your first Content Group' + And I set new the name and click the button 'Cancel' + Then I see that there is no content groups in the course + """ + self.group_configurations_page.visit() + self.group_configurations_page.create_first_content_group() + config = self.group_configurations_page.content_groups[0] + config.name = "Content Group" + config.cancel() + self.assertEqual(0, len(self.group_configurations_page.content_groups)) @attr('shard_1') diff --git a/common/test/acceptance/tests/studio/test_studio_split_test.py b/common/test/acceptance/tests/studio/test_studio_split_test.py index 0225cf7439..395cb1f48b 100644 --- a/common/test/acceptance/tests/studio/test_studio_split_test.py +++ b/common/test/acceptance/tests/studio/test_studio_split_test.py @@ -202,28 +202,28 @@ class SplitTest(ContainerBase, SplitTestMixin): @attr('shard_1') -class SettingsMenuTest(StudioCourseTest): +class GroupConfigurationsNoSplitTest(StudioCourseTest): """ - Tests that Settings menu is rendered correctly in Studio + Tests how the Group Configuration page should look when the split_test module is not enabled. """ - def setUp(self): - super(SettingsMenuTest, self).setUp() - self.advanced_settings = AdvancedSettingsPage( + super(GroupConfigurationsNoSplitTest, self).setUp() + self.group_configurations_page = GroupConfigurationsPage( self.browser, self.course_info['org'], self.course_info['number'], self.course_info['run'] ) - self.advanced_settings.visit() - def test_link_exist(self): + def test_no_content_experiment_sections(self): """ - Ensure that the link to the "Group Configurations" page is shown in the - Settings menu. + Scenario: if split_test module is not present in Advanced Settings, content experiment + parts of the Group Configurations page are not shown. + Given I have a course with split_test module not enabled + Then when I go to the Group Configurations page there are no content experiment sections """ - link_css = 'li.nav-course-settings-group-configurations a' - self.assertTrue(self.advanced_settings.q(css=link_css).present) + self.group_configurations_page.visit() + self.assertFalse(self.group_configurations_page.experiment_group_sections_present) @attr('shard_1') @@ -329,7 +329,7 @@ class GroupConfigurationsTest(ContainerBase, SplitTestMixin): # Go to the Group Configuration Page self.page.visit() - config = self.page.group_configurations[0] + config = self.page.experiment_group_configurations[0] if associate_experiment: return config, split_test @@ -364,14 +364,14 @@ class GroupConfigurationsTest(ContainerBase, SplitTestMixin): shown when group configurations were not added. Given I have a course without group configurations When I go to the Group Configuration page in Studio - Then I see "You haven't created any group configurations yet." message - And "Create new Group Configuration" button is available + Then I see "You have not created any group configurations yet." message """ self.page.visit() - self.assertTrue(self.page.no_group_configuration_message_is_present) + self.assertTrue(self.page.experiment_group_sections_present) + self.assertTrue(self.page.no_experiment_groups_message_is_present) self.assertIn( - "You haven't created any group configurations yet.", - self.page.no_group_configuration_message_text + "You have not created any group configurations yet.", + self.page.no_experiment_groups_message_text ) def test_group_configurations_have_correct_data(self): @@ -405,7 +405,7 @@ class GroupConfigurationsTest(ContainerBase, SplitTestMixin): }) self.page.visit() - config = self.page.group_configurations[0] + config = self.page.experiment_group_configurations[0] # no groups when the the configuration is collapsed self.assertEqual(len(config.groups), 0) self._assert_fields( @@ -415,7 +415,7 @@ class GroupConfigurationsTest(ContainerBase, SplitTestMixin): groups=["Group 0", "Group 1"] ) - config = self.page.group_configurations[1] + config = self.page.experiment_group_configurations[1] self._assert_fields( config, @@ -438,10 +438,10 @@ class GroupConfigurationsTest(ContainerBase, SplitTestMixin): Then I see the group configuration is saved successfully and has the new data """ self.page.visit() - self.assertEqual(len(self.page.group_configurations), 0) + self.assertEqual(len(self.page.experiment_group_configurations), 0) # Create new group configuration - self.page.create() - config = self.page.group_configurations[0] + self.page.create_experiment_group_configuration() + config = self.page.experiment_group_configurations[0] config.name = "New Group Configuration Name" config.description = "New Description of the group configuration." config.groups[1].name = "New Group Name" @@ -496,8 +496,8 @@ class GroupConfigurationsTest(ContainerBase, SplitTestMixin): """ self.page.visit() # Create new group configuration - self.page.create() - config = self.page.group_configurations[0] + self.page.create_experiment_group_configuration() + config = self.page.experiment_group_configurations[0] config.name = "New Group Configuration Name" # Add new group config.add_group() @@ -547,7 +547,7 @@ class GroupConfigurationsTest(ContainerBase, SplitTestMixin): split_test = self._add_split_test_to_vertical(number=0, group_configuration_metadata={'user_partition_id': 0}) self.page.visit() - config = self.page.group_configurations[0] + config = self.page.experiment_group_configurations[0] config.edit() config.name = "Second Group Configuration Name" # `Group C` -> `Second Group` @@ -591,11 +591,11 @@ class GroupConfigurationsTest(ContainerBase, SplitTestMixin): """ self.page.visit() - self.assertEqual(len(self.page.group_configurations), 0) + self.assertEqual(len(self.page.experiment_group_configurations), 0) # Create new group configuration - self.page.create() + self.page.create_experiment_group_configuration() - config = self.page.group_configurations[0] + config = self.page.experiment_group_configurations[0] config.name = "Name of the Group Configuration" config.description = "Description of the group configuration." # Add new group @@ -603,7 +603,7 @@ class GroupConfigurationsTest(ContainerBase, SplitTestMixin): # Cancel the configuration config.cancel() - self.assertEqual(len(self.page.group_configurations), 0) + self.assertEqual(len(self.page.experiment_group_configurations), 0) def test_can_cancel_editing_of_group_configuration(self): """ @@ -633,7 +633,7 @@ class GroupConfigurationsTest(ContainerBase, SplitTestMixin): }, }) self.page.visit() - config = self.page.group_configurations[0] + config = self.page.experiment_group_configurations[0] config.name = "New Group Configuration Name" config.description = "New Description of the group configuration." # Add 2 new groups @@ -674,9 +674,9 @@ class GroupConfigurationsTest(ContainerBase, SplitTestMixin): self.page.visit() # Create new group configuration - self.page.create() + self.page.create_experiment_group_configuration() # Leave empty required field - config = self.page.group_configurations[0] + config = self.page.experiment_group_configurations[0] config.description = "Description of the group configuration." try_to_save_and_verify_error_message("Group Configuration name is required.") @@ -725,7 +725,7 @@ class GroupConfigurationsTest(ContainerBase, SplitTestMixin): # Go to the Group Configuration Page and click on outline anchor self.page.visit() - config = self.page.group_configurations[0] + config = self.page.experiment_group_configurations[0] config.toggle() config.click_outline_anchor() @@ -770,7 +770,7 @@ class GroupConfigurationsTest(ContainerBase, SplitTestMixin): # Go to the Group Configuration Page and click unit anchor self.page.visit() - config = self.page.group_configurations[0] + config = self.page.experiment_group_configurations[0] config.toggle() usage = config.usages[0] config.click_unit_anchor() @@ -815,18 +815,18 @@ class GroupConfigurationsTest(ContainerBase, SplitTestMixin): }) self.page.visit() - self.assertEqual(len(self.page.group_configurations), 2) - config = self.page.group_configurations[1] + self.assertEqual(len(self.page.experiment_group_configurations), 2) + config = self.page.experiment_group_configurations[1] # Delete first group configuration via detail view config.delete() - self.assertEqual(len(self.page.group_configurations), 1) + self.assertEqual(len(self.page.experiment_group_configurations), 1) - config = self.page.group_configurations[0] + config = self.page.experiment_group_configurations[0] config.edit() self.assertFalse(config.delete_button_is_disabled) # Delete first group configuration via edit view config.delete() - self.assertEqual(len(self.page.group_configurations), 0) + self.assertEqual(len(self.page.experiment_group_configurations), 0) def test_cannot_delete_used_group_configuration(self): """ @@ -858,7 +858,7 @@ class GroupConfigurationsTest(ContainerBase, SplitTestMixin): # Go to the Group Configuration Page and click unit anchor self.page.visit() - config = self.page.group_configurations[0] + config = self.page.experiment_group_configurations[0] self.assertTrue(config.delete_button_is_disabled) self.assertIn('Cannot delete when in use by an experiment', config.delete_note) @@ -915,12 +915,12 @@ class GroupConfigurationsTest(ContainerBase, SplitTestMixin): self.page.wait_for_page() # Appropriate Group Configuration is expanded. - self.assertFalse(self.page.group_configurations[0].is_expanded) - self.assertTrue(self.page.group_configurations[1].is_expanded) + self.assertFalse(self.page.experiment_group_configurations[0].is_expanded) + self.assertTrue(self.page.experiment_group_configurations[1].is_expanded) self.assertEqual( group_configuration_link_name, - self.page.group_configurations[1].name + self.page.experiment_group_configurations[1].name ) def test_details_error_validation_message(self):