playwright-browserstack 1.62.0__py3-none-win32.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- playwright/__init__.py +19 -0
- playwright/__main__.py +33 -0
- playwright/_impl/__init__.py +0 -0
- playwright/_impl/__pyinstaller/__init__.py +20 -0
- playwright/_impl/__pyinstaller/hook-playwright.async_api.py +17 -0
- playwright/_impl/__pyinstaller/hook-playwright.sync_api.py +17 -0
- playwright/_impl/_android.py +704 -0
- playwright/_impl/_api_structures.py +365 -0
- playwright/_impl/_artifact.py +87 -0
- playwright/_impl/_assertions.py +1124 -0
- playwright/_impl/_async_base.py +105 -0
- playwright/_impl/_browser.py +293 -0
- playwright/_impl/_browser_context.py +754 -0
- playwright/_impl/_browser_type.py +368 -0
- playwright/_impl/_cdp_session.py +46 -0
- playwright/_impl/_clock.py +104 -0
- playwright/_impl/_connection.py +764 -0
- playwright/_impl/_console_message.py +98 -0
- playwright/_impl/_credentials.py +57 -0
- playwright/_impl/_debugger.py +54 -0
- playwright/_impl/_dialog.py +63 -0
- playwright/_impl/_disposable.py +96 -0
- playwright/_impl/_download.py +64 -0
- playwright/_impl/_driver.py +41 -0
- playwright/_impl/_element_handle.py +480 -0
- playwright/_impl/_errors.py +64 -0
- playwright/_impl/_event_context_manager.py +33 -0
- playwright/_impl/_fetch.py +626 -0
- playwright/_impl/_file_chooser.py +57 -0
- playwright/_impl/_form_data.py +34 -0
- playwright/_impl/_frame.py +985 -0
- playwright/_impl/_glob.py +65 -0
- playwright/_impl/_greenlets.py +49 -0
- playwright/_impl/_har_router.py +122 -0
- playwright/_impl/_helper.py +601 -0
- playwright/_impl/_impl_to_api_mapping.py +158 -0
- playwright/_impl/_input.py +111 -0
- playwright/_impl/_js_handle.py +336 -0
- playwright/_impl/_json_pipe.py +97 -0
- playwright/_impl/_local_utils.py +95 -0
- playwright/_impl/_locator.py +1024 -0
- playwright/_impl/_map.py +31 -0
- playwright/_impl/_network.py +1017 -0
- playwright/_impl/_object_factory.py +116 -0
- playwright/_impl/_page.py +1637 -0
- playwright/_impl/_path_utils.py +27 -0
- playwright/_impl/_playwright.py +68 -0
- playwright/_impl/_screencast.py +177 -0
- playwright/_impl/_selectors.py +67 -0
- playwright/_impl/_set_input_files_helpers.py +158 -0
- playwright/_impl/_str_utils.py +76 -0
- playwright/_impl/_stream.py +46 -0
- playwright/_impl/_sync_base.py +151 -0
- playwright/_impl/_tracing.py +281 -0
- playwright/_impl/_transport.py +184 -0
- playwright/_impl/_video.py +56 -0
- playwright/_impl/_waiter.py +197 -0
- playwright/_impl/_web_error.py +48 -0
- playwright/_impl/_web_storage.py +58 -0
- playwright/_impl/_writable_stream.py +42 -0
- playwright/_repo_version.py +24 -0
- playwright/async_api/__init__.py +275 -0
- playwright/async_api/_android_generated.py +462 -0
- playwright/async_api/_context_manager.py +57 -0
- playwright/async_api/_generated.py +23875 -0
- playwright/driver/LICENSE +2946 -0
- playwright/driver/README.md +1 -0
- playwright/driver/node.exe +0 -0
- playwright/driver/package/LICENSE +202 -0
- playwright/driver/package/NOTICE +5 -0
- playwright/driver/package/README.md +3 -0
- playwright/driver/package/ThirdPartyNotices.txt +13 -0
- playwright/driver/package/bin/install_media_pack.ps1 +5 -0
- playwright/driver/package/bin/install_webkit_wsl.ps1 +33 -0
- playwright/driver/package/bin/reinstall_chrome_beta_linux.sh +42 -0
- playwright/driver/package/bin/reinstall_chrome_beta_mac.sh +13 -0
- playwright/driver/package/bin/reinstall_chrome_beta_win.ps1 +24 -0
- playwright/driver/package/bin/reinstall_chrome_stable_linux.sh +42 -0
- playwright/driver/package/bin/reinstall_chrome_stable_mac.sh +12 -0
- playwright/driver/package/bin/reinstall_chrome_stable_win.ps1 +24 -0
- playwright/driver/package/bin/reinstall_msedge_beta_linux.sh +48 -0
- playwright/driver/package/bin/reinstall_msedge_beta_mac.sh +11 -0
- playwright/driver/package/bin/reinstall_msedge_beta_win.ps1 +23 -0
- playwright/driver/package/bin/reinstall_msedge_dev_linux.sh +48 -0
- playwright/driver/package/bin/reinstall_msedge_dev_mac.sh +11 -0
- playwright/driver/package/bin/reinstall_msedge_dev_win.ps1 +23 -0
- playwright/driver/package/bin/reinstall_msedge_stable_linux.sh +48 -0
- playwright/driver/package/bin/reinstall_msedge_stable_mac.sh +11 -0
- playwright/driver/package/bin/reinstall_msedge_stable_win.ps1 +24 -0
- playwright/driver/package/browsers.json +75 -0
- playwright/driver/package/cli.js +21 -0
- playwright/driver/package/index.d.ts +17 -0
- playwright/driver/package/index.js +17 -0
- playwright/driver/package/index.mjs +28 -0
- playwright/driver/package/lib/bootstrap.js +88 -0
- playwright/driver/package/lib/coreBundle.js +74830 -0
- playwright/driver/package/lib/entry/cliDaemon.js +5 -0
- playwright/driver/package/lib/entry/dashboardApp.js +3 -0
- playwright/driver/package/lib/entry/mcp.js +10 -0
- playwright/driver/package/lib/entry/oopBrowserDownload.js +3 -0
- playwright/driver/package/lib/package.js +50 -0
- playwright/driver/package/lib/server/chromium/appIcon.png +0 -0
- playwright/driver/package/lib/server/electron/loader.js +118 -0
- playwright/driver/package/lib/serverRegistry.js +7347 -0
- playwright/driver/package/lib/serverRegistry.js.LICENSE +354 -0
- playwright/driver/package/lib/tools/cli-client/channelSessions.js +141 -0
- playwright/driver/package/lib/tools/cli-client/cli.js +6 -0
- playwright/driver/package/lib/tools/cli-client/help.json +708 -0
- playwright/driver/package/lib/tools/cli-client/minimist.js +128 -0
- playwright/driver/package/lib/tools/cli-client/output.js +343 -0
- playwright/driver/package/lib/tools/cli-client/program.js +404 -0
- playwright/driver/package/lib/tools/cli-client/registry.js +176 -0
- playwright/driver/package/lib/tools/cli-client/session.js +258 -0
- playwright/driver/package/lib/tools/dashboard/appIcon.png +0 -0
- playwright/driver/package/lib/tools/skills/playwright-cli/SKILL.md +420 -0
- playwright/driver/package/lib/tools/skills/playwright-cli/references/element-attributes.md +23 -0
- playwright/driver/package/lib/tools/skills/playwright-cli/references/playwright-tests.md +39 -0
- playwright/driver/package/lib/tools/skills/playwright-cli/references/request-mocking.md +87 -0
- playwright/driver/package/lib/tools/skills/playwright-cli/references/running-code.md +241 -0
- playwright/driver/package/lib/tools/skills/playwright-cli/references/session-management.md +225 -0
- playwright/driver/package/lib/tools/skills/playwright-cli/references/storage-state.md +275 -0
- playwright/driver/package/lib/tools/skills/playwright-cli/references/test-generation.md +433 -0
- playwright/driver/package/lib/tools/skills/playwright-cli/references/tracing.md +139 -0
- playwright/driver/package/lib/tools/skills/playwright-cli/references/video-recording.md +143 -0
- playwright/driver/package/lib/tools/skills/playwright-component-testing/SKILL.md +143 -0
- playwright/driver/package/lib/tools/skills/playwright-component-testing/references/gallery-spec.md +144 -0
- playwright/driver/package/lib/tools/skills/playwright-component-testing/references/migration.md +85 -0
- playwright/driver/package/lib/tools/skills/playwright-component-testing/references/react.md +67 -0
- playwright/driver/package/lib/tools/skills/playwright-component-testing/references/vue.md +75 -0
- playwright/driver/package/lib/tools/skills/playwright-trace/SKILL.md +171 -0
- playwright/driver/package/lib/tools/utils/extension.js +101 -0
- playwright/driver/package/lib/tools/utils/socketConnection.js +108 -0
- playwright/driver/package/lib/utilsBundle.js +90764 -0
- playwright/driver/package/lib/utilsBundle.js.LICENSE +2179 -0
- playwright/driver/package/lib/vite/dashboard/assets/codicon-DCmgc-ay.ttf +0 -0
- playwright/driver/package/lib/vite/dashboard/assets/firefox-1bWoP6pv.svg +1 -0
- playwright/driver/package/lib/vite/dashboard/assets/firefox-beta-k3eOH_eK.svg +1 -0
- playwright/driver/package/lib/vite/dashboard/assets/firefox-nightly-Cp5nfeDT.svg +1 -0
- playwright/driver/package/lib/vite/dashboard/assets/index-CyWAfh-p.js +11 -0
- playwright/driver/package/lib/vite/dashboard/assets/index-DhC616m4.css +1 -0
- playwright/driver/package/lib/vite/dashboard/assets/safari-na3_-uQk.svg +1 -0
- playwright/driver/package/lib/vite/dashboard/index.html +29 -0
- playwright/driver/package/lib/vite/dashboard/playwright-logo.svg +24 -0
- playwright/driver/package/lib/vite/htmlReport/index.html +16 -0
- playwright/driver/package/lib/vite/htmlReport/report.css +2 -0
- playwright/driver/package/lib/vite/htmlReport/report.js +32 -0
- playwright/driver/package/lib/vite/recorder/assets/codeMirrorModule--QdMvsKi.css +1 -0
- playwright/driver/package/lib/vite/recorder/assets/codeMirrorModule-CwYYHbcZ.js +32 -0
- playwright/driver/package/lib/vite/recorder/assets/codicon-DCmgc-ay.ttf +0 -0
- playwright/driver/package/lib/vite/recorder/assets/index-DYjdXIbE.js +129 -0
- playwright/driver/package/lib/vite/recorder/assets/index-l_lX622x.css +1 -0
- playwright/driver/package/lib/vite/recorder/index.html +29 -0
- playwright/driver/package/lib/vite/recorder/playwright-logo.svg +9 -0
- playwright/driver/package/lib/vite/traceViewer/assets/codeMirrorModule-By56iMx7.js +32 -0
- playwright/driver/package/lib/vite/traceViewer/assets/defaultSettingsView-B34OrIms.js +181 -0
- playwright/driver/package/lib/vite/traceViewer/assets/urlMatch-L3liM589.js +1 -0
- playwright/driver/package/lib/vite/traceViewer/assets/xtermModule-COQkjINf.js +7 -0
- playwright/driver/package/lib/vite/traceViewer/codeMirrorModule.-QdMvsKi.css +1 -0
- playwright/driver/package/lib/vite/traceViewer/codicon.DCmgc-ay.ttf +0 -0
- playwright/driver/package/lib/vite/traceViewer/defaultSettingsView.BLFoOugd.css +1 -0
- playwright/driver/package/lib/vite/traceViewer/index.B_TqY17P.css +1 -0
- playwright/driver/package/lib/vite/traceViewer/index.Dl36UVQT.js +1 -0
- playwright/driver/package/lib/vite/traceViewer/index.html +44 -0
- playwright/driver/package/lib/vite/traceViewer/manifest.webmanifest +16 -0
- playwright/driver/package/lib/vite/traceViewer/playwright-logo.svg +9 -0
- playwright/driver/package/lib/vite/traceViewer/snapshot.B_Jk1wbt.js +1 -0
- playwright/driver/package/lib/vite/traceViewer/snapshot.html +10 -0
- playwright/driver/package/lib/vite/traceViewer/sw.bundle.js +4 -0
- playwright/driver/package/lib/vite/traceViewer/uiMode.C7UW1sC9.css +1 -0
- playwright/driver/package/lib/vite/traceViewer/uiMode.D962mr9b.js +5 -0
- playwright/driver/package/lib/vite/traceViewer/uiMode.html +18 -0
- playwright/driver/package/lib/vite/traceViewer/xtermModule.kHJ-D0s7.css +1 -0
- playwright/driver/package/lib/webp_codec.LICENSE +173 -0
- playwright/driver/package/lib/webp_codec.wasm +0 -0
- playwright/driver/package/lib/xdg-open +1267 -0
- playwright/driver/package/package.json +34 -0
- playwright/driver/package/types/protocol.d.ts +24842 -0
- playwright/driver/package/types/structs.d.ts +47 -0
- playwright/driver/package/types/types.d.ts +26188 -0
- playwright/py.typed +0 -0
- playwright/sync_api/__init__.py +275 -0
- playwright/sync_api/_android_generated.py +494 -0
- playwright/sync_api/_context_manager.py +98 -0
- playwright/sync_api/_generated.py +24045 -0
- playwright_browserstack-1.62.0.dist-info/METADATA +82 -0
- playwright_browserstack-1.62.0.dist-info/RECORD +192 -0
- playwright_browserstack-1.62.0.dist-info/WHEEL +5 -0
- playwright_browserstack-1.62.0.dist-info/entry_points.txt +5 -0
- playwright_browserstack-1.62.0.dist-info/licenses/LICENSE +202 -0
- playwright_browserstack-1.62.0.dist-info/licenses/LICENSE.txt +51 -0
- playwright_browserstack-1.62.0.dist-info/licenses/NOTICE +18 -0
- playwright_browserstack-1.62.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,197 @@
|
|
|
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 asyncio
|
|
16
|
+
import inspect
|
|
17
|
+
import math
|
|
18
|
+
import uuid
|
|
19
|
+
from asyncio.tasks import Task
|
|
20
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
|
21
|
+
|
|
22
|
+
from pyee import EventEmitter
|
|
23
|
+
|
|
24
|
+
from playwright._impl._connection import ChannelOwner
|
|
25
|
+
from playwright._impl._errors import Error, TimeoutError
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class Waiter:
|
|
29
|
+
def __init__(self, channel_owner: ChannelOwner, event: str) -> None:
|
|
30
|
+
self._result: asyncio.Future = asyncio.Future()
|
|
31
|
+
self._wait_id = uuid.uuid4().hex
|
|
32
|
+
self._loop = channel_owner._loop
|
|
33
|
+
self._pending_tasks: List[Task] = []
|
|
34
|
+
self._channel = channel_owner._channel
|
|
35
|
+
self._registered_listeners: List[Tuple[EventEmitter, str, Callable]] = []
|
|
36
|
+
self._logs: List[str] = []
|
|
37
|
+
self._wait_for_event_info_before(self._wait_id, event)
|
|
38
|
+
|
|
39
|
+
def _wait_for_event_info_before(self, wait_id: str, event: str) -> None:
|
|
40
|
+
self._send_wait_for_event_info(
|
|
41
|
+
{
|
|
42
|
+
"waitId": wait_id,
|
|
43
|
+
"phase": "before",
|
|
44
|
+
"event": event,
|
|
45
|
+
},
|
|
46
|
+
title=f'Wait for event "{event}"',
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
def _wait_for_event_info_after(self, wait_id: str, error: Exception = None) -> None:
|
|
50
|
+
self._send_wait_for_event_info(
|
|
51
|
+
{
|
|
52
|
+
"waitId": wait_id,
|
|
53
|
+
"phase": "after",
|
|
54
|
+
**({"error": str(error)} if error else {}),
|
|
55
|
+
},
|
|
56
|
+
is_internal=True,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def _send_wait_for_event_info(
|
|
60
|
+
self, params: Dict[str, Any], is_internal: bool = False, title: str = None
|
|
61
|
+
) -> None:
|
|
62
|
+
# Wait info is fire-and-forget telemetry and must not affect the waiter.
|
|
63
|
+
try:
|
|
64
|
+
self._channel.send_no_reply(
|
|
65
|
+
"__waitInfo__",
|
|
66
|
+
None,
|
|
67
|
+
params,
|
|
68
|
+
is_internal=is_internal,
|
|
69
|
+
title=title,
|
|
70
|
+
)
|
|
71
|
+
except Error:
|
|
72
|
+
pass
|
|
73
|
+
|
|
74
|
+
def reject_on_event(
|
|
75
|
+
self,
|
|
76
|
+
emitter: EventEmitter,
|
|
77
|
+
event: str,
|
|
78
|
+
error: Union[Error, Callable[..., Error]],
|
|
79
|
+
predicate: Callable = None,
|
|
80
|
+
) -> None:
|
|
81
|
+
def on_match() -> None:
|
|
82
|
+
self._reject(error() if callable(error) else error)
|
|
83
|
+
|
|
84
|
+
def listener(event_data: Any = None) -> None:
|
|
85
|
+
self._evaluate_predicate(predicate, event_data, on_match)
|
|
86
|
+
|
|
87
|
+
emitter.on(event, listener)
|
|
88
|
+
self._registered_listeners.append((emitter, event, listener))
|
|
89
|
+
|
|
90
|
+
def reject_on_timeout(self, timeout: float, message: str) -> None:
|
|
91
|
+
if timeout == 0:
|
|
92
|
+
return
|
|
93
|
+
|
|
94
|
+
async def reject() -> None:
|
|
95
|
+
await asyncio.sleep(timeout / 1000)
|
|
96
|
+
self._reject(TimeoutError(message))
|
|
97
|
+
|
|
98
|
+
self._pending_tasks.append(self._loop.create_task(reject()))
|
|
99
|
+
|
|
100
|
+
def _cleanup(self) -> None:
|
|
101
|
+
for task in self._pending_tasks:
|
|
102
|
+
if not task.done():
|
|
103
|
+
task.cancel()
|
|
104
|
+
for listener in self._registered_listeners:
|
|
105
|
+
listener[0].remove_listener(listener[1], listener[2])
|
|
106
|
+
|
|
107
|
+
def _fulfill(self, result: Any) -> None:
|
|
108
|
+
self._cleanup()
|
|
109
|
+
if not self._result.done():
|
|
110
|
+
self._result.set_result(result)
|
|
111
|
+
self._wait_for_event_info_after(self._wait_id)
|
|
112
|
+
|
|
113
|
+
def _reject(self, exception: Exception) -> None:
|
|
114
|
+
self._cleanup()
|
|
115
|
+
if exception:
|
|
116
|
+
base_class = TimeoutError if isinstance(exception, TimeoutError) else Error
|
|
117
|
+
exception = base_class(str(exception) + format_log_recording(self._logs))
|
|
118
|
+
if not self._result.done():
|
|
119
|
+
self._result.set_exception(exception)
|
|
120
|
+
self._wait_for_event_info_after(self._wait_id, exception)
|
|
121
|
+
|
|
122
|
+
def wait_for_event(
|
|
123
|
+
self,
|
|
124
|
+
emitter: EventEmitter,
|
|
125
|
+
event: str,
|
|
126
|
+
predicate: Callable = None,
|
|
127
|
+
) -> None:
|
|
128
|
+
def listener(event_data: Any = None) -> None:
|
|
129
|
+
self._evaluate_predicate(
|
|
130
|
+
predicate, event_data, lambda: self._fulfill(event_data)
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
emitter.on(event, listener)
|
|
134
|
+
self._registered_listeners.append((emitter, event, listener))
|
|
135
|
+
|
|
136
|
+
def _evaluate_predicate(
|
|
137
|
+
self,
|
|
138
|
+
predicate: Optional[Callable],
|
|
139
|
+
event_data: Any,
|
|
140
|
+
on_match: Callable[[], None],
|
|
141
|
+
) -> None:
|
|
142
|
+
if predicate is None:
|
|
143
|
+
on_match()
|
|
144
|
+
return
|
|
145
|
+
try:
|
|
146
|
+
result = predicate(event_data)
|
|
147
|
+
except Exception as e:
|
|
148
|
+
self._reject(e)
|
|
149
|
+
return
|
|
150
|
+
if inspect.iscoroutine(result):
|
|
151
|
+
|
|
152
|
+
async def _await_predicate(coro: Any) -> None:
|
|
153
|
+
try:
|
|
154
|
+
matched = await coro
|
|
155
|
+
except Exception as e:
|
|
156
|
+
self._reject(e)
|
|
157
|
+
return
|
|
158
|
+
if matched and not self._result.done():
|
|
159
|
+
on_match()
|
|
160
|
+
|
|
161
|
+
self._pending_tasks.append(self._loop.create_task(_await_predicate(result)))
|
|
162
|
+
return
|
|
163
|
+
if result:
|
|
164
|
+
on_match()
|
|
165
|
+
|
|
166
|
+
def result(self) -> asyncio.Future:
|
|
167
|
+
return self._result
|
|
168
|
+
|
|
169
|
+
def log(self, message: str) -> None:
|
|
170
|
+
self._logs.append(message)
|
|
171
|
+
self._send_wait_for_event_info(
|
|
172
|
+
{
|
|
173
|
+
"waitId": self._wait_id,
|
|
174
|
+
"phase": "log",
|
|
175
|
+
"message": message,
|
|
176
|
+
},
|
|
177
|
+
is_internal=True,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def throw_on_timeout(timeout: float, exception: Exception) -> asyncio.Task:
|
|
182
|
+
async def throw() -> None:
|
|
183
|
+
await asyncio.sleep(timeout / 1000)
|
|
184
|
+
raise exception
|
|
185
|
+
|
|
186
|
+
return asyncio.create_task(throw())
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def format_log_recording(log: List[str]) -> str:
|
|
190
|
+
if not log:
|
|
191
|
+
return ""
|
|
192
|
+
header = " logs "
|
|
193
|
+
header_length = 60
|
|
194
|
+
left_length = math.floor((header_length - len(header)) / 2)
|
|
195
|
+
right_length = header_length - len(header) - left_length
|
|
196
|
+
new_line = "\n"
|
|
197
|
+
return f"{new_line}{'=' * left_length}{header}{'=' * right_length}{new_line}{new_line.join(log)}{new_line}{'=' * header_length}"
|
|
@@ -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
|
+
from asyncio import AbstractEventLoop
|
|
16
|
+
from typing import Any, Optional
|
|
17
|
+
|
|
18
|
+
from playwright._impl._api_structures import WebErrorLocation
|
|
19
|
+
from playwright._impl._helper import Error
|
|
20
|
+
from playwright._impl._page import Page
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class WebError:
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
loop: AbstractEventLoop,
|
|
27
|
+
dispatcher_fiber: Any,
|
|
28
|
+
page: Optional[Page],
|
|
29
|
+
error: Error,
|
|
30
|
+
location: WebErrorLocation,
|
|
31
|
+
) -> None:
|
|
32
|
+
self._loop = loop
|
|
33
|
+
self._dispatcher_fiber = dispatcher_fiber
|
|
34
|
+
self._page = page
|
|
35
|
+
self._error = error
|
|
36
|
+
self._location = location
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def page(self) -> Optional[Page]:
|
|
40
|
+
return self._page
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def error(self) -> Error:
|
|
44
|
+
return self._error
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def location(self) -> WebErrorLocation:
|
|
48
|
+
return self._location
|
|
@@ -0,0 +1,58 @@
|
|
|
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
|
+
from typing import TYPE_CHECKING, List, Literal, Optional
|
|
16
|
+
|
|
17
|
+
from playwright._impl._api_structures import NameValue
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from playwright._impl._page import Page
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
WebStorageKind = Literal["local", "session"]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class WebStorage:
|
|
27
|
+
def __init__(self, page: "Page", kind: WebStorageKind) -> None:
|
|
28
|
+
self._page = page
|
|
29
|
+
self._kind = kind
|
|
30
|
+
self._loop = page._loop
|
|
31
|
+
self._dispatcher_fiber = page._dispatcher_fiber
|
|
32
|
+
|
|
33
|
+
async def items(self) -> List[NameValue]:
|
|
34
|
+
result = await self._page._channel.send_return_as_dict(
|
|
35
|
+
"webStorageItems", None, {"kind": self._kind}
|
|
36
|
+
)
|
|
37
|
+
return (result or {}).get("items", [])
|
|
38
|
+
|
|
39
|
+
async def get_item(self, name: str) -> Optional[str]:
|
|
40
|
+
result = await self._page._channel.send_return_as_dict(
|
|
41
|
+
"webStorageGetItem", None, {"kind": self._kind, "name": name}
|
|
42
|
+
)
|
|
43
|
+
return (result or {}).get("value")
|
|
44
|
+
|
|
45
|
+
async def set_item(self, name: str, value: str) -> None:
|
|
46
|
+
await self._page._channel.send(
|
|
47
|
+
"webStorageSetItem",
|
|
48
|
+
None,
|
|
49
|
+
{"kind": self._kind, "name": name, "value": value},
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
async def remove_item(self, name: str) -> None:
|
|
53
|
+
await self._page._channel.send(
|
|
54
|
+
"webStorageRemoveItem", None, {"kind": self._kind, "name": name}
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
async def clear(self) -> None:
|
|
58
|
+
await self._page._channel.send("webStorageClear", None, {"kind": self._kind})
|
|
@@ -0,0 +1,42 @@
|
|
|
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 base64
|
|
16
|
+
import os
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import Dict, Union
|
|
19
|
+
|
|
20
|
+
from playwright._impl._connection import ChannelOwner
|
|
21
|
+
|
|
22
|
+
# COPY_BUFSIZE is taken from shutil.py in the standard library
|
|
23
|
+
_WINDOWS = os.name == "nt"
|
|
24
|
+
COPY_BUFSIZE = 1024 * 1024 if _WINDOWS else 64 * 1024
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class WritableStream(ChannelOwner):
|
|
28
|
+
def __init__(
|
|
29
|
+
self, parent: ChannelOwner, type: str, guid: str, initializer: Dict
|
|
30
|
+
) -> None:
|
|
31
|
+
super().__init__(parent, type, guid, initializer)
|
|
32
|
+
|
|
33
|
+
async def copy(self, path: Union[str, Path]) -> None:
|
|
34
|
+
with open(path, "rb") as f:
|
|
35
|
+
while True:
|
|
36
|
+
data = f.read(COPY_BUFSIZE)
|
|
37
|
+
if not data:
|
|
38
|
+
break
|
|
39
|
+
await self._channel.send(
|
|
40
|
+
"write", None, {"binary": base64.b64encode(data).decode()}
|
|
41
|
+
)
|
|
42
|
+
await self._channel.send("close", None)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# file generated by vcs-versioning
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"__version__",
|
|
7
|
+
"__version_tuple__",
|
|
8
|
+
"version",
|
|
9
|
+
"version_tuple",
|
|
10
|
+
"__commit_id__",
|
|
11
|
+
"commit_id",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
version: str
|
|
15
|
+
__version__: str
|
|
16
|
+
__version_tuple__: tuple[int | str, ...]
|
|
17
|
+
version_tuple: tuple[int | str, ...]
|
|
18
|
+
commit_id: str | None
|
|
19
|
+
__commit_id__: str | None
|
|
20
|
+
|
|
21
|
+
__version__ = version = '1.62.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 62, 0)
|
|
23
|
+
|
|
24
|
+
__commit_id__ = commit_id = 'gd1456f41f'
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Modifications Copyright 2025 BrowserStack
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
Python package `playwright` is a Python library to automate Chromium,
|
|
18
|
+
Firefox and WebKit with a single API. Playwright is built to enable cross-browser
|
|
19
|
+
web automation that is ever-green, capable, reliable and fast.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from typing import Any, Optional, Union, overload
|
|
23
|
+
|
|
24
|
+
import playwright._impl._api_structures
|
|
25
|
+
import playwright._impl._errors
|
|
26
|
+
import playwright._impl._form_data
|
|
27
|
+
import playwright.async_api._generated
|
|
28
|
+
from playwright._impl._assertions import (
|
|
29
|
+
APIResponseAssertions as APIResponseAssertionsImpl,
|
|
30
|
+
)
|
|
31
|
+
from playwright._impl._assertions import LocatorAssertions as LocatorAssertionsImpl
|
|
32
|
+
from playwright._impl._assertions import PageAssertions as PageAssertionsImpl
|
|
33
|
+
from playwright.async_api._android_generated import (
|
|
34
|
+
Android,
|
|
35
|
+
AndroidDevice,
|
|
36
|
+
AndroidInput,
|
|
37
|
+
AndroidSocket,
|
|
38
|
+
AndroidWebView,
|
|
39
|
+
)
|
|
40
|
+
from playwright.async_api._context_manager import PlaywrightContextManager
|
|
41
|
+
from playwright.async_api._generated import (
|
|
42
|
+
APIRequest,
|
|
43
|
+
APIRequestContext,
|
|
44
|
+
APIResponse,
|
|
45
|
+
APIResponseAssertions,
|
|
46
|
+
Browser,
|
|
47
|
+
BrowserContext,
|
|
48
|
+
BrowserType,
|
|
49
|
+
CDPSession,
|
|
50
|
+
ConsoleMessage,
|
|
51
|
+
Dialog,
|
|
52
|
+
Download,
|
|
53
|
+
ElementHandle,
|
|
54
|
+
FileChooser,
|
|
55
|
+
Frame,
|
|
56
|
+
FrameLocator,
|
|
57
|
+
JSHandle,
|
|
58
|
+
Keyboard,
|
|
59
|
+
Locator,
|
|
60
|
+
LocatorAssertions,
|
|
61
|
+
Mouse,
|
|
62
|
+
Page,
|
|
63
|
+
PageAssertions,
|
|
64
|
+
Playwright,
|
|
65
|
+
Request,
|
|
66
|
+
Response,
|
|
67
|
+
Route,
|
|
68
|
+
Selectors,
|
|
69
|
+
Touchscreen,
|
|
70
|
+
Video,
|
|
71
|
+
WebError,
|
|
72
|
+
WebSocket,
|
|
73
|
+
WebSocketRoute,
|
|
74
|
+
Worker,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
ChromiumBrowserContext = BrowserContext
|
|
78
|
+
|
|
79
|
+
Cookie = playwright._impl._api_structures.Cookie
|
|
80
|
+
FilePayload = playwright._impl._api_structures.FilePayload
|
|
81
|
+
FormData = playwright._impl._form_data.FormData
|
|
82
|
+
FloatRect = playwright._impl._api_structures.FloatRect
|
|
83
|
+
Geolocation = playwright._impl._api_structures.Geolocation
|
|
84
|
+
HttpCredentials = playwright._impl._api_structures.HttpCredentials
|
|
85
|
+
BrowserBindResult = playwright._impl._api_structures.BrowserBindResult
|
|
86
|
+
DebuggerLocation = playwright._impl._api_structures.DebuggerLocation
|
|
87
|
+
DebuggerPausedDetails = playwright._impl._api_structures.DebuggerPausedDetails
|
|
88
|
+
PdfMargins = playwright._impl._api_structures.PdfMargins
|
|
89
|
+
Position = playwright._impl._api_structures.Position
|
|
90
|
+
ProxySettings = playwright._impl._api_structures.ProxySettings
|
|
91
|
+
ResourceTiming = playwright._impl._api_structures.ResourceTiming
|
|
92
|
+
ScreencastFrame = playwright._impl._api_structures.ScreencastFrame
|
|
93
|
+
ScreencastSize = playwright._impl._api_structures.ScreencastSize
|
|
94
|
+
SourceLocation = playwright._impl._api_structures.SourceLocation
|
|
95
|
+
StorageState = playwright._impl._api_structures.StorageState
|
|
96
|
+
StorageStateCookie = playwright._impl._api_structures.StorageStateCookie
|
|
97
|
+
ViewportSize = playwright._impl._api_structures.ViewportSize
|
|
98
|
+
VirtualCredential = playwright._impl._api_structures.VirtualCredential
|
|
99
|
+
|
|
100
|
+
Error = playwright._impl._errors.Error
|
|
101
|
+
TimeoutError = playwright._impl._errors.TimeoutError
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def async_playwright() -> PlaywrightContextManager:
|
|
105
|
+
return PlaywrightContextManager()
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class Expect:
|
|
109
|
+
_unset: Any = object()
|
|
110
|
+
|
|
111
|
+
def __init__(self) -> None:
|
|
112
|
+
self._timeout: Optional[float] = None
|
|
113
|
+
|
|
114
|
+
def set_options(self, timeout: Optional[float] = _unset) -> None:
|
|
115
|
+
"""
|
|
116
|
+
This method sets global `expect()` options.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
timeout (float): Timeout value in milliseconds. Default to 5000 milliseconds.
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
None
|
|
123
|
+
"""
|
|
124
|
+
if timeout is not self._unset:
|
|
125
|
+
self._timeout = timeout
|
|
126
|
+
|
|
127
|
+
@overload
|
|
128
|
+
def __call__(
|
|
129
|
+
self, actual: Page, message: Optional[str] = None
|
|
130
|
+
) -> PageAssertions: ...
|
|
131
|
+
|
|
132
|
+
@overload
|
|
133
|
+
def __call__(
|
|
134
|
+
self, actual: Locator, message: Optional[str] = None
|
|
135
|
+
) -> LocatorAssertions: ...
|
|
136
|
+
|
|
137
|
+
@overload
|
|
138
|
+
def __call__(
|
|
139
|
+
self, actual: APIResponse, message: Optional[str] = None
|
|
140
|
+
) -> APIResponseAssertions: ...
|
|
141
|
+
|
|
142
|
+
def __call__(
|
|
143
|
+
self, actual: Union[Page, Locator, APIResponse], message: Optional[str] = None
|
|
144
|
+
) -> Union[PageAssertions, LocatorAssertions, APIResponseAssertions]:
|
|
145
|
+
return self._dispatch(actual, message, is_soft=False)
|
|
146
|
+
|
|
147
|
+
@overload
|
|
148
|
+
def soft(self, actual: Page, message: Optional[str] = None) -> PageAssertions: ...
|
|
149
|
+
|
|
150
|
+
@overload
|
|
151
|
+
def soft(
|
|
152
|
+
self, actual: Locator, message: Optional[str] = None
|
|
153
|
+
) -> LocatorAssertions: ...
|
|
154
|
+
|
|
155
|
+
@overload
|
|
156
|
+
def soft(
|
|
157
|
+
self, actual: APIResponse, message: Optional[str] = None
|
|
158
|
+
) -> APIResponseAssertions: ...
|
|
159
|
+
|
|
160
|
+
def soft(
|
|
161
|
+
self, actual: Union[Page, Locator, APIResponse], message: Optional[str] = None
|
|
162
|
+
) -> Union[PageAssertions, LocatorAssertions, APIResponseAssertions]:
|
|
163
|
+
"""
|
|
164
|
+
Creates a [soft assertion](https://playwright.dev/python/docs/test-assertions#soft-assertions).
|
|
165
|
+
Failing soft assertions do not abort test execution, but mark the test
|
|
166
|
+
as failed. Multiple failures from the same test are surfaced together
|
|
167
|
+
at the end of the test.
|
|
168
|
+
|
|
169
|
+
Requires the [pytest-playwright](https://pypi.org/project/pytest-playwright/)
|
|
170
|
+
plugin to establish the per-test scope that collects soft assertion
|
|
171
|
+
failures.
|
|
172
|
+
"""
|
|
173
|
+
return self._dispatch(actual, message, is_soft=True)
|
|
174
|
+
|
|
175
|
+
def _dispatch(
|
|
176
|
+
self,
|
|
177
|
+
actual: Union[Page, Locator, APIResponse],
|
|
178
|
+
message: Optional[str],
|
|
179
|
+
is_soft: bool,
|
|
180
|
+
) -> Union[PageAssertions, LocatorAssertions, APIResponseAssertions]:
|
|
181
|
+
if isinstance(actual, Page):
|
|
182
|
+
return PageAssertions(
|
|
183
|
+
PageAssertionsImpl(
|
|
184
|
+
actual._impl_obj,
|
|
185
|
+
self._timeout,
|
|
186
|
+
message=message,
|
|
187
|
+
is_soft=is_soft,
|
|
188
|
+
)
|
|
189
|
+
)
|
|
190
|
+
elif isinstance(actual, Locator):
|
|
191
|
+
return LocatorAssertions(
|
|
192
|
+
LocatorAssertionsImpl(
|
|
193
|
+
actual._impl_obj,
|
|
194
|
+
self._timeout,
|
|
195
|
+
message=message,
|
|
196
|
+
is_soft=is_soft,
|
|
197
|
+
)
|
|
198
|
+
)
|
|
199
|
+
elif isinstance(actual, APIResponse):
|
|
200
|
+
return APIResponseAssertions(
|
|
201
|
+
APIResponseAssertionsImpl(
|
|
202
|
+
actual._impl_obj,
|
|
203
|
+
self._timeout,
|
|
204
|
+
message=message,
|
|
205
|
+
is_soft=is_soft,
|
|
206
|
+
)
|
|
207
|
+
)
|
|
208
|
+
raise ValueError(f"Unsupported type: {type(actual)}")
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
expect = Expect()
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
__all__ = [
|
|
215
|
+
"expect",
|
|
216
|
+
"async_playwright",
|
|
217
|
+
"Android",
|
|
218
|
+
"AndroidDevice",
|
|
219
|
+
"AndroidInput",
|
|
220
|
+
"AndroidSocket",
|
|
221
|
+
"AndroidWebView",
|
|
222
|
+
"APIRequest",
|
|
223
|
+
"APIRequestContext",
|
|
224
|
+
"APIResponse",
|
|
225
|
+
"Browser",
|
|
226
|
+
"BrowserBindResult",
|
|
227
|
+
"BrowserContext",
|
|
228
|
+
"BrowserType",
|
|
229
|
+
"CDPSession",
|
|
230
|
+
"ChromiumBrowserContext",
|
|
231
|
+
"ConsoleMessage",
|
|
232
|
+
"Cookie",
|
|
233
|
+
"Dialog",
|
|
234
|
+
"Download",
|
|
235
|
+
"ElementHandle",
|
|
236
|
+
"Error",
|
|
237
|
+
"FileChooser",
|
|
238
|
+
"FilePayload",
|
|
239
|
+
"FloatRect",
|
|
240
|
+
"FormData",
|
|
241
|
+
"Frame",
|
|
242
|
+
"FrameLocator",
|
|
243
|
+
"Geolocation",
|
|
244
|
+
"HttpCredentials",
|
|
245
|
+
"JSHandle",
|
|
246
|
+
"Keyboard",
|
|
247
|
+
"Locator",
|
|
248
|
+
"Mouse",
|
|
249
|
+
"DebuggerLocation",
|
|
250
|
+
"DebuggerPausedDetails",
|
|
251
|
+
"Page",
|
|
252
|
+
"PdfMargins",
|
|
253
|
+
"Position",
|
|
254
|
+
"Playwright",
|
|
255
|
+
"ProxySettings",
|
|
256
|
+
"Request",
|
|
257
|
+
"ResourceTiming",
|
|
258
|
+
"Response",
|
|
259
|
+
"Route",
|
|
260
|
+
"ScreencastFrame",
|
|
261
|
+
"ScreencastSize",
|
|
262
|
+
"Selectors",
|
|
263
|
+
"SourceLocation",
|
|
264
|
+
"StorageState",
|
|
265
|
+
"StorageStateCookie",
|
|
266
|
+
"TimeoutError",
|
|
267
|
+
"Touchscreen",
|
|
268
|
+
"Video",
|
|
269
|
+
"ViewportSize",
|
|
270
|
+
"VirtualCredential",
|
|
271
|
+
"WebError",
|
|
272
|
+
"WebSocket",
|
|
273
|
+
"WebSocketRoute",
|
|
274
|
+
"Worker",
|
|
275
|
+
]
|