Beispiel #1
0
    def test_import_tracker(self):
        """Tests that imports are tracked correctly."""

        self._login()
        url = self.url(f"/controls/components")
        self.browser.get(url)

        # Test initial import of Component(s) and Statement(s)
        self.click_element('a#import_records_link')

        current_path = urlparse(self.browser.current_url).path
        self.assertEqual('/controls/import_records', current_path)

        import_record_links = self.browser.find_elements_by_class_name('import_record_detail_link')
        self.assertEqual(len(import_record_links), 0)

        # Create an Import Record with a component and statement
        helper = ControlTestHelper()
        helper.create_simple_import_record()

        self.browser.refresh()
        var_sleep(1)

        import_record_links = self.browser.find_elements_by_class_name('import_record_detail_link')
        self.assertEqual(len(import_record_links), 1)
Beispiel #2
0
    def test_component_download_oscal_json(self):
        self._login()
        url = self.url(
            f"/systems/{self.system.id}/component/{self.component.id}")
        self.browser.get(url)
        self.click_element('a[href="#oscal"]')

        # sigh; selenium doesn't really let us find out the name of the
        # downloaded file, so let's make sure it doesn't exist before we
        # download
        # definite race condition possibility

        if self.json_download.is_file():
            self.json_download.unlink()
        elif os.path.isfile(self.json_download.name):
            os.remove(self.json_download.name)
        self.click_element("a#oscal_download_json_link")
        var_sleep(2)  # need to wait for download, alas
        # assert download exists!
        try:
            self.assertTrue(self.json_download.is_file())
            filetoopen = self.json_download
        except:
            self.assertTrue(os.path.isfile(self.json_download.name))
            # assert that it is valid JSON by trying to load it
            filetoopen = self.json_download.name
        with open(filetoopen, 'r') as f:
            json_data = json.load(f)
            self.assertIsNotNone(json_data)

        if self.json_download.is_file():
            self.json_download.unlink()
        elif os.path.isfile(self.json_download.name):
            os.remove(self.json_download.name)
Beispiel #3
0
    def create_fill_statement_form(self, name, statement, part, status,
                                   statusvalue, remarks, num):
        """
        In the component statements tab create and then fill a new component statement with the given information.
        """

        self.click_components_tab()

        # Click to add new component statement
        self.click_element("#new_component_statement")

        # Open the new component form open
        try:
            new_comp_btn = self.browser.find_element_by_link_text(
                "New Component Statement")

        except:
            new_comp_btn = self.browser.find_element_by_id(
                f"producer_element-{num}-title")
        new_comp_btn.click()
        var_sleep(2)
        # Fill out form
        self.browser.find_element_by_id("producer_element_name").send_keys(
            name)
        self.browser.find_elements_by_name("body")[-1].send_keys(statement)
        self.browser.find_elements_by_name("pid")[-1].send_keys(part)
        select = self.dropdown_option(status)
        select.select_by_value(statusvalue)
        self.browser.find_elements_by_name("remarks")[-1].send_keys(remarks)
        # Save form
        self.browser.find_elements_by_name("save")[-1].click()
        self.browser.refresh()
Beispiel #4
0
    def test_deployments_page_exists(self):

        # login as the first user and create a new project
        self._login()
        self._new_project()

        # systemid = System.objects.all().first()
        project = Project.objects.all().last()
        system = project.system

        self.navigateToPage(f"/systems/{system.id}/deployments")
        wait_for_sleep_after(lambda: self.assertInNodeText(
            "New Deployment", ".systems-element-button"))

        # # Add deault deployments to system
        deployment = Deployment(name="Training",
                                description="Training environment",
                                system=system)
        deployment.save()

        # Does new deployment appear on deployments list?
        self.navigateToPage(f"/systems/{system.id}/deployments")
        var_sleep(3)  # wait for page to open
        wait_for_sleep_after(lambda: self.assertInNodeText(
            "New Deployment", ".systems-element-button"))
        def do_invitation(username):
            start_invitation(username)
            var_sleep(.5)  # wait for invitation to be sent

            # Log out and accept the invitation as an anonymous user.
            self.browser.get(self.url("/accounts/logout/"))
            self._accept_invitation(username)
    def test_grant_portfolio_access(self):
        # Grant another member access to portfolio
        self._login()
        self.browser.get(self.url("/portfolios"))
        self.click_element("#portfolio_{}".format(self.user.username))
        self.click_element("#grant-portfolio-access")
        var_sleep(.5)
        wait_for_sleep_after(lambda: self.select_option_by_visible_text(
            '#invite-user-select', 'me2'))
        wait_for_sleep_after(
            lambda: self.click_element("#invitation_modal button.btn-submit"))
        wait_for_sleep_after(
            lambda: self.assertInNodeText("me2", "#portfolio-member-me2"))

        # Grant another member ownership of portfolio
        wait_for_sleep_after(
            lambda: self.click_element("#me2_grant_owner_permission"))
        var_sleep(0.5)
        wait_for_sleep_after(lambda: self.assertInNodeText(
            "me2 (Owner)", "#portfolio-member-me2"))

        # Grant another member access to portfolio
        self.click_element("#grant-portfolio-access")
        self.select_option_by_visible_text('#invite-user-select', 'me3')
        self.click_element("#invitation_modal button.btn-submit")
        wait_for_sleep_after(
            lambda: self.assertInNodeText("me3", "#portfolio-member-me3"))

        # Remove another member access to portfolio
        self.click_element("#me3_remove_permissions")
        self.assertNotInNodeText("me3", "#portfolio-members")
        self.assertNodeNotVisible("#portfolio-member-me3")
Beispiel #7
0
 def _new_project(self):
     self.browser.get(self.url("/projects"))
     self.click_element("#new-project")
     self.click_element(".app[data-app='fixture/simple_project'] .view-app")
     self.click_element("#start-project")
     var_sleep(1)
     self.assertRegex(self.browser.title,
                      "I want to answer some questions on Q.")
