def test_createThread(self):
     Automate.login(self.driver, False)
     # Click 'Create Thread'
     self.driver.find_element_by_class_name(
         "card").find_element_by_class_name("form-control").click()
     # User input of thread fields
     # time.sleep(1)
     container = self.driver.find_element_by_class_name("card-body")
     titleField = container.find_element_by_name("thread_title")
     titleField.send_keys("test thread title")
     dropdowns = container.find_elements_by_class_name("css-1hwfws3")
     self.actions.move_to_element(dropdowns[0]).click().send_keys(
         Keys.DOWN).send_keys(Keys.RETURN)
     self.actions.move_to_element(dropdowns[1]).click().send_keys(
         Keys.DOWN).send_keys(Keys.RETURN)
     self.actions.move_to_element(dropdowns[2]).click().send_keys(
         Keys.DOWN).send_keys(Keys.RETURN).perform()
     commentField = container.find_element_by_name("comment")
     commentField.send_keys("test thread post")
     # Read user inputs
     school = dropdowns[1].text
     course = dropdowns[2].text
     title = titleField.text
     commentField.submit()
     thread = self.driver.find_element_by_class_name("thread-card.card")
     # Compare values with created thread
     self.assertEqual(school,
                      thread.find_elements_by_class_name("data")[0].text)
     self.assertEqual(course,
                      thread.find_elements_by_class_name("data")[1].text)
     self.assertEqual(title,
                      thread.find_element_by_class_name("card-title").text)
 def test_voteOnce(self):
     Automate.login(self.driver, False)
     for i, section in enumerate(
             self.driver.find_elements_by_class_name("votes-section")):
         upvote = section.find_elements_by_tag_name("div")[0]
         downvote = section.find_elements_by_tag_name("div")[1]
         voteCount = int(section.find_elements_by_tag_name("div")[2].text)
         # if voted thread
         if upvote.get_attribute(
                 "class") == "vote-icon upvote-icon is-true":
             upvote.click()
             time.sleep(5)
             newVoteCount = int(
                 self.driver.find_elements_by_class_name("votes-section")
                 [i].find_elements_by_tag_name("div")[2].text)
             self.assertEqual(voteCount - 1, newVoteCount)
         elif downvote.get_attribute(
                 "class") == "vote-icon downvote-icon is-true":
             downvote.click()
             time.sleep(5)
             newVoteCount = int(
                 self.driver.find_elements_by_class_name("votes-section")
                 [i].find_elements_by_tag_name("div")[2].text)
             self.assertEqual(voteCount + 1, newVoteCount)
         else:
             continue
         break
 def test_emptyFields(self):
     Automate.login(self.driver, False)
     self.driver.find_element_by_class_name(
         "card").find_element_by_class_name("form-control").click()
     container = self.driver.find_element_by_class_name("card-body")
     # time.sleep(1)
     titleField = container.find_element_by_name("thread_title")
     titleField.click()
     dropdowns = container.find_elements_by_class_name("css-1hwfws3")
     dropdowns[0].click()
     self.assertEqual(
         self.driver.find_elements_by_class_name("invalid-feedback")
         [0].text, "Required")
     dropdowns[1].click()
     self.assertEqual(
         self.driver.find_elements_by_class_name("invalid-feedback")
         [1].text, "Required")
     dropdowns[2].click()
     self.assertEqual(
         self.driver.find_elements_by_class_name("invalid-feedback")
         [2].text, "Required")
     self.driver.find_element_by_name("comment").click()
     self.driver.find_element_by_class_name("btn.btn-info").click()
     self.assertEqual(
         self.driver.find_elements_by_class_name("invalid-feedback")
         [3].text, "Required")
    def ableToWriteOrUploadPicInPost(self):
        Automate.navigateToSelectiveThread(self.driver, 4)

        # write post content and click the post button to post
        testMsg = "Testing 123"
        Automate.writeAPost(self.driver, testMsg)

        # see if the test post is successfully created
        latestPost = self.driver.find_elements_by_class_name("card-text")[0]
        self.assertEqual(latestPost.text, testMsg)
    def test_editOwnThread(self):
        username = Automate.login(self.driver, False)
        threads = self.driver.find_elements_by_class_name("thread-card.card")
        for threadIndex, thread in enumerate(threads):
            if thread.find_elements_by_class_name("data")[3].text == username:
                # Read thread details
                threadDetails = Automate.getThreadDetails(thread)
                # Click Thread Options -> Edit
                thread.find_element_by_class_name("thread-dropdown").click()
                thread.find_element_by_class_name("dropdown-item").click()
                break
        # update thread fields
        # time.sleep(1)
        container = self.driver.find_element_by_class_name("card-body")
        titleField = container.find_element_by_name("thread_title")
        titleField.clear()
        titleField.send_keys(threadDetails["title"] + " edited")
        dropdowns = container.find_elements_by_class_name("css-1hwfws3")
        dropdowns[0].click()
        collegeList = self.driver.find_element_by_xpath(
            "/html/body/div[1]/div/div/div/form/div[2]/div[2]/div[1]/div"
        ).text.split("\n")

        for i in range(1, len(collegeList)):
            if collegeList[i] in collegeList[0]:
                break
            else:
                self.actions.send_keys(Keys.DOWN)
        self.actions.send_keys(Keys.DOWN).send_keys(Keys.RETURN)

        self.actions.move_to_element(dropdowns[1]).click().send_keys(
            Keys.RETURN)
        self.actions.move_to_element(dropdowns[2]).click().send_keys(
            Keys.RETURN).perform()
        school_new = dropdowns[1].text
        course_new = dropdowns[2].text
        title_new = titleField.text
        self.driver.find_element_by_class_name("btn.btn-info").click()
        # using threadIndex as page is refreshed -> DOM became stale
        threadDetails_displayed = Automate.getThreadDetails(
            self.driver.find_elements_by_class_name("thread-card.card")
            [threadIndex])
        # Check that thread details are updated correctly
        self.assertNotEqual(threadDetails_displayed["school"],
                            threadDetails["school"])
        self.assertNotEqual(threadDetails_displayed["course"],
                            threadDetails["course"])
        self.assertNotEqual(threadDetails_displayed["title"],
                            threadDetails["title"])
        self.assertEqual(threadDetails_displayed["school"], school_new)
        self.assertEqual(threadDetails_displayed["course"], course_new)
        self.assertEqual(threadDetails_displayed["title"], title_new)
 def test_deleteAnyThread_mod(self):
     Automate.login(self.driver, True)
     threads = self.driver.find_elements_by_class_name("thread-card.card")
     threadCount = len(threads)
     for thread in threads:
         thread.find_element_by_class_name("thread-dropdown").click()
         thread.find_elements_by_class_name("dropdown-item")[1].click()
         self.driver.find_element_by_class_name("btn.btn-danger").click()
         break
     time.sleep(5)
     newThreadCount = len(
         self.driver.find_elements_by_class_name("thread-card.card"))
     self.assertEqual(threadCount - 1, newThreadCount)
    def postWithoutContent(self):
        # navigate to first thread on the homepage
        Automate.navigateToSelectiveThread(self.driver, 0)

        # if can find button with class name "btn.btn-info.disabled", means the button is disabled since we didn't write any content
        self.postButton = self.driver.find_element_by_class_name(
            "btn.btn-info.disabled")

        # write content to post's textbox again and see if the button will be disabled once there is no content
        postTxtBox = self.driver.find_element_by_class_name("form-control")
        postTxtBox.send_keys("AAA")
        # check if the post button is toggled to enable to post
        postButton = self.driver.find_element_by_class_name("btn.btn-info")
        postTxtBox.clear()
        # see if the post button is toggled backed to disabled now that the content is empty
        self.postButton = self.driver.find_element_by_class_name(
            "btn.btn-info.disabled")
 def test_editAnyThread_user(self):
     username = Automate.login(self.driver, False)
     threads = self.driver.find_elements_by_class_name("thread-card.card")
     for thread in threads:
         if thread.find_elements_by_class_name("data")[3].text != username:
             thread.find_element_by_class_name("thread-dropdown").click()
             options = thread.find_elements_by_class_name("dropdown-item")
             for option in options:
                 self.assertNotIn("Edit", option.text)
         break
 def test_downvoteThread(self):
     Automate.login(self.driver, False)
     for i, section in enumerate(
             self.driver.find_elements_by_class_name("votes-section")):
         upvote = section.find_elements_by_tag_name("div")[0]
         downvote = section.find_elements_by_tag_name("div")[1]
         # unvoted thread
         if upvote.get_attribute(
                 "class"
         ) == "vote-icon upvote-icon " and downvote.get_attribute(
                 "class") == "vote-icon downvote-icon ":
             voteCount = int(
                 section.find_elements_by_tag_name("div")[2].text)
             downvote.click()
             break
     time.sleep(5)
     newVoteCount = int(
         self.driver.find_elements_by_class_name("votes-section")
         [i].find_elements_by_tag_name("div")[2].text)
     self.assertEqual(voteCount - 1, newVoteCount)
