Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[grid] Dynamic Grid is able to trigger video record in browser node #15047

Merged
merged 4 commits into from
Jan 12, 2025

Conversation

VietND96
Copy link
Member

@VietND96 VietND96 commented Jan 8, 2025

User description

Thanks for contributing to Selenium!
A PR well described will help maintainers to quickly review and merge it

Before submitting your PR, please check our contributing guidelines.
Avoid large PRs, help reviewers by making them as simple and short as possible.

Description

Fixes #14757

  • The second container (video container) can be disabled by setting --docker-video-image false
  • If external video container is disabled, but session capabilities set se:recordVideo=true, the recording in the browser node can be triggered itself (details of the implementation is explained in Enable video recorder in Node/Standalone containers docker-selenium#2539)

If users want to use the previous approach for recording (backward compatible). Set below config
In TOML config

[docker]
video-image = "selenium/video:latest"

In CLI option

--docker-video-image "selenium/video:latest"

Motivation and Context

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • I have read the contributing document.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

PR Type

Enhancement


Description

  • Added ability to disable video container in Dynamic Grid.

  • Modified DockerOptions to handle false video-image configuration.

  • Updated DockerSessionFactory to check for null video image before starting.

  • Enhanced video container logic for better configurability.


Changes walkthrough 📝

Relevant files
Enhancement
DockerOptions.java
Handle disabling video container in DockerOptions               

java/src/org/openqa/selenium/grid/node/docker/DockerOptions.java

  • Added null check for video image loading.
  • Modified getVideoImage to handle false configuration.
  • Enhanced logic to skip video container setup when disabled.
  • +6/-1     
    DockerSessionFactory.java
    Update video container start logic in DockerSessionFactory

    java/src/org/openqa/selenium/grid/node/docker/DockerSessionFactory.java

  • Added null check for video image before starting video container.
  • Updated logic to ensure video container is not started unnecessarily.
  • +1/-1     

    💡 PR-Agent usage: Comment /help "your question" on any pull request to receive relevant information

    Copy link
    Contributor

    qodo-merge-pro bot commented Jan 8, 2025

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    🎫 Ticket compliance analysis ✅

    14757 - PR Code Verified

    Compliant requirements:

    • Add ability to disable video container spawn in Dynamic Grid
    • Allow setting video container disable by passing 'false' value

    Requires further human verification:

    • Verify if TOML config support works as expected
    • Verify if video recording via environment variable works correctly
    ⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Null Check

    The video container logic now returns null in two cases but there's no documentation about the behavior change. This could affect downstream code expecting non-null containers.

    if (videoImage == null || !recordVideoForSession(sessionCapabilities)) {
      return null;

    Copy link
    Contributor

    qodo-merge-pro bot commented Jan 8, 2025

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Score
    General
    Use constants instead of string literals for configuration values to improve code maintainability

    Add case-insensitive constant for "false" string comparison to improve
    maintainability and prevent string literal duplication.

    java/src/org/openqa/selenium/grid/node/docker/DockerOptions.java [229-231]

    -if (videoImage.equalsIgnoreCase("false")) {
    +private static final String DISABLED_VALUE = "false";
    +// ...
    +if (videoImage.equalsIgnoreCase(DISABLED_VALUE)) {
       return null;
     }
    Suggestion importance[1-10]: 5

    Why: Using a constant for the "false" string would improve maintainability and reduce magic strings in the code. This is a good practice, though not critical for functionality.

    5
    Possible issue
    Separate null checks from business logic to prevent potential null pointer exceptions and improve code clarity

    Add a null check for videoImage before attempting to access its properties or
    methods in other parts of the code to prevent potential NullPointerExceptions.

    java/src/org/openqa/selenium/grid/node/docker/DockerSessionFactory.java [338-340]

    -if (videoImage == null || !recordVideoForSession(sessionCapabilities)) {
    +if (videoImage == null) {
    +  return null;
    +}
    +if (!recordVideoForSession(sessionCapabilities)) {
       return null;
     }
    • Apply this suggestion
    Suggestion importance[1-10]: 3

    Why: While the suggestion aims to improve code clarity by separating conditions, the existing code is already safe and follows common practice of combining related conditions. The change would add unnecessary verbosity.

    3

    Copy link
    Contributor

    qodo-merge-pro bot commented Jan 8, 2025

    CI Failure Feedback 🧐

    (Checks updated until commit b20c9aa)

    Action: Python / Browser Tests (chrome, ubuntu) / Integration Tests (chrome, ubuntu)

    Failed stage: Run Bazel [❌]

    Failed test name: test_collect_log_mutations[chrome]

    Failure summary:

    The test failed due to an InvalidSelectorException in the test_collect_log_mutations[chrome] test.
    The error occurred when trying to find elements using an invalid CSS selector. Specifically, the
    test failed when attempting to find elements with a data-__webdriver_id attribute, but the selector
    syntax was invalid.

    Relevant error logs:
    1:  ##[group]Operating System
    2:  Ubuntu
    ...
    
    972:  Package 'php-symfony-debug-bundle' is not installed, so not removed
    973:  Package 'php-symfony-dependency-injection' is not installed, so not removed
    974:  Package 'php-symfony-deprecation-contracts' is not installed, so not removed
    975:  Package 'php-symfony-discord-notifier' is not installed, so not removed
    976:  Package 'php-symfony-doctrine-bridge' is not installed, so not removed
    977:  Package 'php-symfony-doctrine-messenger' is not installed, so not removed
    978:  Package 'php-symfony-dom-crawler' is not installed, so not removed
    979:  Package 'php-symfony-dotenv' is not installed, so not removed
    980:  Package 'php-symfony-error-handler' is not installed, so not removed
    ...
    
    1963:  Setting up fonts-terminus-otb (4.48-3.1) ...
    1964:  Processing triggers for install-info (6.8-4build1) ...
    1965:  Processing triggers for mailcap (3.70+nmu1ubuntu1) ...
    1966:  Processing triggers for fontconfig (2.13.1-4.2ubuntu5) ...
    1967:  Processing triggers for hicolor-icon-theme (0.17-2) ...
    1968:  Processing triggers for libc-bin (2.35-0ubuntu3.8) ...
    1969:  Processing triggers for man-db (2.10.2-1) ...
    1970:  Processing triggers for menu (2.1.47ubuntu4) ...
    1971:  /usr/share/menu/tk8.6: 1: Syntax error: word unexpected (expecting ")")
    1972:  /usr/share/menu/monodoc-http: 1: Syntax error: word unexpected (expecting ")")
    1973:  /usr/share/menu/telnet: 1: Syntax error: word unexpected (expecting ")")
    1974:  /usr/share/menu/dash: 1: Syntax error: word unexpected (expecting ")")
    1975:  /usr/share/menu/google-chrome.menu: 1: Syntax error: word unexpected (expecting ")")
    1976:  /usr/share/menu/microsoft-edge.menu: 1: Syntax error: word unexpected (expecting ")")
    1977:  /usr/share/menu/procps: 1: Syntax error: word unexpected (expecting ")")
    1978:  /usr/share/menu/psmisc: 1: Syntax error: word unexpected (expecting ")")
    1979:  /usr/share/menu/tcl8.6: 1: Syntax error: word unexpected (expecting ")")
    1980:  /usr/share/menu/bash: 1: Syntax error: word unexpected (expecting ")")
    1981:  Warning: Failed to open file(/usr/share/fluxbox/nls/C.UTF-8/fluxbox.cat)
    1982:  for translation, using default messages.
    1983:  Failed to read: session.ignoreBorder
    1984:  Setting default value
    1985:  Failed to read: session.forcePseudoTransparency
    1986:  Setting default value
    1987:  Failed to read: session.colorsPerChannel
    1988:  Setting default value
    1989:  Failed to read: session.doubleClickInterval
    1990:  Setting default value
    1991:  Failed to read: session.tabPadding
    1992:  Setting default value
    1993:  Failed to read: session.styleOverlay
    1994:  Setting default value
    1995:  Failed to read: session.slitlistFile
    1996:  Setting default value
    1997:  Failed to read: session.appsFile
    1998:  Setting default value
    1999:  Failed to read: session.tabsAttachArea
    2000:  Setting default value
    2001:  Failed to read: session.cacheLife
    2002:  Setting default value
    2003:  Failed to read: session.cacheMax
    2004:  Setting default value
    2005:  Failed to read: session.autoRaiseDelay
    2006:  Setting default value
    2007:  Failed to read: session.ignoreBorder
    2008:  Setting default value
    2009:  Failed to read: session.forcePseudoTransparency
    2010:  Setting default value
    2011:  Failed to read: session.colorsPerChannel
    2012:  Setting default value
    2013:  Failed to read: session.doubleClickInterval
    2014:  Setting default value
    2015:  Failed to read: session.tabPadding
    2016:  Setting default value
    2017:  Failed to read: session.styleOverlay
    2018:  Setting default value
    2019:  Failed to read: session.slitlistFile
    2020:  Setting default value
    2021:  Failed to read: session.appsFile
    2022:  Setting default value
    2023:  Failed to read: session.tabsAttachArea
    2024:  Setting default value
    2025:  Failed to read: session.cacheLife
    2026:  Setting default value
    2027:  Failed to read: session.cacheMax
    2028:  Setting default value
    2029:  Failed to read: session.autoRaiseDelay
    2030:  Setting default value
    2031:  Failed to read: session.screen0.opaqueMove
    2032:  Setting default value
    2033:  Failed to read: session.screen0.fullMaximization
    2034:  Setting default value
    2035:  Failed to read: session.screen0.maxIgnoreIncrement
    2036:  Setting default value
    2037:  Failed to read: session.screen0.maxDisableMove
    2038:  Setting default value
    2039:  Failed to read: session.screen0.maxDisableResize
    2040:  Setting default value
    2041:  Failed to read: session.screen0.workspacewarping
    2042:  Setting default value
    2043:  Failed to read: session.screen0.showwindowposition
    2044:  Setting default value
    2045:  Failed to read: session.screen0.autoRaise
    2046:  Setting default value
    2047:  Failed to read: session.screen0.clickRaises
    2048:  Setting default value
    2049:  Failed to read: session.screen0.defaultDeco
    2050:  Setting default value
    2051:  Failed to read: session.screen0.tab.placement
    2052:  Setting default value
    2053:  Failed to read: session.screen0.windowMenu
    2054:  Setting default value
    2055:  Failed to read: session.screen0.noFocusWhileTypingDelay
    2056:  Setting default value
    2057:  Failed to read: session.screen0.workspaces
    2058:  Setting default value
    2059:  Failed to read: session.screen0.edgeSnapThreshold
    2060:  Setting default value
    2061:  Failed to read: session.screen0.window.focus.alpha
    2062:  Setting default value
    2063:  Failed to read: session.screen0.window.unfocus.alpha
    2064:  Setting default value
    2065:  Failed to read: session.screen0.menu.alpha
    2066:  Setting default value
    2067:  Failed to read: session.screen0.menuDelay
    2068:  Setting default value
    2069:  Failed to read: session.screen0.tab.width
    2070:  Setting default value
    2071:  Failed to read: session.screen0.tooltipDelay
    2072:  Setting default value
    2073:  Failed to read: session.screen0.allowRemoteActions
    2074:  Setting default value
    2075:  Failed to read: session.screen0.clientMenu.usePixmap
    2076:  Setting default value
    2077:  Failed to read: session.screen0.tabs.usePixmap
    2078:  Setting default value
    2079:  Failed to read: session.screen0.tabs.maxOver
    2080:  Setting default value
    2081:  Failed to read: session.screen0.tabs.intitlebar
    2082:  Setting default value
    2083:  Failed to read: session.screen0.focusModel
    2084:  Setting default value
    2085:  Failed to read: session.screen0.tabFocusModel
    2086:  Setting default value
    2087:  Failed to read: session.screen0.focusNewWindows
    2088:  Setting default value
    2089:  Failed to read: session.screen0.focusSameHead
    2090:  Setting default value
    2091:  Failed to read: session.screen0.rowPlacementDirection
    2092:  Setting default value
    2093:  Failed to read: session.screen0.colPlacementDirection
    2094:  Setting default value
    2095:  Failed to read: session.screen0.windowPlacement
    2096:  Setting default value
    2097:  Failed to read: session.ignoreBorder
    2098:  Setting default value
    2099:  Failed to read: session.forcePseudoTransparency
    2100:  Setting default value
    2101:  Failed to read: session.colorsPerChannel
    2102:  Setting default value
    2103:  Failed to read: session.doubleClickInterval
    2104:  Setting default value
    2105:  Failed to read: session.tabPadding
    2106:  Setting default value
    2107:  Failed to read: session.styleOverlay
    2108:  Setting default value
    2109:  Failed to read: session.slitlistFile
    2110:  Setting default value
    2111:  Failed to read: session.appsFile
    2112:  Setting default value
    2113:  Failed to read: session.tabsAttachArea
    2114:  Setting default value
    2115:  Failed to read: session.cacheLife
    2116:  Setting default value
    2117:  Failed to read: session.cacheMax
    2118:  Setting default value
    2119:  Failed to read: session.autoRaiseDelay
    2120:  Setting default value
    2121:  Failed to read: session.screen0.opaqueMove
    2122:  Setting default value
    2123:  Failed to read: session.screen0.fullMaximization
    2124:  Setting default value
    2125:  Failed to read: session.screen0.maxIgnoreIncrement
    2126:  Setting default value
    2127:  Failed to read: session.screen0.maxDisableMove
    2128:  Setting default value
    2129:  Failed to read: session.screen0.maxDisableResize
    2130:  Setting default value
    2131:  Failed to read: session.screen0.workspacewarping
    2132:  Setting default value
    2133:  Failed to read: session.screen0.showwindowposition
    2134:  Setting default value
    2135:  Failed to read: session.screen0.autoRaise
    2136:  Setting default value
    2137:  Failed to read: session.screen0.clickRaises
    2138:  Setting default value
    2139:  Failed to read: session.screen0.defaultDeco
    2140:  Setting default value
    2141:  Failed to read: session.screen0.tab.placement
    2142:  Setting default value
    2143:  Failed to read: session.screen0.windowMenu
    2144:  Setting default value
    2145:  Failed to read: session.screen0.noFocusWhileTypingDelay
    2146:  Setting default value
    2147:  Failed to read: session.screen0.workspaces
    2148:  Setting default value
    2149:  Failed to read: session.screen0.edgeSnapThreshold
    2150:  Setting default value
    2151:  Failed to read: session.screen0.window.focus.alpha
    2152:  Setting default value
    2153:  Failed to read: session.screen0.window.unfocus.alpha
    2154:  Setting default value
    2155:  Failed to read: session.screen0.menu.alpha
    2156:  Setting default value
    2157:  Failed to read: session.screen0.menuDelay
    2158:  Setting default value
    2159:  Failed to read: session.screen0.tab.width
    2160:  Setting default value
    2161:  Failed to read: session.screen0.tooltipDelay
    2162:  Setting default value
    2163:  Failed to read: session.screen0.allowRemoteActions
    2164:  Setting default value
    2165:  Failed to read: session.screen0.clientMenu.usePixmap
    2166:  Setting default value
    2167:  Failed to read: session.screen0.tabs.usePixmap
    2168:  Setting default value
    2169:  Failed to read: session.screen0.tabs.maxOver
    2170:  Setting default value
    2171:  Failed to read: session.screen0.tabs.intitlebar
    2172:  Setting default value
    2173:  Failed to read: session.screen0.focusModel
    2174:  Setting default value
    2175:  Failed to read: session.screen0.tabFocusModel
    2176:  Setting default value
    2177:  Failed to read: session.screen0.focusNewWindows
    2178:  Setting default value
    2179:  Failed to read: session.screen0.focusSameHead
    2180:  Setting default value
    2181:  Failed to read: session.screen0.rowPlacementDirection
    2182:  Setting default value
    2183:  Failed to read: session.screen0.colPlacementDirection
    2184:  Setting default value
    2185:  Failed to read: session.screen0.windowPlacement
    2186:  Setting default value
    2187:  Failed to read: session.screen0.slit.acceptKdeDockapps
    2188:  Setting default value
    2189:  Failed to read: session.screen0.slit.autoHide
    2190:  Setting default value
    2191:  Failed to read: session.screen0.slit.maxOver
    2192:  Setting default value
    2193:  Failed to read: session.screen0.slit.placement
    2194:  Setting default value
    2195:  Failed to read: session.screen0.slit.alpha
    2196:  Setting default value
    2197:  Failed to read: session.screen0.slit.onhead
    2198:  Setting default value
    2199:  Failed to read: session.screen0.slit.layer
    2200:  Setting default value
    2201:  Failed to read: session.screen0.toolbar.autoHide
    2202:  Setting default value
    2203:  Failed to read: session.screen0.toolbar.maxOver
    2204:  Setting default value
    2205:  Failed to read: session.screen0.toolbar.visible
    2206:  Setting default value
    2207:  Failed to read: session.screen0.toolbar.alpha
    2208:  Setting default value
    2209:  Failed to read: session.screen0.toolbar.layer
    2210:  Setting default value
    2211:  Failed to read: session.screen0.toolbar.onhead
    2212:  Setting default value
    2213:  Failed to read: session.screen0.toolbar.placement
    2214:  Setting default value
    2215:  Failed to read: session.screen0.toolbar.height
    2216:  Setting default value
    2217:  Failed to read: session.screen0.iconbar.mode
    2218:  Setting default value
    2219:  Failed to read: session.screen0.iconbar.alignment
    2220:  Setting default value
    2221:  Failed to read: session.screen0.iconbar.iconWidth
    2222:  Setting default value
    2223:  Failed to read: session.screen0.iconbar.iconTextPadding
    2224:  Setting default value
    2225:  Failed to read: session.screen0.iconbar.usePixmap
    ...
    
    2529:  �[32m[1,028 / 1,048]�[0m 33 / 53 tests;�[0m Testing //py:common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py; 46s local, disk-cache ... (4 actions, 2 running)
    2530:  �[32m[1,028 / 1,048]�[0m 33 / 53 tests;�[0m Testing //py:common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py; 56s local, disk-cache ... (4 actions, 2 running)
    2531:  �[32m[1,028 / 1,048]�[0m 33 / 53 tests;�[0m Testing //py:common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py; 60s local, disk-cache ... (4 actions, 3 running)
    2532:  �[32m[1,029 / 1,048]�[0m 34 / 53 tests;�[0m Testing //py:common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py; 61s local, disk-cache ... (4 actions, 2 running)
    2533:  �[32m[1,029 / 1,048]�[0m 34 / 53 tests;�[0m Testing //py:common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py; 71s local, disk-cache ... (4 actions, 2 running)
    2534:  �[32m[1,030 / 1,048]�[0m 35 / 53 tests;�[0m Testing //py:common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py; 72s local, disk-cache ... (4 actions, 1 running)
    2535:  �[32m[1,030 / 1,048]�[0m 35 / 53 tests;�[0m Testing //py:common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py; 77s local, disk-cache ... (4 actions, 2 running)
    2536:  �[31m�[1mFAIL: �[0m//py:common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py (see /home/runner/.bazel/execroot/_main/bazel-out/k8-fastbuild/testlogs/py/common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py/test.log)
    2537:  �[31m�[1mFAILED: �[0m//py:common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py (Summary)
    ...
    
    2542:  ==================== Test output for //py:common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py:
    2543:  ============================= test session starts ==============================
    2544:  platform linux -- Python 3.8.19, pytest-7.4.4, pluggy-1.3.0
    2545:  rootdir: /home/runner/.bazel/execroot/_main/bazel-out/k8-fastbuild/bin/py/common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py.runfiles/_main/py
    2546:  configfile: pyproject.toml
    2547:  plugins: instafail-0.5.0, trio-0.8.0, mock-3.12.0
    2548:  collected 4 items
    2549:  py/test/selenium/webdriver/common/bidi_tests.py::test_check_console_messages[chrome] PASSED [ 25%]
    2550:  py/test/selenium/webdriver/common/bidi_tests.py::test_check_error_console_messages[chrome] PASSED [ 50%]
    2551:  py/test/selenium/webdriver/common/bidi_tests.py::test_collect_js_exceptions[chrome] PASSED [ 75%]
    2552:  py/test/selenium/webdriver/common/bidi_tests.py::test_collect_log_mutations[chrome] FAILED [100%]
    ...
    
    2569:  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
    2570:  /home/runner/.bazel/external/rules_python~~python~python_3_8_x86_64-unknown-linux-gnu/lib/python3.8/contextlib.py:178: in __aexit__
    2571:  await self.gen.__anext__()
    2572:  py/selenium/webdriver/common/log.py:93: in mutation_events
    2573:  elements: list = self.driver.find_elements(By.CSS_SELECTOR, f"*[data-__webdriver_id={payload['target']}]")
    2574:  py/selenium/webdriver/remote/webdriver.py:844: in find_elements
    2575:  return self.execute(Command.FIND_ELEMENTS, {"using": by, "value": value})["value"] or []
    2576:  py/selenium/webdriver/remote/webdriver.py:404: in execute
    2577:  self.error_handler.check_response(response)
    2578:  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
    2579:  self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x7f63a9c961c0>
    2580:  response = {'status': 400, 'value': '{"value":{"error":"invalid selector","message":"invalid selector\\nfrom javascript error: {\...\\n#19 0x55c609ea4450 \\u003Cunknown>\\n#20 0x55c609eb4076 \\u003Cunknown>\\n#21 0x7f0a51a94ac3 \\u003Cunknown>\\n"}}'}
    2581:  def check_response(self, response: Dict[str, Any]) -> None:
    2582:  """Checks that a JSON response from the WebDriver does not have an
    2583:  error.
    2584:  :Args:
    2585:  - response - The JSON response from the WebDriver server as a dictionary
    2586:  object.
    2587:  :Raises: If the response contains an error message.
    2588:  """
    2589:  status = response.get("status", None)
    2590:  if not status or status == ErrorCode.SUCCESS:
    ...
    
    2596:  if isinstance(status, int):
    2597:  value_json = response.get("value", None)
    2598:  if value_json and isinstance(value_json, str):
    2599:  import json
    2600:  try:
    2601:  value = json.loads(value_json)
    2602:  if len(value) == 1:
    2603:  value = value["value"]
    2604:  status = value.get("error", None)
    2605:  if not status:
    2606:  status = value.get("status", ErrorCode.UNKNOWN_ERROR)
    2607:  message = value.get("value") or value.get("message")
    2608:  if not isinstance(message, str):
    2609:  value = message
    2610:  message = message.get("message")
    2611:  else:
    2612:  message = value.get("message", None)
    2613:  except ValueError:
    2614:  pass
    2615:  exception_class: Type[WebDriverException]
    2616:  e = ErrorCode()
    2617:  error_codes = [item for item in dir(e) if not item.startswith("__")]
    2618:  for error_code in error_codes:
    2619:  error_info = getattr(ErrorCode, error_code)
    2620:  if isinstance(error_info, list) and status in error_info:
    2621:  exception_class = getattr(ExceptionMapping, error_code, WebDriverException)
    ...
    
    2645:  if line:
    2646:  file = f"{file}:{line}"
    2647:  meth = frame.get("methodName", "<anonymous>")
    2648:  if "className" in frame:
    2649:  meth = f"{frame['className']}.{meth}"
    2650:  msg = "    at %s (%s)"
    2651:  msg = msg % (meth, file)
    2652:  stacktrace.append(msg)
    2653:  except TypeError:
    ...
    
    2656:  alert_text = None
    2657:  if "data" in value:
    2658:  alert_text = value["data"].get("text")
    2659:  elif "alert" in value:
    2660:  alert_text = value["alert"].get("text")
    2661:  raise exception_class(message, screen, stacktrace, alert_text)  # type: ignore[call-arg]  # mypy is not smart enough here
    2662:  >       raise exception_class(message, screen, stacktrace)
    2663:  E       selenium.common.exceptions.InvalidSelectorException: Message: invalid selector
    2664:  E       from javascript error: {"status":32,"value":"An invalid or illegal selector was specified"}
    2665:  E         (Session info: chrome=131.0.6778.204); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#invalid-selector-exception
    ...
    
    2681:  E       #14 0x55c609e850c7 <unknown>
    2682:  E       #15 0x55c609e6e6cc <unknown>
    2683:  E       #16 0x55c609e85c47 <unknown>
    2684:  E       #17 0x55c609e5367f <unknown>
    2685:  E       #18 0x55c609ea4288 <unknown>
    2686:  E       #19 0x55c609ea4450 <unknown>
    2687:  E       #20 0x55c609eb4076 <unknown>
    2688:  E       #21 0x7f0a51a94ac3 <unknown>
    2689:  py/selenium/webdriver/remote/errorhandler.py:232: InvalidSelectorException
    2690:  =========================== short test summary info ============================
    2691:  FAILED py/test/selenium/webdriver/common/bidi_tests.py::test_collect_log_mutations[chrome] - selenium.common.exceptions.InvalidSelectorException: Message: invalid selector
    2692:  from javascript error: {"status":32,"value":"An invalid or illegal selector was specified"}
    2693:  (Session info: chrome=131.0.6778.204); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#invalid-selector-exception
    ...
    
    2709:  #14 0x55c609e850c7 <unknown>
    2710:  #15 0x55c609e6e6cc <unknown>
    2711:  #16 0x55c609e85c47 <unknown>
    2712:  #17 0x55c609e5367f <unknown>
    2713:  #18 0x55c609ea4288 <unknown>
    2714:  #19 0x55c609ea4450 <unknown>
    2715:  #20 0x55c609eb4076 <unknown>
    2716:  #21 0x7f0a51a94ac3 <unknown>
    2717:  ========================= 1 failed, 3 passed in 4.17s ==========================
    ...
    
    2719:  ==================== Test output for //py:common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py:
    2720:  ============================= test session starts ==============================
    2721:  platform linux -- Python 3.8.19, pytest-7.4.4, pluggy-1.3.0
    2722:  rootdir: /home/runner/.bazel/execroot/_main/bazel-out/k8-fastbuild/bin/py/common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py.runfiles/_main/py
    2723:  configfile: pyproject.toml
    2724:  plugins: instafail-0.5.0, trio-0.8.0, mock-3.12.0
    2725:  collected 4 items
    2726:  py/test/selenium/webdriver/common/bidi_tests.py::test_check_console_messages[chrome] PASSED [ 25%]
    2727:  py/test/selenium/webdriver/common/bidi_tests.py::test_check_error_console_messages[chrome] PASSED [ 50%]
    2728:  py/test/selenium/webdriver/common/bidi_tests.py::test_collect_js_exceptions[chrome] PASSED [ 75%]
    2729:  py/test/selenium/webdriver/common/bidi_tests.py::test_collect_log_mutations[chrome] FAILED [100%]
    ...
    
    2746:  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
    2747:  /home/runner/.bazel/external/rules_python~~python~python_3_8_x86_64-unknown-linux-gnu/lib/python3.8/contextlib.py:178: in __aexit__
    2748:  await self.gen.__anext__()
    2749:  py/selenium/webdriver/common/log.py:93: in mutation_events
    2750:  elements: list = self.driver.find_elements(By.CSS_SELECTOR, f"*[data-__webdriver_id={payload['target']}]")
    2751:  py/selenium/webdriver/remote/webdriver.py:844: in find_elements
    2752:  return self.execute(Command.FIND_ELEMENTS, {"using": by, "value": value})["value"] or []
    2753:  py/selenium/webdriver/remote/webdriver.py:404: in execute
    2754:  self.error_handler.check_response(response)
    2755:  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
    2756:  self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x7f72a4a09c70>
    2757:  response = {'status': 400, 'value': '{"value":{"error":"invalid selector","message":"invalid selector\\nfrom javascript error: {\...\\n#19 0x5611d3e6f450 \\u003Cunknown>\\n#20 0x5611d3e7f076 \\u003Cunknown>\\n#21 0x7f0ccc094ac3 \\u003Cunknown>\\n"}}'}
    2758:  def check_response(self, response: Dict[str, Any]) -> None:
    2759:  """Checks that a JSON response from the WebDriver does not have an
    2760:  error.
    2761:  :Args:
    2762:  - response - The JSON response from the WebDriver server as a dictionary
    2763:  object.
    2764:  :Raises: If the response contains an error message.
    2765:  """
    2766:  status = response.get("status", None)
    2767:  if not status or status == ErrorCode.SUCCESS:
    ...
    
    2773:  if isinstance(status, int):
    2774:  value_json = response.get("value", None)
    2775:  if value_json and isinstance(value_json, str):
    2776:  import json
    2777:  try:
    2778:  value = json.loads(value_json)
    2779:  if len(value) == 1:
    2780:  value = value["value"]
    2781:  status = value.get("error", None)
    2782:  if not status:
    2783:  status = value.get("status", ErrorCode.UNKNOWN_ERROR)
    2784:  message = value.get("value") or value.get("message")
    2785:  if not isinstance(message, str):
    2786:  value = message
    2787:  message = message.get("message")
    2788:  else:
    2789:  message = value.get("message", None)
    2790:  except ValueError:
    2791:  pass
    2792:  exception_class: Type[WebDriverException]
    2793:  e = ErrorCode()
    2794:  error_codes = [item for item in dir(e) if not item.startswith("__")]
    2795:  for error_code in error_codes:
    2796:  error_info = getattr(ErrorCode, error_code)
    2797:  if isinstance(error_info, list) and status in error_info:
    2798:  exception_class = getattr(ExceptionMapping, error_code, WebDriverException)
    ...
    
    2822:  if line:
    2823:  file = f"{file}:{line}"
    2824:  meth = frame.get("methodName", "<anonymous>")
    2825:  if "className" in frame:
    2826:  meth = f"{frame['className']}.{meth}"
    2827:  msg = "    at %s (%s)"
    2828:  msg = msg % (meth, file)
    2829:  stacktrace.append(msg)
    2830:  except TypeError:
    ...
    
    2833:  alert_text = None
    2834:  if "data" in value:
    2835:  alert_text = value["data"].get("text")
    2836:  elif "alert" in value:
    2837:  alert_text = value["alert"].get("text")
    2838:  raise exception_class(message, screen, stacktrace, alert_text)  # type: ignore[call-arg]  # mypy is not smart enough here
    2839:  >       raise exception_class(message, screen, stacktrace)
    2840:  E       selenium.common.exceptions.InvalidSelectorException: Message: invalid selector
    2841:  E       from javascript error: {"status":32,"value":"An invalid or illegal selector was specified"}
    2842:  E         (Session info: chrome=131.0.6778.204); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#invalid-selector-exception
    ...
    
    2858:  E       #14 0x5611d3e500c7 <unknown>
    2859:  E       #15 0x5611d3e396cc <unknown>
    2860:  E       #16 0x5611d3e50c47 <unknown>
    2861:  E       #17 0x5611d3e1e67f <unknown>
    2862:  E       #18 0x5611d3e6f288 <unknown>
    2863:  E       #19 0x5611d3e6f450 <unknown>
    2864:  E       #20 0x5611d3e7f076 <unknown>
    2865:  E       #21 0x7f0ccc094ac3 <unknown>
    2866:  py/selenium/webdriver/remote/errorhandler.py:232: InvalidSelectorException
    2867:  =========================== short test summary info ============================
    2868:  FAILED py/test/selenium/webdriver/common/bidi_tests.py::test_collect_log_mutations[chrome] - selenium.common.exceptions.InvalidSelectorException: Message: invalid selector
    2869:  from javascript error: {"status":32,"value":"An invalid or illegal selector was specified"}
    2870:  (Session info: chrome=131.0.6778.204); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#invalid-selector-exception
    ...
    
    2886:  #14 0x5611d3e500c7 <unknown>
    2887:  #15 0x5611d3e396cc <unknown>
    2888:  #16 0x5611d3e50c47 <unknown>
    2889:  #17 0x5611d3e1e67f <unknown>
    2890:  #18 0x5611d3e6f288 <unknown>
    2891:  #19 0x5611d3e6f450 <unknown>
    2892:  #20 0x5611d3e7f076 <unknown>
    2893:  #21 0x7f0ccc094ac3 <unknown>
    2894:  ========================= 1 failed, 3 passed in 4.15s ==========================
    ...
    
    2896:  ==================== Test output for //py:common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py:
    2897:  ============================= test session starts ==============================
    2898:  platform linux -- Python 3.8.19, pytest-7.4.4, pluggy-1.3.0
    2899:  rootdir: /home/runner/.bazel/execroot/_main/bazel-out/k8-fastbuild/bin/py/common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py.runfiles/_main/py
    2900:  configfile: pyproject.toml
    2901:  plugins: instafail-0.5.0, trio-0.8.0, mock-3.12.0
    2902:  collected 4 items
    2903:  py/test/selenium/webdriver/common/bidi_tests.py::test_check_console_messages[chrome] PASSED [ 25%]
    2904:  py/test/selenium/webdriver/common/bidi_tests.py::test_check_error_console_messages[chrome] PASSED [ 50%]
    2905:  py/test/selenium/webdriver/common/bidi_tests.py::test_collect_js_exceptions[chrome] PASSED [ 75%]
    2906:  py/test/selenium/webdriver/common/bidi_tests.py::test_collect_log_mutations[chrome] FAILED [100%]
    ...
    
    2923:  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
    2924:  /home/runner/.bazel/external/rules_python~~python~python_3_8_x86_64-unknown-linux-gnu/lib/python3.8/contextlib.py:178: in __aexit__
    2925:  await self.gen.__anext__()
    2926:  py/selenium/webdriver/common/log.py:93: in mutation_events
    2927:  elements: list = self.driver.find_elements(By.CSS_SELECTOR, f"*[data-__webdriver_id={payload['target']}]")
    2928:  py/selenium/webdriver/remote/webdriver.py:844: in find_elements
    2929:  return self.execute(Command.FIND_ELEMENTS, {"using": by, "value": value})["value"] or []
    2930:  py/selenium/webdriver/remote/webdriver.py:404: in execute
    2931:  self.error_handler.check_response(response)
    2932:  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
    2933:  self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x7f36d50ca8e0>
    2934:  response = {'status': 400, 'value': '{"value":{"error":"invalid selector","message":"invalid selector\\nfrom javascript error: {\...\\n#19 0x5568132c6450 \\u003Cunknown>\\n#20 0x5568132d6076 \\u003Cunknown>\\n#21 0x7f277a494ac3 \\u003Cunknown>\\n"}}'}
    2935:  def check_response(self, response: Dict[str, Any]) -> None:
    2936:  """Checks that a JSON response from the WebDriver does not have an
    2937:  error.
    2938:  :Args:
    2939:  - response - The JSON response from the WebDriver server as a dictionary
    2940:  object.
    2941:  :Raises: If the response contains an error message.
    2942:  """
    2943:  status = response.get("status", None)
    2944:  if not status or status == ErrorCode.SUCCESS:
    ...
    
    2950:  if isinstance(status, int):
    2951:  value_json = response.get("value", None)
    2952:  if value_json and isinstance(value_json, str):
    2953:  import json
    2954:  try:
    2955:  value = json.loads(value_json)
    2956:  if len(value) == 1:
    2957:  value = value["value"]
    2958:  status = value.get("error", None)
    2959:  if not status:
    2960:  status = value.get("status", ErrorCode.UNKNOWN_ERROR)
    2961:  message = value.get("value") or value.get("message")
    2962:  if not isinstance(message, str):
    2963:  value = message
    2964:  message = message.get("message")
    2965:  else:
    2966:  message = value.get("message", None)
    2967:  except ValueError:
    2968:  pass
    2969:  exception_class: Type[WebDriverException]
    2970:  e = ErrorCode()
    2971:  error_codes = [item for item in dir(e) if not item.startswith("__")]
    2972:  for error_code in error_codes:
    2973:  error_info = getattr(ErrorCode, error_code)
    2974:  if isinstance(error_info, list) and status in error_info:
    2975:  exception_class = getattr(ExceptionMapping, error_code, WebDriverException)
    ...
    
    2999:  if line:
    3000:  file = f"{file}:{line}"
    3001:  meth = frame.get("methodName", "<anonymous>")
    3002:  if "className" in frame:
    3003:  meth = f"{frame['className']}.{meth}"
    3004:  msg = "    at %s (%s)"
    3005:  msg = msg % (meth, file)
    3006:  stacktrace.append(msg)
    3007:  except TypeError:
    ...
    
    3010:  alert_text = None
    3011:  if "data" in value:
    3012:  alert_text = value["data"].get("text")
    3013:  elif "alert" in value:
    3014:  alert_text = value["alert"].get("text")
    3015:  raise exception_class(message, screen, stacktrace, alert_text)  # type: ignore[call-arg]  # mypy is not smart enough here
    3016:  >       raise exception_class(message, screen, stacktrace)
    3017:  E       selenium.common.exceptions.InvalidSelectorException: Message: invalid selector
    3018:  E       from javascript error: {"status":32,"value":"An invalid or illegal selector was specified"}
    3019:  E         (Session info: chrome=131.0.6778.204); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#invalid-selector-exception
    ...
    
    3035:  E       #14 0x5568132a70c7 <unknown>
    3036:  E       #15 0x5568132906cc <unknown>
    3037:  E       #16 0x5568132a7c47 <unknown>
    3038:  E       #17 0x55681327567f <unknown>
    3039:  E       #18 0x5568132c6288 <unknown>
    3040:  E       #19 0x5568132c6450 <unknown>
    3041:  E       #20 0x5568132d6076 <unknown>
    3042:  E       #21 0x7f277a494ac3 <unknown>
    3043:  py/selenium/webdriver/remote/errorhandler.py:232: InvalidSelectorException
    3044:  =========================== short test summary info ============================
    3045:  FAILED py/test/selenium/webdriver/common/bidi_tests.py::test_collect_log_mutations[chrome] - selenium.common.exceptions.InvalidSelectorException: Message: invalid selector
    3046:  from javascript error: {"status":32,"value":"An invalid or illegal selector was specified"}
    3047:  (Session info: chrome=131.0.6778.204); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#invalid-selector-exception
    ...
    
    3063:  #14 0x5568132a70c7 <unknown>
    3064:  #15 0x5568132906cc <unknown>
    3065:  #16 0x5568132a7c47 <unknown>
    3066:  #17 0x55681327567f <unknown>
    3067:  #18 0x5568132c6288 <unknown>
    3068:  #19 0x5568132c6450 <unknown>
    3069:  #20 0x5568132d6076 <unknown>
    3070:  #21 0x7f277a494ac3 <unknown>
    3071:  ========================= 1 failed, 3 passed in 4.10s ==========================
    3072:  ================================================================================
    3073:  �[32m[1,031 / 1,048]�[0m 36 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/quit_tests.py; 18s ... (4 actions, 1 running)
    3074:  �[32m[1,032 / 1,048]�[0m 37 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/form_handling_tests.py; 7s ... (4 actions, 1 running)
    3075:  �[32m[1,032 / 1,048]�[0m 37 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/element_aria_tests.py ... (4 actions, 2 running)
    3076:  �[32m[1,033 / 1,048]�[0m 38 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/element_aria_tests.py; 5s ... (4 actions, 1 running)
    3077:  �[32m[1,033 / 1,048]�[0m 38 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/element_aria_tests.py; 15s ... (4 actions, 1 running)
    3078:  �[32m[1,033 / 1,048]�[0m 38 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/stale_reference_tests.py; 18s ... (4 actions, 2 running)
    3079:  �[32m[1,034 / 1,048]�[0m 39 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/stale_reference_tests.py; 20s ... (4 actions, 1 running)
    3080:  �[32m[1,034 / 1,048]�[0m 39 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/window_switching_tests.py; 20s ... (4 actions, 2 running)
    3081:  �[32m[1,035 / 1,048]�[0m 40 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/window_switching_tests.py; 22s ... (4 actions, 1 running)
    3082:  �[32m[1,035 / 1,048]�[0m 40 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/typing_tests.py; 5s ... (4 actions, 2 running)
    3083:  �[32m[1,036 / 1,048]�[0m 41 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/typing_tests.py; 7s ... (4 actions, 1 running)
    3084:  �[32m[1,036 / 1,048]�[0m 41 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/executing_javascript_tests.py; 12s ... (4 actions, 2 running)
    3085:  �[32m[1,037 / 1,048]�[0m 42 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/executing_javascript_tests.py; 13s ... (4 actions, 1 running)
    3086:  �[32m[1,037 / 1,048]�[0m 42 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/executing_javascript_tests.py; 24s ... (4 actions, 1 running)
    3087:  �[32m[1,037 / 1,048]�[0m 42 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/correct_event_firing_tests.py; 31s ... (4 actions, 2 running)
    3088:  �[32m[1,038 / 1,048]�[0m 43 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/correct_event_firing_tests.py; 33s ... (4 actions, 1 running)
    3089:  �[32m[1,038 / 1,048]�[0m 43 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/correct_event_firing_tests.py; 43s ... (4 actions, 1 running)
    3090:  �[32m[1,038 / 1,048]�[0m 43 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/support/event_firing_webdriver_tests.py; 42s ... (4 actions, 2 running)
    3091:  �[32m[1,039 / 1,048]�[0m 44 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/support/event_firing_webdriver_tests.py; 44s ... (4 actions, 1 running)
    3092:  �[32m[1,039 / 1,048]�[0m 44 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/webdriverwait_tests.py; 30s ... (4 actions, 2 running)
    3093:  �[32m[1,040 / 1,048]�[0m 45 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/webdriverwait_tests.py; 32s ... (4 actions, 1 running)
    3094:  �[32m[1,040 / 1,048]�[0m 45 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/virtual_authenticator_tests.py; 19s ... (4 actions, 2 running)
    3095:  �[32m[1,041 / 1,048]�[0m 46 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/virtual_authenticator_tests.py; 20s ... (4 actions, 1 running)
    3096:  �[32m[1,041 / 1,048]�[0m 46 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/virtual_authenticator_tests.py; 30s ... (4 actions, 1 running)
    3097:  �[32m[1,041 / 1,048]�[0m 46 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/virtual_authenticator_tests.py; 60s ... (4 actions, 1 running)
    3098:  �[32m[1,041 / 1,048]�[0m 46 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/upload_tests.py; 78s ... (4 actions, 2 running)
    3099:  �[32m[1,042 / 1,048]�[0m 47 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/upload_tests.py; 80s ... (4 actions, 1 running)
    3100:  �[32m[1,042 / 1,048]�[0m 47 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/fedcm_tests.py; 75s ... (4 actions, 2 running)
    3101:  �[32m[1,043 / 1,048]�[0m 48 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/fedcm_tests.py; 77s ... (4 actions, 1 running)
    3102:  �[32m[1,043 / 1,048]�[0m 48 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/window_tests.py; 9s ... (4 actions, 2 running)
    3103:  �[32m[1,044 / 1,048]�[0m 49 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/window_tests.py; 10s ... (4 actions, 1 running)
    3104:  �[32m[1,044 / 1,048]�[0m 49 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/window_tests.py; 20s ... (4 actions, 1 running)
    3105:  �[32m[1,044 / 1,048]�[0m 49 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/web_components_tests.py; 24s ... (4 actions, 2 running)
    3106:  �[32m[1,045 / 1,048]�[0m 50 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/web_components_tests.py; 26s ... (3 actions, 1 running)
    3107:  �[32m[1,045 / 1,048]�[0m 50 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/element_attribute_tests.py; 26s ... (3 actions, 2 running)
    3108:  �[32m[1,046 / 1,048]�[0m 51 / 53 tests, �[31m�[1m1 failed�[0m;�[0m [Sched] Testing //py:common-chrome-bidi-test/selenium/webdriver/common/element_attribute_tests.py; 28s ... (2 actions, 1 running)
    3109:  �[32m[1,046 / 1,048]�[0m 51 / 53 tests, �[31m�[1m1 failed�[0m;�[0m Testing //py:common-chrome-bidi-test/selenium/webdriver/common/web_components_tests.py; 4s local, disk-cache ... (2 actions running)
    3110:  �[32m[1,047 / 1,048]�[0m 52 / 53 tests, �[31m�[1m1 failed�[0m;�[0m Testing //py:common-chrome-bidi-test/selenium/webdriver/common/element_attribute_tests.py; 1s local, disk-cache
    3111:  �[32m[1,047 / 1,048]�[0m 52 / 53 tests, �[31m�[1m1 failed�[0m;�[0m Testing //py:common-chrome-bidi-test/selenium/webdriver/common/element_attribute_tests.py; 11s local, disk-cache
    3112:  �[32m[1,047 / 1,048]�[0m 52 / 53 tests, �[31m�[1m1 failed�[0m;�[0m Testing //py:common-chrome-bidi-test/selenium/webdriver/common/element_attribute_tests.py; 18s local, disk-cache
    3113:  �[32mINFO: �[0mFound 53 test targets...
    3114:  �[32mINFO: �[0mElapsed time: 659.534s, Critical Path: 142.39s
    3115:  �[32mINFO: �[0m1048 processes: 461 disk cache hit, 473 internal, 12 linux-sandbox, 102 local.
    3116:  �[32mINFO: �[0mBuild completed, 1 test FAILED, 1048 total actions
    ...
    
    3161:  //py:common-chrome-bidi-test/selenium/webdriver/common/w3c_interaction_tests.py �[0m�[32mPASSED�[0m in 15.9s
    3162:  //py:common-chrome-bidi-test/selenium/webdriver/common/web_components_tests.py �[0m�[32mPASSED�[0m in 4.2s
    3163:  //py:common-chrome-bidi-test/selenium/webdriver/common/webdriverwait_tests.py �[0m�[32mPASSED�[0m in 69.4s
    3164:  //py:common-chrome-bidi-test/selenium/webdriver/common/window_switching_tests.py �[0m�[32mPASSED�[0m in 9.8s
    3165:  //py:common-chrome-bidi-test/selenium/webdriver/common/window_tests.py   �[0m�[32mPASSED�[0m in 4.6s
    3166:  //py:common-chrome-bidi-test/selenium/webdriver/support/event_firing_webdriver_tests.py �[0m�[32mPASSED�[0m in 9.4s
    3167:  //py:common-chrome-bidi-test/selenium/webdriver/support/expected_conditions_tests.py �[0m�[32mPASSED�[0m in 10.0s
    3168:  //py:common-chrome-bidi-test/selenium/webdriver/support/relative_by_tests.py �[0m�[32mPASSED�[0m in 12.2s
    3169:  //py:common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py     �[0m�[31m�[1mFAILED�[0m in 3 out of 3 in 5.4s
    3170:  Stats over 3 runs: max = 5.4s, min = 5.0s, avg = 5.1s, dev = 0.2s
    3171:  /home/runner/.bazel/execroot/_main/bazel-out/k8-fastbuild/testlogs/py/common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py/test.log
    3172:  /home/runner/.bazel/execroot/_main/bazel-out/k8-fastbuild/testlogs/py/common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py/test_attempts/attempt_1.log
    3173:  /home/runner/.bazel/execroot/_main/bazel-out/k8-fastbuild/testlogs/py/common-chrome-bidi-test/selenium/webdriver/common/bidi_tests.py/test_attempts/attempt_2.log
    3174:  Executed 53 out of 53 tests: 52 tests pass and �[0m�[31m�[1m1 fails locally�[0m.
    3175:  There were tests whose specified size is too big. Use the --test_verbose_timeout_warnings command line option to see which ones these are.
    3176:  �[0m
    3177:  ##[error]Process completed with exit code 3.
    

    ✨ CI feedback usage guide:

    The CI feedback tool (/checks) automatically triggers when a PR has a failed check.
    The tool analyzes the failed checks and provides several feedbacks:

    • Failed stage
    • Failed test name
    • Failure summary
    • Relevant error logs

    In addition to being automatically triggered, the tool can also be invoked manually by commenting on a PR:

    /checks "https://github.com/{repo_name}/actions/runs/{run_number}/job/{job_number}"
    

    where {repo_name} is the name of the repository, {run_number} is the run number of the failed check, and {job_number} is the job number of the failed check.

    Configuration options

    • enable_auto_checks_feedback - if set to true, the tool will automatically provide feedback when a check is failed. Default is true.
    • excluded_checks_list - a list of checks to exclude from the feedback, for example: ["check1", "check2"]. Default is an empty list.
    • enable_help_text - if set to true, the tool will provide a help message with the feedback. Default is true.
    • persistent_comment - if set to true, the tool will overwrite a previous checks comment with the new feedback. Default is true.
    • final_update_message - if persistent_comment is true and updating a previous checks message, the tool will also create a new message: "Persistent checks updated to latest commit". Default is true.

    See more information about the checks tool in the docs.

    @VietND96 VietND96 changed the title [grid] Dynamic Grid is able to disable video container spawn up [grid] Dynamic Grid is able to trigger video record in browser node Jan 12, 2025
    @VietND96 VietND96 merged commit 928833e into trunk Jan 12, 2025
    33 checks passed
    @VietND96 VietND96 deleted the dynamic-grid branch January 12, 2025 13:54
    VietND96 added a commit to SeleniumHQ/docker-selenium that referenced this pull request Jan 13, 2025
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    [🚀 Feature]: Dynamic Grid is able to disable video container spawn up
    1 participant