class DiscussionComponentTest(ContainerBase):
    """
    Feature: CMS.Component Adding
    As a course author, I want to be able to add and edit Discussion component
    """
    def setUp(self, is_staff=True):
        """
        Create a course with a section, subsection, and unit to which to add the component.
        """
        super(DiscussionComponentTest, self).setUp(is_staff=is_staff)
        self.component = 'discussion'
        self.unit = self.go_to_unit_page()
        self.container_page = ContainerPage(self.browser, None)
        # Add Discussion component
        add_component(self.container_page, 'discussion', self.component)
        self.component = self.unit.xblocks[1]
        self.container_page.edit()
        self.discussion_editor = DiscussionComponentEditor(self.browser, self.component.locator)

    def populate_course_fixture(self, course_fixture):
        """
        Adds a course fixture
        """
        course_fixture.add_children(
            XBlockFixtureDesc('chapter', 'Test Section').add_children(
                XBlockFixtureDesc('sequential', 'Test Subsection').add_children(
                    XBlockFixtureDesc('vertical', 'Test Unit')
                )
            )
        )

    def test_view_discussion_component_metadata(self):
        """
        Scenario: Staff user can view discussion component metadata
            Given I am in Studio and I have added a Discussion component
            When I edit Discussion component
            Then I see three settings and their expected values
        """

        field_values = self.discussion_editor.edit_discussion_field_values
        self.assertEqual(
            field_values,
            ['Discussion', 'Week 1', 'Topic-Level Student-Visible Label']
        )

    def test_edit_discussion_component(self):
        """
        Scenario: Staff user can modify display name
            Given I am in Studio and I have added a Discussion component
            When I open Discussion component's edit dialogue
            Then I can modify the display name
            And My display name change is persisted on save
        """

        field_name = 'Display Name'
        new_name = 'Test Name'
        self.discussion_editor.set_field_val(field_name, new_name)
        self.discussion_editor.save()
        component_name = self.unit.xblock_titles[0]
        self.assertEqual(component_name, new_name)
    def test_use_group_configuration(self):
        """
        Scenario: Ensure that the group configuration can be used by split_module correctly
        Given I have a course without group configurations
        When I create new group configuration
        And I set new name and add a new group, save the group configuration
        And I go to the unit page in Studio
        And I add new advanced module "Content Experiment"
        When I assign created group configuration to the module
        Then I see the module has correct groups
        """
        self.page.visit()
        # Create new group configuration
        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()
        config.groups[2].name = "New group"
        # Save the configuration
        config.save()

        split_test = self._add_split_test_to_vertical(number=0)

        container = ContainerPage(self.browser, split_test.locator)
        container.visit()
        container.edit()
        component_editor = ComponentEditorView(self.browser, container.locator)
        component_editor.set_select_value_and_save('Group Configuration', 'New Group Configuration Name')
        self.verify_groups(container, ['Group A', 'Group B', 'New group'], [])
class DiscussionComponentTest(ContainerBase):
    """
    Feature: CMS.Component Adding
    As a course author, I want to be able to add and edit Discussion component
    """
    def setUp(self, is_staff=True):
        """
        Create a course with a section, subsection, and unit to which to add the component.
        """
        super(DiscussionComponentTest, self).setUp(is_staff=is_staff)
        self.component = 'discussion'
        self.unit = self.go_to_unit_page()
        self.container_page = ContainerPage(self.browser, None)
        # Add Discussion component
        add_component(self.container_page, 'discussion', self.component)
        self.component = self.unit.xblocks[1]
        self.container_page.edit()
        self.discussion_editor = DiscussionComponentEditor(
            self.browser, self.component.locator)

    def populate_course_fixture(self, course_fixture):
        """
        Adds a course fixture
        """
        course_fixture.add_children(
            XBlockFixtureDesc('chapter', 'Test Section').add_children(
                XBlockFixtureDesc('sequential',
                                  'Test Subsection').add_children(
                                      XBlockFixtureDesc(
                                          'vertical', 'Test Unit'))))

    def test_view_discussion_component_metadata(self):
        """
        Scenario: Staff user can view discussion component metadata
            Given I am in Studio and I have added a Discussion component
            When I edit Discussion component
            Then I see three settings and their expected values
        """

        field_values = self.discussion_editor.edit_discussion_field_values
        self.assertEqual(
            field_values,
            ['Discussion', 'Week 1', 'Topic-Level Student-Visible Label'])

    def test_edit_discussion_component(self):
        """
        Scenario: Staff user can modify display name
            Given I am in Studio and I have added a Discussion component
            When I open Discussion component's edit dialogue
            Then I can modify the display name
            And My display name change is persisted on save
        """

        field_name = 'Display Name'
        new_name = 'Test Name'
        self.discussion_editor.set_field_val(field_name, new_name)
        self.discussion_editor.save()
        component_name = self.unit.xblock_titles[0]
        self.assertEqual(component_name, new_name)
Exemple #4
0
    def test_easy_access_from_experiment(self):
        """
        Scenario: When a Content Experiment uses a Group Configuration,
        ensure that the link to that Group Configuration works correctly.

        Given I have a course with two Group Configurations
        And Content Experiment is assigned to one Group Configuration
        Then I see a link to Group Configuration
        When I click on the Group Configuration link
        Then I see the Group Configurations page
        And I see that appropriate Group Configuration is expanded.
        """
        # Create a new group configurations
        self.course_fixture._update_xblock(
            self.course_fixture._course_location, {
                "metadata": {
                    u"user_partitions": [
                        create_user_partition_json(
                            0, "Name", "Description.",
                            [Group("0", "Group A"),
                             Group("1", "Group B")]),
                        create_user_partition_json(
                            1, 'Name of second Group Configuration',
                            'Second group configuration.', [
                                Group("0", 'Alpha'),
                                Group("1", 'Beta'),
                                Group("2", 'Gamma')
                            ]),
                    ],
                },
            })

        # Assign newly created group configuration to unit
        vertical = self.course_fixture.get_nested_xblocks(
            category="vertical")[0]
        self.course_fixture.create_xblock(
            vertical.locator,
            XBlockFixtureDesc('split_test',
                              'Test Content Experiment',
                              metadata={'user_partition_id': 1}))

        unit = ContainerPage(self.browser, vertical.locator)
        unit.visit()
        experiment = unit.xblocks[0]

        group_configuration_link_name = experiment.group_configuration_link_name

        experiment.go_to_group_configuration_page()
        self.page.wait_for_page()

        # Appropriate Group Configuration 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.experiment_group_configurations[1].name)
    def test_easy_access_from_experiment(self):
        """
        Scenario: When a Content Experiment uses a Group Configuration,
        ensure that the link to that Group Configuration works correctly.

        Given I have a course with two Group Configurations
        And Content Experiment is assigned to one Group Configuration
        Then I see a link to Group Configuration
        When I click on the Group Configuration link
        Then I see the Group Configurations page
        And I see that appropriate Group Configuration is expanded.
        """
        # Create a new group configurations
        self.course_fixture._update_xblock(self.course_fixture._course_location, {
            "metadata": {
                u"user_partitions": [
                    create_user_partition_json(
                        0,
                        "Name",
                        "Description.",
                        [Group("0", "Group A"), Group("1", "Group B")]
                    ),
                    create_user_partition_json(
                        1,
                        'Name of second Group Configuration',
                        'Second group configuration.',
                        [Group("0", 'Alpha'), Group("1", 'Beta'), Group("2", 'Gamma')]
                    ),
                ],
            },
        })

        # Assign newly created group configuration to unit
        vertical = self.course_fixture.get_nested_xblocks(category="vertical")[0]
        self.course_fixture.create_xblock(
            vertical.locator,
            XBlockFixtureDesc('split_test', 'Test Content Experiment', metadata={'user_partition_id': 1})
        )

        unit = ContainerPage(self.browser, vertical.locator)
        unit.visit()
        experiment = unit.xblocks[0]

        group_configuration_link_name = experiment.group_configuration_link_name

        experiment.go_to_group_configuration_page()
        self.page.wait_for_page()

        # Appropriate Group Configuration 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.experiment_group_configurations[1].name
        )
 def setUp(self, is_staff=True):
     """
     Create a course with a section, subsection, and unit to which to add the component.
     """
     super(HTMLComponentEditorTests, self).setUp(is_staff=is_staff)
     self.unit = self.go_to_unit_page()
     self.container_page = ContainerPage(self.browser, None)
     self.xblock_wrapper = XBlockWrapper(self.browser, None)
     self.component = None
     self.html_editor = None
     self.iframe = None
Exemple #7
0
 def setUp(self, is_staff=True):
     """
     Create a course with a section, subsection, and unit to which to add the component.
     """
     super(DiscussionComponentTest, self).setUp(is_staff=is_staff)
     self.component = 'discussion'
     self.unit = self.go_to_unit_page()
     self.container_page = ContainerPage(self.browser, None)
     # Add Discussion component
     add_component(self.container_page, 'discussion', self.component)
     self.component = self.unit.xblocks[1]
     self.container_page.edit()
     self.discussion_editor = DiscussionComponentEditor(self.browser, self.component.locator)