Exemple #10
0
 def goCreateInvoice(self):
     self.user = self.chooseUser.currentText()
     self.company = self.chooseCompany.currentText()
     self.desc = self.jobDesc.toPlainText()
     self.PO = self.PONum.toPlainText() if self.PONeeded else None
     self.stDate = self.startDate.date().toPyDate()
     self.endDate = self.endDate.date().toPyDate()
     self.session = Automate.Automate(self.user, self.company)
     self.session.createDoc(self.desc, self.stDate, self.endDate, self.PO)
     infoWin = InfoWindow(self)
     infoWin.exec()
Exemple #11
0
def build_automate(s):
    stack = []
    if len(s) == 0:
        raise BadRegexp.BadRegexp("empty regexp")

    for item in s:
        # simple items
        if item == '1':
            stack.append(Automate.Automate("#"))
        elif item in ['a', 'b', 'c']:
            stack.append(Automate.Automate(item))

        # operations
        elif item == '.':
            if len(stack) < 2:
                raise BadRegexp.BadRegexp("concatenation error")
            b = stack.pop()
            a = stack.pop()
            stack.append(a.merge(b))

        elif item == '+':
            if len(stack) < 2:
                raise BadRegexp.BadRegexp("addition error")
            b = stack.pop()
            a = stack.pop()
            stack.append(a.add(b))

        elif item == '*':
            if len(stack) < 1:
                raise BadRegexp.BadRegexp("star error")
            a = stack.pop()
            stack.append(a.star())
        else:
            raise BadRegexp.BadRegexp("invalid symbol")

    if len(stack) != 1:
        raise BadRegexp.BadRegexp("few operations")

    return stack[0]
    def test_PostWithoutLogin(self):
        try:
            # to check the status of the login button see if it is not login before proceeding
            loginButtonStatus = self.driver.find_element_by_class_name(
                "dropdown-toggle.nav-link")
        except selenium.common.exceptions.NoSuchElementException as e:
            # no need logout cause not login
            pass
        else:
            # to logout since is login as can find the dropdown toggle button which only login then appear
            # have a few elements with the same class name. The button to logout is the first element with that class name
            logoutButton = self.driver.find_elements_by_class_name(
                "dropdown-item")[0]
            # click to logout
            logoutButton.click()

        Automate.navigateToSelectiveThread(self.driver, 0)

        # delay 5 sec to let page load
        #self.driver.implicitly_wait(5)
        # if cannot find then throw exception means fail test case
        promptLogin = self.driver.find_element_by_class_name(
            "login-prompt-text")
    def deleteOwnPost(self):
        Automate.navigateToSelectiveThread(self.driver, 0)
        Automate.writeAPost(self.driver, "Testing testing")

        # get the list of posts
        listOfPosts = self.driver.find_elements_by_class_name("post-card.card")

        # use the 1st post since it is the post we have just written
        firstPost = listOfPosts[0]
        # click post options
        postOptionButton = firstPost.find_element_by_class_name(
            "post-dropdown")
        postOptionButton.click()
        # get a list of post options
        postOptionsList = firstPost.find_elements_by_class_name(
            "dropdown-item")
        # there are many dropdown items with the same class name in the same page. So have to find the right one we wants to click
        # to delete the post we have just created
        for i in range(len(postOptionsList)):
            if "Delete post" in postOptionsList[i].text:
                postOptionsList[i].click()
                break

        # to click the confirm delete button when being prompted before delete
        self.driver.implicitly_wait(7)
        confirmDeleteButton = self.driver.find_element_by_class_name(
            "btn.btn-danger")
        confirmDeleteButton.click()

        # delay 5 sec to let page update to load the new post into the page
        time.sleep(3)
        # get the list of posts after deleting a post
        newListOfPosts = self.driver.find_elements_by_class_name(
            "post-card.card")
        # check if the number of posts in the thread should be reduced by 1 means successfully deleted that post
        self.assertEqual(len(listOfPosts) - 1, len(newListOfPosts))
 def test_deleteAnyThread_user(self):
     username = Automate.login(self.driver, False)
     threads = self.driver.find_elements_by_class_name("thread-card.card")
     for thread in threads:
         if thread.find_elements_by_class_name("data")[3].text != username:
             thread.find_element_by_class_name("thread-dropdown").click()
             options = thread.find_elements_by_class_name("dropdown-item")
             optionFound = False
             for option in options:
                 print("option:", option.text)
                 self.assertNotIn("Delete thread", option.text)
                 optionFound = True
                 break
             if optionFound:
                 break
    def editOwnPost(self):
        Automate.navigateToSelectiveThread(self.driver, 4)
        Automate.writeAPost(self.driver, "Testing testing")

        # use the 1st post since it is the post we have just written
        firstPost = self.driver.find_elements_by_class_name(
            "post-card.card")[0]
        # click post options then click the edit button on the latest post we created for this test
        postOptionButton = firstPost.find_element_by_class_name(
            "post-dropdown")
        postOptionButton.click()
        # get a list of post options then search for the "Edit" option
        postOptionsList = firstPost.find_elements_by_class_name(
            "dropdown-item")
        for i in range(len(postOptionsList)):
            if postOptionsList[i].text == "Edit":
                postOptionsList[i].click()
                break

        # write post content and click the post button to post
        newEditedPostContent = "Hello!"
        postEditTxtBox = firstPost.find_element_by_class_name("form-control")
        # clear post's content
        postEditTxtBox.clear()
        postEditTxtBox.send_keys(newEditedPostContent)
        # cause have 2 button of the same class name in the same page as one is for the create new post an another is save edited post
        postButton = firstPost.find_element_by_class_name("btn.btn-info")
        postButton.click()

        # delay 5 sec to let page update the new post's content before comparing the content
        time.sleep(5)
        # see if the post is successfully edited
        firstPostText = firstPost.find_element_by_class_name("card-text")
        self.assertEqual(firstPostText.text, newEditedPostContent)
        # see if the edited post reflect it has been edited
        firstPost.find_element_by_class_name("edited")
 def test_deleteOwnThread(self):
     username = Automate.login(self.driver, False)
     threads = self.driver.find_elements_by_class_name("thread-card.card")
     threadCount = len(threads)
     for thread in threads:
         if thread.find_elements_by_class_name("data")[3].text == username:
             thread.find_element_by_class_name("thread-dropdown").click()
             thread.find_elements_by_class_name("dropdown-item")[1].click()
             self.driver.find_element_by_class_name(
                 "btn.btn-danger").click()
             break
     time.sleep(5)
     # Check that total threads decremented by 1
     newThreadCount = len(
         self.driver.find_elements_by_class_name("thread-card.card"))
     self.assertEqual(threadCount - 1, newThreadCount)
    def test_reportThread(self):
        username = Automate.login(self.driver, False)
        for thread in self.driver.find_elements_by_class_name(
                "thread-card.card"):
            optionFound = False
            if thread.find_elements_by_class_name("data")[3].text != username:
                # time.sleep(1)
                thread.find_element_by_class_name("thread-dropdown").click()
                try:
                    options = thread.find_element_by_class_name(
                        "dropdown-menu.show").find_elements_by_class_name(
                            "dropdown-item")
                    for option in options:
                        print(option.text)
                        if "Report thread" in option.text:
                            threadDetails = Automate.getThreadDetails(thread)
                            option.click()
                            optionFound = True
                            break
                except selenium.common.exceptions.NoSuchElementException:
                    continue

            if optionFound:
                break
        self.driver.find_element_by_class_name("custom-control-label").click()
        self.driver.find_element_by_class_name("btn.btn-danger").click()

        # view thread to get thread url
        time.sleep(3)
        thread.click()
        threadUrl = self.driver.current_url
        # Logout
        Automate.logout(self.driver)
        # Login with Moderator account to access Control Panel
        Automate.login(self.driver, True)
        self.driver.find_element_by_class_name("dropdown.nav-item").click()
        self.driver.find_element_by_class_name("dropdown-item").click()
        # Check that reported thread is recorded in Control Panel
        for report in self.driver.find_elements_by_class_name(
                "report-card.card"):
            user_reported = report.find_element_by_class_name("data").text
            title_reported = report.find_element_by_class_name(
                "card-title").text
            if user_reported == threadDetails[
                    "user"] and title_reported == threadDetails["title"]:
                report.click()
                break
        threadUrl_reported = self.driver.current_url
        self.assertEqual(threadUrl, threadUrl_reported)
 def test_postWithoutContent_mod(self):
     Automate.login(self.driver, True)
     self.postWithoutContent()
 def test_postWithoutContent_user(self):
     Automate.login(self.driver, False)
     self.postWithoutContent()
 def test_ableToWriteOrUploadPicInPost_mod(self):
     Automate.login(self.driver, True)
     self.ableToWriteOrUploadPicInPost()
 def test_ableToWriteOrUploadPicInPost_user(self):
     Automate.login(self.driver, False)
     self.ableToWriteOrUploadPicInPost()
