Skip to content

Commit 49fa5e8

Browse files
committed
chore: move pure code into shared modules ported from upstream
1 parent ac0dd3c commit 49fa5e8

28 files changed

Lines changed: 668 additions & 503 deletions

‎playwright/_impl/_artifact.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
from typing import Dict, Optional, Union, cast
1818

1919
from playwright._impl._connection import ChannelOwner, from_channel
20-
from playwright._impl._helper import Error, make_dirs_for_file, patch_error_message
20+
from playwright._impl._errors import Error, patch_error_message
21+
from playwright._impl._helper import make_dirs_for_file
2122
from playwright._impl._stream import Stream
2223

2324

‎playwright/_impl/_assertions.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@
2020
from playwright._impl._connection import format_call_log
2121
from playwright._impl._errors import Error
2222
from playwright._impl._fetch import APIResponse
23-
from playwright._impl._helper import is_textual_mime_type
2423
from playwright._impl._internal_structures import (
2524
AriaRole,
2625
ExpectedTextValue,
2726
FrameExpectOptions,
2827
FrameExpectResult,
2928
)
30-
from playwright._impl._js_handle import parse_value
3129
from playwright._impl._locator import Locator
30+
from playwright._impl._mime_type import is_textual_mime_type
3231
from playwright._impl._page import Page
32+
from playwright._impl._serializers import parse_value
3333
from playwright._impl._str_utils import escape_regex_flags
3434

3535
_soft_errors: Optional[List[AssertionError]] = None

‎playwright/_impl/_browser_context.py‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,25 +50,24 @@
5050
from playwright._impl._debugger import Debugger
5151
from playwright._impl._dialog import Dialog
5252
from playwright._impl._disposable import Disposable, DisposableStub
53-
from playwright._impl._errors import Error, TargetClosedError
53+
from playwright._impl._errors import Error, TargetClosedError, parse_error
5454
from playwright._impl._event_context_manager import EventContextManagerImpl
5555
from playwright._impl._fetch import APIRequestContext
5656
from playwright._impl._frame import Frame
5757
from playwright._impl._har_router import HarRouter
58+
from playwright._impl._headers import serialize_headers
5859
from playwright._impl._helper import (
5960
HarContentPolicy,
6061
HarMode,
6162
RouteFromHarNotFoundPolicy,
6263
RouteHandler,
6364
RouteHandlerCallback,
64-
TimeoutSettings,
6565
URLMatch,
6666
WebSocketRouteHandlerCallback,
6767
async_readfile,
6868
async_writefile,
6969
create_task_and_ignore_exception,
7070
locals_to_params,
71-
parse_error,
7271
to_impl,
7372
)
7473
from playwright._impl._network import (
@@ -77,10 +76,10 @@
7776
Route,
7877
WebSocketRoute,
7978
WebSocketRouteHandler,
80-
serialize_headers,
8179
to_clear_cookies_params,
8280
)
8381
from playwright._impl._page import BindingCall, Page, Worker
82+
from playwright._impl._timeout_settings import TimeoutSettings
8483
from playwright._impl._tracing import Tracing
8584
from playwright._impl._waiter import Waiter
8685
from playwright._impl._web_error import WebError

‎playwright/_impl/_browser_type.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from playwright._impl._browser_context import BrowserContext
3030
from playwright._impl._connection import ChannelOwner, Connection, from_channel
3131
from playwright._impl._errors import Error
32+
from playwright._impl._headers import serialize_headers
3233
from playwright._impl._helper import (
3334
PLAYWRIGHT_MAX_DEADLINE,
3435
ColorScheme,
@@ -39,16 +40,15 @@
3940
HarMode,
4041
ReducedMotion,
4142
ServiceWorkersPolicy,
42-
TimeoutSettings,
4343
async_readfile,
4444
locals_to_params,
4545
)
4646
from playwright._impl._json_pipe import JsonPipeTransport
4747
from playwright._impl._network import (
48-
serialize_headers,
4948
to_client_certificates_protocol,
5049
to_http_credentials_protocol,
5150
)
51+
from playwright._impl._timeout_settings import TimeoutSettings
5252
from playwright._impl._waiter import throw_on_timeout
5353

5454
if TYPE_CHECKING:

‎playwright/_impl/_connection.py‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,16 @@
4040

4141
import playwright
4242
import playwright._impl._impl_to_api_mapping
43-
from playwright._impl._errors import TargetClosedError, rewrite_error
43+
from playwright._impl._errors import (
44+
Error,
45+
TargetClosedError,
46+
parse_error,
47+
rewrite_error,
48+
)
4449
from playwright._impl._greenlets import EventGreenlet
4550
from playwright._impl._helper import (
46-
Error,
4751
ParsedMessagePayload,
4852
create_task_and_ignore_exception,
49-
parse_error,
5053
)
5154
from playwright._impl._protocol_check import check_message, is_enabled
5255
from playwright._impl._transport import Transport

‎playwright/_impl/_element_handle.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929

