""" Acceptance tests for Studio related to the split_test module. """ from unittest import skip from ..fixtures.course import CourseFixture, XBlockFixtureDesc from ..pages.studio.component_editor import ComponentEditorView from test_studio_container import ContainerBase from ..pages.studio.utils import add_advanced_component from xmodule.partitions.partitions import Group, UserPartition from bok_choy.promise import Promise class SplitTest(ContainerBase): """ Tests for creating and editing split test instances in Studio. """ __test__ = True def setup_fixtures(self): course_fix = CourseFixture( self.course_info['org'], self.course_info['number'], self.course_info['run'], self.course_info['display_name'] ) course_fix.add_advanced_settings( { u"advanced_modules": ["split_test"], u"user_partitions": [ UserPartition(0, 'Configuration alpha,beta', 'first', [Group("0", 'alpha'), Group("1", 'beta')]).to_json(), UserPartition(1, 'Configuration 0,1,2', 'second', [Group("0", 'Group 0'), Group("1", 'Group 1'), Group("2", 'Group 2')]).to_json() ] } ) course_fix.add_children( XBlockFixtureDesc('chapter', 'Test Section').add_children( XBlockFixtureDesc('sequential', 'Test Subsection').add_children( XBlockFixtureDesc('vertical', 'Test Unit') ) ) ).install() self.course_fix = course_fix self.user = course_fix.user def verify_groups(self, container, active_groups, inactive_groups, verify_missing_groups_not_present=True): """ Check that the groups appear and are correctly categorized as to active and inactive. Also checks that the "add missing groups" button/link is not present unless a value of False is passed for verify_missing_groups_not_present. """ def wait_for_xblocks_to_render(): # First xblock is the container for the page, subtract 1. return (len(active_groups) + len(inactive_groups) == len(container.xblocks) - 1, len(active_groups)) Promise(wait_for_xblocks_to_render, "Number of xblocks on the page are incorrect").fulfill() def check_xblock_names(expected_groups, actual_blocks): self.assertEqual(len(expected_groups), len(actual_blocks)) for idx, expected in enumerate(expected_groups): self.assertEqual('Expand or Collapse\n{}'.format(expected), actual_blocks[idx].name) check_xblock_names(active_groups, container.active_xblocks) check_xblock_names(inactive_groups, container.inactive_xblocks) # Verify inactive xblocks appear after active xblocks check_xblock_names(active_groups + inactive_groups, container.xblocks[1:]) if verify_missing_groups_not_present: self.verify_add_missing_groups_button_not_present(container) def verify_add_missing_groups_button_not_present(self, container): """ Checks that the "add missing gorups" button/link is not present. """ def missing_groups_button_not_present(): button_present = container.missing_groups_button_present() return (not button_present, not button_present) Promise(missing_groups_button_not_present, "Add missing groups button should not be showing.").fulfill() def create_poorly_configured_split_instance(self): """ Creates a split test instance with a missing group and an inactive group. Returns the container page. """ unit = self.go_to_unit_page(make_draft=True) add_advanced_component(unit, 0, 'split_test') container = self.go_to_container_page() container.edit() component_editor = ComponentEditorView(self.browser, container.locator) component_editor.set_select_value_and_save('Group Configuration', 'Configuration alpha,beta') self.course_fix.add_advanced_settings( { u"user_partitions": [ UserPartition(0, 'Configuration alpha,beta', 'first', [Group("0", 'alpha'), Group("2", 'gamma')]).to_json() ] } ) self.course_fix._add_advanced_settings() return self.go_to_container_page() def test_create_and_select_group_configuration(self): """ Tests creating a split test instance on the unit page, and then assigning the group configuration. """ unit = self.go_to_unit_page(make_draft=True) add_advanced_component(unit, 0, 'split_test') container = self.go_to_container_page() container.edit() component_editor = ComponentEditorView(self.browser, container.locator) component_editor.set_select_value_and_save('Group Configuration', 'Configuration alpha,beta') self.verify_groups(container, ['alpha', 'beta'], []) # Switch to the other group configuration. Must navigate again to the container page so # that there is only a single "editor" on the page. container = self.go_to_container_page() container.edit() component_editor = ComponentEditorView(self.browser, container.locator) component_editor.set_select_value_and_save('Group Configuration', 'Configuration 0,1,2') self.verify_groups(container, ['Group 0', 'Group 1', 'Group 2'], ['alpha', 'beta']) # Reload the page to make sure the groups were persisted. container = self.go_to_container_page() self.verify_groups(container, ['Group 0', 'Group 1', 'Group 2'], ['alpha', 'beta']) @skip("This fails periodically where it fails to trigger the add missing groups action.Dis") def test_missing_group(self): """ The case of a split test with invalid configuration (missing group). """ container = self.create_poorly_configured_split_instance() container.add_missing_groups() self.verify_groups(container, ['alpha', 'gamma'], ['beta']) # Reload the page to make sure the groups were persisted. container = self.go_to_container_page() self.verify_groups(container, ['alpha', 'gamma'], ['beta']) def test_delete_inactive_group(self): """ Test deleting an inactive group. """ container = self.create_poorly_configured_split_instance() container.delete(0) self.verify_groups(container, ['alpha'], [], verify_missing_groups_not_present=False)