pybiolib 0.2.951__py3-none-any.whl → 1.2.1890__py3-none-any.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.
- biolib/__init__.py +357 -11
- biolib/_data_record/data_record.py +380 -0
- biolib/_index/__init__.py +0 -0
- biolib/_index/index.py +55 -0
- biolib/_index/query_result.py +103 -0
- biolib/_internal/__init__.py +0 -0
- biolib/_internal/add_copilot_prompts.py +58 -0
- biolib/_internal/add_gui_files.py +81 -0
- biolib/_internal/data_record/__init__.py +1 -0
- biolib/_internal/data_record/data_record.py +85 -0
- biolib/_internal/data_record/push_data.py +116 -0
- biolib/_internal/data_record/remote_storage_endpoint.py +43 -0
- biolib/_internal/errors.py +5 -0
- biolib/_internal/file_utils.py +125 -0
- biolib/_internal/fuse_mount/__init__.py +1 -0
- biolib/_internal/fuse_mount/experiment_fuse_mount.py +209 -0
- biolib/_internal/http_client.py +159 -0
- biolib/_internal/lfs/__init__.py +1 -0
- biolib/_internal/lfs/cache.py +51 -0
- biolib/_internal/libs/__init__.py +1 -0
- biolib/_internal/libs/fusepy/__init__.py +1257 -0
- biolib/_internal/push_application.py +488 -0
- biolib/_internal/runtime.py +22 -0
- biolib/_internal/string_utils.py +13 -0
- biolib/_internal/templates/__init__.py +1 -0
- biolib/_internal/templates/copilot_template/.github/instructions/general-app-knowledge.instructions.md +10 -0
- biolib/_internal/templates/copilot_template/.github/instructions/style-general.instructions.md +20 -0
- biolib/_internal/templates/copilot_template/.github/instructions/style-python.instructions.md +16 -0
- biolib/_internal/templates/copilot_template/.github/instructions/style-react-ts.instructions.md +47 -0
- biolib/_internal/templates/copilot_template/.github/prompts/biolib_app_inputs.prompt.md +11 -0
- biolib/_internal/templates/copilot_template/.github/prompts/biolib_onboard_repo.prompt.md +19 -0
- biolib/_internal/templates/copilot_template/.github/prompts/biolib_run_apps.prompt.md +12 -0
- biolib/_internal/templates/dashboard_template/.biolib/config.yml +5 -0
- biolib/_internal/templates/github_workflow_template/.github/workflows/biolib.yml +21 -0
- biolib/_internal/templates/gitignore_template/.gitignore +10 -0
- biolib/_internal/templates/gui_template/.yarnrc.yml +1 -0
- biolib/_internal/templates/gui_template/App.tsx +53 -0
- biolib/_internal/templates/gui_template/Dockerfile +27 -0
- biolib/_internal/templates/gui_template/biolib-sdk.ts +82 -0
- biolib/_internal/templates/gui_template/dev-data/output.json +7 -0
- biolib/_internal/templates/gui_template/index.css +5 -0
- biolib/_internal/templates/gui_template/index.html +13 -0
- biolib/_internal/templates/gui_template/index.tsx +10 -0
- biolib/_internal/templates/gui_template/package.json +27 -0
- biolib/_internal/templates/gui_template/tsconfig.json +24 -0
- biolib/_internal/templates/gui_template/vite-plugin-dev-data.ts +50 -0
- biolib/_internal/templates/gui_template/vite.config.mts +10 -0
- biolib/_internal/templates/init_template/.biolib/config.yml +19 -0
- biolib/_internal/templates/init_template/Dockerfile +14 -0
- biolib/_internal/templates/init_template/requirements.txt +1 -0
- biolib/_internal/templates/init_template/run.py +12 -0
- biolib/_internal/templates/init_template/run.sh +4 -0
- biolib/_internal/templates/templates.py +25 -0
- biolib/_internal/tree_utils.py +106 -0
- biolib/_internal/utils/__init__.py +65 -0
- biolib/_internal/utils/auth.py +46 -0
- biolib/_internal/utils/job_url.py +33 -0
- biolib/_internal/utils/multinode.py +263 -0
- biolib/_runtime/runtime.py +157 -0
- biolib/_session/session.py +44 -0
- biolib/_shared/__init__.py +0 -0
- biolib/_shared/types/__init__.py +74 -0
- biolib/_shared/types/account.py +12 -0
- biolib/_shared/types/account_member.py +8 -0
- biolib/_shared/types/app.py +9 -0
- biolib/_shared/types/data_record.py +40 -0
- biolib/_shared/types/experiment.py +32 -0
- biolib/_shared/types/file_node.py +17 -0
- biolib/_shared/types/push.py +6 -0
- biolib/_shared/types/resource.py +37 -0
- biolib/_shared/types/resource_deploy_key.py +11 -0
- biolib/_shared/types/resource_permission.py +14 -0
- biolib/_shared/types/resource_version.py +19 -0
- biolib/_shared/types/result.py +14 -0
- biolib/_shared/types/typing.py +10 -0
- biolib/_shared/types/user.py +19 -0
- biolib/_shared/utils/__init__.py +7 -0
- biolib/_shared/utils/resource_uri.py +75 -0
- biolib/api/__init__.py +6 -0
- biolib/api/client.py +168 -0
- biolib/app/app.py +252 -49
- biolib/app/search_apps.py +45 -0
- biolib/biolib_api_client/api_client.py +126 -31
- biolib/biolib_api_client/app_types.py +24 -4
- biolib/biolib_api_client/auth.py +31 -8
- biolib/biolib_api_client/biolib_app_api.py +147 -52
- biolib/biolib_api_client/biolib_job_api.py +161 -141
- biolib/biolib_api_client/job_types.py +21 -5
- biolib/biolib_api_client/lfs_types.py +7 -23
- biolib/biolib_api_client/user_state.py +56 -0
- biolib/biolib_binary_format/__init__.py +1 -4
- biolib/biolib_binary_format/file_in_container.py +105 -0
- biolib/biolib_binary_format/module_input.py +24 -7
- biolib/biolib_binary_format/module_output_v2.py +149 -0
- biolib/biolib_binary_format/remote_endpoints.py +34 -0
- biolib/biolib_binary_format/remote_stream_seeker.py +59 -0
- biolib/biolib_binary_format/saved_job.py +3 -2
- biolib/biolib_binary_format/{attestation_document.py → stdout_and_stderr.py} +8 -8
- biolib/biolib_binary_format/system_status_update.py +3 -2
- biolib/biolib_binary_format/utils.py +175 -0
- biolib/biolib_docker_client/__init__.py +11 -2
- biolib/biolib_errors.py +36 -0
- biolib/biolib_logging.py +27 -10
- biolib/cli/__init__.py +38 -0
- biolib/cli/auth.py +46 -0
- biolib/cli/data_record.py +164 -0
- biolib/cli/index.py +32 -0
- biolib/cli/init.py +421 -0
- biolib/cli/lfs.py +101 -0
- biolib/cli/push.py +50 -0
- biolib/cli/run.py +63 -0
- biolib/cli/runtime.py +14 -0
- biolib/cli/sdk.py +16 -0
- biolib/cli/start.py +56 -0
- biolib/compute_node/cloud_utils/cloud_utils.py +110 -161
- biolib/compute_node/job_worker/cache_state.py +66 -88
- biolib/compute_node/job_worker/cache_types.py +1 -6
- biolib/compute_node/job_worker/docker_image_cache.py +112 -37
- biolib/compute_node/job_worker/executors/__init__.py +0 -3
- biolib/compute_node/job_worker/executors/docker_executor.py +532 -199
- biolib/compute_node/job_worker/executors/docker_types.py +9 -1
- biolib/compute_node/job_worker/executors/types.py +19 -9
- biolib/compute_node/job_worker/job_legacy_input_wait_timeout_thread.py +30 -0
- biolib/compute_node/job_worker/job_max_runtime_timer_thread.py +3 -5
- biolib/compute_node/job_worker/job_storage.py +108 -0
- biolib/compute_node/job_worker/job_worker.py +397 -212
- biolib/compute_node/job_worker/large_file_system.py +87 -38
- biolib/compute_node/job_worker/network_alloc.py +99 -0
- biolib/compute_node/job_worker/network_buffer.py +240 -0
- biolib/compute_node/job_worker/utilization_reporter_thread.py +197 -0
- biolib/compute_node/job_worker/utils.py +9 -24
- biolib/compute_node/remote_host_proxy.py +400 -98
- biolib/compute_node/utils.py +31 -9
- biolib/compute_node/webserver/compute_node_results_proxy.py +189 -0
- biolib/compute_node/webserver/proxy_utils.py +28 -0
- biolib/compute_node/webserver/webserver.py +130 -44
- biolib/compute_node/webserver/webserver_types.py +2 -6
- biolib/compute_node/webserver/webserver_utils.py +77 -12
- biolib/compute_node/webserver/worker_thread.py +183 -42
- biolib/experiments/__init__.py +0 -0
- biolib/experiments/experiment.py +356 -0
- biolib/jobs/__init__.py +1 -0
- biolib/jobs/job.py +741 -0
- biolib/jobs/job_result.py +185 -0
- biolib/jobs/types.py +50 -0
- biolib/py.typed +0 -0
- biolib/runtime/__init__.py +14 -0
- biolib/sdk/__init__.py +91 -0
- biolib/tables.py +34 -0
- biolib/typing_utils.py +2 -7
- biolib/user/__init__.py +1 -0
- biolib/user/sign_in.py +54 -0
- biolib/utils/__init__.py +162 -0
- biolib/utils/cache_state.py +94 -0
- biolib/utils/multipart_uploader.py +194 -0
- biolib/utils/seq_util.py +150 -0
- biolib/utils/zip/remote_zip.py +640 -0
- pybiolib-1.2.1890.dist-info/METADATA +41 -0
- pybiolib-1.2.1890.dist-info/RECORD +177 -0
- {pybiolib-0.2.951.dist-info → pybiolib-1.2.1890.dist-info}/WHEEL +1 -1
- pybiolib-1.2.1890.dist-info/entry_points.txt +2 -0
- README.md +0 -17
- biolib/app/app_result.py +0 -68
- biolib/app/utils.py +0 -62
- biolib/biolib-js/0-biolib.worker.js +0 -1
- biolib/biolib-js/1-biolib.worker.js +0 -1
- biolib/biolib-js/2-biolib.worker.js +0 -1
- biolib/biolib-js/3-biolib.worker.js +0 -1
- biolib/biolib-js/4-biolib.worker.js +0 -1
- biolib/biolib-js/5-biolib.worker.js +0 -1
- biolib/biolib-js/6-biolib.worker.js +0 -1
- biolib/biolib-js/index.html +0 -10
- biolib/biolib-js/main-biolib.js +0 -1
- biolib/biolib_api_client/biolib_account_api.py +0 -21
- biolib/biolib_api_client/biolib_large_file_system_api.py +0 -108
- biolib/biolib_binary_format/aes_encrypted_package.py +0 -42
- biolib/biolib_binary_format/module_output.py +0 -58
- biolib/biolib_binary_format/rsa_encrypted_aes_package.py +0 -57
- biolib/biolib_push.py +0 -114
- biolib/cli.py +0 -203
- biolib/cli_utils.py +0 -273
- biolib/compute_node/cloud_utils/enclave_parent_types.py +0 -7
- biolib/compute_node/enclave/__init__.py +0 -2
- biolib/compute_node/enclave/enclave_remote_hosts.py +0 -53
- biolib/compute_node/enclave/nitro_secure_module_utils.py +0 -64
- biolib/compute_node/job_worker/executors/base_executor.py +0 -18
- biolib/compute_node/job_worker/executors/pyppeteer_executor.py +0 -173
- biolib/compute_node/job_worker/executors/remote/__init__.py +0 -1
- biolib/compute_node/job_worker/executors/remote/nitro_enclave_utils.py +0 -81
- biolib/compute_node/job_worker/executors/remote/remote_executor.py +0 -51
- biolib/lfs.py +0 -196
- biolib/pyppeteer/.circleci/config.yml +0 -100
- biolib/pyppeteer/.coveragerc +0 -3
- biolib/pyppeteer/.gitignore +0 -89
- biolib/pyppeteer/.pre-commit-config.yaml +0 -28
- biolib/pyppeteer/CHANGES.md +0 -253
- biolib/pyppeteer/CONTRIBUTING.md +0 -26
- biolib/pyppeteer/LICENSE +0 -12
- biolib/pyppeteer/README.md +0 -137
- biolib/pyppeteer/docs/Makefile +0 -177
- biolib/pyppeteer/docs/_static/custom.css +0 -28
- biolib/pyppeteer/docs/_templates/layout.html +0 -10
- biolib/pyppeteer/docs/changes.md +0 -1
- biolib/pyppeteer/docs/conf.py +0 -299
- biolib/pyppeteer/docs/index.md +0 -21
- biolib/pyppeteer/docs/make.bat +0 -242
- biolib/pyppeteer/docs/reference.md +0 -211
- biolib/pyppeteer/docs/server.py +0 -60
- biolib/pyppeteer/poetry.lock +0 -1699
- biolib/pyppeteer/pyppeteer/__init__.py +0 -135
- biolib/pyppeteer/pyppeteer/accessibility.py +0 -286
- biolib/pyppeteer/pyppeteer/browser.py +0 -401
- biolib/pyppeteer/pyppeteer/browser_fetcher.py +0 -194
- biolib/pyppeteer/pyppeteer/command.py +0 -22
- biolib/pyppeteer/pyppeteer/connection/__init__.py +0 -242
- biolib/pyppeteer/pyppeteer/connection/cdpsession.py +0 -101
- biolib/pyppeteer/pyppeteer/coverage.py +0 -346
- biolib/pyppeteer/pyppeteer/device_descriptors.py +0 -787
- biolib/pyppeteer/pyppeteer/dialog.py +0 -79
- biolib/pyppeteer/pyppeteer/domworld.py +0 -597
- biolib/pyppeteer/pyppeteer/emulation_manager.py +0 -53
- biolib/pyppeteer/pyppeteer/errors.py +0 -48
- biolib/pyppeteer/pyppeteer/events.py +0 -63
- biolib/pyppeteer/pyppeteer/execution_context.py +0 -156
- biolib/pyppeteer/pyppeteer/frame/__init__.py +0 -299
- biolib/pyppeteer/pyppeteer/frame/frame_manager.py +0 -306
- biolib/pyppeteer/pyppeteer/helpers.py +0 -245
- biolib/pyppeteer/pyppeteer/input.py +0 -371
- biolib/pyppeteer/pyppeteer/jshandle.py +0 -598
- biolib/pyppeteer/pyppeteer/launcher.py +0 -683
- biolib/pyppeteer/pyppeteer/lifecycle_watcher.py +0 -169
- biolib/pyppeteer/pyppeteer/models/__init__.py +0 -103
- biolib/pyppeteer/pyppeteer/models/_protocol.py +0 -12460
- biolib/pyppeteer/pyppeteer/multimap.py +0 -82
- biolib/pyppeteer/pyppeteer/network_manager.py +0 -678
- biolib/pyppeteer/pyppeteer/options.py +0 -8
- biolib/pyppeteer/pyppeteer/page.py +0 -1728
- biolib/pyppeteer/pyppeteer/pipe_transport.py +0 -59
- biolib/pyppeteer/pyppeteer/target.py +0 -147
- biolib/pyppeteer/pyppeteer/task_queue.py +0 -24
- biolib/pyppeteer/pyppeteer/timeout_settings.py +0 -36
- biolib/pyppeteer/pyppeteer/tracing.py +0 -93
- biolib/pyppeteer/pyppeteer/us_keyboard_layout.py +0 -305
- biolib/pyppeteer/pyppeteer/util.py +0 -18
- biolib/pyppeteer/pyppeteer/websocket_transport.py +0 -47
- biolib/pyppeteer/pyppeteer/worker.py +0 -101
- biolib/pyppeteer/pyproject.toml +0 -97
- biolib/pyppeteer/spell.txt +0 -137
- biolib/pyppeteer/tox.ini +0 -72
- biolib/pyppeteer/utils/generate_protocol_types.py +0 -603
- biolib/start_cli.py +0 -7
- biolib/utils.py +0 -47
- biolib/validators/validate_app_version.py +0 -183
- biolib/validators/validate_argument.py +0 -134
- biolib/validators/validate_module.py +0 -323
- biolib/validators/validate_zip_file.py +0 -40
- biolib/validators/validator_utils.py +0 -103
- pybiolib-0.2.951.dist-info/LICENSE +0 -21
- pybiolib-0.2.951.dist-info/METADATA +0 -61
- pybiolib-0.2.951.dist-info/RECORD +0 -153
- pybiolib-0.2.951.dist-info/entry_points.txt +0 -3
- /LICENSE → /pybiolib-1.2.1890.dist-info/licenses/LICENSE +0 -0
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
"""Emulation Manager module."""
|
|
5
|
-
import asyncio
|
|
6
|
-
|
|
7
|
-
from biolib.pyppeteer.pyppeteer.connection import CDPSession
|
|
8
|
-
from biolib.pyppeteer.pyppeteer.models import Protocol
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class EmulationManager:
|
|
12
|
-
"""EmulationManager class."""
|
|
13
|
-
|
|
14
|
-
def __init__(self, client: CDPSession) -> None:
|
|
15
|
-
"""Make new emulation manager."""
|
|
16
|
-
self._client = client
|
|
17
|
-
self._emulatingMobile = False
|
|
18
|
-
self._hasTouch = False
|
|
19
|
-
self._emulatingMobile = False
|
|
20
|
-
|
|
21
|
-
async def emulateViewport(self, viewport: Protocol.Page.Viewport) -> bool:
|
|
22
|
-
"""
|
|
23
|
-
Evaluate viewport.
|
|
24
|
-
:param viewport: dictionary which supports keys: isMobile, width, height,
|
|
25
|
-
deviceScaleFactor, isLandscape, hasTouch
|
|
26
|
-
"""
|
|
27
|
-
mobile = viewport.get('isMobile', False)
|
|
28
|
-
width = viewport.get('width')
|
|
29
|
-
height = viewport.get('height')
|
|
30
|
-
deviceScaleFactor = viewport.get('deviceScaleFactor', 1)
|
|
31
|
-
if viewport.get('isLandscape'):
|
|
32
|
-
screenOrientation = {'angle': 90, 'type': 'landscapePrimary'}
|
|
33
|
-
else:
|
|
34
|
-
screenOrientation = {'angle': 0, 'type': 'portraitPrimary'}
|
|
35
|
-
hasTouch = viewport.get('hasTouch', False)
|
|
36
|
-
|
|
37
|
-
await asyncio.gather(
|
|
38
|
-
self._client.send(
|
|
39
|
-
'Emulation.setDeviceMetricsOverride',
|
|
40
|
-
{
|
|
41
|
-
'mobile': mobile,
|
|
42
|
-
'width': width,
|
|
43
|
-
'height': height,
|
|
44
|
-
'deviceScaleFactor': deviceScaleFactor,
|
|
45
|
-
'screenOrientation': screenOrientation,
|
|
46
|
-
},
|
|
47
|
-
),
|
|
48
|
-
self._client.send('Emulation.setTouchEmulationEnabled', {'enabled': hasTouch}),
|
|
49
|
-
)
|
|
50
|
-
reloadNeeded = self._emulatingMobile != mobile or self._hasTouch != hasTouch
|
|
51
|
-
self._emulatingMobile = mobile
|
|
52
|
-
self._hasTouch = hasTouch
|
|
53
|
-
return reloadNeeded
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
"""Exceptions for pyppeteer package."""
|
|
5
|
-
|
|
6
|
-
import asyncio
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class PyppeteerError(Exception): # noqa: D204
|
|
10
|
-
"""Base exception for pyppeteer."""
|
|
11
|
-
|
|
12
|
-
pass
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class BrowserError(PyppeteerError): # noqa: D204
|
|
16
|
-
"""Exception raised from browser."""
|
|
17
|
-
|
|
18
|
-
pass
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class ElementHandleError(PyppeteerError): # noqa: D204
|
|
22
|
-
"""ElementHandle related exception."""
|
|
23
|
-
|
|
24
|
-
pass
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class NetworkError(PyppeteerError): # noqa: D204
|
|
28
|
-
"""Network/Protocol related exception."""
|
|
29
|
-
|
|
30
|
-
pass
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
class PageError(PyppeteerError): # noqa: D204
|
|
34
|
-
"""Page/Frame related exception."""
|
|
35
|
-
|
|
36
|
-
pass
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
class TimeoutError(asyncio.TimeoutError): # noqa: D204
|
|
40
|
-
"""Timeout Error class."""
|
|
41
|
-
|
|
42
|
-
pass
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class DeprecationError(PyppeteerError): # noqa: D204
|
|
46
|
-
"""Deprecated Error class"""
|
|
47
|
-
|
|
48
|
-
pass
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
"""
|
|
4
|
-
Events module
|
|
5
|
-
|
|
6
|
-
puppeteer equivalent: Events.js
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class Events:
|
|
11
|
-
class Page:
|
|
12
|
-
Close = 'close'
|
|
13
|
-
Console = 'console'
|
|
14
|
-
Dialog = 'dialog'
|
|
15
|
-
DOMContentLoaded = 'domcontentloaded'
|
|
16
|
-
Error = 'error'
|
|
17
|
-
# Can't use just 'error' due to node.js special treatment of error events.
|
|
18
|
-
# @see https://nodejs.org/api/events.html#events_error_events
|
|
19
|
-
PageError = 'pageerror'
|
|
20
|
-
Request = 'request'
|
|
21
|
-
Response = 'response'
|
|
22
|
-
RequestFailed = 'requestfailed'
|
|
23
|
-
RequestFinished = 'requestfinished'
|
|
24
|
-
FrameAttached = 'frameattached'
|
|
25
|
-
FrameDetached = 'framedetached'
|
|
26
|
-
FrameNavigated = 'framenavigated'
|
|
27
|
-
Load = 'load'
|
|
28
|
-
Metrics = 'metrics'
|
|
29
|
-
Popup = 'popup'
|
|
30
|
-
WorkerCreated = 'workercreated'
|
|
31
|
-
WorkerDestroyed = 'workerdestroyed'
|
|
32
|
-
|
|
33
|
-
class Browser:
|
|
34
|
-
TargetCreated = 'targetcreated'
|
|
35
|
-
TargetDestroyed = 'targetdestroyed'
|
|
36
|
-
TargetChanged = 'targetchanged'
|
|
37
|
-
Disconnected = 'disconnected'
|
|
38
|
-
|
|
39
|
-
class BrowserContext:
|
|
40
|
-
TargetCreated = 'targetcreated'
|
|
41
|
-
TargetDestroyed = 'targetdestroyed'
|
|
42
|
-
TargetChanged = 'targetchanged'
|
|
43
|
-
|
|
44
|
-
class NetworkManager:
|
|
45
|
-
Request = 'Events.NetworkManager.Request'
|
|
46
|
-
Response = 'Events.NetworkManager.Response'
|
|
47
|
-
RequestFailed = 'Events.NetworkManager.RequestFailed'
|
|
48
|
-
RequestFinished = 'Events.NetworkManager.RequestFinished'
|
|
49
|
-
|
|
50
|
-
class FrameManager:
|
|
51
|
-
FrameAttached = 'Events.FrameManager.FrameAttached'
|
|
52
|
-
FrameNavigated = 'Events.FrameManager.FrameNavigated'
|
|
53
|
-
FrameDetached = 'Events.FrameManager.FrameDetached'
|
|
54
|
-
LifecycleEvent = 'Events.FrameManager.LifecycleEvent'
|
|
55
|
-
FrameNavigatedWithinDocument = 'Events.FrameManager.FrameNavigatedWithinDocument'
|
|
56
|
-
ExecutionContextCreated = 'Events.FrameManager.ExecutionContextCreated'
|
|
57
|
-
ExecutionContextDestroyed = 'Events.FrameManager.ExecutionContextDestroyed'
|
|
58
|
-
|
|
59
|
-
class Connection:
|
|
60
|
-
Disconnected = 'Events.Connection.Disconnected'
|
|
61
|
-
|
|
62
|
-
class CDPSession:
|
|
63
|
-
Disconnected = 'Events.CDPSession.Disconnected'
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
"""Execution Context Module."""
|
|
5
|
-
|
|
6
|
-
import logging
|
|
7
|
-
import math
|
|
8
|
-
import re
|
|
9
|
-
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
|
|
10
|
-
|
|
11
|
-
from biolib.pyppeteer.pyppeteer import helpers
|
|
12
|
-
from biolib.pyppeteer.pyppeteer.connection import CDPSession
|
|
13
|
-
from biolib.pyppeteer.pyppeteer.errors import ElementHandleError
|
|
14
|
-
from biolib.pyppeteer.pyppeteer.jshandle import ElementHandle, JSHandle, createJSHandle
|
|
15
|
-
from biolib.pyppeteer.pyppeteer.models import JSFunctionArg
|
|
16
|
-
|
|
17
|
-
if TYPE_CHECKING:
|
|
18
|
-
from pyppeteer.frame import Frame
|
|
19
|
-
from pyppeteer.domworld import DOMWorld
|
|
20
|
-
|
|
21
|
-
logger = logging.getLogger(__name__)
|
|
22
|
-
|
|
23
|
-
EVALUATION_SCRIPT_URL = '__pyppeteer_evaluation_script__'
|
|
24
|
-
SOURCE_URL_REGEX = re.compile(r'^[ \t]*//[@#] sourceURL=\s*(\S*?)\s*$', re.MULTILINE,)
|
|
25
|
-
|
|
26
|
-
class ExecutionContext:
|
|
27
|
-
"""Execution Context class."""
|
|
28
|
-
|
|
29
|
-
def __init__(self, client: CDPSession, contextPayload: Dict, world: Optional['DOMWorld']) -> None:
|
|
30
|
-
self._client = client
|
|
31
|
-
self._world = world
|
|
32
|
-
self._contextId = contextPayload['id']
|
|
33
|
-
|
|
34
|
-
@property
|
|
35
|
-
def frame(self) -> Optional['Frame']:
|
|
36
|
-
"""Return frame associated with this execution context."""
|
|
37
|
-
if self._world:
|
|
38
|
-
return self._world.frame
|
|
39
|
-
|
|
40
|
-
async def evaluate(self, pageFunction: str, *args: JSFunctionArg) -> JSFunctionArg:
|
|
41
|
-
"""Execute ``pageFunction`` on this context.
|
|
42
|
-
|
|
43
|
-
Details see :meth:`pyppeteer.page.Page.evaluate`.
|
|
44
|
-
"""
|
|
45
|
-
return await self._evaluateInternal(True, pageFunction, *args)
|
|
46
|
-
|
|
47
|
-
async def evaluateHandle(self, pageFunction: str, *args: JSFunctionArg) -> Union['JSHandle', 'ElementHandle']:
|
|
48
|
-
"""Execute ``pageFunction`` on this context.
|
|
49
|
-
Details see :meth:`pyppeteer.page.Page.evaluateHandle`.
|
|
50
|
-
"""
|
|
51
|
-
return await self._evaluateInternal(False, pageFunction, *args)
|
|
52
|
-
|
|
53
|
-
async def _evaluateInternal(
|
|
54
|
-
self, returnByValue: bool, pageFunction: str, *args: JSFunctionArg
|
|
55
|
-
) -> Union['JSHandle', 'ElementHandle', JSFunctionArg]:
|
|
56
|
-
suffix = f'//# sourceURL={EVALUATION_SCRIPT_URL}'
|
|
57
|
-
|
|
58
|
-
if not helpers.is_js_func(pageFunction):
|
|
59
|
-
try:
|
|
60
|
-
if SOURCE_URL_REGEX.match(pageFunction):
|
|
61
|
-
expressionWithSourceUrl = pageFunction
|
|
62
|
-
else:
|
|
63
|
-
expressionWithSourceUrl = f'{pageFunction}\n{suffix}'
|
|
64
|
-
remoteObject = await self._client.send(
|
|
65
|
-
'Runtime.evaluate',
|
|
66
|
-
{
|
|
67
|
-
'expression': expressionWithSourceUrl,
|
|
68
|
-
'contextId': self._contextId,
|
|
69
|
-
'returnByValue': returnByValue,
|
|
70
|
-
'awaitPromise': True,
|
|
71
|
-
'userGesture': True,
|
|
72
|
-
},
|
|
73
|
-
)
|
|
74
|
-
except Exception as e:
|
|
75
|
-
exceptionDetails = rewriteError(e)
|
|
76
|
-
raise type(e)(f'Evaluation failed: {helpers.getExceptionMessage(exceptionDetails)}')
|
|
77
|
-
else:
|
|
78
|
-
try:
|
|
79
|
-
remoteObject = await self._client.send(
|
|
80
|
-
'Runtime.callFunctionOn',
|
|
81
|
-
{
|
|
82
|
-
'functionDeclaration': f'{pageFunction}\n{suffix}\n',
|
|
83
|
-
'executionContextId': self._contextId,
|
|
84
|
-
'arguments': [self._convertArgument(arg) for arg in args],
|
|
85
|
-
'returnByValue': returnByValue,
|
|
86
|
-
'awaitPromise': True,
|
|
87
|
-
'userGesture': True,
|
|
88
|
-
},
|
|
89
|
-
)
|
|
90
|
-
except Exception as e:
|
|
91
|
-
exceptionDetails = rewriteError(e)
|
|
92
|
-
raise type(e)(f'Evaluation failed: {helpers.getExceptionMessage(exceptionDetails)}')
|
|
93
|
-
|
|
94
|
-
exceptionDetails = remoteObject.get('exceptionDetails')
|
|
95
|
-
if exceptionDetails:
|
|
96
|
-
raise ElementHandleError('Evaluation failed: {}'.format(helpers.getExceptionMessage(exceptionDetails)))
|
|
97
|
-
|
|
98
|
-
remoteObject = remoteObject['result']
|
|
99
|
-
if returnByValue:
|
|
100
|
-
return helpers.valueFromRemoteObject(remoteObject)
|
|
101
|
-
else:
|
|
102
|
-
return createJSHandle(self, remoteObject)
|
|
103
|
-
|
|
104
|
-
def _convertArgument(self, arg: Any) -> Dict: # noqa: C901
|
|
105
|
-
if arg == math.inf:
|
|
106
|
-
return {'unserializableValue': 'Infinity'}
|
|
107
|
-
if arg == -math.inf:
|
|
108
|
-
return {'unserializableValue': '-Infinity'}
|
|
109
|
-
objectHandle = arg if isinstance(arg, JSHandle) else None
|
|
110
|
-
if objectHandle:
|
|
111
|
-
if objectHandle._context != self:
|
|
112
|
-
raise ElementHandleError('JSHandles can be evaluated only in the context they were created!')
|
|
113
|
-
if objectHandle._disposed:
|
|
114
|
-
raise ElementHandleError('JSHandle is disposed!')
|
|
115
|
-
if objectHandle._remoteObject.get('unserializableValue'):
|
|
116
|
-
return {'unserializableValue': objectHandle._remoteObject.get('unserializableValue')}
|
|
117
|
-
if not objectHandle._remoteObject.get('objectId'):
|
|
118
|
-
return {'value': objectHandle._remoteObject.get('value')}
|
|
119
|
-
return {'objectId': objectHandle._remoteObject.get('objectId')}
|
|
120
|
-
return {'value': arg}
|
|
121
|
-
|
|
122
|
-
async def queryObjects(self, prototypeHandle: 'JSHandle'):
|
|
123
|
-
if prototypeHandle._disposed:
|
|
124
|
-
raise ElementHandleError('Prototype JSHandle is disposed')
|
|
125
|
-
if not prototypeHandle._remoteObject.get('objectId'):
|
|
126
|
-
raise ElementHandleError('Prototype JSHandle must not be referencing primitive value')
|
|
127
|
-
response = await self._client.send(
|
|
128
|
-
'Runtime.queryObjects', {'prototypeObjectId': prototypeHandle._remoteObject['objectId']}
|
|
129
|
-
)
|
|
130
|
-
return createJSHandle(context=self, remoteObject=response.get('objects'))
|
|
131
|
-
|
|
132
|
-
async def _adoptBackendNodeId(self, backendNodeId: int):
|
|
133
|
-
obj = await self._client.send(
|
|
134
|
-
'DOM.resolveNode', {'backendNodeId': backendNodeId, 'executionContextId': self._contextId}
|
|
135
|
-
)
|
|
136
|
-
obj = obj['object']
|
|
137
|
-
return createJSHandle(context=self, remoteObject=obj)
|
|
138
|
-
|
|
139
|
-
async def _adoptElementHandle(self, elementHandle: ElementHandle):
|
|
140
|
-
if elementHandle.executionContext == self:
|
|
141
|
-
raise ElementHandleError('Cannot adopt handle that already belongs to this execution context')
|
|
142
|
-
if not self._world:
|
|
143
|
-
raise ElementHandleError('Cannot adopt handle without DOMWorld')
|
|
144
|
-
nodeInfo = await self._client.send('DOM.describeNode', {'objectId': elementHandle._remoteObject['objectId']})
|
|
145
|
-
return await self._adoptBackendNodeId(nodeInfo['node']['backendNodeId'])
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
def rewriteError(error: Exception) -> Union[None, Dict[str, Dict[str, str]]]:
|
|
149
|
-
msg = error.args[0]
|
|
150
|
-
if 'Object reference chain is too long' in msg:
|
|
151
|
-
return {'result': {'type': 'undefined'}}
|
|
152
|
-
if "Object couldn't be returned by value" in msg:
|
|
153
|
-
return {'result': {'type': 'undefined'}}
|
|
154
|
-
if msg.endswith('Cannot find context with specified id'):
|
|
155
|
-
raise type(error)('Execution context was destroyed, most likely because of a navigation.')
|
|
156
|
-
raise error
|
|
@@ -1,299 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import TYPE_CHECKING, Any, Awaitable, List, Optional, Set, Union
|
|
4
|
-
|
|
5
|
-
from ordered_set import OrderedSet
|
|
6
|
-
from biolib.pyppeteer.pyppeteer import helpers
|
|
7
|
-
from biolib.pyppeteer.pyppeteer.connection import CDPSession
|
|
8
|
-
from biolib.pyppeteer.pyppeteer.domworld import DOMWorld, WaitTask
|
|
9
|
-
from biolib.pyppeteer.pyppeteer.errors import BrowserError, PageError
|
|
10
|
-
from biolib.pyppeteer.pyppeteer.jshandle import ElementHandle, JSHandle
|
|
11
|
-
from biolib.pyppeteer.pyppeteer.models import JSFunctionArg, WaitTargets
|
|
12
|
-
from biolib.pyppeteer.pyppeteer.network_manager import Response
|
|
13
|
-
|
|
14
|
-
if TYPE_CHECKING:
|
|
15
|
-
from pyppeteer.execution_context import ExecutionContext
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class Frame:
|
|
19
|
-
"""Frame class.
|
|
20
|
-
|
|
21
|
-
Frame objects can be obtained via :attr:`pyppeteer.page.Page.mainFrame`.
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
def __init__(
|
|
25
|
-
self, frameManager: 'FrameManager', client: CDPSession, parentFrame: Optional['Frame'], frameId: str
|
|
26
|
-
) -> None:
|
|
27
|
-
self._frameManager = frameManager
|
|
28
|
-
self._client = client
|
|
29
|
-
self._parentFrame = parentFrame
|
|
30
|
-
self._url = ''
|
|
31
|
-
self._id = frameId
|
|
32
|
-
self._detached = False
|
|
33
|
-
|
|
34
|
-
self._loaderId = ''
|
|
35
|
-
self._lifecycleEvents: Set[str] = set()
|
|
36
|
-
self._mainWorld = DOMWorld(frameManager, self, frameManager._timeoutSettings)
|
|
37
|
-
self._secondaryWorld = DOMWorld(frameManager, self, frameManager._timeoutSettings)
|
|
38
|
-
self._childFrames: OrderedSet[Frame] = OrderedSet()
|
|
39
|
-
if self._parentFrame:
|
|
40
|
-
self._parentFrame._childFrames.add(self)
|
|
41
|
-
|
|
42
|
-
self._waitTasks: Set[WaitTask] = set()
|
|
43
|
-
if self._parentFrame:
|
|
44
|
-
self._parentFrame._childFrames.add(self)
|
|
45
|
-
|
|
46
|
-
self.addScriptTag = self.mainWorld.addScriptTag
|
|
47
|
-
self.addStyleTag = self.mainWorld.addStyleTag
|
|
48
|
-
self.evaluate = self.mainWorld.evaluate
|
|
49
|
-
self.evaluateHandle = self.mainWorld.evaluateHandle
|
|
50
|
-
self.querySelector = self.J = self.mainWorld.querySelector
|
|
51
|
-
self.querySelectorAll = self.JJ = self.mainWorld.querySelectorAll
|
|
52
|
-
self.querySelectorAllEval = self.JJeval = self.mainWorld.querySelectorAllEval
|
|
53
|
-
self.querySelectorEval = self.Jeval = self.mainWorld.querySelectorEval
|
|
54
|
-
self.type = self.mainWorld.type
|
|
55
|
-
self.waitForFunction = self.mainWorld.waitForFunction
|
|
56
|
-
self.xpath = self.Jx = self.mainWorld.xpath
|
|
57
|
-
|
|
58
|
-
self.click = self.secondaryWorld.click
|
|
59
|
-
self.focus = self.secondaryWorld.focus
|
|
60
|
-
self.hover = self.secondaryWorld.hover
|
|
61
|
-
self.select = self.secondaryWorld.select
|
|
62
|
-
self.setContent = self.secondaryWorld.setContent
|
|
63
|
-
self.tap = self.secondaryWorld.tap
|
|
64
|
-
|
|
65
|
-
@property
|
|
66
|
-
async def executionContext(self) -> Optional['ExecutionContext']:
|
|
67
|
-
return await self.mainWorld.executionContext
|
|
68
|
-
|
|
69
|
-
@property
|
|
70
|
-
async def content(self) -> str:
|
|
71
|
-
return await self.secondaryWorld.content
|
|
72
|
-
|
|
73
|
-
@property
|
|
74
|
-
async def title(self) -> str:
|
|
75
|
-
return await self.secondaryWorld.title
|
|
76
|
-
|
|
77
|
-
async def goto(
|
|
78
|
-
self, url: str, referer: str = None, timeout: float = None, waitUntil: WaitTargets = None
|
|
79
|
-
) -> Optional[Response]:
|
|
80
|
-
return await self._frameManager.navigateFrame(
|
|
81
|
-
self, url=url, referer=referer, timeout=timeout, waitUntil=waitUntil
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
async def waitForNavigation(
|
|
85
|
-
self, timeout: Optional[float] = None, waitUntil: Optional[WaitTargets] = None
|
|
86
|
-
) -> Optional[Response]:
|
|
87
|
-
return await self._frameManager.waitForFrameNavigation(self, waitUntil=waitUntil, timeout=timeout)
|
|
88
|
-
|
|
89
|
-
@property
|
|
90
|
-
def mainWorld(self) -> 'DOMWorld': # ensure mainWorld not settable
|
|
91
|
-
return self._mainWorld
|
|
92
|
-
|
|
93
|
-
@property
|
|
94
|
-
def secondaryWorld(self) -> 'DOMWorld': # ensure secondaryWorld is not settable
|
|
95
|
-
return self._secondaryWorld
|
|
96
|
-
|
|
97
|
-
@property
|
|
98
|
-
def name(self) -> str:
|
|
99
|
-
"""Get frame name."""
|
|
100
|
-
return getattr(self, '_name', '')
|
|
101
|
-
|
|
102
|
-
@property
|
|
103
|
-
def url(self) -> str:
|
|
104
|
-
"""Get url of the frame."""
|
|
105
|
-
return self._url
|
|
106
|
-
|
|
107
|
-
@property
|
|
108
|
-
def parentFrame(self) -> Optional['Frame']:
|
|
109
|
-
"""Get parent frame.
|
|
110
|
-
|
|
111
|
-
If this frame is main frame or detached frame, return ``None``.
|
|
112
|
-
"""
|
|
113
|
-
return self._parentFrame
|
|
114
|
-
|
|
115
|
-
@property
|
|
116
|
-
def childFrames(self) -> List['Frame']:
|
|
117
|
-
"""Get child frames."""
|
|
118
|
-
return list(self._childFrames)
|
|
119
|
-
|
|
120
|
-
@property
|
|
121
|
-
def isDetached(self) -> bool:
|
|
122
|
-
"""Return ``True`` if this frame is detached.
|
|
123
|
-
|
|
124
|
-
Otherwise return ``False``.
|
|
125
|
-
"""
|
|
126
|
-
return self._detached
|
|
127
|
-
|
|
128
|
-
async def addScriptTag(
|
|
129
|
-
self,
|
|
130
|
-
url: Optional[str] = None,
|
|
131
|
-
path: Optional[Union[str, Path]] = None,
|
|
132
|
-
content: Optional[str] = None,
|
|
133
|
-
type_: str = '',
|
|
134
|
-
) -> ElementHandle:
|
|
135
|
-
"""Add script tag to this frame.
|
|
136
|
-
|
|
137
|
-
Details see :meth:`pyppeteer.page.Page.addScriptTag`.
|
|
138
|
-
"""
|
|
139
|
-
return await self._mainWorld.addScriptTag(url=url, path=path, content=content, type_=type_)
|
|
140
|
-
|
|
141
|
-
async def addStyleTag(
|
|
142
|
-
self, url: Optional[str] = None, path: Optional[Union[str, Path]] = None, content: Optional[str] = None
|
|
143
|
-
) -> Optional['ElementHandle']:
|
|
144
|
-
return await self._mainWorld.addStyleTag(url=url, path=path, content=content)
|
|
145
|
-
|
|
146
|
-
async def focus(self, selector: str) -> None:
|
|
147
|
-
"""Focus element which matches ``selector``.
|
|
148
|
-
|
|
149
|
-
Details see :meth:`pyppeteer.page.Page.focus`.
|
|
150
|
-
"""
|
|
151
|
-
handle = await self.J(selector)
|
|
152
|
-
if not handle:
|
|
153
|
-
raise PageError('No node found for selector: ' + selector)
|
|
154
|
-
await self.evaluate('element => element.focus()', handle)
|
|
155
|
-
await handle.dispose()
|
|
156
|
-
|
|
157
|
-
async def hover(self, selector: str) -> None:
|
|
158
|
-
"""Mouse hover the element which matches ``selector``.
|
|
159
|
-
|
|
160
|
-
Details see :meth:`pyppeteer.page.Page.hover`.
|
|
161
|
-
"""
|
|
162
|
-
handle = await self.J(selector)
|
|
163
|
-
if not handle:
|
|
164
|
-
raise PageError('No node found for selector: ' + selector)
|
|
165
|
-
await handle.hover()
|
|
166
|
-
await handle.dispose()
|
|
167
|
-
|
|
168
|
-
async def select(self, selector: str, *values: str) -> List[str]:
|
|
169
|
-
"""Select options and return selected values.
|
|
170
|
-
|
|
171
|
-
Details see :meth:`pyppeteer.page.Page.select`.
|
|
172
|
-
"""
|
|
173
|
-
for index, value in values:
|
|
174
|
-
if not isinstance(value, str):
|
|
175
|
-
raise TypeError(f'Values must be string. Found {value} of type {type(value)} at index {index}')
|
|
176
|
-
return await self.querySelectorEval( # type: ignore
|
|
177
|
-
selector,
|
|
178
|
-
'''
|
|
179
|
-
(element, values) => {
|
|
180
|
-
if (element.nodeName.toLowerCase() !== 'select')
|
|
181
|
-
throw new Error('Element is not a <select> element.');
|
|
182
|
-
|
|
183
|
-
const options = Array.from(element.options);
|
|
184
|
-
element.value = undefined;
|
|
185
|
-
for (const option of options) {
|
|
186
|
-
option.selected = values.includes(option.value);
|
|
187
|
-
if (option.selected && !element.multiple)
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
element.dispatchEvent(new Event('input', { 'bubbles': true }));
|
|
192
|
-
element.dispatchEvent(new Event('change', { 'bubbles': true }));
|
|
193
|
-
return options.filter(option => option.selected).map(options => options.value)
|
|
194
|
-
}
|
|
195
|
-
''',
|
|
196
|
-
*values,
|
|
197
|
-
)
|
|
198
|
-
|
|
199
|
-
async def tap(self, selector: str) -> None:
|
|
200
|
-
"""Tap the element which matches the ``selector``.
|
|
201
|
-
|
|
202
|
-
Details see :meth:`pyppeteer.page.Page.tap`.
|
|
203
|
-
"""
|
|
204
|
-
handle = await self.J(selector)
|
|
205
|
-
if not handle:
|
|
206
|
-
raise PageError('No node found for selector: ' + selector)
|
|
207
|
-
await handle.tap()
|
|
208
|
-
await handle.dispose()
|
|
209
|
-
|
|
210
|
-
async def type(self, selector: str, text: str, delay: float = 0) -> None:
|
|
211
|
-
"""Type ``text`` on the element which matches ``selector``.
|
|
212
|
-
|
|
213
|
-
Details see :meth:`pyppeteer.page.Page.type`.
|
|
214
|
-
"""
|
|
215
|
-
handle = await self.querySelector(selector)
|
|
216
|
-
if handle is None:
|
|
217
|
-
raise PageError(f'Cannot find {selector} on this page')
|
|
218
|
-
await handle.type(text, delay)
|
|
219
|
-
await handle.dispose()
|
|
220
|
-
|
|
221
|
-
def waitFor(
|
|
222
|
-
self, selectorOrFunctionOrTimeout: Union[str, int, float], *args: JSFunctionArg, **kwargs: Any
|
|
223
|
-
) -> Awaitable[Optional[JSHandle]]:
|
|
224
|
-
"""Wait until `selectorOrFunctionOrTimeout`.
|
|
225
|
-
|
|
226
|
-
Details see :meth:`pyppeteer.page.Page.waitFor`.
|
|
227
|
-
"""
|
|
228
|
-
xPathPattern = '//'
|
|
229
|
-
if helpers.is_js_func(selectorOrFunctionOrTimeout):
|
|
230
|
-
return self.waitForFunction(selectorOrFunctionOrTimeout, *args, **kwargs)
|
|
231
|
-
if isinstance(selectorOrFunctionOrTimeout, str):
|
|
232
|
-
string = selectorOrFunctionOrTimeout
|
|
233
|
-
if string.startswith(xPathPattern):
|
|
234
|
-
return self.waitForXPath(string, **kwargs)
|
|
235
|
-
return self.waitForSelector(string, **kwargs)
|
|
236
|
-
if isinstance(selectorOrFunctionOrTimeout, (int, float)):
|
|
237
|
-
return self._client.loop.create_task(asyncio.sleep(selectorOrFunctionOrTimeout / 1000))
|
|
238
|
-
f = self._client.loop.create_future()
|
|
239
|
-
f.set_exception(BrowserError(f'Unsupported target type: {type(selectorOrFunctionOrTimeout)}'))
|
|
240
|
-
return f
|
|
241
|
-
|
|
242
|
-
async def waitForSelector(
|
|
243
|
-
self, selector: str, visible: bool = False, hidden: bool = False, timeout: float = None
|
|
244
|
-
) -> Optional['ElementHandle']:
|
|
245
|
-
"""Wait until element which matches ``selector`` appears on page.
|
|
246
|
-
|
|
247
|
-
Details see :meth:`pyppeteer.page.Page.waitForSelector`.
|
|
248
|
-
"""
|
|
249
|
-
handle = await self._secondaryWorld.waitForSelector(selector, visible=visible, hidden=hidden, timeout=timeout)
|
|
250
|
-
if handle:
|
|
251
|
-
mainExecutionContext = await self._mainWorld.executionContext
|
|
252
|
-
result = await mainExecutionContext._adoptElementHandle(handle)
|
|
253
|
-
await handle.dispose()
|
|
254
|
-
return result
|
|
255
|
-
|
|
256
|
-
async def waitForXPath(
|
|
257
|
-
self, xpath: str, visible: bool = False, hidden: bool = False, timeout: int = None
|
|
258
|
-
) -> Optional['ElementHandle']:
|
|
259
|
-
"""Wait until element which matches ``xpath`` appears on page.
|
|
260
|
-
|
|
261
|
-
Details see :meth:`pyppeteer.page.Page.waitForXPath`.
|
|
262
|
-
"""
|
|
263
|
-
handle = await self._secondaryWorld.waitForXpath(xpath, visible=visible, hidden=hidden, timeout=timeout)
|
|
264
|
-
if not handle:
|
|
265
|
-
return None
|
|
266
|
-
mainExecutionContext = await self._mainWorld.executionContext
|
|
267
|
-
result = await mainExecutionContext._adoptElementHandle(handle)
|
|
268
|
-
await handle.dispose()
|
|
269
|
-
return result
|
|
270
|
-
|
|
271
|
-
def _navigated(self, framePayload: dict) -> None:
|
|
272
|
-
self._name = framePayload.get('name', '')
|
|
273
|
-
self._navigationURL = framePayload.get('url', '')
|
|
274
|
-
self._url = framePayload.get('url', '')
|
|
275
|
-
|
|
276
|
-
def _navigatedWithinDocument(self, url: str) -> None:
|
|
277
|
-
self._url = url
|
|
278
|
-
|
|
279
|
-
def _onLifecycleEvent(self, loaderId: str, name: str) -> None:
|
|
280
|
-
if name == 'init':
|
|
281
|
-
self._loaderId = loaderId
|
|
282
|
-
self._lifecycleEvents.clear()
|
|
283
|
-
else:
|
|
284
|
-
self._lifecycleEvents.add(name)
|
|
285
|
-
|
|
286
|
-
def _onLoadingStopped(self) -> None:
|
|
287
|
-
self._lifecycleEvents.add('DOMContentLoaded')
|
|
288
|
-
self._lifecycleEvents.add('load')
|
|
289
|
-
|
|
290
|
-
def _detach(self) -> None:
|
|
291
|
-
self._detached = True
|
|
292
|
-
self.mainWorld._detach()
|
|
293
|
-
self.secondaryWorld._detach()
|
|
294
|
-
if self._parentFrame:
|
|
295
|
-
self._parentFrame._childFrames.remove(self)
|
|
296
|
-
self._parentFrame = None
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
from biolib.pyppeteer.pyppeteer.frame.frame_manager import FrameManager # isort:skip
|