Beispiel #8
0
 def _upload_discussion_image(self, img_css_selector):
     """
     Upload an image in a discussion section
     """
     var_sleep(.5)
     self.click_element("#discussion .comment-input button.btn-primary")
     var_sleep(1.5)# Give time for the image to upload.
     img = wait_for_sleep_after(lambda: self.browser.find_element_by_css_selector(img_css_selector) )
     return img
Beispiel #9
0
    def test_component_import_oscal_json(self):
        self._login()
        url = self.url(f"/controls/components")
        self.browser.get(url)

        # Test initial import of Component(s) and Statement(s)
        self.click_element('a#component-import-oscal')
        app_root = os.path.dirname(os.path.realpath(__file__))
        oscal_json_path = os.path.join(app_root, "data/test_data",
                                       "test_oscal_component.json")
        file_input = self.find_selected_option('input#id_file')
        oscal_json_path = self.filepath_conversion(file_input, oscal_json_path,
                                                   "sendkeys")

        self.click_element('input#import_component_submit')

        element_count = Element.objects.filter(
            name='Test OSCAL Component').count()
        self.assertEqual(element_count, 1)

        statement1_count = Statement.objects.filter(
            uuid='1ab0b252-90d3-4d2c-9785-0c4efb254dfc').count()
        self.assertEqual(statement1_count, 1)

        statement2_count = Statement.objects.filter(
            uuid='2ab0b252-90d3-4d2c-9785-0c4efb254dfc').count()
        self.assertEqual(statement2_count, 1)

        # Verify that statements without a proper Catalog don't get entered
        statement3_count = Statement.objects.filter(
            uuid='4ab0b252-90d3-4d2c-9785-0c4efb254dfc').count()
        self.assertEqual(statement3_count, 0)

        # Verify that statements without a proper Control don't get entered
        statement4_count = Statement.objects.filter(
            uuid='6ab0b252-90d3-4d2c-9785-0c4efb254dfc').count()
        self.assertEqual(statement4_count, 0)

        var_sleep(1)  # Needed to allow page to refresh and messages to render

        # Test that duplicate Components and Statements are not re-imported
        self.click_element('a#component-import-oscal')
        file_input = self.find_selected_option('input#id_file')
        # Using converted keys from above
        file_input.send_keys(oscal_json_path)

        self.click_element('input#import_component_submit')

        element_count = Element.objects.filter(
            name='Test OSCAL Component').count()
        self.assertEqual(element_count, 1)

        statement1_count = Statement.objects.filter(
            uuid='1ab0b252-90d3-4d2c-9785-0c4efb254dfc').count()
        self.assertEqual(statement1_count, 1)
Beispiel #10
0
    def test_component_import_oscal_json(self):
        self._login()
        url = self.url(f"/controls/components")# component library
        self.browser.get(url)

        element_count_before_import = Element.objects.filter(element_type="system_element").count()
        statement_count_before_import = Statement.objects.filter(statement_type=StatementTypeEnum.CONTROL_IMPLEMENTATION_PROTOTYPE.value).count()

        # Test initial import of Component(s) and Statement(s)
        self.click_element('a#component-import-oscal')
        app_root = os.path.dirname(os.path.realpath(__file__))
        oscal_json_path = os.path.join(app_root, "data/test_data", "test_oscal_component.json")
        file_input = self.find_selected_option('input#id_file')
        oscal_json_path = self.filepath_conversion(file_input, oscal_json_path, "sendkeys")

        self.click_element('input#import_component_submit')
        var_sleep(2)
        element_count_after_import = wait_for_sleep_after(lambda: Element.objects.filter(element_type="system_element").count())

        wait_for_sleep_after(lambda: self.assertEqual(element_count_before_import + 2, element_count_after_import))

        statement_count_after_import = Statement.objects.filter(statement_type=StatementTypeEnum.CONTROL_IMPLEMENTATION_PROTOTYPE.value).count()
        self.assertEqual(statement_count_before_import + 4, statement_count_after_import)
        # Test file contains 6 Statements, but only 4 get imported
        # because one has an improper Catalog
        # and another has an improper Control
        # but we can't test individual statements because the UUIDs are randomly generated and not consistent
        # with the OSCAL JSON file. So we simply do a count.

        # Test that duplicate Components are re-imported with a different name and that Statements get reimported

        wait_for_sleep_after(lambda: self.click_element('a#component-import-oscal'))

        file_input = self.find_selected_option('input#id_file')
        # Using converted keys from above
        file_input.send_keys(oscal_json_path)

        self.click_element('input#import_component_submit')

        element_count_after_duplicate_import = wait_for_sleep_after(lambda: Element.objects.filter(element_type="system_element").count())

        self.assertEqual(element_count_after_import + 2, element_count_after_duplicate_import)

        original_import_element_count = Element.objects.filter(name='Test OSCAL Component1').count()
        self.assertEqual(original_import_element_count, 1)

        duplicate_import_element_count = Element.objects.filter(name='Test OSCAL Component1 (1)').count()
        self.assertEqual(duplicate_import_element_count, 1)

        statement_count_after_duplicate_import = Statement.objects.filter(
            statement_type=StatementTypeEnum.CONTROL_IMPLEMENTATION_PROTOTYPE.value).count()
        self.assertEqual(statement_count_after_import + 4, statement_count_after_duplicate_import)
