def open_and_switch_to_new_tab(self):
        """
        Execute javascript to open new tab and then switch to the new tab
        """
        try:
            self.browser.execute_script("window.open('');")
            sleep(1)
            self.browser.switch_to.window(self.browser.window_handles[1])
            console_print('success', '[New tab opened!]')
        except JavascriptException as error:
            console_print('failed', '[New tab open failed!]')
            console_print('failed', str(error))
            self.browser.quit()

            raise
    def visit_login_page(self):
        """
        Visit the web application's given login url
        :return: bool
        """
        try:
            self.browser.get(self.url)
            console_print('success', '[Login page OK!]')
            sleep(2)
        except TimeoutException as error:
            console_print('failed', '[Login page not OK!]')
            console_print('failed', str(error))
            self.browser.quit()

            raise
    def logout(self, menu: str, logout_link: str):
        """
        Logout from dashboard
        :param menu: Upper right menu in dashboard
        :param logout_link: logout link
        """
        try:
            self.browser.find_element_by_xpath(menu).click()
            self.browser.find_element_by_xpath(logout_link).click()
            console_print('success', '[Logout successful!]') if \
                self.browser.current_url == self.url else \
                console_print('failed', '[Logout failed!]')
        except (ElementNotInteractableException,
                NoSuchElementException) as error:
            console_print('failed', '[Logout failed!]')
            console_print('failed', str(error))
            self.browser.quit()
            print()

            raise
    def check_registration_validation_message(self, username: str, email: str,
                                              password: str,
                                              confirm_password: str,
                                              phone: str,
                                              error_messages: list) -> bool:
        """
        Attempt a failed registration and then will check the validation
        messages is in our predefined expected list
        :param username: will be empty
        :param email: will be empty or invalid email
        :param password: invalid password will be given
        :param confirm_password: password and confirm password will not be same
        :param phone: might be empty for this particular test
        :param error_messages: predefined expected validation messages
        :return: True / False according to the test
        """
        try:
            self._browser.refresh()
            sleep(1)
            self.register(username, email, password, confirm_password, phone)
            sleep(2)
            validation_message_ul = self._browser.find_element_by_xpath(
                self.registration_x_paths['error_message_box'])
            validation_messages_li = validation_message_ul. \
                find_elements_by_tag_name('li')
            validation_messages = []
            for li in validation_messages_li:
                validation_messages.append(li.text)
            print(validation_messages)
            for message in validation_messages:
                if message not in error_messages:
                    console_print('failed',
                                  '[Validation message didnt match!]')
                    print(message)
                    return False
            console_print('success', '[All validation message matched!]')

            return True
        except (ElementNotInteractableException,
                NoSuchElementException) as error:
            console_print('failed', str(error))
            self._browser.quit()

            return False
    def set_description(self, description: str):
        """
        Set description
        :param description: category description
        """
        try:
            description_field = self.browser.find_element_by_xpath(
                CATEGORY_FORM_X_PATHS['description'])
            description_field.send_keys(description)
            console_print('success', '[Serial has been set]')
            self.assertTrue(True)

        except (ElementNotInteractableException,
                NoSuchElementException) as error:
            console_print('failed', str(error))
            console_print('failed', str(error))
            self.close_browser()

            raise
    def error_validation_message_is_ok(self):
        """
        Check all error validation message by giving empty string to all fields
        """
        try:
            for message_x_path in ERROR_VALIDATION_MESSAGE_X_PATHS:
                message = self.browser.find_element_by_xpath(
                    ERROR_VALIDATION_MESSAGE_X_PATHS[message_x_path]).text
                if message not in ERROR_VALIDATION_MESSAGES:
                    console_print(
                        'failed', '[' + message_x_path +
                        'validation message didnt match!]')
                    print(message)
                else:
                    console_print('success',
                                  '[All validation message matched!]')
        except (ElementNotInteractableException,
                NoSuchElementException) as error:
            console_print('failed', str(error))

            raise
    def registration_with_invalid_email(self, username: str, email: str,
                                        password: str, confirm_password: str,
                                        phone: str, invalid_email_message):
        """
        This method will try to register with a given invalid email where
        other information will be valid. And we will check the HTML validation
        message is shown or not. We will return True if it does otherwise, we
        will return False.
        :param username:
        :param email:
        :param password:
        :param confirm_password:
        :param phone:
        :param invalid_email_message:
        :return:
        """
        try:
            self._browser.refresh()
            self.register(username, email, password, confirm_password, phone)
            sleep(1)
            email_validation_message = self._browser.find_element_by_xpath(
                self.registration_x_paths['email_field']) \
                .get_attribute('validationMessage')
            sleep(1)
            print(email_validation_message)
            if email_validation_message != invalid_email_message:
                console_print(
                    'failed', '[Invalid email validation message '
                    'didnt match!]')
                return False
            console_print('success', '[Invalid email validation message '
                          'matched!]')

            return True
        except (ElementNotInteractableException,
                NoSuchElementException) as error:
            console_print('failed', str(error))
            self._browser.quit()

            return False
    def duplicate_category_creation(self, form_data):
        """
        Submit form with a duplicate category name
        :param form_data:
        """
        try:
            self.create(form_data)
            message = self.browser.find_element_by_xpath(
                DUPLICATE_NAME_VALIDATION_MESSAGE_X_PATH)
            if message not in ERROR_VALIDATION_MESSAGES:
                console_print(
                    'success', '[Duplicate name '
                    'validation message didnt match!]')
            else:
                console_print(
                    'failed', '[Duplicate name '
                    'validation message matched!]')
        except (ElementNotInteractableException,
                NoSuchElementException) as error:
            console_print('failed', str(error))

            raise
    def success_validation_message_is_ok(self, message):
        """
        Check the validation message of a successful category creation
        :param message: success validation message
        """
        try:
            message_box = self.browser.find_element_by_xpath(
                SUCCESS_VALIDATION_BOX_XPATH)
            inner_text = message_box.text
            clean_text = inner_text.replace('x', '')
            print(len(clean_text.strip()))
            print(len(message.strip()))
            if clean_text.strip() == message.strip():
                console_print('success',
                              '[Success validation message matched]')
                self.assertTrue(True)
            else:
                console_print('failed', '[Success validation didnt'
                              ' message match]')
        except (ElementNotInteractableException, NoSuchElementException,
                JavascriptException) as error:
            console_print('failed', str(error))

            raise