Exemple #8
0
 def setUp(self, is_staff=True):
     """
     Create a course with a section, subsection, and unit to which to add the component.
     """
     super(ProblemComponentEditor, self).setUp(is_staff=is_staff)
     self.component = 'Blank Common Problem'
     self.unit = self.go_to_unit_page()
     self.container_page = ContainerPage(self.browser, None)
     # Add a Problem
     add_component(self.container_page, 'problem', self.component)
     self.component = self.unit.xblocks[1]
     self.container_page.edit()
     self.problem_editor = ProblemXBlockEditorView(self.browser, self.component.locator)
    def test_split_test_LMS_staff_view(self):
        """
        Scenario: Ensure that split test is correctly rendered in LMS staff mode as it is
                  and after inactive group removal.

        Given I have a course with group configurations and split test that assigned to first group configuration
        Then I publish split test and view it in LMS in staff view
        And it is rendered correctly
        Then I go to group configuration and delete group
        Then I publish split test and view it in LMS in staff view
        And it is rendered correctly
        Then I go to split test and delete inactive vertical
        Then I publish unit and view unit in LMS in staff view
        And it is rendered correctly
        """

        config, split_test = self.create_group_configuration_experiment([Group("0", "Group A"), Group("1", "Group B"), Group("2", "Group C")], True)
        container = ContainerPage(self.browser, split_test.locator)

        # render in LMS correctly
        courseware_page = CoursewarePage(self.browser, self.course_id)
        self.publish_unit_and_verify_groups_in_lms(courseware_page, [u'Group A', u'Group B', u'Group C'])

        # I go to group configuration and delete group
        self.page.visit()
        self.page.q(css='.group-toggle').first.click()
        config.edit()
        config.groups[2].remove()
        config.save()
        self.page.q(css='.group-toggle').first.click()
        self._assert_fields(config, name="Name", description="Description", groups=["Group A", "Group B"])
        self.browser.close()
        self.browser.switch_to_window(self.browser.window_handles[0])

        # render in LMS to see how inactive vertical is rendered
        self.publish_unit_and_verify_groups_in_lms(
            courseware_page,
            [u'Group A', u'Group B', u'Group ID 2 (inactive)'],
            publish=False
        )

        self.browser.close()
        self.browser.switch_to_window(self.browser.window_handles[0])

        # I go to split test and delete inactive vertical
        container.visit()
        container.delete(0)

        # render in LMS again
        self.publish_unit_and_verify_groups_in_lms(courseware_page, [u'Group A', u'Group B'])
Exemple #10
0
 def setUp(self, is_staff=True):
     """
     Create a course with a section, subsection, and unit to which to add the component.
     """
     super(HTMLComponentEditor, self).setUp(is_staff=is_staff)
     self.component = 'Text'
     self.unit = self.go_to_unit_page()
     self.container_page = ContainerPage(self.browser, None)
     self.xblock_wrapper = XBlockWrapper(self.browser, None)
     # Add HTML component
     add_component(self.container_page, 'html', self.component)
     self.component = self.unit.xblocks[1]
     self.container_page.edit()
     self.html_editor = HtmlXBlockEditorView(self.browser, self.component.locator)
     self.iframe = HTMLEditorIframe(self.browser, self.component.locator)
 def test_add_html_component(self):
     """
     Scenario: I can add HTML components
     Given I am in Studio editing a new unit
     When I add this type of HTML component:
         | Component               |
         | Text                    |
         | Announcement            |
         | Zooming Image Tool      |
         | Raw HTML                |
     Then I see HTML components in this order:
         | Component               |
         | Text                    |
         | Announcement            |
         | Zooming Image Tool      |
         | Raw HTML                |
     """
     # Components to be added
     components = ['Text', 'Announcement', 'Zooming Image Tool', 'Raw HTML']
     self.go_to_unit_page()
     container_page = ContainerPage(self.browser, None)
     # Add components
     add_components(container_page, 'html', components)
     problems = [x_block.name for x_block in container_page.xblocks[1:]]
     # Assert that components appear in same order as added.
     self.assertEqual(problems, components)
    def test_common_problem_component(self):
        """
        Scenario: I can add Common Problem components
        Given I am in Studio editing a new unit
        When I add this type of Problem component:
            | Component            |`
            | Blank Common Problem |
            | Checkboxes           |
            | Dropdown             |
            | Multiple Choice      |
            | Numerical Input      |
            | Text Input           |
        Then I see Problem components in this order:
            | Component            |
            | Blank Common Problem |
            | Checkboxes           |
            | Dropdown             |
            | Multiple Choice      |
            | Numerical Input      |
            | Text Input           |
        """
        # Components to be added.
        components = ['Blank Common Problem', 'Checkboxes', 'Dropdown',
                      'Multiple Choice', 'Numerical Input', 'Text Input']

        self.go_to_unit_page()
        container_page = ContainerPage(self.browser, None)
        # Add components
        add_components(container_page, 'problem', components)
        problems = [x_block.name for x_block in container_page.xblocks[1:]]
        # Assert that components appear in the same order as added.
        self.assertEqual(problems, components)
Exemple #13
0
 def test_add_latex_html_component(self):
     """
     Scenario: I can add Latex HTML components
     Given I am in Studio editing a new unit
     Given I have enabled latex compiler
     When I add this type of HTML component:
         | Component               |
         | E-text Written in LaTeX |
     Then I see HTML components in this order:
         | Component               |
         | E-text Written in LaTeX |
     """
     # Latex component
     component = 'E-text Written in LaTeX'
     # Visit advanced settings page and enable latex compiler.
     self.advanced_settings.visit()
     self.advanced_settings.set('Enable LaTeX Compiler', 'True')
     self.go_to_unit_page()
     container_page = ContainerPage(self.browser, None)
     # Add latex component
     add_component(container_page,
                   'html',
                   component,
                   is_advanced_problem=False)
     problem = container_page.xblocks[1]
     # Asset that component has been added.
     self.assertEqual(problem.name, component)
Exemple #14
0
 def setUp(self):  # pylint: disable=arguments-differ
     super(TestCourseBadExport, self).setUp()
     self.export_page = ExportCoursePage(
         self.browser,
         self.course_info['org'], self.course_info['number'], self.course_info['run'],
     )
     self.edit_page = ContainerPage(self.browser, self.unit.locator)
     self.export_page.visit()
 def setUp(self, is_staff=True):
     """
     Create a course with a section, subsection, and unit to which to add the component.
     """
     super(HTMLComponentEditorTests, self).setUp(is_staff=is_staff)
     self.unit = self.go_to_unit_page()
     self.container_page = ContainerPage(self.browser, None)
     self.xblock_wrapper = XBlockWrapper(self.browser, None)
     self.component = None
     self.html_editor = None
     self.iframe = None
Exemple #16
0
    def test_use_group_configuration(self):
        """
        Scenario: Ensure that the group configuration can be used by split_module correctly
        Given I have a course without group configurations
        When I create new group configuration
        And I set new name and add a new group, save the group configuration
        And I go to the unit page in Studio
        And I add new advanced module "Content Experiment"
        When I assign created group configuration to the module
        Then I see the module has correct groups
        """
        self.page.visit()
        # Create new group configuration
        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()
        config.groups[2].name = "New group"
        # Save the configuration
        config.save()

        split_test = self._add_split_test_to_vertical(number=0)

        container = ContainerPage(self.browser, split_test.locator)
        container.visit()
        container.edit()
        component_editor = XBlockEditorView(self.browser, container.locator)
        component_editor.set_select_value_and_save(
            'Group Configuration', 'New Group Configuration Name')
        self.verify_groups(container, ['Group A', 'Group B', 'New group'], [])
 def setUp(self, is_staff=True):
     """
     Create a course with a section, subsection, and unit to which to add the component.
     """
     super(ProblemComponentEditor, self).setUp(is_staff=is_staff)
     self.component = 'Blank Common Problem'
     self.unit = self.go_to_unit_page()
     self.container_page = ContainerPage(self.browser, None)
     # Add a Problem
     add_component(self.container_page, 'problem', self.component)
     self.component = self.unit.xblocks[1]
     self.container_page.edit()
     self.problem_editor = ProblemXBlockEditorView(self.browser, self.component.locator)
 def setUp(self, is_staff=True):
     """
     Create a course with a section, subsection, and unit to which to add the component.
     """
     super(DiscussionComponentTest, self).setUp(is_staff=is_staff)
     self.component = 'discussion'
     self.unit = self.go_to_unit_page()
     self.container_page = ContainerPage(self.browser, None)
     # Add Discussion component
     add_component(self.container_page, 'discussion', self.component)
     self.component = self.unit.xblocks[1]
     self.container_page.edit()
     self.discussion_editor = DiscussionComponentEditor(self.browser, self.component.locator)
Exemple #19
0
    def test_split_test_LMS_staff_view(self):
        """
        Scenario: Ensure that split test is correctly rendered in LMS staff mode as it is
                  and after inactive group removal.

        Given I have a course with group configurations and split test that assigned to first group configuration
        Then I publish split test and view it in LMS in staff view
        And it is rendered correctly
        Then I go to group configuration and delete group
        Then I publish split test and view it in LMS in staff view
        And it is rendered correctly
        Then I go to split test and delete inactive vertical
        Then I publish unit and view unit in LMS in staff view
        And it is rendered correctly
        """

        config, split_test = self.create_group_configuration_experiment([
            Group("0", "Group A"),
            Group("1", "Group B"),
            Group("2", "Group C")
        ], True)
        container = ContainerPage(self.browser, split_test.locator)

        # render in LMS correctly
        courseware_page = CoursewarePage(self.browser, self.course_id)
        self.publish_unit_and_verify_groups_in_lms(
            courseware_page, [u'Group A', u'Group B', u'Group C'])

        # I go to group configuration and delete group
        self.page.visit()
        self.page.q(css='.group-toggle').first.click()
        config.edit()
        config.groups[2].remove()
        config.save()
        self.page.q(css='.group-toggle').first.click()
        self._assert_fields(config,
                            name="Name",
                            description="Description",
                            groups=["Group A", "Group B"])
        self.browser.close()
        self.browser.switch_to_window(self.browser.window_handles[0])

        # render in LMS to see how inactive vertical is rendered
        self.publish_unit_and_verify_groups_in_lms(
            courseware_page,
            [u'Group A', u'Group B', u'Group ID 2 (inactive)'],
            publish=False)

        self.browser.close()
        self.browser.switch_to_window(self.browser.window_handles[0])

        # I go to split test and delete inactive vertical
        container.visit()
        container.delete(0)

        # render in LMS again
        self.publish_unit_and_verify_groups_in_lms(courseware_page,
                                                   [u'Group A', u'Group B'])
