Fix the http request timeout

Update the http request timeout to be optional

Bug: 370843968
Change-Id: Ife954f86073f8a68bd9def21376395c08ce3ce5a
Reviewed-on: https://chromium-review.googlesource.com/c/crossbench/+/5905928
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Commit-Queue: Suhua Lei <lsuhua@google.com>
diff --git a/crossbench/browsers/browser.py b/crossbench/browsers/browser.py
index a914df2..0de50ef 100644
--- a/crossbench/browsers/browser.py
+++ b/crossbench/browsers/browser.py
@@ -130,6 +130,10 @@
   def wipe_system_user_data(self) -> bool:
     return self._settings.wipe_system_user_data
 
+  @property
+  def http_request_timeout(self) -> dt.timedelta:
+    return self._settings.http_request_timeout
+
   @viewport.setter
   def viewport(self, value: Viewport) -> None:
     self._settings.viewport = value
diff --git a/crossbench/browsers/settings.py b/crossbench/browsers/settings.py
index 83771e6..e10b9f4 100644
--- a/crossbench/browsers/settings.py
+++ b/crossbench/browsers/settings.py
@@ -4,6 +4,7 @@
 
 from __future__ import annotations
 
+import datetime as dt
 from typing import TYPE_CHECKING, Dict, Optional
 
 from crossbench import path as pth
@@ -33,7 +34,8 @@
                platform: Optional[plt.Platform] = None,
                secrets: Optional[SecretsDict] = None,
                driver_logging: bool = False,
-               wipe_system_user_data: Optional[bool] = False):
+               wipe_system_user_data: Optional[bool] = False,
+               http_request_timeout: dt.timedelta = dt.timedelta()):
     self._flags = self._convert_flags(flags, "flags")
     self._js_flags = self._extract_js_flags(self._flags, js_flags)
     self._cache_dir = cache_dir
@@ -45,6 +47,7 @@
     self._secrets: SecretsDict = secrets or {}
     self._driver_logging = driver_logging
     self._wipe_system_user_data = wipe_system_user_data
+    self._http_request_timeout = http_request_timeout
 
   def _extract_js_flags(self, flags: Flags,
                         js_flags: Optional[Flags.InitialDataType]) -> Flags:
@@ -109,6 +112,10 @@
     return self._wipe_system_user_data
 
   @property
+  def http_request_timeout(self) -> dt.timedelta:
+    return self._http_request_timeout
+
+  @property
   def viewport(self) -> Viewport:
     return self._viewport
 
diff --git a/crossbench/browsers/webdriver.py b/crossbench/browsers/webdriver.py
index 25bc5d5..16df64d 100644
--- a/crossbench/browsers/webdriver.py
+++ b/crossbench/browsers/webdriver.py
@@ -96,6 +96,9 @@
 
   def start(self, session: BrowserSessionRunGroup) -> None:
     assert self._driver_path
+    if timeout := self.http_request_timeout:
+      logging.debug("Setting http request timeout to %s", timeout)
+      RemoteConnection.set_timeout(timeout.total_seconds())
     try:
       self._driver = self._start_driver(session, self._driver_path)
     except selenium.common.exceptions.SessionNotCreatedException as e:
diff --git a/crossbench/cli/cli.py b/crossbench/cli/cli.py
index 17bc7b9..4a60828 100644
--- a/crossbench/cli/cli.py
+++ b/crossbench/cli/cli.py
@@ -601,6 +601,13 @@
         action="store_true",
         help="Clear user data at the beginning of the test "
         "(be careful using it).")
+    browser_group.add_argument(
+        "--http-request-timeout",
+        type=DurationParser.positive_or_zero_duration,
+        default=dt.timedelta(),
+        help=("Set the timeout of http request. "
+              f"Format: {DurationParser.help()}. "
+              "When not speficied, there will be no timeout."))
 
     splashscreen_group = browser_group.add_mutually_exclusive_group()
     splashscreen_group.add_argument(
diff --git a/crossbench/cli/config/browser_variants.py b/crossbench/cli/config/browser_variants.py
index 8cebad0..51472fe 100644
--- a/crossbench/cli/config/browser_variants.py
+++ b/crossbench/cli/config/browser_variants.py
@@ -430,7 +430,8 @@
           platform=browser_platform,
           secrets=args.secrets.as_dict(),
           driver_logging=args.driver_logging,
-          wipe_system_user_data=args.wipe_system_user_data)
+          wipe_system_user_data=args.wipe_system_user_data,
+          http_request_timeout=args.http_request_timeout)
       browser_instance = browser_cls(
           label=label, path=browser_config.path, settings=settings)
       # pytype: enable=not-instantiable
@@ -716,7 +717,8 @@
           platform=browser_platform,
           secrets=args.secrets.as_dict(),
           driver_logging=args.driver_logging,
-          wipe_system_user_data=args.wipe_system_user_data)
+          wipe_system_user_data=args.wipe_system_user_data,
+          http_request_timeout=args.http_request_timeout)
       browser_instance = browser_cls(  # pytype: disable=not-instantiable
           label=label,
           path=path,
diff --git a/tests/crossbench/base.py b/tests/crossbench/base.py
index 30903fd..353e44a 100644
--- a/tests/crossbench/base.py
+++ b/tests/crossbench/base.py
@@ -6,6 +6,7 @@
 
 import abc
 import contextlib
+import datetime as dt
 import io
 import logging
 import pathlib
@@ -96,6 +97,7 @@
         splash_screen=None,
         secrets=SecretsConfig(),
         wipe_system_user_data=False,
+        http_request_timeout=dt.timedelta(),
         cache_dir=pathlib.Path("test_cache_dir"),
         enable_features=None,
         disable_features=None,