From 68216153f3d1459c5f1e649697c9f20d07b7a2e4 Mon Sep 17 00:00:00 2001 From: daijro Date: Sun, 3 Nov 2024 05:55:34 -0600 Subject: [PATCH] Add Playwright tests Adds Playwright's async tests to ensure that functionality is not broken. --- .gitattributes | 3 +- .gitignore | 7 +- Makefile | 9 +- tests/README.md | 41 + tests/__init__.py | 0 tests/assets/beforeunload.html | 9 + tests/assets/client-certificates/README.md | 60 + .../client/self-signed/cert.pem | 28 + .../client/self-signed/csr.pem | 26 + .../client/self-signed/key.pem | 52 + .../client/trusted/cert.pem | 29 + .../client/trusted/csr.pem | 26 + .../client/trusted/key.pem | 52 + .../server/server_cert.pem | 32 + .../client-certificates/server/server_key.pem | 52 + tests/assets/client.py | 34 + tests/assets/consolelog.html | 11 + tests/assets/csp.html | 1 + tests/assets/digits/0.png | Bin 0 -> 434 bytes tests/assets/digits/1.png | Bin 0 -> 346 bytes tests/assets/digits/2.png | Bin 0 -> 413 bytes tests/assets/digits/3.png | Bin 0 -> 434 bytes tests/assets/digits/4.png | Bin 0 -> 403 bytes tests/assets/digits/5.png | Bin 0 -> 422 bytes tests/assets/digits/6.png | Bin 0 -> 445 bytes tests/assets/digits/7.png | Bin 0 -> 387 bytes tests/assets/digits/8.png | Bin 0 -> 447 bytes tests/assets/digits/9.png | Bin 0 -> 437 bytes tests/assets/dom.html | 4 + tests/assets/download-blob.html | 29 + tests/assets/drag-n-drop.html | 40 + tests/assets/dummy_bad_browser_executable.js | 3 + tests/assets/empty.html | 0 tests/assets/error.html | 17 + tests/assets/es6/.eslintrc | 5 + tests/assets/es6/es6import.js | 2 + tests/assets/es6/es6module.js | 1 + tests/assets/es6/es6pathimport.js | 2 + tests/assets/file-to-upload-2.txt | 1 + tests/assets/file-to-upload.txt | 1 + tests/assets/frames/child-redirect.html | 1 + tests/assets/frames/frame.html | 15 + tests/assets/frames/frameset.html | 8 + tests/assets/frames/nested-frames.html | 30 + tests/assets/frames/one-frame.html | 1 + tests/assets/frames/redirect-my-parent.html | 3 + tests/assets/frames/script.js | 1 + tests/assets/frames/style.css | 3 + tests/assets/frames/two-frames.html | 16 + tests/assets/geolocation.html | 7 + tests/assets/global-var.html | 3 + tests/assets/grid.html | 52 + tests/assets/har-fulfill.har | 366 +++++ tests/assets/har-redirect.har | 620 ++++++++ tests/assets/har-sha1-main-response.txt | 1 + tests/assets/har-sha1.har | 95 ++ tests/assets/har.html | 3 + tests/assets/headings.html | 15 + tests/assets/historyapi.html | 5 + tests/assets/injectedfile.js | 3 + tests/assets/injectedstyle.css | 3 + tests/assets/input/animating-button.html | 42 + tests/assets/input/button.html | 32 + tests/assets/input/checkbox.html | 42 + tests/assets/input/fileupload-multi.html | 12 + tests/assets/input/fileupload.html | 12 + tests/assets/input/folderupload.html | 12 + tests/assets/input/handle-locator.html | 91 ++ tests/assets/input/keyboard.html | 42 + tests/assets/input/mouse-helper.js | 62 + tests/assets/input/rotatedButton.html | 21 + tests/assets/input/scrollable.html | 23 + tests/assets/input/select.html | 69 + tests/assets/input/textarea.html | 20 + tests/assets/input/touches.html | 35 + tests/assets/mobile.html | 1 + tests/assets/networkidle.html | 1 + tests/assets/networkidle.js | 12 + tests/assets/offscreenbuttons.html | 55 + tests/assets/one-style.css | 3 + tests/assets/one-style.html | 2 + tests/assets/playground.html | 15 + tests/assets/popup/popup.html | 12 + tests/assets/popup/window-open.html | 11 + tests/assets/pptr.png | Bin 0 -> 6138 bytes tests/assets/react.html | 33 + .../react/react-dom@16.13.1.production.min.js | 239 +++ .../react/react@16.13.1.production.min.js | 32 + tests/assets/sectionselectorengine.js | 10 + tests/assets/self-request.html | 5 + tests/assets/serviceworkers/empty/sw.html | 3 + tests/assets/serviceworkers/empty/sw.js | 0 tests/assets/serviceworkers/fetch/style.css | 3 + tests/assets/serviceworkers/fetch/sw.html | 5 + tests/assets/serviceworkers/fetch/sw.js | 7 + .../assets/serviceworkers/fetchdummy/sw.html | 12 + tests/assets/serviceworkers/fetchdummy/sw.js | 15 + tests/assets/shadow.html | 17 + .../assets/simple-extension/content-script.js | 2 + tests/assets/simple-extension/index.js | 2 + tests/assets/simple-extension/manifest.json | 14 + tests/assets/simple.json | 1 + tests/assets/title.html | 1 + tests/assets/worker/worker.html | 14 + tests/assets/worker/worker.js | 16 + tests/assets/wrappedlink.html | 32 + tests/async/__init__.py | 0 tests/async/conftest.py | 139 ++ tests/async/test_accessibility.py | 383 +++++ tests/async/test_add_init_script.py | 98 ++ tests/async/test_assertions.py | 810 ++++++++++ tests/async/test_asyncio.py | 69 + tests/async/test_browser.py | 53 + tests/async/test_browsercontext.py | 794 ++++++++++ .../async/test_browsercontext_add_cookies.py | 413 +++++ .../async/test_browsercontext_clearcookies.py | 194 +++ ...sercontext_client_certificates.py.disabled | 227 +++ tests/async/test_browsercontext_cookies.py | 229 +++ tests/async/test_browsercontext_events.py | 193 +++ tests/async/test_browsercontext_proxy.py | 135 ++ .../test_browsercontext_request_fallback.py | 288 ++++ .../test_browsercontext_request_intercept.py | 192 +++ tests/async/test_browsercontext_route.py | 490 ++++++ ...st_browsercontext_service_worker_policy.py | 36 + .../test_browsercontext_storage_state.py | 112 ++ tests/async/test_browsertype_connect.py | 458 ++++++ tests/async/test_browsertype_connect_cdp.py | 117 ++ tests/async/test_cdp_session.py | 93 ++ tests/async/test_check.py.disabled | 85 ++ tests/async/test_click.py.disabled | 1113 ++++++++++++++ tests/async/test_console.py | 152 ++ tests/async/test_context_manager.py | 36 + tests/async/test_defaultbrowsercontext.py | 438 ++++++ tests/async/test_device_descriptors.py | 54 + tests/async/test_dialog.py | 102 ++ tests/async/test_dispatch_event.py.disabled | 191 +++ tests/async/test_download.py | 376 +++++ tests/async/test_element_handle.py.disabled | 754 +++++++++ ...t_element_handle_wait_for_element_state.py | 156 ++ tests/async/test_emulation_focus.py | 173 +++ tests/async/test_expect_misc.py | 76 + tests/async/test_fetch_browser_context.py | 314 ++++ tests/async/test_fetch_global.py | 472 ++++++ tests/async/test_fill.py.disabled | 31 + tests/async/test_focus.py.disabled | 110 ++ tests/async/test_frames.py | 280 ++++ tests/async/test_geolocation.py | 136 ++ tests/async/test_har.py | 750 +++++++++ tests/async/test_headful.py | 178 +++ tests/async/test_ignore_https_errors.py | 37 + tests/async/test_input.py | 500 ++++++ tests/async/test_issues.py | 53 + tests/async/test_jshandle.py | 231 +++ tests/async/test_keyboard.py | 525 +++++++ tests/async/test_launcher.py.disabled | 145 ++ tests/async/test_listeners.py | 32 + tests/async/test_locators.py | 1039 +++++++++++++ tests/async/test_navigation.py | 1057 +++++++++++++ tests/async/test_network.py | 879 +++++++++++ tests/async/test_page.py | 1358 +++++++++++++++++ tests/async/test_page_add_locator_handler.py | 377 +++++ tests/async/test_page_base_url.py | 114 ++ tests/async/test_page_clock.py | 462 ++++++ tests/async/test_page_evaluate.py | 320 ++++ tests/async/test_page_network_request.py | 61 + tests/async/test_page_network_response.py | 70 + tests/async/test_page_request_fallback.py | 352 +++++ tests/async/test_page_request_intercept.py | 95 ++ tests/async/test_page_route.py | 1059 +++++++++++++ tests/async/test_page_select_option.py | 214 +++ tests/async/test_pdf.py | 43 + tests/async/test_popup.py.disabled | 448 ++++++ tests/async/test_proxy.py | 131 ++ tests/async/test_queryselector.py | 352 +++++ tests/async/test_request_continue.py | 186 +++ tests/async/test_request_fulfill.py | 71 + tests/async/test_request_intercept.py | 171 +++ tests/async/test_resource_timing.py | 106 ++ tests/async/test_screenshot.py | 44 + tests/async/test_selector_generator.py | 48 + tests/async/test_selectors_get_by.py | 176 +++ tests/async/test_selectors_misc.py | 54 + tests/async/test_selectors_text.py | 210 +++ tests/async/test_tap.py | 237 +++ tests/async/test_tracing.py | 285 ++++ tests/async/test_unroute_behavior.py | 453 ++++++ tests/async/test_video.py | 82 + tests/async/test_wait_for_function.py | 91 ++ tests/async/test_wait_for_url.py | 130 ++ tests/async/test_websocket.py | 193 +++ tests/async/test_worker.py | 191 +++ tests/async/utils.py | 75 + tests/async_imp/__init__.py | 0 tests/async_imp/conftest.py | 139 ++ tests/async_imp/test_frames.py | 280 ++++ tests/async_imp/utils.py | 75 + tests/conftest.py | 302 ++++ tests/golden-firefox/grid-cell-0.png | Bin 0 -> 331 bytes .../mask-should-work-with-element-handle.png | Bin 0 -> 98144 bytes .../mask-should-work-with-locator.png | Bin 0 -> 98144 bytes .../mask-should-work-with-page.png | Bin 0 -> 45962 bytes tests/golden-firefox/mock-binary-response.png | Bin 0 -> 6001 bytes tests/golden-firefox/mock-svg.png | Bin 0 -> 206 bytes .../screenshot-element-bounding-box.png | Bin 0 -> 311 bytes tests/golden-firefox/screenshot-sanity.png | Bin 0 -> 36252 bytes tests/local-requirements.txt | 25 + tests/pyproject.toml | 19 + tests/run-tests.sh | 77 + tests/server.py | 299 ++++ tests/setup-venv.sh | 7 + tests/testserver/cert.pem | 28 + tests/testserver/key.pem | 52 + tests/utils.py | 78 + 213 files changed, 28551 insertions(+), 5 deletions(-) create mode 100644 tests/README.md create mode 100644 tests/__init__.py create mode 100644 tests/assets/beforeunload.html create mode 100644 tests/assets/client-certificates/README.md create mode 100644 tests/assets/client-certificates/client/self-signed/cert.pem create mode 100644 tests/assets/client-certificates/client/self-signed/csr.pem create mode 100644 tests/assets/client-certificates/client/self-signed/key.pem create mode 100644 tests/assets/client-certificates/client/trusted/cert.pem create mode 100644 tests/assets/client-certificates/client/trusted/csr.pem create mode 100644 tests/assets/client-certificates/client/trusted/key.pem create mode 100644 tests/assets/client-certificates/server/server_cert.pem create mode 100644 tests/assets/client-certificates/server/server_key.pem create mode 100644 tests/assets/client.py create mode 100644 tests/assets/consolelog.html create mode 100644 tests/assets/csp.html create mode 100644 tests/assets/digits/0.png create mode 100644 tests/assets/digits/1.png create mode 100644 tests/assets/digits/2.png create mode 100644 tests/assets/digits/3.png create mode 100644 tests/assets/digits/4.png create mode 100644 tests/assets/digits/5.png create mode 100644 tests/assets/digits/6.png create mode 100644 tests/assets/digits/7.png create mode 100644 tests/assets/digits/8.png create mode 100644 tests/assets/digits/9.png create mode 100644 tests/assets/dom.html create mode 100644 tests/assets/download-blob.html create mode 100644 tests/assets/drag-n-drop.html create mode 100755 tests/assets/dummy_bad_browser_executable.js create mode 100644 tests/assets/empty.html create mode 100644 tests/assets/error.html create mode 100644 tests/assets/es6/.eslintrc create mode 100644 tests/assets/es6/es6import.js create mode 100644 tests/assets/es6/es6module.js create mode 100644 tests/assets/es6/es6pathimport.js create mode 100644 tests/assets/file-to-upload-2.txt create mode 100644 tests/assets/file-to-upload.txt create mode 100644 tests/assets/frames/child-redirect.html create mode 100644 tests/assets/frames/frame.html create mode 100644 tests/assets/frames/frameset.html create mode 100644 tests/assets/frames/nested-frames.html create mode 100644 tests/assets/frames/one-frame.html create mode 100644 tests/assets/frames/redirect-my-parent.html create mode 100644 tests/assets/frames/script.js create mode 100644 tests/assets/frames/style.css create mode 100644 tests/assets/frames/two-frames.html create mode 100644 tests/assets/geolocation.html create mode 100644 tests/assets/global-var.html create mode 100644 tests/assets/grid.html create mode 100644 tests/assets/har-fulfill.har create mode 100644 tests/assets/har-redirect.har create mode 100644 tests/assets/har-sha1-main-response.txt create mode 100644 tests/assets/har-sha1.har create mode 100644 tests/assets/har.html create mode 100644 tests/assets/headings.html create mode 100644 tests/assets/historyapi.html create mode 100644 tests/assets/injectedfile.js create mode 100644 tests/assets/injectedstyle.css create mode 100644 tests/assets/input/animating-button.html create mode 100644 tests/assets/input/button.html create mode 100644 tests/assets/input/checkbox.html create mode 100644 tests/assets/input/fileupload-multi.html create mode 100644 tests/assets/input/fileupload.html create mode 100644 tests/assets/input/folderupload.html create mode 100644 tests/assets/input/handle-locator.html create mode 100644 tests/assets/input/keyboard.html create mode 100644 tests/assets/input/mouse-helper.js create mode 100644 tests/assets/input/rotatedButton.html create mode 100644 tests/assets/input/scrollable.html create mode 100644 tests/assets/input/select.html create mode 100644 tests/assets/input/textarea.html create mode 100644 tests/assets/input/touches.html create mode 100644 tests/assets/mobile.html create mode 100644 tests/assets/networkidle.html create mode 100644 tests/assets/networkidle.js create mode 100644 tests/assets/offscreenbuttons.html create mode 100644 tests/assets/one-style.css create mode 100644 tests/assets/one-style.html create mode 100644 tests/assets/playground.html create mode 100644 tests/assets/popup/popup.html create mode 100644 tests/assets/popup/window-open.html create mode 100644 tests/assets/pptr.png create mode 100644 tests/assets/react.html create mode 100644 tests/assets/react/react-dom@16.13.1.production.min.js create mode 100644 tests/assets/react/react@16.13.1.production.min.js create mode 100644 tests/assets/sectionselectorengine.js create mode 100644 tests/assets/self-request.html create mode 100644 tests/assets/serviceworkers/empty/sw.html create mode 100644 tests/assets/serviceworkers/empty/sw.js create mode 100644 tests/assets/serviceworkers/fetch/style.css create mode 100644 tests/assets/serviceworkers/fetch/sw.html create mode 100644 tests/assets/serviceworkers/fetch/sw.js create mode 100644 tests/assets/serviceworkers/fetchdummy/sw.html create mode 100644 tests/assets/serviceworkers/fetchdummy/sw.js create mode 100644 tests/assets/shadow.html create mode 100644 tests/assets/simple-extension/content-script.js create mode 100644 tests/assets/simple-extension/index.js create mode 100644 tests/assets/simple-extension/manifest.json create mode 100644 tests/assets/simple.json create mode 100644 tests/assets/title.html create mode 100644 tests/assets/worker/worker.html create mode 100644 tests/assets/worker/worker.js create mode 100644 tests/assets/wrappedlink.html create mode 100644 tests/async/__init__.py create mode 100644 tests/async/conftest.py create mode 100644 tests/async/test_accessibility.py create mode 100644 tests/async/test_add_init_script.py create mode 100644 tests/async/test_assertions.py create mode 100644 tests/async/test_asyncio.py create mode 100644 tests/async/test_browser.py create mode 100644 tests/async/test_browsercontext.py create mode 100644 tests/async/test_browsercontext_add_cookies.py create mode 100644 tests/async/test_browsercontext_clearcookies.py create mode 100644 tests/async/test_browsercontext_client_certificates.py.disabled create mode 100644 tests/async/test_browsercontext_cookies.py create mode 100644 tests/async/test_browsercontext_events.py create mode 100644 tests/async/test_browsercontext_proxy.py create mode 100644 tests/async/test_browsercontext_request_fallback.py create mode 100644 tests/async/test_browsercontext_request_intercept.py create mode 100644 tests/async/test_browsercontext_route.py create mode 100644 tests/async/test_browsercontext_service_worker_policy.py create mode 100644 tests/async/test_browsercontext_storage_state.py create mode 100644 tests/async/test_browsertype_connect.py create mode 100644 tests/async/test_browsertype_connect_cdp.py create mode 100644 tests/async/test_cdp_session.py create mode 100644 tests/async/test_check.py.disabled create mode 100644 tests/async/test_click.py.disabled create mode 100644 tests/async/test_console.py create mode 100644 tests/async/test_context_manager.py create mode 100644 tests/async/test_defaultbrowsercontext.py create mode 100644 tests/async/test_device_descriptors.py create mode 100644 tests/async/test_dialog.py create mode 100644 tests/async/test_dispatch_event.py.disabled create mode 100644 tests/async/test_download.py create mode 100644 tests/async/test_element_handle.py.disabled create mode 100644 tests/async/test_element_handle_wait_for_element_state.py create mode 100644 tests/async/test_emulation_focus.py create mode 100644 tests/async/test_expect_misc.py create mode 100644 tests/async/test_fetch_browser_context.py create mode 100644 tests/async/test_fetch_global.py create mode 100644 tests/async/test_fill.py.disabled create mode 100644 tests/async/test_focus.py.disabled create mode 100644 tests/async/test_frames.py create mode 100644 tests/async/test_geolocation.py create mode 100644 tests/async/test_har.py create mode 100644 tests/async/test_headful.py create mode 100644 tests/async/test_ignore_https_errors.py create mode 100644 tests/async/test_input.py create mode 100644 tests/async/test_issues.py create mode 100644 tests/async/test_jshandle.py create mode 100644 tests/async/test_keyboard.py create mode 100644 tests/async/test_launcher.py.disabled create mode 100644 tests/async/test_listeners.py create mode 100644 tests/async/test_locators.py create mode 100644 tests/async/test_navigation.py create mode 100644 tests/async/test_network.py create mode 100644 tests/async/test_page.py create mode 100644 tests/async/test_page_add_locator_handler.py create mode 100644 tests/async/test_page_base_url.py create mode 100644 tests/async/test_page_clock.py create mode 100644 tests/async/test_page_evaluate.py create mode 100644 tests/async/test_page_network_request.py create mode 100644 tests/async/test_page_network_response.py create mode 100644 tests/async/test_page_request_fallback.py create mode 100644 tests/async/test_page_request_intercept.py create mode 100644 tests/async/test_page_route.py create mode 100644 tests/async/test_page_select_option.py create mode 100644 tests/async/test_pdf.py create mode 100644 tests/async/test_popup.py.disabled create mode 100644 tests/async/test_proxy.py create mode 100644 tests/async/test_queryselector.py create mode 100644 tests/async/test_request_continue.py create mode 100644 tests/async/test_request_fulfill.py create mode 100644 tests/async/test_request_intercept.py create mode 100644 tests/async/test_resource_timing.py create mode 100644 tests/async/test_screenshot.py create mode 100644 tests/async/test_selector_generator.py create mode 100644 tests/async/test_selectors_get_by.py create mode 100644 tests/async/test_selectors_misc.py create mode 100644 tests/async/test_selectors_text.py create mode 100644 tests/async/test_tap.py create mode 100644 tests/async/test_tracing.py create mode 100644 tests/async/test_unroute_behavior.py create mode 100644 tests/async/test_video.py create mode 100644 tests/async/test_wait_for_function.py create mode 100644 tests/async/test_wait_for_url.py create mode 100644 tests/async/test_websocket.py create mode 100644 tests/async/test_worker.py create mode 100644 tests/async/utils.py create mode 100644 tests/async_imp/__init__.py create mode 100644 tests/async_imp/conftest.py create mode 100644 tests/async_imp/test_frames.py create mode 100644 tests/async_imp/utils.py create mode 100644 tests/conftest.py create mode 100644 tests/golden-firefox/grid-cell-0.png create mode 100644 tests/golden-firefox/mask-should-work-with-element-handle.png create mode 100644 tests/golden-firefox/mask-should-work-with-locator.png create mode 100644 tests/golden-firefox/mask-should-work-with-page.png create mode 100644 tests/golden-firefox/mock-binary-response.png create mode 100644 tests/golden-firefox/mock-svg.png create mode 100644 tests/golden-firefox/screenshot-element-bounding-box.png create mode 100644 tests/golden-firefox/screenshot-sanity.png create mode 100644 tests/local-requirements.txt create mode 100644 tests/pyproject.toml create mode 100644 tests/run-tests.sh create mode 100644 tests/server.py create mode 100644 tests/setup-venv.sh create mode 100644 tests/testserver/cert.pem create mode 100644 tests/testserver/key.pem create mode 100644 tests/utils.py diff --git a/.gitattributes b/.gitattributes index 94f480d..06e0503 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,2 @@ -* text=auto eol=lf \ No newline at end of file +* text=auto eol=lf +tests/** linguist-detectable=false diff --git a/.gitignore b/.gitignore index 5ee8d0f..b7a9961 100644 --- a/.gitignore +++ b/.gitignore @@ -9,16 +9,17 @@ launch.exe # Internal testing /extra-docs -/tests +pythonlib/test* /.vscode /bundle/fonts/extra pythonlib/*.png scripts/*.png -test* .vscode +/tests/*.disabled # Old data _old/ +_old_*/ *.old # Logs @@ -30,4 +31,4 @@ wget-log venv/ __pycache__/ *.pyc -*.mmdb \ No newline at end of file +*.mmdb diff --git a/Makefile b/Makefile index 0ee143c..e324840 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ pacman := python python-pip p7zip go msitools wget aria2 .PHONY: help fetch setup setup-minimal clean set-target distclean build package \ build-launcher check-arch revert edits run bootstrap mozbootstrap dir \ package-linux package-macos package-windows vcredist_arch patch unpatch \ - workspace check-arg edit-cfg ff-dbg + workspace check-arg edit-cfg ff-dbg tests help: @echo "Available targets:" @@ -36,6 +36,7 @@ help: @echo " patch - Apply a patch" @echo " unpatch - Remove a patch" @echo " workspace - Sets the workspace to a patch, assuming its applied" + @echo " tests - Runs the Playwright tests" _ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)) $(eval $(_ARGS):;@:) @@ -210,4 +211,10 @@ workspace: make checkpoint || true make patch $(_ARGS) +tests: + cd ./tests && \ + bash run-tests.sh \ + --executable-path ../$(cf_source_dir)/obj-x86_64-pc-linux-gnu/dist/bin/camoufox-bin \ + $(if $(filter true,$(headful)),--headful,) + vcredist_arch := $(shell echo $(arch) | sed 's/x86_64/x64/' | sed 's/i686/x86/') diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..22f7b7b --- /dev/null +++ b/tests/README.md @@ -0,0 +1,41 @@ +# Camoufox Tests + +Ensures that Playwright functionality is not broken. + +--- + +This directory is based on the original Playwright-Python [tests](https://github.com/microsoft/playwright-python/tree/main/tests). + +It has been modified to skip tests that use the following features: + +- Injecting JavaScript into the page or writing to DOM. Camoufox's `page.evaluate` only supports reading values, not executing within the page context. +- Overriding the User-Agent. +- Any tests specific to Chromium or Webkit. + +--- + +# Usage + +### Setting up the environment + +Cd to this directory and run the following command to setup the venv and install the dependencies: + +```bash +bash setup-venv.sh +``` + +### Running the tests + +Run via the shell script: + +```bash +bash run-tests.sh --headful --executable-path /path/to/camoufox-bin +``` + +Or through the Makefile: + +```bash +make tests headful=true +``` + +--- \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/assets/beforeunload.html b/tests/assets/beforeunload.html new file mode 100644 index 0000000..aff6a50 --- /dev/null +++ b/tests/assets/beforeunload.html @@ -0,0 +1,9 @@ +
beforeunload demo.
+ diff --git a/tests/assets/client-certificates/README.md b/tests/assets/client-certificates/README.md new file mode 100644 index 0000000..b0ee78e --- /dev/null +++ b/tests/assets/client-certificates/README.md @@ -0,0 +1,60 @@ +# Client Certificate test-certificates + +## Server + +```bash +openssl req \ + -x509 \ + -newkey rsa:4096 \ + -keyout server/server_key.pem \ + -out server/server_cert.pem \ + -nodes \ + -days 365 \ + -subj "/CN=localhost/O=Client\ Certificate\ Demo" \ + -addext "subjectAltName=DNS:localhost,DNS:local.playwright" +``` + +## Trusted client-certificate (server signed/valid) + +``` +mkdir -p client/trusted +# generate server-signed (valid) certifcate +openssl req \ + -newkey rsa:4096 \ + -keyout client/trusted/key.pem \ + -out client/trusted/csr.pem \ + -nodes \ + -days 365 \ + -subj "/CN=Alice" + +# sign with server_cert.pem +openssl x509 \ + -req \ + -in client/trusted/csr.pem \ + -CA server/server_cert.pem \ + -CAkey server/server_key.pem \ + -out client/trusted/cert.pem \ + -set_serial 01 \ + -days 365 +``` + +## Self-signed certificate (invalid) + +``` +mkdir -p client/self-signed +openssl req \ + -newkey rsa:4096 \ + -keyout client/self-signed/key.pem \ + -out client/self-signed/csr.pem \ + -nodes \ + -days 365 \ + -subj "/CN=Bob" + +# sign with self-signed/key.pem +openssl x509 \ + -req \ + -in client/self-signed/csr.pem \ + -signkey client/self-signed/key.pem \ + -out client/self-signed/cert.pem \ + -days 365 +``` diff --git a/tests/assets/client-certificates/client/self-signed/cert.pem b/tests/assets/client-certificates/client/self-signed/cert.pem new file mode 100644 index 0000000..3c07717 --- /dev/null +++ b/tests/assets/client-certificates/client/self-signed/cert.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIEyzCCArOgAwIBAgIUYps4gh4MqFYg8zqQhHYL7zYfbLkwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDQm9iMB4XDTI0MDcxOTEyNDc0MFoXDTI1MDcxOTEyNDc0 +MFowDjEMMAoGA1UEAwwDQm9iMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC +AgEA179eTsqcc1c3AOQHzCZEyYLPta2CCAscUFqcEZ9vWvjW0uzOv9TDlB33Unov +jch4CElZOBhzTadVsbmnYKpxwyVU89WCuQKvedz4k1vu7S1YryfNbmS8PWbnQ4ds +9NB7SgJNHZILvx9DXuWeFEyzRIo1984z4HheBzrkf791LqpYKaKziANUo8h8t0dm +TX/boOz8cEnQNwtTC0ZX3aD0obG/UAhr/22ZGPo/E659fh4ptyYX2LrIUHGy+Eux +nJ9Y4cTqa88Ee6K6AkDiT/AoNQNxE4X++jqLuie8j/ZYpI1Oll38GwKVOyy1msRL +toGmISNwkMIQDGABrJlxgpP4QQAQ+08v9srzXOlkdxdr7OCP81r+ccBXiSQEe7BA +kdJ8l98l5dprJ++GJ+SZcV4+/iGR0dKU2IdAG5HiKZIFn6ch9Ux+UMqeGaYCpkHr +TiietHwcXgtVBlE0jFmB/HspmI/O0abK+grMmueaH7XtTI8YHnw0mUpL8+yp7mfA +7zFusgFgyiBPXeD/NQgg8vja67k++d1VGoXm2xr+5WPQCSbgQoMkkOBMLHWJTefd +6F4Z5M+oI0VwYbf6eQW246wJgpCHSPR0Vdijd6MAGRWKUuLfDsA9+12iGbKvwJ2e +nJlStft2V2LZcjBfdIMbigW1aSVNN5w6m6YVrQPry3WPkWcCAwEAAaMhMB8wHQYD +VR0OBBYEFPxKWTFQJSg4HD2qjxL0dnXX/z4qMA0GCSqGSIb3DQEBCwUAA4ICAQBz +4H1d5eGRU9bekUvi7LbZ5CP/I6w6PL/9AlXqO3BZKxplK7fYGHd3uqyDorJEsvjV +hxwvFlEnS0JIU3nRzhJU/h4Yaivf1WLRFwGZ4TPBjX9KFU27exFWD3rppazkWybJ +i4WuEdP3TJMdKLcNTtXWUDroDOgPlS66u6oZ+mUyUROil+B+fgQgVDhjRc5fvRgZ +Lng8wuejCo3ExQyxkwn2G5guyIimgHmOQghPtLO5xlc67Z4GPUZ1m4tC+BCiFO4D +YIXl3QiIpmU7Pss39LLKMGXXAgLRqyMzqE52lsznu18v5vDLfTaRH4u/wjzULhXz +SrV1IUJmhgEXta4EeDmPH0itgKtkbwjgCOD7drrFrJq/EnvIaJ5cpxiI1pFmYD8g +VVD7/KT/CyT1Uz1dI8QaP/JX8XEgtMJaSkPfjPErIViN9rh9ECCNLgFyv7Y0Plar +A6YlvdyV1Rta/BHndf5Hqz9QWNhbFCMQRGVQNEcoKwpFyjAE9SXoKJvFIK/w5WXu +qKzIYA26QXE3p734Xu1n8QiFJIyltVHbyUlD0k06194t5a2WK+/eDeReIsk0QOI8 +FGqhyPZ7YjR5tSZTmgljtViqBO5AA23QOVFqtjOUrjXP5pTbPJel99Z/FTkqSwvB +Rt4OX7HfuokWQDTT0TMn5jVtJyi54cH7f9MmsNJ23g== +-----END CERTIFICATE----- diff --git a/tests/assets/client-certificates/client/self-signed/csr.pem b/tests/assets/client-certificates/client/self-signed/csr.pem new file mode 100644 index 0000000..4c99e13 --- /dev/null +++ b/tests/assets/client-certificates/client/self-signed/csr.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIEUzCCAjsCAQAwDjEMMAoGA1UEAwwDQm9iMIICIjANBgkqhkiG9w0BAQEFAAOC +Ag8AMIICCgKCAgEA179eTsqcc1c3AOQHzCZEyYLPta2CCAscUFqcEZ9vWvjW0uzO +v9TDlB33Unovjch4CElZOBhzTadVsbmnYKpxwyVU89WCuQKvedz4k1vu7S1YryfN +bmS8PWbnQ4ds9NB7SgJNHZILvx9DXuWeFEyzRIo1984z4HheBzrkf791LqpYKaKz +iANUo8h8t0dmTX/boOz8cEnQNwtTC0ZX3aD0obG/UAhr/22ZGPo/E659fh4ptyYX +2LrIUHGy+EuxnJ9Y4cTqa88Ee6K6AkDiT/AoNQNxE4X++jqLuie8j/ZYpI1Oll38 +GwKVOyy1msRLtoGmISNwkMIQDGABrJlxgpP4QQAQ+08v9srzXOlkdxdr7OCP81r+ +ccBXiSQEe7BAkdJ8l98l5dprJ++GJ+SZcV4+/iGR0dKU2IdAG5HiKZIFn6ch9Ux+ +UMqeGaYCpkHrTiietHwcXgtVBlE0jFmB/HspmI/O0abK+grMmueaH7XtTI8YHnw0 +mUpL8+yp7mfA7zFusgFgyiBPXeD/NQgg8vja67k++d1VGoXm2xr+5WPQCSbgQoMk +kOBMLHWJTefd6F4Z5M+oI0VwYbf6eQW246wJgpCHSPR0Vdijd6MAGRWKUuLfDsA9 ++12iGbKvwJ2enJlStft2V2LZcjBfdIMbigW1aSVNN5w6m6YVrQPry3WPkWcCAwEA +AaAAMA0GCSqGSIb3DQEBCwUAA4ICAQCb07d2IjUy1PeHCj/2k/z9FrZSo6K3c8y6 +b/u/MZ0AXPKLPDSo7UYpOJ8Z2cBiJ8jQapjTSEL8POUYqcvCmP55R6u68KmvINHo ++Ly7pP+xPrbA4Q0WmPnz37hQn+I1he0GuEQyjZZqUln9zwp67TsWNKxKtCH+1j8M +Ltzx6kuHCdPtDUtv291yhVRqvbjiDs+gzdQYNJtAkUbHwHFxu8oZhg8QZGyXYMN8 +TGoQ1LTezFZXJtX69K7WnrDGrjsgB6EMvwkqAFSYNH0LFvI0xo13OOgXr9mrwohA +76uZtjXL9B15EqrMce6mdUZi46QJuQ2avTi57Lz+fqvsBYdQO89VcFSmqu2nfspN +QZDrooyjHrlls8MpoBd8fde9oT4uA4/d9SJtuHUnjgGN7Qr7eTruWXL8wVMwFnvL +igWE4detO9y2gpRLq6uEqzWYMGtN9PXJCGU8C8m9E2EBUKMrT/bpNbboatLcgRrW +acj0BRVqoVzk1sRq7Sa6ejywqgARvIhTehg6DqdMdcENCPQ7rxDRu5PSDM8/mwIj +0KYl8d2PlECB4ofRyLcy17BZzjP6hSnkGzcFk0/bChZOSIRnwvKbvfXnB45hhPk8 +XwT/6UNSwC2STP3gtOmLqrWj+OE0gy0AkDMvP3UnQVGMUvgfYg+N4ROCVtlqzxe9 +W65c05Mm1g== +-----END CERTIFICATE REQUEST----- diff --git a/tests/assets/client-certificates/client/self-signed/key.pem b/tests/assets/client-certificates/client/self-signed/key.pem new file mode 100644 index 0000000..70d5e3d --- /dev/null +++ b/tests/assets/client-certificates/client/self-signed/key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +dg6m3MAyZ1IXjHlogOdmGvnq07/w +-----END PRIVATE KEY----- diff --git a/tests/assets/client-certificates/client/trusted/cert.pem b/tests/assets/client-certificates/client/trusted/cert.pem new file mode 100644 index 0000000..76d1e1a --- /dev/null +++ b/tests/assets/client-certificates/client/trusted/cert.pem @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIFAzCCAuugAwIBAgIBATANBgkqhkiG9w0BAQsFADA2MRIwEAYDVQQDDAlsb2Nh +bGhvc3QxIDAeBgNVBAoMF0NsaWVudCBDZXJ0aWZpY2F0ZSBEZW1vMB4XDTI0MDcx +OTEyNDczN1oXDTI1MDcxOTEyNDczN1owEDEOMAwGA1UEAwwFQWxpY2UwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCac3+4rNmH4/N1s4HqR2X168tgS/aA +6sHW5at8mWRnq54Nm11RvnK55jHQYVAdBgJy5M07w0wakp8inxzlY95wqxBimYG6 +3Un/1p7mX9FkB4LNISCc6j/s/Ufv85MXPbn0S5rm9UcQO9cINJb1RP1YgDDLN5cx +Mz6X4nyofN8H6Lhvh4JDdBw4DfDEFERkVfF+bkZ7YW4XHEChgzm3RxCF0eeGzIXG +rkkK9AsSdJAhOvTlHPFCQKXTYZhsL5+3Ma4RnWnDWvLTHx6KzoU+twTM2mYhhQuQ +gQpnmDHxGge8kGeHGtfdgAjtVJTE57xF/shP0JU+tuIV8NNhQ/vEmhL0Wa093/Ev +pTVp0EUEuDh9ORRH5K5M4bKJyU4XX5noiht6yOn00uaoJcWduUAWsU+cDSvDTMw8 +1opWWm0QIAV3G2yuRSkumHAKqvQLeyeyiKz+OEhyEiZ7EZNExPD0TSpApSTU6aCT +UAvPYGQ59VjsMHTuJ9r4wKIYaDvfL+t72vg2vTQma5cTOBJfIdxH9blFTjEnToH3 +LX8t0XndQ2RkiRnIze2p2jUShxo/lWCjCw+2Iaw0A0fNUK1BbOrFRPq1u7AnEuMJ +t7HF50MloItM97R9vofDwgDIzlX/PzlVRcn1WCo8Fr/0EXxPPreX0YDIp1ANQ8fS +v7bKb2vQIxWuCQIDAQABo0IwQDAdBgNVHQ4EFgQUVJVRJJ2k/Z4r0M1AXe6agyD4 +uCwwHwYDVR0jBBgwFoAUEHtrxWCk96Ehr60E0HBuwLk2i+IwDQYJKoZIhvcNAQEL +BQADggIBAGEvSkxhxRKmlvKG8wCXop2OaUUAOG16+T96vd+aFYaJNlfGoPvqv4Lw +qaHztVktnRrJ//fpNWOsdxkE1uPU4uyGjl2KbyH81JvkE6A3OX0P4B01n8lcimY2 +j3oje6KjORUouYVsypD1VcwfWJgsE3U2Txv5srD8BoemVWgWbWjfyim4kk8C5zlf +tWEazVAaI4MWecqtU4P5gIEomCI7MG9ebxYp5oQhRxeOndOYdUbSzAkZj50gXFA1 ++TNkvuhTFlJF0F7qIFVJSJTmJ+6E5B4ddbkyUYwbOdO+P8mz5N5mSljE+EiIQTxo +AwbG8cSivMy/jI3h048tCUONAJzcSWCF4k1r9Qr6xbyW2ud2GmKiFCEYJkYTsMWV +fM/RujTHlGvJ2+bQK5HiNyW0tO9znW9kaoxolu1YBvTh2492v3agK7nALyGGgdo1 +/nN/ikgkQiyaCpZwFeooJv1YFU5aDhR9RjIIJ9UbJ8FdAv8Xd00E3viunLTvqqXK +RVMokw+tFQTEzjKofKWYArPDjB9LUbN+vQbumKalis3+NlJ3WolYPrCg55tqt1o3 +zXi+xv7120cJFouilRFwrafNFV6F+pRMkMmiWopMnoVJPVXcoqyJRcsmO62uslhg +BLFgAH4H/14drYrgWIMz0no78RInEz0z507zwLkWk5d9W9pJ/4Rf +-----END CERTIFICATE----- diff --git a/tests/assets/client-certificates/client/trusted/csr.pem b/tests/assets/client-certificates/client/trusted/csr.pem new file mode 100644 index 0000000..8ead6da --- /dev/null +++ b/tests/assets/client-certificates/client/trusted/csr.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIEVTCCAj0CAQAwEDEOMAwGA1UEAwwFQWxpY2UwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQCac3+4rNmH4/N1s4HqR2X168tgS/aA6sHW5at8mWRnq54N +m11RvnK55jHQYVAdBgJy5M07w0wakp8inxzlY95wqxBimYG63Un/1p7mX9FkB4LN +ISCc6j/s/Ufv85MXPbn0S5rm9UcQO9cINJb1RP1YgDDLN5cxMz6X4nyofN8H6Lhv +h4JDdBw4DfDEFERkVfF+bkZ7YW4XHEChgzm3RxCF0eeGzIXGrkkK9AsSdJAhOvTl +HPFCQKXTYZhsL5+3Ma4RnWnDWvLTHx6KzoU+twTM2mYhhQuQgQpnmDHxGge8kGeH +GtfdgAjtVJTE57xF/shP0JU+tuIV8NNhQ/vEmhL0Wa093/EvpTVp0EUEuDh9ORRH +5K5M4bKJyU4XX5noiht6yOn00uaoJcWduUAWsU+cDSvDTMw81opWWm0QIAV3G2yu +RSkumHAKqvQLeyeyiKz+OEhyEiZ7EZNExPD0TSpApSTU6aCTUAvPYGQ59VjsMHTu +J9r4wKIYaDvfL+t72vg2vTQma5cTOBJfIdxH9blFTjEnToH3LX8t0XndQ2RkiRnI +ze2p2jUShxo/lWCjCw+2Iaw0A0fNUK1BbOrFRPq1u7AnEuMJt7HF50MloItM97R9 +vofDwgDIzlX/PzlVRcn1WCo8Fr/0EXxPPreX0YDIp1ANQ8fSv7bKb2vQIxWuCQID +AQABoAAwDQYJKoZIhvcNAQELBQADggIBAGgf3EC8WL3RGmuGA+d/4wd1jNfrfU6n +xjnDwdEEX0TQZGGPjh5xvoCK76yZPkO6+z0IYSepEmWBS27HJKl7nuoOvS7MjQyJ +C+3Bdk3ToCeQjmNBlRBKsUw5ftTU902oMl5BptHGj1KGjYBLAkPdXb44wXSVKJ8q +ihFhWlovsva6GDoUorksU3vOwijdlGzTANQHJGFncgrRud9ATavpGS3KVxR73R3A +aBbu3Qw+QIfu8Qx5eBJp8CbMrpAmjfuq17STvqr5bC10Fnn4NegrnHOQG9JcK02+ +5Bn3+9X/n1mue7aohIdErLEiDMSqMOwFfrJeaH6YM1G4QkWyqGugtmHsWOUf0nlU +nkH1krvfw9rb6b+03c4A6GSeHnbX5ufFDSf5gaR6Wy7c0jBnoxVbtBLH2zXlrd0k +iRQG7C6XZzGMS7hb7GL7+bkRy9kWjmDL7z7Fp+EgzKhNmzuWII3E9X9va33HoQ/Q +UdK3JVToxRQg6XRKOxL9+U/+8i6U8lxObLWkWh2cypZqbz5qJxa+2u5JYO/KEoHZ +G963UX7XWezR98vZuTc1XHGZtBDMrjjDd7Kmb4/i/xBPeWwseeGtzFy9z2pnEnkL +uKE4C8wUNpzUUlsn4LneZXObIoErE7FqAAlVFujVe7iaJBmXoUXZR36drbfiaODK +vwAGyrYHaOlR +-----END CERTIFICATE REQUEST----- diff --git a/tests/assets/client-certificates/client/trusted/key.pem b/tests/assets/client-certificates/client/trusted/key.pem new file mode 100644 index 0000000..d60201e --- /dev/null +++ b/tests/assets/client-certificates/client/trusted/key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +Y+eu85cike5J4vnz8uG04yt7rXjIrUav +-----END PRIVATE KEY----- diff --git a/tests/assets/client-certificates/server/server_cert.pem b/tests/assets/client-certificates/server/server_cert.pem new file mode 100644 index 0000000..52d8f53 --- /dev/null +++ b/tests/assets/client-certificates/server/server_cert.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFdTCCA12gAwIBAgIUNPWupe2xcu8YYG1ozoqk9viqDJswDQYJKoZIhvcNAQEL +BQAwNjESMBAGA1UEAwwJbG9jYWxob3N0MSAwHgYDVQQKDBdDbGllbnQgQ2VydGlm +aWNhdGUgRGVtbzAeFw0yNDA3MTkxMjQ3MzNaFw0yNTA3MTkxMjQ3MzNaMDYxEjAQ +BgNVBAMMCWxvY2FsaG9zdDEgMB4GA1UECgwXQ2xpZW50IENlcnRpZmljYXRlIERl +bW8wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC+K5JWhlfvI47ZL/Az +L0xnOl+cMelr2BqH+7XS8187SbvluhFfFkq/7V7rwgsHI64sn8pgRCOnqKWV6jtb +651dGzn7Nby6InmyOQzF4VwfSVWQ6BYXgXuryS9Gm0gi8sOL1Ji/jV49n1gzLyIx +LNhd7NG2DCCedTHJnxyz4xq8MWhI/qI85iWJqcHhxkDb8wtH1Vd6nd/ZRVDbjgTv +PH3EDK7JqmnYG9+x4Jz0yEhvV7jL3gNu2mIyttvm7oRna9oHgaKFUJt4BCfPbT5U +3ipvcq29hdD5/5QIDzTWcExTnklolg5xpFext1+3KPSppESxcfBBNoL3h1B8ZcZa +lEMC/IoFUIDJQj5gmSn4okwMWIxgf+AL0609MKEqQ2FavOsvBmhHcQsqLk4MO/v0 +NGFv1/xGe4tUkX4han6ykf1+sqzupJT5qnUONmvghb2SpIt83o4j4KHVzZwk8JK0 +N6hN7JEjXQwSKCh3b0FFg+kPAe12d6BBcsNzEYmt2C1KNPbXMX84zIkgPN01XMg6 +kdCdjP6DH7CK+brW9qQufOqYpd3eNhJyeBm+oP3PhnhEiMTIO8X2GdSN5Rxozgxl +VIj/QWhLV64r5AqPr/Vpd1vcsxrg3aS5CASmoWQmTPuhEZptRtrkPkGw7k9NPZ34 +lnRenvKJ9e3DXhXRMqeYUY6wjwIDAQABo3sweTAdBgNVHQ4EFgQUEHtrxWCk96Eh +r60E0HBuwLk2i+IwHwYDVR0jBBgwFoAUEHtrxWCk96Ehr60E0HBuwLk2i+IwDwYD +VR0TAQH/BAUwAwEB/zAmBgNVHREEHzAdgglsb2NhbGhvc3SCEGxvY2FsLnBsYXl3 +cmlnaHQwDQYJKoZIhvcNAQELBQADggIBALP4kOAP21ZusbEH89VkZT3MkGlZuDQP +LyTYdLzT3EzN//2+lBDmJfpIPLL/K3sNEVSzNppa6tcCXiVNes/xJM7tHRhTOJ31 +HinSsib2r6DZ6SitQJWmD5FoAdkp9qdG8mA/5vOiwiVKKFV2/Z3i+3iUI/ZnEhUq +uUA1I3TI5LAQzgWLwYu1jSEM1EbH6uQiZ8AmXLVO4GQnVQdbyarWHxIy+zsg+MJN +fxIG/phDpkt1mI3SkAdpWRWjCKESQhrIcRUtu5eVk0lho6ttHODXF8bM7iWLoRc7 +rpcllI4HXHoXQqQkZHRa7KwTf0YVwwQbXTecZONWXwE9Ej5R5IcZzja5FWCSstsb +ULNW0JVxGBE7j5aOjxasYAbRexDmlfEdLvnp6bctZuvMvuBxrB+x5HSEZl6bVnbC +nvtoslylQJM1bwlZdCqJm04JXe1787HDBef2gABv27BjvG/zn89L5ipogZCrGpl6 +P9qs0eSERHuSrm3eHUVgXSQ1nbvOpk7RPFbsbp/npc1NbEDBdAMoXhLP9A+ytxLq +TF+w08nfCF6yJJ3jTkvABo10UH6zcPnfH3Ys7JYsHRbcloMfn+mc88KrTaCO+VZx +qjhFcz+zDu/AbtJkDJtxX2X7jNL0pzWS+9H8jFTrd3ta8XrJiSFq2VMxEU6R0IHk +2Ct10prMWB/3 +-----END CERTIFICATE----- diff --git a/tests/assets/client-certificates/server/server_key.pem b/tests/assets/client-certificates/server/server_key.pem new file mode 100644 index 0000000..ff6a3fc --- /dev/null +++ b/tests/assets/client-certificates/server/server_key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +8ynLaTs3oV3BjQya9pAUyzIX5L67 +-----END PRIVATE KEY----- diff --git a/tests/assets/client.py b/tests/assets/client.py new file mode 100644 index 0000000..670242f --- /dev/null +++ b/tests/assets/client.py @@ -0,0 +1,34 @@ +# Copyright (c) Microsoft Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +from pathlib import Path + +from playwright.sync_api import Playwright, sync_playwright + + +def main(playwright: Playwright, browser_name: str) -> None: + browser = playwright[browser_name].launch() + page = browser.new_page() + page.goto("data:text/html,Foobar") + here = Path(__file__).parent.resolve() + page.screenshot(path=here / f"{browser_name}.png") + page.close() + browser.close() + + +if __name__ == "__main__": + browser_name = sys.argv[1] + with sync_playwright() as p: + main(p, browser_name) diff --git a/tests/assets/consolelog.html b/tests/assets/consolelog.html new file mode 100644 index 0000000..7fa1b21 --- /dev/null +++ b/tests/assets/consolelog.html @@ -0,0 +1,11 @@ + + + + console.log test + + + + + diff --git a/tests/assets/csp.html b/tests/assets/csp.html new file mode 100644 index 0000000..34fc1fc --- /dev/null +++ b/tests/assets/csp.html @@ -0,0 +1 @@ + diff --git a/tests/assets/digits/0.png b/tests/assets/digits/0.png new file mode 100644 index 0000000000000000000000000000000000000000..ac3c4768edfbe7bd47c436b1451938fa83483a0c GIT binary patch literal 434 zcmeAS@N?(olHy`uVBq!ia0vp^Ahr+(3y?gqul)d!Vo7)Ob!1@J*w6hZkrl{SNcITw zWnidMV_;}#VPN<`%l_%+p4TGxUM+vVxv7$R|b>IB0qra%Ul`~MX*b+&Ovv2B|q(!_F5JEB7P zed0v5sZ%E?Yh1hbjAP{`Rxy#BDWWlty*FwfV(a#?G%)Vx{1iU1`q`mv2gSp$&p2~* z-}_~cq6GO$WM?Q#u2eqHG5>*&;LICE?MK)yaHod0^GXWrZw)prU@KA-JFv3vi--cJ zxiY6feZzXKeM^rjA81T>7dtU=-Ac=*J)Oz+GF_*I;`H`Ro8h-tLFm*jTUKAWRU1F- zfBotg>*8DSc8V=VKyNdsmbgZgq$HN4S|t~y0x1R~14DCN12bJivk*g5D-%O2V@q8F mb1MUbn=hryP&DM`r(~v8;?}TY%i>c&4Gf;HelF{r5}E+JGmpjq literal 0 HcmV?d00001 diff --git a/tests/assets/digits/1.png b/tests/assets/digits/1.png new file mode 100644 index 0000000000000000000000000000000000000000..6768222729b7a487d338fdd7691e44ca4604b216 GIT binary patch literal 346 zcmeAS@N?(olHy`uVBq!ia0vp^Ahr+(3y?gqul)d!Vo7)Ob!1@J*w6hZkrl{SNcITw zWnidMV_;}#VPN<`%l_%+p4TGxUMOY(Ga43W5;{O5cF=M0GtoN~YQ|NXb^`8@xj{o(qyZXTZh zNB`|_{xm~E;-A5pf9w0RzSOs614Wzvrz@>Y`EmY3PvY_a|9PY*vP4Qqs7R_vN=noT zzEz3h*rdQ|G)c~jg_Tj2N2{sHz90fFVdQ&MBb@0M_4YL;wH) literal 0 HcmV?d00001 diff --git a/tests/assets/digits/2.png b/tests/assets/digits/2.png new file mode 100644 index 0000000000000000000000000000000000000000..b1daa4735d8a8c8dcce6be0fc2db02beb265860b GIT binary patch literal 413 zcmeAS@N?(olHy`uVBq!ia0vp^Ahr+(3y?gqul)d!Vo7)Ob!1@J*w6hZkrl{SNcITw zWnidMV_;}#VPN<`%l_%$`QSZ$aB6k6)(;us=vdFljxE~Y{OxBK}UC0Lr@F!n?rT`(_E{}JO6 z<{7z73T*rf7DVR9aWl3E8iRZQbg$2f$a-VDO8#vl&KeD#DWG<1jqwYkJ(8lLS zB4RWT1dM<5ebWu_3N}u7Cea|(Ea3RP_Gw+vkLTX@hooODEC@-v@oNsy!Kx*$5hW>! zC8<`)MX5lF!N|bST-U%%*U&7)(A3Jr(8|O>*TCG$z`$)w_#PAux%nxXX_dG&n7@1v QRL{WR>FVdQ&MBb@0Eyv<`%l_%$`QSZ$aB6x!wK;us=vdFq6XS%(-TTK3zgoV~U1u8i>$)?1-gCGWI< z@aS2U3)ZwcEm*ubc;$ti-mV3rF6`=#s{>A4SDeUI_Oe&LoV{Fey4Mfsycbe!vf}Dh z3k0h9j%Z)+Fc6$CIUO_QmvAUQh^kMk%6JPu7R1Zp;?Hbsg;SLm5G6_ nfw`4|f!mhwJt!J-^HVa@DsgKtfB7D$o`J#B)z4*}Q$iB}nZcB~ literal 0 HcmV?d00001 diff --git a/tests/assets/digits/4.png b/tests/assets/digits/4.png new file mode 100644 index 0000000000000000000000000000000000000000..a721071e2cc4f4d3aeb9a939fb353bee19a655b5 GIT binary patch literal 403 zcmeAS@N?(olHy`uVBq!ia0vp^Ahr+(3y?gqul)d!Vo7)Ob!1@J*w6hZkrl{SNcITw zWnidMV_;}#VPN<`%l_%$^T+cq!(g=TxYIEF}Eo;tyhk1Daqt63f# z{2;4qbecI;$g&|gJoK~I{dMMIqQ-q^Z?t=`WG!sjc4tSKLf;*&Y1X25Kle?TG^sF6 z>D=BYXVM%qnde@pu;0vgB#G~T{mbP)S=PRcF1)|-gago-swJ)wB`Jv|saDBFsX&Us z$iUEC*T78I&@9Bz)XKyVh;$9itqcqv9FE~Y(U6;;l9^VCTf@Y8PqqLxFnGH9xvX<`%l_%$^T+cq!(h1PkxIEF}E?wz22-my@kZT1K|fI9blJ2l{+r3^|)} z*8RfYYV*z8_c%_x;UgqEd!^9Poh`*TW`=*TdCT>^*4BT*|H;1(oM7&m8^G|u$3Da% zDeBX$-lmw9w+s(E_C1K%nffs5$fStkT(0({CkN(r>}Jt>Q{|STYPMH+)2ATwXX;N9 zUY^;$J4woIp1{qfw?{sQ>->K1(PN|HYUInB{Z4ScYq_3-VJ}bo{&&hX4DrV0Symw> zhk!0uEpd$~Nl7e8wMs5Z1yT$~28QOk24=d3W+8^ARwjl(q-$VqWnl2&a0~~EhTQy= Z%(P0}8Ya$rvIVGt!PC{xWt~$(69C)6lY0OF literal 0 HcmV?d00001 diff --git a/tests/assets/digits/6.png b/tests/assets/digits/6.png new file mode 100644 index 0000000000000000000000000000000000000000..639f38439d94e856e41a6750952b6e06c418cf3f GIT binary patch literal 445 zcmeAS@N?(olHy`uVBq!ia0vp^Ahr+(3y?gqul)d!Vo7)Ob!1@J*w6hZkrl{SNcITw zWnidMV_;}#VPN<`%l_%*enOfK#K3LW)yaSV~TJavMh*Wm;PxBK(YEu72bwVdZ}kbt`XgDKWG zHhQxkJbRS+g$`@}15O#2T~i(@MY241a<;z7)g=_)Zn4zjOK<*{ z^|H0Og+AWm-uT?SDW)^nHSdUci~p}UEv0yy-ENEcy{zt3Kiarmu2tfJsEduUXmP#3 zy#q&>em;$vqY=pZB*h^?VgbV<=ODgW9}Ojw!x+xA)XDx=DXab9=X3YU$4?nbk5(4D zIQzm0Xkxq!^4049#^7%ybRS xLJUo5~f0{rI44$rjF6*2UngAmjmB9c2 literal 0 HcmV?d00001 diff --git a/tests/assets/digits/7.png b/tests/assets/digits/7.png new file mode 100644 index 0000000000000000000000000000000000000000..5c1150b005a9fe3c2b970617dcb8801d98408fe7 GIT binary patch literal 387 zcmeAS@N?(olHy`uVBq!ia0vp^Ahr+(3y?gqul)d!Vo7)Ob!1@J*w6hZkrl{SNcITw zWnidMV_;}#VPN<`%l_%*enOfK#K3UzzBIEF}E?!B;(m&sAU?cw&>o3As9E-=s#a$@F?F}=VL zyP)8Tqo9h03QMC?e9=i(rpg_=V;%1F{Qf6sEc|5qBl*P@8;rI@9-ZW>@#KW&%vnq~ zzOl}^kHZ9KZ=-wR{MdtU&MofI@cqgkb+dDrc!nov}_HpAKo1^uZt{iyr``c~- z=k|r)r~i7)zL771W73?7Q-RJ>Epd$~Nl7e8wMs5Z1yT$~28QOk24=d3W+8^ARwjm4 pCPumj=2iv<7q#6`HRR@}WTsW(*07-LpC-@-22WQ%mvv4FO#tK!e`o*z literal 0 HcmV?d00001 diff --git a/tests/assets/digits/8.png b/tests/assets/digits/8.png new file mode 100644 index 0000000000000000000000000000000000000000..abb8b48b0b1e5ac8aabb667265d9469d48b7fa24 GIT binary patch literal 447 zcmeAS@N?(olHy`uVBq!ia0vp^Ahr+(3y?gqul)d!Vo7)Ob!1@J*w6hZkrl{SNcITw zWnidMV_;}#VPN<`%l_%*e4jUVa(g^qi=IEF}Eo;pF-zbR3qZT<755iFO44ID4;ZXsr|G6Z-3AQ~YMF#9yB;s?AMz zKS@rU5cTWfbfKwA)i>7f%FSiSf0jRY%Pf;;KrgA5xJHzuB$lLFB^RXvDF!10LvvjN zGhIWo5JOWd6GJN#V_gGtD+7b_7+*yc4Y~O#nQ4`{HLx*$oeR{!;OXk;vd$@?2>`+@ BpQr!; literal 0 HcmV?d00001 diff --git a/tests/assets/digits/9.png b/tests/assets/digits/9.png new file mode 100644 index 0000000000000000000000000000000000000000..6a40a21c6f58545cab61ea346f1b6bb8b9300c6d GIT binary patch literal 437 zcmeAS@N?(olHy`uVBq!ia0vp^Ahr+(3y?gqul)d!Vo7)Ob!1@J*w6hZkrl{SNcITw zWnidMV_;}#VPN<`%l_%*e4jUVa(h4y;7IEF}Eo;pD>k10`t_4)k-!5MN3m>MJ651DFC-ODU@ zpZg1!gh!athOH(nj7nKY-017|7X(lneSP5`X2ea_zN%F?Q`q4 z_N=>MvQe>5^dWanr4!!~yIt-xI*MIYJ|5&1TI#UWB`1>;t5@F(qUrTrX|{*Mm$Cl}5-eYz`MaCM!?KE?X)(klhI z7Jr!kGOw6X)u&2!`$KOxphr|oTq8
Text, +more text
+ + diff --git a/tests/assets/download-blob.html b/tests/assets/download-blob.html new file mode 100644 index 0000000..3c4a3d8 --- /dev/null +++ b/tests/assets/download-blob.html @@ -0,0 +1,29 @@ + + + + Blob Download Example + + + +
Download + + diff --git a/tests/assets/drag-n-drop.html b/tests/assets/drag-n-drop.html new file mode 100644 index 0000000..f43583e --- /dev/null +++ b/tests/assets/drag-n-drop.html @@ -0,0 +1,40 @@ + + + + + +
+

