def test_ss_details(self):
        # Login
        self.login('*****@*****.**')

        # Open Workflows page
        self.access_workflow_from_home_page(self.workflow_name)

        # Go to workflow details
        self.go_to_details()

        # Table of columns (separated)
        self.element_ss("//div[@id='column-table_wrapper']",
                        'wokflow_columns.png')

        #
        # Ops/Edit Column
        #
        self.open_column_edit('SID')
        self.modal_ss('workflow_column_edit.png')

        # Click in the cancel button
        self.cancel_modal()

        # End of session
        self.logout()

        # Close the db_engine
        destroy_db_engine()
    def test_sql_admin(self):
        # Login
        self.login('*****@*****.**')
        self.body_ss('workflow_superuser_index.png')

        #
        # Open SQL Connection
        #
        self.go_to_sql_connections()
        self.body_ss('workflow_sql_connections_index.png')

        # click in the edit element
        self.selenium.find_element_by_xpath(
            "//table[@id='sqlconn-admin-table']"
            "//tr/td[1][normalize-space() = 'remote server']"
        ).click()
        self.wait_for_modal_open()

        # Take picture of the modal
        self.modal_ss('workflow_superuser_sql_edit.png')

        # Click in the cancel button
        self.cancel_modal()

        # End of session
        self.logout()

        # Close the db_engine
        destroy_db_engine()
    def test_ss_table(self):
        # Login
        self.login('*****@*****.**')

        # Open Workflows page
        self.access_workflow_from_home_page(self.workflow_name)

        #
        # Table
        #
        self.go_to_table()

        # Picture of the body
        self.body_ss('table.png')

        # Picture of the buttons
        self.element_ss("//div[@id='table-operation-buttons']",
                        'table_buttons.png')

        #
        # Table Views
        #
        self.go_to_table_views()

        # Picture of the body
        self.body_ss('table_views.png')

        #
        # Specific table view
        #
        self.open_view('Midterm')

        # Picture of the body
        self.body_ss('table_view_view.png')

        # Click edit view definition
        self.go_to_table_views()
        element = self.search_table_row_by_string('view-table', 1, 'Midterm')
        element.find_element_by_xpath("td[1]/a").click()
        self.wait_for_modal_open()

        # Take picture of the modal
        self.modal_ss('table_view_edit.png')

        # Click in the cancel button
        self.cancel_modal()

        # End of session
        self.logout()

        # Close the db_engine
        destroy_db_engine()
    def test_ss_01(self):
        """
        Create a workflow, upload data and merge
        :return:
        """

        # Login
        self.login('*****@*****.**')

        # Open Import page
        self.selenium.find_element_by_link_text('Import workflow').click()
        WebDriverWait(self.selenium, 10).until(
            EC.text_to_be_present_in_element((By.XPATH, "//body/div/h1"),
                                             'Import workflow')
        )

        #
        # Import workflow
        #
        self.selenium.find_element_by_id('id_name').send_keys(
            self.workflow_name
        )
        self.selenium.find_element_by_id('id_wf_file').send_keys(
            os.path.join(settings.BASE_DIR(),
                         '..',
                         'initial_workflow.gz')
        )

        # Picture of the body
        self.body_ss('workflow_import.png')

        # Click the import button
        self.selenium.find_element_by_xpath(
            "//form/div/button[@type='Submit']"
        ).click()
        self.wait_for_page(title='OnTask :: Workflows')

        # End of session
        self.logout()

        # Close the db_engine
        destroy_db_engine()
    def test_ss_logs(self):
        # Login
        self.login('*****@*****.**')

        # Open Workflows page
        self.access_workflow_from_home_page(self.workflow_name)

        #
        # Logs
        #
        self.go_to_logs()

        # Take picture of the body
        self.body_ss('logs.png')

        # End of session
        self.logout()

        # Close the db_engine
        destroy_db_engine()
    def test_ss_00(self):
        """
        Create a workflow, upload data and merge
        :return:
        """

        # Login
        self.login('*****@*****.**')
        self.body_ss('workflow_index_empty.png')

        #
        # Create new workflow
        #
        self.selenium.find_element_by_class_name(
            'js-create-workflow').click()
        self.wait_for_modal_open()

        self.selenium.find_element_by_id(
            'id_name').send_keys(self.workflow_name)
        desc = self.selenium.find_element_by_id('id_description_text')
        desc.send_keys(self.description)

        # Take capture of the modal
        self.modal_ss('workflow_create.png')

        # Close the modal.
        desc.send_keys(Keys.RETURN)
        self.wait_for_modal_close()
        WebDriverWait(self.selenium, 10).until(
            EC.visibility_of_element_located(
                (By.XPATH, "//table[@id='dataops-table']")
            )
        )

        self.body_ss('dataops_datauploadmerge2.png')
        # End of session
        self.logout()

        # Close the db_engine
        destroy_db_engine()