Beispiel #11
0
    def test_discussion(self):
        # Log in and create a new project.
        self._login()
        self._new_project()
        wait_for_sleep_after(
            lambda: self._start_task())  # wait for page to reload

        # Move past the introduction screen.
        self.assertRegex(self.browser.title,
                         "Next Question: Module Introduction")
        self.click_element("#save-button")
        var_sleep(.8)  # wait for page to reload

        # Click interstitial "Got it" button
        self.click_element("#save-button")
        var_sleep(.5)

        # We're now on the first actual question.
        # Start a team conversation.
        wait_for_sleep_after(lambda: self.click_element("#start-a-discussion"))
        wait_for_sleep_after(lambda: self.fill_field(
            "#discussion-your-comment", "Hello is anyone *here*?"))
        var_sleep(.5)
        wait_for_sleep_after(lambda: self.click_element(
            "#discussion .comment-input button.btn-primary"))
        var_sleep(1.0)
        self.assertInNodeText("Hello", '.comment[data-id="1"] .comment-text p')

        # Test Script injection
        script = "<script id='injectiontest2'>document.getElementsByTagName('body')[0]" \
                 ".appendChild('<div id=\\'injectiontest1\\'></div>');</script>"
        wait_for_sleep_after(
            lambda: self.fill_field("#discussion-your-comment", script))
        wait_for_sleep_after(lambda: self.click_element(
            "#discussion .comment-input button.btn-primary"))

        # Check that the element was *not* added to the page.
        with self.assertRaises(NoSuchElementException):
            self.browser.find_element_by_css_selector('#injectiontest1')

        # Check that the script tag was removed entirely.
        with self.assertRaises(NoSuchElementException):
            self.browser.find_element_by_css_selector('#injectiontest2')

        # Test some special characters
        wait_for_sleep_after(
            lambda: self.fill_field("#discussion-your-comment", "¥"))
        wait_for_sleep_after(lambda: self.click_element(
            "#discussion .comment-input button.btn-primary"))
        var_sleep(0.5)
        self.assertInNodeText("¥", '.comment[data-id="3"] .comment-text p')
Beispiel #12
0
    def _new_project(self):
        self.browser.get(self.url("/projects"))
        self.click_element("#new-project")

        # Select Portfolio
        self.select_option_by_visible_text('#id_portfolio', self.user.username)
        self.click_element("#select_portfolio_submit")
        var_sleep(2)

        self.click_element(".app[data-app='fixture/simple_project'] .view-app")
        self.click_element("#start-project")
        var_sleep(1)
        self.assertRegex(self.browser.title,
                         "I want to answer some questions on Q.")
Beispiel #13
0
    def _new_project(self):
        self.browser.get(self.url("/store"))

        # wait_for_sleep_after(lambda: self.click_element("#new-project-link-from-projects"))

        var_sleep(1)
        # Click Add Button
        wait_for_sleep_after(lambda: self.click_element(
            ".app-form[data-app='project/simple_project'] .start-app"))
        wait_for_sleep_after(lambda: self.assertRegex(
            self.browser.title, "I want to answer some questions on Q."))

        m = re.match(r"http://.*?/projects/(\d+)/", self.browser.current_url)
        self.current_project = Project.objects.get(id=m.group(1))
Beispiel #14
0
    def test_import_delete(self):
        """Tests that import deletions remove child components and statements."""

        # Create an Import Record with a component and statement
        helper = ControlTestHelper()
        import_record = helper.create_simple_import_record()

        self._login()
        url = self.url(f"/controls/import_records")
        self.browser.get(url)

        self.click_element(f"a.import_record_detail_link")
        self.click_element(f"a#delete-import")

        # Test that cancel doesn't delete the import, and redirects to the component library
        self.click_element(f"a#cancel-import-delete")

        current_path = urlparse(self.browser.current_url).path
        self.assertEqual('/controls/components', current_path)

        import_records_count = ImportRecord.objects.all().count()
        self.assertEqual(import_records_count, 1)
        component_count = Element.objects.filter(
            import_record=import_record).count()
        self.assertEqual(component_count, 1)
        statement_count = Statement.objects.filter(
            import_record=import_record).count()
        self.assertEqual(statement_count, 1)

        # Test that confirming the deletion deletes the import, component, and statement
        url = self.url(f"/controls/import_records")
        self.browser.get(url)
        self.click_element(f"a.import_record_detail_link")
        self.click_element(f"a#delete-import")

        self.click_element(f"a#confirm-import-delete")

        var_sleep(1)
        current_path = urlparse(self.browser.current_url).path
        self.assertEqual('/controls/components', current_path)

        import_records_count = ImportRecord.objects.all().count()
        self.assertEqual(import_records_count, 0)
        component_count = Element.objects.filter(
            import_record=import_record).count()
        self.assertEqual(component_count, 0)
        statement_count = Statement.objects.filter(
            import_record=import_record).count()
        self.assertEqual(statement_count, 0)
