From 6d6f4bc633f702da8306879415b7e153b84c18d1 Mon Sep 17 00:00:00 2001 From: Jeffrey Date: Mon, 27 Jul 2026 08:41:29 +0800 Subject: [PATCH] fix(browser): restore stale profile permissions --- pyproject.toml | 4 +++- tests/unit/browser/test_browser_setup.py | 10 +++++++--- uv.lock | 13 ++++++++++++- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index dc0bc372..84c7fc18 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,6 +34,7 @@ dependencies = [ "boto3>=1.40.61", "harness-browser>=0.7.4", "playwright>=1.40", + "socksio>=1.0.0", ] [project.optional-dependencies] @@ -174,6 +175,7 @@ disable_error_code = ["attr-defined"] [tool.pytest.ini_options] testpaths = ["tests"] asyncio_mode = "auto" +tmp_path_retention_count = 1 markers = [ "live: tests that hit real LLM endpoints (skipped by default)", ] @@ -184,4 +186,4 @@ markers = [ # fallback is intentional for this environment, so silence the noise. filterwarnings = [ "ignore::starlette.exceptions.StarletteDeprecationWarning", -] \ No newline at end of file +] diff --git a/tests/unit/browser/test_browser_setup.py b/tests/unit/browser/test_browser_setup.py index e52691aa..9aabe73b 100644 --- a/tests/unit/browser/test_browser_setup.py +++ b/tests/unit/browser/test_browser_setup.py @@ -2,6 +2,7 @@ from __future__ import annotations +import contextlib import json import os from pathlib import Path @@ -169,9 +170,12 @@ def test_ensure_profile_writable_recreates_when_not_writable( assert result == profile or "harness-browser-profiles" in str(result) assert _probe_dir_writable(result) finally: - os.chmod(profile, 0o700) - if profile.exists(): - os.chmod(profile, 0o700) + # Restore permissions on the profile and any stale dirs renamed + # by ensure_profile_writable (they keep 0o000 → pytest can't rm). + for d in [profile, *tmp_path.glob("default.stale-*")]: + if d.exists(): + with contextlib.suppress(OSError): + os.chmod(d, 0o700) else: assert ensure_profile_writable(profile) == profile diff --git a/uv.lock b/uv.lock index 272f812f..98eeff96 100644 --- a/uv.lock +++ b/uv.lock @@ -2168,7 +2168,7 @@ wheels = [ [[package]] name = "octop" -version = "0.9.11" +version = "0.9.12" source = { editable = "." } dependencies = [ { name = "acme" }, @@ -2192,6 +2192,7 @@ dependencies = [ { name = "rich" }, { name = "scalar-fastapi" }, { name = "segno" }, + { name = "socksio" }, { name = "uvicorn", extra = ["standard"] }, { name = "websockets" }, ] @@ -2260,6 +2261,7 @@ requires-dist = [ { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.4" }, { name = "scalar-fastapi", specifier = ">=1.0" }, { name = "segno", specifier = ">=1.6" }, + { name = "socksio", specifier = ">=1.0.0" }, { name = "uvicorn", extras = ["standard"], specifier = ">=0.27" }, { name = "websockets", specifier = ">=13.0" }, ] @@ -3761,6 +3763,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, ] +[[package]] +name = "socksio" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/5c/48a7d9495be3d1c651198fd99dbb6ce190e2274d0f28b9051307bdec6b85/socksio-1.0.0.tar.gz", hash = "sha256:f88beb3da5b5c38b9890469de67d0cb0f9d494b78b106ca1845f96c10b91c4ac", size = 19055, upload-time = "2020-04-17T15:50:34.664Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/37/c3/6eeb6034408dac0fa653d126c9204ade96b819c936e136c5e8a6897eee9c/socksio-1.0.0-py3-none-any.whl", hash = "sha256:95dc1f15f9b34e8d7b16f06d74b8ccf48f609af32ab33c608d08761c5dcbb1f3", size = 12763, upload-time = "2020-04-17T15:50:31.878Z" }, +] + [[package]] name = "soupsieve" version = "2.8.4"