From eca119e99d6cb324fa02a1e17593f8bdbe2be6c0 Mon Sep 17 00:00:00 2001 From: hirohira Date: Thu, 9 Jul 2026 23:47:59 +0900 Subject: [PATCH 1/4] feat: add enable_extensions option to control browser extension loading --- src/choreographer/browsers/chromium.py | 6 ++++++ tests/conftest.py | 4 ++++ tests/test_process.py | 6 ++++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/choreographer/browsers/chromium.py b/src/choreographer/browsers/chromium.py index 88524f33..af450c16 100644 --- a/src/choreographer/browsers/chromium.py +++ b/src/choreographer/browsers/chromium.py @@ -62,6 +62,8 @@ class Chromium: path: str | Path | None """The path to the chromium executable.""" + extension_enabled: bool + """True to enable browser extensions. True by default.""" gpu_enabled: bool """True if we should use the gpu. False by default for compatibility.""" headless: bool @@ -142,6 +144,7 @@ def __init__( channel: the `choreographer.Channel` we'll be using (WebSockets? Pipe?) path: path to the browser kwargs: + extension_enabled (default True): Enable extensions? gpu_enabled (default False): Turn on GPU? Doesn't work in all envs. headless (default True): Actually launch a browser? sandbox_enabled (default False): Enable sandbox- @@ -155,6 +158,7 @@ def __init__( """ _logger.info(f"Chromium init'ed with kwargs {kwargs}") self.path = path + self.extension_enabled = kwargs.pop("enable_extensions", True) self.gpu_enabled = kwargs.pop("enable_gpu", False) self.headless = kwargs.pop("headless", True) self.sandbox_enabled = kwargs.pop("enable_sandbox", False) @@ -237,6 +241,8 @@ def get_cli(self) -> Sequence[str]: str(self.path), ] + if not self.extension_enabled: + cli.append("--disable-extensions") if not self.gpu_enabled: cli.append("--disable-gpu") if self.headless: diff --git a/tests/conftest.py b/tests/conftest.py index a4f9d258..61ff25d5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -25,6 +25,10 @@ def gpu(request): def headless(request): return request.param +@pytest.fixture(params=[True, False], ids=["enable_extensions", ""]) +def extension(request): + return request.param + # --headless is the default flag for most tests, # but you can set --no-headless if you want to watch diff --git a/tests/test_process.py b/tests/test_process.py index 8da9d276..357132f3 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -18,7 +18,7 @@ @pytest.mark.asyncio(loop_scope="function") -async def test_context(headless, sandbox, gpu): +async def test_context(headless, sandbox, gpu, extension): _logger.info("testing...") if sandbox and "ubuntu" in platform.version().lower(): pytest.skip( @@ -35,6 +35,7 @@ async def test_context(headless, sandbox, gpu): headless=headless, enable_sandbox=sandbox, enable_gpu=gpu, + enable_extensions=extension, ) as browser: response = await browser.send_command(command="Target.getTargets") assert "result" in response and "targetInfos" in response["result"] # noqa: PT018 combined assert @@ -51,7 +52,7 @@ async def test_context(headless, sandbox, gpu): @pytest.mark.asyncio(loop_scope="function") -async def test_no_context(headless, sandbox, gpu): +async def test_no_context(headless, sandbox, gpu, extension): _logger.info("testing...") if sandbox and "ubuntu" in platform.version().lower(): pytest.skip("Ubuntu doesn't support sandbox unless installed from snap.") @@ -59,6 +60,7 @@ async def test_no_context(headless, sandbox, gpu): headless=headless, enable_sandbox=sandbox, enable_gpu=gpu, + enable_extensions=extension, ) try: async with timeout(pytest.default_timeout): # type: ignore[reportAttributeAccessIssue] From 4df54641f7a989969bffd26317fe8782604ea973 Mon Sep 17 00:00:00 2001 From: hirohira Date: Thu, 23 Jul 2026 06:06:31 +0900 Subject: [PATCH 2/4] Apply suggestions from code review Co-authored-by: Cameron DeCoster --- src/choreographer/browsers/chromium.py | 8 ++++---- tests/conftest.py | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/choreographer/browsers/chromium.py b/src/choreographer/browsers/chromium.py index af450c16..5d926983 100644 --- a/src/choreographer/browsers/chromium.py +++ b/src/choreographer/browsers/chromium.py @@ -62,7 +62,7 @@ class Chromium: path: str | Path | None """The path to the chromium executable.""" - extension_enabled: bool + extensions_enabled: bool """True to enable browser extensions. True by default.""" gpu_enabled: bool """True if we should use the gpu. False by default for compatibility.""" @@ -144,10 +144,10 @@ def __init__( channel: the `choreographer.Channel` we'll be using (WebSockets? Pipe?) path: path to the browser kwargs: - extension_enabled (default True): Enable extensions? - gpu_enabled (default False): Turn on GPU? Doesn't work in all envs. + enable_extensions (default True): Enable extensions? + enable_gpu (default False): Turn on GPU? Doesn't work in all envs. headless (default True): Actually launch a browser? - sandbox_enabled (default False): Enable sandbox- + enable_sandbox (default False): Enable sandbox- a persnickety thing depending on environment, OS, user, etc tmp_dir (default None): Manually set the temporary directory diff --git a/tests/conftest.py b/tests/conftest.py index 61ff25d5..c34e10cc 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -25,6 +25,7 @@ def gpu(request): def headless(request): return request.param + @pytest.fixture(params=[True, False], ids=["enable_extensions", ""]) def extension(request): return request.param From 5d5217c933e65ca501be7a407e290343165abd9f Mon Sep 17 00:00:00 2001 From: hirohira Date: Thu, 23 Jul 2026 06:38:20 +0900 Subject: [PATCH 3/4] Address review feedback and update CHANGELOG --- CHANGELOG.md | 3 +++ src/choreographer/browsers/chromium.py | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69004a77..5ebf867d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ where X.Y.Z is the semver of the most recent choreographer release. ## [Unreleased] +### Added +- Add `enable_extensions` option to control browser extension loading [[#303](https://github.com/plotly/choreographer/pull/303)], with thanks to @hirohira9119 for the contribution! + ### Fixed - Improve platform architecture detection for arm on Linux and Windows [[#290](https://github.com/plotly/choreographer/pull/290)], with thanks to @juliabeliaeva for the contribution! - Fix license file and add a valid SPDX identifier to project settings [[#294](https://github.com/plotly/choreographer/pull/294)], with thanks to @ecederstrand for the contribution! diff --git a/src/choreographer/browsers/chromium.py b/src/choreographer/browsers/chromium.py index 5d926983..767e9b88 100644 --- a/src/choreographer/browsers/chromium.py +++ b/src/choreographer/browsers/chromium.py @@ -158,7 +158,7 @@ def __init__( """ _logger.info(f"Chromium init'ed with kwargs {kwargs}") self.path = path - self.extension_enabled = kwargs.pop("enable_extensions", True) + self.extensions_enabled = kwargs.pop("enable_extensions", True) self.gpu_enabled = kwargs.pop("enable_gpu", False) self.headless = kwargs.pop("headless", True) self.sandbox_enabled = kwargs.pop("enable_sandbox", False) @@ -241,7 +241,7 @@ def get_cli(self) -> Sequence[str]: str(self.path), ] - if not self.extension_enabled: + if not self.extensions_enabled: cli.append("--disable-extensions") if not self.gpu_enabled: cli.append("--disable-gpu") From 0d733b30c447ed74655b5d198c646bf442435a06 Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Wed, 22 Jul 2026 17:19:52 -0600 Subject: [PATCH 4/4] Fix some more docstrings Co-authored-by: Cameron DeCoster --- src/choreographer/browsers/chromium.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/choreographer/browsers/chromium.py b/src/choreographer/browsers/chromium.py index 767e9b88..0b32239a 100644 --- a/src/choreographer/browsers/chromium.py +++ b/src/choreographer/browsers/chromium.py @@ -67,7 +67,7 @@ class Chromium: gpu_enabled: bool """True if we should use the gpu. False by default for compatibility.""" headless: bool - """True if we should not show the browser, true by default.""" + """True if we should not show the browser. True by default.""" sandbox_enabled: bool """True to enable the sandbox. False by default.""" skip_local: bool @@ -146,7 +146,7 @@ def __init__( kwargs: enable_extensions (default True): Enable extensions? enable_gpu (default False): Turn on GPU? Doesn't work in all envs. - headless (default True): Actually launch a browser? + headless (default True): Run the browser in headless mode? enable_sandbox (default False): Enable sandbox- a persnickety thing depending on environment, OS, user, etc tmp_dir (default None): Manually set the temporary directory