示例#7
0
    def test_import_complete(self):

        # Login and wait for the table of workflows
        self.login('*****@*****.**')

        # Click in the import button and wait
        self.selenium.find_element_by_link_text('Import workflow').click()
        WebDriverWait(self.selenium, 10).until(
            EC.text_to_be_present_in_element((By.XPATH, "//body/div/h1"),
                                             'Import workflow'))

        # Set the workflow name and file
        wname = self.selenium.find_element_by_id('id_name')
        wname.send_keys('newwf')
        wfile = self.selenium.find_element_by_id('id_wf_file')
        wfile.send_keys(
            os.path.join(settings.BASE_DIR(), 'workflow', 'fixtures',
                         'ontask_workflow.gz'))

        # Click in the submit
        self.selenium.find_element_by_xpath("//button[@type='Submit']").click()
        WebDriverWait(self.selenium, 10).until(
            EC.presence_of_element_located(
                (By.XPATH, "//h5[contains(@class, 'card-header') "
                 "and normalize-space(text()) = '{0}']".format('newwf')), ))

        # Check elements in workflow and in newwf
        w1 = Workflow.objects.get(name=test.wflow_name)
        w2 = Workflow.objects.get(name='newwf')

        # Equal descriptions
        self.assertEqual(w1.description_text, w2.description_text)

        # Equal number of columns
        self.assertEqual(w1.columns.count(), w2.columns.count())

        # Identical attributes
        self.assertEqual(w1.attributes, w2.attributes)

        # Equal number of rows and columns
        self.assertEqual(w1.nrows, w2.nrows)
        self.assertEqual(w1.ncols, w2.ncols)

        # Equal names and column types
        for x, y in zip(w1.columns.all(), w2.columns.all()):
            self.assertEqual(x.name, y.name)
            self.assertEqual(x.data_type, y.data_type)
            self.assertEqual(x.is_key, y.is_key)

        # Equal number of actions
        self.assertEqual(w1.actions.count(), w2.actions.count())

        # Equal names and content in the conditions
        for x, y in zip(w1.actions.all(), w2.actions.all()):
            self.assertEqual(x.name, y.name)
            self.assertEqual(x.description_text, y.description_text)
            self.assertEqual(x.text_content, y.text_content)
            self.assertEqual(x.conditions.count(), y.conditions.count())
            for c1, c2 in zip(x.conditions.all(), y.conditions.all()):
                self.assertEqual(c1.name, c2.name)
                self.assertEqual(c1.description_text, c2.description_text)
                self.assertEqual(c1.formula, c2.formula)
                self.assertEqual(c1.is_filter, c2.is_filter)

        # End of session
        self.logout()

        # Close the db_engine
        destroy_db_engine()
    def test_ss_scheduler(self):
        # Login
        self.login('*****@*****.**')

        # Open Workflows page
        self.access_workflow_from_home_page(self.workflow_name)

        #
        # Open Action Schedule and schedule the Personalized Text action
        #
        self.open_action_schedule('Midterm comments')

        # Fill out some fields
        self.selenium.find_element_by_id('id_name').send_keys(
            'Send Emails after week 3'
        )
        Select(self.selenium.find_element_by_id(
            'id_item_column')
        ).select_by_visible_text('email')
        dt_widget = self.selenium.find_element_by_xpath(
            "//input[@id='id_execute']"
        )
        self.selenium.execute_script(
            "arguments[0].value = '2110-07-05 17:30:51';",
            dt_widget
        )
        self.selenium.find_element_by_id('id_subject').send_keys(
            'Your preparation activities for the week'
        )
        self.selenium.find_element_by_id('id_track_read').click()

        # Take picture of the export page.
        self.body_ss('schedule_action_email.png')

        # Click the schedule button
        self.selenium.find_element_by_xpath(
            "//button[@id='next-step-off']"
        ).click()
        self.wait_for_page(title='OnTask :: Action scheduled')

        #
        # Actions
        #
        self.go_to_actions()

        #
        # Open Action Schedule and schedule the Personalized JSON
        #
        self.open_action_schedule('Send JSON to remote server')

        # Fill out some fields
        self.selenium.find_element_by_id('id_name').send_keys(
            'Send JSON object in Week 5'
        )
        dt_widget = self.selenium.find_element_by_xpath(
            "//input[@id='id_execute']"
        )
        self.selenium.execute_script(
            "arguments[0].value = '2110-07-25 17:00:00';",
            dt_widget
        )
        self.selenium.find_element_by_id('id_token').send_keys(
            'afabkvaidlfvsidkfe..kekfioroelallasifjjf;alksid'
        )

        # Take picture of the export page.
        self.body_ss('schedule_action_json.png')

        # Click the schedule button
        self.selenium.find_element_by_xpath(
            "//button[@id='next-step-off']"
        ).click()
        self.wait_for_page(title='OnTask :: Action scheduled')

        #
        # Scheduler
        #
        self.go_to_scheduler()

        # Take picture of the export page.
        self.body_ss('schedule.png')

        # End of session
        self.logout()

        # Close the db_engine
        destroy_db_engine()
    def test_ss_dataops(self):
        # Login
        self.login('*****@*****.**')

        # Open Workflows page
        self.access_workflow_from_home_page(self.workflow_name)

        # Go to CSV
        self.go_to_upload_merge()
        self.body_ss('dataops_datauploadmerge.png')

        self.selenium.find_element_by_link_text("CSV").click()
        WebDriverWait(self.selenium, 10).until(
            EC.title_is('OnTask :: Upload/Merge CSV')
        )
        self.selenium.find_element_by_id('id_data_file').send_keys(
            os.path.join(settings.BASE_DIR(),
                         '..',
                         'initial_workflow',
                         'initial_workflow.csv')
        )

        # Picture of the body
        self.body_ss('dataops_csvupload.png')

        #
        # Dataops/Merge CSV Merge Step 2
        #
        # Click the NEXT button
        self.selenium.find_element_by_xpath(
            "//button[@type='Submit']"
        ).click()
        self.wait_for_page()
        WebDriverWait(self.selenium, 10).until(
            EC.element_to_be_clickable(
                (By.XPATH, "//input[@id='id_make_key_2']")
            )
        )
        # Uncheck the columns that won't be keys
        for k_num in [2, 3, 40, 45, 46, 47, 49, 50, 51, 59, 61, 64]:
            self.selenium.find_element_by_id(
                'id_make_key_{0}'.format(k_num)
            ).click()
        self.selenium.execute_script("window.scroll(0,0);")

        # Picture of the body
        self.body_ss('dataops_upload_merge_step2.png')

        #
        # Dataops/Merge CSV Merge Step 3
        #
        # Click the NEXT button
        self.selenium.find_element_by_xpath(
            "//button[@type='Submit']"
        ).click()
        self.wait_for_page()
        WebDriverWait(self.selenium, 10).until(
            EC.element_to_be_clickable(
                (By.XPATH, "//select[@id='id_dst_key']")
            )
        )

        #
        # Dataops/Merge CSV Merge Step 4
        #
        # Click the NEXT button
        # Select left merge
        Select(self.selenium.find_element_by_id(
            'id_how_merge'
        )).select_by_value('left')

        # Picture of the body
        self.body_ss('dataops_upload_merge_step3.png')

        # Click the NEXT button
        self.selenium.find_element_by_xpath(
            "//button[@type='Submit']"
        ).click()
        WebDriverWait(self.selenium, 10).until(
            EC.text_to_be_present_in_element(
                (By.XPATH, "//body/div/h1"), 'Review and confirm')
        )

        # Picture of the body
        self.body_ss('dataops_upload_merge_step4.png')

        # Click on Finish
        self.selenium.find_element_by_xpath(
            "//button[normalize-space()='Finish']"
        ).click()
        self.wait_for_datatable('table-data_previous')

        #
        # Dataops/Merge Excel Merge
        #
        # Go to Excel Upload/Merge
        self.go_to_excel_upload_merge_step_1()
        self.body_ss('dataops_upload_excel.png')
        self.go_to_table()
        #
        # Google doc merge
        #
        # Go to Excel Upload/Merge
        self.go_to_google_sheet_upload_merge_step_1()
        self.body_ss('dataops_upload_gsheet.png')
        self.go_to_table()

        #
        # S3 CSV merge
        #
        self.go_to_s3_upload_merge_step_1()
        self.body_ss('dataops_upload_s3.png')
        self.go_to_table()

        #
        # Dataops/Merge SQL Connection
        #
        self.go_to_sql_upload_merge()
        self.body_ss('dataops_SQL_available.png')

        # Click on the link RUN
        self.selenium.find_element_by_link_text('Run').click()
        self.wait_for_page(None, 'sql-load-step1')

        # Picture of the RUN menu in SQL
        self.body_ss('dataops_SQL_run.png')

        # Go back to details
        self.go_to_details()

        #
        # Dataops: Transform
        #
        self.go_to_transform()
        self.body_ss('dataops_transform_list.png')

        # Click to run test_plugin_1
        element = self.search_table_row_by_string(
            'transform-table',
            1,
            'Test Plugin 1 Name')
        element.find_element_by_xpath('td[1]/a').click()
        WebDriverWait(self.selenium, 10).until(
            EC.presence_of_element_located((By.NAME, 'csrfmiddlewaretoken'))
        )

        # Picture of the body
        self.body_ss('dataops_transformation_run.png')

        #
        # Dataops: Model
        #
        self.go_to_model()
        self.body_ss('dataops_model_list.png')

        # Click to run linear model
        element = self.search_table_row_by_string(
            'transform-table',
            1,
            'Linear Model')
        element.find_element_by_xpath('td[1]/a').click()
        WebDriverWait(self.selenium, 10).until(
            EC.presence_of_element_located((By.NAME, 'csrfmiddlewaretoken'))
        )

        # Picture of the body
        self.body_ss('dataops_model_run.png')

        # End of session
        self.logout()

        # Close the db_engine
        destroy_db_engine()
    def test_ss_workflow(self):
        # Login
        self.login('*****@*****.**')

        # List of workflows, navigation
        self.body_ss('workflow_index.png')

        # Workdlow card
        self.element_ss('//div[contains(@class, "ontask-card")]',
                        'workflow_card.png')
        #
        # Navigation bar, details
        #
        self.access_workflow_from_home_page(self.workflow_name)

        # Take picture of the navigation bar
        self.element_ss("//body/div[@id='wflow-name']", 'navigation_bar.png')

        #
        # New column modal
        #
        self.go_to_details()
        self.body_ss('workflow_details.png')
        self.open_add_regular_column()
        self.modal_ss('workflow_add_column.png')

        # Click in the cancel button
        self.cancel_modal()

        #
        # Attributes
        #
        self.go_to_attribute_page()
        self.body_ss('workflow_attributes.png')

        #
        # Share
        #
        self.go_to_workflow_share()
        self.body_ss('workflow_share.png')

        #
        # EXPORT
        #
        self.go_to_workflow_export()
        self.body_ss('workflow_export.png')

        # Click back to the details page
        self.selenium.find_element_by_xpath(
            "//a[normalize-space()='Cancel']"
        ).click()
        self.wait_for_datatable('attribute-table_previous')

        #
        # RENAME
        #
        self.go_to_workflow_rename()
        self.modal_ss('workflow_rename.png')

        # Click in the cancel button
        self.cancel_modal()

        #
        # FLUSH DATA
        #
        self.go_to_workflow_flush()
        self.modal_ss('workflow_flush.png')

        # Click in the cancel button
        self.cancel_modal()

        #
        # DELETE
        #
        self.go_to_workflow_delete()
        self.modal_ss('workflow_delete.png')

        # Click in the cancel button
        self.cancel_modal()

        # End of session
        self.logout()

        # Close the db_engine
        destroy_db_engine()