Exemple #20
0
    def test_group_configuration_non_empty_usage(self):
        """
        Scenario: When group configuration is used, ensure that the links to units using a group configuration work correctly.
        Given I have a course without group configurations
        And I create new group configuration with 2 default groups
        And I create a unit and assign the newly created group configuration
        And open the Group Configuration page
        Then I see a link to the newly created unit
        When I click on the unit link
        Then I see correct unit page
        """
        # Create a new group configurations
        self.course_fixture._update_xblock(self.course_fixture._course_location, {
            "metadata": {
                u"user_partitions": [
                    create_user_partition_json(
                        0,
                        "Name",
                        "Description.",
                        [Group("0", "Group A"), Group("1", "Group B")]
                    ),
                ],
            },
        })

        # Assign newly created group configuration to unit
        vertical = self.course_fixture.get_nested_xblocks(category="vertical")[0]
        self.course_fixture.create_xblock(
            vertical.locator,
            XBlockFixtureDesc('split_test', 'Test Content Experiment', metadata={'user_partition_id': 0})
        )
        unit = CourseOutlineUnit(self.browser, vertical.locator)

        # Go to the Group Configuration Page and click unit anchor
        self.page.visit()
        config = self.page.experiment_group_configurations[0]
        config.toggle()
        usage = config.usages[0]
        config.click_unit_anchor()

        unit = ContainerPage(self.browser, vertical.locator)
        # Waiting for the page load and verify that we've landed on the unit page
        EmptyPromise(
            lambda: unit.is_browser_on_page(), "loaded page {!r}".format(unit),
            timeout=30
        ).fulfill()

        self.assertIn(unit.name, usage)
    def _studio_add_content(self, studio_course_outline, html_content):
        """
        Add content to first section on studio course page.
        """
        # create a unit in course outline
        studio_course_outline.visit()
        subsection = studio_course_outline.section_at(0).subsection_at(0)
        subsection.expand_subsection()
        subsection.add_unit()

        # got to unit and create an HTML component and save (not publish)
        unit_page = ContainerPage(self.browser, None)
        unit_page.wait_for_page()
        add_html_component(unit_page, 0)
        unit_page.wait_for_element_presence('.edit-button', 'Edit button is visible')
        click_css(unit_page, '.edit-button', 0, require_notification=False)
        unit_page.wait_for_element_visibility('.modal-editor', 'Modal editor is visible')
        type_in_codemirror(unit_page, 0, html_content)
        click_css(unit_page, '.action-save', 0)
    def _studio_add_content(self, section_index):
        """
        Add content on studio course page under specified section
        """

        self._auto_auth(self.STAFF_USERNAME, self.STAFF_EMAIL, True)
        # create a unit in course outline
        self.studio_course_outline.visit()
        subsection = self.studio_course_outline.section_at(section_index).subsection_at(0)
        subsection.expand_subsection()
        subsection.add_unit()

        # got to unit and create an HTML component and save (not publish)
        unit_page = ContainerPage(self.browser, None)
        unit_page.wait_for_page()
        add_html_component(unit_page, 0)
        unit_page.wait_for_element_presence('.edit-button', 'Edit button is visible')
        click_css(unit_page, '.edit-button', 0, require_notification=False)
        unit_page.wait_for_element_visibility('.modal-editor', 'Modal editor is visible')
        type_in_codemirror(unit_page, 0, self.HTML_CONTENT)
        click_css(unit_page, '.action-save', 0)
    def test_add_advanced_problem(self, component):
        """
        Scenario Outline: I can add Advanced Problem components
           Given I am in Studio editing a new unit
           When I add a "<Component>" "Advanced Problem" component
           Then I see a "<Component>" Problem component

        Examples:
               | Component                     |
               | Blank Advanced Problem        |
               | Circuit Schematic Builder     |
               | Custom Python-Evaluated Input |
               | Drag and Drop                 |
               | Image Mapped Input            |
               | Math Expression Input         |
               | Problem with Adaptive Hint    |
        """
        self.go_to_unit_page()
        page = ContainerPage(self.browser, None)
        add_component(page, 'problem', component, is_advanced_problem=True)
        problem = page.xblocks[1]
        self.assertEqual(problem.name, component)
    def _studio_add_content(self, section_index):
        """
        Add content on studio course page under specified section
        """

        self._auto_auth(self.STAFF_USERNAME, self.STAFF_EMAIL, True)
        # create a unit in course outline
        self.studio_course_outline.visit()
        subsection = self.studio_course_outline.section_at(section_index).subsection_at(0)
        subsection.expand_subsection()
        subsection.add_unit()

        # got to unit and create an HTML component and save (not publish)
        unit_page = ContainerPage(self.browser, None)
        unit_page.wait_for_page()
        add_html_component(unit_page, 0)
        unit_page.wait_for_element_presence('.edit-button', 'Edit button is visible')
        click_css(unit_page, '.edit-button', 0, require_notification=False)
        unit_page.wait_for_element_visibility('.modal-editor', 'Modal editor is visible')
        type_in_codemirror(unit_page, 0, self.HTML_CONTENT)
        click_css(unit_page, '.action-save', 0)