Exemple #22
0
from Automate import *

if __name__ == '__main__':
    input = ""
    while input != "O":
        automate = Automate()
        try:
            print(automate)
            print("==determinisation et completion==")
            automate.determinisation_et_completion_synchrone()
            print(automate)
            print("==minimisation==")
            automate.minimisation()
            print(automate)
            print("==complémentarisation==")
            automate.automate_complementaire()
        except:
            print(f"Erreur sur le fichier {automate.filename}")
        input = askstring_or_tk("Voulez vous arrêtez ? (O)ui (*)Non")
 def test_editOwnPost_mod(self):
     Automate.login(self.driver, True)
     self.editOwnPost()
    def deleteAnyPost(self, isMod):
        if isMod:
            # log in mod account to post at the 1st thread
            Automate.login(self.driver, False)
        else:
            # log in mod account to post at the 1st thread
            Automate.login(self.driver, True)

        # navigate to first thread and create a post
        Automate.navigateToSelectiveThread(self.driver, 0)
        Automate.writeAPost(self.driver, "AAA")

        if isMod:
            # user account do not have control panel so logout button is 1st option in the list
            Automate.logout(self.driver)
            # login moderator account to test if it can edit other people's (for this case is the user's) post at the 1st thread
            Automate.login(self.driver, True)
        else:
            # moderator account have control panel as the 1st option of the list while logout button is 2nd option in the list
            Automate.logout(self.driver)
            # login user account to test if it can edit other people's (for this case is the mod's) post at the 1st thread
            Automate.login(self.driver, False)

        # navigate to first thread
        Automate.navigateToSelectiveThread(self.driver, 0)

        # get the list of posts
        listOfPosts = self.driver.find_elements_by_class_name("post-card.card")

        # use the 1st post since it is the post we have just written
        firstPost = listOfPosts[0]
        # click post options then click the edit button on the latest post we created for this test
        postOptionButton = firstPost.find_element_by_class_name(
            "post-dropdown")
        postOptionButton.click()
        # get a list of post options then search for the "Edit" option
        postOptionsList = firstPost.find_elements_by_class_name(
            "dropdown-item")

        if isMod:
            for i in range(len(postOptionsList)):
                if "Delete post" in postOptionsList[i].text:
                    postOptionsList[i].click()
                    break

            # to click the confirm delete button when being prompted before delete
            self.driver.implicitly_wait(7)
            confirmDeleteButton = self.driver.find_element_by_class_name(
                "btn.btn-danger")
            confirmDeleteButton.click()

            # delay 5 sec to let page update to load the new post into the page
            time.sleep(3)
            # get the list of posts after deleting a post
            newListOfPosts = self.driver.find_elements_by_class_name(
                "post-card.card")
            # check if the number of posts in the thread should be reduced by 1 means successfully deleted that post
            self.assertEqual(len(listOfPosts) - 1, len(newListOfPosts))

        else:
            # user cannot edit other people's post. If have means fail test case. So iterate the list of options to find if have "Edit"
            for i in range(len(postOptionsList)):
                self.assertNotEqual(postOptionsList, "Delete post")
 def test_deleteOwnPost_mod(self):
     Automate.login(self.driver, True)
     self.deleteOwnPost()
 def test_deleteOwnPost_user(self):
     Automate.login(self.driver, False)
     self.deleteOwnPost()
    def editAnyPost(self, isMod):
        if isMod:
            # log in mod account to post at the 1st thread
            Automate.login(self.driver, False)
        else:
            # log in mod account to post at the 1st thread
            Automate.login(self.driver, True)

        # navigate to first thread and create a post
        Automate.navigateToSelectiveThread(self.driver, 0)
        Automate.writeAPost(self.driver, "AAA")

        if isMod:
            # user account do not have control panel so logout button is 1st option in the list
            Automate.logout(self.driver)
            # login moderator account to test if it can edit other people's (for this case is the user's) post at the 1st thread
            Automate.login(self.driver, True)
        else:
            # moderator account have control panel as the 1st option of the list while logout button is 2nd option in the list
            Automate.logout(self.driver)
            # login user account to test if it can edit other people's (for this case is the mod's) post at the 1st thread
            Automate.login(self.driver, False)

        # navigate to first thread
        Automate.navigateToSelectiveThread(self.driver, 0)

        # use the 1st post since it is the post we have just written
        firstPost = self.driver.find_elements_by_class_name(
            "post-card.card")[0]
        # click post options then click the edit button on the latest post we created for this test
        postOptionButton = firstPost.find_element_by_class_name(
            "post-dropdown")
        postOptionButton.click()
        # get a list of post options then search for the "Edit" option
        postOptionsList = firstPost.find_elements_by_class_name(
            "dropdown-item")

        if isMod:
            for i in range(len(postOptionsList)):
                if postOptionsList[i].text == "Edit":
                    postOptionsList[i].click()
                    break

            # write post content and click the post button to post
            newEditedPostContent = "Hello!"
            postEditTxtBox = firstPost.find_element_by_class_name(
                "form-control")
            # clear post's content
            postEditTxtBox.clear()
            postEditTxtBox.send_keys(newEditedPostContent)
            # cause have 2 button of the same class name in the same page as one is for the create new post an another is save edited post
            postButton = firstPost.find_element_by_class_name("btn.btn-info")
            postButton.click()

            # delay 5 sec to let page update the new post's content before comparing the content
            time.sleep(5)
            # see if the post is successfully edited
            firstPostText = firstPost.find_element_by_class_name("card-text")
            self.assertEqual(firstPostText.text, newEditedPostContent)
            # see if the edited post reflect it has been edited
            firstPost.find_element_by_class_name("edited")

        else:
            # user cannot edit other people's post. If have means fail test case. So iterate the list of options to find if have "Edit"
            for i in range(len(postOptionsList)):
                self.assertNotEqual(postOptionsList, "Edit")