示例#11
0
    def test(self):
        """
        Create a workflow, upload data and merge
        :return:
        """

        # Login
        self.login('*****@*****.**')

        # Open Import page
        self.selenium.find_element_by_link_text('Import workflow').click()
        WebDriverWait(self.selenium, 10).until(
            EC.text_to_be_present_in_element((By.XPATH, "//body/div/h1"),
                                             'Import workflow'))

        #
        # Import workflow
        #
        self.selenium.find_element_by_id('id_name').send_keys(
            self.workflow_name)
        self.selenium.find_element_by_id('id_wf_file').send_keys(
            os.path.join(settings.BASE_DIR(), '..', 'docs_src', 'Scenarios',
                         'scenario_01', 'scenario_01_wflow.gz'))

        # Click the import button
        self.selenium.find_element_by_xpath(
            "//form/div/button[@type='Submit']").click()
        self.wait_for_page(element_id='workflow-index')

        # Select the workflow
        self.access_workflow_from_home_page(self.workflow_name)

        # Open the right action
        self.open_action_edit('Email students in SMED')

        # Picture of the editor
        self.body_ss('scenario_01_action_SMED.png')

        # Edit the filter
        self.select_filter_tab()
        self.selenium.find_element_by_class_name('js-filter-edit').click()
        # Wait for the form to modify the filter
        WebDriverWait(self.selenium, 10).until(
            ElementHasFullOpacity((By.XPATH, "//div[@id='modal-item']")))

        # Take picture of the modal
        self.modal_ss('scenario_01_action_filter.png')

        # Click in the cancel button
        self.cancel_modal()

        # Go to actions and open email
        self.go_to_actions()
        self.open_action_email('Email students in SMED')

        # Picture of the body
        self.body_ss('scenario_01_action_SMED_email.png')

        # End of session
        self.logout()

        # Close the db_engine
        destroy_db_engine()
