Skip to content

Commit

Permalink
fixing negative testcase
Browse files Browse the repository at this point in the history
  • Loading branch information
shriyanshagnihotri committed Nov 15, 2024
1 parent d8771bc commit 35b6e4c
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
77 changes: 19 additions & 58 deletions testzeus_hercules/core/tools/click_using_selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.",
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand All @@ -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:
Expand All @@ -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')
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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}"
45 changes: 11 additions & 34 deletions testzeus_hercules/core/tools/enter_text_and_click.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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()
Expand All @@ -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)
Expand Down Expand Up @@ -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"):
Expand All @@ -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,
Expand All @@ -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)

Expand Down

0 comments on commit 35b6e4c

Please sign in to comment.