add action setup/teardown stage (#159)
This commit is contained in:
@@ -6,10 +6,6 @@ Each element is tagged with an ID.
|
|||||||
If you see any information in red in the page screenshot, this means a condition wasn't satisfied. prioritize actions with the red information.
|
If you see any information in red in the page screenshot, this means a condition wasn't satisfied. prioritize actions with the red information.
|
||||||
If you see a popup in the page screenshot, prioritize actions on the popup.
|
If you see a popup in the page screenshot, prioritize actions on the popup.
|
||||||
|
|
||||||
{% if "lever" in url %}
|
|
||||||
DO NOT UPDATE ANY LOCATION FIELDS
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
Reply in JSON format with the following keys:
|
Reply in JSON format with the following keys:
|
||||||
{
|
{
|
||||||
"actions": array // An array of actions. Here's the format of each action:
|
"actions": array // An array of actions. Here's the format of each action:
|
||||||
|
|||||||
@@ -30,6 +30,14 @@ class ActionHandler:
|
|||||||
ActionType, Callable[[Action, Page, ScrapedPage, Task, Step], Awaitable[list[ActionResult]]]
|
ActionType, Callable[[Action, Page, ScrapedPage, Task, Step], Awaitable[list[ActionResult]]]
|
||||||
] = {}
|
] = {}
|
||||||
|
|
||||||
|
_setup_action_types: dict[
|
||||||
|
ActionType, Callable[[Action, Page, ScrapedPage, Task, Step], Awaitable[list[ActionResult]]]
|
||||||
|
] = {}
|
||||||
|
|
||||||
|
_teardown_action_types: dict[
|
||||||
|
ActionType, Callable[[Action, Page, ScrapedPage, Task, Step], Awaitable[list[ActionResult]]]
|
||||||
|
] = {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def register_action_type(
|
def register_action_type(
|
||||||
cls,
|
cls,
|
||||||
@@ -38,6 +46,22 @@ class ActionHandler:
|
|||||||
) -> None:
|
) -> None:
|
||||||
cls._handled_action_types[action_type] = handler
|
cls._handled_action_types[action_type] = handler
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def register_setup_for_action_type(
|
||||||
|
cls,
|
||||||
|
action_type: ActionType,
|
||||||
|
handler: Callable[[Action, Page, ScrapedPage, Task, Step], Awaitable[list[ActionResult]]],
|
||||||
|
) -> None:
|
||||||
|
cls._setup_action_types[action_type] = handler
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def register_teardown_for_action_type(
|
||||||
|
cls,
|
||||||
|
action_type: ActionType,
|
||||||
|
handler: Callable[[Action, Page, ScrapedPage, Task, Step], Awaitable[list[ActionResult]]],
|
||||||
|
) -> None:
|
||||||
|
cls._teardown_action_types[action_type] = handler
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def handle_action(
|
async def handle_action(
|
||||||
scraped_page: ScrapedPage,
|
scraped_page: ScrapedPage,
|
||||||
@@ -50,8 +74,31 @@ class ActionHandler:
|
|||||||
page = await browser_state.get_or_create_page()
|
page = await browser_state.get_or_create_page()
|
||||||
try:
|
try:
|
||||||
if action.action_type in ActionHandler._handled_action_types:
|
if action.action_type in ActionHandler._handled_action_types:
|
||||||
|
actions_result: list[ActionResult] = []
|
||||||
|
|
||||||
|
# do setup before action handler
|
||||||
|
if setup := ActionHandler._setup_action_types.get(action.action_type):
|
||||||
|
results = await setup(action, page, scraped_page, task, step)
|
||||||
|
actions_result.extend(results)
|
||||||
|
if results and results[-1] != ActionSuccess:
|
||||||
|
return actions_result
|
||||||
|
|
||||||
|
# do the handler
|
||||||
handler = ActionHandler._handled_action_types[action.action_type]
|
handler = ActionHandler._handled_action_types[action.action_type]
|
||||||
return await handler(action, page, scraped_page, task, step)
|
results = await handler(action, page, scraped_page, task, step)
|
||||||
|
actions_result.extend(results)
|
||||||
|
if not results or type(actions_result[-1]) != ActionSuccess:
|
||||||
|
return actions_result
|
||||||
|
|
||||||
|
# do the teardown
|
||||||
|
teardown = ActionHandler._teardown_action_types.get(action.action_type)
|
||||||
|
if not teardown:
|
||||||
|
return actions_result
|
||||||
|
|
||||||
|
results = await teardown(action, page, scraped_page, task, step)
|
||||||
|
actions_result.extend(results)
|
||||||
|
return actions_result
|
||||||
|
|
||||||
else:
|
else:
|
||||||
LOG.error("Unsupported action type in handler", action=action, type=type(action))
|
LOG.error("Unsupported action type in handler", action=action, type=type(action))
|
||||||
return [ActionFailure(Exception(f"Unsupported action type: {type(action)}"))]
|
return [ActionFailure(Exception(f"Unsupported action type: {type(action)}"))]
|
||||||
@@ -98,19 +145,6 @@ async def handle_input_text_action(
|
|||||||
await locator.clear()
|
await locator.clear()
|
||||||
text = get_actual_value_of_parameter_if_secret(task, action.text)
|
text = get_actual_value_of_parameter_if_secret(task, action.text)
|
||||||
await locator.fill(text, timeout=SettingsManager.get_settings().BROWSER_ACTION_TIMEOUT_MS)
|
await locator.fill(text, timeout=SettingsManager.get_settings().BROWSER_ACTION_TIMEOUT_MS)
|
||||||
|
|
||||||
# This is a hack that gets dropdowns to select the "best" option based on what's typed
|
|
||||||
# Fixes situations like tsk_228671423990405776 where the location isn't being autocompleted
|
|
||||||
await locator.press("Tab", timeout=SettingsManager.get_settings().BROWSER_ACTION_TIMEOUT_MS)
|
|
||||||
input_value = await locator.input_value(timeout=SettingsManager.get_settings().BROWSER_ACTION_TIMEOUT_MS)
|
|
||||||
if not input_value:
|
|
||||||
LOG.info("Failed to input the text, trying to press sequentially with an enter click", action=action)
|
|
||||||
await locator.clear()
|
|
||||||
await locator.press_sequentially(text, timeout=SettingsManager.get_settings().BROWSER_ACTION_TIMEOUT_MS)
|
|
||||||
await locator.press("Enter", timeout=SettingsManager.get_settings().BROWSER_ACTION_TIMEOUT_MS)
|
|
||||||
input_value = await locator.input_value(timeout=SettingsManager.get_settings().BROWSER_ACTION_TIMEOUT_MS)
|
|
||||||
LOG.info("Input value", input_value=input_value, action=action)
|
|
||||||
|
|
||||||
return [ActionSuccess()]
|
return [ActionSuccess()]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user