示例#12
0
    def test(self):
        """
        Create a workflow, upload data and merge
        :return:
        """

        question_values = 'DNA duplication, Mitosis, Kreb\'s cycle, None'

        # Login
        self.login('*****@*****.**')

        #
        # Create the workflow
        #
        self.create_new_workflow(self.workflow_name, self.description)

        # Go to CSV upload/merge
        self.selenium.find_element_by_xpath(
            '//tbody/tr[1]/td[1]/a[1]'
        ).click()
        WebDriverWait(self.selenium, 10).until(
            EC.visibility_of_element_located(
                (By.XPATH, '//form')
            )
        )

        # Set the file name
        self.selenium.find_element_by_id('id_data_file').send_keys(
            os.path.join(settings.BASE_DIR(),
                         '..',
                         'docs_src',
                         'Dataset',
                         'all_data.csv')
        )

        self.body_ss('tutorial_csv_upload_learner_information.png')

        # Click on the NEXT button
        self.selenium.find_element_by_xpath(
            '//button[@name="Submit"]'
        ).click()
        WebDriverWait(self.selenium, 10).until(
            EC.text_to_be_present_in_element((By.XPATH, '//body/div/h1'),
                                             'Select Columns')
        )

        # Uncheck two elements
        element = self.search_table_row_by_string('workflow-table',
                                                  2,
                                                  'Surname')
        element.find_element_by_xpath('td[5]/input').click()
        element = self.search_table_row_by_string('workflow-table',
                                                  2,
                                                  'GivenName')
        element.find_element_by_xpath('td[5]/input').click()

        self.body_ss('tutorial_csv_upload_confirm.png')

        # Click on the Next button
        self.selenium.find_element_by_xpath(
            '//button[@name="Submit"]'
        ).click()
        self.wait_for_datatable('table-data_paginate')

        # Take picture of the table
        self.body_ss('tutorial_initial_table.png')

        # Take picture of the top-bar menu
        self.element_ss('//nav[contains(@class, "fixed-top")]',
                        'tutorial_top_menu_bar.png')

        # Go back to details
        self.go_to_details()
        self.body_ss('tutorial_details_1.png')

        # Go back to details
        self.go_to_workflow_operations()
        self.body_ss('tutorial_workflow_operations.png')

        # Create a new view
        self.go_to_table()
        self.go_to_table_views()

        # Button to add a view
        self.selenium.find_element_by_xpath(
            '//button[normalize-space() = "View"]'
        ).click()
        # Wait for the form to create the derived column
        self.wait_for_modal_open()

        # Insert data to create the view
        element = self.selenium.find_element_by_id('id_name')
        element.click()
        element.clear()
        element.send_keys('Subset 1')
        element = self.selenium.find_element_by_id('id_description_text')
        element.click()
        element.clear()
        element.send_keys(
            'View only student email, program and enrolment type')

        # Focus on the column area
        self.selenium.find_element_by_xpath(
            '//*[@placeholder="Click here to search"]').click()
        options = self.selenium.find_element_by_xpath(
            '//*[@id="div_id_columns"]//div[@class="sol-selection"]'
        )
        for cname in ['email', 'Program', 'Enrolment Type']:
            options.find_element_by_xpath(
                'div/label/div[normalize-space()="{0}"]'.format(cname)
            ).click()

        self.selenium.find_element_by_css_selector('div.modal-header').click()

        self.modal_ss('tutorial_table_view_create.png')

        # Save the view
        self.selenium.find_element_by_xpath(
            '//button[normalize-space()="Add view"]'
        ).click()
        self.wait_close_modal_refresh_table('view-table_previous')

        # Open the view
        self.open_view('Subset 1')

        # Take picture of the table
        self.body_ss('tutorial_table_view.png')

        # select the statistics of one of the learners
        element = self.search_table_row_by_string('table-data',
                                                  2,
                                                  '*****@*****.**')
        stat_page = element.find_element_by_xpath(
            'td//a[contains(@href, "stat_row")]'
        ).get_attribute('href')
        self.selenium.get(stat_page)
        WebDriverWait(self.selenium, 10).until(
            EC.presence_of_element_located(
                (By.XPATH,
                 '//div[@class="text-center"]/a[normalize-space()="Back"]')
            )
        )

        # Picture of the statistics.
        self.body_ss('tutorial_row_statistics.png')

        # Go to the actions page
        self.go_to_actions()
        self.body_ss('tutorial_action_index.png')

        # Go to the import action page
        self.selenium.find_element_by_link_text('Import action').click()
        WebDriverWait(self.selenium, 10).until(
            EC.element_to_be_clickable(
                (By.XPATH, '//input[@id="id_name"]')
            )
        )
        self.body_ss('tutorial_action_import.png')
        self.go_to_actions()

        #
        # Merge data from Moodle
        #
        self.go_to_upload_merge()
        self.selenium.find_element_by_link_text('CSV').click()
        WebDriverWait(self.selenium, 10).until(
            EC.title_is('OnTask :: Upload/Merge CSV')
        )
        self.selenium.find_element_by_id('id_data_file').send_keys(
            os.path.join(settings.BASE_DIR(),
                         '..',
                         'docs_src',
                         'Dataset',
                         'moodle_grades.csv')
        )

        # Picture of the body
        self.body_ss('tutorial_moodle_merge_step1.png')

        # Click the NEXT button
        self.selenium.find_element_by_xpath(
            '//button[@type="Submit"]'
        ).click()
        self.wait_for_page()
        WebDriverWait(self.selenium, 10).until(
            EC.element_to_be_clickable(
                (By.XPATH, '//input[@id="id_make_key_2"]')
            )
        )

        # Uncheck all the columns
        self.selenium.find_element_by_id('checkAll').click()

        # Check the columns to select and maintain email as unique
        for k_num in [0, 1, 2]:
            self.selenium.find_element_by_id(
                'id_upload_{0}'.format(k_num)
            ).click()
        self.selenium.find_element_by_id('id_new_name_2').clear()
        self.selenium.find_element_by_id('id_new_name_2').send_keys('email')
        # self.selenium.find_element_by_id('id_make_key_2').click()

        # Picture of the body
        self.body_ss('tutorial_moodle_merge_step2.png')

        # Click the NEXT button
        self.selenium.find_element_by_xpath('//button[@type="Submit"]').click()
        self.wait_for_page()
        WebDriverWait(self.selenium, 10).until(
            EC.element_to_be_clickable(
                (By.XPATH, '//select[@id="id_dst_key"]')
            )
        )

        # Dataops/Merge CSV Merge Step 3
        Select(self.selenium.find_element_by_id(
            'id_dst_key'
        )).select_by_value('email')
        Select(self.selenium.find_element_by_id(
            'id_src_key'
        )).select_by_value('email')
        Select(self.selenium.find_element_by_id(
            'id_how_merge'
        )).select_by_value('right')

        # Picture of the body
        self.body_ss('tutorial_moodle_merge_step3.png')

        # Click the NEXT button
        self.selenium.find_element_by_xpath(
            '//button[@type="Submit"]'
        ).click()
        WebDriverWait(self.selenium, 10).until(
            EC.text_to_be_present_in_element(
                (By.XPATH, '//body/div/h1'), 'Review and confirm')
        )

        # Picture of the body
        self.body_ss('tutorial_moodle_merge_step4.png')

        # Click on Finish
        self.selenium.find_element_by_xpath(
            '//button[normalize-space()="Finish"]'
        ).click()
        self.wait_for_datatable('table-data_previous')

        #
        # Create PERSONALISED ACTION.
        #
        self.go_to_actions()
        self.selenium.find_element_by_class_name('js-create-action').click()
        self.wait_for_modal_open()

        # Set the name, description and type of the action
        self.selenium.find_element_by_id('id_name').send_keys('Program advice')
        desc = self.selenium.find_element_by_id('id_description_text')
        # Select the action type
        select = Select(self.selenium.find_element_by_id('id_action_type'))
        select.select_by_value(Action.personalized_text)
        desc.send_keys('')

        self.modal_ss('tutorial_personalized_text_create.png')

        desc.send_keys(Keys.RETURN)
        # Wait for the spinner to disappear, and then for the button to be
        # clickable
        WebDriverWait(self.selenium, 10).until(
            EC.visibility_of_element_located(
                (By.ID, 'action-out-editor')
            )
        )
        WebDriverWait(self.selenium, 10).until_not(
            EC.visibility_of_element_located((By.ID, 'div-spinner'))
        )

        # Action editor
        self.body_ss('tutorial_personalized_text_editor.png')

        self.selenium.find_element_by_class_name('note-editable').click()
        self.selenium.find_element_by_class_name('note-editable').send_keys(
            self.script1
        )

        # Take picture of the html editor
        self.element_ss('//div[@id="html-editor"]',
                        'tutorial_personalized_text_editor_with_column.png')

        # Create the first condition
        self.select_condition_tab()
        self.create_condition(
            'Program is FASS',
            '',
            [('Program', 'equal', 'FASS')]
        )
        self.open_condition('Program is FASS')

        self.modal_ss('tutorial_condition_program_FASS.png')

        self.cancel_modal()

        self.select_text_tab()
        self.selenium.find_element_by_class_name('note-editable').click()
        self.selenium.find_element_by_class_name('note-editable').send_keys(
            self.script2
        )

        # Take picture of the html editor
        self.element_ss('//div[@id="html-editor"]',
                        'tutorial_personalized_text_condition_inserted.png')

        # Create the remaining conditions
        self.select_condition_tab()
        self.create_condition('Program is FSCI',
                              '',
                              [('Program', 'equal', 'FSCI')]
                              )
        self.create_condition('Program is FEIT',
                              '',
                              [('Program', 'equal', 'FEIT')]
                              )
        self.create_condition('Program is SMED',
                              '',
                              [('Program', 'equal', 'SMED')]
                              )

        # Insert additional sentences for each program
        self.select_text_tab()
        self.selenium.find_element_by_class_name('note-editable').click()
        self.selenium.find_element_by_class_name('note-editable').send_keys(
            self.script3
        )

        # Take picture of the html editor
        self.element_ss('//div[@id="html-editor"]',
                        'tutorial_personalized_text_condition_inserted2.png')

        # Open the filter condition
        self.select_filter_tab()
        self.create_filter('Full time attendance',
                           [('Attendance', 'equal', 'Full Time')])
        # Open it again for the picture
        self.open_filter()
        self.modal_ss('tutorial_personalized_text_filter.png')

        # Close the modal
        self.cancel_modal()

        # Action editor
        self.body_ss('tutorial_personalized_text_editor2.png')

        # Open the preview
        self.selenium.find_element_by_xpath(
            '//button[normalize-space()="Preview"]'
        ).click()
        WebDriverWait(self.selenium, 10).until(
            ElementHasFullOpacity((By.XPATH, '//div[@id="modal-item"]'))
        )
        self.modal_ss('tutorial_personalized_text_preview.png')

        self.cancel_modal()

        # Save action and back to action index
        self.selenium.find_element_by_xpath(
            '//button[normalize-space()="Close"]'
        ).click()
        self.wait_for_datatable('action-table_previous')

        # Click in the email button
        self.open_action_run('Program advice')

        # Set the various fields in the form to send the email
        self.selenium.find_element_by_id('id_subject').send_keys(
            'Connecting your program with this course'
        )
        select = Select(self.selenium.find_element_by_id(
            'id_email_column'))
        select.select_by_value('email')
        self.selenium.find_element_by_id('id_cc_email').send_keys(
            '[email protected], [email protected]'
        )
        self.selenium.find_element_by_id('id_bcc_email').send_keys(
            '*****@*****.**'
        )
        self.selenium.find_element_by_id('id_confirm_items').click()

        # Screen shot of the body
        self.body_ss('action_personalized_text_email.png')

        # Click in the preview
        self.selenium.find_element_by_xpath(
            '//button[normalize-space()="Preview"]'
        ).click()
        self.wait_for_modal_open('//div[@id="preview-body"]')

        self.modal_ss('tutorial_email_preview.png')

        self.cancel_modal()

        # Click in the next button to go to the filter email screen
        self.selenium.find_element_by_xpath(
            '//button[@name="Submit"]'
        ).click()
        WebDriverWait(self.selenium, 10).until(
            EC.text_to_be_present_in_element(
                (By.XPATH, '//body/div/h1'),
                'Select items to exclude from action')
        )

        # Select two emails to exclude from the send.
        self.selenium.find_element_by_css_selector(
            'div.sol-input-container > input[type="text"]'
        ).click()
        self.selenium.find_element_by_name('exclude_values').click()
        self.selenium.find_element_by_xpath(
            '(//input[@name="exclude_values"])[2]'
        ).click()
        self.selenium.find_element_by_xpath(
            '(//input[@name="exclude_values"])[3]'
        ).click()

        self.body_ss('tutorial_exclude_action_items.png')

        # Cancel email and go back to action index
        self.selenium.find_element_by_link_text('Cancel').click()
        self.wait_for_datatable('action-table_previous')

        # Click in the URL link
        self.open_action_url('Program advice', 'URL Off')

        # Capture the modal with the URL
        self.modal_ss('tutorial_personalzed_text_URL.png')

        # Cancel the modal
        self.cancel_modal()

        #
        # Download ZIP (for Moodle)
        #
        self.open_action_zip('Program advice')

        # Select the key column
        select = Select(self.selenium.find_element_by_id(
            'id_participant_column')
        )
        select.select_by_value('Identifier')
        select = Select(self.selenium.find_element_by_id(
            'id_user_fname_column')
        )
        select.select_by_value('Full name')
        self.selenium.find_element_by_id('id_file_suffix').send_keys(
            'feedback.html'
        )
        self.selenium.find_element_by_id('id_zip_for_moodle').click()

        self.body_ss('tutorial_action_zip.png')

        # Click in the Cancel button
        self.selenium.find_element_by_link_text('Cancel').click()

        #
        # Create new personalized JSON Action
        #
        self.selenium.find_element_by_class_name('js-create-action').click()
        self.wait_for_modal_open()

        # Select the options to create a personalized JSON and then close the
        # screen
        self.selenium.find_element_by_id('id_name').send_keys(
            'Send JSON to remote server'
        )
        desc = self.selenium.find_element_by_id(
            'id_description_text'
        )
        desc.send_keys(
            'Send a JSON object to a remote server (outside this platform)'
        )
        # Select the action type
        select = Select(self.selenium.find_element_by_id('id_action_type'))
        select.select_by_value(Action.personalized_json)
        desc.send_keys('')

        self.modal_ss('tutorial_personalized_json_create.png')

        desc.send_keys(Keys.RETURN)
        # Wait for the spinner to disappear, and then for the button to be
        # clickable
        # Wait for the spinner to disappear, and then for the button to be
        # clickable
        WebDriverWait(self.selenium, 10).until(
            EC.visibility_of_element_located(
                (By.ID, 'action-out-editor')
            )
        )
        WebDriverWait(self.selenium, 10).until_not(
            EC.visibility_of_element_located((By.ID, 'div-spinner'))
        )

        self.create_condition('Less than 50 in the midterm',
                              '',
                              [('Total', 'less', '50')])
        self.create_condition('More or equal to 50 in midterm',
                              '',
                              [('Total', 'greater or equal', '50')])

        self.select_json_text_tab()
        self.selenium.find_element_by_id('id_text_content').send_keys(
            """{
  "sid": {{ SID }},
  "midterm_total": {{ Total }},
  "msg":
     {% if Less than 50 in the midterm %}"Message number 1"{% endif %}
    {% if More or equal to 50 in midterm %}"Message number 2"{% endif %}
}"""
        )

        self.selenium.find_element_by_id('id_target_url').send_keys(
            'http://127.0.0.1'
        )

        # Action editor
        self.body_ss('tutorial_personalized_json_editor.png')

        # Open the preview
        self.open_preview()
        self.modal_ss('tutorial_personalized_json_preview.png')

        self.cancel_modal()

        # Save action and back to action index
        self.selenium.find_element_by_xpath(
            '//button[normalize-space()="Close"]'
        ).click()
        self.wait_for_datatable('action-table_previous')

        #
        # Click on the create action SURVEY
        #
        self.selenium.find_element_by_class_name('js-create-action').click()
        WebDriverWait(self.selenium, 10).until(
            EC.presence_of_element_located((By.ID, 'id_name')))

        # Set the name, description and type of the action
        self.selenium.find_element_by_id('id_name').send_keys('Survey 1')
        desc = self.selenium.find_element_by_id('id_description_text')
        # Select the action type
        select = Select(self.selenium.find_element_by_id('id_action_type'))
        select.select_by_value(Action.survey)
        desc.send_keys('Survey description for the learners')

        self.modal_ss('tutorial_survey_create.png')

        desc.send_keys(Keys.RETURN)
        # Wait for the spinner to disappear, and then for the button to be
        # clickable
        WebDriverWait(self.selenium, 10).until(
            EC.visibility_of_element_located(
                (By.XPATH, '//*[@id="action-in-editor"]')
            )
        )
        WebDriverWait(self.selenium, 10).until_not(
            EC.visibility_of_element_located((By.ID, 'div-spinner'))
        )

        # Show the editor
        self.body_ss('tutorial_survey_editor.png')

        # Click on the Add Column button
        self.select_questions_tab()
        self.selenium.find_element_by_xpath(
            '//button[normalize-space()="Create question"]'
        ).click()
        self.wait_for_modal_open()

        # Set the fields
        self.selenium.find_element_by_id('id_name').send_keys('Survey Q1')
        self.selenium.find_element_by_id(
            'id_description_text'
        ).send_keys(
            'What was the most challenging topic for you this week?'
        )
        select = Select(self.selenium.find_element_by_id(
            'id_data_type'))
        select.select_by_value('string')
        self.selenium.find_element_by_id(
            'id_raw_categories'
        ).send_keys(question_values)

        self.modal_ss('tutorial_survey_column_creation.png')

        # Click on the Submit button
        self.selenium.find_element_by_xpath(
            '//div[@id="modal-item"]//button[normalize-space()="Add question"]'
        ).click()

        self.wait_close_modal_refresh_table('column-selected-table_previous')

        # Create the second column
        self.selenium.find_element_by_xpath(
            '//button[normalize-space()="Create question"]'
        ).click()
        self.wait_for_modal_open()

        # Set the fields
        self.selenium.find_element_by_id('id_name').send_keys('Survey Q2')
        self.selenium.find_element_by_id(
            'id_description_text'
        ).send_keys(
            'What was your dedication to the course this week?'
        )
        select = Select(self.selenium.find_element_by_id(
            'id_data_type'))
        select.select_by_value('string')
        self.selenium.find_element_by_id(
            'id_raw_categories'
        ).send_keys(
            'less than 2 hours',
            'between 2 and 4 hours',
            'between 4 and 6 hours',
            'more than 6 hours'
        )

        # Click on the Submit button
        self.selenium.find_element_by_xpath(
            '//div[@id="modal-item"]//button[normalize-space()="Add question"]'
        ).click()

        self.wait_close_modal_refresh_table('column-selected-table_previous')

        # Click in the key-select
        self.select_parameters_tab()

        # Select email column as key column
        self.click_dropdown_option('//div[@id="select-key-column-name"]',
                                   'email')
        # Table disappears (page is updating) -- Wait for spinner, and then
        # refresh
        WebDriverWait(self.selenium, 10).until_not(
            EC.visibility_of_element_located((By.ID, 'div-spinner'))
        )

        # Show the editor
        WebDriverWait(self.selenium, 10).until(
            EC.visibility_of_element_located((By.ID, 'insert-questions'))
        )
        self.select_parameters_tab()
        self.select_questions_tab()
        sleep(1)
        self.body_ss('tutorial_survey_editor2.png')

        # Click the preview button
        self.open_preview()
        self.modal_ss('tutorial_survey_preview.png')

        self.cancel_modal()

        # Save action and back to action index
        self.selenium.find_element_by_link_text('Done').click()
        self.wait_for_datatable('action-table_previous')

        #
        # Create an new action combining existing data with survey ata
        #
        self.create_new_personalized_text_action('More Strategies', '')

        # Create the conditions for those that failed the exam
        self.select_condition_tab()
        topics = [x.strip() for x in question_values.split(',')]
        for topic in topics:
            self.create_condition(
                topic[0:4] + ' - Fail',
                '',
                [('Survey Q1', 'equal', topic),
                 ('Total', 'less', 50)]
            )
        # Create the conditions for those that passed the exam
        for topic in topics:
            self.create_condition(
                topic[0:4] + ' - Passed',
                '',
                [('Survey Q1', 'equal', topic),
                 ('Total', 'greater or equal', 50)]
            )

        # Action editor
        self.select_text_tab()
        self.selenium.find_element_by_class_name('note-editable').click()
        self.selenium.find_element_by_class_name('note-editable').send_keys(
            'Dear {{ GivenName }}\n' +
            'Here are some suggestions.\n'
        )

        # Add the text for those that failed
        for topic in topics:
            self.selenium.find_element_by_class_name('note-editable').send_keys(
                ('{{% if {0} - Fail %}} Tips about {0} ' +
                 'for those that failed.{{% endif %}}\n').format(topic)
            )

        # Add the text for those that passed
        for topic in topics:
            self.selenium.find_element_by_class_name('note-editable').send_keys(
                ('{{% if {0} - Passed %}}Tips about {0} ' +
                 'for those that passed.{{% endif %}}\n').format(topic)
            )

        self.selenium.find_element_by_class_name('note-editable').send_keys(
            'Kind regards -- Jane Doe'
        )

        # Create the filter
        self.select_filter_tab()
        self.create_filter('Complete data',
                           [('Survey Q1', 'is not null', None),
                            ('Total', 'is not null', None)])

        # Open to take the picture
        self.open_filter()
        self.modal_ss('tutorial_personalized_text_and_survey_filter.png')
        self.cancel_modal()

        # Action editor
        self.select_text_tab()
        self.body_ss('tutorial_personalized_text_and_survey.png')

        # Save action and back to action index
        self.selenium.find_element_by_xpath(
            '//button[normalize-space()="Close"]'
        ).click()
        self.wait_for_datatable('action-table_previous')

        # End of session
        self.logout()

        # Close the db_engine
        destroy_db_engine()
    def test(self):
        """
        Create a workflow, upload data and merge
        :return:
        """

        # Login
        self.login('*****@*****.**')

        # Open Import page
        self.selenium.find_element_by_link_text('Import workflow').click()
        WebDriverWait(self.selenium, 10).until(
            EC.text_to_be_present_in_element((By.XPATH, "//body/div/h1"),
                                             'Import workflow'))

        #
        # Import workflow
        #
        self.selenium.find_element_by_id('id_name').send_keys(
            self.workflow_name)
        self.selenium.find_element_by_id('id_wf_file').send_keys(
            os.path.join(settings.BASE_DIR(), '..', 'docs_src', 'Scenarios',
                         'scenario_03', 'scenario_03_wflow.gz'))

        # Click the import button
        self.selenium.find_element_by_xpath(
            "//form/div/button[@type='Submit']").click()
        self.wait_for_page(element_id='workflow-index')

        # Select the workflow
        self.access_workflow_from_home_page(self.workflow_name)

        # Open the right action
        self.open_action_edit('Send email with suggestions')

        # Picture of the editor
        self.body_ss('scenario_03_text.png')

        # Open the modal with the filter
        self.select_filter_tab()
        self.open_filter()

        # Take picture of the filter
        self.modal_ss('scenario_03_filter.png')

        # Click in the cancel button
        self.cancel_modal()

        # Edit condition 1
        self.select_condition_tab()
        self.open_condition('Bottom third')

        # Take picture of the modal
        self.modal_ss('scenario_03_condition_one.png')

        # Click in the cancel button
        self.cancel_modal()

        # Edit condition 2
        self.open_condition('Middle underperforming')

        # Take picture of the modal
        self.modal_ss('scenario_03_condition_two.png')

        # Click in the cancel button
        self.cancel_modal()

        # Go back to actions
        self.go_to_actions()

        # Open the email action
        self.open_action_email('Send email with suggestions')

        # Capture the email
        self.body_ss('scenario_03_email.png')

        # End of session
        self.logout()

        # Close the db_engine
        destroy_db_engine()