import Automate

Automate.init_gpio(0)

Automate.turn_right(1)

Automate.turn_left(1)
 def test_editOwnPost_user(self):
     Automate.login(self.driver, False)
     self.editOwnPost()
    def downvoteOnce(self, isMod):
        if isMod:
            # log in mod account to post at the 1st thread
            Automate.login(self.driver, False)
        else:
            # log in mod account to post at the 1st thread
            Automate.login(self.driver, True)

        # navigate to first thread and create a post
        Automate.navigateToSelectiveThread(self.driver, 0)
        Automate.writeAPost(self.driver, "AAA")

        if isMod:
            # user account do not have control panel so logout button is 1st option in the list
            Automate.logout(self.driver)
            # login moderator account to test if it can edit other people's (for this case is the user's) post at the 1st thread
            Automate.login(self.driver, True)
        else:
            # moderator account have control panel as the 1st option of the list while logout button is 2nd option in the list
            Automate.logout(self.driver)
            # login user account to test if it can edit other people's (for this case is the mod's) post at the 1st thread
            Automate.login(self.driver, False)

        # navigate to first thread
        Automate.navigateToSelectiveThread(self.driver, 0)

        # use the 1st post since it is the post we have just written
        firstPost = self.driver.find_elements_by_class_name(
            "post-card.card")[0]

        # get the original number of votes
        voteSection = firstPost.find_element_by_class_name("votes-section")
        orignNumOfVotes = int(voteSection.text)
        # search for the upvote button and click on it
        upVoteButton = voteSection.find_element_by_class_name(
            "vote-icon.downvote-icon")
        upVoteButton.click()
        # need time for the vote change to be reflected
        time.sleep(5)
        # check if the vote increases by one
        voteSection = firstPost.find_element_by_class_name("votes-section")
        self.assertEqual(orignNumOfVotes - 1, int(voteSection.text))
        upVoteButton.click()
        # need time for the vote change to be reflected
        time.sleep(5)
        voteSection = firstPost.find_element_by_class_name("votes-section")
        self.assertEqual(orignNumOfVotes, int(voteSection.text))
