11import logging
22import os
33import signal
4+ from contextlib import AbstractAsyncContextManager
45from enum import Enum
56from threading import Event
67from typing import AsyncGenerator
78
89import pytest
910
1011import zendriver as zd
11- from tests .browser_args import get_browser_args
1212
1313logger = logging .getLogger (__name__ )
1414
@@ -28,26 +28,82 @@ def fixture_params(self):
2828 return [{"headless" : True }, {"headless" : False }]
2929
3030
31- BROWSER_MODE = BrowserMode (os .getenv ("ZENDRIVER_TEST_BROWSERS" , "all" ))
32-
33- PAUSE_AFTER_TEST = os .getenv ("ZENDRIVER_PAUSE_AFTER_TEST" , "false" ) == "true"
3431NEXT_TEST_EVENT = Event ()
3532
3633
37- @pytest .fixture (params = BROWSER_MODE .fixture_params )
38- async def browser (request : pytest .FixtureRequest ) -> AsyncGenerator [zd .Browser , None ]:
34+ class TestConfig :
35+ BROWSER_MODE = BrowserMode (os .getenv ("ZENDRIVER_TEST_BROWSERS" , "all" ))
36+ PAUSE_AFTER_TEST = os .getenv ("ZENDRIVER_PAUSE_AFTER_TEST" , "false" ) == "true"
37+ SANDBOX = os .getenv ("ZENDRIVER_TEST_SANDBOX" , "false" ) == "true"
38+ USE_WAYLAND = os .getenv ("WAYLAND_DISPLAY" ) is not None
39+
40+
41+ class CreateBrowser (AbstractAsyncContextManager ):
42+ def __init__ (
43+ self ,
44+ * ,
45+ headless : bool = True ,
46+ sandbox : bool = TestConfig .SANDBOX ,
47+ browser_args : list [str ] | None = None ,
48+ ):
49+ self .headless = headless
50+ self .sandbox = sandbox
51+ self .browser_args = browser_args
52+ self .browser : zd .Browser | None = None
53+ self .browser_pid : int | None = None
54+
55+ def _browser_args (self ) -> list [str ]:
56+ args = []
57+ if not self .headless and TestConfig .USE_WAYLAND :
58+ # use wayland backend instead of x11
59+ args .extend (
60+ ["--disable-features=UseOzonePlatform" , "--ozone-platform=wayland" ]
61+ )
62+ if self .browser_args is not None :
63+ args .extend (self .browser_args )
64+
65+ return args
66+
67+ def config (self ) -> zd .Config :
68+ return zd .Config (
69+ headless = self .headless ,
70+ sandbox = self .sandbox ,
71+ browser_args = self ._browser_args (),
72+ )
73+
74+ async def __aenter__ (self ) -> zd .Browser :
75+ self .browser = await zd .start (self .config ())
76+ browser_pid = self .browser ._process_pid
77+ assert browser_pid is not None and browser_pid > 0
78+ await self .browser .wait (0 )
79+ return self .browser
80+
81+ async def __aexit__ (self , exc_type , exc_val , exc_tb ):
82+ if self .browser is not None :
83+ await self .browser .stop ()
84+ assert self .browser_pid is None
85+
86+
87+ @pytest .fixture
88+ def create_browser () -> type [CreateBrowser ]:
89+ return CreateBrowser
90+
91+
92+ @pytest .fixture (params = TestConfig .BROWSER_MODE .fixture_params )
93+ def headless (request : pytest .FixtureRequest ) -> bool :
94+ return request .param ["headless" ]
95+
96+
97+ @pytest .fixture
98+ async def browser (
99+ headless : bool , create_browser : type [CreateBrowser ]
100+ ) -> AsyncGenerator [zd .Browser , None ]:
39101 NEXT_TEST_EVENT .clear ()
40- args = get_browser_args (headless = request .param ["headless" ])
41- browser = await zd .start (
42- # use wayland for rendering instead of default X11 backend
43- browser_args = args ,
44- headless = request .param ["headless" ],
45- )
46- browser_pid = browser ._process_pid
47- assert browser_pid is not None and browser_pid > 0
48- await browser .wait (0 )
49- yield browser
50- if PAUSE_AFTER_TEST :
102+
103+ async with create_browser (headless = headless ) as browser :
104+ yield browser
105+
106+ if TestConfig .PAUSE_AFTER_TEST :
51107 logger .info (
52108 "Pausing after test. Send next test hotkey (default Mod+Return) to continue to next test"
53109 )
@@ -58,7 +114,7 @@ async def browser(request: pytest.FixtureRequest) -> AsyncGenerator[zd.Browser,
58114
59115# signal handler for starting next test
60116def handle_next_test (signum , frame ):
61- if not PAUSE_AFTER_TEST :
117+ if not TestConfig . PAUSE_AFTER_TEST :
62118 logger .warning (
63119 "Next test signal received, but ZENDRIVER_PAUSE_AFTER_TEST is not set."
64120 )
0 commit comments