Beispiel #15
0
    def test_update_project_json_import(self):
        """
        Testing the update of a project through project JSON import and ingestion of components and their statements
        """

        # login as the first user and create a new project
        self._login()
        self._new_project()

        # Checks the number of projects and components before the import
        self.assertEqual(Project.objects.all().count(), 3)
        self.assertEqual(
            Element.objects.all().exclude(element_type='system').count(), 0)

        ## Update current project
        # click import project button, opening the modal
        self.click_element(
            "#action-buttons\ action-row > div.btn-group > button:nth-child(4)"
        )
        ## select through the modal information needed and browse for the import needed
        self.select_option_by_visible_text("#id_appsource_compapp", "project")

        # The selection variable found by id
        select = Select(
            self.browser.find_element_by_id("id_appsource_version_id"))
        # Select the last option by index
        selectLen = len(select.options)
        select.select_by_index(selectLen - 1)

        file_input = self.browser.find_element_by_css_selector("#id_file")

        file_path = os.getcwd() + "/fixtures/test_project_import_data.json"
        # convert filepath if necessary and send keys
        self.filepath_conversion(file_input, file_path, "sendkeys")
        self.browser.find_element_by_id("import_component_submit").click()

        # Check the new number of projects, and validate that it's the same
        project_num = Project.objects.all().count()
        self.assertEqual(project_num, 3)
        # Has the updated name?
        var_sleep(5)
        self.assertEqual(Project.objects.all()[project_num - 1].title,
                         "New Test Project")

        # Components and their statements?
        self.assertEqual(
            Element.objects.all().exclude(element_type='system').count(), 1)
        self.assertEqual(Statement.objects.all().count(), 3)
    def test_edit_portfolio(self):
        """
        Editing a portfolio's title and/or description provides appropriate validation and messaging
        """
        # journey to portfolios and ensure i have multiple portfolios if not then create new portfolios
        self._login()
        self.browser.get(self.url("/portfolios"))
        # Navigate to the portfolio form
        self.click_element_with_link_text("Portfolios")
        # Click Create Portfolio button
        self.click_element("#new-portfolio")
        var_sleep(0.5)
        # Fill in form
        wait_for_sleep_after(lambda: self.fill_field("#id_title", "Test 1"))
        self.fill_field("#id_description", "Test 1 portfolio")
        # Submit form
        self.click_element("#create-portfolio-button")
        # Test we are on portfolio page we just created
        var_sleep(0.35)
        wait_for_sleep_after(lambda: self.assertRegex(
            self.browser.title, "Test 1 Portfolio - GovReady-Q"))
        # Navigate to portfolios
        self.browser.get(self.url("/portfolios"))

        # Navigate to portfolios
        self.browser.get(self.url("/portfolios"))
        # Click on the pencil anchor tag to edit
        self.browser.find_elements_by_class_name(
            "portfolio-project-link")[-1].click()

        # Edit title to a real new name and press update
        self.clear_and_fill_field("#id_title", "new me")
        self.clear_and_fill_field("#id_description", "new me portfolio")
        # Submit form
        self.click_element("#edit_portfolio_submit")

        # Verify new portfolio name is listed under portfolios
        self.assertIn("new me", self._getNodeText("#portfolio_new\ me"))
        # Verify 'updated' message is correct
        self.assertIn("The portfolio 'new me' has been updated.",
                      self._getNodeText("div.alert.fade.in.alert-info"))

        # verify new description by journeying back to edit_form
        self.browser.find_elements_by_class_name(
            "portfolio-project-link")[-1].click()
Beispiel #17
0
    def test_component_download_oscal_json(self):
        self._login()
        url = self.url(
            f"/systems/{self.system.id}/component/{self.component.id}")
        self.browser.get(url)
        self.click_element('a[href="#oscal"]')

        # sigh; selenium doesn't really let us find out the name of the
        # downloaded file, so let's make sure it doesn't exist before we
        # download
        # definite race condition possibility

        if self.json_download.is_file():
            self.json_download.unlink()
        elif os.path.isfile(self.json_download.name):
            os.remove(self.json_download.name)
        wait_for_sleep_after(
            lambda: self.click_element("a#oscal_download_json_link"))
        var_sleep(2)
        # assert download exists!
        try:
            # The following test FAILS on MacOS when tests run in HEADLESS mode.
            # Test passes when tests run in visible mode.
            # See: https://github.com/SeleniumHQ/selenium/issues/5292#issuecomment-544264234
            # To use visible mode, add to environment.json file ` "test_visible": true `
            # See: https://govready-q.readthedocs.io/en/latest/testing-for-govready-q/automated-testing.html#for-developers
            self.assertTrue(self.json_download.is_file())
            wait_for_sleep_after(
                lambda: self.assertTrue(self.json_download.is_file()))
            filetoopen = self.json_download
        except:
            wait_for_sleep_after(lambda: self.assertTrue(
                os.path.isfile(self.json_download.name)))
            # assert that it is valid JSON by trying to load it
            filetoopen = self.json_download.name
        with open(filetoopen, 'r') as f:
            json_data = json.load(f)
            self.assertIsNotNone(json_data)

        if self.json_download.is_file():
            self.json_download.unlink()
        elif os.path.isfile(self.json_download.name):
            os.remove(self.json_download.name)
Beispiel #18
0
    def _accept_invitation(self, email):
        # Assumes an invitation email was sent.

        # Extract the URL in the email and visit it.
        invitation_body = self.pop_email().body
        invitation_url_pattern = re.escape(self.url("/invitation/")) + r"\S+"
        self.assertRegex(invitation_body, invitation_url_pattern)
        m = re.search(invitation_url_pattern, invitation_body)
        self.browser.get(m.group(0))

        # Since we're not logged in, we hit the invitation splash page.
        self.click_element('#button-sign-in')
        var_sleep(.5)  # wait for page to load

        # We're at the sign-in page. Go to the create account page
        # and register. Use a random username so that we submit something
        # unique, since a test may create multiple users.
        self.assertRegex(self.browser.title, "Sign In")
        self.click_element(
            "p a")  # This isn't a very good targetting of the "sign up" link.
        var_sleep(.5)  # wait for page to load
        self.fill_field("#id_username",
                        "*****@*****.**" % get_random_string(6))
        self.fill_field("#id_email", email)
        self.fill_field("#id_password1", "1234")
        self.fill_field("#id_password2", "1234")
        self.click_element(
            "form.signup button"
        )  # This isn't a very good targetting of the "sign up" link.
        var_sleep(.5)  # wait for next page to load

        # Test that an allauth confirmation email was sent.
        self.assertIn(
            "Please confirm your email address at GovReady Q by following this link",
            self.pop_email().body)