import Automate
import time
Automate.init_gpio(0)

Automate.move_forward(50)
time.sleep(3)

Automate.turn_right(1)
time.sleep(3)

Automate.move_forward(50)
time.sleep(3)

Automate.turn_right(1)
time.sleep(3)

Automate.move_forward(50)
time.sleep(3)

Automate.turn_right(1)
time.sleep(3)

Automate.move_forward(50)
time.sleep(3)

Automate.turn_right(1)
time.sleep(3)


    def reportThread(self, isMod):
        # content to write to a post
        contentToWrite = "AAA"

        if isMod:
            # log in mod account to post at the 1st thread
            Automate.login(self.driver, False)
        else:
            # log in mod account to post at the 1st thread
            Automate.login(self.driver, True)

        # navigate to first thread and create a post
        Automate.navigateToSelectiveThread(self.driver, 0)
        Automate.writeAPost(self.driver, contentToWrite)

        if isMod:
            # user account do not have control panel so logout button is 1st option in the list
            Automate.logout(self.driver)
            # login moderator account to test if it can report other people's (for this case is the user's) post at the 1st thread
            reporterUsername = Automate.login(self.driver, True)
        else:
            # moderator account have control panel as the 1st option of the list while logout button is 2nd option in the list
            Automate.logout(self.driver)
            # login user account to test if it can report other people's (for this case is the mod's) post at the 1st thread
            reporterUsername = Automate.login(self.driver, False)

        # navigate to first thread
        Automate.navigateToSelectiveThread(self.driver, 0)

        # use the 1st post since it is the post we have just written
        firstPost = self.driver.find_elements_by_class_name(
            "post-card.card")[0]
        # click post options
        postOptionButton = firstPost.find_element_by_class_name(
            "post-dropdown")
        postOptionButton.click()
        # get a list of post options
        postOptionsList = firstPost.find_elements_by_class_name(
            "dropdown-item")
        # there are many dropdown items with the same class name in the same page. So have to find the right one we wants to click
        # to report the post we have just created
        for i in range(len(postOptionsList)):
            if "Report post" in postOptionsList[i].text:
                postOptionsList[i].click()
                break

        # to confirm reporting the post and reason for reporting
        self.driver.find_element_by_class_name("custom-control-label").click()
        self.driver.find_element_by_class_name("btn.btn-danger").click()

        # takes time for the page to load after reporting
        time.sleep(3)

        # get the URL for the thread the post is in
        threadUrl = self.driver.current_url

        # login moderator account if is user account testing if reporting works
        if not isMod:
            # Logout
            Automate.logout(self.driver)
            # Login with Moderator account to access Control Panel
            Automate.login(self.driver, True)

        accountMenuOptions = self.driver.find_element_by_class_name(
            "dropdown.nav-item")
        accountMenuOptions.click()
        # get a list of options
        userOptionsList = accountMenuOptions.find_elements_by_class_name(
            "dropdown-item")
        # iterate the list of options to find the Control Panel option and click on it to access it
        for i in range(len(userOptionsList)):
            if "Control Panel" in userOptionsList[i].text:
                userOptionsList[i].click()
                break

        time.sleep(1)
        # Check that reported thread is recorded in Control Panel
        # click on the "Reported posts" tab button
        reportedPostsTabButton = self.driver.find_elements_by_xpath(
            "//a[@class='nav-link']")[0]
        reportedPostsTabButton.click()

        time.sleep(1)
        reportedPostsTab = self.driver.find_element_by_class_name(
            "tab-pane.active")
        # get a list of reported posts
        reportedPostList = reportedPostsTab.find_elements_by_class_name(
            "report-card.card")

        for i in range(len(reportedPostList)):
            user_reported = reportedPostList[i].find_element_by_class_name(
                "data").text
            postContent = reportedPostList[i].find_element_by_class_name(
                "card-title").text

            if user_reported == reporterUsername and postContent == contentToWrite:
                reportedPostList[i].click()
                time.sleep(3)

                try:
                    # check if is the same post based on the thread the post is in cause can have the same user and post content but in different threads
                    self.assertEqual(threadUrl, self.driver.current_url)
                    return
                # driver with same name and title will be removed
                except AssertionError:
                    self.driver.back()
                    # click on the "Reported posts" tab button cause pressed back then it's default at "Reported threads" page and DOM will stale
                    reportedPostsTabButton = self.driver.find_elements_by_xpath(
                        "//a[@class='nav-link']")[0]
                    reportedPostsTabButton.click()
                    # let it have time to load
                    time.sleep(1)
                    reportedPostsTab = self.driver.find_element_by_class_name(
                        "tab-pane.active")
                    # get a list of reported posts since DOM will be stale so need get the new DOM object
                    reportedPostList = reportedPostsTab.find_elements_by_class_name(
                        "report-card.card")

        # throws assertion exception since reported post not found in list of reported posts in the control panel
        raise AssertionError()