@@ -42,29 +42,29 @@ async def _run_chromium_devtools() -> Tuple[subprocess.Popen, str]:
42
42
return proc , devtools_url
43
43
44
44
45
- def _run_playwright_browser_server () -> Tuple [subprocess .Popen , str ]:
45
+ def _run_chromium_browser_server () -> Tuple [subprocess .Popen , str ]:
46
46
"""Start a Playwright server in a separate process, return the process
47
47
object and a string with its websocket endpoint.
48
48
Pass fixed port and ws path as arguments instead of allowing Playwright
49
49
to choose, for some reason I was unable to capture stdout/stderr :shrug:
50
50
"""
51
51
port = str (random .randint (60_000 , 63_000 ))
52
52
ws_path = str (uuid .uuid4 ())
53
- launch_server_script_path = str (Path (__file__ ).parent .parent / "launch_browser_server .js" )
53
+ launch_server_script_path = str (Path (__file__ ).parent .parent / "launch_chromium_server .js" )
54
54
command = ["node" , launch_server_script_path , port , ws_path ]
55
55
proc = subprocess .Popen (command ) # pylint: disable=consider-using-with
56
56
return proc , f"ws://localhost:{ port } /{ ws_path } "
57
57
58
58
59
59
@asynccontextmanager
60
- async def remote_browser ( is_chrome_devtools_protocol : bool = True ):
60
+ async def remote_chromium ( with_devtools_protocol : bool = True ):
61
61
"""Launch a remote browser that lasts while in the context."""
62
62
proc = url = None
63
63
try :
64
- if is_chrome_devtools_protocol :
64
+ if with_devtools_protocol :
65
65
proc , url = await _run_chromium_devtools ()
66
66
else :
67
- proc , url = _run_playwright_browser_server ()
67
+ proc , url = _run_chromium_browser_server ()
68
68
await asyncio .sleep (1 ) # allow some time for the browser to start
69
69
except Exception :
70
70
pass
@@ -77,15 +77,15 @@ async def remote_browser(is_chrome_devtools_protocol: bool = True):
77
77
proc .communicate ()
78
78
79
79
80
- class TestRemote (IsolatedAsyncioTestCase ):
80
+ class TestRemoteBrowser (IsolatedAsyncioTestCase ):
81
81
@pytest .fixture (autouse = True )
82
82
def inject_fixtures (self , caplog ):
83
83
caplog .set_level (logging .DEBUG )
84
84
self ._caplog = caplog
85
85
86
86
@allow_windows
87
87
async def test_connect_devtools (self ):
88
- async with remote_browser ( is_chrome_devtools_protocol = True ) as devtools_url :
88
+ async with remote_chromium ( with_devtools_protocol = True ) as devtools_url :
89
89
settings_dict = {
90
90
"PLAYWRIGHT_CDP_URL" : devtools_url ,
91
91
"PLAYWRIGHT_LAUNCH_OPTIONS" : {"headless" : True },
@@ -103,7 +103,7 @@ async def test_connect_devtools(self):
103
103
104
104
@allow_windows
105
105
async def test_connect (self ):
106
- async with remote_browser ( is_chrome_devtools_protocol = False ) as browser_url :
106
+ async with remote_chromium ( with_devtools_protocol = False ) as browser_url :
107
107
settings_dict = {
108
108
"PLAYWRIGHT_CONNECT_URL" : browser_url ,
109
109
"PLAYWRIGHT_LAUNCH_OPTIONS" : {"headless" : True },
@@ -128,3 +128,47 @@ async def test_connect(self):
128
128
logging .WARNING ,
129
129
"Connecting to remote browser, ignoring PLAYWRIGHT_LAUNCH_OPTIONS" ,
130
130
) in self ._caplog .record_tuples
131
+
132
+
133
+ class TestBrowserReconnect (IsolatedAsyncioTestCase ):
134
+ @pytest .fixture (autouse = True )
135
+ def inject_fixtures (self , caplog ):
136
+ caplog .set_level (logging .DEBUG )
137
+ self ._caplog = caplog
138
+
139
+ @allow_windows
140
+ async def test_restart_browser (self ):
141
+ spider = Spider ("foo" )
142
+ async with make_handler () as handler :
143
+ with StaticMockServer () as server :
144
+ req1 = Request (
145
+ server .urljoin ("/index.html" ),
146
+ meta = {"playwright" : True , "playwright_include_page" : True },
147
+ )
148
+ resp1 = await handler ._download_request (req1 , spider )
149
+ page = resp1 .meta ["playwright_page" ]
150
+ await page .context .browser .close ()
151
+ req2 = Request (server .urljoin ("/gallery.html" ), meta = {"playwright" : True })
152
+ resp2 = await handler ._download_request (req2 , spider )
153
+ assert_correct_response (resp1 , req1 )
154
+ assert_correct_response (resp2 , req2 )
155
+ assert (
156
+ self ._caplog .record_tuples .count (
157
+ (
158
+ "scrapy-playwright" ,
159
+ logging .DEBUG ,
160
+ "Browser disconnected" ,
161
+ )
162
+ )
163
+ == 2 # one mid-crawl after calling Browser.close() manually, one at the end
164
+ )
165
+ assert (
166
+ self ._caplog .record_tuples .count (
167
+ (
168
+ "scrapy-playwright" ,
169
+ logging .INFO ,
170
+ "Launching browser chromium" ,
171
+ )
172
+ )
173
+ == 2 # one at the beginning, one after calling Browser.close() manually
174
+ )
0 commit comments