Skip to content

Commit b3c0638

Browse files
committed
start_grpc_server from BroserBatteries
1 parent 2021549 commit b3c0638

File tree

4 files changed

+79
-25
lines changed

4 files changed

+79
-25
lines changed

Browser/playwright.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,24 +132,26 @@ def start_playwright(self) -> Optional[Popen]:
132132
logfile = self.playwright_log.open("w", encoding="utf-8")
133133
else:
134134
logfile = Path(os.devnull).open("w", encoding="utf-8") # noqa: SIM115
135+
host = str(self.host) if self.host is not None else "127.0.0.1"
136+
port = str(find_free_port())
137+
self.host = host
138+
self.port = port
135139
if start_grpc_server is None:
136-
return self._start_playwright_from_node(logfile)
137-
return start_grpc_server(logfile)
140+
return self._start_playwright_from_node(logfile, host, port)
141+
return start_grpc_server(logfile, host, port, self.enable_playwright_debug)
138142

139-
def _start_playwright_from_node(self, logfile: TextIOWrapper) -> Popen:
143+
def _start_playwright_from_node(
144+
self, logfile: TextIOWrapper, host: str, port: str
145+
) -> Popen:
140146
"""Start Playwright from nodejs wrapper."""
141147
current_dir = Path(__file__).parent
142148
workdir = current_dir / "wrapper"
143149
playwright_script = workdir / "index.js"
144-
host = str(self.host) if self.host is not None else "127.0.0.1"
145-
port = str(find_free_port())
146150
if self.enable_playwright_debug == PlaywrightLogTypes.playwright:
147151
os.environ["DEBUG"] = "pw:api"
148152
logger.info(
149153
f"Starting Browser process {playwright_script} using at {host}:{port}"
150154
)
151-
self.host = host
152-
self.port = port
153155
node_args = ["node"]
154156
node_debug_options = os.environ.get(
155157
"ROBOT_FRAMEWORK_BROWSER_NODE_DEBUG_OPTIONS"

Browser/utils/misc.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import socket
1919
import string
2020
import subprocess
21+
from io import TextIOWrapper
2122
from pathlib import Path
2223
from typing import Any, Union
2324

@@ -51,11 +52,23 @@ def spawn_node_process(output_dir: Path) -> tuple[subprocess.Popen, str]:
5152
5253
5354
"""
55+
try:
56+
from BrowserBatteries import start_grpc_server # noqa: PLC0415
57+
except ImportError:
58+
start_grpc_server = None # type: ignore[assignment]
5459
logfile = output_dir.open("w", encoding="utf-8")
5560
os.environ["DEBUG"] = "pw:api"
56-
os.environ["PLAYWRIGHT_BROWSERS_PATH"] = "0"
61+
if start_grpc_server is None:
62+
os.environ["PLAYWRIGHT_BROWSERS_PATH"] = "0"
5763
host = "127.0.0.1"
5864
port = str(find_free_port())
65+
if start_grpc_server is None:
66+
return _spawn_node_process(logfile, host, port)
67+
process = start_grpc_server(logfile, host, port, True)
68+
return process, port
69+
70+
71+
def _spawn_node_process(logfile: TextIOWrapper, host: str, port: str):
5972
process = subprocess.Popen(
6073
[
6174
"node",

browser_batteries/BrowserBatteries/__init__.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,43 @@
1313
# limitations under the License.
1414

1515

16+
import os
1617
from io import TextIOWrapper
1718
from pathlib import Path
18-
from subprocess import Popen
19+
from subprocess import STDOUT, Popen
1920

2021
from robot.api import logger
2122

23+
from Browser.utils.data_types import PlaywrightLogTypes
2224

23-
def start_grpc_server(logfile: TextIOWrapper) -> Popen:
25+
26+
def start_grpc_server(
27+
logfile: TextIOWrapper,
28+
host: str,
29+
port: str,
30+
enable_playwright_debug: "PlaywrightLogTypes | bool",
31+
) -> Popen:
2432
"""Run the prebuilt gRPC server."""
2533
current_dir = Path(__file__).parent
2634
playwright_script = current_dir / "bin" / "grpc_server"
27-
logger.trace(f"Starting gRPC server from {playwright_script}")
28-
return Popen([str(playwright_script)])
35+
logger.info(f"Starting GRPC process {playwright_script} using at {host}:{port}")
36+
args = [str(playwright_script), host, port]
37+
workdir = current_dir / "bin"
38+
if enable_playwright_debug == PlaywrightLogTypes.playwright:
39+
logger.trace("Enabling Playwright debug logging")
40+
os.environ["DEBUG"] = "pw:api"
41+
if os.environ.get("ROBOT_FRAMEWORK_BROWSER_NODE_DEBUG_OPTIONS"):
42+
logger.trace(
43+
"it is not possible to define ROBOT_FRAMEWORK_BROWSER_NODE_DEBUG_OPTIONS for BrowserBatteries"
44+
)
45+
if not os.environ.get("PLAYWRIGHT_BROWSERS_PATH"):
46+
logger.trace("Setting PLAYWRIGHT_BROWSERS_PATH to '0'")
47+
os.environ["PLAYWRIGHT_BROWSERS_PATH"] = "0"
48+
logger.trace(f"GRPC startup parameters: {args}")
49+
return Popen(
50+
args,
51+
cwd=workdir,
52+
env=os.environ,
53+
stdout=logfile,
54+
stderr=STDOUT,
55+
)

tasks.py

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@
4444
WRAPPER_DIR = PYTHON_SRC_DIR / "wrapper"
4545
node_protobuf_dir = ROOT_DIR / "node" / "playwright-wrapper" / "generated"
4646
node_dir = ROOT_DIR / "node"
47-
npm_deps_timestamp_file = ROOT_DIR / "node_modules" / ".installed"
47+
NODE_MODULES = ROOT_DIR / "node_modules"
48+
npm_deps_timestamp_file = NODE_MODULES / ".installed"
49+
4850
node_lint_timestamp_file = node_dir / ".linted"
4951
ATEST_TIMEOUT = 900
5052
cpu_count = os.cpu_count() or 1
@@ -104,7 +106,7 @@ def deps(c, system=False):
104106
print("Install package dependencies.")
105107
c.run(uv_deps_cmd)
106108
if os.environ.get("CI"):
107-
shutil.rmtree("node_modules", ignore_errors=True)
109+
shutil.rmtree(str(NODE_MODULES), ignore_errors=True)
108110

109111
if _sources_changed([ROOT_DIR / "./package-lock.json"], npm_deps_timestamp_file):
110112
arch = " --target_arch=x64" if platform.processor() == "arm" else ""
@@ -198,14 +200,9 @@ def _python_protobuf_gen(c):
198200
def _node_protobuf_gen(c):
199201
plugin_suffix = ".cmd" if platform.platform().startswith("Windows") else ""
200202
protoc_plugin = (
201-
ROOT_DIR
202-
/ "node_modules"
203-
/ ".bin"
204-
/ f"grpc_tools_node_protoc_plugin{plugin_suffix}"
205-
)
206-
protoc_ts_plugin = (
207-
ROOT_DIR / "node_modules" / ".bin" / f"protoc-gen-ts{plugin_suffix}"
203+
NODE_MODULES / ".bin" / f"grpc_tools_node_protoc_plugin{plugin_suffix}"
208204
)
205+
protoc_ts_plugin = NODE_MODULES / ".bin" / f"protoc-gen-ts{plugin_suffix}"
209206
cmd = (
210207
"npm run grpc_tools_node_protoc -- "
211208
f"--js_out=import_style=commonjs,binary:{node_protobuf_dir} "
@@ -320,6 +317,14 @@ def clean_atest(c):
320317
_clean_zip_dir()
321318

322319

320+
def _batteries(batteries: bool):
321+
if batteries:
322+
print("Running with BrowserBatteries")
323+
sys.path.append(str(BROWSER_BATTERIES_DIR))
324+
browser_path = NODE_MODULES / "playwright-core" / ".local-browsers"
325+
os.environ["PLAYWRIGHT_BROWSERS_PATH"] = str(browser_path)
326+
327+
323328
@task(clean_atest, create_test_app)
324329
def atest(
325330
c,
@@ -335,6 +340,7 @@ def atest(
335340
framed=False,
336341
exclude=None,
337342
loglevel=None,
343+
batteries=False,
338344
):
339345
"""Runs Robot Framework acceptance tests with pabot.
340346
@@ -348,6 +354,7 @@ def atest(
348354
smoke: If true, runs only tests that take less than 500ms.
349355
include_mac: Does not exclude no-mac-support tags. Should be only used in local testing
350356
loglevel: Set log level for robot framework
357+
batteries: Run test with BrowserBatteries. Assumes that GRPC server is build.
351358
"""
352359
if IS_GITPOD and (not processes or int(processes) > 6):
353360
processes = "6"
@@ -381,7 +388,7 @@ def atest(
381388
loglevel = loglevel or "DEBUG"
382389
args.extend(["--exclude", "tidy-transformer"])
383390
ATEST_OUTPUT.mkdir(parents=True, exist_ok=True)
384-
391+
_batteries(batteries)
385392
background_process, port = spawn_node_process(ATEST_OUTPUT / "playwright-log.txt")
386393
try:
387394
os.environ["ROBOT_FRAMEWORK_BROWSER_NODE_PORT"] = port
@@ -475,12 +482,13 @@ def copy_xunit(c):
475482

476483

477484
@task(clean_atest)
478-
def atest_robot(c, zip=None, smoke=False, suite=None):
485+
def atest_robot(c, zip=None, smoke=False, suite=None, batteries=False):
479486
"""Run atest with Robot Framework
480487
481488
Arguments:
482489
zip: Create zip file from output files.
483490
smoke: If true, runs only tests that take less than 500ms.
491+
batteries: If true, includes BrowserBatteries in the test run.
484492
"""
485493
os.environ["ROBOT_SYSLOG_FILE"] = str(ATEST_OUTPUT / "syslog.txt")
486494
sys_var_ci = int(os.environ.get("SYS_VAR_CI_INSTALL_TEST", 0))
@@ -511,6 +519,7 @@ def atest_robot(c, zip=None, smoke=False, suite=None):
511519
command_args.extend(["--suite", suite])
512520
command_args = _add_skips(command_args)
513521
command_args.append("atest/test")
522+
_batteries(batteries)
514523
env = os.environ.copy()
515524
process = subprocess.Popen(command_args, env=env)
516525
process.wait(ATEST_TIMEOUT)
@@ -540,11 +549,14 @@ def atest_failed(c):
540549

541550

542551
@task()
543-
def run_tests(c, tests):
552+
def run_tests(c, tests, batteries=False):
544553
"""Run robot with dev Browser.
545554
546-
Parameter [tests] is the path to tests to run.
555+
Arguments:
556+
tests: is the path to tests to run.
557+
batteries: If true, includes BrowserBatteries in the test run.
547558
"""
559+
_batteries(batteries)
548560
env = os.environ.copy()
549561
process = subprocess.Popen(
550562
[

0 commit comments

Comments
 (0)