Beispiel #19
0
    def test_discussion(self):

        # Log in and create a new project.
        self._login()
        self._new_project()
        self._start_task()

        # Move past the introduction screen.
        self.assertRegex(self.browser.title, "Next Question: Introduction")
        self.click_element("#save-button")
        var_sleep(.5)  # wait for page to reload

        # We're now on the first actual question.
        # Start a team conversation.
        self.click_element("#start-a-discussion")
        self.fill_field("#discussion-your-comment", "Hello is anyone *here*?")
        var_sleep(.5)
        self.click_element("#discussion .comment-input button.btn-primary")
        var_sleep(.5)

        # Test Script injection
        self.fill_field(
            "#discussion-your-comment",
            "<script id='injectiontest2'>document.getElementsByTagName('body')[0].appendChild('<div id=\\'injectiontest1\\'></div>');</script>"
        )
        var_sleep(.5)
        self.click_element("#discussion .comment-input button.btn-primary")
        var_sleep(.5)

        # Check that the element was *not* added to the page.
        with self.assertRaises(NoSuchElementException):
            self.browser.find_element_by_css_selector('#injectiontest1')

        # Check that the script tag was removed entirely.
        with self.assertRaises(NoSuchElementException):
            self.browser.find_element_by_css_selector('#injectiontest2')

        # Test some special characters
        self.fill_field("#discussion-your-comment", "¥")
        var_sleep(.5)
        self.click_element("#discussion .comment-input button.btn-primary")
        var_sleep(.5)

        self.assertInNodeText("¥", '.comment[data-id="3"] .comment-text p')

        # Test file attachments

        # We need to upload a file that we know exists.
        testFilePath = os.path.join(
            os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
            'fixtures', 'testimage.png')

        self.fill_field("#discussion-attach-file", testFilePath)
        var_sleep(1)
        self.click_element("#discussion .comment-input button.btn-primary")
        var_sleep(1)  # Give time for the image to upload.

        # Test that we have an image.
        img = self.browser.find_element_by_css_selector(
            '.comment[data-id="4"] .comment-text p img')
        self.assertIsNotNone(img)

        # Test that the image actually exists.
        imageFile = img.get_attribute('src')

        result = self.browser.execute_script(
            """var http = new XMLHttpRequest();
            http.open('HEAD', '{}', false);
            http.send();
            return http.status!=404;""".format(imageFile))

        self.assertTrue(result)
Beispiel #20
0
    def test_smt_autocomplete(self):
        """
        Testing if the textbox can autocomplete and filter for existing components
        """

        # login as the first user and create a new project
        self._login()
        self._new_project()

        # TODO: Why is system being overridden/conditional. system_id will be 1 in test class and 4 in full test suite
        systemid = System.objects.all().first()
        #print("systemid")
        #print(systemid.id)
        self.navigateToPage(f"/systems/{systemid.id}/controls/selected")

        # Select moderate
        self.navigateToPage(
            f"/systems/{systemid.id}/controls/baseline/NIST_SP-800-53_rev4/moderate/_assign"
        )
        # Head to the control ac-3
        self.navigateToPage(
            f"/systems/{systemid.id}/controls/catalogs/NIST_SP-800-53_rev4/control/ac-3"
        )

        statement_title_list = self.browser.find_elements_by_css_selector(
            "span#producer_element-panel_num-title")
        assert len(statement_title_list) == 0
        # Starts at 4
        num = 4
        # Creating a few components

        self.create_fill_statement_form("Component 1", "Component body", 'a',
                                        'status_', "Planned",
                                        "Component remarks", num)
        num += 1
        var_sleep(.5)
        self.create_fill_statement_form("Component 2", "Component body", 'b',
                                        'status_', "Planned",
                                        "Component remarks", num)
        num += 1
        var_sleep(.5)
        self.create_fill_statement_form("Component 3", "Component body", 'c',
                                        'status_', "Planned",
                                        "Component remarks", num)
        num += 1
        var_sleep(.5)
        self.create_fill_statement_form("Test name 1", "Component body", 'a',
                                        'status_', "Planned",
                                        "Component remarks", num)
        num += 1
        var_sleep(.5)
        self.create_fill_statement_form("Test name 2", "Component body", 'b',
                                        'status_', "Planned",
                                        "Component remarks", num)
        num += 1
        var_sleep(.5)
        self.create_fill_statement_form("Test name 3", "Component body", 'c',
                                        'status_', "Planned",
                                        "Component remarks", num)
        var_sleep(1)
        self.click_components_tab()
        var_sleep(1)
        # Confirm the dropdown sees all components
        comps_dropdown = self.dropdown_option(
            "selected_producer_element_form_id")
        assert len(comps_dropdown.options) == 6
        # Click on search bar
        search_comps_txtbar = self.browser.find_elements_by_id(
            "producer_element_search")

        # Type a few text combinations and make sure filtering is working
        # Need to click the new dropdown after sending keys

        ## Search for Component
        search_comps_txtbar[-1].click()
        search_comps_txtbar[-1].clear()
        search_comps_txtbar[-1].send_keys("Component")
        self.browser.find_elements_by_id(
            "selected_producer_element_form_id")[-1].click()
        var_sleep(3)
        assert len(comps_dropdown.options) == 3

        ## Search for 2
        search_comps_txtbar[-1].click()
        search_comps_txtbar[-1].clear()
        search_comps_txtbar[-1].send_keys("2")
        self.browser.find_elements_by_id(
            "selected_producer_element_form_id")[-1].click()
        var_sleep(3)
        assert len(comps_dropdown.options) == 2

        # Add a new component based on one of the options available in the filtered dropdown
        try:
            ## Test name 2 has a value of 6 and Component 2 has a value of 3
            self.select_option("select#selected_producer_element_form_id", "6")
            assert self.find_selected_option(
                "select#selected_producer_element_form_id").get_attribute(
                    "value") == "6"
        except:
            self.select_option("select#selected_producer_element_form_id",
                               "13")
            assert self.find_selected_option(
                "select#selected_producer_element_form_id").get_attribute(
                    "value") == "13"

        try:
            ## Test name 2 has a value of 6 and Component 2 has a value of 3
            self.select_option("select#selected_producer_element_form_id", "3")
            assert self.find_selected_option(
                "select#selected_producer_element_form_id").get_attribute(
                    "value") == "3"
        except:
            self.select_option("select#selected_producer_element_form_id",
                               "10")
            assert self.find_selected_option(
                "select#selected_producer_element_form_id").get_attribute(
                    "value") == "10"

        # Open a modal will with component statements related to the select component prototype
        add_related_statements_btn = self.browser.find_elements_by_id(
            "add_related_statements")
        add_related_statements_btn[-1].click()
        var_sleep(2)
        # Ensure we can't submit no component statements and that the alert pops up.
        self.browser.find_element_by_xpath(
            "//*[@id='relatedcompModal']/div/div[1]/div[4]/button").click()

        # Open the first panel
        component_element_btn = self.browser.find_element_by_id(
            "related-panel-1")
        component_element_btn.click()
        var_sleep(1)
        select_comp_statement_check = self.browser.find_element_by_name(
            "relatedcomps")
        select_comp_statement_check.click()
        var_sleep(1)
        # Add component statement
        submit_comp_statement = self.browser.find_element_by_xpath(
            "//*[@id='relatedcompModal']/div/div[1]/div[4]/button")
        submit_comp_statement.click()

        self.click_components_tab()

        statement_title_list = self.browser.find_elements_by_css_selector(
            "span#producer_element-panel_num-title")
        assert len(statement_title_list) == 7
