(self)
| 772 | self.playwright = None |
| 773 | |
| 774 | async def _start(self) -> None: |
| 775 | from playwright.async_api import async_playwright |
| 776 | |
| 777 | self.profile_dir.mkdir(parents=True, exist_ok=True) |
| 778 | self.downloads_dir.mkdir(parents=True, exist_ok=True) |
| 779 | self._release_orphaned_profile_singleton() |
| 780 | browser_config = get_browser_config() |
| 781 | launch_config = build_browser_launch_config(browser_config) |
| 782 | configure_playwright_env() |
| 783 | browser_binary = ensure_playwright_binary() |
| 784 | |
| 785 | self.playwright = await async_playwright().start() |
| 786 | launch_kwargs: dict[str, Any] = { |
| 787 | "user_data_dir": str(self.profile_dir), |
| 788 | "headless": True, |
| 789 | "accept_downloads": True, |
| 790 | "downloads_path": str(self.downloads_dir), |
| 791 | "viewport": DEFAULT_VIEWPORT, |
| 792 | "screen": DEFAULT_VIEWPORT, |
| 793 | "no_viewport": False, |
| 794 | "args": launch_config["args"], |
| 795 | } |
| 796 | if launch_config["channel"]: |
| 797 | launch_kwargs["channel"] = launch_config["channel"] |
| 798 | else: |
| 799 | launch_kwargs["executable_path"] = str(browser_binary) |
| 800 | try: |
| 801 | self.context = await self.playwright.chromium.launch_persistent_context( |
| 802 | **launch_kwargs |
| 803 | ) |
| 804 | except Exception: |
| 805 | if self.playwright: |
| 806 | try: |
| 807 | await self.playwright.stop() |
| 808 | except Exception: |
| 809 | pass |
| 810 | self.playwright = None |
| 811 | raise |
| 812 | self.context.set_default_timeout(30000) |
| 813 | self.context.set_default_navigation_timeout(30000) |
| 814 | self.context.on("close", self._on_context_closed) |
| 815 | self.context.on("page", self._on_new_page_sync) |
| 816 | await self.context.add_init_script(path=str(DOM_HELPER_PATH)) |
| 817 | await self.context.add_init_script(path=str(CONTENT_HELPER_PATH)) |
| 818 | |
| 819 | for page in list(self.context.pages): |
| 820 | if page.url == "about:blank": |
| 821 | try: |
| 822 | await page.close() |
| 823 | except Exception: |
| 824 | pass |
| 825 | continue |
| 826 | await self._register_page(page) |
| 827 | |
| 828 | def _release_orphaned_profile_singleton(self) -> None: |
| 829 | lock_path = self.profile_dir / "SingletonLock" |
no test coverage detected