playwright-browserstack 1.62.0__py3-none-win_amd64.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,494 @@
|
|
|
1
|
+
# Copyright (c) 2025 BrowserStack. All rights reserved.
|
|
2
|
+
#
|
|
3
|
+
# This software is the confidential and proprietary information of BrowserStack.
|
|
4
|
+
# You shall not disclose such Confidential Information and shall use it only in
|
|
5
|
+
# accordance with the terms of the license agreement you entered into with BrowserStack.
|
|
6
|
+
|
|
7
|
+
"""BrowserStack Android API wrappers for the sync API.
|
|
8
|
+
|
|
9
|
+
These wrappers are hand-maintained on purpose. Upstream marks the Android API
|
|
10
|
+
as JS-only (``langs.only``), so ``scripts/generate_sync_api.py`` cannot emit
|
|
11
|
+
them: ``documentation_provider.py`` filters the classes out of ``api.json`` and
|
|
12
|
+
then raises ``Invalid class Android``.
|
|
13
|
+
|
|
14
|
+
They deliberately live outside ``_generated.py`` because
|
|
15
|
+
``scripts/update_api.sh`` runs
|
|
16
|
+
``git checkout HEAD -- playwright/sync_api/_generated.py`` before
|
|
17
|
+
regenerating it, so anything added there is silently dropped on the next
|
|
18
|
+
upstream version bump. Anything here survives untouched.
|
|
19
|
+
|
|
20
|
+
Importing this module registers the Android impl->API mapping and attaches the
|
|
21
|
+
``Playwright.android`` property, so ``playwright/sync_api/__init__.py`` must
|
|
22
|
+
import it.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
import pathlib
|
|
26
|
+
import typing
|
|
27
|
+
from typing import Literal
|
|
28
|
+
|
|
29
|
+
from playwright._impl._android import Android as AndroidImpl
|
|
30
|
+
from playwright._impl._android import AndroidDevice as AndroidDeviceImpl
|
|
31
|
+
from playwright._impl._android import AndroidInput as AndroidInputImpl
|
|
32
|
+
from playwright._impl._android import AndroidSocket as AndroidSocketImpl
|
|
33
|
+
from playwright._impl._android import AndroidWebView as AndroidWebViewImpl
|
|
34
|
+
from playwright._impl._sync_base import SyncBase, mapping
|
|
35
|
+
from playwright.sync_api._generated import BrowserContext, Page, Playwright
|
|
36
|
+
|
|
37
|
+
__all__ = [
|
|
38
|
+
"Android",
|
|
39
|
+
"AndroidDevice",
|
|
40
|
+
"AndroidInput",
|
|
41
|
+
"AndroidSocket",
|
|
42
|
+
"AndroidWebView",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
# Referenced by the string annotations in the wrappers below; imported for
|
|
46
|
+
# runtime type resolution, not used directly here.
|
|
47
|
+
_ = (BrowserContext, Page)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class AndroidSocket(SyncBase):
|
|
51
|
+
|
|
52
|
+
def write(self, data: bytes) -> None:
|
|
53
|
+
return mapping.from_maybe_impl(self._sync(self._impl_obj.write(data=data)))
|
|
54
|
+
|
|
55
|
+
def close(self) -> None:
|
|
56
|
+
return mapping.from_maybe_impl(self._sync(self._impl_obj.close()))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
mapping.register(AndroidSocketImpl, AndroidSocket)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class AndroidWebView(SyncBase):
|
|
63
|
+
|
|
64
|
+
def __init__(self, impl_obj: AndroidWebViewImpl) -> None:
|
|
65
|
+
self._impl_obj = impl_obj
|
|
66
|
+
self._loop = impl_obj._device._loop
|
|
67
|
+
self._dispatcher_fiber = impl_obj._device._dispatcher_fiber
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def pid(self) -> int:
|
|
71
|
+
return self._impl_obj.pid
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def pkg(self) -> str:
|
|
75
|
+
return self._impl_obj.pkg
|
|
76
|
+
|
|
77
|
+
def page(self) -> "Page":
|
|
78
|
+
return mapping.from_impl(self._sync(self._impl_obj.page()))
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
mapping.register(AndroidWebViewImpl, AndroidWebView)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class AndroidInput(SyncBase):
|
|
85
|
+
|
|
86
|
+
def __init__(self, impl_obj: AndroidInputImpl) -> None:
|
|
87
|
+
self._impl_obj = impl_obj
|
|
88
|
+
self._loop = impl_obj._device._loop
|
|
89
|
+
self._dispatcher_fiber = impl_obj._device._dispatcher_fiber
|
|
90
|
+
|
|
91
|
+
def type(self, text: str) -> None:
|
|
92
|
+
return mapping.from_maybe_impl(self._sync(self._impl_obj.type(text=text)))
|
|
93
|
+
|
|
94
|
+
def press(self, key: str) -> None:
|
|
95
|
+
return mapping.from_maybe_impl(self._sync(self._impl_obj.press(key=key)))
|
|
96
|
+
|
|
97
|
+
def tap(self, point: typing.Dict) -> None:
|
|
98
|
+
return mapping.from_maybe_impl(self._sync(self._impl_obj.tap(point=point)))
|
|
99
|
+
|
|
100
|
+
def swipe(
|
|
101
|
+
self,
|
|
102
|
+
start: typing.Dict,
|
|
103
|
+
segments: typing.List[typing.Dict],
|
|
104
|
+
steps: int,
|
|
105
|
+
) -> None:
|
|
106
|
+
return mapping.from_maybe_impl(
|
|
107
|
+
self._sync(
|
|
108
|
+
self._impl_obj.swipe(start=start, segments=segments, steps=steps)
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
def drag(self, start: typing.Dict, end: typing.Dict, steps: int) -> None:
|
|
113
|
+
return mapping.from_maybe_impl(
|
|
114
|
+
self._sync(self._impl_obj.drag(start=start, end=end, steps=steps))
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
mapping.register(AndroidInputImpl, AndroidInput)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class AndroidDevice(SyncBase):
|
|
122
|
+
|
|
123
|
+
@property
|
|
124
|
+
def input(self) -> "AndroidInput":
|
|
125
|
+
return mapping.from_impl(self._impl_obj.input)
|
|
126
|
+
|
|
127
|
+
@property
|
|
128
|
+
def serial(self) -> str:
|
|
129
|
+
return self._impl_obj.serial
|
|
130
|
+
|
|
131
|
+
@property
|
|
132
|
+
def model(self) -> str:
|
|
133
|
+
return self._impl_obj.model
|
|
134
|
+
|
|
135
|
+
def screenshot(
|
|
136
|
+
self, *, path: typing.Optional[typing.Union[str, pathlib.Path]] = None
|
|
137
|
+
) -> bytes:
|
|
138
|
+
return mapping.from_maybe_impl(self._sync(self._impl_obj.screenshot(path=path)))
|
|
139
|
+
|
|
140
|
+
def shell(self, command: str) -> bytes:
|
|
141
|
+
return mapping.from_maybe_impl(
|
|
142
|
+
self._sync(self._impl_obj.shell(command=command))
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
def open(self, command: str) -> "AndroidSocket":
|
|
146
|
+
return mapping.from_impl(self._sync(self._impl_obj.open(command=command)))
|
|
147
|
+
|
|
148
|
+
def install_apk(
|
|
149
|
+
self,
|
|
150
|
+
file: typing.Union[str, pathlib.Path, bytes],
|
|
151
|
+
*,
|
|
152
|
+
args: typing.Optional[typing.List[str]] = None,
|
|
153
|
+
) -> None:
|
|
154
|
+
return mapping.from_maybe_impl(
|
|
155
|
+
self._sync(self._impl_obj.install_apk(file=file, args=args))
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
def push(
|
|
159
|
+
self,
|
|
160
|
+
file: typing.Union[str, pathlib.Path, bytes],
|
|
161
|
+
path: str,
|
|
162
|
+
*,
|
|
163
|
+
mode: typing.Optional[int] = None,
|
|
164
|
+
) -> None:
|
|
165
|
+
return mapping.from_maybe_impl(
|
|
166
|
+
self._sync(self._impl_obj.push(file=file, path=path, mode=mode))
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
def launch_browser(
|
|
170
|
+
self,
|
|
171
|
+
*,
|
|
172
|
+
pkg: typing.Optional[str] = None,
|
|
173
|
+
args: typing.Optional[typing.List[str]] = None,
|
|
174
|
+
proxy: typing.Optional[typing.Dict] = None,
|
|
175
|
+
permissions: typing.Optional[typing.List[str]] = None,
|
|
176
|
+
extra_http_headers: typing.Optional[typing.Dict[str, str]] = None,
|
|
177
|
+
offline: typing.Optional[bool] = None,
|
|
178
|
+
http_credentials: typing.Optional[typing.Dict] = None,
|
|
179
|
+
device_scale_factor: typing.Optional[float] = None,
|
|
180
|
+
is_mobile: typing.Optional[bool] = None,
|
|
181
|
+
has_touch: typing.Optional[bool] = None,
|
|
182
|
+
color_scheme: typing.Optional[
|
|
183
|
+
Literal["dark", "light", "no-preference", "null"]
|
|
184
|
+
] = None,
|
|
185
|
+
locale: typing.Optional[str] = None,
|
|
186
|
+
timezone_id: typing.Optional[str] = None,
|
|
187
|
+
geolocation: typing.Optional[typing.Dict] = None,
|
|
188
|
+
user_agent: typing.Optional[str] = None,
|
|
189
|
+
accept_downloads: typing.Optional[bool] = None,
|
|
190
|
+
ignore_https_errors: typing.Optional[bool] = None,
|
|
191
|
+
java_script_enabled: typing.Optional[bool] = None,
|
|
192
|
+
bypass_csp: typing.Optional[bool] = None,
|
|
193
|
+
viewport: typing.Optional[typing.Dict] = None,
|
|
194
|
+
screen: typing.Optional[typing.Dict] = None,
|
|
195
|
+
no_viewport: typing.Optional[bool] = None,
|
|
196
|
+
record_video: typing.Optional[typing.Dict] = None,
|
|
197
|
+
record_har: typing.Optional[typing.Dict] = None,
|
|
198
|
+
base_url: typing.Optional[str] = None,
|
|
199
|
+
strict_selectors: typing.Optional[bool] = None,
|
|
200
|
+
service_workers: typing.Optional[Literal["allow", "block"]] = None,
|
|
201
|
+
) -> "BrowserContext":
|
|
202
|
+
return mapping.from_impl(
|
|
203
|
+
self._sync(
|
|
204
|
+
self._impl_obj.launch_browser(
|
|
205
|
+
pkg=pkg,
|
|
206
|
+
args=args,
|
|
207
|
+
proxy=proxy,
|
|
208
|
+
permissions=permissions,
|
|
209
|
+
extraHTTPHeaders=extra_http_headers,
|
|
210
|
+
offline=offline,
|
|
211
|
+
httpCredentials=http_credentials,
|
|
212
|
+
deviceScaleFactor=device_scale_factor,
|
|
213
|
+
isMobile=is_mobile,
|
|
214
|
+
hasTouch=has_touch,
|
|
215
|
+
colorScheme=color_scheme,
|
|
216
|
+
locale=locale,
|
|
217
|
+
timezoneId=timezone_id,
|
|
218
|
+
geolocation=geolocation,
|
|
219
|
+
userAgent=user_agent,
|
|
220
|
+
acceptDownloads=accept_downloads,
|
|
221
|
+
ignoreHTTPSErrors=ignore_https_errors,
|
|
222
|
+
javaScriptEnabled=java_script_enabled,
|
|
223
|
+
bypassCSP=bypass_csp,
|
|
224
|
+
viewport=viewport,
|
|
225
|
+
screen=screen,
|
|
226
|
+
noViewport=no_viewport,
|
|
227
|
+
recordVideo=record_video,
|
|
228
|
+
recordHar=record_har,
|
|
229
|
+
baseURL=base_url,
|
|
230
|
+
strictSelectors=strict_selectors,
|
|
231
|
+
serviceWorkers=service_workers,
|
|
232
|
+
)
|
|
233
|
+
)
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
def web_views(self) -> typing.List["AndroidWebView"]:
|
|
237
|
+
return mapping.from_impl_list(self._impl_obj.web_views())
|
|
238
|
+
|
|
239
|
+
def web_view(
|
|
240
|
+
self, selector: typing.Dict, *, timeout: typing.Optional[float] = None
|
|
241
|
+
) -> "AndroidWebView":
|
|
242
|
+
return mapping.from_impl(
|
|
243
|
+
self._sync(self._impl_obj.web_view(selector=selector, timeout=timeout))
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
def wait(
|
|
247
|
+
self,
|
|
248
|
+
selector: typing.Dict,
|
|
249
|
+
*,
|
|
250
|
+
state: typing.Optional[Literal["gone"]] = None,
|
|
251
|
+
timeout: typing.Optional[float] = None,
|
|
252
|
+
) -> None:
|
|
253
|
+
return mapping.from_maybe_impl(
|
|
254
|
+
self._sync(
|
|
255
|
+
self._impl_obj.wait(selector=selector, state=state, timeout=timeout)
|
|
256
|
+
)
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
def fill(
|
|
260
|
+
self,
|
|
261
|
+
selector: typing.Dict,
|
|
262
|
+
text: str,
|
|
263
|
+
*,
|
|
264
|
+
timeout: typing.Optional[float] = None,
|
|
265
|
+
) -> None:
|
|
266
|
+
return mapping.from_maybe_impl(
|
|
267
|
+
self._sync(
|
|
268
|
+
self._impl_obj.fill(selector=selector, text=text, timeout=timeout)
|
|
269
|
+
)
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
def tap(
|
|
273
|
+
self,
|
|
274
|
+
selector: typing.Dict,
|
|
275
|
+
*,
|
|
276
|
+
duration: typing.Optional[float] = None,
|
|
277
|
+
timeout: typing.Optional[float] = None,
|
|
278
|
+
) -> None:
|
|
279
|
+
return mapping.from_maybe_impl(
|
|
280
|
+
self._sync(
|
|
281
|
+
self._impl_obj.tap(
|
|
282
|
+
selector=selector, duration=duration, timeout=timeout
|
|
283
|
+
)
|
|
284
|
+
)
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
def long_tap(
|
|
288
|
+
self, selector: typing.Dict, *, timeout: typing.Optional[float] = None
|
|
289
|
+
) -> None:
|
|
290
|
+
return mapping.from_maybe_impl(
|
|
291
|
+
self._sync(self._impl_obj.long_tap(selector=selector, timeout=timeout))
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
def drag(
|
|
295
|
+
self,
|
|
296
|
+
selector: typing.Dict,
|
|
297
|
+
dest: typing.Dict,
|
|
298
|
+
*,
|
|
299
|
+
speed: typing.Optional[int] = None,
|
|
300
|
+
timeout: typing.Optional[float] = None,
|
|
301
|
+
) -> None:
|
|
302
|
+
return mapping.from_maybe_impl(
|
|
303
|
+
self._sync(
|
|
304
|
+
self._impl_obj.drag(
|
|
305
|
+
selector=selector, dest=dest, speed=speed, timeout=timeout
|
|
306
|
+
)
|
|
307
|
+
)
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
def fling(
|
|
311
|
+
self,
|
|
312
|
+
selector: typing.Dict,
|
|
313
|
+
direction: Literal["down", "left", "right", "up"],
|
|
314
|
+
*,
|
|
315
|
+
speed: typing.Optional[int] = None,
|
|
316
|
+
timeout: typing.Optional[float] = None,
|
|
317
|
+
) -> None:
|
|
318
|
+
return mapping.from_maybe_impl(
|
|
319
|
+
self._sync(
|
|
320
|
+
self._impl_obj.fling(
|
|
321
|
+
selector=selector, direction=direction, speed=speed, timeout=timeout
|
|
322
|
+
)
|
|
323
|
+
)
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
def pinch_close(
|
|
327
|
+
self,
|
|
328
|
+
selector: typing.Dict,
|
|
329
|
+
percent: float,
|
|
330
|
+
*,
|
|
331
|
+
speed: typing.Optional[int] = None,
|
|
332
|
+
timeout: typing.Optional[float] = None,
|
|
333
|
+
) -> None:
|
|
334
|
+
return mapping.from_maybe_impl(
|
|
335
|
+
self._sync(
|
|
336
|
+
self._impl_obj.pinch_close(
|
|
337
|
+
selector=selector, percent=percent, speed=speed, timeout=timeout
|
|
338
|
+
)
|
|
339
|
+
)
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
def pinch_open(
|
|
343
|
+
self,
|
|
344
|
+
selector: typing.Dict,
|
|
345
|
+
percent: float,
|
|
346
|
+
*,
|
|
347
|
+
speed: typing.Optional[int] = None,
|
|
348
|
+
timeout: typing.Optional[float] = None,
|
|
349
|
+
) -> None:
|
|
350
|
+
return mapping.from_maybe_impl(
|
|
351
|
+
self._sync(
|
|
352
|
+
self._impl_obj.pinch_open(
|
|
353
|
+
selector=selector, percent=percent, speed=speed, timeout=timeout
|
|
354
|
+
)
|
|
355
|
+
)
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
def scroll(
|
|
359
|
+
self,
|
|
360
|
+
selector: typing.Dict,
|
|
361
|
+
direction: Literal["down", "left", "right", "up"],
|
|
362
|
+
percent: float,
|
|
363
|
+
*,
|
|
364
|
+
speed: typing.Optional[int] = None,
|
|
365
|
+
timeout: typing.Optional[float] = None,
|
|
366
|
+
) -> None:
|
|
367
|
+
return mapping.from_maybe_impl(
|
|
368
|
+
self._sync(
|
|
369
|
+
self._impl_obj.scroll(
|
|
370
|
+
selector=selector,
|
|
371
|
+
direction=direction,
|
|
372
|
+
percent=percent,
|
|
373
|
+
speed=speed,
|
|
374
|
+
timeout=timeout,
|
|
375
|
+
)
|
|
376
|
+
)
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
def swipe(
|
|
380
|
+
self,
|
|
381
|
+
selector: typing.Dict,
|
|
382
|
+
direction: Literal["down", "left", "right", "up"],
|
|
383
|
+
percent: float,
|
|
384
|
+
*,
|
|
385
|
+
speed: typing.Optional[int] = None,
|
|
386
|
+
timeout: typing.Optional[float] = None,
|
|
387
|
+
) -> None:
|
|
388
|
+
return mapping.from_maybe_impl(
|
|
389
|
+
self._sync(
|
|
390
|
+
self._impl_obj.swipe(
|
|
391
|
+
selector=selector,
|
|
392
|
+
direction=direction,
|
|
393
|
+
percent=percent,
|
|
394
|
+
speed=speed,
|
|
395
|
+
timeout=timeout,
|
|
396
|
+
)
|
|
397
|
+
)
|
|
398
|
+
)
|
|
399
|
+
|
|
400
|
+
def press(
|
|
401
|
+
self,
|
|
402
|
+
selector: typing.Dict,
|
|
403
|
+
key: str,
|
|
404
|
+
*,
|
|
405
|
+
timeout: typing.Optional[float] = None,
|
|
406
|
+
) -> None:
|
|
407
|
+
return mapping.from_maybe_impl(
|
|
408
|
+
self._sync(
|
|
409
|
+
self._impl_obj.press(selector=selector, key=key, timeout=timeout)
|
|
410
|
+
)
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
def info(self, selector: typing.Dict) -> typing.Dict:
|
|
414
|
+
return mapping.from_maybe_impl(
|
|
415
|
+
self._sync(self._impl_obj.info(selector=selector))
|
|
416
|
+
)
|
|
417
|
+
|
|
418
|
+
def set_default_timeout(self, timeout: float) -> None:
|
|
419
|
+
return mapping.from_maybe_impl(
|
|
420
|
+
self._impl_obj.set_default_timeout(timeout=timeout)
|
|
421
|
+
)
|
|
422
|
+
|
|
423
|
+
def wait_for_event(
|
|
424
|
+
self,
|
|
425
|
+
event: str,
|
|
426
|
+
*,
|
|
427
|
+
predicate: typing.Optional[typing.Callable] = None,
|
|
428
|
+
timeout: typing.Optional[float] = None,
|
|
429
|
+
) -> typing.Any:
|
|
430
|
+
return mapping.from_maybe_impl(
|
|
431
|
+
self._sync(
|
|
432
|
+
self._impl_obj.wait_for_event(
|
|
433
|
+
event=event, predicate=predicate, timeout=timeout
|
|
434
|
+
)
|
|
435
|
+
)
|
|
436
|
+
)
|
|
437
|
+
|
|
438
|
+
def close(self) -> None:
|
|
439
|
+
return mapping.from_maybe_impl(self._sync(self._impl_obj.close()))
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
mapping.register(AndroidDeviceImpl, AndroidDevice)
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
class Android(SyncBase):
|
|
446
|
+
|
|
447
|
+
def devices(
|
|
448
|
+
self, *, port: typing.Optional[int] = None
|
|
449
|
+
) -> typing.List["AndroidDevice"]:
|
|
450
|
+
return mapping.from_impl_list(self._sync(self._impl_obj.devices(port=port)))
|
|
451
|
+
|
|
452
|
+
def set_default_timeout(self, timeout: float) -> None:
|
|
453
|
+
return mapping.from_maybe_impl(
|
|
454
|
+
self._impl_obj.set_default_timeout(timeout=timeout)
|
|
455
|
+
)
|
|
456
|
+
|
|
457
|
+
def connect(
|
|
458
|
+
self,
|
|
459
|
+
ws_endpoint: str,
|
|
460
|
+
*,
|
|
461
|
+
headers: typing.Optional[typing.Dict[str, str]] = None,
|
|
462
|
+
slow_mo: typing.Optional[float] = None,
|
|
463
|
+
timeout: typing.Optional[float] = None,
|
|
464
|
+
) -> "AndroidDevice":
|
|
465
|
+
return mapping.from_impl(
|
|
466
|
+
self._sync(
|
|
467
|
+
self._impl_obj.connect(
|
|
468
|
+
wsEndpoint=ws_endpoint,
|
|
469
|
+
headers=headers,
|
|
470
|
+
slowMo=slow_mo,
|
|
471
|
+
timeout=timeout,
|
|
472
|
+
)
|
|
473
|
+
)
|
|
474
|
+
)
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
mapping.register(AndroidImpl, Android)
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
# Attached here rather than in _generated.py so that regenerating that file
|
|
481
|
+
# cannot drop it. See the module docstring.
|
|
482
|
+
def _android(self: Playwright) -> Android:
|
|
483
|
+
"""Playwright.android
|
|
484
|
+
|
|
485
|
+
Android support for Playwright.
|
|
486
|
+
|
|
487
|
+
Returns
|
|
488
|
+
-------
|
|
489
|
+
Android
|
|
490
|
+
"""
|
|
491
|
+
return mapping.from_impl(self._impl_obj.android)
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
Playwright.android = property(_android) # type: ignore[attr-defined]
|
|
@@ -0,0 +1,98 @@
|
|
|
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
|
+
from typing import TYPE_CHECKING, Any, Optional, cast
|
|
17
|
+
|
|
18
|
+
from greenlet import greenlet
|
|
19
|
+
|
|
20
|
+
from playwright._impl._connection import ChannelOwner, Connection
|
|
21
|
+
from playwright._impl._errors import Error
|
|
22
|
+
from playwright._impl._greenlets import MainGreenlet
|
|
23
|
+
from playwright._impl._object_factory import create_remote_object
|
|
24
|
+
from playwright._impl._playwright import Playwright
|
|
25
|
+
from playwright._impl._transport import PipeTransport
|
|
26
|
+
from playwright.sync_api._generated import Playwright as SyncPlaywright
|
|
27
|
+
|
|
28
|
+
if TYPE_CHECKING:
|
|
29
|
+
from asyncio.unix_events import AbstractChildWatcher
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class PlaywrightContextManager:
|
|
33
|
+
def __init__(self) -> None:
|
|
34
|
+
self._playwright: SyncPlaywright
|
|
35
|
+
self._loop: asyncio.AbstractEventLoop
|
|
36
|
+
self._own_loop = False
|
|
37
|
+
self._watcher: Optional[AbstractChildWatcher] = None
|
|
38
|
+
self._exit_was_called = False
|
|
39
|
+
|
|
40
|
+
def __enter__(self) -> SyncPlaywright:
|
|
41
|
+
try:
|
|
42
|
+
self._loop = asyncio.get_running_loop()
|
|
43
|
+
except RuntimeError:
|
|
44
|
+
self._loop = asyncio.new_event_loop()
|
|
45
|
+
self._own_loop = True
|
|
46
|
+
if self._loop.is_running():
|
|
47
|
+
raise Error(
|
|
48
|
+
"""It looks like you are using Playwright Sync API inside the asyncio loop.
|
|
49
|
+
Please use the Async API instead."""
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# Create a new fiber for the protocol dispatcher. It will be pumping events
|
|
53
|
+
# until the end of times. We will pass control to that fiber every time we
|
|
54
|
+
# block while waiting for a response.
|
|
55
|
+
def greenlet_main() -> None:
|
|
56
|
+
self._loop.run_until_complete(self._connection.run_as_sync())
|
|
57
|
+
|
|
58
|
+
dispatcher_fiber = MainGreenlet(greenlet_main)
|
|
59
|
+
|
|
60
|
+
self._connection = Connection(
|
|
61
|
+
dispatcher_fiber,
|
|
62
|
+
create_remote_object,
|
|
63
|
+
PipeTransport(self._loop),
|
|
64
|
+
self._loop,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
g_self = greenlet.getcurrent()
|
|
68
|
+
|
|
69
|
+
def callback_wrapper(channel_owner: ChannelOwner) -> None:
|
|
70
|
+
playwright_impl = cast(Playwright, channel_owner)
|
|
71
|
+
self._playwright = SyncPlaywright(playwright_impl)
|
|
72
|
+
g_self.switch()
|
|
73
|
+
|
|
74
|
+
# Switch control to the dispatcher, it'll fire an event and pass control to
|
|
75
|
+
# the calling greenlet.
|
|
76
|
+
self._connection.call_on_object_with_known_name("Playwright", callback_wrapper)
|
|
77
|
+
dispatcher_fiber.switch()
|
|
78
|
+
|
|
79
|
+
playwright = self._playwright
|
|
80
|
+
playwright.stop = self.__exit__ # type: ignore
|
|
81
|
+
return playwright
|
|
82
|
+
|
|
83
|
+
def start(self) -> SyncPlaywright:
|
|
84
|
+
return self.__enter__()
|
|
85
|
+
|
|
86
|
+
def __exit__(self, *args: Any) -> None:
|
|
87
|
+
if self._exit_was_called:
|
|
88
|
+
return
|
|
89
|
+
self._exit_was_called = True
|
|
90
|
+
self._connection.stop_sync()
|
|
91
|
+
if self._watcher:
|
|
92
|
+
self._watcher.close()
|
|
93
|
+
if self._own_loop:
|
|
94
|
+
tasks = asyncio.all_tasks(self._loop)
|
|
95
|
+
for t in [t for t in tasks if not (t.done() or t.cancelled())]:
|
|
96
|
+
t.cancel()
|
|
97
|
+
self._loop.run_until_complete(self._loop.shutdown_asyncgens())
|
|
98
|
+
self._loop.close()
|