Beispiel #21
0
    def test_smt_autocomplete(self):
        """
        Testing if the textbox can autocomplete and filter for existing components
        """

        # login as the first user and create a new project
        self._login()
        self._new_project()

        # TODO: Why is system being overridden/conditional. system_id will be 1 in test class and 4 in full test suite
        systemid = System.objects.all().first()
        self.navigateToPage(f"/systems/{systemid.id}/controls/selected")

        # Select moderate
        self.navigateToPage(
            f"/systems/{systemid.id}/controls/baseline/NIST_SP-800-53_rev4/moderate/_assign"
        )
        # Head to the control ac-3
        self.navigateToPage(
            f"/systems/{systemid.id}/controls/catalogs/NIST_SP-800-53_rev4/control/ac-3"
        )

        # How many components are there currently?
        # Confirm the dropdown sees all components
        comps_dropdown = wait_for_sleep_after(
            lambda: self.dropdown_option("selected_producer_element_form_id"))
        num = len(comps_dropdown.options)

        # Create components
        self.create_fill_statement_form("Component 1", "Component body", 'a',
                                        'status_', "Planned",
                                        "Component remarks", num)
        num += 1
        wait_for_sleep_after(lambda: self.create_fill_statement_form(
            "Component 2", "Component body", 'b', 'status_', "Planned",
            "Component remarks", num))
        num += 1
        wait_for_sleep_after(lambda: self.create_fill_statement_form(
            "Component 3", "Component body", 'c', 'status_', "Planned",
            "Component remarks", num))
        num += 1
        wait_for_sleep_after(lambda: self.create_fill_statement_form(
            "Test name 1", "Component body", 'a', 'status_', "Planned",
            "Component remarks", num))
        num += 1
        wait_for_sleep_after(lambda: self.create_fill_statement_form(
            "Test name 2", "Component body", 'b', 'status_', "Planned",
            "Component remarks", num))
        num += 1
        wait_for_sleep_after(lambda: self.create_fill_statement_form(
            "Test name 3", "Component body", 'c', 'status_', "Planned",
            "Component remarks", num))

        # Refresh page to refresh items in selection
        self.navigateToPage(
            f"/systems/{systemid.id}/controls/catalogs/NIST_SP-800-53_rev4/control/ac-3"
        )

        wait_for_sleep_after(lambda: self.click_components_tab())

        # Confirm the dropdown sees all components
        comps_dropdown = wait_for_sleep_after(
            lambda: self.dropdown_option("selected_producer_element_form_id"))

        self.assertEquals(len(comps_dropdown.options), 7)

        # Click on search bar
        search_comps_txtbar = self.browser.find_elements_by_id(
            "producer_element_search")

        # Type a few text combinations and make sure filtering is working
        # Need to click the new dropdown after sending keys

        ## Search for Component
        search_comps_txtbar[-1].click()
        search_comps_txtbar[-1].clear()
        search_comps_txtbar[-1].send_keys("Component")
        self.browser.find_elements_by_id(
            "selected_producer_element_form_id")[-1].click()  # Ajax request
        var_sleep(1)
        assert len(comps_dropdown.options) == 3

        ## Search for 2
        search_comps_txtbar[-1].click()
        search_comps_txtbar[-1].clear()
        search_comps_txtbar[-1].send_keys("2")
        self.browser.find_elements_by_id(
            "selected_producer_element_form_id")[-1].click()  # Ajax request
        var_sleep(1)
        # print("####### len(comps_dropdown.options)", len(comps_dropdown.options))
        assert len(comps_dropdown.options) == 2
        # Use elements from database to avoid hard-coding element ids expected
        elements = Element.objects.all()
        testname2_ele = str(elements[5].id)
        component2_ele = str(elements[2].id)
        # Add a new component based on one of the options available in the filtered dropdown
        ## Test name 2 has a value of 6 and Component 2 has a value of 3
        self.select_option("select#selected_producer_element_form_id",
                           testname2_ele)
        assert self.find_selected_option(
            "select#selected_producer_element_form_id").get_property(
                "value") == testname2_ele

        ## Test name 2 has a value of 6 and Component 2 has a value of 3
        self.select_option("select#selected_producer_element_form_id",
                           component2_ele)
        assert self.find_selected_option(
            "select#selected_producer_element_form_id").get_property(
                "value") == component2_ele

        # Open a modal will with component statements related to the select component prototype
        add_related_statements_btn = self.browser.find_elements_by_id(
            "add_related_statements")
        add_related_statements_btn[-1].click()
        # Ensure we can't submit no component statements and that the alert pops up.
        wait_for_sleep_after(lambda: self.browser.find_element_by_xpath(
            "//*[@id='relatedcompModal']/div/div[1]/div[4]/button").click())

        # Open the first panel
        component_element_btn = self.browser.find_element_by_id(
            "related-panel-1")
        component_element_btn.click()
        select_comp_statement_check = wait_for_sleep_after(
            lambda: self.browser.find_element_by_name("relatedcomps"))
        var_sleep(1)
        wait_for_sleep_after(lambda: select_comp_statement_check.click())
        var_sleep(1)
        # Add component statement
        submit_comp_statement = wait_for_sleep_after(
            lambda: self.browser.find_element_by_xpath(
                "//*[@id='relatedcompModal']/div/div[1]/div[4]/button"))
        submit_comp_statement.click()