+ Select this element, drag it to the Drop Zone and then release the selection to move the element.

+
+
Drop Zone
+ diff --git a/tests/assets/dummy_bad_browser_executable.js b/tests/assets/dummy_bad_browser_executable.js new file mode 100755 index 0000000..92f1453 --- /dev/null +++ b/tests/assets/dummy_bad_browser_executable.js @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +process.exit(1); diff --git a/tests/assets/empty.html b/tests/assets/empty.html new file mode 100644 index 0000000..e69de29 diff --git a/tests/assets/error.html b/tests/assets/error.html new file mode 100644 index 0000000..0851c4d --- /dev/null +++ b/tests/assets/error.html @@ -0,0 +1,17 @@ + diff --git a/tests/assets/es6/.eslintrc b/tests/assets/es6/.eslintrc new file mode 100644 index 0000000..1fbe592 --- /dev/null +++ b/tests/assets/es6/.eslintrc @@ -0,0 +1,5 @@ +{ + "parserOptions": { + "sourceType": "module" + } +} diff --git a/tests/assets/es6/es6import.js b/tests/assets/es6/es6import.js new file mode 100644 index 0000000..9aac2d4 --- /dev/null +++ b/tests/assets/es6/es6import.js @@ -0,0 +1,2 @@ +import num from './es6module.js'; +window.__es6injected = num; diff --git a/tests/assets/es6/es6module.js b/tests/assets/es6/es6module.js new file mode 100644 index 0000000..7a4e8a7 --- /dev/null +++ b/tests/assets/es6/es6module.js @@ -0,0 +1 @@ +export default 42; diff --git a/tests/assets/es6/es6pathimport.js b/tests/assets/es6/es6pathimport.js new file mode 100644 index 0000000..eb17a9a --- /dev/null +++ b/tests/assets/es6/es6pathimport.js @@ -0,0 +1,2 @@ +import num from './es6/es6module.js'; +window.__es6injected = num; diff --git a/tests/assets/file-to-upload-2.txt b/tests/assets/file-to-upload-2.txt new file mode 100644 index 0000000..2e2da21 --- /dev/null +++ b/tests/assets/file-to-upload-2.txt @@ -0,0 +1 @@ +contents of the file diff --git a/tests/assets/file-to-upload.txt b/tests/assets/file-to-upload.txt new file mode 100644 index 0000000..2e2da21 --- /dev/null +++ b/tests/assets/file-to-upload.txt @@ -0,0 +1 @@ +contents of the file diff --git a/tests/assets/frames/child-redirect.html b/tests/assets/frames/child-redirect.html new file mode 100644 index 0000000..d4806e7 --- /dev/null +++ b/tests/assets/frames/child-redirect.html @@ -0,0 +1 @@ + diff --git a/tests/assets/frames/frame.html b/tests/assets/frames/frame.html new file mode 100644 index 0000000..4fa9268 --- /dev/null +++ b/tests/assets/frames/frame.html @@ -0,0 +1,15 @@ + + + +
Hi, I'm frame
diff --git a/tests/assets/frames/frameset.html b/tests/assets/frames/frameset.html new file mode 100644 index 0000000..4d56f88 --- /dev/null +++ b/tests/assets/frames/frameset.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/assets/frames/nested-frames.html b/tests/assets/frames/nested-frames.html new file mode 100644 index 0000000..d858d32 --- /dev/null +++ b/tests/assets/frames/nested-frames.html @@ -0,0 +1,30 @@ + + + + diff --git a/tests/assets/frames/one-frame.html b/tests/assets/frames/one-frame.html new file mode 100644 index 0000000..e941d79 --- /dev/null +++ b/tests/assets/frames/one-frame.html @@ -0,0 +1 @@ + diff --git a/tests/assets/frames/redirect-my-parent.html b/tests/assets/frames/redirect-my-parent.html new file mode 100644 index 0000000..3beb0aa --- /dev/null +++ b/tests/assets/frames/redirect-my-parent.html @@ -0,0 +1,3 @@ + diff --git a/tests/assets/frames/script.js b/tests/assets/frames/script.js new file mode 100644 index 0000000..be22256 --- /dev/null +++ b/tests/assets/frames/script.js @@ -0,0 +1 @@ +console.log('Cheers!'); diff --git a/tests/assets/frames/style.css b/tests/assets/frames/style.css new file mode 100644 index 0000000..5b5436e --- /dev/null +++ b/tests/assets/frames/style.css @@ -0,0 +1,3 @@ +div { + color: blue; +} diff --git a/tests/assets/frames/two-frames.html b/tests/assets/frames/two-frames.html new file mode 100644 index 0000000..00324f0 --- /dev/null +++ b/tests/assets/frames/two-frames.html @@ -0,0 +1,16 @@ + + + diff --git a/tests/assets/geolocation.html b/tests/assets/geolocation.html new file mode 100644 index 0000000..3d44c3f --- /dev/null +++ b/tests/assets/geolocation.html @@ -0,0 +1,7 @@ + diff --git a/tests/assets/global-var.html b/tests/assets/global-var.html new file mode 100644 index 0000000..52eb94e --- /dev/null +++ b/tests/assets/global-var.html @@ -0,0 +1,3 @@ + diff --git a/tests/assets/grid.html b/tests/assets/grid.html new file mode 100644 index 0000000..0bdbb12 --- /dev/null +++ b/tests/assets/grid.html @@ -0,0 +1,52 @@ + + + diff --git a/tests/assets/har-fulfill.har b/tests/assets/har-fulfill.har new file mode 100644 index 0000000..dc6b7c6 --- /dev/null +++ b/tests/assets/har-fulfill.har @@ -0,0 +1,366 @@ +{ + "log": { + "version": "1.2", + "creator": { + "name": "Playwright", + "version": "1.23.0-next" + }, + "browser": { + "name": "chromium", + "version": "103.0.5060.33" + }, + "pages": [ + { + "startedDateTime": "2022-06-10T04:27:32.125Z", + "id": "page@b17b177f1c2e66459db3dcbe44636ffd", + "title": "Hey", + "pageTimings": { + "onContentLoad": 70, + "onLoad": 70 + } + } + ], + "entries": [ + { + "_frameref": "frame@c7467fc0f1f86f09fc3b0d727a3862ea", + "_monotonicTime": 270572145.898, + "startedDateTime": "2022-06-10T04:27:32.146Z", + "time": 8.286, + "request": { + "method": "GET", + "url": "http://no.playwright/", + "httpVersion": "HTTP/1.1", + "cookies": [], + "headers": [ + { + "name": "Accept", + "value": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" + }, + { + "name": "Upgrade-Insecure-Requests", + "value": "1" + }, + { + "name": "User-Agent", + "value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.33 Safari/537.36" + } + ], + "queryString": [], + "headersSize": 326, + "bodySize": 0 + }, + "response": { + "status": 200, + "statusText": "OK", + "httpVersion": "HTTP/1.1", + "cookies": [], + "headers": [ + { + "name": "content-length", + "value": "111" + }, + { + "name": "content-type", + "value": "text/html" + } + ], + "content": { + "size": 111, + "mimeType": "text/html", + "compression": 0, + "text": "Hey
hello
" + }, + "headersSize": 65, + "bodySize": 170, + "redirectURL": "", + "_transferSize": 170 + }, + "cache": { + "beforeRequest": null, + "afterRequest": null + }, + "timings": { + "dns": -1, + "connect": -1, + "ssl": -1, + "send": 0, + "wait": 8.286, + "receive": -1 + }, + "pageref": "page@b17b177f1c2e66459db3dcbe44636ffd", + "_securityDetails": {} + }, + { + "_frameref": "frame@c7467fc0f1f86f09fc3b0d727a3862ea", + "_monotonicTime": 270572174.683, + "startedDateTime": "2022-06-10T04:27:32.172Z", + "time": 7.132, + "request": { + "method": "POST", + "url": "http://no.playwright/style.css", + "httpVersion": "HTTP/1.1", + "cookies": [], + "headers": [ + { + "name": "Accept", + "value": "text/css,*/*;q=0.1" + }, + { + "name": "Referer", + "value": "http://no.playwright/" + }, + { + "name": "User-Agent", + "value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.33 Safari/537.36" + } + ], + "queryString": [], + "headersSize": 220, + "bodySize": 0 + }, + "response": { + "status": 200, + "statusText": "OK", + "httpVersion": "HTTP/1.1", + "cookies": [], + "headers": [ + { + "name": "content-length", + "value": "24" + }, + { + "name": "content-type", + "value": "text/css" + } + ], + "content": { + "size": 24, + "mimeType": "text/css", + "compression": 0, + "text": "body { background:cyan }" + }, + "headersSize": 63, + "bodySize": 81, + "redirectURL": "", + "_transferSize": 81 + }, + "cache": { + "beforeRequest": null, + "afterRequest": null + }, + "timings": { + "dns": -1, + "connect": -1, + "ssl": -1, + "send": 0, + "wait": 8.132, + "receive": -1 + }, + "pageref": "page@b17b177f1c2e66459db3dcbe44636ffd", + "_securityDetails": {} + }, + { + "_frameref": "frame@c7467fc0f1f86f09fc3b0d727a3862ea", + "_monotonicTime": 270572174.683, + "startedDateTime": "2022-06-10T04:27:32.174Z", + "time": 8.132, + "request": { + "method": "GET", + "url": "http://no.playwright/style.css", + "httpVersion": "HTTP/1.1", + "cookies": [], + "headers": [ + { + "name": "Accept", + "value": "text/css,*/*;q=0.1" + }, + { + "name": "Referer", + "value": "http://no.playwright/" + }, + { + "name": "User-Agent", + "value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.33 Safari/537.36" + } + ], + "queryString": [], + "headersSize": 220, + "bodySize": 0 + }, + "response": { + "status": 200, + "statusText": "OK", + "httpVersion": "HTTP/1.1", + "cookies": [], + "headers": [ + { + "name": "content-length", + "value": "24" + }, + { + "name": "content-type", + "value": "text/css" + } + ], + "content": { + "size": 24, + "mimeType": "text/css", + "compression": 0, + "text": "body { background: red }" + }, + "headersSize": 63, + "bodySize": 81, + "redirectURL": "", + "_transferSize": 81 + }, + "cache": { + "beforeRequest": null, + "afterRequest": null + }, + "timings": { + "dns": -1, + "connect": -1, + "ssl": -1, + "send": 0, + "wait": 8.132, + "receive": -1 + }, + "pageref": "page@b17b177f1c2e66459db3dcbe44636ffd", + "_securityDetails": {} + }, + { + "_frameref": "frame@c7467fc0f1f86f09fc3b0d727a3862ea", + "_monotonicTime": 270572175.042, + "startedDateTime": "2022-06-10T04:27:32.175Z", + "time": 15.997, + "request": { + "method": "GET", + "url": "http://no.playwright/script.js", + "httpVersion": "HTTP/1.1", + "cookies": [], + "headers": [ + { + "name": "Accept", + "value": "*/*" + }, + { + "name": "Referer", + "value": "http://no.playwright/" + }, + { + "name": "User-Agent", + "value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.33 Safari/537.36" + } + ], + "queryString": [], + "headersSize": 205, + "bodySize": 0 + }, + "response": { + "status": 301, + "statusText": "Moved Permanently", + "httpVersion": "HTTP/1.1", + "cookies": [], + "headers": [ + { + "name": "location", + "value": "http://no.playwright/script2.js" + } + ], + "content": { + "size": -1, + "mimeType": "x-unknown", + "compression": 0 + }, + "headersSize": 77, + "bodySize": 0, + "redirectURL": "http://no.playwright/script2.js", + "_transferSize": 77 + }, + "cache": { + "beforeRequest": null, + "afterRequest": null + }, + "timings": { + "dns": -1, + "connect": -1, + "ssl": -1, + "send": 0, + "wait": 7.673, + "receive": 8.324 + }, + "pageref": "page@b17b177f1c2e66459db3dcbe44636ffd", + "_securityDetails": {} + }, + { + "_frameref": "frame@c7467fc0f1f86f09fc3b0d727a3862ea", + "_monotonicTime": 270572181.822, + "startedDateTime": "2022-06-10T04:27:32.182Z", + "time": 6.735, + "request": { + "method": "GET", + "url": "http://no.playwright/script2.js", + "httpVersion": "HTTP/1.1", + "cookies": [], + "headers": [ + { + "name": "Accept", + "value": "*/*" + }, + { + "name": "Referer", + "value": "http://no.playwright/" + }, + { + "name": "User-Agent", + "value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.33 Safari/537.36" + } + ], + "queryString": [], + "headersSize": 206, + "bodySize": 0 + }, + "response": { + "status": 200, + "statusText": "OK", + "httpVersion": "HTTP/1.1", + "cookies": [], + "headers": [ + { + "name": "content-length", + "value": "18" + }, + { + "name": "content-type", + "value": "text/javascript" + } + ], + "content": { + "size": 18, + "mimeType": "text/javascript", + "compression": 0, + "text": "window.value='foo'" + }, + "headersSize": 70, + "bodySize": 82, + "redirectURL": "", + "_transferSize": 82 + }, + "cache": { + "beforeRequest": null, + "afterRequest": null + }, + "timings": { + "dns": -1, + "connect": -1, + "ssl": -1, + "send": 0, + "wait": 6.735, + "receive": -1 + }, + "pageref": "page@b17b177f1c2e66459db3dcbe44636ffd", + "_securityDetails": {} + } + ] + } +} diff --git a/tests/assets/har-redirect.har b/tests/assets/har-redirect.har new file mode 100644 index 0000000..b2e5733 --- /dev/null +++ b/tests/assets/har-redirect.har @@ -0,0 +1,620 @@ +{ + "log": { + "version": "1.2", + "creator": { + "name": "Playwright", + "version": "1.23.0-next" + }, + "browser": { + "name": "chromium", + "version": "103.0.5060.42" + }, + "pages": [ + { + "startedDateTime": "2022-06-16T21:41:23.901Z", + "id": "page@8f314969edc000996eb5c2ab22f0e6b3", + "title": "Microsoft", + "pageTimings": { + "onContentLoad": 8363, + "onLoad": 8896 + } + } + ], + "entries": [ + { + "_frameref": "frame@3767e074ecde4cb8372abba2f6f9bb4f", + "_monotonicTime": 110928357.437, + "startedDateTime": "2022-06-16T21:41:23.951Z", + "time": 93.99, + "request": { + "method": "GET", + "url": "https://theverge.com/", + "httpVersion": "HTTP/2.0", + "cookies": [], + "headers": [ + { + "name": ":authority", + "value": "theverge.com" + }, + { + "name": ":method", + "value": "GET" + }, + { + "name": ":path", + "value": "/" + }, + { + "name": ":scheme", + "value": "https" + }, + { + "name": "accept", + "value": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" + }, + { + "name": "accept-encoding", + "value": "gzip, deflate, br" + }, + { + "name": "accept-language", + "value": "en-US,en;q=0.9" + }, + { + "name": "sec-ch-ua", + "value": "\"Chromium\";v=\"103\", \".Not/A)Brand\";v=\"99\"" + }, + { + "name": "sec-ch-ua-mobile", + "value": "?0" + }, + { + "name": "sec-ch-ua-platform", + "value": "\"Linux\"" + }, + { + "name": "sec-fetch-dest", + "value": "document" + }, + { + "name": "sec-fetch-mode", + "value": "navigate" + }, + { + "name": "sec-fetch-site", + "value": "none" + }, + { + "name": "sec-fetch-user", + "value": "?1" + }, + { + "name": "upgrade-insecure-requests", + "value": "1" + }, + { + "name": "user-agent", + "value": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.42 Safari/537.36" + } + ], + "queryString": [], + "headersSize": 644, + "bodySize": 0 + }, + "response": { + "status": 301, + "statusText": "", + "httpVersion": "HTTP/2.0", + "cookies": [ + { + "name": "vmidv1", + "value": "9faf31ab-1415-4b90-b367-24b670205f41", + "expires": "2027-06-15T21:41:24.000Z", + "domain": "theverge.com", + "path": "/", + "sameSite": "Lax", + "secure": true + } + ], + "headers": [ + { + "name": "accept-ranges", + "value": "bytes" + }, + { + "name": "content-length", + "value": "0" + }, + { + "name": "date", + "value": "Thu, 16 Jun 2022 21:41:24 GMT" + }, + { + "name": "location", + "value": "http://www.theverge.com/" + }, + { + "name": "retry-after", + "value": "0" + }, + { + "name": "server", + "value": "Varnish" + }, + { + "name": "set-cookie", + "value": "vmidv1=9faf31ab-1415-4b90-b367-24b670205f41;Expires=Tue, 15 Jun 2027 21:41:24 GMT;Domain=theverge.com;Path=/;SameSite=Lax;Secure" + }, + { + "name": "via", + "value": "1.1 varnish" + }, + { + "name": "x-cache", + "value": "HIT" + }, + { + "name": "x-cache-hits", + "value": "0" + }, + { + "name": "x-served-by", + "value": "cache-pao17442-PAO" + }, + { + "name": "x-timer", + "value": "S1655415684.005867,VS0,VE0" + } + ], + "content": { + "size": -1, + "mimeType": "x-unknown", + "compression": 0 + }, + "headersSize": 425, + "bodySize": 0, + "redirectURL": "http://www.theverge.com/", + "_transferSize": 425 + }, + "cache": { + "beforeRequest": null, + "afterRequest": null + }, + "timings": { + "dns": 0, + "connect": 34.151, + "ssl": 28.074, + "send": 0, + "wait": 27.549, + "receive": 4.216 + }, + "pageref": "page@8f314969edc000996eb5c2ab22f0e6b3", + "serverIPAddress": "151.101.65.52", + "_serverPort": 443, + "_securityDetails": { + "protocol": "TLS 1.2", + "subjectName": "*.americanninjawarriornation.com", + "issuer": "GlobalSign Atlas R3 DV TLS CA 2022 Q1", + "validFrom": 1644853133, + "validTo": 1679153932 + } + }, + { + "_frameref": "frame@3767e074ecde4cb8372abba2f6f9bb4f", + "_monotonicTime": 110928427.603, + "startedDateTime": "2022-06-16T21:41:24.022Z", + "time": 44.39499999999999, + "request": { + "method": "GET", + "url": "http://www.theverge.com/", + "httpVersion": "HTTP/1.1", + "cookies": [], + "headers": [ + { + "name": "Accept", + "value": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" + }, + { + "name": "Accept-Encoding", + "value": "gzip, deflate" + }, + { + "name": "Accept-Language", + "value": "en-US,en;q=0.9" + }, + { + "name": "Connection", + "value": "keep-alive" + }, + { + "name": "Host", + "value": "www.theverge.com" + }, + { + "name": "Upgrade-Insecure-Requests", + "value": "1" + }, + { + "name": "User-Agent", + "value": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.42 Safari/537.36" + } + ], + "queryString": [], + "headersSize": 423, + "bodySize": 0 + }, + "response": { + "status": 301, + "statusText": "Moved Permanently", + "httpVersion": "HTTP/1.1", + "cookies": [ + { + "name": "_chorus_geoip_continent", + "value": "NA" + }, + { + "name": "vmidv1", + "value": "4e0c1265-10f8-4cb1-a5de-1c3cf70b531c", + "expires": "2027-06-15T21:41:24.000Z", + "domain": "www.theverge.com", + "path": "/", + "sameSite": "Lax", + "secure": true + } + ], + "headers": [ + { + "name": "Accept-Ranges", + "value": "bytes" + }, + { + "name": "Age", + "value": "2615" + }, + { + "name": "Connection", + "value": "keep-alive" + }, + { + "name": "Content-Length", + "value": "0" + }, + { + "name": "Content-Type", + "value": "text/html" + }, + { + "name": "Date", + "value": "Thu, 16 Jun 2022 21:41:24 GMT" + }, + { + "name": "Location", + "value": "https://www.theverge.com/" + }, + { + "name": "Server", + "value": "nginx" + }, + { + "name": "Set-Cookie", + "value": "_chorus_geoip_continent=NA; expires=Fri, 17 Jun 2022 21:41:24 GMT; path=/;" + }, + { + "name": "Set-Cookie", + "value": "vmidv1=4e0c1265-10f8-4cb1-a5de-1c3cf70b531c;Expires=Tue, 15 Jun 2027 21:41:24 GMT;Domain=www.theverge.com;Path=/;SameSite=Lax;Secure" + }, + { + "name": "Vary", + "value": "X-Forwarded-Proto, Cookie, X-Chorus-Unison-Testing, X-Chorus-Require-Privacy-Consent, X-Chorus-Restrict-In-Privacy-Consent-Region, Accept-Encoding" + }, + { + "name": "Via", + "value": "1.1 varnish" + }, + { + "name": "X-Cache", + "value": "HIT" + }, + { + "name": "X-Cache-Hits", + "value": "2" + }, + { + "name": "X-Served-By", + "value": "cache-pao17450-PAO" + }, + { + "name": "X-Timer", + "value": "S1655415684.035748,VS0,VE0" + } + ], + "content": { + "size": -1, + "mimeType": "text/html", + "compression": 0 + }, + "headersSize": 731, + "bodySize": 0, + "redirectURL": "https://www.theverge.com/", + "_transferSize": 731 + }, + "cache": { + "beforeRequest": null, + "afterRequest": null + }, + "timings": { + "dns": 2.742, + "connect": 10.03, + "ssl": 14.123, + "send": 0, + "wait": 15.023, + "receive": 2.477 + }, + "pageref": "page@8f314969edc000996eb5c2ab22f0e6b3", + "serverIPAddress": "151.101.189.52", + "_serverPort": 80, + "_securityDetails": {} + }, + { + "_frameref": "frame@3767e074ecde4cb8372abba2f6f9bb4f", + "_monotonicTime": 110928455.901, + "startedDateTime": "2022-06-16T21:41:24.050Z", + "time": 50.29199999999999, + "request": { + "method": "GET", + "url": "https://www.theverge.com/", + "httpVersion": "HTTP/2.0", + "cookies": [ + { + "name": "vmidv1", + "value": "9faf31ab-1415-4b90-b367-24b670205f41" + }, + { + "name": "_chorus_geoip_continent", + "value": "NA" + } + ], + "headers": [ + { + "name": ":authority", + "value": "www.theverge.com" + }, + { + "name": ":method", + "value": "GET" + }, + { + "name": ":path", + "value": "/" + }, + { + "name": ":scheme", + "value": "https" + }, + { + "name": "accept", + "value": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" + }, + { + "name": "accept-encoding", + "value": "gzip, deflate, br" + }, + { + "name": "accept-language", + "value": "en-US,en;q=0.9" + }, + { + "name": "cookie", + "value": "vmidv1=9faf31ab-1415-4b90-b367-24b670205f41; _chorus_geoip_continent=NA" + }, + { + "name": "sec-ch-ua", + "value": "\"Chromium\";v=\"103\", \".Not/A)Brand\";v=\"99\"" + }, + { + "name": "sec-ch-ua-mobile", + "value": "?0" + }, + { + "name": "sec-ch-ua-platform", + "value": "\"Linux\"" + }, + { + "name": "sec-fetch-dest", + "value": "document" + }, + { + "name": "sec-fetch-mode", + "value": "navigate" + }, + { + "name": "sec-fetch-site", + "value": "none" + }, + { + "name": "sec-fetch-user", + "value": "?1" + }, + { + "name": "upgrade-insecure-requests", + "value": "1" + }, + { + "name": "user-agent", + "value": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.42 Safari/537.36" + } + ], + "queryString": [], + "headersSize": 729, + "bodySize": 0 + }, + "response": { + "status": 200, + "statusText": "", + "httpVersion": "HTTP/2.0", + "cookies": [ + { + "name": "_chorus_geoip_continent", + "value": "NA" + }, + { + "name": "vmidv1", + "value": "40d8fd14-5ac3-4757-9e9c-efb106e82d3a", + "expires": "2027-06-15T21:41:24.000Z", + "domain": "www.theverge.com", + "path": "/", + "sameSite": "Lax", + "secure": true + } + ], + "headers": [ + { + "name": "accept-ranges", + "value": "bytes" + }, + { + "name": "age", + "value": "263" + }, + { + "name": "cache-control", + "value": "max-age=0, public, must-revalidate" + }, + { + "name": "content-encoding", + "value": "br" + }, + { + "name": "content-length", + "value": "14" + }, + { + "name": "content-security-policy", + "value": "default-src https: data: 'unsafe-inline' 'unsafe-eval'; child-src https: data: blob:; connect-src https: data: blob: ; font-src https: data:; img-src https: data: blob:; media-src https: data: blob:; object-src https:; script-src https: data: blob: 'unsafe-inline' 'unsafe-eval'; style-src https: 'unsafe-inline'; block-all-mixed-content; upgrade-insecure-requests" + }, + { + "name": "content-type", + "value": "text/html; charset=utf-8" + }, + { + "name": "date", + "value": "Thu, 16 Jun 2022 21:41:24 GMT" + }, + { + "name": "etag", + "value": "W/\"d498ef668223d015000070a66a181e85\"" + }, + { + "name": "link", + "value": "; rel=preload; as=fetch; crossorigin" + }, + { + "name": "referrer-policy", + "value": "strict-origin-when-cross-origin" + }, + { + "name": "server", + "value": "nginx" + }, + { + "name": "set-cookie", + "value": "_chorus_geoip_continent=NA; expires=Fri, 17 Jun 2022 21:41:24 GMT; path=/;" + }, + { + "name": "set-cookie", + "value": "vmidv1=40d8fd14-5ac3-4757-9e9c-efb106e82d3a;Expires=Tue, 15 Jun 2027 21:41:24 GMT;Domain=www.theverge.com;Path=/;SameSite=Lax;Secure" + }, + { + "name": "strict-transport-security", + "value": "max-age=31556952; preload" + }, + { + "name": "vary", + "value": "Accept-Encoding, X-Chorus-Unison-Testing, X-Chorus-Require-Privacy-Consent, X-Chorus-Restrict-In-Privacy-Consent-Region, Origin, X-Forwarded-Proto, Cookie, X-Chorus-Unison-Testing, X-Chorus-Require-Privacy-Consent, X-Chorus-Restrict-In-Privacy-Consent-Region" + }, + { + "name": "via", + "value": "1.1 varnish" + }, + { + "name": "x-cache", + "value": "HIT" + }, + { + "name": "x-cache-hits", + "value": "1" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "x-download-options", + "value": "noopen" + }, + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "x-permitted-cross-domain-policies", + "value": "none" + }, + { + "name": "x-request-id", + "value": "97363ad70e272e63641c0bb784fa06a01b848dfd" + }, + { + "name": "x-runtime", + "value": "0.257911" + }, + { + "name": "x-served-by", + "value": "cache-pao17436-PAO" + }, + { + "name": "x-timer", + "value": "S1655415684.075077,VS0,VE1" + }, + { + "name": "x-xss-protection", + "value": "1; mode=block" + } + ], + "content": { + "size": 14, + "mimeType": "text/html", + "compression": 0, + "text": "

hello

" + }, + "headersSize": 1742, + "bodySize": 48716, + "redirectURL": "", + "_transferSize": 48716 + }, + "cache": { + "beforeRequest": null, + "afterRequest": null + }, + "timings": { + "dns": 0.016, + "connect": 24.487, + "ssl": 17.406, + "send": 0, + "wait": 8.383, + "receive": -1 + }, + "pageref": "page@8f314969edc000996eb5c2ab22f0e6b3", + "serverIPAddress": "151.101.189.52", + "_serverPort": 443, + "_securityDetails": { + "protocol": "TLS 1.2", + "subjectName": "*.americanninjawarriornation.com", + "issuer": "GlobalSign Atlas R3 DV TLS CA 2022 Q1", + "validFrom": 1644853133, + "validTo": 1679153932 + } + } + ] + } +} diff --git a/tests/assets/har-sha1-main-response.txt b/tests/assets/har-sha1-main-response.txt new file mode 100644 index 0000000..dbe9dba --- /dev/null +++ b/tests/assets/har-sha1-main-response.txt @@ -0,0 +1 @@ +Hello, world \ No newline at end of file diff --git a/tests/assets/har-sha1.har b/tests/assets/har-sha1.har new file mode 100644 index 0000000..850b06d --- /dev/null +++ b/tests/assets/har-sha1.har @@ -0,0 +1,95 @@ +{ + "log": { + "version": "1.2", + "creator": { + "name": "Playwright", + "version": "1.23.0-next" + }, + "browser": { + "name": "chromium", + "version": "103.0.5060.33" + }, + "pages": [ + { + "startedDateTime": "2022-06-10T04:27:32.125Z", + "id": "page@b17b177f1c2e66459db3dcbe44636ffd", + "title": "Hey", + "pageTimings": { + "onContentLoad": 70, + "onLoad": 70 + } + } + ], + "entries": [ + { + "_frameref": "frame@c7467fc0f1f86f09fc3b0d727a3862ea", + "_monotonicTime": 270572145.898, + "startedDateTime": "2022-06-10T04:27:32.146Z", + "time": 8.286, + "request": { + "method": "GET", + "url": "http://no.playwright/", + "httpVersion": "HTTP/1.1", + "cookies": [], + "headers": [ + { + "name": "Accept", + "value": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" + }, + { + "name": "Upgrade-Insecure-Requests", + "value": "1" + }, + { + "name": "User-Agent", + "value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.33 Safari/537.36" + } + ], + "queryString": [], + "headersSize": 326, + "bodySize": 0 + }, + "response": { + "status": 200, + "statusText": "OK", + "httpVersion": "HTTP/1.1", + "cookies": [], + "headers": [ + { + "name": "content-length", + "value": "12" + }, + { + "name": "content-type", + "value": "text/html" + } + ], + "content": { + "size": 12, + "mimeType": "text/html", + "compression": 0, + "_file": "har-sha1-main-response.txt" + }, + "headersSize": 64, + "bodySize": 71, + "redirectURL": "", + "_transferSize": 71 + }, + "cache": { + "beforeRequest": null, + "afterRequest": null + }, + "timings": { + "dns": -1, + "connect": -1, + "ssl": -1, + "send": 0, + "wait": 8.286, + "receive": -1 + }, + "pageref": "page@b17b177f1c2e66459db3dcbe44636ffd", + "_securityDetails": {} + } + ] + } +} diff --git a/tests/assets/har.html b/tests/assets/har.html new file mode 100644 index 0000000..054bb0e --- /dev/null +++ b/tests/assets/har.html @@ -0,0 +1,3 @@ +HAR Page + +
hello, world!
diff --git a/tests/assets/headings.html b/tests/assets/headings.html new file mode 100644 index 0000000..ba770fa --- /dev/null +++ b/tests/assets/headings.html @@ -0,0 +1,15 @@ + + + + + Headings + + + +

Title

+

Subtitle

+

Subsubtitle

+

Subtitle

+ + + diff --git a/tests/assets/historyapi.html b/tests/assets/historyapi.html new file mode 100644 index 0000000..bacaf9e --- /dev/null +++ b/tests/assets/historyapi.html @@ -0,0 +1,5 @@ + diff --git a/tests/assets/injectedfile.js b/tests/assets/injectedfile.js new file mode 100644 index 0000000..377253c --- /dev/null +++ b/tests/assets/injectedfile.js @@ -0,0 +1,3 @@ +window.__injected = 42; +window.injected = 123; +window.__injectedError = new Error('hi'); diff --git a/tests/assets/injectedstyle.css b/tests/assets/injectedstyle.css new file mode 100644 index 0000000..aa1634c --- /dev/null +++ b/tests/assets/injectedstyle.css @@ -0,0 +1,3 @@ +body { + background-color: red; +} diff --git a/tests/assets/input/animating-button.html b/tests/assets/input/animating-button.html new file mode 100644 index 0000000..2946f2e --- /dev/null +++ b/tests/assets/input/animating-button.html @@ -0,0 +1,42 @@ + + diff --git a/tests/assets/input/button.html b/tests/assets/input/button.html new file mode 100644 index 0000000..5a2702c --- /dev/null +++ b/tests/assets/input/button.html @@ -0,0 +1,32 @@ + + + + Button test + + + + + + + diff --git a/tests/assets/input/checkbox.html b/tests/assets/input/checkbox.html new file mode 100644 index 0000000..ca56762 --- /dev/null +++ b/tests/assets/input/checkbox.html @@ -0,0 +1,42 @@ + + + + Selection Test + + + + + + + diff --git a/tests/assets/input/fileupload-multi.html b/tests/assets/input/fileupload-multi.html new file mode 100644 index 0000000..05dd5a2 --- /dev/null +++ b/tests/assets/input/fileupload-multi.html @@ -0,0 +1,12 @@ + + + + File upload test + + +
+ + +
+ + diff --git a/tests/assets/input/fileupload.html b/tests/assets/input/fileupload.html new file mode 100644 index 0000000..771dc4c --- /dev/null +++ b/tests/assets/input/fileupload.html @@ -0,0 +1,12 @@ + + + + File upload test + + +
+ + +
+ + diff --git a/tests/assets/input/folderupload.html b/tests/assets/input/folderupload.html new file mode 100644 index 0000000..b6a2693 --- /dev/null +++ b/tests/assets/input/folderupload.html @@ -0,0 +1,12 @@ + + + + Folder upload test + + +
+ + +
+ + diff --git a/tests/assets/input/handle-locator.html b/tests/assets/input/handle-locator.html new file mode 100644 index 0000000..f8f2111 --- /dev/null +++ b/tests/assets/input/handle-locator.html @@ -0,0 +1,91 @@ + + + + Interstitial test + + + +
+
A place on the side to hover
+
+
This interstitial covers the button
+ +
+ + + diff --git a/tests/assets/input/keyboard.html b/tests/assets/input/keyboard.html new file mode 100644 index 0000000..4788b0d --- /dev/null +++ b/tests/assets/input/keyboard.html @@ -0,0 +1,42 @@ + + + + Keyboard test + + + + + + diff --git a/tests/assets/input/mouse-helper.js b/tests/assets/input/mouse-helper.js new file mode 100644 index 0000000..3c4d570 --- /dev/null +++ b/tests/assets/input/mouse-helper.js @@ -0,0 +1,62 @@ +// This injects a box into the page that moves with the mouse; +// Useful for debugging +(function(){ + const box = document.createElement('div'); + box.classList.add('mouse-helper'); + const styleElement = document.createElement('style'); + styleElement.innerHTML = ` + .mouse-helper { + pointer-events: none; + position: absolute; + top: 0; + left: 0; + width: 20px; + height: 20px; + background: rgba(0,0,0,.4); + border: 1px solid white; + border-radius: 10px; + margin-left: -10px; + margin-top: -10px; + transition: background .2s, border-radius .2s, border-color .2s; + } + .mouse-helper.button-1 { + transition: none; + background: rgba(0,0,0,0.9); + } + .mouse-helper.button-2 { + transition: none; + border-color: rgba(0,0,255,0.9); + } + .mouse-helper.button-3 { + transition: none; + border-radius: 4px; + } + .mouse-helper.button-4 { + transition: none; + border-color: rgba(255,0,0,0.9); + } + .mouse-helper.button-5 { + transition: none; + border-color: rgba(0,255,0,0.9); + } + `; + document.head.appendChild(styleElement); + document.body.appendChild(box); + document.addEventListener('mousemove', event => { + box.style.left = event.pageX + 'px'; + box.style.top = event.pageY + 'px'; + updateButtons(event.buttons); + }, true); + document.addEventListener('mousedown', event => { + updateButtons(event.buttons); + box.classList.add('button-' + event.which); + }, true); + document.addEventListener('mouseup', event => { + updateButtons(event.buttons); + box.classList.remove('button-' + event.which); + }, true); + function updateButtons(buttons) { + for (let i = 0; i < 5; i++) + box.classList.toggle('button-' + i, buttons & (1 << i)); + } +})(); diff --git a/tests/assets/input/rotatedButton.html b/tests/assets/input/rotatedButton.html new file mode 100644 index 0000000..1bce66c --- /dev/null +++ b/tests/assets/input/rotatedButton.html @@ -0,0 +1,21 @@ + + + + Rotated button test + + + + + + + + diff --git a/tests/assets/input/scrollable.html b/tests/assets/input/scrollable.html new file mode 100644 index 0000000..2d81882 --- /dev/null +++ b/tests/assets/input/scrollable.html @@ -0,0 +1,23 @@ + + + + Scrollable test + + + + + + diff --git a/tests/assets/input/select.html b/tests/assets/input/select.html new file mode 100644 index 0000000..53dd06a --- /dev/null +++ b/tests/assets/input/select.html @@ -0,0 +1,69 @@ + + + + Selection Test + + + + + + diff --git a/tests/assets/input/textarea.html b/tests/assets/input/textarea.html new file mode 100644 index 0000000..86d4a58 --- /dev/null +++ b/tests/assets/input/textarea.html @@ -0,0 +1,20 @@ + + + + Textarea test + + + + +
+
Plain div
+ + + + diff --git a/tests/assets/input/touches.html b/tests/assets/input/touches.html new file mode 100644 index 0000000..6a0347d --- /dev/null +++ b/tests/assets/input/touches.html @@ -0,0 +1,35 @@ + + + + Touch test + + + + + + + diff --git a/tests/assets/mobile.html b/tests/assets/mobile.html new file mode 100644 index 0000000..8e94b2f --- /dev/null +++ b/tests/assets/mobile.html @@ -0,0 +1 @@ + diff --git a/tests/assets/networkidle.html b/tests/assets/networkidle.html new file mode 100644 index 0000000..ab10c97 --- /dev/null +++ b/tests/assets/networkidle.html @@ -0,0 +1 @@ + diff --git a/tests/assets/networkidle.js b/tests/assets/networkidle.js new file mode 100644 index 0000000..9d89984 --- /dev/null +++ b/tests/assets/networkidle.js @@ -0,0 +1,12 @@ +async function main() { + window.ws = new WebSocket('ws://localhost:' + window.location.port + '/ws'); + window.ws.addEventListener('message', message => {}); + + fetch('fetch-request-a.js'); + window.top.fetchSecond = () => { + // Do not return the promise here. + fetch('fetch-request-b.js'); + }; +} + +main(); diff --git a/tests/assets/offscreenbuttons.html b/tests/assets/offscreenbuttons.html new file mode 100644 index 0000000..b7f381d --- /dev/null +++ b/tests/assets/offscreenbuttons.html @@ -0,0 +1,55 @@ + +
+ + + + + + + + + + + +
+ diff --git a/tests/assets/one-style.css b/tests/assets/one-style.css new file mode 100644 index 0000000..7b26410 --- /dev/null +++ b/tests/assets/one-style.css @@ -0,0 +1,3 @@ +body { + background-color: pink; +} diff --git a/tests/assets/one-style.html b/tests/assets/one-style.html new file mode 100644 index 0000000..4760f2b --- /dev/null +++ b/tests/assets/one-style.html @@ -0,0 +1,2 @@ + +
hello, world!
diff --git a/tests/assets/playground.html b/tests/assets/playground.html new file mode 100644 index 0000000..de25516 --- /dev/null +++ b/tests/assets/playground.html @@ -0,0 +1,15 @@ + + + + Playground + + + + +
First div
+
+ Second div + Inner span +
+ + diff --git a/tests/assets/popup/popup.html b/tests/assets/popup/popup.html new file mode 100644 index 0000000..76a33e8 --- /dev/null +++ b/tests/assets/popup/popup.html @@ -0,0 +1,12 @@ + + + + Popup + + + + I am a popup + + diff --git a/tests/assets/popup/window-open.html b/tests/assets/popup/window-open.html new file mode 100644 index 0000000..d138be1 --- /dev/null +++ b/tests/assets/popup/window-open.html @@ -0,0 +1,11 @@ + + + + Popup test + + + + + diff --git a/tests/assets/pptr.png b/tests/assets/pptr.png new file mode 100644 index 0000000000000000000000000000000000000000..65d87c68e65902c058af18d2a595fc89f423f4ff GIT binary patch literal 6138 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 W{|p>bpZvrb0Q9tsH0#uzQ2zrM7gd%3 literal 0 HcmV?d00001 diff --git a/tests/assets/react.html b/tests/assets/react.html new file mode 100644 index 0000000..0377b48 --- /dev/null +++ b/tests/assets/react.html @@ -0,0 +1,33 @@ + + + + + +
+ + diff --git a/tests/assets/react/react-dom@16.13.1.production.min.js b/tests/assets/react/react-dom@16.13.1.production.min.js new file mode 100644 index 0000000..8ddde06 --- /dev/null +++ b/tests/assets/react/react-dom@16.13.1.production.min.js @@ -0,0 +1,239 @@ +/** @license React v16.13.1 + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/* + Modernizr 3.0.0pre (Custom Build) | MIT +*/ +'use strict';(function(I,ea){"object"===typeof exports&&"undefined"!==typeof module?ea(exports,require("react")):"function"===typeof define&&define.amd?define(["exports","react"],ea):(I=I||self,ea(I.ReactDOM={},I.React))})(this,function(I,ea){function k(a){for(var b="https://reactjs.org/docs/error-decoder.html?invariant="+a,c=1;cb}return!1}function L(a, +b,c,d,e,f){this.acceptsBooleans=2===b||3===b||4===b;this.attributeName=d;this.attributeNamespace=e;this.mustUseProperty=c;this.propertyName=a;this.type=b;this.sanitizeURL=f}function xd(a,b,c,d){var e=E.hasOwnProperty(b)?E[b]:null;var f=null!==e?0===e.type:d?!1:!(2=c.length))throw Error(k(93));c=c[0]}b=c}null==b&&(b="");c=b}a._wrapperState={initialValue:va(c)}}function Lf(a,b){var c=va(b.value),d=va(b.defaultValue);null!=c&&(c=""+c,c!==a.value&&(a.value=c),null==b.defaultValue&&a.defaultValue!==c&&(a.defaultValue=c));null!=d&&(a.defaultValue=""+d)}function Mf(a,b){b=a.textContent;b===a._wrapperState.initialValue&&""!== +b&&null!==b&&(a.value=b)}function Nf(a){switch(a){case "svg":return"http://www.w3.org/2000/svg";case "math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function Hd(a,b){return null==a||"http://www.w3.org/1999/xhtml"===a?Nf(b):"http://www.w3.org/2000/svg"===a&&"foreignObject"===b?"http://www.w3.org/1999/xhtml":a}function nc(a,b){var c={};c[a.toLowerCase()]=b.toLowerCase();c["Webkit"+a]="webkit"+b;c["Moz"+a]="moz"+b;return c}function oc(a){if(Id[a])return Id[a]; +if(!ib[a])return a;var b=ib[a],c;for(c in b)if(b.hasOwnProperty(c)&&c in Of)return Id[a]=b[c];return a}function Jd(a){var b=Pf.get(a);void 0===b&&(b=new Map,Pf.set(a,b));return b}function Na(a){var b=a,c=a;if(a.alternate)for(;b.return;)b=b.return;else{a=b;do b=a,0!==(b.effectTag&1026)&&(c=b.return),a=b.return;while(a)}return 3===b.tag?c:null}function Qf(a){if(13===a.tag){var b=a.memoizedState;null===b&&(a=a.alternate,null!==a&&(b=a.memoizedState));if(null!==b)return b.dehydrated}return null}function Rf(a){if(Na(a)!== +a)throw Error(k(188));}function vi(a){var b=a.alternate;if(!b){b=Na(a);if(null===b)throw Error(k(188));return b!==a?null:a}for(var c=a,d=b;;){var e=c.return;if(null===e)break;var f=e.alternate;if(null===f){d=e.return;if(null!==d){c=d;continue}break}if(e.child===f.child){for(f=e.child;f;){if(f===c)return Rf(e),a;if(f===d)return Rf(e),b;f=f.sibling}throw Error(k(188));}if(c.return!==d.return)c=e,d=f;else{for(var g=!1,h=e.child;h;){if(h===c){g=!0;c=e;d=f;break}if(h===d){g=!0;d=e;c=f;break}h=h.sibling}if(!g){for(h= +f.child;h;){if(h===c){g=!0;c=f;d=e;break}if(h===d){g=!0;d=f;c=e;break}h=h.sibling}if(!g)throw Error(k(189));}}if(c.alternate!==d)throw Error(k(190));}if(3!==c.tag)throw Error(k(188));return c.stateNode.current===c?a:b}function Sf(a){a=vi(a);if(!a)return null;for(var b=a;;){if(5===b.tag||6===b.tag)return b;if(b.child)b.child.return=b,b=b.child;else{if(b===a)break;for(;!b.sibling;){if(!b.return||b.return===a)return null;b=b.return}b.sibling.return=b.return;b=b.sibling}}return null}function jb(a,b){if(null== +b)throw Error(k(30));if(null==a)return b;if(Array.isArray(a)){if(Array.isArray(b))return a.push.apply(a,b),a;a.push(b);return a}return Array.isArray(b)?[a].concat(b):[a,b]}function Kd(a,b,c){Array.isArray(a)?a.forEach(b,c):a&&b.call(c,a)}function pc(a){null!==a&&(Ab=jb(Ab,a));a=Ab;Ab=null;if(a){Kd(a,wi);if(Ab)throw Error(k(95));if(hc)throw a=pd,hc=!1,pd=null,a;}}function Ld(a){a=a.target||a.srcElement||window;a.correspondingUseElement&&(a=a.correspondingUseElement);return 3===a.nodeType?a.parentNode: +a}function Tf(a){if(!wa)return!1;a="on"+a;var b=a in document;b||(b=document.createElement("div"),b.setAttribute(a,"return;"),b="function"===typeof b[a]);return b}function Uf(a){a.topLevelType=null;a.nativeEvent=null;a.targetInst=null;a.ancestors.length=0;10>qc.length&&qc.push(a)}function Vf(a,b,c,d){if(qc.length){var e=qc.pop();e.topLevelType=a;e.eventSystemFlags=d;e.nativeEvent=b;e.targetInst=c;return e}return{topLevelType:a,eventSystemFlags:d,nativeEvent:b,targetInst:c,ancestors:[]}}function Wf(a){var b= +a.targetInst,c=b;do{if(!c){a.ancestors.push(c);break}var d=c;if(3===d.tag)d=d.stateNode.containerInfo;else{for(;d.return;)d=d.return;d=3!==d.tag?null:d.stateNode.containerInfo}if(!d)break;b=c.tag;5!==b&&6!==b||a.ancestors.push(c);c=Bb(d)}while(c);for(c=0;c=b)return{node:c, +offset:b-a};a=d}a:{for(;c;){if(c.nextSibling){c=c.nextSibling;break a}c=c.parentNode}c=void 0}c=hg(c)}}function jg(a,b){return a&&b?a===b?!0:a&&3===a.nodeType?!1:b&&3===b.nodeType?jg(a,b.parentNode):"contains"in a?a.contains(b):a.compareDocumentPosition?!!(a.compareDocumentPosition(b)&16):!1:!1}function kg(){for(var a=window,b=Wd();b instanceof a.HTMLIFrameElement;){try{var c="string"===typeof b.contentWindow.location.href}catch(d){c=!1}if(c)a=b.contentWindow;else break;b=Wd(a.document)}return b} +function Xd(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return b&&("input"===b&&("text"===a.type||"search"===a.type||"tel"===a.type||"url"===a.type||"password"===a.type)||"textarea"===b||"true"===a.contentEditable)}function lg(a,b){switch(a){case "button":case "input":case "select":case "textarea":return!!b.autoFocus}return!1}function Yd(a,b){return"textarea"===a||"option"===a||"noscript"===a||"string"===typeof b.children||"number"===typeof b.children||"object"===typeof b.dangerouslySetInnerHTML&& +null!==b.dangerouslySetInnerHTML&&null!=b.dangerouslySetInnerHTML.__html}function kb(a){for(;null!=a;a=a.nextSibling){var b=a.nodeType;if(1===b||3===b)break}return a}function mg(a){a=a.previousSibling;for(var b=0;a;){if(8===a.nodeType){var c=a.data;if(c===ng||c===Zd||c===$d){if(0===b)return a;b--}else c===og&&b++}a=a.previousSibling}return null}function Bb(a){var b=a[Aa];if(b)return b;for(var c=a.parentNode;c;){if(b=c[Lb]||c[Aa]){c=b.alternate;if(null!==b.child||null!==c&&null!==c.child)for(a=mg(a);null!== +a;){if(c=a[Aa])return c;a=mg(a)}return b}a=c;c=a.parentNode}return null}function Hb(a){a=a[Aa]||a[Lb];return!a||5!==a.tag&&6!==a.tag&&13!==a.tag&&3!==a.tag?null:a}function Pa(a){if(5===a.tag||6===a.tag)return a.stateNode;throw Error(k(33));}function ae(a){return a[vc]||null}function pa(a){do a=a.return;while(a&&5!==a.tag);return a?a:null}function pg(a,b){var c=a.stateNode;if(!c)return null;var d=td(c);if(!d)return null;c=d[b];a:switch(b){case "onClick":case "onClickCapture":case "onDoubleClick":case "onDoubleClickCapture":case "onMouseDown":case "onMouseDownCapture":case "onMouseMove":case "onMouseMoveCapture":case "onMouseUp":case "onMouseUpCapture":case "onMouseEnter":(d= +!d.disabled)||(a=a.type,d=!("button"===a||"input"===a||"select"===a||"textarea"===a));a=!d;break a;default:a=!1}if(a)return null;if(c&&"function"!==typeof c)throw Error(k(231,b,typeof c));return c}function qg(a,b,c){if(b=pg(a,c.dispatchConfig.phasedRegistrationNames[b]))c._dispatchListeners=jb(c._dispatchListeners,b),c._dispatchInstances=jb(c._dispatchInstances,a)}function Ji(a){if(a&&a.dispatchConfig.phasedRegistrationNames){for(var b=a._targetInst,c=[];b;)c.push(b),b=pa(b);for(b=c.length;0this.eventPool.length&&this.eventPool.push(a)}function sg(a){a.eventPool=[];a.getPooled=Li;a.release=Mi}function tg(a,b){switch(a){case "keyup":return-1!==Ni.indexOf(b.keyCode);case "keydown":return 229!==b.keyCode;case "keypress":case "mousedown":case "blur":return!0;default:return!1}}function ug(a){a=a.detail;return"object"===typeof a&&"data"in +a?a.data:null}function Oi(a,b){switch(a){case "compositionend":return ug(b);case "keypress":if(32!==b.which)return null;vg=!0;return wg;case "textInput":return a=b.data,a===wg&&vg?null:a;default:return null}}function Pi(a,b){if(mb)return"compositionend"===a||!de&&tg(a,b)?(a=rg(),wc=ce=Ba=null,mb=!1,a):null;switch(a){case "paste":return null;case "keypress":if(!(b.ctrlKey||b.altKey||b.metaKey)||b.ctrlKey&&b.altKey){if(b.char&&1ob||(a.current=ie[ob],ie[ob]=null,ob--)}function y(a,b,c){ob++; +ie[ob]=a.current;a.current=b}function pb(a,b){var c=a.type.contextTypes;if(!c)return Ca;var d=a.stateNode;if(d&&d.__reactInternalMemoizedUnmaskedChildContext===b)return d.__reactInternalMemoizedMaskedChildContext;var e={},f;for(f in c)e[f]=b[f];d&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext=b,a.__reactInternalMemoizedMaskedChildContext=e);return e}function N(a){a=a.childContextTypes;return null!==a&&void 0!==a}function Fg(a,b,c){if(B.current!==Ca)throw Error(k(168));y(B,b);y(G,c)} +function Gg(a,b,c){var d=a.stateNode;a=b.childContextTypes;if("function"!==typeof d.getChildContext)return c;d=d.getChildContext();for(var e in d)if(!(e in a))throw Error(k(108,na(b)||"Unknown",e));return M({},c,{},d)}function Bc(a){a=(a=a.stateNode)&&a.__reactInternalMemoizedMergedChildContext||Ca;Ra=B.current;y(B,a);y(G,G.current);return!0}function Hg(a,b,c){var d=a.stateNode;if(!d)throw Error(k(169));c?(a=Gg(a,b,Ra),d.__reactInternalMemoizedMergedChildContext=a,q(G),q(B),y(B,a)):q(G);y(G,c)}function Cc(){switch(aj()){case Dc:return 99; +case Ig:return 98;case Jg:return 97;case Kg:return 96;case Lg:return 95;default:throw Error(k(332));}}function Mg(a){switch(a){case 99:return Dc;case 98:return Ig;case 97:return Jg;case 96:return Kg;case 95:return Lg;default:throw Error(k(332));}}function Da(a,b){a=Mg(a);return bj(a,b)}function Ng(a,b,c){a=Mg(a);return je(a,b,c)}function Og(a){null===qa?(qa=[a],Ec=je(Dc,Pg)):qa.push(a);return Qg}function ha(){if(null!==Ec){var a=Ec;Ec=null;Rg(a)}Pg()}function Pg(){if(!ke&&null!==qa){ke=!0;var a=0; +try{var b=qa;Da(99,function(){for(;a=b&&(ia=!0),a.firstContext=null)}function W(a,b){if(Gc!==a&&!1!==b&&0!==b){if("number"!==typeof b||1073741823===b)Gc=a,b=1073741823;b={context:a,observedBits:b,next:null};if(null===qb){if(null=== +Hc)throw Error(k(308));qb=b;Hc.dependencies={expirationTime:0,firstContext:b,responders:null}}else qb=qb.next=b}return a._currentValue}function ne(a){a.updateQueue={baseState:a.memoizedState,baseQueue:null,shared:{pending:null},effects:null}}function oe(a,b){a=a.updateQueue;b.updateQueue===a&&(b.updateQueue={baseState:a.baseState,baseQueue:a.baseQueue,shared:a.shared,effects:a.effects})}function Ea(a,b){a={expirationTime:a,suspenseConfig:b,tag:Tg,payload:null,callback:null,next:null};return a.next= +a}function Fa(a,b){a=a.updateQueue;if(null!==a){a=a.shared;var c=a.pending;null===c?b.next=b:(b.next=c.next,c.next=b);a.pending=b}}function Ug(a,b){var c=a.alternate;null!==c&&oe(c,a);a=a.updateQueue;c=a.baseQueue;null===c?(a.baseQueue=b.next=b,b.next=b):(b.next=c.next,c.next=b)}function Qb(a,b,c,d){var e=a.updateQueue;Ga=!1;var f=e.baseQueue,g=e.shared.pending;if(null!==g){if(null!==f){var h=f.next;f.next=g.next;g.next=h}f=g;e.shared.pending=null;h=a.alternate;null!==h&&(h=h.updateQueue,null!==h&& +(h.baseQueue=g))}if(null!==f){h=f.next;var m=e.baseState,n=0,k=null,ba=null,l=null;if(null!==h){var p=h;do{g=p.expirationTime;if(gn&&(n=g)}else{null!==l&&(l=l.next={expirationTime:1073741823,suspenseConfig:p.suspenseConfig,tag:p.tag,payload:p.payload,callback:p.callback,next:null});Vg(g,p.suspenseConfig);a:{var q=a,r=p;g=b;t=c;switch(r.tag){case 1:q= +r.payload;if("function"===typeof q){m=q.call(t,m,g);break a}m=q;break a;case 3:q.effectTag=q.effectTag&-4097|64;case Tg:q=r.payload;g="function"===typeof q?q.call(t,m,g):q;if(null===g||void 0===g)break a;m=M({},m,g);break a;case Jc:Ga=!0}}null!==p.callback&&(a.effectTag|=32,g=e.effects,null===g?e.effects=[p]:g.push(p))}p=p.next;if(null===p||p===h)if(g=e.shared.pending,null===g)break;else p=f.next=g.next,g.next=h,e.baseQueue=f=g,e.shared.pending=null}while(1)}null===l?k=m:l.next=ba;e.baseState=k;e.baseQueue= +l;Kc(n);a.expirationTime=n;a.memoizedState=m}}function Wg(a,b,c){a=b.effects;b.effects=null;if(null!==a)for(b=0;br?(C=l,l=null):C=l.sibling;var O=p(e,l,h[r],m);if(null===O){null===l&&(l=C);break}a&&l&&null===O.alternate&&b(e,l);g=f(O,g,r);null===k?n=O:k.sibling=O;k=O;l=C}if(r===h.length)return c(e,l),n;if(null===l){for(;rC?(O=r,r=null):O=r.sibling;var q=p(e,r,v.value,n);if(null===q){null===r&&(r=O);break}a&&r&&null===q.alternate&&b(e,r);g=f(q,g,C);null===l?m=q:l.sibling=q;l=q;r=O}if(v.done)return c(e,r),m; +if(null===r){for(;!v.done;C++,v=h.next())v=ba(e,v.value,n),null!==v&&(g=f(v,g,C),null===l?m=v:l.sibling=v,l=v);return m}for(r=d(e,r);!v.done;C++,v=h.next())v=t(r,e,C,v.value,n),null!==v&&(a&&null!==v.alternate&&r.delete(null===v.key?C:v.key),g=f(v,g,C),null===l?m=v:l.sibling=v,l=v);a&&r.forEach(function(a){return b(e,a)});return m}return function(a,d,f,h){var m="object"===typeof f&&null!==f&&f.type===Ma&&null===f.key;m&&(f=f.props.children);var n="object"===typeof f&&null!==f;if(n)switch(f.$$typeof){case Pc:a:{n= +f.key;for(m=d;null!==m;){if(m.key===n){switch(m.tag){case 7:if(f.type===Ma){c(a,m.sibling);d=e(m,f.props.children);d.return=a;a=d;break a}break;default:if(m.elementType===f.type){c(a,m.sibling);d=e(m,f.props);d.ref=Rb(a,m,f);d.return=a;a=d;break a}}c(a,m);break}else b(a,m);m=m.sibling}f.type===Ma?(d=Ha(f.props.children,a.mode,h,f.key),d.return=a,a=d):(h=Oc(f.type,f.key,f.props,null,a.mode,h),h.ref=Rb(a,d,f),h.return=a,a=h)}return g(a);case gb:a:{for(m=f.key;null!==d;){if(d.key===m)if(4===d.tag&&d.stateNode.containerInfo=== +f.containerInfo&&d.stateNode.implementation===f.implementation){c(a,d.sibling);d=e(d,f.children||[]);d.return=a;a=d;break a}else{c(a,d);break}else b(a,d);d=d.sibling}d=re(f,a.mode,h);d.return=a;a=d}return g(a)}if("string"===typeof f||"number"===typeof f)return f=""+f,null!==d&&6===d.tag?(c(a,d.sibling),d=e(d,f),d.return=a,a=d):(c(a,d),d=qe(f,a.mode,h),d.return=a,a=d),g(a);if(Qc(f))return q(a,d,f,h);if(zb(f))return w(a,d,f,h);n&&Nc(a,f);if("undefined"===typeof f&&!m)switch(a.tag){case 1:case 0:throw a= +a.type,Error(k(152,a.displayName||a.name||"Component"));}return c(a,d)}}function Ta(a){if(a===Sb)throw Error(k(174));return a}function se(a,b){y(Tb,b);y(Ub,a);y(ja,Sb);a=b.nodeType;switch(a){case 9:case 11:b=(b=b.documentElement)?b.namespaceURI:Hd(null,"");break;default:a=8===a?b.parentNode:b,b=a.namespaceURI||null,a=a.tagName,b=Hd(b,a)}q(ja);y(ja,b)}function tb(a){q(ja);q(Ub);q(Tb)}function bh(a){Ta(Tb.current);var b=Ta(ja.current);var c=Hd(b,a.type);b!==c&&(y(Ub,a),y(ja,c))}function te(a){Ub.current=== +a&&(q(ja),q(Ub))}function Rc(a){for(var b=a;null!==b;){if(13===b.tag){var c=b.memoizedState;if(null!==c&&(c=c.dehydrated,null===c||c.data===$d||c.data===Zd))return b}else if(19===b.tag&&void 0!==b.memoizedProps.revealOrder){if(0!==(b.effectTag&64))return b}else if(null!==b.child){b.child.return=b;b=b.child;continue}if(b===a)break;for(;null===b.sibling;){if(null===b.return||b.return===a)return null;b=b.return}b.sibling.return=b.return;b=b.sibling}return null}function ue(a,b){return{responder:a,props:b}} +function S(){throw Error(k(321));}function ve(a,b){if(null===b)return!1;for(var c=0;cf))throw Error(k(301));f+=1;J=K=null;b.updateQueue=null;Sc.current=fj;a=c(d,e)}while(b.expirationTime===Ia)}Sc.current=Tc;b=null!==K&&null!==K.next; +Ia=0;J=K=z=null;Uc=!1;if(b)throw Error(k(300));return a}function ub(){var a={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};null===J?z.memoizedState=J=a:J=J.next=a;return J}function vb(){if(null===K){var a=z.alternate;a=null!==a?a.memoizedState:null}else a=K.next;var b=null===J?z.memoizedState:J.next;if(null!==b)J=b,K=a;else{if(null===a)throw Error(k(310));K=a;a={memoizedState:K.memoizedState,baseState:K.baseState,baseQueue:K.baseQueue,queue:K.queue,next:null};null===J?z.memoizedState= +J=a:J=J.next=a}return J}function Ua(a,b){return"function"===typeof b?b(a):b}function Vc(a,b,c){b=vb();c=b.queue;if(null===c)throw Error(k(311));c.lastRenderedReducer=a;var d=K,e=d.baseQueue,f=c.pending;if(null!==f){if(null!==e){var g=e.next;e.next=f.next;f.next=g}d.baseQueue=e=f;c.pending=null}if(null!==e){e=e.next;d=d.baseState;var h=g=f=null,m=e;do{var n=m.expirationTime;if(nz.expirationTime&&(z.expirationTime=n,Kc(n))}else null!==h&&(h=h.next={expirationTime:1073741823,suspenseConfig:m.suspenseConfig,action:m.action,eagerReducer:m.eagerReducer,eagerState:m.eagerState,next:null}),Vg(n,m.suspenseConfig),d=m.eagerReducer===a?m.eagerState:a(d,m.action);m=m.next}while(null!==m&&m!==e);null===h?f=d:h.next=g;Qa(d,b.memoizedState)||(ia=!0);b.memoizedState=d;b.baseState=f;b.baseQueue=h;c.lastRenderedState=d}return[b.memoizedState, +c.dispatch]}function Wc(a,b,c){b=vb();c=b.queue;if(null===c)throw Error(k(311));c.lastRenderedReducer=a;var d=c.dispatch,e=c.pending,f=b.memoizedState;if(null!==e){c.pending=null;var g=e=e.next;do f=a(f,g.action),g=g.next;while(g!==e);Qa(f,b.memoizedState)||(ia=!0);b.memoizedState=f;null===b.baseQueue&&(b.baseState=f);c.lastRenderedState=f}return[f,d]}function xe(a){var b=ub();"function"===typeof a&&(a=a());b.memoizedState=b.baseState=a;a=b.queue={pending:null,dispatch:null,lastRenderedReducer:Ua, +lastRenderedState:a};a=a.dispatch=ch.bind(null,z,a);return[b.memoizedState,a]}function ye(a,b,c,d){a={tag:a,create:b,destroy:c,deps:d,next:null};b=z.updateQueue;null===b?(b={lastEffect:null},z.updateQueue=b,b.lastEffect=a.next=a):(c=b.lastEffect,null===c?b.lastEffect=a.next=a:(d=c.next,c.next=a,a.next=d,b.lastEffect=a));return a}function dh(a){return vb().memoizedState}function ze(a,b,c,d){var e=ub();z.effectTag|=a;e.memoizedState=ye(1|b,c,void 0,void 0===d?null:d)}function Ae(a,b,c,d){var e=vb(); +d=void 0===d?null:d;var f=void 0;if(null!==K){var g=K.memoizedState;f=g.destroy;if(null!==d&&ve(d,g.deps)){ye(b,c,f,d);return}}z.effectTag|=a;e.memoizedState=ye(1|b,c,f,d)}function eh(a,b){return ze(516,4,a,b)}function Xc(a,b){return Ae(516,4,a,b)}function fh(a,b){return Ae(4,2,a,b)}function gh(a,b){if("function"===typeof b)return a=a(),b(a),function(){b(null)};if(null!==b&&void 0!==b)return a=a(),b.current=a,function(){b.current=null}}function hh(a,b,c){c=null!==c&&void 0!==c?c.concat([a]):null; +return Ae(4,2,gh.bind(null,b,a),c)}function Be(a,b){}function ih(a,b){ub().memoizedState=[a,void 0===b?null:b];return a}function Yc(a,b){var c=vb();b=void 0===b?null:b;var d=c.memoizedState;if(null!==d&&null!==b&&ve(b,d[1]))return d[0];c.memoizedState=[a,b];return a}function jh(a,b){var c=vb();b=void 0===b?null:b;var d=c.memoizedState;if(null!==d&&null!==b&&ve(b,d[1]))return d[0];a=a();c.memoizedState=[a,b];return a}function Ce(a,b,c){var d=Cc();Da(98>d?98:d,function(){a(!0)});Da(97\x3c/script>",a=a.removeChild(a.firstChild)):"string"===typeof d.is?a=g.createElement(e,{is:d.is}):(a=g.createElement(e),"select"===e&&(g=a,d.multiple?g.multiple=!0:d.size&&(g.size=d.size))):a=g.createElementNS(a,e);a[Aa]=b;a[vc]=d;jj(a,b,!1,!1);b.stateNode=a;g=Vd(e,d);switch(e){case "iframe":case "object":case "embed":w("load",a);h=d;break;case "video":case "audio":for(h=0;hd.tailExpiration&& +1a?c:a;return 2>=a&&b!==a?0:a}function V(a){if(0!==a.lastExpiredTime)a.callbackExpirationTime=1073741823,a.callbackPriority=99,a.callbackNode=Og(Te.bind(null,a));else{var b=fd(a),c=a.callbackNode;if(0===b)null!==c&&(a.callbackNode=null,a.callbackExpirationTime=0,a.callbackPriority=90);else{var d=ka(); +1073741823===b?d=99:1===b||2===b?d=95:(d=10*(1073741821-b)-10*(1073741821-d),d=0>=d?99:250>=d?98:5250>=d?97:95);if(null!==c){var e=a.callbackPriority;if(a.callbackExpirationTime===b&&e>=d)return;c!==Qg&&Rg(c)}a.callbackExpirationTime=b;a.callbackPriority=d;b=1073741823===b?Og(Te.bind(null,a)):Ng(d,Lh.bind(null,a),{timeout:10*(1073741821-b)-Y()});a.callbackNode=b}}}function Lh(a,b){dd=0;if(b)return b=ka(),Ue(a,b),V(a),null;var c=fd(a);if(0!==c){b=a.callbackNode;if((p&(ca|ma))!==H)throw Error(k(327)); +xb();a===U&&c===P||$a(a,c);if(null!==t){var d=p;p|=ca;var e=Mh();do try{rj();break}catch(h){Nh(a,h)}while(1);le();p=d;gd.current=e;if(F===hd)throw b=id,$a(a,c),Ya(a,c),V(a),b;if(null===t)switch(e=a.finishedWork=a.current.alternate,a.finishedExpirationTime=c,d=F,U=null,d){case Xa:case hd:throw Error(k(345));case Oh:Ue(a,2=c){a.lastPingedTime= +c;$a(a,c);break}}f=fd(a);if(0!==f&&f!==c)break;if(0!==d&&d!==c){a.lastPingedTime=d;break}a.timeoutHandle=We(ab.bind(null,a),e);break}ab(a);break;case bd:Ya(a,c);d=a.lastSuspendedTime;c===d&&(a.nextKnownPendingLevel=Ve(e));if(jd&&(e=a.lastPingedTime,0===e||e>=c)){a.lastPingedTime=c;$a(a,c);break}e=fd(a);if(0!==e&&e!==c)break;if(0!==d&&d!==c){a.lastPingedTime=d;break}1073741823!==Yb?d=10*(1073741821-Yb)-Y():1073741823===ta?d=0:(d=10*(1073741821-ta)-5E3,e=Y(),c=10*(1073741821-c)-e,d=e-d,0>d&&(d=0),d= +(120>d?120:480>d?480:1080>d?1080:1920>d?1920:3E3>d?3E3:4320>d?4320:1960*sj(d/1960))-d,c=d?d=0:(e=g.busyDelayMs|0,f=Y()-(10*(1073741821-f)-(g.timeoutMs|0||5E3)),d=f<=e?0:e+d-f);if(10 component higher in the tree to provide a loading indicator or placeholder to display."+ +Bd(g))}F!==Xe&&(F=Oh);h=Le(h,g);k=f;do{switch(k.tag){case 3:m=h;k.effectTag|=4096;k.expirationTime=b;var A=Ih(k,m,b);Ug(k,A);break a;case 1:m=h;var u=k.type,B=k.stateNode;if(0===(k.effectTag&64)&&("function"===typeof u.getDerivedStateFromError||null!==B&&"function"===typeof B.componentDidCatch&&(null===La||!La.has(B)))){k.effectTag|=4096;k.expirationTime=b;var H=Jh(k,m,b);Ug(k,H);break a}}k=k.return}while(null!==k)}t=Sh(t)}catch(cj){b=cj;continue}break}while(1)}function Mh(a){a=gd.current;gd.current= +Tc;return null===a?Tc:a}function Vg(a,b){aXb&&(Xb=a)}function tj(){for(;null!==t;)t=Th(t)}function rj(){for(;null!==t&&!yj();)t=Th(t)}function Th(a){var b=zj(a.alternate,a,P);a.memoizedProps=a.pendingProps;null===b&&(b=Sh(a));Uh.current=null;return b}function Sh(a){t=a;do{var b=t.alternate;a=t.return;if(0===(t.effectTag&2048)){b=hj(b,t,P);if(1===P||1!==t.childExpirationTime){for(var c=0,d=t.child;null!==d;){var e=d.expirationTime, +f=d.childExpirationTime;e>c&&(c=e);f>c&&(c=f);d=d.sibling}t.childExpirationTime=c}if(null!==b)return b;null!==a&&0===(a.effectTag&2048)&&(null===a.firstEffect&&(a.firstEffect=t.firstEffect),null!==t.lastEffect&&(null!==a.lastEffect&&(a.lastEffect.nextEffect=t.firstEffect),a.lastEffect=t.lastEffect),1a?b:a}function ab(a){var b=Cc();Da(99,Aj.bind(null,a,b));return null}function Aj(a,b){do xb();while(null!==Zb);if((p&(ca|ma))!==H)throw Error(k(327));var c=a.finishedWork,d=a.finishedExpirationTime;if(null===c)return null;a.finishedWork=null;a.finishedExpirationTime=0;if(c===a.current)throw Error(k(177));a.callbackNode=null;a.callbackExpirationTime= +0;a.callbackPriority=90;a.nextKnownPendingLevel=0;var e=Ve(c);a.firstPendingTime=e;d<=a.lastSuspendedTime?a.firstSuspendedTime=a.lastSuspendedTime=a.nextKnownPendingLevel=0:d<=a.firstSuspendedTime&&(a.firstSuspendedTime=d-1);d<=a.lastPingedTime&&(a.lastPingedTime=0);d<=a.lastExpiredTime&&(a.lastExpiredTime=0);a===U&&(t=U=null,P=0);1h&&(n=h,h=g,g=n),n=ig(x,g),q=ig(x,h),n&&q&&(1!==u.rangeCount||u.anchorNode!==n.node||u.anchorOffset!==n.offset||u.focusNode!==q.node||u.focusOffset!==q.offset)&&(A=A.createRange(), +A.setStart(n.node,n.offset),u.removeAllRanges(),g>h?(u.addRange(A),u.extend(q.node,q.offset)):(A.setEnd(q.node,q.offset),u.addRange(A))))));A=[];for(u=x;u=u.parentNode;)1===u.nodeType&&A.push({element:u,left:u.scrollLeft,top:u.scrollTop});"function"===typeof x.focus&&x.focus();for(x=0;x=b&&a<=b}function Ya(a,b){var c=a.firstSuspendedTime,d=a.lastSuspendedTime; +cb||0===c)a.lastSuspendedTime=b;b<=a.lastPingedTime&&(a.lastPingedTime=0);b<=a.lastExpiredTime&&(a.lastExpiredTime=0)}function yh(a,b){b>a.firstPendingTime&&(a.firstPendingTime=b);var c=a.firstSuspendedTime;0!==c&&(b>=c?a.firstSuspendedTime=a.lastSuspendedTime=a.nextKnownPendingLevel=0:b>=a.lastSuspendedTime&&(a.lastSuspendedTime=b+1),b>a.nextKnownPendingLevel&&(a.nextKnownPendingLevel=b))}function Ue(a,b){var c=a.lastExpiredTime;if(0===c||c>b)a.lastExpiredTime=b} +function md(a,b,c,d){var e=b.current,f=ka(),g=Vb.suspense;f=Va(f,e,g);a:if(c){c=c._reactInternalFiber;b:{if(Na(c)!==c||1!==c.tag)throw Error(k(170));var h=c;do{switch(h.tag){case 3:h=h.stateNode.context;break b;case 1:if(N(h.type)){h=h.stateNode.__reactInternalMemoizedMergedChildContext;break b}}h=h.return}while(null!==h);throw Error(k(171));}if(1===c.tag){var m=c.type;if(N(m)){c=Gg(c,m,h);break a}}c=h}else c=Ca;null===b.context?b.context=c:b.pendingContext=c;b=Ea(f,g);b.payload={element:a};d=void 0=== +d?null:d;null!==d&&(b.callback=d);Fa(e,b);Ja(e,f);return f}function cf(a){a=a.current;if(!a.child)return null;switch(a.child.tag){case 5:return a.child.stateNode;default:return a.child.stateNode}}function Wh(a,b){a=a.memoizedState;null!==a&&null!==a.dehydrated&&a.retryTime