Skip to content

Commit 0977f88

Browse files
authored
fix: update api generator to support new api.json format (microsoft#275)
1 parent a80f3ff commit 0977f88

11 files changed

+47
-21
lines changed

api.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

build_package.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222

2323
from playwright.path_utils import get_file_dirname
2424

25-
driver_version_64 = "0.160.0-next.1604019206789"
26-
driver_version_32 = "0.160.0-next.1604019246361"
25+
driver_version_64 = "0.160.0-next.1604373941495"
26+
driver_version_32 = "0.160.0-next.1604373978475"
2727

2828

2929
def driver_version(platform: str) -> str:

playwright/async_api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5880,7 +5880,7 @@ async def newContext(
58805880
acceptDownloads : Optional[bool]
58815881
Whether to automatically download all the attachments. Defaults to `false` where all the downloads are canceled.
58825882
proxy : Optional[{"server": str, "bypass": Optional[str], "username": Optional[str], "password": Optional[str]}]
5883-
Network proxy settings to use with this context. Note that browser needs to be launched with the global proxy for this option to work. If all contexts override the proxy, global proxy will be never used and can be any string, for example `launch({ proxy: { server: 'per-proxy' } })`.
5883+
Network proxy settings to use with this context. Note that browser needs to be launched with the global proxy for this option to work. If all contexts override the proxy, global proxy will be never used and can be any string, for example `launch({ proxy: { server: 'per-context' } })`.
58845884
videosPath : Optional[str]
58855885
Enables video recording for all pages to `videosPath` folder. If not specified, videos are not recorded. Make sure to await `browserContext.close` for videos to be saved.
58865886
videoSize : Optional[{"width": int, "height": int}]
@@ -5985,7 +5985,7 @@ async def newPage(
59855985
acceptDownloads : Optional[bool]
59865986
Whether to automatically download all the attachments. Defaults to `false` where all the downloads are canceled.
59875987
proxy : Optional[{"server": str, "bypass": Optional[str], "username": Optional[str], "password": Optional[str]}]
5988-
Network proxy settings to use with this context. Note that browser needs to be launched with the global proxy for this option to work. If all contexts override the proxy, global proxy will be never used and can be any string, for example `launch({ proxy: { server: 'per-proxy' } })`.
5988+
Network proxy settings to use with this context. Note that browser needs to be launched with the global proxy for this option to work. If all contexts override the proxy, global proxy will be never used and can be any string, for example `launch({ proxy: { server: 'per-context' } })`.
59895989
videosPath : Optional[str]
59905990
Enables video recording for all pages to `videosPath` folder. If not specified, videos are not recorded. Make sure to await `page.close` for videos to be saved.
59915991
videoSize : Optional[{"width": int, "height": int}]

playwright/browser.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
IntSize,
2626
ProxyServer,
2727
RecordHarOptions,
28+
is_safe_close_error,
2829
locals_to_params,
2930
)
3031
from playwright.network import serialize_headers
@@ -150,7 +151,11 @@ async def close(self) -> None:
150151
if self._is_closed_or_closing:
151152
return
152153
self._is_closed_or_closing = True
153-
await self._channel.send("close")
154+
try:
155+
await self._channel.send("close")
156+
except Exception as e:
157+
if not is_safe_close_error(e):
158+
raise e
154159

155160
@property
156161
def version(self) -> str:

playwright/browser_context.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
TimeoutSettings,
3030
URLMatch,
3131
URLMatcher,
32+
is_safe_close_error,
3233
locals_to_params,
3334
)
3435
from playwright.network import Request, Route, serialize_headers
@@ -228,7 +229,11 @@ async def close(self) -> None:
228229
if self._is_closed_or_closing:
229230
return
230231
self._is_closed_or_closing = True
231-
await self._channel.send("close")
232+
try:
233+
await self._channel.send("close")
234+
except Exception as e:
235+
if not is_safe_close_error(e):
236+
raise e
232237

233238
def expect_event(
234239
self,

playwright/helper.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,13 @@ def __init__(self, matcher: URLMatcher, handler: RouteHandler):
321321
self.handler = handler
322322

323323

324+
def is_safe_close_error(error: Exception) -> bool:
325+
message = str(error)
326+
return message.endswith("Browser has been closed") or message.endswith(
327+
"Target page, context or browser has been closed"
328+
)
329+
330+
324331
def not_installed_error(message: str) -> Exception:
325332
return Exception(
326333
f"""

playwright/page.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
URLMatcher,
4848
Viewport,
4949
is_function_body,
50+
is_safe_close_error,
5051
locals_to_params,
5152
parse_error,
5253
serialize_error,
@@ -622,9 +623,13 @@ async def title(self) -> str:
622623
return await self._main_frame.title()
623624

624625
async def close(self, runBeforeUnload: bool = None) -> None:
625-
await self._channel.send("close", locals_to_params(locals()))
626-
if self._owned_context:
627-
await self._owned_context.close()
626+
try:
627+
await self._channel.send("close", locals_to_params(locals()))
628+
if self._owned_context:
629+
await self._owned_context.close()
630+
except Exception as e:
631+
if not is_safe_close_error(e):
632+
raise e
628633

629634
def isClosed(self) -> bool:
630635
return self._is_closed

playwright/sync_api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6116,7 +6116,7 @@ def newContext(
61166116
acceptDownloads : Optional[bool]
61176117
Whether to automatically download all the attachments. Defaults to `false` where all the downloads are canceled.
61186118
proxy : Optional[{"server": str, "bypass": Optional[str], "username": Optional[str], "password": Optional[str]}]
6119-
Network proxy settings to use with this context. Note that browser needs to be launched with the global proxy for this option to work. If all contexts override the proxy, global proxy will be never used and can be any string, for example `launch({ proxy: { server: 'per-proxy' } })`.
6119+
Network proxy settings to use with this context. Note that browser needs to be launched with the global proxy for this option to work. If all contexts override the proxy, global proxy will be never used and can be any string, for example `launch({ proxy: { server: 'per-context' } })`.
61206120
videosPath : Optional[str]
61216121
Enables video recording for all pages to `videosPath` folder. If not specified, videos are not recorded. Make sure to await `browserContext.close` for videos to be saved.
61226122
videoSize : Optional[{"width": int, "height": int}]
@@ -6223,7 +6223,7 @@ def newPage(
62236223
acceptDownloads : Optional[bool]
62246224
Whether to automatically download all the attachments. Defaults to `false` where all the downloads are canceled.
62256225
proxy : Optional[{"server": str, "bypass": Optional[str], "username": Optional[str], "password": Optional[str]}]
6226-
Network proxy settings to use with this context. Note that browser needs to be launched with the global proxy for this option to work. If all contexts override the proxy, global proxy will be never used and can be any string, for example `launch({ proxy: { server: 'per-proxy' } })`.
6226+
Network proxy settings to use with this context. Note that browser needs to be launched with the global proxy for this option to work. If all contexts override the proxy, global proxy will be never used and can be any string, for example `launch({ proxy: { server: 'per-context' } })`.
62276227
videosPath : Optional[str]
62286228
Enables video recording for all pages to `videosPath` folder. If not specified, videos are not recorded. Make sure to await `page.close` for videos to be saved.
62296229
videoSize : Optional[{"width": int, "height": int}]

scripts/documentation_provider.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,15 @@ def print_entry(
7878
self.printed_entries.append(f"ElementHandle.{method_name}")
7979
clazz = self.api[class_name]
8080
super_clazz = self.api.get(clazz.get("extends"))
81-
method = clazz["members"].get(method_name) or super_clazz["members"].get(
82-
method_name
81+
method = (
82+
clazz["methods"].get(method_name)
83+
or clazz["properties"].get(method_name)
84+
or super_clazz["methods"].get(method_name)
8385
)
8486
fqname = f"{class_name}.{method_name}"
8587
indent = " " * 8
8688
print(f'{indent}"""{class_name}.{original_method_name}')
87-
if method["comment"]:
89+
if method.get("comment"):
8890
print(f"{indent}{self.beautify_method_comment(method['comment'], indent)}")
8991
signature_no_return = {**signature} if signature else None
9092
if signature_no_return and "return" in signature_no_return:
@@ -134,7 +136,7 @@ def print_entry(
134136
code_type = self.serialize_python_type(value)
135137

136138
print(f"{indent}{original_name} : {code_type}")
137-
if doc_value["comment"]:
139+
if doc_value.get("comment"):
138140
print(
139141
f"{indent} {self.indent_paragraph(doc_value['comment'], f'{indent} ')}"
140142
)
@@ -156,7 +158,7 @@ def print_entry(
156158
print(" Returns")
157159
print(" -------")
158160
print(f" {self.serialize_python_type(value)}")
159-
if method["returnComment"]:
161+
if method.get("returnComment"):
160162
print(
161163
f" {self.indent_paragraph(method['returnComment'], ' ')}"
162164
)
@@ -393,9 +395,9 @@ def print_remainder(self) -> None:
393395
class_name = re.sub(r"Chromium(.*)", r"\1", class_name)
394396
class_name = re.sub(r"WebKit(.*)", r"\1", class_name)
395397
class_name = re.sub(r"Firefox(.*)", r"\1", class_name)
396-
for [method_name, method] in value["members"].items():
397-
if method["kind"] == "event":
398-
continue
398+
for [method_name, method] in list(value["methods"].items()) + list(
399+
value["properties"].items()
400+
):
399401
entry = f"{class_name}.{method_name}"
400402
if entry not in self.printed_entries:
401403
self.errors.add(f"Method not implemented: {entry}")

scripts/expected_api_mismatch.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ Method not implemented: Download.createReadStream
1919
Method not implemented: Logger.isEnabled
2020
Method not implemented: Logger.log
2121
Method not implemented: Page.coverage
22+
Method not implemented: WebSocket.isClosed
23+
Method not implemented: WebSocket.waitForEvent
2224

2325
# Parameter overloads
2426
Parameter not documented: BrowserContext.waitForEvent(predicate=)

tests/async/test_cdp_session.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ async def test_should_be_able_to_detach_session(page):
5454
await client.send(
5555
"Runtime.evaluate", {"expression": "3 + 1", "returnByValue": True}
5656
)
57-
assert "Target browser or context has been closed" in exc_info.value.message
57+
assert "Target page, context or browser has been closed" in exc_info.value.message
5858

5959

6060
@pytest.mark.only_browser("chromium")

0 commit comments

Comments
 (0)