3030
from playwright._impl._api_structures import FilePayload, FloatRect, Position
3131
from playwright._impl._connection import ChannelOwner, from_nullable_channel
32+
from playwright._impl._errors import Error
3233
from playwright._impl._helper import (
33-
Error,
3434
KeyboardModifier,
3535
MouseButton,
3636
async_writefile,

‎playwright/_impl/_errors.py‎

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,16 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
"""Port of packages/playwright-core/src/client/errors.ts."""
16+
1517
# These are types that we use in the API. They are public and are a part of the
1618
# stable API.
1719

1820

19-
from typing import Any, List, Optional
21+
import re
22+
import traceback
23+
from types import TracebackType
24+
from typing import Any, List, Optional, TypedDict
2025

2126

2227
def is_target_closed_error(error: Exception) -> bool:
@@ -62,3 +67,49 @@ def rewrite_error(error: Exception, message: str) -> Exception:
6267
rewritten_exc._details = error._details
6368
rewritten_exc._log = error._log
6469
return rewritten_exc
70+
71+
72+
class ErrorPayload(TypedDict, total=False):
73+
message: str
74+
name: str
75+
stack: str
76+
value: Optional[Any]
77+
78+
79+
def serialize_error(ex: Exception, tb: Optional[TracebackType]) -> ErrorPayload:
80+
return ErrorPayload(
81+
message=str(ex), name="Error", stack="".join(traceback.format_tb(tb))
82+
)
83+
84+
85+
def parse_error(error: ErrorPayload, log: Optional[str] = None) -> Error:
86+
base_error_class = Error
87+
if error.get("name") == "TimeoutError":
88+
base_error_class = TimeoutError
89+
if error.get("name") == "TargetClosedError":
90+
base_error_class = TargetClosedError
91+
if not log:
92+
log = ""
93+
exc = base_error_class(patch_error_message(error["message"]) + log)
94+
exc._name = error["name"]
95+
exc._stack = error["stack"]
96+
return exc
97+
98+
99+
def patch_error_message(message: str) -> str:
100+
match = re.match(r"(\w+)(: expected .*)", message)
101+
if match:
102+
message = to_snake_case(match.group(1)) + match.group(2)
103+
message = message.replace(
104+
"Pass { acceptDownloads: true }", "Pass 'accept_downloads=True'"
105+
)
106+
return message
107+
108+
109+
# Upstream: toSnakeCase() in packages/isomorphic/stringUtils.ts. It is here, not
110+
# in _str_utils.py, because _str_utils.py imports this module.
111+
to_snake_case_regex = re.compile("((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))")
112+
113+
114+
def to_snake_case(name: str) -> str:
115+
return to_snake_case_regex.sub(r"_\1", name).lower()

‎playwright/_impl/_fetch.py‎

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,27 +34,28 @@
3434
StorageState,
3535
)
3636
from playwright._impl._connection import ChannelOwner, from_channel
37-
from playwright._impl._errors import is_target_closed_error
37+
from playwright._impl._errors import Error, TargetClosedError, is_target_closed_error
3838
from playwright._impl._form_data import FormData
39+
from playwright._impl._headers import serialize_headers
3940
from playwright._impl._helper import (
40-
Error,
41-
NameValue,
42-
TargetClosedError,
43-
TimeoutSettings,
4441
async_readfile,
4542
async_writefile,
4643
is_file_payload,
4744
locals_to_params,
48-
object_to_array,
4945
to_impl,
5046
)
51-
from playwright._impl._internal_structures import FormField, Headers, ServerFilePayload
47+
from playwright._impl._internal_structures import (
48+
FormField,
49+
Headers,
50+
NameValue,
51+
ServerFilePayload,
52+
)
5253
from playwright._impl._network import (
53-
serialize_headers,
5454
to_clear_cookies_params,
5555
to_client_certificates_protocol,
5656
to_http_credentials_protocol,
5757
)
58+
from playwright._impl._timeout_settings import TimeoutSettings
5859
from playwright._impl._tracing import Tracing
5960

6061
if typing.TYPE_CHECKING:
@@ -493,6 +494,15 @@ async def storage_state(
493494
return result
494495

495496

497+
def object_to_array(obj: Optional[Dict]) -> Optional[List[NameValue]]:
498+
if not obj:
499+
return None
500+
result = []
501+
for key, value in obj.items():
502+
result.append(NameValue(name=key, value=str(value)))
503+
return result
504+
505+
496506
def file_payload_to_json(payload: FilePayload) -> ServerFilePayload:
497507
return ServerFilePayload(
498508
name=payload["name"],

‎playwright/_impl/_frame.py‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,9 @@
4444
FrameNavigatedEvent,
4545
KeyboardModifier,
4646
MouseButton,
47-
TimeoutSettings,
4847
URLMatch,
4948
async_readfile,
5049
locals_to_params,
51-
monotonic_time,
5250
url_matches,
5351
)
5452
from playwright._impl._internal_structures import (
@@ -61,24 +59,28 @@
6159
Serializable,
6260
add_source_url_to_script,
6361
parse_result,
64-
parse_value,
6562
serialize_argument,
6663
)
6764
from playwright._impl._locator import (
6865
ANY_FRAME_SELECTOR,
6966
FrameLocator,
7067
Locator,
68+
test_id_attribute_name,
69+
)
70+
from playwright._impl._locator_utils import (
7171
get_by_alt_text_selector,
7272
get_by_label_selector,
7373
get_by_placeholder_selector,
7474
get_by_role_selector,
7575
get_by_test_id_selector,
7676
get_by_text_selector,
7777
get_by_title_selector,
78-
test_id_attribute_name,
7978
)
8079
from playwright._impl._network import Response
80+
from playwright._impl._serializers import parse_value
8181
from playwright._impl._set_input_files_helpers import convert_input_files
82+
from playwright._impl._time import monotonic_time
83+
from playwright._impl._timeout_settings import TimeoutSettings
8284
from playwright._impl._waiter import Waiter
8385
from playwright._impl._web_mcp import WebMCP
8486

‎playwright/_impl/_headers.py‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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+
"""Port of packages/isomorphic/headers.ts."""
16+
17+
from typing import Dict
18+
19+
from playwright._impl._internal_structures import HeadersArray
20+
21+
22+
# Upstream: headersObjectToArray().
23+
def serialize_headers(headers: Dict[str, str]) -> HeadersArray:
24+
return [
25+
{"name": name, "value": value}
26+
for name, value in headers.items()
27+
if value is not None
28+
]

0 commit comments

Comments
 (0)