helper function for wait animation (#3240)
This commit is contained in:
@@ -974,18 +974,7 @@ async def handle_input_text_action(
|
||||
action=action,
|
||||
)
|
||||
|
||||
try:
|
||||
await skyvern_frame.get_frame().wait_for_load_state("load", timeout=3000)
|
||||
await skyvern_frame.safe_wait_for_animation_end()
|
||||
except Exception:
|
||||
LOG.info(
|
||||
"Timeout to wait for the frame to load, ignore the timeout and continue to execute the action",
|
||||
task_id=task.task_id,
|
||||
step_id=step.step_id,
|
||||
element_id=skyvern_element.get_id(),
|
||||
action=action,
|
||||
)
|
||||
|
||||
await skyvern_frame.safe_wait_for_animation_end()
|
||||
incremental_element = await incremental_scraped.get_incremental_element_tree(
|
||||
clean_and_remove_element_tree_factory(
|
||||
task=task, step=step, check_filter_funcs=[check_existed_but_not_option_element_in_dom_factory(dom)]
|
||||
@@ -1126,18 +1115,7 @@ async def handle_input_text_action(
|
||||
return [ActionFailure(InvalidElementForTextInput(element_id=action.element_id, tag_name=tag_name))]
|
||||
|
||||
# wait for blocking element to show up
|
||||
try:
|
||||
await skyvern_frame.get_frame().wait_for_load_state("load", timeout=3000)
|
||||
await skyvern_frame.safe_wait_for_animation_end()
|
||||
except Exception:
|
||||
LOG.info(
|
||||
"Timeout to wait for the frame to load, ignore the timeout and continue to execute the action",
|
||||
task_id=task.task_id,
|
||||
step_id=step.step_id,
|
||||
element_id=skyvern_element.get_id(),
|
||||
action=action,
|
||||
)
|
||||
|
||||
await skyvern_frame.safe_wait_for_animation_end()
|
||||
try:
|
||||
blocking_element, exist = await skyvern_element.find_blocking_element(
|
||||
dom=dom, incremental_page=incremental_scraped
|
||||
@@ -1538,15 +1516,7 @@ async def handle_select_option_action(
|
||||
|
||||
await skyvern_element.click(page=page, dom=dom, timeout=timeout)
|
||||
# wait for options to load
|
||||
await asyncio.sleep(0.5)
|
||||
try:
|
||||
await skyvern_frame.get_frame().wait_for_event("load", timeout=3000)
|
||||
await skyvern_frame.safe_wait_for_animation_end()
|
||||
except Exception:
|
||||
LOG.info(
|
||||
"Failed to wait for the frame to load, ignore the timeout and continue to get incremental element tree",
|
||||
exc_info=True,
|
||||
)
|
||||
await skyvern_frame.safe_wait_for_animation_end(before_wait_sec=0.5)
|
||||
|
||||
incremental_element = await incremental_scraped.get_incremental_element_tree(
|
||||
clean_and_remove_element_tree_factory(
|
||||
@@ -1564,15 +1534,7 @@ async def handle_select_option_action(
|
||||
await skyvern_element.scroll_into_view()
|
||||
await skyvern_element.press_key("ArrowDown")
|
||||
# wait for options to load
|
||||
await asyncio.sleep(0.5)
|
||||
try:
|
||||
await skyvern_frame.get_frame().wait_for_event("load", timeout=3000)
|
||||
await skyvern_frame.safe_wait_for_animation_end()
|
||||
except Exception:
|
||||
LOG.info(
|
||||
"Failed to wait for the frame to load, ignore the timeout and continue to get incremental element tree",
|
||||
exc_info=True,
|
||||
)
|
||||
await skyvern_frame.safe_wait_for_animation_end(before_wait_sec=0.5)
|
||||
incremental_element = await incremental_scraped.get_incremental_element_tree(
|
||||
clean_and_remove_element_tree_factory(
|
||||
task=task, step=step, check_filter_funcs=[check_existed_but_not_option_element_in_dom_factory(dom)]
|
||||
@@ -1669,15 +1631,7 @@ async def handle_select_option_action(
|
||||
await skyvern_element.scroll_into_view()
|
||||
await skyvern_element.press_key("ArrowDown")
|
||||
|
||||
try:
|
||||
await asyncio.sleep(0.5)
|
||||
await skyvern_frame.get_frame().wait_for_event("load", timeout=3000)
|
||||
await skyvern_frame.safe_wait_for_animation_end()
|
||||
except Exception:
|
||||
LOG.info(
|
||||
"Failed to wait for the frame to load, ignore the exception and continue",
|
||||
exc_info=True,
|
||||
)
|
||||
await skyvern_frame.safe_wait_for_animation_end(before_wait_sec=0.5)
|
||||
is_open = True
|
||||
|
||||
result = await select_from_dropdown_by_value(
|
||||
@@ -2200,15 +2154,7 @@ async def choose_auto_completion_dropdown(
|
||||
try:
|
||||
await skyvern_element.press_fill(text)
|
||||
# wait for new elemnts to load
|
||||
try:
|
||||
await asyncio.sleep(0.5)
|
||||
await skyvern_frame.get_frame().wait_for_load_state("load", timeout=3000)
|
||||
await skyvern_frame.safe_wait_for_animation_end()
|
||||
except Exception:
|
||||
LOG.warning(
|
||||
"Failed to wait for load state or animation end after input the value, will continue to get incremental element tree",
|
||||
exc_info=True,
|
||||
)
|
||||
await skyvern_frame.safe_wait_for_animation_end(before_wait_sec=0.5)
|
||||
incremental_element = await incremental_scraped.get_incremental_element_tree(
|
||||
clean_and_remove_element_tree_factory(
|
||||
task=task, step=step, check_filter_funcs=[check_existed_but_not_option_element_in_dom_factory(dom)]
|
||||
@@ -2608,15 +2554,7 @@ async def sequentially_select_from_dropdown(
|
||||
select_history.append(single_select_result)
|
||||
values.append(single_select_result.value)
|
||||
# wait 1s until DOM finished updating
|
||||
try:
|
||||
await asyncio.sleep(0.5)
|
||||
await skyvern_frame.get_frame().wait_for_event("load", timeout=3000)
|
||||
await skyvern_frame.safe_wait_for_animation_end()
|
||||
except Exception:
|
||||
LOG.info(
|
||||
"Failed to wait for the animation to end, ignore the exception and continue",
|
||||
exc_info=True,
|
||||
)
|
||||
await skyvern_frame.safe_wait_for_animation_end(before_wait_sec=0.5)
|
||||
|
||||
if await single_select_result.is_done():
|
||||
return single_select_result
|
||||
@@ -2637,15 +2575,7 @@ async def sequentially_select_from_dropdown(
|
||||
step_id=step.step_id,
|
||||
)
|
||||
# wait to load new options
|
||||
try:
|
||||
await asyncio.sleep(0.5)
|
||||
await skyvern_frame.get_frame().wait_for_event("load", timeout=3000)
|
||||
await skyvern_frame.safe_wait_for_animation_end()
|
||||
except Exception:
|
||||
LOG.info(
|
||||
"Failed to wait for the animation to end, ignore the exception and continue",
|
||||
exc_info=True,
|
||||
)
|
||||
await skyvern_frame.safe_wait_for_animation_end(before_wait_sec=0.5)
|
||||
|
||||
check_filter_funcs.append(
|
||||
check_disappeared_element_id_in_incremental_factory(incremental_scraped=incremental_scraped)
|
||||
@@ -3356,29 +3286,13 @@ async def scroll_down_to_load_all_options(
|
||||
else:
|
||||
await skyvern_frame.scroll_to_element_bottom(dropdown_menu_element_handle, page_by_page)
|
||||
# wait until animation ends, otherwise the scroll operation could be overwritten
|
||||
try:
|
||||
await asyncio.sleep(0.5)
|
||||
await skyvern_frame.get_frame().wait_for_event("load", timeout=3000)
|
||||
await skyvern_frame.safe_wait_for_animation_end()
|
||||
except Exception:
|
||||
LOG.info(
|
||||
"Failed to wait for the animation to end, ignore the exception and continue",
|
||||
exc_info=True,
|
||||
)
|
||||
await skyvern_frame.safe_wait_for_animation_end(before_wait_sec=0.5)
|
||||
|
||||
# scroll a little back and scroll down to trigger the loading
|
||||
await page.mouse.wheel(0, -1e-5)
|
||||
await page.mouse.wheel(0, 1e-5)
|
||||
# wait for while to load new options
|
||||
try:
|
||||
await asyncio.sleep(0.5)
|
||||
await skyvern_frame.get_frame().wait_for_event("load", timeout=3000)
|
||||
await skyvern_frame.safe_wait_for_animation_end()
|
||||
except Exception:
|
||||
LOG.info(
|
||||
"Failed to wait for the animation to end, ignore the exception and continue",
|
||||
exc_info=True,
|
||||
)
|
||||
await skyvern_frame.safe_wait_for_animation_end(before_wait_sec=0.5)
|
||||
|
||||
current_num = await incremental_scraped.get_incremental_elements_num()
|
||||
LOG.info(
|
||||
@@ -3403,15 +3317,7 @@ async def scroll_down_to_load_all_options(
|
||||
await page.mouse.wheel(0, -scroll_pace)
|
||||
else:
|
||||
await skyvern_frame.scroll_to_element_top(dropdown_menu_element_handle)
|
||||
try:
|
||||
await asyncio.sleep(0.5)
|
||||
await skyvern_frame.get_frame().wait_for_event("load", timeout=3000)
|
||||
await skyvern_frame.safe_wait_for_animation_end()
|
||||
except Exception:
|
||||
LOG.info(
|
||||
"Failed to wait for the animation to end, ignore the exception and continue",
|
||||
exc_info=True,
|
||||
)
|
||||
await skyvern_frame.safe_wait_for_animation_end(before_wait_sec=0.5)
|
||||
|
||||
|
||||
async def normal_select(
|
||||
|
||||
@@ -555,12 +555,8 @@ async def scrape_web_unsafe(
|
||||
if url == "about:blank" and not support_empty_page:
|
||||
raise ScrapingFailedBlankPage()
|
||||
|
||||
try:
|
||||
await page.wait_for_load_state("load", timeout=3000)
|
||||
skyvern_frame = await SkyvernFrame.create_instance(page)
|
||||
await skyvern_frame.safe_wait_for_animation_end()
|
||||
except Exception:
|
||||
LOG.warning("Failed to wait for load state, will continue scraping", exc_info=True)
|
||||
skyvern_frame = await SkyvernFrame.create_instance(page)
|
||||
await skyvern_frame.safe_wait_for_animation_end()
|
||||
|
||||
if wait_seconds > 0:
|
||||
LOG.info(f"Waiting for {wait_seconds} seconds before scraping the website.", wait_seconds=wait_seconds)
|
||||
@@ -689,15 +685,7 @@ async def add_frame_interactable_elements(
|
||||
return elements, element_tree
|
||||
|
||||
skyvern_frame = await SkyvernFrame.create_instance(frame)
|
||||
try:
|
||||
await skyvern_frame.get_frame().wait_for_load_state("load", timeout=3000)
|
||||
await skyvern_frame.safe_wait_for_animation_end()
|
||||
except Exception:
|
||||
LOG.warning(
|
||||
"Failed to wait for load state or animation end for the frame, will continue scraping",
|
||||
frame_id=unique_id,
|
||||
exc_info=True,
|
||||
)
|
||||
await skyvern_frame.safe_wait_for_animation_end()
|
||||
|
||||
frame_elements, frame_element_tree = await skyvern_frame.build_tree_from_body(
|
||||
frame_name=unique_id, frame_index=frame_index
|
||||
|
||||
@@ -517,22 +517,23 @@ class SkyvernFrame:
|
||||
frame=self.frame, expression=js_script, timeout_ms=timeout_ms, arg=[starter, frame, full_tree]
|
||||
)
|
||||
|
||||
async def safe_wait_for_animation_end(self, timeout_ms: float = 3000) -> None:
|
||||
async def safe_wait_for_animation_end(self, before_wait_sec: float = 0, timeout_ms: float = 3000) -> None:
|
||||
try:
|
||||
async with asyncio.timeout(timeout_ms / 1000):
|
||||
while True:
|
||||
try:
|
||||
is_finished = await self.evaluate(
|
||||
frame=self.frame,
|
||||
expression="() => isAnimationFinished()",
|
||||
timeout_ms=timeout_ms,
|
||||
)
|
||||
if is_finished:
|
||||
return
|
||||
await asyncio.sleep(0.1)
|
||||
except Exception:
|
||||
LOG.warning("Failed to wait for animation end, but ignore it", exc_info=True)
|
||||
return
|
||||
except asyncio.TimeoutError:
|
||||
LOG.debug("Timeout while waiting for animation end, but ignore it", exc_info=True)
|
||||
await asyncio.sleep(before_wait_sec)
|
||||
await self.frame.wait_for_load_state("load", timeout=timeout_ms)
|
||||
await self.wait_for_animation_end(timeout_ms=timeout_ms)
|
||||
except Exception:
|
||||
LOG.info("Failed to wait for animation end, but ignore it", exc_info=True)
|
||||
return
|
||||
|
||||
async def wait_for_animation_end(self, timeout_ms: float = 3000) -> None:
|
||||
async with asyncio.timeout(timeout_ms / 1000):
|
||||
while True:
|
||||
is_finished = await self.evaluate(
|
||||
frame=self.frame,
|
||||
expression="() => isAnimationFinished()",
|
||||
timeout_ms=timeout_ms,
|
||||
)
|
||||
if is_finished:
|
||||
return
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
Reference in New Issue
Block a user