@@ -446,10 +446,16 @@ def find_elements(
446446 dictionaries. It does not return live SeleniumBase element objects.
447447
448448 Args:
449- selector: A SeleniumBase-supported selector, typically CSS or XPath.
449+ selector: A CSS selector, or an XPath selector that SeleniumBase can
450+ convert to CSS. In sb.find_elements, SeleniumBase automatically
451+ attempts to convert XPath to CSS. Some XPath expressions, such
452+ as those using `contains(...)`, cannot be converted to CSS and
453+ therefore aren't supported by this tool.
450454
451455 timeout: Maximum number of seconds to wait for at least one matching
452- element to appear.
456+ element to appear. If the selector is an XPath selector that
457+ cannot be converted into a valid CSS selector, then the wait
458+ might be less than the timeout.
453459
454460 include_html: If True, include each matching element's outer HTML.
455461 If False, return only tag name and text.
@@ -459,7 +465,8 @@ def find_elements(
459465 - count: Number of matching elements found.
460466 - matches: A list of element dictionaries containing tag_name and
461467 text, plus html when include_html=True.
462- If there's an error, returns a string with error details.
468+ If there's an error during search, then "error" is added into the
469+ returned dictionary with error details.
463470
464471 Tool selection:
465472 - Need structured information about matching elements ->
@@ -470,77 +477,63 @@ def find_elements(
470477 - Need to know whether an element is present/visible ->
471478 use check_condition.
472479
473- Note :
480+ Notes :
474481 Element handles cannot be persisted across MCP calls. If you find
475482 elements and then need to act on one, resolve it again with the
476483 appropriate interaction tool.
484+
485+ For uncaught errors, @handle_sb_errors returns strings.
477486 """
478487 sb = _get_sb ()
479- elements = sb . find_elements ( selector , timeout = timeout )
480-
481- if include_html :
488+ try :
489+ elements = sb . find_elements ( selector , timeout = timeout )
490+ except Exception as e :
482491 return {
483- "count" : len (elements ),
484- "matches" : [
485- {
486- "tag_name" : element .tag_name ,
487- "text" : element .text ,
488- "html" : element .get_html (),
489- }
490- for element in elements
491- ],
492+ "count" : 0 ,
493+ "matches" : [],
494+ "error" : str (e ),
492495 }
493496
497+ matches = []
498+ for element in elements :
499+ match = {
500+ "tag_name" : element .tag_name ,
501+ "text" : element .text ,
502+ }
503+ if include_html :
504+ match ["html" ] = element .get_html ()
505+ matches .append (match )
506+
494507 return {
495- "count" : len (elements ),
496- "matches" : [
497- {
498- "tag_name" : element .tag_name ,
499- "text" : element .text ,
500- }
501- for element in elements
502- ],
508+ "count" : len (matches ),
509+ "matches" : matches ,
503510 }
504511
505512
506513@mcp .tool ()
507514@handle_sb_errors
508515def get_content (
509- selector : str | None = None ,
516+ selector : str = "body" ,
510517 output_format : Literal ["text" , "html" , "urls" ] = "text" ,
511- include_shadow_dom : bool = True ,
518+ timeout : float = 5 ,
512519) -> str | list [str ]:
513- """Read visible text, HTML, or discovered URLs from the current page .
520+ """Read visible text, HTML, or discovered URLs from the selected element .
514521
515- Use this tool when you need actual page content or URL information rather
516- than page metadata.
522+ Use this tool when you need to get actual page content or URL information
523+ rather than page metadata.
517524
518525 Args:
519- selector: Optional CSS selector or SeleniumBase text-matching selector
520- identifying the element whose content should be read. For
521- output_format="text" or "html", the selector scopes the returned
522- content to that element. For output_format="urls", the selector
523- scopes URL discovery to URLs within that element. When omitted,
524- the operation applies to the whole page.
526+ selector: CSS selector or SeleniumBase-supported XPath selector.
525527
526528 output_format:
527- - "text": Return visible text from the page or selected element.
528- - "html": Return HTML from the page or selected element.
529- - "urls": Return URLs discovered by SeleniumBase from the page
530- or selected element. URLs associated with elements such as
531- anchors, links, images, scripts, and metadata may be included.
532- SeleniumBase returns full URLs with their URL protocol prefixes.
529+ - "text": Return visible text from the selected element.
530+ - "html": Return HTML from the selected element.
531+ - "urls": Return URLs discovered by SeleniumBase within the
532+ selected element. Returned URLs are normalized to full URLs
533+ with their protocol prefixes.
533534
534- include_shadow_dom: When output_format="html" and selector is omitted,
535- include any shadow-root HTML present in the page. This option has
536- no effect for "text" or "urls", or when a selector is specified.
537535
538- Returns:
539- For output_format="text", a string containing visible text.
540- For output_format="html", a string containing HTML.
541- For output_format="urls", a list of URL strings. This is useful for
542- crawling, link discovery, resource inspection, and finding candidate
543- URLs before navigating to them.
536+ timeout: Maximum seconds to wait for the target element. Default: 5.
544537
545538 Tool selection:
546539 - Need URL, title, origin, or User-Agent -> use get_page_info.
@@ -554,43 +547,44 @@ def get_content(
554547 """
555548 sb = _get_sb ()
556549
557- if output_format == "urls" :
558- return sb .get_all_urls (selector = selector )
559-
560- if selector is None :
561- if output_format == "html" :
562- return sb .get_page_source (
563- include_shadow_dom = include_shadow_dom
564- )
565- return sb .get_text ("body" )
550+ if output_format == "text" :
551+ return sb .get_text (selector , timeout = timeout )
566552
567553 if output_format == "html" :
568- return sb .get_element_html (selector )
554+ return sb .get_element_html (selector , timeout = timeout )
569555
570- return sb .get_text (selector )
556+ if output_format == "urls" :
557+ return sb .get_all_urls (selector = selector , timeout = timeout )
558+
559+ return (
560+ f"Error: unknown output_format '{ output_format } '. "
561+ "Use 'text', 'html', or 'urls'."
562+ )
571563
572564
573565@mcp .tool ()
574566@handle_sb_errors
575567def get_attributes (
576568 selector : str ,
577569 attribute : str | None = None ,
578- ) -> Any :
579- """Read HTML attributes from a matching element.
570+ timeout : float = 5 ,
571+ ) -> str | dict [str , Any ] | None :
572+ """Read HTML attributes from the first matching element.
580573
581- Use this tool when you need the value of one or more HTML attributes
582- such as href, src, value, class, id, name, type, aria-label, or data-*.
574+ Use this tool when you need the value of a specific HTML attribute,
575+ or all HTML attributes of an element. Attributes could be something
576+ such as href, src, value, class, id, name, type, aria-label, etc.
583577
584578 Args:
585- selector: CSS selector or SeleniumBase text-matching selector for
586- the target element.
579+ selector: CSS selector or SeleniumBase-supported XPath selector.
587580
588581 attribute: Specific HTML attribute to retrieve. When omitted, return
589- all HTML attributes of the element as a dictionary.
582+ all HTML attributes of the first matching element as a dictionary.
583+
584+ timeout: Maximum seconds to wait for the target element. Default: 5.
590585
591586 Returns:
592- The requested attribute value, or a dictionary containing all
593- HTML attributes of the element when attribute is omitted.
587+ The requested attribute(s).
594588
595589 Tool selection:
596590 - Need one or more HTML attribute values from a specific element ->
@@ -601,13 +595,16 @@ def get_attributes(
601595 - Need to check element presence/visibility -> use 'check_condition'.
602596
603597 This is a read-only operation.
598+
599+ If there's no matching element found within the timeout,
600+ then @handle_sb_errors will return details from the exception raised.
604601 """
605602 sb = _get_sb ()
606603
607604 if attribute :
608- return sb .get_attribute (selector , attribute )
605+ return sb .get_attribute (selector , attribute , timeout = timeout )
609606
610- return sb .get_element_attributes (selector )
607+ return sb .get_element_attributes (selector , timeout = timeout )
611608
612609
613610@mcp .tool ()
@@ -963,6 +960,7 @@ def focus(
963960 "focus" ,
964961 "highlight" ,
965962 ] = "scroll_to_element" ,
963+ timeout : float = 5 ,
966964) -> str :
967965 """Scroll to, focus, or highlight an element.
968966
@@ -976,16 +974,22 @@ def focus(
976974 - "scroll_to_element": Scroll the element into the viewport.
977975 - "focus": Move keyboard focus to the element.
978976 - "highlight": Temporarily highlight the element for debugging or
979- demonstration. May affect timing and reduce stealth.
977+ demonstration by changing the border color. May affect timing
978+ and/or reduce stealth.
979+
980+ timeout: Maximum seconds to wait for the target element. Default: 5.
981+
982+ If there's no matching element found within the timeout,
983+ then @handle_sb_errors will return details from the exception raised.
980984 """
981985 sb = _get_sb ()
982986
983987 if action == "scroll_to_element" :
984- sb .scroll_into_view (selector )
988+ sb .scroll_into_view (selector , timeout = timeout )
985989 elif action == "focus" :
986- sb .find_element (selector ).focus ()
990+ sb .find_element (selector , timeout = timeout ).focus ()
987991 elif action == "highlight" :
988- sb .highlight (selector )
992+ sb .highlight (selector , timeout = timeout )
989993 else :
990994 return (
991995 f"Error: unknown action '{ action } '. "
0 commit comments