Skip to content

Commit 9534c38

Browse files
feat(roll): roll to Playwright 1.12.0-next-1621456974000 (microsoft#682)
1 parent 50892f6 commit 9534c38

17 files changed

+524
-159
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ Playwright is a Python library to automate [Chromium](https://www.chromium.org/H
66

77
| | Linux | macOS | Windows |
88
| :--- | :---: | :---: | :---: |
9-
| Chromium <!-- GEN:chromium-version -->92.0.4498.0<!-- GEN:stop --> ||||
9+
| Chromium <!-- GEN:chromium-version -->92.0.4500.0<!-- GEN:stop --> ||||
1010
| WebKit <!-- GEN:webkit-version -->14.2<!-- GEN:stop --> ||||
11-
| Firefox <!-- GEN:firefox-version -->89.0b6<!-- GEN:stop --> ||||
11+
| Firefox <!-- GEN:firefox-version -->89.0b9<!-- GEN:stop --> ||||
1212

1313
Headless execution is supported for all browsers on all platforms.
1414

playwright/_impl/_browser_context.py

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@
2222
from playwright._impl._api_structures import Cookie, Geolocation, StorageState
2323
from playwright._impl._api_types import Error
2424
from playwright._impl._cdp_session import CDPSession
25-
from playwright._impl._connection import ChannelOwner, from_channel
25+
from playwright._impl._connection import (
26+
ChannelOwner,
27+
from_channel,
28+
from_nullable_channel,
29+
)
2630
from playwright._impl._event_context_manager import EventContextManagerImpl
2731
from playwright._impl._helper import (
2832
RouteHandler,
@@ -33,8 +37,9 @@
3337
is_safe_close_error,
3438
locals_to_params,
3539
)
36-
from playwright._impl._network import Request, Route, serialize_headers
40+
from playwright._impl._network import Request, Response, Route, serialize_headers
3741
from playwright._impl._page import BindingCall, Page, Worker
42+
from playwright._impl._tracing import Tracing
3843
from playwright._impl._wait_helper import WaitHelper
3944

4045
if TYPE_CHECKING: # pragma: no cover
@@ -48,6 +53,10 @@ class BrowserContext(ChannelOwner):
4853
Close="close",
4954
Page="page",
5055
ServiceWorker="serviceworker",
56+
Request="request",
57+
Response="response",
58+
RequestFailed="requestfailed",
59+
RequestFinished="requestfinished",
5160
)
5261

5362
def __init__(
@@ -64,7 +73,7 @@ def __init__(
6473
self._options: Dict[str, Any] = {}
6574
self._background_pages: Set[Page] = set()
6675
self._service_workers: Set[Worker] = set()
67-
76+
self._tracing = Tracing(self)
6877
self._channel.on(
6978
"bindingCall",
7079
lambda params: self._on_binding(from_channel(params["binding"])),
@@ -89,6 +98,37 @@ def __init__(
8998
"serviceWorker",
9099
lambda params: self._on_service_worker(from_channel(params["worker"])),
91100
)
101+
self._channel.on(
102+
"request",
103+
lambda params: self._on_request(
104+
from_channel(params["request"]),
105+
from_nullable_channel(params.get("page")),
106+
),
107+
)
108+
self._channel.on(
109+
"response",
110+
lambda params: self._on_response(
111+
from_channel(params["response"]),
112+
from_nullable_channel(params.get("page")),
113+
),
114+
)
115+
self._channel.on(
116+
"requestFailed",
117+
lambda params: self._on_request_failed(
118+
from_channel(params["request"]),
119+
params["responseEndTiming"],
120+
params["failureText"],
121+
from_nullable_channel(params.get("page")),
122+
),
123+
)
124+
self._channel.on(
125+
"requestFinished",
126+
lambda params: self._on_request_finished(
127+
from_channel(params["request"]),
128+
params["responseEndTiming"],
129+
from_nullable_channel(params.get("page")),
130+
),
131+
)
92132

93133
def __repr__(self) -> str:
94134
return f"<BrowserContext browser={self.browser}>"
@@ -287,6 +327,39 @@ def _on_service_worker(self, worker: Worker) -> None:
287327
self._service_workers.add(worker)
288328
self.emit(BrowserContext.Events.ServiceWorker, worker)
289329

330+
def _on_request_failed(
331+
self,
332+
request: Request,
333+
response_end_timing: float,
334+
failure_text: Optional[str],
335+
page: Optional[Page],
336+
) -> None:
337+
request._failure_text = failure_text
338+
if request._timing:
339+
request._timing["responseEnd"] = response_end_timing
340+
self.emit(BrowserContext.Events.RequestFailed, request)
341+
if page:
342+
page.emit(Page.Events.RequestFailed, request)
343+
344+
def _on_request_finished(
345+
self, request: Request, response_end_timing: float, page: Optional[Page]
346+
) -> None:
347+
if request._timing:
348+
request._timing["responseEnd"] = response_end_timing
349+
self.emit(BrowserContext.Events.RequestFinished, request)
350+
if page:
351+
page.emit(Page.Events.RequestFinished, request)
352+
353+
def _on_request(self, request: Request, page: Optional[Page]) -> None:
354+
self.emit(BrowserContext.Events.Request, request)
355+
if page:
356+
page.emit(Page.Events.Request, request)
357+
358+
def _on_response(self, response: Response, page: Optional[Page]) -> None:
359+
self.emit(BrowserContext.Events.Response, response)
360+
if page:
361+
page.emit(Page.Events.Response, response)
362+
290363
@property
291364
def background_pages(self) -> List[Page]:
292365
return list(self._background_pages)
@@ -299,3 +372,7 @@ async def new_cdp_session(self, page: Page) -> CDPSession:
299372
return from_channel(
300373
await self._channel.send("newCDPSession", {"page": page._channel})
301374
)
375+
376+
@property
377+
def tracing(self) -> Tracing:
378+
return self._tracing

playwright/_impl/_browser_type.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
import asyncio
16+
import pathlib
1617
from pathlib import Path
1718
from typing import Dict, List, Optional, Union, cast
1819

@@ -75,6 +76,7 @@ async def launch(
7576
proxy: ProxySettings = None,
7677
downloadsPath: Union[str, Path] = None,
7778
slowMo: float = None,
79+
traceDir: Union[pathlib.Path, str] = None,
7880
chromiumSandbox: bool = None,
7981
firefoxUserPrefs: Dict[str, Union[str, float, bool]] = None,
8082
) -> Browser:
@@ -123,6 +125,7 @@ async def launch_persistent_context(
123125
hasTouch: bool = None,
124126
colorScheme: ColorScheme = None,
125127
acceptDownloads: bool = None,
128+
traceDir: Union[pathlib.Path, str] = None,
126129
chromiumSandbox: bool = None,
127130
recordHarPath: Union[Path, str] = None,
128131
recordHarOmitContent: bool = None,
@@ -209,7 +212,14 @@ async def connect(
209212
browser._is_remote = True
210213
browser._is_connected_over_websocket = True
211214

212-
transport.once("close", browser._on_close)
215+
def handle_transport_close() -> None:
216+
for context in browser.contexts:
217+
for page in context.pages:
218+
page._on_close()
219+
context._on_close()
220+
browser._on_close()
221+
222+
transport.once("close", handle_transport_close)
213223

214224
return browser
215225

playwright/_impl/_download.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class Download:
2626
def __init__(
2727
self, page: "Page", url: str, suggested_filename: str, artifact: Artifact
2828
) -> None:
29+
self._page = page
2930
self._loop = page._loop
3031
self._dispatcher_fiber = page._dispatcher_fiber
3132
self._url = url
@@ -35,6 +36,10 @@ def __init__(
3536
def __repr__(self) -> str:
3637
return f"<Download url={self.url!r} suggested_filename={self.suggested_filename!r}>"
3738

39+
@property
40+
def page(self) -> "Page":
41+
return self._page
42+
3843
@property
3944
def url(self) -> str:
4045
return self._url

playwright/_impl/_helper.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@
5959
"chrome-beta",
6060
"chrome-canary",
6161
"chrome-dev",
62-
"firefox-stable",
6362
"msedge",
6463
"msedge-beta",
6564
"msedge-canary",

playwright/_impl/_page.py

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -173,32 +173,6 @@ def __init__(
173173
Page.Events.PageError, parse_error(params["error"]["error"])
174174
),
175175
)
176-
self._channel.on(
177-
"request",
178-
lambda params: self.emit(
179-
Page.Events.Request, from_channel(params["request"])
180-
),
181-
)
182-
self._channel.on(
183-
"requestFailed",
184-
lambda params: self._on_request_failed(
185-
from_channel(params["request"]),
186-
params["responseEndTiming"],
187-
params["failureText"],
188-
),
189-
)
190-
self._channel.on(
191-
"requestFinished",
192-
lambda params: self._on_request_finished(
193-
from_channel(params["request"]), params["responseEndTiming"]
194-
),
195-
)
196-
self._channel.on(
197-
"response",
198-
lambda params: self.emit(
199-
Page.Events.Response, from_channel(params["response"])
200-
),
201-
)
202176
self._channel.on(
203177
"route",
204178
lambda params: self._on_route(
@@ -219,24 +193,6 @@ def __init__(
219193
def __repr__(self) -> str:
220194
return f"<Page url={self.url!r}>"
221195

222-
def _on_request_failed(
223-
self,
224-
request: Request,
225-
response_end_timing: float,
226-
failure_text: str = None,
227-
) -> None:
228-
request._failure_text = failure_text
229-
if request._timing:
230-
request._timing["responseEnd"] = response_end_timing
231-
self.emit(Page.Events.RequestFailed, request)
232-
233-
def _on_request_finished(
234-
self, request: Request, response_end_timing: float
235-
) -> None:
236-
if request._timing:
237-
request._timing["responseEnd"] = response_end_timing
238-
self.emit(Page.Events.RequestFinished, request)
239-
240196
def _on_frame_attached(self, frame: Frame) -> None:
241197
frame._page = self
242198
self._frames.append(frame)

playwright/_impl/_tracing.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Copyright (c) Microsoft Corporation.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import pathlib
16+
from typing import TYPE_CHECKING, Union, cast
17+
18+
from playwright._impl._artifact import Artifact
19+
from playwright._impl._connection import from_channel
20+
from playwright._impl._helper import locals_to_params
21+
22+
if TYPE_CHECKING:
23+
from playwright._impl._browser_context import BrowserContext
24+
25+
26+
class Tracing:
27+
def __init__(self, context: "BrowserContext") -> None:
28+
self._context = context
29+
self._channel = context._channel
30+
self._loop = context._loop
31+
32+
async def start(
33+
self, name: str = None, snapshots: bool = None, screenshots: bool = None
34+
) -> None:
35+
params = locals_to_params(locals())
36+
await self._channel.send("tracingStart", params)
37+
38+
async def stop(self) -> None:
39+
await self._channel.send("tracingStop")
40+
41+
async def export(self, path: Union[pathlib.Path, str]) -> None:
42+
artifact = cast(
43+
Artifact, from_channel(await self._channel.send("tracingExport"))
44+
)
45+
if self._context._browser:
46+
artifact._is_remote = self._context._browser._is_remote
47+
await artifact.save_as(path)
48+
await artifact.delete()

playwright/_impl/_transport.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ def __init__(
161161

162162
def request_stop(self) -> None:
163163
self._stopped = True
164+
self.emit("close")
164165
self._loop.create_task(self._connection.close())
165166

166167
def dispose(self) -> None:
@@ -190,7 +191,10 @@ async def run(self) -> None:
190191
break
191192
obj = self.deserialize_message(message)
192193
self.on_message(obj)
193-
except websockets.exceptions.ConnectionClosed:
194+
except (
195+
websockets.exceptions.ConnectionClosed,
196+
websockets.exceptions.ConnectionClosedError,
197+
):
194198
if not self._stopped:
195199
self.emit("close")
196200
self.on_error_future.set_exception(

0 commit comments

Comments
 (0)