diff --git a/Project insights and readme.pdf b/Project insights and readme.pdf new file mode 100644 index 0000000..ecae4dc Binary files /dev/null and b/Project insights and readme.pdf differ diff --git a/libs/Base.py b/libs/Base.py new file mode 100644 index 0000000..260261b --- /dev/null +++ b/libs/Base.py @@ -0,0 +1,56 @@ +from playwright.sync_api import sync_playwright + +from vars import configs + + +class Base: + browser = None + context = None + page = None + pwSync = None + + @staticmethod + def launch_browser(browser_name=configs.browser_name, + record_video=configs.record_video, + headless=configs.headless, + slowmo=configs.slowmo): + print("Opening Browser : " + browser_name) + + Base.pwSync = sync_playwright().start() # creating sync obj + if browser_name.lower() == 'chromium': + Base.browser = Base.pwSync.chromium.launch(headless=headless, slow_mo=slowmo) + elif browser_name.lower() == 'firefox': + Base.browser = Base.pwSync.firefox.launch(headless=headless, slow_mo=slowmo) + else: + Base.browser = Base.pwSync.webkit.launch(headless=headless, slow_mo=slowmo) + if record_video: + Base.context = Base.browser.new_context( + viewport={"width": 1375, "height": 885}, + record_video_dir="../reports/Videos/", + record_video_size={"width": 640, "height": 480} + ) + else: + Base.context = Base.browser.new_context() + + @staticmethod + def open_application(url=configs.base_url): + Base.page = Base.context.new_page() + Base.page.goto(url) + + @staticmethod + def get_page_object(): + return Base.page + + @staticmethod + def take_screenshot(): + return Base.page.screenshot(path="Reports/screenshot.png") + + @staticmethod + def close_application(): + Base.page.close() + + @staticmethod + def close_browser(): + Base.context.close() + Base.browser.close() + Base.pwSync.stop() diff --git a/libs/__init__.py b/libs/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pages/QuestionPage.py b/pages/QuestionPage.py new file mode 100644 index 0000000..c0f6d69 --- /dev/null +++ b/pages/QuestionPage.py @@ -0,0 +1,123 @@ +from faker import Faker +from playwright.sync_api import expect + +from libs.Base import Base + + +class QuestionPage(Base): + def __init__(self): + self.sidebar_locator = 'div.sidebar' + self.question_count = 1 + self.remove_questions_button_selector = 'button:has-text("Remove questions")' + self.sort_button_selector = 'button.btn-primary:has-text("Sort questions")' + self.deleted_questions_alert_message = 'No questions yet :-(' + self.deleted_questions_alert = f'div.alert.alert-danger' + self.question_input_selector = '#question' + self.answer_input_selector = '#answer' + self.create_question_button_selector = 'button:has-text("Create question")' + self.questions_selector = 'li.list-group-item.question' + self.header = 'header.header' + self.questions_title = 'h2.tooltipped-title__title' + self.answers_title = '.tooltipped-title__tooltip' + + def check_sidebar_text(self): + count = self.question_count + if self.question_count == 0: + sidebar_text = f'Here you can find no questions. Feel free to create your own questions!' + elif self.question_count == 1: + sidebar_text = f'Here you can find 1 question. Feel free to create your own questions!' + else: + sidebar_text = f'Here you can find {count} questions. Feel free to create your own questions!' + expect(self.page.locator(self.sidebar_locator)).to_contain_text([sidebar_text]) + + def remove_questions(self): + self.page.locator(self.remove_questions_button_selector).click() + self.question_count = 0 + + def check_questions_removed(self): + expect(self.page.locator(self.deleted_questions_alert)).to_have_text(self.deleted_questions_alert_message) + self.check_sidebar_text() + + def fill_question(self, question: str): + expect(self.page.locator(self.question_input_selector)).to_have_attribute("required", "") + self.page.locator(self.question_input_selector).fill(question) + + def fill_answer(self, answer: str): + expect(self.page.locator(self.question_input_selector)).to_have_attribute("required", "") + self.page.locator(self.answer_input_selector).fill(answer) + + def add_question(self, success: bool = True): + self.page.locator(self.create_question_button_selector).click() + if success: + self.question_count += 1 + + def check_questions_count(self): + count = self.question_count + expect(self.page.locator(self.questions_selector)).to_have_count(count) + + def create_question_and_answer(self, count): + fake = Faker() + for i in range(count): + self.fill_question(fake.text()) + self.fill_answer(fake.text()) + self.add_question() + + def sort_questions(self): + self.page.locator(self.sort_button_selector).click() + + def check_question_order(self, index, question): + expect(self.page.locator(self.questions_selector).nth(index).locator('.question__question')).to_have_text( + question) + + def check_answer(self, index, answer): + locator = self.page.locator(self.questions_selector).nth(index) + self.check_answer_visibility(index=index, visible=False) + self.click_on_question(index) + self.check_answer_visibility(index=index, visible=True) + expect(locator.locator('.question__answer')).to_have_text(answer) + + def check_answer_visibility(self, index, visible=True): + locator = self.page.locator(self.questions_selector).nth(index).locator('.question__answer') + if visible: + expect(locator).to_be_visible() + else: + expect(locator).to_be_hidden() + + def click_on_question(self, index): + self.page.locator(self.questions_selector).nth(index).locator('.question__question').click() + + def clear_fields(self, question: bool = True, answer: bool = True): + if question: + self.page.locator(self.question_input_selector).select_text() + self.page.keyboard.press("Backspace") + if answer: + self.page.locator(self.question_input_selector).select_text() + self.page.keyboard.press("Backspace") + + def check_static_texts(self): + question_locator = self.page.locator('.questions') + question_maker_locator = self.page.locator('.question-maker') + + expect(self.page.locator(self.header).locator('h1')).to_have_text('The awesome Q/A tool') + + expect(question_locator.locator(self.questions_title)).to_have_text('Created questions') + expect(question_locator.locator(self.answers_title)).to_be_hidden() + question_locator.locator(self.questions_title).hover() + expect(question_locator.locator(self.answers_title)).to_be_visible() + expect(question_locator.locator(self.answers_title)).to_have_text( + 'Here you can find the created questions and their answers.') + + expect(question_maker_locator.locator(self.questions_title)).to_have_text('Create a new question') + expect(question_maker_locator.locator(self.answers_title)).to_be_hidden() + question_maker_locator.locator(self.questions_title).hover() + expect(question_maker_locator.locator(self.answers_title)).to_be_visible() + expect(question_maker_locator.locator(self.answers_title)).to_have_text( + 'Here you can create new questions and their answers.') + + def check_buttons_removed(self,exist:bool= False): + if exist: + expect(self.page.locator(self.remove_questions_button_selector)).to_have_count(1) + expect(self.page.locator(self.sort_button_selector)).to_have_count(1) + else: + expect(self.page.locator(self.remove_questions_button_selector)).to_have_count(0) + expect(self.page.locator(self.sort_button_selector)).to_have_count(0) \ No newline at end of file diff --git a/pages/__init__.py b/pages/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..28d113e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +Faker==15.1.1 +playwright==1.27.1 +robotframework==6.0 +robotframework-pabot==2.8.0 diff --git a/tests/question_page.robot b/tests/question_page.robot new file mode 100644 index 0000000..93633fc --- /dev/null +++ b/tests/question_page.robot @@ -0,0 +1,131 @@ +*** Settings *** +Library pages/QuestionPage.py +Force Tags studocu +Test Setup setup +Test Teardown Tear Down + +*** Keywords *** +setup + Launch Browser + Open Application + + +tear down + Close Application + Close Browser + + +*** Test Cases *** +check sidebar text with one, two and no questions + [Tags] sidebar questions + Check Questions Count + Check Sidebar Text + Create Question And Answer count=${2} + Check Questions Count + Check Sidebar Text + Remove Questions + Check Questions Count + Check Sidebar Text + +check sort functionality with questions that start with integer + [Tags] sort questions answers + remove questions + Fill Question question=11-question + Fill Answer answer=11-answer + add_question + Fill Question question=5-question + Fill Answer answer=5-answer + add_question + Fill Question question=1-question + Fill Answer answer=1-answer + add_question + Check Question Order index=0 question=11-question + Check Question Order index=1 question=5-question + Check Question Order index=2 question=1-question + Sort Questions + Check Question Order index=0 question=1-question + Check Question Order index=1 question=5-question + Check Question Order index=2 question=11-question + +check answer visibility before after sort with two questions open + [Tags] visibility sort answers questions + + Fill Question question=1-question + Fill Answer answer=1-answer + add_question + Check Answer index=1 answer=1-answer + Click On Question index=0 + Sort Questions + Check Answer Visibility index=0 visible=${True} + Check Answer Visibility index=1 visible=${True} + +check answer visibility after sort with one question open + [Tags] visibility answers + Fill Question question=2-question + Fill Answer answer=2-answer + add question + Fill Question question=1-question + Fill Answer answer=1-answer + add question + Click On Question index=0 + Check Answer Visibility index=0 + Sort Questions + Check Answer Visibility index=0 visible=${False} + Check Answer Visibility index=2 visible=${True} + +check sort functionality with string questions + [Tags] sort + Fill Question question=a-question + Fill Answer answer=a-answer + add question + Fill Question question=c-question + Fill Answer answer=c-answer + add question + Fill Question question=b-question + Fill Answer answer=b-answer + add question + Sort Questions + Check Question Order index=1 question=b-question + +check required fields + [Tags] required + add question success=${False} + Check Questions Count + Check Sidebar Text + Fill Question question=a-question + add question success=${False} + Check Questions Count + Check Sidebar Text + Clear Fields + Fill Answer answer=a-answer + add question success=${False} + Check Questions Count + Check Sidebar Text + +check remove button + [Tags] questions + remove questions + check questions_removed + Check Questions Count + check sidebar text + +check questions with whitespace + [Tags] required questions + Fill Question question=${SPACE} + Fill Answer answer=${SPACE} + add question + Click On Question index=1 + Check Answer Visibility index=1 visible=${True} + +check static texts + [Tags] texts + Check Static Texts + Check Question Order index=0 question=How to add a question? + Check Answer index=0 answer=Just use the form below! + +check buttons removed + [Tags] sort + Remove Questions + Check Buttons Removed + Create Question And Answer count=${1} + Check Buttons Removed exist=${True} \ No newline at end of file diff --git a/vars/configs.py b/vars/configs.py new file mode 100644 index 0000000..eaa991f --- /dev/null +++ b/vars/configs.py @@ -0,0 +1,20 @@ +import os + +from robot.libraries.BuiltIn import BuiltIn + +bi = BuiltIn() +base_url = os.environ.get('PROJECT_BASE_URL', '127.0.0.1:8000') +browser_name = os.environ.get('BROWSER_NAME', 'chromium') +record_video = os.environ.get('RECORD_VIDEO', False) +slowmo = os.environ.get('SLOWMO', None) +headless = os.environ.get('HEADLESS', True) + +try: + base_url = bi.get_variable_value('${base_url}', base_url) + browser_name = bi.get_variable_value('${browser_name}', browser_name) + record_video = bi.get_variable_value('${record_video}', record_video) + slowmo = bi.get_variable_value('${slowmo}', slowmo) + headless = bi.get_variable_value('${headless}', headless) + +except Exception as e: + bi.log_to_console(str(e))