|
18 | 18 | import platform
|
19 | 19 | import time
|
20 | 20 | from functools import cached_property
|
| 21 | +from io import TextIOWrapper |
21 | 22 | from pathlib import Path
|
22 | 23 | from subprocess import DEVNULL, STDOUT, CalledProcessError, Popen, run
|
23 | 24 | from typing import TYPE_CHECKING, Optional, Union
|
24 | 25 |
|
25 | 26 | import grpc # type: ignore
|
26 | 27 |
|
| 28 | +try: |
| 29 | + from BrowserBatteries import start_grpc_server |
| 30 | +except ImportError: |
| 31 | + start_grpc_server = None # type: ignore[assignment] |
| 32 | + |
27 | 33 | from Browser.generated import playwright_pb2_grpc
|
28 | 34 | from Browser.generated.playwright_pb2 import Request
|
29 | 35 |
|
|
36 | 42 | from .utils import PlaywrightLogTypes, find_free_port, logger
|
37 | 43 |
|
38 | 44 |
|
| 45 | +def _run_grpc_server() -> bool: |
| 46 | + return start_grpc_server is not None |
| 47 | + |
| 48 | + |
39 | 49 | class Playwright(LibraryComponent):
|
40 | 50 | """A wrapper for communicating with nodejs Playwright process."""
|
41 | 51 |
|
@@ -66,7 +76,15 @@ def _playwright_process(self) -> Optional[Popen]:
|
66 | 76 | return process
|
67 | 77 |
|
68 | 78 | def ensure_node_dependencies(self):
|
69 |
| - # Checks if node is in PATH, errors if it isn't |
| 79 | + """Ensure that node dependencies are installed. |
| 80 | +
|
| 81 | + If BrowserBatteries is installed, does nothing. |
| 82 | + """ |
| 83 | + if _run_grpc_server(): |
| 84 | + logger.trace( |
| 85 | + "Running gRPC server from BrowserBatteries, no need to check node" |
| 86 | + ) |
| 87 | + return |
70 | 88 | try:
|
71 | 89 | run(["node", "-v"], stdout=DEVNULL, check=True)
|
72 | 90 | except (CalledProcessError, FileNotFoundError, PermissionError) as err:
|
@@ -114,13 +132,19 @@ def start_playwright(self) -> Optional[Popen]:
|
114 | 132 | f"ROBOT_FRAMEWORK_BROWSER_NODE_PORT {existing_port} defined in env, skipping Browser process start"
|
115 | 133 | )
|
116 | 134 | return None
|
117 |
| - current_dir = Path(__file__).parent |
118 |
| - workdir = current_dir / "wrapper" |
119 |
| - playwright_script = workdir / "index.js" |
120 | 135 | if self.playwright_log:
|
121 | 136 | logfile = self.playwright_log.open("w", encoding="utf-8")
|
122 | 137 | else:
|
123 | 138 | logfile = Path(os.devnull).open("w", encoding="utf-8") # noqa: SIM115
|
| 139 | + if _run_grpc_server(): |
| 140 | + return start_grpc_server(logfile) |
| 141 | + return self._start_playwright_from_node(logfile) |
| 142 | + |
| 143 | + def _start_playwright_from_node(self, logfile: TextIOWrapper) -> Popen: |
| 144 | + """Start Playwright from nodejs wrapper.""" |
| 145 | + current_dir = Path(__file__).parent |
| 146 | + workdir = current_dir / "wrapper" |
| 147 | + playwright_script = workdir / "index.js" |
124 | 148 | host = str(self.host) if self.host is not None else "127.0.0.1"
|
125 | 149 | port = str(find_free_port())
|
126 | 150 | if self.enable_playwright_debug == PlaywrightLogTypes.playwright:
|
|
0 commit comments