Beispiel #22
0
 def test_control_lookup(self):
     self.browser.get(
         self.url("/controls/catalogs/NIST_SP-800-53_rev4/control/au-2"))
     var_sleep(2)
     self.assertInNodeText("AU-2", "#control-heading")
     self.assertInNodeText("Audit Events", "#control-heading")
Beispiel #23
0
    def test_discussion(self):
        # Log in and create a new project.
        self._login()
        self._new_project()
        var_sleep(.5)  # wait for page to reload
        self._start_task()

        # Move past the introduction screen.
        self.assertRegex(self.browser.title, "Next Question: Introduction")
        self.click_element("#save-button")
        var_sleep(.8)  # wait for page to reload

        # Click interstital "Got it" button
        self.click_element("#save-button")
        var_sleep(.5)

        # We're now on the first actual question.
        # Start a team conversation.
        self.click_element("#start-a-discussion")
        var_sleep(1)
        self.fill_field("#discussion-your-comment", "Hello is anyone *here*?")
        var_sleep(.5)
        self.click_element("#discussion .comment-input button.btn-primary")
        var_sleep(.5)

        # Test Script injection
        script = "<script id='injectiontest2'>document.getElementsByTagName('body')[0]" \
                 ".appendChild('<div id=\\'injectiontest1\\'></div>');</script>"
        self.fill_field("#discussion-your-comment", script)
        var_sleep(.5)
        self.click_element("#discussion .comment-input button.btn-primary")
        var_sleep(.5)

        # Check that the element was *not* added to the page.
        with self.assertRaises(NoSuchElementException):
            self.browser.find_element_by_css_selector('#injectiontest1')

        # Check that the script tag was removed entirely.
        with self.assertRaises(NoSuchElementException):
            self.browser.find_element_by_css_selector('#injectiontest2')

        # Test some special characters
        self.fill_field("#discussion-your-comment", "¥")
        var_sleep(.5)
        self.click_element("#discussion .comment-input button.btn-primary")
        var_sleep(.5)

        self.assertInNodeText("¥", '.comment[data-id="3"] .comment-text p')

        # Test file attachments upload successfully

        # We need to upload a file that we know exists.
        test_file_name = "".join([TEST_FILENAME, ".png"])
        test_file_path = os.path.join(
            os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
            FIXTURE_DIR, test_file_name)

        self.filepath_conversion("#discussion-attach-file", test_file_path,
                                 "fill")

        var_sleep(.5)
        self.click_element("#discussion .comment-input button.btn-primary")

        var_sleep(.5)  # Give time for the image to upload.
        # Test that we have an image.
        img = self.browser.find_element_by_css_selector(
            '.comment[data-id="4"] .comment-text p img')
        # self.assertIsNotNone(img)

        # Test that valid PNG image actually exists with valid content type.
        image_url = img.get_attribute('src')
        cookies = self._get_browser_cookies()
        response = requests.get(image_url, cookies=cookies)
        image_contents = response.content

        file_model = SimpleUploadedFile(test_file_name,
                                        image_contents,
                                        content_type="image/png")
        image_file_valid = validate_file_extension(file_model)
        self.assertIsNone(image_file_valid)

        result = self.browser.execute_script(
            """var http = new XMLHttpRequest();
            http.open('HEAD', '{}', false);
            http.send();
            return http.status!=404;""".format(image_url))

        self.assertTrue(result)
    def test_invitations(self):
        # Test a bunch of invitations.

        # Log in and create a new project.
        self._login()
        self._new_project()
        project_page = self.browser.current_url

        # And create a new task.
        self._start_task()
        task_page = self.browser.current_url

        # But now go back to the project page.
        self.browser.get(project_page)

        def start_invitation(username):
            # Fill out the invitation modal.
            # self.select_option_by_visible_text('#invite-user-select', username) # This is for selecting user from dropdown list
            wait_for_sleep_after(
                lambda: self.fill_field("input#invite-user-email", username))
            wait_for_sleep_after(lambda: self.click_element(
                "#invitation_modal button.btn-submit"))

        def do_invitation(username):
            start_invitation(username)
            var_sleep(.5)  # wait for invitation to be sent

            # Log out and accept the invitation as an anonymous user.
            self.browser.get(self.url("/accounts/logout/"))
            self._accept_invitation(username)

        def reset_login():
            # Log out and back in as the original user.
            self.browser.get(self.url("/accounts/logout/"))
            self._login()
            wait_for_sleep_after(lambda: self.browser.get(project_page))

        # Test an invitation to that project. For unknown reasons, when
        # executing this on CircleCI (but not locally), the click fails
        # because the element is not clickable -- it reports a coordinate
        # that's above the button in the site header. Not sure what's
        # happening. So load the modal using Javascript.
        wait_for_sleep_after(
            lambda: self.click_element("#menu-btn-show-project-invite"))
        self.browser.execute_script("invite_user_into_project()")
        # Toggle field to invite user by email
        self.browser.execute_script(
            "$('#invite-user-email').parent().toggle(true)")

        # Test an invalid email address.
        start_invitation("example")
        wait_for_sleep_after(lambda: self.assertInNodeText(
            "The email address is not valid.", "#global_modal")
                             )  # make sure we get a stern message.
        wait_for_sleep_after(lambda: self.click_element("#global_modal button")
                             )  # dismiss the warning.

        wait_for_sleep_after(lambda: self.click_element(
            "#menu-btn-show-project-invite"))  # Re-open the invite box.
        self.browser.execute_script(
            "invite_user_into_project()")  # See comment above.
        # Toggle field to invite user by email

        wait_for_sleep_after(lambda: self.browser.execute_script(
            "$('#invite-user-email').parent().toggle(true)"))
        var_sleep(3)  # Adding to avoid lock
        do_invitation(self.user2.email)
        self.fill_field("#id_login", self.user2.username)
        self.fill_field("#id_password", self.user2.clear_password)
        self.click_element("form button.primaryAction")

        self.assertRegex(self.browser.title,
                         "I want to answer some questions on Q"
                         )  # user is on the project page
        wait_for_sleep_after(lambda: self.click_element(
            '#question-simple_module'))  # go to the task page
        wait_for_sleep_after(lambda: self.assertRegex(
            self.browser.title, "Next Question: Module Introduction")
                             )  # user is on the task page

        # reset_login()

        # Test an invitation to take over editing a task but without joining the project.
        var_sleep(.5)
        wait_for_sleep_after(
            lambda: self.click_element("#save-button")
        )  # pass over the Introductory question because the Help link is suppressed on interstitials
        wait_for_sleep_after(lambda: self.click_element('#transfer-editorship')
                             )  # Toggle field to invite user by email

        self.browser.execute_script(
            "$('#invite-user-email').parent().toggle(true)")
        wait_for_sleep_after(lambda: do_invitation(self.user3.email)
                             )  # Toggle field to invite user by email

        self.fill_field("#id_login", self.user3.username)
        self.fill_field("#id_password", self.user3.clear_password)
        self.click_element("form button.primaryAction")
        wait_for_sleep_after(lambda: self.assertRegex(
            self.browser.title, "Next Question: The Question")
                             )  # user is on the task page

        # Test assigning existing user to a project.
        reset_login()
        self._new_project()
        project_page = self.browser.current_url

        # And create a new task.
        self._start_task()
        task_page = self.browser.current_url

        # But now go back to the project page.
        self.browser.get(project_page)
        wait_for_sleep_after(
            lambda: self.click_element("#menu-btn-show-project-invite"))

        # Select username "me3"
        wait_for_sleep_after(lambda: self.select_option_by_visible_text(
            '#invite-user-select', "me3"))
        wait_for_sleep_after(lambda: self.click_element("#invite_submit_btn"))
        wait_for_sleep_after(lambda: self.assertInNodeText(
            "me3 granted edit permission to project", ".alert"))
    def test_create_portfolios(self):
        # Create a new account
        self.browser.get(self.url("/"))
        self.click_element('#tab-register')
        self._fill_in_signup_form("*****@*****.**",
                                  "portfolio_user")
        self.click_element("#signup-button")
        if "Warning Message" in self.browser.title:
            self.click_element("#btn-accept")

        # Go to portfolio page
        self.browser.get(self.url("/portfolios"))

        # Navigate to portfolio created on signup
        self.click_element_with_link_text("portfolio_user")

        # Test creating a portfolio using the form
        # Navigate to the portfolio form
        wait_for_sleep_after(
            lambda: self.click_element_with_link_text("Portfolios"))
        # Click Create Portfolio button
        self.click_element("#new-portfolio")
        var_sleep(0.5)
        # Fill in form
        wait_for_sleep_after(lambda: self.fill_field("#id_title", "Test 1"))
        self.fill_field("#id_description", "Test 1 portfolio")
        # Submit form
        self.click_element("#create-portfolio-button")
        # Test we are on portfolio page we just created
        wait_for_sleep_after(lambda: self.assertRegex(
            self.browser.title, "Test 1 Portfolio - GovReady-Q"))

        # Test we cannot create a portfolio with the same name
        # Navigate to the portfolio form
        self.click_element_with_link_text("Portfolios")
        # Click Create Portfolio button
        self.click_element("#new-portfolio")
        var_sleep(0.5)
        # Fill in form
        wait_for_sleep_after(lambda: self.fill_field("#id_title", "Test 1"))
        self.fill_field("#id_description", "Test 1 portfolio")
        # Submit form
        self.click_element("#create-portfolio-button")
        # We should get an error

        # test error
        wait_for_sleep_after(lambda: self.assertIn(
            "Portfolio name Test 1 not available.",
            self._getNodeText(
                "div.alert.alert-danger.alert-dismissable.alert-link")))
        # Test uniqueness with case insensitivity
        # Navigate to the portfolio form
        self.click_element_with_link_text("Portfolios")
        # Click Create Portfolio button
        self.click_element("#new-portfolio")
        var_sleep(0.5)
        # Fill in form
        wait_for_sleep_after(lambda: self.fill_field("#id_title", "test 1"))
        # Submit form
        wait_for_sleep_after(
            lambda: self.click_element("#create-portfolio-button"))
        # We should get an error
        var_sleep(0.5)
        # test error
        wait_for_sleep_after(lambda: self.assertIn(
            "Portfolio name test 1 not available.",
            self._getNodeText(
                "div.alert.alert-danger.alert-dismissable.alert-link")))