Exemple #25
0
class ProblemComponentEditor(ContainerBase):
    """
    Feature: CMS.Component Adding
    As a course author, I want to be able to add and edit Problem
    """

    def setUp(self, is_staff=True):
        """
        Create a course with a section, subsection, and unit to which to add the component.
        """
        super(ProblemComponentEditor, self).setUp(is_staff=is_staff)
        self.component = 'Blank Common Problem'
        self.unit = self.go_to_unit_page()
        self.container_page = ContainerPage(self.browser, None)
        # Add a Problem
        add_component(self.container_page, 'problem', self.component)
        self.component = self.unit.xblocks[1]
        self.container_page.edit()
        self.problem_editor = ProblemXBlockEditorView(self.browser, self.component.locator)

    def populate_course_fixture(self, course_fixture):
        """
        Adds a course fixture
        """
        course_fixture.add_children(
            XBlockFixtureDesc('chapter', 'Test Section').add_children(
                XBlockFixtureDesc('sequential', 'Test Subsection').add_children(
                    XBlockFixtureDesc('vertical', 'Test Unit')
                )
            )
        )

    def test_user_can_view_metadata(self):
        """
        Scenario: User can view metadata
        Given I have created a Blank Common Problem
        When I edit and select Settings
        Then I see the advanced settings and their expected values
        And Edit High Level Source is not visible
        """
        expected_default_settings = {
            'Display Name': u'Blank Common Problem',
            'Matlab API key': u'',
            'Maximum Attempts': u'',
            'Problem Weight': u'',
            'Randomization': u'Never',
            'Show Answer': u'Finished',
            'Show Reset Button': u'False',
            'Timer Between Attempts': u'0'
        }
        self.problem_editor.open_settings()
        settings = self.problem_editor.get_settings()
        self.assertEqual(expected_default_settings, settings)
        self.assertFalse(self.problem_editor.is_latex_compiler_present())

    def test_user_can_modify_string_values(self):
        """
        Given I have created a Blank Common Problem
        When I edit and select Settings
        Then I can modify the display name
        And my display name change is persisted on save
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Display Name', 'New Name')
        self.problem_editor.save()
        component_name = self.unit.xblock_titles[0]
        self.assertEqual(component_name, 'New Name', 'Component Name is not same as the new name')

    def test_user_can_specify_special_characters(self):
        """
        Scenario: User can specify special characters in String values
        Given I have created a Blank Common Problem
        When I edit and select Settings
        Then I can specify special characters in the display name
        And my special characters are persisted on save
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Display Name', '&&&')
        self.problem_editor.save()
        component_name = self.unit.xblock_titles[0]
        self.assertEqual(component_name, '&&&', 'Component Name is not same as the new name')

    def test_user_can_revert_display_name_to_unset(self):
        """
        Scenario: User can revert display name to unset
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then I can revert the display name to unset
        And my display name is unset on save
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Display Name', 'New Name')
        self.problem_editor.save()

        # reopen settings
        self.container_page.edit()
        self.problem_editor.open_settings()

        self.problem_editor.revert_setting(display_name=True)
        self.problem_editor.save()
        component_name = self.unit.xblock_titles[0]
        self.assertEqual(component_name, 'Blank Advanced Problem', 'Component Name is not reverted to default name')

    def test_user_can_set_html_in_display_name(self):
        """
        Scenario: User can specify html in display name and it will be escaped
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then I can specify html in the display name and save
            And the problem display name is "<script>alert('test')</script>"
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Display Name', '<script>alert("test")</script>')
        self.problem_editor.save()
        component_name = self.unit.xblock_titles[0]
        self.assertEqual(
            component_name,
            '<script>alert("test")</script>',
            'Component Name is not same as the new name'
        )

    def test_user_can_modify_float_input(self):
        """
        Scenario: User can modify float input values
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then I can set the weight to "3.5"
            And my change to weight is persisted
            And I can revert to the default value of unset for weight
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Problem Weight', '3.5')
        self.problem_editor.save()

        # reopen settings
        self.container_page.edit()
        self.problem_editor.open_settings()

        field_value = self.problem_editor.get_field_val('Problem Weight')
        self.assertEqual(field_value, '3.5')
        self.problem_editor.revert_setting()
        field_value = self.problem_editor.get_field_val('Problem Weight')
        self.assertEqual(field_value, '', 'Component settings is not reverted to default')

    def test_user_cannot_type_letters(self):
        """
        Scenario: User cannot type letters in float number field
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then if I set the weight to "abc", it remains unset
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Problem Weight', 'abc')
        field_value = self.problem_editor.get_field_val('Problem Weight')
        self.assertEqual(field_value, '', "Only the Numerical input is allowed in this field")

    @skip_if_browser('firefox')
    # Lettuce tests run on chrome and chrome does not allow to enter
    # periods/dots in this field and consequently we have to save the
    # value as '234'. Whereas, bokchoy runs with the older version of
    # firefox on jenkins, which does not allow to save the value if it
    # has a period/dot. Clicking on save button after filling '2.34' in
    # field, does not do anything and test does not go any further.
    # So, it fails always.
    def test_user_cannot_type_decimal_values(self):
        """
        Scenario: User cannot type decimal values integer number field
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then if I set the max attempts to "2.34", it will persist as a valid integer
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Maximum Attempts', '2.34')
        self.problem_editor.save()

        # reopen settings
        self.container_page.edit()
        self.problem_editor.open_settings()

        field_value = self.problem_editor.get_field_val('Maximum Attempts')
        self.assertEqual(field_value, '234', "Decimal values are not allowed in this field")

    def test_user_cannot_type_out_of_range_values(self):
        """
        Scenario: User cannot type out of range values in an integer number field
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then if I set the max attempts to "-3", it will persist as a valid integer
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Maximum Attempts', '-3')
        self.problem_editor.save()

        # reopen settings
        self.container_page.edit()
        self.problem_editor.open_settings()

        field_value = self.problem_editor.get_field_val('Maximum Attempts')
        self.assertGreaterEqual(field_value, '0', "Negative values are not allowed in this field")

    def test_settings_are_not_saved_on_cancel(self):
        """
        Scenario: Settings changes are not saved on Cancel
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then I can set the weight to "3.5"
        And I can modify the display name
            Then If I press Cancel my changes are not persisted
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Problem Weight', '3.5')
        self.problem_editor.cancel()

        # reopen settings
        self.container_page.edit()
        self.problem_editor.open_settings()

        field_value = self.problem_editor.get_field_val('Problem Weight')
        self.assertEqual(field_value, '', "Component setting should not appear updated if cancelled during editing")

    def test_cheat_sheet_visible_on_toggle(self):
        """
        Scenario: Cheat sheet visible on toggle
        Given I have created a Blank Common Problem
        And I can edit the problem
            Then I can see cheatsheet
        """
        self.problem_editor.toggle_cheatsheet()
        self.assertTrue(self.problem_editor.is_cheatsheet_present(), "Cheatsheet not present")

    def test_user_can_select_values(self):
        """
        Scenario: User can select values in a Select
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then I can select 'Per Student' for Randomization
            And my change to randomization is persisted
            And I can revert to the default value for randomization
        """
        dropdown_name = 'Randomization'
        self.problem_editor.open_settings()
        self.problem_editor.select_from_dropdown(dropdown_name, 'Per Student')
        self.problem_editor.save()

        # reopen the settings
        self.container_page.edit()
        self.problem_editor.open_settings()

        dropdown_value = self.problem_editor.get_value_from_the_dropdown(dropdown_name)
        self.assertEqual(dropdown_value, 'Per Student', "Component setting is not changed")

        # revert settings
        self.problem_editor.revert_setting()
        dropdown_value = self.problem_editor.get_value_from_the_dropdown(dropdown_name)
        self.assertEqual(dropdown_value, 'Never', 'Component setting is not reverted to default')
class ProblemComponentEditor(ContainerBase):
    """
    Feature: CMS.Component Adding
    As a course author, I want to be able to add and edit Problem
    """

    def setUp(self, is_staff=True):
        """
        Create a course with a section, subsection, and unit to which to add the component.
        """
        super(ProblemComponentEditor, self).setUp(is_staff=is_staff)
        self.component = 'Blank Common Problem'
        self.unit = self.go_to_unit_page()
        self.container_page = ContainerPage(self.browser, None)
        # Add a Problem
        add_component(self.container_page, 'problem', self.component)
        self.component = self.unit.xblocks[1]
        self.container_page.edit()
        self.problem_editor = ProblemXBlockEditorView(self.browser, self.component.locator)

    def populate_course_fixture(self, course_fixture):
        """
        Adds a course fixture
        """
        course_fixture.add_children(
            XBlockFixtureDesc('chapter', 'Test Section').add_children(
                XBlockFixtureDesc('sequential', 'Test Subsection').add_children(
                    XBlockFixtureDesc('vertical', 'Test Unit')
                )
            )
        )

    def test_user_can_view_metadata(self):
        """
        Scenario: User can view metadata
        Given I have created a Blank Common Problem
        When I edit and select Settings
        Then I see the advanced settings and their expected values
        And Edit High Level Source is not visible
        """
        expected_default_settings = {
            'Display Name': u'Blank Common Problem',
            'Matlab API key': u'',
            'Maximum Attempts': u'',
            'Problem Weight': u'',
            'Randomization': u'Never',
            'Show Answer': u'Finished',
            'Show Answer: Number of Attempts': u'0',
            'Show Reset Button': u'False',
            'Timer Between Attempts': u'0'
        }
        self.problem_editor.open_settings()
        settings = self.problem_editor.get_settings()
        self.assertEqual(expected_default_settings, settings)
        self.assertFalse(self.problem_editor.is_latex_compiler_present())

    def test_user_can_modify_string_values(self):
        """
        Given I have created a Blank Common Problem
        When I edit and select Settings
        Then I can modify the display name
        And my display name change is persisted on save
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Display Name', 'New Name')
        self.problem_editor.save()
        component_name = self.unit.xblock_titles[0]
        self.assertEqual(component_name, 'New Name', 'Component Name is not same as the new name')

    def test_user_can_specify_special_characters(self):
        """
        Scenario: User can specify special characters in String values
        Given I have created a Blank Common Problem
        When I edit and select Settings
        Then I can specify special characters in the display name
        And my special characters are persisted on save
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Display Name', '&&&')
        self.problem_editor.save()
        component_name = self.unit.xblock_titles[0]
        self.assertEqual(component_name, '&&&', 'Component Name is not same as the new name')

    def test_user_can_revert_display_name_to_unset(self):
        """
        Scenario: User can revert display name to unset
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then I can revert the display name to unset
        And my display name is unset on save
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Display Name', 'New Name')
        self.problem_editor.save()

        # reopen settings
        self.container_page.edit()
        self.problem_editor.open_settings()

        self.problem_editor.revert_setting(display_name=True)
        self.problem_editor.save()
        component_name = self.unit.xblock_titles[0]
        self.assertEqual(component_name, 'Blank Advanced Problem', 'Component Name is not reverted to default name')

    def test_user_can_set_html_in_display_name(self):
        """
        Scenario: User can specify html in display name and it will be escaped
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then I can specify html in the display name and save
            And the problem display name is "<script>alert('test')</script>"
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Display Name', '<script>alert("test")</script>')
        self.problem_editor.save()
        component_name = self.unit.xblock_titles[0]
        self.assertEqual(
            component_name,
            '<script>alert("test")</script>',
            'Component Name is not same as the new name'
        )

    def test_user_can_modify_float_input(self):
        """
        Scenario: User can modify float input values
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then I can set the weight to "3.5"
            And my change to weight is persisted
            And I can revert to the default value of unset for weight
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Problem Weight', '3.5')
        self.problem_editor.save()

        # reopen settings
        self.container_page.edit()
        self.problem_editor.open_settings()

        field_value = self.problem_editor.get_field_val('Problem Weight')
        self.assertEqual(field_value, '3.5')
        self.problem_editor.revert_setting()
        field_value = self.problem_editor.get_field_val('Problem Weight')
        self.assertEqual(field_value, '', 'Component settings is not reverted to default')

    def test_user_cannot_type_letters(self):
        """
        Scenario: User cannot type letters in float number field
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then if I set the weight to "abc", it remains unset
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Problem Weight', 'abc')
        field_value = self.problem_editor.get_field_val('Problem Weight')
        self.assertEqual(field_value, '', "Only the Numerical input is allowed in this field")

    @skip_if_browser('firefox')
    # Lettuce tests run on chrome and chrome does not allow to enter
    # periods/dots in this field and consequently we have to save the
    # value as '234'. Whereas, bokchoy runs with the older version of
    # firefox on jenkins, which does not allow to save the value if it
    # has a period/dot. Clicking on save button after filling '2.34' in
    # field, does not do anything and test does not go any further.
    # So, it fails always.
    def test_user_cannot_type_decimal_values(self):
        """
        Scenario: User cannot type decimal values integer number field
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then if I set the max attempts to "2.34", it will persist as a valid integer
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Maximum Attempts', '2.34')
        self.problem_editor.save()

        # reopen settings
        self.container_page.edit()
        self.problem_editor.open_settings()

        field_value = self.problem_editor.get_field_val('Maximum Attempts')
        self.assertEqual(field_value, '234', "Decimal values are not allowed in this field")

    def test_user_cannot_type_out_of_range_values(self):
        """
        Scenario: User cannot type out of range values in an integer number field
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then if I set the max attempts to "-3", it will persist as a valid integer
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Maximum Attempts', '-3')
        self.problem_editor.save()

        # reopen settings
        self.container_page.edit()
        self.problem_editor.open_settings()

        field_value = self.problem_editor.get_field_val('Maximum Attempts')
        self.assertGreaterEqual(field_value, '0', "Negative values are not allowed in this field")

    def test_settings_are_not_saved_on_cancel(self):
        """
        Scenario: Settings changes are not saved on Cancel
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then I can set the weight to "3.5"
        And I can modify the display name
            Then If I press Cancel my changes are not persisted
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Problem Weight', '3.5')
        self.problem_editor.cancel()

        # reopen settings
        self.container_page.edit()
        self.problem_editor.open_settings()

        field_value = self.problem_editor.get_field_val('Problem Weight')
        self.assertEqual(field_value, '', "Component setting should not appear updated if cancelled during editing")

    def test_cheat_sheet_visible_on_toggle(self):
        """
        Scenario: Cheat sheet visible on toggle
        Given I have created a Blank Common Problem
        And I can edit the problem
            Then I can see cheatsheet
        """
        self.problem_editor.toggle_cheatsheet()
        self.assertTrue(self.problem_editor.is_cheatsheet_present(), "Cheatsheet not present")

    def test_user_can_select_values(self):
        """
        Scenario: User can select values in a Select
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then I can select 'Per Student' for Randomization
            And my change to randomization is persisted
            And I can revert to the default value for randomization
        """
        dropdown_name = 'Randomization'
        self.problem_editor.open_settings()
        self.problem_editor.select_from_dropdown(dropdown_name, 'Per Student')
        self.problem_editor.save()

        # reopen the settings
        self.container_page.edit()
        self.problem_editor.open_settings()

        dropdown_value = self.problem_editor.get_value_from_the_dropdown(dropdown_name)
        self.assertEqual(dropdown_value, 'Per Student', "Component setting is not changed")

        # revert settings
        self.problem_editor.revert_setting()
        dropdown_value = self.problem_editor.get_value_from_the_dropdown(dropdown_name)
        self.assertEqual(dropdown_value, 'Never', 'Component setting is not reverted to default')
    def test_container_page_active_verticals_names_are_synced(self):
        """
        Scenario: Ensure that the Content Experiment display synced vertical names and correct groups.
        Given I have a course with group configuration
        And I go to the Group Configuration page in Studio
        And I edit the name of the group configuration, add new group and remove old one
        And I change the name for the group "New group" to "Second Group"
        And I go to the Container page in Studio
        And I edit the Content Experiment
        Then I see the group configuration name is changed in `Group Configuration` dropdown
        And the group configuration name is changed on container page
        And I see the module has 2 active groups and one inactive
        And I see "Add missing groups" link exists
        When I click on "Add missing groups" link
        The I see the module has 3 active groups and one inactive
        """
        self.course_fixture._update_xblock(self.course_fixture._course_location, {
            "metadata": {
                u"user_partitions": [
                    create_user_partition_json(
                        0,
                        'Name of the Group Configuration',
                        'Description of the group configuration.',
                        [Group("0", 'Group A'), Group("1", 'Group B'), Group("2", 'Group C')]
                    ),
                ],
            },
        })

        # Add split test to vertical and assign newly created group configuration to it
        split_test = self._add_split_test_to_vertical(number=0, group_configuration_metadata={'user_partition_id': 0})

        self.page.visit()
        config = self.page.experiment_group_configurations[0]
        config.edit()
        config.name = "Second Group Configuration Name"
        # `Group C` -> `Second Group`
        config.groups[2].name = "Second Group"
        # Add new group
        config.add_group()  # Group D
        # Remove Group A
        config.groups[0].remove()
        # Save the configuration
        config.save()

        container = ContainerPage(self.browser, split_test.locator)
        container.visit()
        container.edit()
        component_editor = ComponentEditorView(self.browser, container.locator)
        self.assertEqual(
            "Second Group Configuration Name",
            component_editor.get_selected_option_text('Group Configuration')
        )
        component_editor.cancel()
        self.assertIn(
            "Second Group Configuration Name",
            container.get_xblock_information_message()
        )
        self.verify_groups(
            container, ['Group B', 'Second Group'], ['Group ID 0'],
            verify_missing_groups_not_present=False
        )
        # Click the add button and verify that the groups were added on the page
        container.add_missing_groups()
        self.verify_groups(container, ['Group B', 'Second Group', 'Group D'], ['Group ID 0'])
