From bd1fa09dc2a47cd8e512c912e2f977188554d6ad Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Thu, 4 Jun 2026 12:50:16 +0000 Subject: [PATCH 1/3] =?UTF-8?q?Playwright=20tmp=20dirs=20are=20cleaned=20u?= =?UTF-8?q?p=20after=20browser=20close=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pashub_fetcher/tests/test_token_getter.py | 50 +++++++++++++++++++ backend/pashub_fetcher/token_getter.py | 2 + 2 files changed, 52 insertions(+) create mode 100644 backend/pashub_fetcher/tests/test_token_getter.py diff --git a/backend/pashub_fetcher/tests/test_token_getter.py b/backend/pashub_fetcher/tests/test_token_getter.py new file mode 100644 index 00000000..2c847d16 --- /dev/null +++ b/backend/pashub_fetcher/tests/test_token_getter.py @@ -0,0 +1,50 @@ +from unittest.mock import MagicMock, patch + +from backend.pashub_fetcher.token_getter import get_token_from_local_storage + + +def _configure_playwright_mock(mock_sync_playwright: MagicMock) -> None: + mock_page = MagicMock() + mock_page.url = "https://pashub.net/dashboard" + mock_page.evaluate.return_value = "fake-token" + + mock_context = MagicMock() + mock_context.new_page.return_value = mock_page + + mock_browser = MagicMock() + mock_browser.new_context.return_value = mock_context + + mock_p = MagicMock() + mock_p.chromium.launch.return_value = mock_browser + + mock_sync_playwright.return_value.__enter__.return_value = mock_p + + +@patch("backend.pashub_fetcher.token_getter.shutil.rmtree") +@patch("backend.pashub_fetcher.token_getter.glob.glob") +@patch("backend.pashub_fetcher.token_getter.sync_playwright") +def test_playwright_tmp_dirs_are_cleaned_up_after_browser_close( + mock_sync_playwright: MagicMock, + mock_glob: MagicMock, + mock_rmtree: MagicMock, +) -> None: + # Arrange + fake_artifacts = ["/tmp/playwright-artifacts-abc12"] + fake_profiles = ["/tmp/playwright_chromiumdev_profile-xyz99"] + + def glob_side_effect(pattern: str) -> list[str]: + if "playwright-artifacts-*" in pattern: + return fake_artifacts + if "playwright_chromiumdev_profile-*" in pattern: + return fake_profiles + return [] + + mock_glob.side_effect = glob_side_effect + _configure_playwright_mock(mock_sync_playwright) + + # Act + get_token_from_local_storage("user@example.com", "secret") + + # Assert + mock_rmtree.assert_any_call("/tmp/playwright-artifacts-abc12", ignore_errors=True) + mock_rmtree.assert_any_call("/tmp/playwright_chromiumdev_profile-xyz99", ignore_errors=True) diff --git a/backend/pashub_fetcher/token_getter.py b/backend/pashub_fetcher/token_getter.py index 2e2d1440..990e79d0 100644 --- a/backend/pashub_fetcher/token_getter.py +++ b/backend/pashub_fetcher/token_getter.py @@ -1,4 +1,6 @@ +import glob import os +import shutil from playwright.sync_api import sync_playwright, TimeoutError as PlaywrightTimeoutError From 428a5db51356c9575ce5b823d7ae21e7ad91cf0e Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Thu, 4 Jun 2026 12:51:14 +0000 Subject: [PATCH 2/3] =?UTF-8?q?Playwright=20tmp=20dirs=20are=20cleaned=20u?= =?UTF-8?q?p=20after=20browser=20close=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/pashub_fetcher/token_getter.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/backend/pashub_fetcher/token_getter.py b/backend/pashub_fetcher/token_getter.py index 990e79d0..57338a6d 100644 --- a/backend/pashub_fetcher/token_getter.py +++ b/backend/pashub_fetcher/token_getter.py @@ -92,5 +92,12 @@ def get_token_from_local_storage( context.close() browser.close() + for pattern in ( + "/tmp/playwright-artifacts-*", + "/tmp/playwright_chromiumdev_profile-*", + ): + for path in glob.glob(pattern): + shutil.rmtree(path, ignore_errors=True) + if record_video and video_dir: logger.info(f"Video(s) saved in: {video_dir}") From bdae83b715c518cc41a47332af0caebed5e26f96 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Thu, 4 Jun 2026 12:52:07 +0000 Subject: [PATCH 3/3] =?UTF-8?q?SharePoint=20folder=20listing=20requests=20?= =?UTF-8?q?500=20items=20per=20page=20to=20cover=20alphabetically-late=20p?= =?UTF-8?q?roperties=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/sharepoint/domna_sharepoint_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/sharepoint/domna_sharepoint_client.py b/utils/sharepoint/domna_sharepoint_client.py index 3e9168ba..c36cb418 100644 --- a/utils/sharepoint/domna_sharepoint_client.py +++ b/utils/sharepoint/domna_sharepoint_client.py @@ -37,7 +37,7 @@ class DomnaSharepointClient: site_id=self.sharepoint_drive.value, ) - return sharepoint_client.list_folder_contents(path) + return sharepoint_client.list_folder_contents(path, page_size=500) def does_folder_exists_at(self, file_name: str, file_path: str): folders: Dict[str, Any] = self.get_folders_in_path(file_path)