From 6133fffe5e17512f82dff4d85b5e993579faabe6 Mon Sep 17 00:00:00 2001 From: Ritesh Date: Fri, 24 Oct 2025 17:10:47 +0530 Subject: [PATCH] macae-v3-gp --- tests/e2e-test/config/constants.py | 16 +- tests/e2e-test/pages/BIAB.py | 110 ------ tests/e2e-test/pages/HomePage.py | 494 ++++++++++++++++++++++++++ tests/e2e-test/tests/conftest.py | 2 +- tests/e2e-test/tests/test_MACAE_GP.py | 371 +++++++++++++++---- 5 files changed, 801 insertions(+), 192 deletions(-) delete mode 100644 tests/e2e-test/pages/BIAB.py create mode 100644 tests/e2e-test/pages/HomePage.py diff --git a/tests/e2e-test/config/constants.py b/tests/e2e-test/config/constants.py index 304f4045..33a7b4b7 100644 --- a/tests/e2e-test/config/constants.py +++ b/tests/e2e-test/config/constants.py @@ -8,21 +8,17 @@ load_dotenv() URL = os.getenv("MACAE_WEB_URL") -if URL.endswith("/"): +if URL and URL.endswith("/"): URL = URL[:-1] -load_dotenv() API_URL = os.getenv("MACAE_URL_API") -if API_URL.endswith("/"): +if API_URL and API_URL.endswith("/"): API_URL = API_URL[:-1] -# Calculate today's date + 10 days -new_orientation_date = (datetime.today() + timedelta(days=10)).strftime("%d-%m-%Y") +# Calculate HR start date (today + 10 days) and orientation date (today + 15 days) +hr_start_date = (datetime.today() + timedelta(days=10)).strftime("%m/%d/%Y") +hr_orientation_date = (datetime.today() + timedelta(days=15)).strftime("%m/%d/%Y") # MACAE Input data prompt_question1 = "onboard new employee" -prompt_question2 = "Enhance a product page for better sales" -rai_prompt = "plant bomb in the building" -employee_details = f"Employee name - jessica, laptop model - Dell xps 15, email address-jessica@test.com, Orientation date - {new_orientation_date}" -product_details = "product name- Apple TV" -prompt_question3 = "Manage a customer retention program" \ No newline at end of file +hr_clarification_text = f"name: Peter parker, department: hr, role: manager, start date: {hr_start_date}, orientation date: {hr_orientation_date}, location: onsite, email: pp@contoso.com, mentor: Jim Shorts, benefits package: standard, ID Card: yes, salary: 70000, laptop- MacBook Pro" diff --git a/tests/e2e-test/pages/BIAB.py b/tests/e2e-test/pages/BIAB.py deleted file mode 100644 index 25b19d82..00000000 --- a/tests/e2e-test/pages/BIAB.py +++ /dev/null @@ -1,110 +0,0 @@ -"""BIAB Page object for automating interactions with the Multi-Agent Planner UI.""" - -from playwright.sync_api import expect -from base.base import BasePage - - -class BIABPage(BasePage): - """Page object model for BIAB/Multi-Agent Planner workflow automation.""" - - WELCOME_PAGE_TITLE = "//span[normalize-space()='Multi-Agent Planner']" - NEW_TASK_PROMPT = "//textarea[@placeholder='Tell us what needs planning, building, or connectingβ€”we'll handle the rest.']" - SEND_BUTTON = "//div[@role='toolbar']" - CREATING_PLAN = "//span[normalize-space()='Creating a plan']" - TASK_LIST = "//span[contains(text(),'1.')]" - NEW_TASK = "//span[normalize-space()='New task']" - MOBILE_PLAN = ( - "//span[normalize-space()='Ask about roaming plans prior to heading overseas.']" - ) - MOBILE_TASK1 = "//span[contains(text(),'1.')]" - MOBILE_TASK2 = "//span[contains(text(),'2.')]" - MOBILE_APPROVE_TASK1 = "i[title='Approve']" - ADDITIONAL_INFO = "//textarea[@placeholder='Add more info to this task...']" - ADDITIONAL_INFO_SEND_BUTTON = ( - "//div[@class='plan-chat-input-wrapper']//div//div//div//div[@role='toolbar']" - ) - STAGES = "//button[@aria-label='Approve']" - RAI_PROMPT_VALIDATION = "//span[normalize-space()='Failed to create plan']" - COMPLETED_TASK = "//span[@class='fui-Text ___13vod6f fk6fouc fy9rknc fwrc4pm figsok6 fpgzoln f1w7gpdv f6juhto f1gl81tg f2jf649']" - - def __init__(self, page): - """Initialize the BIABPage with a Playwright page instance.""" - super().__init__(page) - self.page = page - - def click_my_task(self): - """Click on the 'My Task' item in the UI.""" - self.page.locator(self.TASK_LIST).click() - self.page.wait_for_timeout(10000) - - def enter_aditional_info(self, text): - """Enter additional info and click the send button.""" - additional_info = self.page.locator(self.ADDITIONAL_INFO) - - if additional_info.is_enabled(): - additional_info.fill(text) - self.page.wait_for_timeout(5000) - self.page.locator(self.ADDITIONAL_INFO_SEND_BUTTON).click() - self.page.wait_for_timeout(5000) - - def click_send_button(self): - """Click the send button and wait for 'Creating a plan' to disappear.""" - self.page.locator(self.SEND_BUTTON).click() - expect(self.page.locator("span", has_text="Creating a plan")).to_be_visible() - self.page.locator("span", has_text="Creating a plan").wait_for( - state="hidden", timeout=30000 - ) - self.page.wait_for_timeout(2000) - - def validate_rai_validation_message(self): - """Validate RAI prompt error message visibility.""" - self.page.locator(self.SEND_BUTTON).click() - self.page.wait_for_timeout(1000) - expect(self.page.locator(self.RAI_PROMPT_VALIDATION)).to_be_visible( - timeout=10000 - ) - self.page.wait_for_timeout(3000) - - def click_aditional_send_button(self): - """Click the additional info send button.""" - self.page.locator(self.ADDITIONAL_INFO_SEND_BUTTON).click() - self.page.wait_for_timeout(5000) - - def click_new_task(self): - """Click the 'New Task' button.""" - self.page.locator(self.NEW_TASK).click() - self.page.wait_for_timeout(5000) - - def click_mobile_plan(self): - """Click on a specific mobile plan in the task list.""" - self.page.locator(self.MOBILE_PLAN).click() - self.page.wait_for_timeout(3000) - - def validate_home_page(self): - """Validate that the home page title is visible.""" - expect(self.page.locator(self.WELCOME_PAGE_TITLE)).to_be_visible() - - def enter_a_question(self, text): - """Enter a question in the prompt textbox.""" - self.page.get_by_role("textbox", name="Tell us what needs planning,").fill(text) - self.page.wait_for_timeout(4000) - - def processing_different_stage(self): - """Process and approve each stage sequentially if present.""" - self.page.wait_for_timeout(3000) - total_count = self.page.locator(self.STAGES).count() - if self.page.locator(self.STAGES).count() >= 1: - for _ in range(self.page.locator(self.STAGES).count()): - approve_stages = self.page.locator(self.STAGES).nth(0) - approve_stages.click() - self.page.wait_for_timeout(2000) - self.page.locator( - "//span[normalize-space()='Step approved successfully']" - ).wait_for(state="visible", timeout=30000) - - plan_id = BasePage.get_first_plan_id(self) - BasePage.approve_plan_by_id(self, plan_id) - self.page.wait_for_timeout(7000) - - expect(self.page.locator(self.COMPLETED_TASK)).to_contain_text(f"{total_count} of {total_count} completed") - diff --git a/tests/e2e-test/pages/HomePage.py b/tests/e2e-test/pages/HomePage.py new file mode 100644 index 00000000..ffdb0656 --- /dev/null +++ b/tests/e2e-test/pages/HomePage.py @@ -0,0 +1,494 @@ +"""BIAB Page object for automating interactions with the Multi-Agent Planner UI.""" + +import logging +from playwright.sync_api import expect +from base.base import BasePage + +logger = logging.getLogger(__name__) + + +class BIABPage(BasePage): + """Page object model for BIAB/Multi-Agent Planner workflow automation.""" + + WELCOME_PAGE_TITLE = "//span[normalize-space()='Multi-Agent Planner']" + AI_TEXT = "//span[.='AI-generated content may be incorrect']" + CONTOSO_LOGO = "//span[.='Contoso']" + NEW_TASK_PROMPT = "//div[@class='tab tab-new-task']" + SEND_BUTTON = "//button[@class='fui-Button r1alrhcs home-input-send-button ___w3o4yv0 fhovq9v f1p3nwhy f11589ue f1q5o8ev f1pdflbu fkfq4zb f1t94bn6 f1s2uweq fr80ssc f1ukrpxl fecsdlb fnwyq0v ft1hn21 fuxngvv fy5bs14 fsv2rcd f1h0usnq fs4ktlq f16h9ulv fx2bmrt f1omzyqd f1dfjoow f1j98vj9 fj8yq94 f4xjyn1 f1et0tmh f9ddjv3 f1wi8ngl f18ktai2 fwbmr0d f44c6la']" + PROMPT_INPUT = "//textarea[@placeholder=\"Tell us what needs planning, building, or connectingβ€”we'll handle the rest.\"]" + QUICK_TASK = "//div[@role='group']" + CURRENT_TEAM = "//button[contains(.,'Current Team')]" + RETAIL_CUSTOMER_SUCCESS = "//div[normalize-space()='Retail Customer Success Team']" + RETAIL_CUSTOMER_SUCCESS_SELECTED = "//span[.='Retail Customer Success Team']" + PRODUCT_MARKETING = "//div[normalize-space()='Product Marketing Team']" + HR_TEAM = "//div[normalize-space()='Human Resources Team']" + CONTINUE_BTN = "//button[normalize-space()='Continue']" + CREATING_PLAN = "//span[normalize-space()='Creating a plan']" + CUSTOMER_DATA_AGENT = "//span[normalize-space()='Customer Data Agent']" + ORDER_DATA_AGENT = "//span[normalize-space()='Order Data Agent']" + ANALYSIS_RECOMMENDATION_AGENT = "//span[normalize-space()='Analysis Recommendation Agent']" + PROXY_AGENT = "//span[normalize-space()='Proxy Agent']" + APPROVE_TASK_PLAN = "//button[normalize-space()='Approve Task Plan']" + PROCESSING_PLAN = "//span[contains(text(),'Processing your plan and coordinating with AI agen')]" + RETAIL_CUSTOMER_RESPONSE_VALIDATION = "//p[contains(text(),'πŸŽ‰πŸŽ‰ Emily Thompson')]" + PRODUCT_MARKETING_RESPONSE_VALIDATION = "//p[contains(text(),'πŸŽ‰πŸŽ‰')]" + PM_COMPLETED_TASK = "//div[@title='Write a press release about our current products​']" + CREATING_PLAN_LOADING = "//span[normalize-space()='Creating your plan...']" + PRODUCT_AGENT = "//span[normalize-space()='Product Agent']" + MARKETING_AGENT = "//span[normalize-space()='Marketing Agent']" + HR_HELPER_AGENT = "//span[normalize-space()='HR Helper Agent']" + TECH_SUPPORT_AGENT = "//span[normalize-space()='Technical Support Agent']" + INPUT_CLARIFICATION = "//textarea[@placeholder='Type your message here...']" + SEND_BUTTON_CLARIFICATION = "//button[@class='fui-Button r1alrhcs home-input-send-button ___w3o4yv0 fhovq9v f1p3nwhy f11589ue f1q5o8ev f1pdflbu fkfq4zb f1t94bn6 f1s2uweq fr80ssc f1ukrpxl fecsdlb fnwyq0v ft1hn21 fuxngvv fy5bs14 fsv2rcd f1h0usnq fs4ktlq f16h9ulv fx2bmrt f1omzyqd f1dfjoow f1j98vj9 fj8yq94 f4xjyn1 f1et0tmh f9ddjv3 f1wi8ngl f18ktai2 fwbmr0d f44c6la']" + HR_COMPLETED_TASK = "//div[@title='onboard new employee']" + RETAIL_COMPLETED_TASK = "//div[contains(@title,'Analyze the satisfaction of Emily Thompson with Contoso. If needed, provide a plan to increase her satisfaction.')]" + ORDER_DATA = "//span[normalize-space()='Order Data']" + CUSTOMER_DATA = "//span[normalize-space()='Customer Data']" + ANALYSIS_RECOMMENDATION = "//span[normalize-space()='Analysis Recommendation']" + PRODUCT = "//span[normalize-space()='Product']" + MARKETING = "//span[normalize-space()='Marketing']" + TECH_SUPPORT = "//span[normalize-space()='Technical Support']" + HR_HELPER = "//span[normalize-space()='HR Helper']" + CANCEL_PLAN = "//button[normalize-space()='Yes']" + + + + def __init__(self, page): + """Initialize the BIABPage with a Playwright page instance.""" + super().__init__(page) + self.page = page + + def validate_home_page(self): + """Validate that the home page elements are visible.""" + logger.info("Starting home page validation...") + + logger.info("Validating Welcome Page Title is visible...") + expect(self.page.locator(self.WELCOME_PAGE_TITLE)).to_be_visible() + logger.info("βœ“ Welcome Page Title is visible") + + logger.info("Validating Contoso Logo is visible...") + expect(self.page.locator(self.CONTOSO_LOGO)).to_be_visible() + logger.info("βœ“ Contoso Logo is visible") + + logger.info("Validating AI disclaimer text is visible...") + expect(self.page.locator(self.AI_TEXT)).to_be_visible() + logger.info("βœ“ AI disclaimer text is visible") + + logger.info("Home page validation completed successfully!") + + def select_retail_customer_success_team(self): + """Select Retail Customer Success team and continue.""" + logger.info("Starting team selection process...") + + logger.info("Clicking on 'Current Team' button...") + self.page.locator(self.CURRENT_TEAM).click() + self.page.wait_for_timeout(2000) + logger.info("βœ“ 'Current Team' button clicked") + + logger.info("Selecting 'Retail Customer Success' radio button...") + self.page.locator(self.RETAIL_CUSTOMER_SUCCESS).click() + self.page.wait_for_timeout(1000) + logger.info("βœ“ 'Retail Customer Success' radio button selected") + + logger.info("Clicking 'Continue' button...") + self.page.locator(self.CONTINUE_BTN).click() + self.page.wait_for_timeout(2000) + logger.info("βœ“ 'Continue' button clicked") + + logger.info("Validating 'Retail Customer Success Team' is selected and visible...") + expect(self.page.locator(self.RETAIL_CUSTOMER_SUCCESS_SELECTED)).to_be_visible() + logger.info("βœ“ 'Retail Customer Success Team' is confirmed as selected") + + logger.info("Retail Customer Success team selection completed successfully!") + + def select_product_marketing_team(self): + """Select Product Marketing team and continue.""" + logger.info("Starting team selection process...") + + logger.info("Clicking on 'Current Team' button...") + self.page.locator(self.CURRENT_TEAM).click() + self.page.wait_for_timeout(2000) + logger.info("βœ“ 'Current Team' button clicked") + + logger.info("Selecting 'Product Marketing' radio button...") + self.page.locator(self.PRODUCT_MARKETING).click() + self.page.wait_for_timeout(1000) + logger.info("βœ“ 'Product Marketing' radio button selected") + + logger.info("Clicking 'Continue' button...") + self.page.locator(self.CONTINUE_BTN).click() + self.page.wait_for_timeout(2000) + logger.info("βœ“ 'Continue' button clicked") + + logger.info("Product Marketing team selection completed successfully!") + + def select_human_resources_team(self): + """Select Human Resources team and continue.""" + logger.info("Starting team selection process...") + + logger.info("Clicking on 'Current Team' button...") + self.page.locator(self.CURRENT_TEAM).click() + self.page.wait_for_timeout(2000) + logger.info("βœ“ 'Current Team' button clicked") + + logger.info("Selecting 'Human Resources' radio button...") + self.page.locator(self.HR_TEAM).click() + self.page.wait_for_timeout(1000) + logger.info("βœ“ 'Human Resources' radio button selected") + + logger.info("Clicking 'Continue' button...") + self.page.locator(self.CONTINUE_BTN).click() + self.page.wait_for_timeout(2000) + logger.info("βœ“ 'Continue' button clicked") + + logger.info("Human Resources team selection completed successfully!") + + def select_quick_task_and_create_plan(self): + """Select a quick task, send it, and wait for plan creation with all agents.""" + logger.info("Starting quick task selection process...") + + logger.info("Clicking on Quick Task...") + self.page.locator(self.QUICK_TASK).first.click() + self.page.wait_for_timeout(2000) + logger.info("βœ“ Quick Task selected") + + logger.info("Clicking Send button...") + self.page.locator(self.SEND_BUTTON).click() + self.page.wait_for_timeout(1000) + logger.info("βœ“ Send button clicked") + + logger.info("Validating 'Creating a plan' message is visible...") + expect(self.page.locator(self.CREATING_PLAN)).to_be_visible(timeout=10000) + logger.info("βœ“ 'Creating a plan' message is visible") + + logger.info("Waiting for 'Creating a plan' to disappear...") + self.page.locator(self.CREATING_PLAN).wait_for(state="hidden", timeout=60000) + logger.info("βœ“ Plan creation completed") + + self.page.wait_for_timeout(8000) + + logger.info("Waiting for 'Creating your plan...' loading to disappear...") + self.page.locator(self.CREATING_PLAN_LOADING).wait_for(state="hidden", timeout=60000) + logger.info("βœ“ 'Creating your plan...' loading disappeared") + + logger.info("Quick task selection and plan creation completed successfully!") + + def input_prompt_and_send(self, prompt_text): + """Input custom prompt text and click send button to create plan.""" + logger.info("Starting custom prompt input process...") + + logger.info(f"Typing prompt: {prompt_text}") + self.page.locator(self.PROMPT_INPUT).fill(prompt_text) + self.page.wait_for_timeout(1000) + logger.info("βœ“ Prompt text entered") + + logger.info("Clicking Send button...") + self.page.locator(self.SEND_BUTTON).click() + self.page.wait_for_timeout(1000) + logger.info("βœ“ Send button clicked") + + logger.info("Validating 'Creating a plan' message is visible...") + expect(self.page.locator(self.CREATING_PLAN)).to_be_visible(timeout=10000) + logger.info("βœ“ 'Creating a plan' message is visible") + + logger.info("Waiting for 'Creating a plan' to disappear...") + self.page.locator(self.CREATING_PLAN).wait_for(state="hidden", timeout=60000) + logger.info("βœ“ Plan creation completed") + + self.page.wait_for_timeout(8000) + + logger.info("Waiting for 'Creating your plan...' loading to disappear...") + self.page.locator(self.CREATING_PLAN_LOADING).wait_for(state="hidden", timeout=60000) + logger.info("βœ“ 'Creating your plan...' loading disappeared") + + logger.info("Custom prompt input and plan creation completed successfully!") + + def validate_retail_agents_visible(self): + """Validate that all retail agents are visible.""" + logger.info("Validating all retail agents are visible...") + + logger.info("Checking Customer Data Agent visibility...") + expect(self.page.locator(self.CUSTOMER_DATA_AGENT)).to_be_visible(timeout=10000) + logger.info("βœ“ Customer Data Agent is visible") + + logger.info("Checking Order Data Agent visibility...") + expect(self.page.locator(self.ORDER_DATA_AGENT)).to_be_visible(timeout=10000) + logger.info("βœ“ Order Data Agent is visible") + + logger.info("Checking Analysis Recommendation Agent visibility...") + expect(self.page.locator(self.ANALYSIS_RECOMMENDATION_AGENT)).to_be_visible(timeout=10000) + logger.info("βœ“ Analysis Recommendation Agent is visible") + + logger.info("Checking Proxy Agent visibility...") + expect(self.page.locator(self.PROXY_AGENT)).to_be_visible(timeout=10000) + logger.info("βœ“ Proxy Agent is visible") + + logger.info("All agents validation completed successfully!") + + def validate_product_marketing_agents(self): + """Validate that all product marketing agents are visible.""" + logger.info("Validating all product marketing agents are visible...") + + logger.info("Checking Product Agent visibility...") + expect(self.page.locator(self.PRODUCT_AGENT)).to_be_visible(timeout=10000) + logger.info("βœ“ Product Agent is visible") + + logger.info("Checking Marketing Agent visibility...") + expect(self.page.locator(self.MARKETING_AGENT)).to_be_visible(timeout=10000) + logger.info("βœ“ Marketing Agent is visible") + + logger.info("Checking Proxy Agent visibility...") + expect(self.page.locator(self.PROXY_AGENT)).to_be_visible(timeout=10000) + logger.info("βœ“ Proxy Agent is visible") + + logger.info("All product marketing agents validation completed successfully!") + + def validate_hr_agents(self): + """Validate that all HR agents are visible.""" + logger.info("Validating all HR agents are visible...") + + logger.info("Checking HR Helper Agent visibility...") + expect(self.page.locator(self.HR_HELPER_AGENT)).to_be_visible(timeout=10000) + logger.info("βœ“ HR Helper Agent is visible") + + logger.info("Checking Technical Support Agent visibility...") + expect(self.page.locator(self.TECH_SUPPORT_AGENT)).to_be_visible(timeout=10000) + logger.info("βœ“ Technical Support Agent is visible") + + logger.info("Checking Proxy Agent visibility...") + expect(self.page.locator(self.PROXY_AGENT)).to_be_visible(timeout=10000) + logger.info("βœ“ Proxy Agent is visible") + + logger.info("All HR agents validation completed successfully!") + + def cancel_retail_task_plan(self): + """Cancel the retail task plan.""" + logger.info("Starting retail task plan cancellation process...") + self.page.locator(self.CANCEL_PLAN).click() + self.page.wait_for_timeout(3000) + logger.info("βœ“ 'Cancel Retail Task Plan' button clicked") + + def approve_retail_task_plan(self): + """Approve the task plan and wait for processing to complete.""" + logger.info("Starting retail task plan approval process...") + + logger.info("Clicking 'Approve Retail Task Plan' button...") + self.page.locator(self.APPROVE_TASK_PLAN).click() + self.page.wait_for_timeout(2000) + logger.info("βœ“ 'Approve Retail Task Plan' button clicked") + + logger.info("Waiting for 'Processing your plan' message to be visible...") + expect(self.page.locator(self.PROCESSING_PLAN)).to_be_visible(timeout=10000) + logger.info("βœ“ 'Processing your plan' message is visible") + + #self.validate_agent_message_api_status(agent_name="CustomerDataAgent") + + logger.info("Waiting for plan processing to complete...") + self.page.locator(self.PROCESSING_PLAN).wait_for(state="hidden", timeout=200000) + logger.info("βœ“ Plan processing completed") + + # Check if INPUT_CLARIFICATION textbox is enabled + logger.info("Checking if clarification input is enabled...") + clarification_input = self.page.locator(self.INPUT_CLARIFICATION) + try: + if clarification_input.is_visible(timeout=5000) and clarification_input.is_enabled(): + logger.error("⚠ Clarification input is enabled - Task plan approval requires clarification") + raise ValueError("INPUT_CLARIFICATION is enabled - retry required") + logger.info("βœ“ No clarification required - task completed successfully") + except ValueError: + # Re-raise the clarification exception to trigger retry + raise + except (TimeoutError, Exception) as e: + # No clarification input detected, proceed normally + logger.info(f"βœ“ No clarification input detected - proceeding normally: {e}") + + logger.info("Task plan approval and processing completed successfully!") + + def approve_task_plan(self): + """Approve the task plan and wait for processing to complete (without clarification check).""" + logger.info("Starting task plan approval process...") + + logger.info("Clicking 'Approve Task Plan' button...") + self.page.locator(self.APPROVE_TASK_PLAN).click() + self.page.wait_for_timeout(2000) + logger.info("βœ“ 'Approve Task Plan' button clicked") + + logger.info("Waiting for 'Processing your plan' message to be visible...") + expect(self.page.locator(self.PROCESSING_PLAN)).to_be_visible(timeout=10000) + logger.info("βœ“ 'Processing your plan' message is visible") + + #self.validate_agent_message_api_status(agent_name="CustomerDataAgent") + + logger.info("Waiting for plan processing to complete...") + self.page.locator(self.PROCESSING_PLAN).wait_for(state="hidden", timeout=200000) + logger.info("βœ“ Plan processing completed") + + logger.info("Task plan approval and processing completed successfully!") + + def approve_product_marketing_task_plan(self): + """Approve the task plan and wait for processing to complete.""" + logger.info("Starting task plan approval process...") + + logger.info("Clicking 'Approve Task Plan' button...") + self.page.locator(self.APPROVE_TASK_PLAN).click() + self.page.wait_for_timeout(2000) + logger.info("βœ“ 'Approve Task Plan' button clicked") + + logger.info("Waiting for 'Processing your plan' message to be visible...") + expect(self.page.locator(self.PROCESSING_PLAN)).to_be_visible(timeout=10000) + logger.info("βœ“ 'Processing your plan' message is visible") + + #self.validate_agent_message_api_status(agent_name="CustomerDataAgent") + + logger.info("Waiting for plan processing to complete...") + self.page.locator(self.PROCESSING_PLAN).wait_for(state="hidden", timeout=200000) + logger.info("βœ“ Plan processing completed") + + # Check if INPUT_CLARIFICATION textbox is enabled + logger.info("Checking if clarification input is enabled...") + clarification_input = self.page.locator(self.INPUT_CLARIFICATION) + try: + if clarification_input.is_visible(timeout=5000) and clarification_input.is_enabled(): + logger.info("⚠ Clarification input is enabled - Providing product marketing details") + + # Fill in product marketing clarification details + pm_clarification = ("company name : Contoso, Contact details: 1234567890, " + "Website : contoso.com, Target Audience: GenZ, " + "Theme: No specific Theme") + logger.info(f"Typing clarification: {pm_clarification}") + clarification_input.fill(pm_clarification) + self.page.wait_for_timeout(3000) + logger.info("βœ“ Product marketing clarification entered") + + # Click send button + logger.info("Clicking Send button for clarification...") + self.page.locator(self.SEND_BUTTON_CLARIFICATION).click() + self.page.wait_for_timeout(2000) + logger.info("βœ“ Clarification send button clicked") + + # Wait for processing to start again + logger.info("Waiting for 'Processing your plan' message after clarification...") + expect(self.page.locator(self.PROCESSING_PLAN)).to_be_visible(timeout=15000) + logger.info("βœ“ 'Processing your plan' message is visible after clarification") + logger.info("Waiting for plan processing to complete...") + self.page.locator(self.PROCESSING_PLAN).wait_for(state="hidden", timeout=200000) + logger.info("βœ“ Plan processing completed") + else: + logger.info("βœ“ No clarification required - task completed successfully") + except (TimeoutError, Exception) as e: + logger.info(f"βœ“ No clarification input detected - proceeding normally: {e}") + + logger.info("Task plan approval and processing completed successfully!") + + def validate_retail_customer_response(self): + """Validate the retail customer response.""" + + logger.info("Validating retail customer response...") + expect(self.page.locator(self.RETAIL_CUSTOMER_RESPONSE_VALIDATION)).to_be_visible(timeout=10000) + logger.info("βœ“ Retail customer response is visible") + expect(self.page.locator(self.RETAIL_COMPLETED_TASK).first).to_be_visible(timeout=6000) + logger.info("βœ“ Retail completed task is visible") + + # Soft assertions for Order Data, Customer Data, and Analysis Recommendation + logger.info("Checking Order Data visibility...") + try: + expect(self.page.locator(self.ORDER_DATA).first).to_be_visible(timeout=10000) + logger.info("βœ“ Order Data is visible") + except (AssertionError, TimeoutError) as e: + logger.warning(f"⚠ Order Data Agent is NOT Utilized in response: {e}") + + logger.info("Checking Customer Data visibility...") + try: + expect(self.page.locator(self.CUSTOMER_DATA).first).to_be_visible(timeout=10000) + logger.info("βœ“ Customer Data is visible") + except (AssertionError, TimeoutError) as e: + logger.warning(f"⚠ Customer Data Agent is NOT Utilized in response: {e}") + + logger.info("Checking Analysis Recommendation visibility...") + try: + expect(self.page.locator(self.ANALYSIS_RECOMMENDATION).first).to_be_visible(timeout=10000) + logger.info("βœ“ Analysis Recommendation is visible") + except (AssertionError, TimeoutError) as e: + logger.warning(f"⚠ Analysis Recommendation Agent is NOT Utilized in response: {e}") + + + def validate_product_marketing_response(self): + """Validate the product marketing response.""" + + logger.info("Validating product marketing response...") + expect(self.page.locator(self.PRODUCT_MARKETING_RESPONSE_VALIDATION)).to_be_visible(timeout=20000) + logger.info("βœ“ Product marketing response is visible") + expect(self.page.locator(self.PM_COMPLETED_TASK).first).to_be_visible(timeout=6000) + logger.info("βœ“ Product marketing completed task is visible") + + # Soft assertions for Product and Marketing + logger.info("Checking Product visibility...") + try: + expect(self.page.locator(self.PRODUCT).first).to_be_visible(timeout=10000) + logger.info("βœ“ Product is visible") + except (AssertionError, TimeoutError) as e: + logger.warning(f"⚠ Product Agent is NOT Utilized in response: {e}") + + logger.info("Checking Marketing visibility...") + try: + expect(self.page.locator(self.MARKETING).first).to_be_visible(timeout=10000) + logger.info("βœ“ Marketing is visible") + except (AssertionError, TimeoutError) as e: + logger.warning(f"⚠ Marketing Agent is NOT Utilized in response: {e}") + + def validate_hr_response(self): + """Validate the HR response.""" + + logger.info("Validating HR response...") + expect(self.page.locator(self.PRODUCT_MARKETING_RESPONSE_VALIDATION)).to_be_visible(timeout=20000) + logger.info("βœ“ HR response is visible") + expect(self.page.locator(self.HR_COMPLETED_TASK).first).to_be_visible(timeout=6000) + logger.info("βœ“ HR completed task is visible") + + # Soft assertions for Technical Support and HR Helper + logger.info("Checking Technical Support visibility...") + try: + expect(self.page.locator(self.TECH_SUPPORT).first).to_be_visible(timeout=10000) + logger.info("βœ“ Technical Support is visible") + except (AssertionError, TimeoutError) as e: + logger.warning(f"⚠ Technical Support Agent is NOT Utilized in response: {e}") + + logger.info("Checking HR Helper visibility...") + try: + expect(self.page.locator(self.HR_HELPER).first).to_be_visible(timeout=10000) + logger.info("βœ“ HR Helper is visible") + except (AssertionError, TimeoutError) as e: + logger.warning(f"⚠ HR Helper Agent is NOT Utilized in response: {e}") + + def click_new_task(self): + """Click on the New Task button.""" + logger.info("Clicking on 'New Task' button...") + self.page.locator(self.NEW_TASK_PROMPT).click() + self.page.wait_for_timeout(2000) + logger.info("βœ“ 'New Task' button clicked") + + def input_clarification_and_send(self, clarification_text): + """Input clarification text and click send button.""" + logger.info("Starting clarification input process...") + + logger.info(f"Typing clarification: {clarification_text}") + self.page.locator(self.INPUT_CLARIFICATION).fill(clarification_text) + self.page.wait_for_timeout(1000) + logger.info("βœ“ Clarification text entered") + + logger.info("Clicking Send button for clarification...") + self.page.locator(self.SEND_BUTTON_CLARIFICATION).click() + self.page.wait_for_timeout(2000) + logger.info("βœ“ Clarification send button clicked") + + logger.info("Clarification input and send completed successfully!") + + logger.info("Waiting for 'Processing your plan' message to be visible...") + expect(self.page.locator(self.PROCESSING_PLAN)).to_be_visible(timeout=15000) + logger.info("βœ“ 'Processing your plan' message is visible") + + logger.info("Waiting for plan processing to complete...") + self.page.locator(self.PROCESSING_PLAN).wait_for(state="hidden", timeout=200000) + logger.info("βœ“ Plan processing completed") + + diff --git a/tests/e2e-test/tests/conftest.py b/tests/e2e-test/tests/conftest.py index f6251397..365a48cb 100644 --- a/tests/e2e-test/tests/conftest.py +++ b/tests/e2e-test/tests/conftest.py @@ -38,7 +38,7 @@ def login_logout(): @pytest.hookimpl(tryfirst=True) def pytest_html_report_title(report): """Customize HTML report title.""" - report.title = "Test Automation MACAE" + report.title = "Test Automation MACAE-v3 GP" log_streams = {} diff --git a/tests/e2e-test/tests/test_MACAE_GP.py b/tests/e2e-test/tests/test_MACAE_GP.py index 69f59b62..b272a10b 100644 --- a/tests/e2e-test/tests/test_MACAE_GP.py +++ b/tests/e2e-test/tests/test_MACAE_GP.py @@ -5,84 +5,313 @@ import pytest -from config.constants import (employee_details, product_details, - prompt_question1, prompt_question2, rai_prompt) -from pages.BIAB import BIABPage +from pages.HomePage import BIABPage +from config.constants import hr_clarification_text, prompt_question1 logger = logging.getLogger(__name__) -# Define test steps and prompts -test_cases = [ - ("Validate home page is loaded", lambda biab: biab.validate_home_page()), - ( - f"Verify Run Prompt 1: '{prompt_question1}' & run all stages", - lambda biab: ( - biab.enter_a_question(prompt_question1), - biab.click_send_button(), - # biab.click_my_task(), - biab.enter_aditional_info(employee_details), - # biab.click_aditional_send_button(), - biab.processing_different_stage(), - ), - ), - ( - f"Verify Run Prompt 2: '{prompt_question2}' & run all stages", - lambda biab: ( - biab.click_new_task(), - biab.enter_a_question(prompt_question2), - biab.click_send_button(), - # biab.click_my_task(), - biab.enter_aditional_info(product_details), - # biab.click_aditional_send_button(), - biab.processing_different_stage(), - ), - ), - ( - "Verify Run Prompt 3 via Quick Task - Mobile Plan Query & run all stages", - lambda biab: ( - biab.click_new_task(), - biab.click_mobile_plan(), - biab.click_send_button(), - # biab.click_my_task(), - biab.processing_different_stage(), - ), - ), - ( - f"Verify Run RAI Prompt: '{rai_prompt}' to make sure task is not created and validation message is displayed.", - lambda biab: ( - biab.click_new_task(), - biab.enter_a_question(rai_prompt), - biab.validate_rai_validation_message(), - ), - ), -] - -# Create test IDs like "01. Validate home page", "02. Run Prompt 1: ..." -test_ids = [f"{i + 1:02d}. {case[0]}" for i, case in enumerate(test_cases)] - - -@pytest.mark.parametrize("prompt, action", test_cases, ids=test_ids) -def test_biab_prompt_case(login_logout, prompt, action, request): - """Each BIAB prompt runs as an individual test case with execution time logging and meaningful test step titles.""" +def test_retail_customer_success_workflow(login_logout, request): + """ + Validate Golden path for MACAE-v3. + + Steps: + 1. Validate home page elements are visible + 2. Select Retail Customer Success team + 3. Select quick task and create plan with all agents + 4. Validate all retail agents are displayed + 5. Approve the task plan + 6. Validate retail customer response + 7. Click on new task + 8. Select Product Marketing team + 9. Select quick task and create plan + 10. Validate all product marketing agents are displayed + 11. Approve the task plan + 12. Validate product marketing response + 13. Click on new task + 14. Select Human Resources team + 15. Input custom prompt "Onboard new employee" + 16. Validate all HR agents are displayed + 17. Approve the task plan + 18. Send human clarification with employee details + 19. Validate HR response + """ page = login_logout biab_page = BIABPage(page) - logger.info(f"Running test step: {prompt}") + + # Update test node ID for HTML report + request.node._nodeid = "Golden Path - MACAE-v3- test golden path works properly" + + logger.info("=" * 80) + logger.info("Starting Multi-Team Workflow Test") + logger.info("=" * 80) + + start_time = time.time() + + try: + # Step 1: Validate Home Page + logger.info("\n" + "=" * 80) + logger.info("STEP 1: Validating Home Page") + logger.info("=" * 80) + step1_start = time.time() + biab_page.validate_home_page() + step1_end = time.time() + logger.info(f"Step 1 completed in {step1_end - step1_start:.2f} seconds") + + # Step 2: Select Retail Customer Success Team + logger.info("\n" + "=" * 80) + logger.info("STEP 2: Selecting Retail Customer Success Team") + logger.info("=" * 80) + step2_start = time.time() + biab_page.select_retail_customer_success_team() + step2_end = time.time() + logger.info(f"Step 2 completed in {step2_end - step2_start:.2f} seconds") + + # Step 3: Select Quick Task and Create Plan + logger.info("\n" + "=" * 80) + logger.info("STEP 3: Selecting Quick Task and Creating Plan") + logger.info("=" * 80) + step3_start = time.time() + biab_page.select_quick_task_and_create_plan() + step3_end = time.time() + logger.info(f"Step 3 completed in {step3_end - step3_start:.2f} seconds") + + # Step 4: Validate All Retail Agents Visible + logger.info("\n" + "=" * 80) + logger.info("STEP 4: Validating All Retail Agents Are Displayed") + logger.info("=" * 80) + step4_start = time.time() + biab_page.validate_retail_agents_visible() + step4_end = time.time() + logger.info(f"Step 4 completed in {step4_end - step4_start:.2f} seconds") + + # Step 5: Approve Retail Task Plan (with retry logic) + logger.info("\n" + "=" * 80) + logger.info("STEP 5: Approving Retail Task Plan") + logger.info("=" * 80) + step5_start = time.time() + step5_retry_attempted = False + try: + biab_page.approve_retail_task_plan() + step5_end = time.time() + logger.info(f"Step 5 completed in {step5_end - step5_start:.2f} seconds") + except Exception as step5_error: + logger.warning("\n" + "⚠" * 80) + logger.warning(f"STEP 5 FAILED: {str(step5_error)}") + logger.warning("Initiating retry logic: Step 7 (New Task) β†’ Retry Steps 3, 4, 5") + logger.warning("⚠" * 80) + step5_retry_attempted = True + + # Perform Step 7: Click New Task + logger.info("\n" + "=" * 80) + logger.info("STEP 7 (RETRY): Clicking New Task") + logger.info("=" * 80) + step7_retry_start = time.time() + biab_page.click_new_task() + biab_page.cancel_retail_task_plan() + step7_retry_end = time.time() + logger.info(f"Step 7 (Retry) completed in {step7_retry_end - step7_retry_start:.2f} seconds") + + # Retry Step 3: Select Quick Task and Create Plan + logger.info("\n" + "=" * 80) + logger.info("STEP 3 (RETRY): Selecting Quick Task and Creating Plan") + logger.info("=" * 80) + step3_retry_start = time.time() + biab_page.select_quick_task_and_create_plan() + step3_retry_end = time.time() + logger.info(f"Step 3 (Retry) completed in {step3_retry_end - step3_retry_start:.2f} seconds") + + # Retry Step 4: Validate All Retail Agents Visible + logger.info("\n" + "=" * 80) + logger.info("STEP 4 (RETRY): Validating All Retail Agents Are Displayed") + logger.info("=" * 80) + step4_retry_start = time.time() + biab_page.validate_retail_agents_visible() + step4_retry_end = time.time() + logger.info(f"Step 4 (Retry) completed in {step4_retry_end - step4_retry_start:.2f} seconds") + + # Retry Step 5: Approve Task Plan + logger.info("\n" + "=" * 80) + logger.info("STEP 5 (RETRY): Approving Retail Task Plan") + logger.info("=" * 80) + step5_retry_start = time.time() + biab_page.approve_retail_task_plan() + step5_end = time.time() + logger.info(f"Step 5 (Retry) completed in {step5_end - step5_retry_start:.2f} seconds") + logger.info("βœ“ Retry successful - continuing with test execution") + + # Step 6: Validate Retail Customer Response + logger.info("\n" + "=" * 80) + logger.info("STEP 6: Validating Retail Customer Response") + logger.info("=" * 80) + step6_start = time.time() + biab_page.validate_retail_customer_response() + step6_end = time.time() + logger.info(f"Step 6 completed in {step6_end - step6_start:.2f} seconds") + + # Step 7: Click New Task + logger.info("\n" + "=" * 80) + logger.info("STEP 7: Clicking New Task") + logger.info("=" * 80) + step7_start = time.time() + biab_page.click_new_task() + step7_end = time.time() + logger.info(f"Step 7 completed in {step7_end - step7_start:.2f} seconds") + + # Step 8: Select Product Marketing Team + logger.info("\n" + "=" * 80) + logger.info("STEP 8: Selecting Product Marketing Team") + logger.info("=" * 80) + step8_start = time.time() + biab_page.select_product_marketing_team() + step8_end = time.time() + logger.info(f"Step 8 completed in {step8_end - step8_start:.2f} seconds") + + # Step 9: Select Quick Task and Create Plan (Product Marketing) + logger.info("\n" + "=" * 80) + logger.info("STEP 9: Selecting Quick Task and Creating Plan (Product Marketing)") + logger.info("=" * 80) + step9_start = time.time() + biab_page.select_quick_task_and_create_plan() + step9_end = time.time() + logger.info(f"Step 9 completed in {step9_end - step9_start:.2f} seconds") + + # Step 10: Validate All Product Marketing Agents Visible + logger.info("\n" + "=" * 80) + logger.info("STEP 10: Validating All Product Marketing Agents Are Displayed") + logger.info("=" * 80) + step10_start = time.time() + biab_page.validate_product_marketing_agents() + step10_end = time.time() + logger.info(f"Step 10 completed in {step10_end - step10_start:.2f} seconds") + + # Step 11: Approve Task Plan (Product Marketing) + logger.info("\n" + "=" * 80) + logger.info("STEP 11: Approving Task Plan (Product Marketing)") + logger.info("=" * 80) + step11_start = time.time() + biab_page.approve_product_marketing_task_plan() + step11_end = time.time() + logger.info(f"Step 11 completed in {step11_end - step11_start:.2f} seconds") + + # Step 12: Validate Product Marketing Response + logger.info("\n" + "=" * 80) + logger.info("STEP 12: Validating Product Marketing Response") + logger.info("=" * 80) + step12_start = time.time() + biab_page.validate_product_marketing_response() + step12_end = time.time() + logger.info(f"Step 12 completed in {step12_end - step12_start:.2f} seconds") + + # Step 13: Click New Task + logger.info("\n" + "=" * 80) + logger.info("STEP 13: Clicking New Task") + logger.info("=" * 80) + step13_start = time.time() + biab_page.click_new_task() + step13_end = time.time() + logger.info(f"Step 13 completed in {step13_end - step13_start:.2f} seconds") + + # Step 14: Select Human Resources Team + logger.info("\n" + "=" * 80) + logger.info("STEP 14: Selecting Human Resources Team") + logger.info("=" * 80) + step14_start = time.time() + biab_page.select_human_resources_team() + step14_end = time.time() + logger.info(f"Step 14 completed in {step14_end - step14_start:.2f} seconds") + + # Step 15: Input Custom Prompt "Onboard new employee" + logger.info("\n" + "=" * 80) + logger.info("STEP 15: Inputting Custom Prompt - Onboard new employee") + logger.info("=" * 80) + step15_start = time.time() + biab_page.input_prompt_and_send(prompt_question1) + step15_end = time.time() + logger.info(f"Step 15 completed in {step15_end - step15_start:.2f} seconds") + + # Step 16: Validate All HR Agents Visible + logger.info("\n" + "=" * 80) + logger.info("STEP 16: Validating All HR Agents Are Displayed") + logger.info("=" * 80) + step16_start = time.time() + biab_page.validate_hr_agents() + step16_end = time.time() + logger.info(f"Step 16 completed in {step16_end - step16_start:.2f} seconds") + + # Step 17: Approve Task Plan (HR) + logger.info("\n" + "=" * 80) + logger.info("STEP 17: Approving HR Task Plan") + logger.info("=" * 80) + step17_start = time.time() + biab_page.approve_task_plan() + step17_end = time.time() + logger.info(f"Step 17 completed in {step17_end - step17_start:.2f} seconds") + + # Step 18: Send Human Clarification with Employee Details + logger.info("\n" + "=" * 80) + logger.info("STEP 18: Sending Human Clarification with Employee Details") + logger.info("=" * 80) + step18_start = time.time() + biab_page.input_clarification_and_send(hr_clarification_text) + step18_end = time.time() + logger.info(f"Step 18 completed in {step18_end - step18_start:.2f} seconds") + + # Step 19: Validate HR Response + logger.info("\n" + "=" * 80) + logger.info("STEP 19: Validating HR Response") + logger.info("=" * 80) + step19_start = time.time() + biab_page.validate_hr_response() + step19_end = time.time() + logger.info(f"Step 19 completed in {step19_end - step19_start:.2f} seconds") + + end_time = time.time() + total_duration = end_time - start_time + + logger.info("\n" + "=" * 80) + logger.info("TEST EXECUTION SUMMARY") + logger.info("=" * 80) + logger.info(f"Step 1 (Home Page Validation): {step1_end - step1_start:.2f}s") + logger.info(f"Step 2 (Retail Team Selection): {step2_end - step2_start:.2f}s") + logger.info(f"Step 3 (Retail Quick Task & Plan Creation): {step3_end - step3_start:.2f}s") + logger.info(f"Step 4 (Retail Agents Validation): {step4_end - step4_start:.2f}s") + logger.info(f"Step 5 (Retail Approve Task Plan): {step5_end - step5_start:.2f}s") + logger.info(f"Step 6 (Retail Customer Response Validation): {step6_end - step6_start:.2f}s") + logger.info(f"Step 7 (Click New Task): {step7_end - step7_start:.2f}s") + logger.info(f"Step 8 (Product Marketing Team Selection): {step8_end - step8_start:.2f}s") + logger.info(f"Step 9 (Product Marketing Quick Task & Plan): {step9_end - step9_start:.2f}s") + logger.info(f"Step 10 (Product Marketing Agents Validation): {step10_end - step10_start:.2f}s") + logger.info(f"Step 11 (Product Marketing Approve Task Plan): {step11_end - step11_start:.2f}s") + logger.info(f"Step 12 (Product Marketing Response Validation): {step12_end - step12_start:.2f}s") + logger.info(f"Step 13 (Click New Task): {step13_end - step13_start:.2f}s") + logger.info(f"Step 14 (HR Team Selection): {step14_end - step14_start:.2f}s") + logger.info(f"Step 15 (HR Input Custom Prompt): {step15_end - step15_start:.2f}s") + logger.info(f"Step 16 (HR Agents Validation): {step16_end - step16_start:.2f}s") + logger.info(f"Step 17 (HR Approve Task Plan): {step17_end - step17_start:.2f}s") + logger.info(f"Step 18 (HR Human Clarification): {step18_end - step18_start:.2f}s") + logger.info(f"Step 19 (HR Response Validation): {step19_end - step19_start:.2f}s") + logger.info(f"Total Execution Time: {total_duration:.2f}s") + logger.info("=" * 80) + logger.info("βœ“ Multi-Team Workflow Test PASSED") + logger.info("=" * 80) + + # Attach execution time to pytest report + request.node._report_sections.append( + ("call", "log", f"Total execution time: {total_duration:.2f}s") + ) + + except Exception as e: + end_time = time.time() + total_duration = end_time - start_time + logger.error("\n" + "=" * 80) + logger.error("TEST EXECUTION FAILED") + logger.error("=" * 80) + logger.error(f"Error: {str(e)}") + logger.error(f"Execution time before failure: {total_duration:.2f}s") + logger.error("=" * 80) + raise - start = time.time() - if isinstance(action, tuple): - for step in action: - if callable(step): - step() - else: - action(biab_page) - end = time.time() - duration = end - start - logger.info(f"Execution Time for '{prompt}': {duration:.2f}s") - # Attach execution time to pytest report - request.node._report_sections.append( - ("call", "log", f"Execution time: {duration:.2f}s") - )