Exemple #28
0
    def test_container_page_active_verticals_names_are_synced(self):
        """
        Scenario: Ensure that the Content Experiment display synced vertical names and correct groups.
        Given I have a course with group configuration
        And I go to the Group Configuration page in Studio
        And I edit the name of the group configuration, add new group and remove old one
        And I change the name for the group "New group" to "Second Group"
        And I go to the Container page in Studio
        And I edit the Content Experiment
        Then I see the group configuration name is changed in `Group Configuration` dropdown
        And the group configuration name is changed on container page
        And I see the module has 2 active groups and one inactive
        And I see "Add missing groups" link exists
        When I click on "Add missing groups" link
        The I see the module has 3 active groups and one inactive
        """
        self.course_fixture._update_xblock(
            self.course_fixture._course_location, {
                "metadata": {
                    u"user_partitions": [
                        create_user_partition_json(
                            0, 'Name of the Group Configuration',
                            'Description of the group configuration.', [
                                Group("0", 'Group A'),
                                Group("1", 'Group B'),
                                Group("2", 'Group C')
                            ]),
                    ],
                },
            })

        # Add split test to vertical and assign newly created group configuration to it
        split_test = self._add_split_test_to_vertical(
            number=0, group_configuration_metadata={'user_partition_id': 0})

        self.page.visit()
        config = self.page.experiment_group_configurations[0]
        config.edit()
        config.name = "Second Group Configuration Name"
        # `Group C` -> `Second Group`
        config.groups[2].name = "Second Group"
        # Add new group
        config.add_group()  # Group D
        # Remove Group A
        config.groups[0].remove()
        # Save the configuration
        config.save()

        container = ContainerPage(self.browser, split_test.locator)
        container.visit()
        container.edit()
        component_editor = XBlockEditorView(self.browser, container.locator)
        self.assertEqual(
            "Second Group Configuration Name",
            component_editor.get_selected_option_text('Group Configuration'))
        component_editor.cancel()
        self.assertIn("Second Group Configuration Name",
                      container.get_xblock_information_message())
        self.verify_groups(container, ['Group B', 'Second Group'],
                           ['Group ID 0'],
                           verify_missing_groups_not_present=False)
        # Click the add button and verify that the groups were added on the page
        container.add_missing_groups()
        self.verify_groups(container, ['Group B', 'Second Group', 'Group D'],
                           ['Group ID 0'])
