From 35b6e4cfbfd1a2ce74b60bd867654403d5a329ce Mon Sep 17 00:00:00 2001 From: Shriyansh Agnihotri Date: Fri, 15 Nov 2024 11:29:05 +0530 Subject: [PATCH] fixing negative testcase --- .../negativeTesting/negativeTesting.feature | 2 +- .../core/tools/click_using_selector.py | 77 +++++-------------- .../core/tools/enter_text_and_click.py | 45 +++-------- 3 files changed, 31 insertions(+), 93 deletions(-) diff --git a/tests/test_features/negativeTesting/negativeTesting.feature b/tests/test_features/negativeTesting/negativeTesting.feature index d07f266..a8a3b85 100644 --- a/tests/test_features/negativeTesting/negativeTesting.feature +++ b/tests/test_features/negativeTesting/negativeTesting.feature @@ -14,7 +14,7 @@ Feature: Negative scenarios for the large action model. Given I am on the Medium website When I navigate to "https://medium.com/non-existent-page" - Then I should see a 404 error page + Then I should see an error page with "Out of nothing, something." and a 404 PAGE NOT FOUND message Scenario: Accessing Restricted Content Without Authentication diff --git a/testzeus_hercules/core/tools/click_using_selector.py b/testzeus_hercules/core/tools/click_using_selector.py index e9f4b57..d68cd16 100644 --- a/testzeus_hercules/core/tools/click_using_selector.py +++ b/testzeus_hercules/core/tools/click_using_selector.py @@ -36,9 +36,7 @@ async def click( Optional[str], "The input response to a dialog box. THIS SHOULD NOT HAVE RANDOM VALUE BUT ONLY AS PER THE TEST INPUT", ] = None, - expected_message_of_dialog: Annotated[ - Optional[str], "The expected message of the dialog box when it opens." - ] = None, + expected_message_of_dialog: Annotated[Optional[str], "The expected message of the dialog box when it opens."] = None, action_on_dialog: Annotated[ Optional[str], "The action to be performed on the dialog box. ONLY 'DISMISS' OR 'ACCEPT' AS A VALUE ALLOWED.", @@ -89,13 +87,8 @@ async def handle_dialog(dialog: Any) -> None: logger.info(f"Dialog message: {dialog.message}") # Check if the dialog message matches the expected message (if provided) - if ( - expected_message_of_dialog - and dialog.message != expected_message_of_dialog - ): - logger.error( - f"Dialog message does not match the expected message: {expected_message_of_dialog}" - ) + if expected_message_of_dialog and dialog.message != expected_message_of_dialog: + logger.error(f"Dialog message does not match the expected message: {expected_message_of_dialog}") if action_on_dialog == "accept": if dialog.type == "prompt": await dialog.accept(user_input_dialog_response) @@ -144,23 +137,17 @@ def detect_dom_changes(changes: str): # type: ignore page.on("dialog", handle_dialog) result = await do_click(page, selector, wait_before_execution, type_of_click) - await asyncio.sleep( - 0.5 - ) # sleep for 500ms to allow the mutation observer to detect changes + await asyncio.sleep(0.5) # sleep for 500ms to allow the mutation observer to detect changes unsubscribe(detect_dom_changes) await browser_manager.take_screenshots(f"{function_name}_end", page) - await browser_manager.notify_user( - result["summary_message"], message_type=MessageType.ACTION - ) + await browser_manager.notify_user(result["summary_message"], message_type=MessageType.ACTION) if dom_changes_detected: return f"Success: {result['summary_message']}.\n As a consequence of this action, new elements have appeared in view: {dom_changes_detected}. This means that the action to click {selector} is not yet executed and needs further interaction. Get all_fields DOM to complete the interaction." return result["detailed_message"] -async def do_click( - page: Page, selector: str, wait_before_execution: float, type_of_click: str -) -> dict[str, str]: +async def do_click(page: Page, selector: str, wait_before_execution: float, type_of_click: str) -> dict[str, str]: """ Executes the click action on the element with the given selector within the provided page, including searching within iframes if necessary. @@ -174,9 +161,7 @@ async def do_click( Returns: dict[str,str] - Explanation of the outcome of this operation represented as a dictionary with 'summary_message' and 'detailed_message'. """ - logger.info( - f'Executing ClickElement with "{selector}" as the selector. Wait time before execution: {wait_before_execution} seconds.' - ) + logger.info(f'Executing ClickElement with "{selector}" as the selector. Wait time before execution: {wait_before_execution} seconds.') # Wait before execution if specified if wait_before_execution > 0: @@ -198,48 +183,34 @@ async def find_element_within_iframes() -> ElementHandle | None: # Wait for the selector to be present and ensure it's attached and visible. If timeout, try JavaScript click try: - logger.info( - f'Executing ClickElement with "{selector}" as the selector. Waiting for the element to be attached and visible.' - ) + logger.info(f'Executing ClickElement with "{selector}" as the selector. Waiting for the element to be attached and visible.') # Attempt to find the element on the main page or in iframes element = await find_element_within_iframes() if element is None: raise ValueError(f'Element with selector: "{selector}" not found') - logger.info( - f'Element with selector: "{selector}" is attached. Scrolling it into view if needed.' - ) + logger.info(f'Element with selector: "{selector}" is attached. Scrolling it into view if needed.') try: await element.scroll_into_view_if_needed(timeout=200) - logger.info( - f'Element with selector: "{selector}" is attached and scrolled into view. Waiting for the element to be visible.' - ) + logger.info(f'Element with selector: "{selector}" is attached and scrolled into view. Waiting for the element to be visible.') except Exception: # If scrollIntoView fails, just move on, not a big deal pass try: await element.wait_for_element_state("visible", timeout=200) - logger.info( - f'Executing ClickElement with "{selector}" as the selector. Element is attached and visible. Clicking the element.' - ) + logger.info(f'Executing ClickElement with "{selector}" as the selector. Element is attached and visible. Clicking the element.') except Exception: # If the element is not visible, try to click it anyway pass - element_tag_name = await element.evaluate( - "element => element.tagName.toLowerCase()" - ) - element_outer_html = await get_element_outer_html( - element, page, element_tag_name - ) + element_tag_name = await element.evaluate("element => element.tagName.toLowerCase()") + element_outer_html = await get_element_outer_html(element, page, element_tag_name) if element_tag_name == "option": element_value = await element.get_attribute("value") - parent_element = await element.evaluate_handle( - "element => element.parentNode" - ) + parent_element = await element.evaluate_handle("element => element.parentNode") await parent_element.select_option(value=element_value) # type: ignore logger.info(f'Select menu option "{element_value}" selected') @@ -340,15 +311,11 @@ async def perform_playwright_click(element: ElementHandle, selector: str) -> Non Returns: - None """ - logger.info( - f"Performing first Step: Playwright Click on element with selector: {selector}" - ) + logger.info(f"Performing first Step: Playwright Click on element with selector: {selector}") await element.click(force=True, timeout=200) -async def perform_javascript_click( - page: Page, selector: str, type_of_click: str -) -> str: +async def perform_javascript_click(page: Page, selector: str, type_of_click: str) -> str: """ Performs a click action on the element using JavaScript. @@ -519,17 +486,11 @@ async def perform_javascript_click( """ try: - logger.info( - f"Executing JavaScript '{type_of_click}' on element with selector: {selector}" - ) + logger.info(f"Executing JavaScript '{type_of_click}' on element with selector: {selector}") result: str = await page.evaluate(js_code, (selector, type_of_click)) - logger.debug( - f"Executed JavaScript '{type_of_click}' on element with selector: {selector}" - ) + logger.debug(f"Executed JavaScript '{type_of_click}' on element with selector: {selector}") return result except Exception as e: - logger.error( - f"Error executing JavaScript '{type_of_click}' on element with selector: {selector}. Error: {e}" - ) + logger.error(f"Error executing JavaScript '{type_of_click}' on element with selector: {selector}. Error: {e}") traceback.print_exc() return f"Error executing JavaScript '{type_of_click}' on element with selector: {selector}" diff --git a/testzeus_hercules/core/tools/enter_text_and_click.py b/testzeus_hercules/core/tools/enter_text_and_click.py index 6cbd605..3d71a98 100644 --- a/testzeus_hercules/core/tools/enter_text_and_click.py +++ b/testzeus_hercules/core/tools/enter_text_and_click.py @@ -41,19 +41,13 @@ async def enter_text_and_click( Optional[str], "The input response to a dialog box. THIS SHOULD NOT HAVE RANDOM VALUE BUT ONLY AS PER THE TEST INPUT", ], - expected_message_of_dialog: Annotated[ - Optional[str], "The expected message of the dialog box when it opens." - ], + expected_message_of_dialog: Annotated[Optional[str], "The expected message of the dialog box when it opens."], action_on_dialog: Annotated[ Optional[str], "The action to be performed on the dialog box. ONLY 'DISMISS' OR 'ACCEPT' AS A VALUE ALLOWED.", ], - wait_before_click_execution: Annotated[ - float, "Optional wait time in seconds before executing the click.", float - ] = 0.0, -) -> Annotated[ - str, "A message indicating success or failure of the text entry and click." -]: + wait_before_click_execution: Annotated[float, "Optional wait time in seconds before executing the click.", float] = 0.0, +) -> Annotated[str, "A message indicating success or failure of the text entry and click."]: """ Enters text into an element and then clicks on another element. @@ -74,9 +68,7 @@ async def enter_text_and_click( await enter_text_and_click("[mmid='1234']", "Hello, World!", "[mmid='5678']", wait_before_click_execution=1.5) ``` """ - logger.info( - f"Entering text '{text_to_enter}' into element with selector '{text_selector}' and then clicking element with selector '{click_selector}'." - ) + logger.info(f"Entering text '{text_to_enter}' into element with selector '{text_selector}' and then clicking element with selector '{click_selector}'.") add_event(EventType.INTERACTION, EventData(detail="enter_text_and_click")) # Initialize PlaywrightManager and get the active browser page browser_manager = PlaywrightManager() @@ -96,13 +88,8 @@ async def handle_dialog(dialog: Any) -> None: logger.info(f"Dialog message: {dialog.message}") # Check if the dialog message matches the expected message (if provided) - if ( - expected_message_of_dialog - and dialog.message != expected_message_of_dialog - ): - logger.error( - f"Dialog message does not match the expected message: {expected_message_of_dialog}" - ) + if expected_message_of_dialog and dialog.message != expected_message_of_dialog: + logger.error(f"Dialog message does not match the expected message: {expected_message_of_dialog}") if action_on_dialog == "accept": if dialog.type == "prompt": await dialog.accept(user_input_dialog_response) @@ -130,9 +117,7 @@ async def handle_dialog(dialog: Any) -> None: function_name = inspect.currentframe().f_code.co_name # type: ignore await browser_manager.take_screenshots(f"{function_name}_start", page) - text_entry_result = await do_entertext( - page, text_selector, text_to_enter, use_keyboard_fill=True - ) + text_entry_result = await do_entertext(page, text_selector, text_to_enter, use_keyboard_fill=True) # await browser_manager.notify_user(text_entry_result["summary_message"]) if not text_entry_result["summary_message"].startswith("Success"): @@ -153,13 +138,9 @@ async def handle_dialog(dialog: Any) -> None: # if the text_selector is the same as the click_selector, press the Enter key instead of clicking if text_selector == click_selector: - do_press_key_combination_result = await do_press_key_combination( - browser_manager, page, "Enter" - ) + do_press_key_combination_result = await do_press_key_combination(browser_manager, page, "Enter") if do_press_key_combination_result: - result[ - "detailed_message" - ] += f' Instead of click, pressed the Enter key successfully on element: "{click_selector}".' + result["detailed_message"] += f' Instead of click, pressed the Enter key successfully on element: "{click_selector}".' await browser_manager.notify_user( f'Pressed the Enter key successfully on element: "{click_selector}".', message_type=MessageType.ACTION, @@ -175,15 +156,11 @@ async def handle_dialog(dialog: Any) -> None: else: await browser_manager.highlight_element(click_selector, True) - do_click_result = await do_click( - page, click_selector, wait_before_click_execution - ) + do_click_result = await do_click(page, click_selector, wait_before_click_execution) result["detailed_message"] += f' {do_click_result["detailed_message"]}' # await browser_manager.notify_user(do_click_result["summary_message"]) - await asyncio.sleep( - 0.1 - ) # sleep for 100ms to allow the mutation observer to detect changes + await asyncio.sleep(0.1) # sleep for 100ms to allow the mutation observer to detect changes await browser_manager.take_screenshots(f"{function_name}_end", page)