class HTMLComponentEditorTests(ContainerBase):
    """
    Feature: CMS.Component Adding
    As a course author, I want to be able to add and edit HTML component
    """
    shard = 18

    def setUp(self, is_staff=True):
        """
        Create a course with a section, subsection, and unit to which to add the component.
        """
        super(HTMLComponentEditorTests, self).setUp(is_staff=is_staff)
        self.unit = self.go_to_unit_page()
        self.container_page = ContainerPage(self.browser, None)
        self.xblock_wrapper = XBlockWrapper(self.browser, None)
        self.component = None
        self.html_editor = None
        self.iframe = None

    def populate_course_fixture(self, course_fixture):
        """
        Adds a course fixture
        """
        course_fixture.add_children(
            XBlockFixtureDesc('chapter', 'Test Section').add_children(
                XBlockFixtureDesc('sequential', 'Test Subsection').add_children(
                    XBlockFixtureDesc('vertical', 'Test Unit')
                )
            )
        )

    def _add_content(self, content):
        """
        Set and save content in editor and assert its presence in container page's html

        Args:
            content(str): Verifiable content
        """
        self.html_editor.set_raw_content(content)
        self.html_editor.save_content()
        self.container_page.wait_for_page()

    def _add_component(self, sub_type):
        """
        Add sub-type of HTML component in studio

        Args:
            sub_type(str): Sub-type of HTML component
        """
        add_component(self.container_page, 'html', sub_type)
        self.component = self.unit.xblocks[1]
        self.html_editor = HtmlXBlockEditorView(self.browser, self.component.locator)
        self.iframe = HTMLEditorIframe(self.browser, self.component.locator)

    def test_user_can_view_metadata(self):
        """
        Scenario: User can view metadata
        Given I have created a Blank HTML Page
            And I edit and select Settings
                Then I see the HTML component settings
        """

        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()
        self.html_editor.open_settings_tab()
        display_name_value = self.html_editor.get_default_settings()[0]
        display_name_key = self.html_editor.keys[0]
        self.assertEqual(
            ['Display Name', 'Text'],
            [display_name_key, display_name_value],
            "Settings not found"
        )
        editor_value = self.html_editor.get_default_settings()[1]
        editor_key = self.html_editor.keys[1]
        self.assertEqual(
            ['Editor', 'Visual'],
            [editor_key, editor_value],
            "Settings not found"
        )

    def test_user_can_modify_display_name(self):
        """
        Scenario: User can modify display name
        Given I have created a Blank HTML Page
            And I edit and select Settings
        Then I can modify the display name
            And my display name change is persisted on save
        """
        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()
        self.html_editor.open_settings_tab()
        self.html_editor.set_field_val('Display Name', 'New Name')
        self.html_editor.save_settings()
        component_name = self.unit.xblock_titles[0]
        self.assertEqual(component_name, 'New Name', "Component name is not as edited")

    def test_link_plugin_sets_url_correctly(self):
        """
        Scenario: TinyMCE link plugin sets urls correctly
        Given I have created a Blank HTML Page
            When I edit the page
            And I add a link with static link "/static/image.jpg" via the Link Plugin Icon
                Then the href link is rewritten to the asset link "image.jpg"
                And the link is shown as "/static/image.jpg" in the Link Plugin
        """
        static_link = '/static/image.jpg'

        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()
        self.html_editor.open_link_plugin()
        self.html_editor.save_static_link(static_link)
        self.html_editor.switch_to_iframe()
        href = self.iframe.href
        self.assertIn('image.jpg', href)
        self.iframe.select_link()
        self.iframe.switch_to_default()
        self.assertEqual(
            self.html_editor.url_from_the_link_plugin,
            static_link,
            "URL in the link plugin is different"
        )

    def test_tinymce_and_codemirror_preserve_style_tags(self):
        """
        Scenario: TinyMCE and CodeMirror preserve style tags
        Given I have created a Blank HTML Page
            When I edit the page
            And type "<p class='title'>pages</p><style><!-- .title { color: red; } --></style>" in the code editor and
            press OK
            And I save the page
                Then the page text contains:
                  ""
                  <p class="title">pages</p>
                  <style><!--
                  .title { color: red; }
                  --></style>
                  ""
        """
        content = u'<p class="title">pages</p><style><!-- .title { color: red; } --></style>'

        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()
        self._add_content(content)
        html = self.container_page.content_html
        self.assertIn(content, html)

    def test_tinymce_and_codemirror_preserve_span_tags(self):
        """
        Scenario: TinyMCE and CodeMirror preserve span tags
        Given I have created a Blank HTML Page
            When I edit the page
            And type "<span>Test</span>" in the code editor and press OK
            And I save the page
                Then the page text contains:
                ""
                    <span>Test</span>
                ""
        """
        content = "<span>Test</span>"

        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()
        self._add_content(content)
        html = self.container_page.content_html
        self.assertIn(content, html)

    def test_tinymce_and_codemirror_preserve_math_tags(self):
        """
        Scenario: TinyMCE and CodeMirror preserve math tags
        Given I have created a Blank HTML Page
            When I edit the page
            And type "<math><msup><mi>x</mi><mn>2</mn></msup></math>" in the code editor and press OK
            And I save the page
                Then the page text contains:
                ""
                    <math><msup><mi>x</mi><mn>2</mn></msup></math>
                ""
        """
        content = "<math><msup><mi>x</mi><mn>2</mn></msup></math>"

        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()
        self._add_content(content)
        html = self.container_page.content_html
        self.assertIn(content, html)

    def test_code_format_toolbar_wraps_text_with_code_tags(self):
        """
        Scenario: Code format toolbar button wraps text with code tags
        Given I have created a Blank HTML Page
            When I edit the page
            And I set the text to "display as code" and I select the text
            And I save the page
                Then the page text contains:
                ""
                    <p><code>display as code</code></p>
                ""
        """
        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()
        self.html_editor.set_text_and_select("display as code")
        self.html_editor.click_code_toolbar_button()
        self.html_editor.save_content()
        html = self.container_page.content_html
        self.assertIn(html, '<p><code>display as code</code></p>')

    def test_raw_html_component_does_not_change_text(self):
        """
        Scenario: Raw HTML component does not change text
        Given I have created a raw HTML component
            When I edit the page
            And type "<li>zzzz<ol> " into the Raw Editor
            And I save the page
                Then the page text contains:
                  ""
                  <li>zzzz<ol>
                  ""
            And I edit the page
                Then the Raw Editor contains exactly:
                  ""
                  <li>zzzz<ol>
                  ""
        """
        content = "<li>zzzz</li>"

        # Add Raw HTML type component
        self._add_component('Raw HTML')
        self.container_page.edit()

        # Set content in tinymce editor
        type_in_codemirror(self.html_editor, 0, content)
        self.html_editor.save_content()

        # The HTML of the content added through tinymce editor
        html = self.container_page.content_html
        # The text content should be present with its tag preserved
        self.assertIn(content, html)

        self.container_page.edit()
        editor_value = self.html_editor.editor_value
        # The tinymce editor value should not be different from the content added in the start
        self.assertEqual(content, editor_value)

    def test_tinymce_toolbar_buttons_are_as_expected(self):
        """
        Scenario: TinyMCE toolbar buttons are as expected
        Given I have created a Blank HTML Page
        When I edit the page
            Then the expected toolbar buttons are displayed
        """
        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()

        expected_buttons = [
            u'bold',
            u'italic',
            u'underline',
            u'forecolor',
            # This is our custom "code style" button, which uses an image instead of a class.
            u'none',
            u'alignleft',
            u'aligncenter',
            u'alignright',
            u'alignjustify',
            u'bullist',
            u'numlist',
            u'outdent',
            u'indent',
            u'blockquote',
            u'link',
            u'unlink',
            u'image'
        ]
        toolbar_dropdowns = self.html_editor.toolbar_dropdown_titles
        # The toolbar is divided in two sections: drop-downs and all other formatting buttons
        # The assertions under asserts for the drop-downs
        self.assertEqual(len(toolbar_dropdowns), 2)
        self.assertEqual(['Paragraph', 'Font Family'], toolbar_dropdowns)

        toolbar_buttons = self.html_editor.toolbar_button_titles
        # The assertions under asserts for all the remaining formatting buttons
        self.assertEqual(len(toolbar_buttons), len(expected_buttons))

        for index, button in enumerate(expected_buttons):
            class_name = toolbar_buttons[index]
            self.assertEqual("mce-ico mce-i-" + button, class_name)

    def test_static_links_converted(self):
        """
        Scenario: Static links are converted when switching between code editor and WYSIWYG views
        Given I have created a Blank HTML Page
        When I edit the page
            And type "<img src="/static/image.jpg">" in the code editor and press OK
        Then the src link is rewritten to the asset link /asset-v1:(course_id)+type@asset+block/image.jpg
            And the code editor displays "<p><img src="/static/image.jpg" /></p>"
        """
        value = '<img src="/static/image.jpg">'

        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()
        self.html_editor.set_raw_content(value)
        self.html_editor.save_content()
        html = self.container_page.content_html
        src = "/asset-v1:{}+type@asset+block/image.jpg".format(self.course_id.strip('course-v1:'))
        self.assertIn(src, html)
        self.container_page.edit()
        self.html_editor.open_raw_editor()
        editor_value = self.html_editor.editor_value
        self.assertEqual(value, editor_value)

    def test_font_selection_dropdown(self):
        """
        Scenario: Font selection dropdown contains Default font and tinyMCE builtin fonts
        Given I have created a Blank HTML Page
        When I edit the page
        And I click font selection dropdown
            Then I should see a list of available fonts
            And "Default" fonts should be available
            And all standard tinyMCE fonts should be available
        """
        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()
        EXPECTED_FONTS = {
            u"Default": [u'"Open Sans"', u'Verdana', u'Arial', u'Helvetica', u'sans-serif'],
            u"Andale Mono": [u'andale mono', u'times'],
            u"Arial": [u'arial', u'helvetica', u'sans-serif'],
            u"Arial Black": [u'arial black', u'avant garde'],
            u"Book Antiqua": [u'book antiqua', u'palatino'],
            u"Comic Sans MS": [u'comic sans ms', u'sans-serif'],
            u"Courier New": [u'courier new', u'courier'],
            u"Georgia": [u'georgia', u'palatino'],
            u"Helvetica": [u'helvetica'],
            u"Impact": [u'impact', u'chicago'],
            u"Symbol": [u'symbol'],
            u"Tahoma": [u'tahoma', u'arial', u'helvetica', u'sans-serif'],
            u"Terminal": [u'terminal', u'monaco'],
            u"Times New Roman": [u'times new roman', u'times'],
            u"Trebuchet MS": [u'trebuchet ms', u'geneva'],
            u"Verdana": [u'verdana', u'geneva'],
            # tinyMCE does not set font-family on dropdown span for these two fonts
            u"Webdings": [u""],  # webdings
            u"Wingdings": [u""]  # wingdings
        }
        self.html_editor.open_font_dropdown()
        self.assertDictContainsSubset(EXPECTED_FONTS, self.html_editor.font_dict())
class HTMLComponentEditorTests(ContainerBase):
    """
    Feature: CMS.Component Adding
    As a course author, I want to be able to add and edit HTML component
    """
    shard = 18

    def setUp(self, is_staff=True):
        """
        Create a course with a section, subsection, and unit to which to add the component.
        """
        super(HTMLComponentEditorTests, self).setUp(is_staff=is_staff)
        self.unit = self.go_to_unit_page()
        self.container_page = ContainerPage(self.browser, None)
        self.xblock_wrapper = XBlockWrapper(self.browser, None)
        self.component = None
        self.html_editor = None
        self.iframe = None

    def populate_course_fixture(self, course_fixture):
        """
        Adds a course fixture
        """
        course_fixture.add_children(
            XBlockFixtureDesc('chapter', 'Test Section').add_children(
                XBlockFixtureDesc('sequential',
                                  'Test Subsection').add_children(
                                      XBlockFixtureDesc(
                                          'vertical', 'Test Unit'))))

    def _add_content(self, content):
        """
        Set and save content in editor and assert its presence in container page's html

        Args:
            content(str): Verifiable content
        """
        self.html_editor.set_raw_content(content)
        self.html_editor.save_content()
        self.container_page.wait_for_page()

    def _add_component(self, sub_type):
        """
        Add sub-type of HTML component in studio

        Args:
            sub_type(str): Sub-type of HTML component
        """
        add_component(self.container_page, 'html', sub_type)
        self.component = self.unit.xblocks[1]
        self.html_editor = HtmlXBlockEditorView(self.browser,
                                                self.component.locator)
        self.iframe = HTMLEditorIframe(self.browser, self.component.locator)

    def test_user_can_view_metadata(self):
        """
        Scenario: User can view metadata
        Given I have created a Blank HTML Page
            And I edit and select Settings
                Then I see the HTML component settings
        """

        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()
        self.html_editor.open_settings_tab()
        display_name_value = self.html_editor.get_default_settings()[0]
        display_name_key = self.html_editor.keys[0]
        self.assertEqual(['Display Name', 'Text'],
                         [display_name_key, display_name_value],
                         "Settings not found")
        editor_value = self.html_editor.get_default_settings()[1]
        editor_key = self.html_editor.keys[1]
        self.assertEqual(['Editor', 'Visual'], [editor_key, editor_value],
                         "Settings not found")

    def test_user_can_modify_display_name(self):
        """
        Scenario: User can modify display name
        Given I have created a Blank HTML Page
            And I edit and select Settings
        Then I can modify the display name
            And my display name change is persisted on save
        """
        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()
        self.html_editor.open_settings_tab()
        self.html_editor.set_field_val('Display Name', 'New Name')
        self.html_editor.save_settings()
        component_name = self.unit.xblock_titles[0]
        self.assertEqual(component_name, 'New Name',
                         "Component name is not as edited")

    def test_link_plugin_sets_url_correctly(self):
        """
        Scenario: TinyMCE link plugin sets urls correctly
        Given I have created a Blank HTML Page
            When I edit the page
            And I add a link with static link "/static/image.jpg" via the Link Plugin Icon
                Then the href link is rewritten to the asset link "image.jpg"
                And the link is shown as "/static/image.jpg" in the Link Plugin
        """
        static_link = '/static/image.jpg'

        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()
        self.html_editor.open_link_plugin()
        self.html_editor.save_static_link(static_link)
        self.html_editor.switch_to_iframe()
        href = self.iframe.href
        self.assertIn('image.jpg', href)
        self.iframe.select_link()
        self.iframe.switch_to_default()
        self.assertEqual(self.html_editor.url_from_the_link_plugin,
                         static_link, "URL in the link plugin is different")

    def test_tinymce_and_codemirror_preserve_style_tags(self):
        """
        Scenario: TinyMCE and CodeMirror preserve style tags
        Given I have created a Blank HTML Page
            When I edit the page
            And type "<p class='title'>pages</p><style><!-- .title { color: red; } --></style>" in the code editor and
            press OK
            And I save the page
                Then the page text contains:
                  ""
                  <p class="title">pages</p>
                  <style><!--
                  .title { color: red; }
                  --></style>
                  ""
        """
        content = u'<p class="title">pages</p><style><!-- .title { color: red; } --></style>'

        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()
        self._add_content(content)
        html = self.container_page.content_html
        self.assertIn(content, html)

    def test_tinymce_and_codemirror_preserve_span_tags(self):
        """
        Scenario: TinyMCE and CodeMirror preserve span tags
        Given I have created a Blank HTML Page
            When I edit the page
            And type "<span>Test</span>" in the code editor and press OK
            And I save the page
                Then the page text contains:
                ""
                    <span>Test</span>
                ""
        """
        content = "<span>Test</span>"

        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()
        self._add_content(content)
        html = self.container_page.content_html
        self.assertIn(content, html)

    def test_tinymce_and_codemirror_preserve_math_tags(self):
        """
        Scenario: TinyMCE and CodeMirror preserve math tags
        Given I have created a Blank HTML Page
            When I edit the page
            And type "<math><msup><mi>x</mi><mn>2</mn></msup></math>" in the code editor and press OK
            And I save the page
                Then the page text contains:
                ""
                    <math><msup><mi>x</mi><mn>2</mn></msup></math>
                ""
        """
        content = "<math><msup><mi>x</mi><mn>2</mn></msup></math>"

        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()
        self._add_content(content)
        html = self.container_page.content_html
        self.assertIn(content, html)

    def test_code_format_toolbar_wraps_text_with_code_tags(self):
        """
        Scenario: Code format toolbar button wraps text with code tags
        Given I have created a Blank HTML Page
            When I edit the page
            And I set the text to "display as code" and I select the text
            And I save the page
                Then the page text contains:
                ""
                    <p><code>display as code</code></p>
                ""
        """
        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()
        self.html_editor.set_text_and_select("display as code")
        self.html_editor.click_code_toolbar_button()
        self.html_editor.save_content()
        html = self.container_page.content_html
        self.assertIn(html, '<p><code>display as code</code></p>')

    def test_raw_html_component_does_not_change_text(self):
        """
        Scenario: Raw HTML component does not change text
        Given I have created a raw HTML component
            When I edit the page
            And type "<li>zzzz<ol> " into the Raw Editor
            And I save the page
                Then the page text contains:
                  ""
                  <li>zzzz<ol>
                  ""
            And I edit the page
                Then the Raw Editor contains exactly:
                  ""
                  <li>zzzz<ol>
                  ""
        """
        content = "<li>zzzz</li>"

        # Add Raw HTML type component
        self._add_component('Raw HTML')
        self.container_page.edit()

        # Set content in tinymce editor
        type_in_codemirror(self.html_editor, 0, content)
        self.html_editor.save_content()

        # The HTML of the content added through tinymce editor
        html = self.container_page.content_html
        # The text content should be present with its tag preserved
        self.assertIn(content, html)

        self.container_page.edit()
        editor_value = self.html_editor.editor_value
        # The tinymce editor value should not be different from the content added in the start
        self.assertEqual(content, editor_value)

    def test_tinymce_toolbar_buttons_are_as_expected(self):
        """
        Scenario: TinyMCE toolbar buttons are as expected
        Given I have created a Blank HTML Page
        When I edit the page
            Then the expected toolbar buttons are displayed
        """
        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()

        expected_buttons = [
            u'bold',
            u'italic',
            u'underline',
            u'forecolor',
            # This is our custom "code style" button, which uses an image instead of a class.
            u'none',
            u'alignleft',
            u'aligncenter',
            u'alignright',
            u'alignjustify',
            u'bullist',
            u'numlist',
            u'outdent',
            u'indent',
            u'blockquote',
            u'link',
            u'unlink',
            u'image'
        ]
        toolbar_dropdowns = self.html_editor.toolbar_dropdown_titles
        # The toolbar is divided in two sections: drop-downs and all other formatting buttons
        # The assertions under asserts for the drop-downs
        self.assertEqual(len(toolbar_dropdowns), 2)
        self.assertEqual(['Paragraph', 'Font Family'], toolbar_dropdowns)

        toolbar_buttons = self.html_editor.toolbar_button_titles
        # The assertions under asserts for all the remaining formatting buttons
        self.assertEqual(len(toolbar_buttons), len(expected_buttons))

        for index, button in enumerate(expected_buttons):
            class_name = toolbar_buttons[index]
            self.assertEqual("mce-ico mce-i-" + button, class_name)

    def test_static_links_converted(self):
        """
        Scenario: Static links are converted when switching between code editor and WYSIWYG views
        Given I have created a Blank HTML Page
        When I edit the page
            And type "<img src="/static/image.jpg">" in the code editor and press OK
        Then the src link is rewritten to the asset link /asset-v1:(course_id)+type@asset+block/image.jpg
            And the code editor displays "<p><img src="/static/image.jpg" /></p>"
        """
        value = '<img src="/static/image.jpg">'

        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()
        self.html_editor.set_raw_content(value)
        self.html_editor.save_content()
        html = self.container_page.content_html
        src = "/asset-v1:{}+type@asset+block/image.jpg".format(
            self.course_id.strip('course-v1:'))
        self.assertIn(src, html)
        self.container_page.edit()
        self.html_editor.open_raw_editor()
        editor_value = self.html_editor.editor_value
        self.assertEqual(value, editor_value)

    def test_font_selection_dropdown(self):
        """
        Scenario: Font selection dropdown contains Default font and tinyMCE builtin fonts
        Given I have created a Blank HTML Page
        When I edit the page
        And I click font selection dropdown
            Then I should see a list of available fonts
            And "Default" fonts should be available
            And all standard tinyMCE fonts should be available
        """
        # Add HTML Text type component
        self._add_component('Text')
        self.container_page.edit()
        EXPECTED_FONTS = {
            u"Default": [
                u'"Open Sans"', u'Verdana', u'Arial', u'Helvetica',
                u'sans-serif'
            ],
            u"Andale Mono": [u'andale mono', u'times'],
            u"Arial": [u'arial', u'helvetica', u'sans-serif'],
            u"Arial Black": [u'arial black', u'avant garde'],
            u"Book Antiqua": [u'book antiqua', u'palatino'],
            u"Comic Sans MS": [u'comic sans ms', u'sans-serif'],
            u"Courier New": [u'courier new', u'courier'],
            u"Georgia": [u'georgia', u'palatino'],
            u"Helvetica": [u'helvetica'],
            u"Impact": [u'impact', u'chicago'],
            u"Symbol": [u'symbol'],
            u"Tahoma": [u'tahoma', u'arial', u'helvetica', u'sans-serif'],
            u"Terminal": [u'terminal', u'monaco'],
            u"Times New Roman": [u'times new roman', u'times'],
            u"Trebuchet MS": [u'trebuchet ms', u'geneva'],
            u"Verdana": [u'verdana', u'geneva'],
            # tinyMCE does not set font-family on dropdown span for these two fonts
            u"Webdings": [u""],  # webdings
            u"Wingdings": [u""]  # wingdings
        }
        self.html_editor.open_font_dropdown()
        self.assertDictContainsSubset(EXPECTED_FONTS,
                                      self.html_editor.font_dict())

    def test_image_modal(self):
        """
        Scenario: TinyMCE text editor allows to add multiple images.

        Given I have created a Blank text editor Page.
        I add an image in TinyMCE text editor and hit save button.
        I edit the component again.
        I add another image in TinyMCE text editor and hit save button again.
            Then it is expected that both images show up on page.
        """
        image_file_names = [u'file-0.png', u'file-1.png']
        self._add_component('Text')

        for image in image_file_names:
            image_path = os.path.join(UPLOAD_FILE_DIR, image)
            self.container_page.edit()
            self.html_editor.open_image_modal()
            self.html_editor.upload_image(image_path)
            self.html_editor.save_content()
            self.html_editor.wait_for_ajax()

        self.container_page.edit()
        self.html_editor.open_raw_editor()
        editor_value = self.html_editor.editor_value
        number_of_images = editor_value.count(u'img')
        self.assertEqual(number_of_images, 2)
Exemple #31
0
 def go_to(self):
     """
     Open the container page linked to by this unit link, and return
     an initialized :class:`.ContainerPage` for that unit.
     """
     return ContainerPage(self.browser, self.locator).visit()
Exemple #32
0
class HTMLComponentEditor(ContainerBase):
    """
    Feature: CMS.Component Adding
    As a course author, I want to be able to add and edit HTML component
    """
    def setUp(self, is_staff=True):
        """
        Create a course with a section, subsection, and unit to which to add the component.
        """
        super(HTMLComponentEditor, self).setUp(is_staff=is_staff)
        self.component = 'Text'
        self.unit = self.go_to_unit_page()
        self.container_page = ContainerPage(self.browser, None)
        self.xblock_wrapper = XBlockWrapper(self.browser, None)
        # Add HTML component
        add_component(self.container_page, 'html', self.component)
        self.component = self.unit.xblocks[1]
        self.container_page.edit()
        self.html_editor = HtmlXBlockEditorView(self.browser, self.component.locator)
        self.iframe = HTMLEditorIframe(self.browser, self.component.locator)

    def populate_course_fixture(self, course_fixture):
        """
        Adds a course fixture
        """
        course_fixture.add_children(
            XBlockFixtureDesc('chapter', 'Test Section').add_children(
                XBlockFixtureDesc('sequential', 'Test Subsection').add_children(
                    XBlockFixtureDesc('vertical', 'Test Unit')
                )
            )
        )

    def test_user_can_view_metadata(self):
        """
        Scenario: User can view metadata
        Given I have created a Blank HTML Page
            And I edit and select Settings
                Then I see the HTML component settings
        """
        self.html_editor.open_settings_tab()
        display_name_value = self.html_editor.get_default_settings()[0]
        display_name_key = self.html_editor.keys[0]
        self.assertEqual(
            ['Display Name', 'Text'],
            [display_name_key, display_name_value],
            "Settings not found"
        )
        editor_value = self.html_editor.get_default_settings()[1]
        editor_key = self.html_editor.keys[1]
        self.assertEqual(
            ['Editor', 'Visual'],
            [editor_key, editor_value],
            "Settings not found"
        )

    def test_user_can_modify_display_name(self):
        """
        Scenario: User can modify display name
        Given I have created a Blank HTML Page
            And I edit and select Settings
        Then I can modify the display name
            And my display name change is persisted on save
        """
        self.html_editor.open_settings_tab()
        self.html_editor.set_field_val('Display Name', 'New Name')
        self.html_editor.save_settings()
        component_name = self.unit.xblock_titles[0]
        self.assertEqual(component_name, 'New Name', "Component name is not as edited")

    def test_link_plugin_sets_url_correctly(self):
        """
        Scenario: TinyMCE link plugin sets urls correctly
        Given I have created a Blank HTML Page
            When I edit the page
            And I add a link with static link "/static/image.jpg" via the Link Plugin Icon
                Then the href link is rewritten to the asset link "image.jpg"
                And the link is shown as "/static/image.jpg" in the Link Plugin
        """
        static_link = '/static/image.jpg'
        self.html_editor.open_link_plugin()
        self.html_editor.save_static_link(static_link)
        self.html_editor.switch_to_iframe()
        href = self.iframe.href
        self.assertIn('image.jpg', href)
        self.iframe.select_link()
        self.iframe.switch_to_default()
        self.assertEqual(
            self.html_editor.url_from_the_link_plugin,
            static_link,
            "URL in the link plugin is different"
        )
Exemple #33
0
class ProblemComponentEditor(ContainerBase):
    """
    Feature: CMS.Component Adding
    As a course author, I want to be able to add and edit Problem
    """
    def setUp(self, is_staff=True):
        """
        Create a course with a section, subsection, and unit to which to add the component.
        """
        super(ProblemComponentEditor, self).setUp(is_staff=is_staff)
        self.component = 'Blank Common Problem'
        self.unit = self.go_to_unit_page()
        self.container_page = ContainerPage(self.browser, None)
        # Add a Problem
        add_component(self.container_page, 'problem', self.component)
        self.component = self.unit.xblocks[1]
        self.container_page.edit()
        self.problem_editor = ProblemXBlockEditorView(self.browser,
                                                      self.component.locator)

    def populate_course_fixture(self, course_fixture):
        """
        Adds a course fixture
        """
        course_fixture.add_children(
            XBlockFixtureDesc('chapter', 'Test Section').add_children(
                XBlockFixtureDesc('sequential',
                                  'Test Subsection').add_children(
                                      XBlockFixtureDesc(
                                          'vertical', 'Test Unit'))))

    def test_user_can_modify_float_input(self):
        """
        Scenario: User can modify float input values
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then I can set the weight to "3.5"
            And my change to weight is persisted
            And I can revert to the default value of unset for weight
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Problem Weight', '3.5')
        self.problem_editor.save()

        # reopen settings
        self.container_page.edit()
        self.problem_editor.open_settings()

        field_value = self.problem_editor.get_field_val('Problem Weight')
        self.assertEqual(field_value, '3.5')
        self.problem_editor.revert_setting()
        field_value = self.problem_editor.get_field_val('Problem Weight')
        self.assertEqual(field_value, '',
                         'Component settings is not reverted to default')

    @skip_if_browser('firefox')
    # Lettuce tests run on chrome and chrome does not allow to enter
    # periods/dots in this field and consequently we have to save the
    # value as '234'. Whereas, bokchoy runs with the older version of
    # firefox on jenkins, which does not allow to save the value if it
    # has a period/dot. Clicking on save button after filling '2.34' in
    # field, does not do anything and test does not go any further.
    # So, it fails always.
    def test_user_cannot_type_decimal_values(self):
        """
        Scenario: User cannot type decimal values integer number field
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then if I set the max attempts to "2.34", it will persist as a valid integer
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Maximum Attempts', '2.34')
        self.problem_editor.save()

        # reopen settings
        self.container_page.edit()
        self.problem_editor.open_settings()

        field_value = self.problem_editor.get_field_val('Maximum Attempts')
        self.assertEqual(field_value, '234',
                         "Decimal values are not allowed in this field")

    def test_settings_are_not_saved_on_cancel(self):
        """
        Scenario: Settings changes are not saved on Cancel
        Given I have created a Blank Common Problem
        When I edit and select Settings
            Then I can set the weight to "3.5"
        And I can modify the display name
            Then If I press Cancel my changes are not persisted
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Problem Weight', '3.5')
        self.problem_editor.cancel()

        # reopen settings
        self.container_page.edit()
        self.problem_editor.open_settings()

        field_value = self.problem_editor.get_field_val('Problem Weight')
        self.assertEqual(
            field_value, '',
            "Component setting should not appear updated if cancelled during editing"
        )

    def test_cheat_sheet_visible_on_toggle(self):
        """
        Scenario: Cheat sheet visible on toggle
        Given I have created a Blank Common Problem
        And I can edit the problem
            Then I can see cheatsheet
        """
        self.problem_editor.toggle_cheatsheet()
        self.assertTrue(self.problem_editor.is_cheatsheet_present(),
                        "Cheatsheet not present")
Exemple #34
0
class ProblemComponentEditor(ContainerBase):
    """
    Feature: CMS.Component Adding
    As a course author, I want to be able to add and edit Problem
    """
    def setUp(self, is_staff=True):
        """
        Create a course with a section, subsection, and unit to which to add the component.
        """
        super(ProblemComponentEditor, self).setUp(is_staff=is_staff)
        self.component = 'Blank Common Problem'
        self.unit = self.go_to_unit_page()
        self.container_page = ContainerPage(self.browser, None)
        # Add a Problem
        add_component(self.container_page, 'problem', self.component)
        self.component = self.unit.xblocks[1]
        self.container_page.edit()
        self.problem_editor = ProblemXBlockEditorView(self.browser,
                                                      self.component.locator)

    def populate_course_fixture(self, course_fixture):
        """
        Adds a course fixture
        """
        course_fixture.add_children(
            XBlockFixtureDesc('chapter', 'Test Section').add_children(
                XBlockFixtureDesc('sequential',
                                  'Test Subsection').add_children(
                                      XBlockFixtureDesc(
                                          'vertical', 'Test Unit'))))

    def test_user_can_view_metadata(self):
        """
        Scenario: User can view metadata
        Given I have created a Blank Common Problem
        When I edit and select Settings
        Then I see the advanced settings and their expected values
        And Edit High Level Source is not visible
        """
        expected_default_settings = {
            'Display Name': u'Blank Common Problem',
            'Matlab API key': u'',
            'Maximum Attempts': u'',
            'Problem Weight': u'',
            'Randomization': u'Never',
            'Show Answer': u'Finished',
            'Show Reset Button': u'False',
            'Timer Between Attempts': u'0'
        }
        self.problem_editor.open_settings()
        settings = self.problem_editor.get_settings()
        self.assertEqual(expected_default_settings, settings)
        self.assertFalse(self.problem_editor.is_latex_compiler_present())

    def test_user_can_modify_string_values(self):
        """
        Given I have created a Blank Common Problem
        When I edit and select Settings
        Then I can modify the display name
        And my display name change is persisted on save
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Display Name', 'New Name')
        self.problem_editor.save()
        component_name = self.unit.xblock_titles[0]
        self.assertEqual(component_name, 'New Name')

    def test_user_can_specify_special_characters(self):
        """
        Scenario: User can specify special characters in String values
        Given I have created a Blank Common Problem
        When I edit and select Settings
        Then I can specify special characters in the display name
        And my special characters are persisted on save
        """
        self.problem_editor.open_settings()
        self.problem_editor.set_field_val('Display Name', '&&&')
        self.problem_editor.save()
        component_name = self.unit.xblock_titles[0]
        self.assertEqual(component_name, '&&&')