Full Code of microsoft/playwright-python for AI

main 3aecfcfded42 cached
379 files
3.6 MB
953.0k tokens
4795 symbols
1 requests
Download .txt
Showing preview only (3,805K chars total). Download the full file or copy to clipboard to get everything.
Repository: microsoft/playwright-python
Branch: main
Commit: 3aecfcfded42
Files: 379
Total size: 3.6 MB

Directory structure:
gitextract_t_9ditla/

├── .azure-pipelines/
│   ├── guardian/
│   │   └── SDL/
│   │       └── .gdnsuppress
│   └── publish.yml
├── .claude/
│   └── skills/
│       └── playwright-roll/
│           └── SKILL.md
├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug.yml
│   │   ├── config.yml
│   │   ├── documentation.yml
│   │   ├── feature.yml
│   │   ├── question.yml
│   │   └── regression.yml
│   ├── dependabot.yml
│   └── workflows/
│       ├── ci.yml
│       ├── publish.yml
│       ├── publish_docker.yml
│       └── test_docker.yml
├── .gitignore
├── .pre-commit-config.yaml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── ROLLING.md
├── SECURITY.md
├── SUPPORT.md
├── conda_build_config_linux_aarch64.yaml
├── conda_build_config_osx_arm64.yaml
├── examples/
│   └── todomvc/
│       ├── mvctests/
│       │   ├── __init__.py
│       │   ├── test_clear_completed_button.py
│       │   ├── test_counter.py
│       │   ├── test_editing.py
│       │   ├── test_item.py
│       │   ├── test_mark_all_as_completed.py
│       │   ├── test_new_todo.py
│       │   ├── test_persistence.py
│       │   ├── test_routing.py
│       │   └── utils.py
│       └── requirements.txt
├── local-requirements.txt
├── meta.yaml
├── playwright/
│   ├── __init__.py
│   ├── __main__.py
│   ├── _impl/
│   │   ├── __init__.py
│   │   ├── __pyinstaller/
│   │   │   ├── __init__.py
│   │   │   ├── hook-playwright.async_api.py
│   │   │   └── hook-playwright.sync_api.py
│   │   ├── _api_structures.py
│   │   ├── _artifact.py
│   │   ├── _assertions.py
│   │   ├── _async_base.py
│   │   ├── _browser.py
│   │   ├── _browser_context.py
│   │   ├── _browser_type.py
│   │   ├── _cdp_session.py
│   │   ├── _clock.py
│   │   ├── _connection.py
│   │   ├── _console_message.py
│   │   ├── _dialog.py
│   │   ├── _download.py
│   │   ├── _driver.py
│   │   ├── _element_handle.py
│   │   ├── _errors.py
│   │   ├── _event_context_manager.py
│   │   ├── _fetch.py
│   │   ├── _file_chooser.py
│   │   ├── _frame.py
│   │   ├── _glob.py
│   │   ├── _greenlets.py
│   │   ├── _har_router.py
│   │   ├── _helper.py
│   │   ├── _impl_to_api_mapping.py
│   │   ├── _input.py
│   │   ├── _js_handle.py
│   │   ├── _json_pipe.py
│   │   ├── _local_utils.py
│   │   ├── _locator.py
│   │   ├── _map.py
│   │   ├── _network.py
│   │   ├── _object_factory.py
│   │   ├── _page.py
│   │   ├── _path_utils.py
│   │   ├── _playwright.py
│   │   ├── _selectors.py
│   │   ├── _set_input_files_helpers.py
│   │   ├── _str_utils.py
│   │   ├── _stream.py
│   │   ├── _sync_base.py
│   │   ├── _tracing.py
│   │   ├── _transport.py
│   │   ├── _video.py
│   │   ├── _waiter.py
│   │   ├── _web_error.py
│   │   └── _writable_stream.py
│   ├── async_api/
│   │   ├── __init__.py
│   │   ├── _context_manager.py
│   │   └── _generated.py
│   ├── py.typed
│   └── sync_api/
│       ├── __init__.py
│       ├── _context_manager.py
│       └── _generated.py
├── pyproject.toml
├── requirements.txt
├── scripts/
│   ├── documentation_provider.py
│   ├── example_async.py
│   ├── example_sync.py
│   ├── expected_api_mismatch.txt
│   ├── generate_api.py
│   ├── generate_async_api.py
│   ├── generate_sync_api.py
│   ├── update_api.sh
│   └── update_versions.py
├── setup.cfg
├── setup.py
├── tests/
│   ├── __init__.py
│   ├── assets/
│   │   ├── beforeunload.html
│   │   ├── client-certificates/
│   │   │   ├── README.md
│   │   │   ├── client/
│   │   │   │   ├── localhost/
│   │   │   │   │   ├── localhost.csr
│   │   │   │   │   ├── localhost.ext
│   │   │   │   │   ├── localhost.key
│   │   │   │   │   └── localhost.pem
│   │   │   │   ├── self-signed/
│   │   │   │   │   ├── cert.pem
│   │   │   │   │   ├── csr.pem
│   │   │   │   │   └── key.pem
│   │   │   │   └── trusted/
│   │   │   │       ├── cert-legacy.pfx
│   │   │   │       ├── cert.pem
│   │   │   │       ├── cert.pfx
│   │   │   │       ├── csr.pem
│   │   │   │       └── key.pem
│   │   │   ├── generate.sh
│   │   │   └── server/
│   │   │       ├── server_cert.pem
│   │   │       └── server_key.pem
│   │   ├── client.py
│   │   ├── consolelog.html
│   │   ├── csp.html
│   │   ├── dom.html
│   │   ├── download-blob.html
│   │   ├── drag-n-drop.html
│   │   ├── dummy_bad_browser_executable.js
│   │   ├── empty.html
│   │   ├── error.html
│   │   ├── es6/
│   │   │   ├── .eslintrc
│   │   │   ├── es6import.js
│   │   │   ├── es6module.js
│   │   │   └── es6pathimport.js
│   │   ├── extension-mv3-simple/
│   │   │   ├── content-script.js
│   │   │   ├── index.js
│   │   │   └── manifest.json
│   │   ├── extension-mv3-with-logging/
│   │   │   ├── background.js
│   │   │   ├── content.js
│   │   │   └── manifest.json
│   │   ├── file-to-upload-2.txt
│   │   ├── file-to-upload.txt
│   │   ├── frames/
│   │   │   ├── child-redirect.html
│   │   │   ├── frame.html
│   │   │   ├── frameset.html
│   │   │   ├── nested-frames.html
│   │   │   ├── one-frame.html
│   │   │   ├── redirect-my-parent.html
│   │   │   ├── script.js
│   │   │   ├── style.css
│   │   │   └── two-frames.html
│   │   ├── geolocation.html
│   │   ├── global-var.html
│   │   ├── grid.html
│   │   ├── har-fulfill.har
│   │   ├── har-redirect.har
│   │   ├── har-sha1-main-response.txt
│   │   ├── har-sha1.har
│   │   ├── har.html
│   │   ├── headings.html
│   │   ├── historyapi.html
│   │   ├── injectedfile.js
│   │   ├── injectedstyle.css
│   │   ├── input/
│   │   │   ├── animating-button.html
│   │   │   ├── button.html
│   │   │   ├── checkbox.html
│   │   │   ├── fileupload-multi.html
│   │   │   ├── fileupload.html
│   │   │   ├── folderupload.html
│   │   │   ├── handle-locator.html
│   │   │   ├── keyboard.html
│   │   │   ├── mouse-helper.js
│   │   │   ├── rotatedButton.html
│   │   │   ├── scrollable.html
│   │   │   ├── select.html
│   │   │   ├── textarea.html
│   │   │   └── touches.html
│   │   ├── mobile.html
│   │   ├── networkidle.html
│   │   ├── networkidle.js
│   │   ├── offscreenbuttons.html
│   │   ├── one-style.css
│   │   ├── one-style.html
│   │   ├── playground.html
│   │   ├── popup/
│   │   │   ├── popup.html
│   │   │   └── window-open.html
│   │   ├── react.html
│   │   ├── sectionselectorengine.js
│   │   ├── self-request.html
│   │   ├── serviceworkers/
│   │   │   ├── empty/
│   │   │   │   ├── sw.html
│   │   │   │   └── sw.js
│   │   │   ├── fetch/
│   │   │   │   ├── style.css
│   │   │   │   ├── sw.html
│   │   │   │   └── sw.js
│   │   │   └── fetchdummy/
│   │   │       ├── sw.html
│   │   │       └── sw.js
│   │   ├── shadow.html
│   │   ├── simple.json
│   │   ├── title.html
│   │   ├── worker/
│   │   │   ├── worker.html
│   │   │   └── worker.js
│   │   └── wrappedlink.html
│   ├── async/
│   │   ├── __init__.py
│   │   ├── conftest.py
│   │   ├── test_add_init_script.py
│   │   ├── test_assertions.py
│   │   ├── test_asyncio.py
│   │   ├── test_browser.py
│   │   ├── test_browsercontext.py
│   │   ├── test_browsercontext_add_cookies.py
│   │   ├── test_browsercontext_clearcookies.py
│   │   ├── test_browsercontext_client_certificates.py
│   │   ├── test_browsercontext_cookies.py
│   │   ├── test_browsercontext_events.py
│   │   ├── test_browsercontext_proxy.py
│   │   ├── test_browsercontext_request_fallback.py
│   │   ├── test_browsercontext_request_intercept.py
│   │   ├── test_browsercontext_route.py
│   │   ├── test_browsercontext_service_worker_policy.py
│   │   ├── test_browsercontext_storage_state.py
│   │   ├── test_browsertype_connect.py
│   │   ├── test_browsertype_connect_cdp.py
│   │   ├── test_cdp_session.py
│   │   ├── test_check.py
│   │   ├── test_chromium_tracing.py
│   │   ├── test_click.py
│   │   ├── test_console.py
│   │   ├── test_context_manager.py
│   │   ├── test_defaultbrowsercontext.py
│   │   ├── test_device_descriptors.py
│   │   ├── test_dialog.py
│   │   ├── test_dispatch_event.py
│   │   ├── test_download.py
│   │   ├── test_element_handle.py
│   │   ├── test_element_handle_wait_for_element_state.py
│   │   ├── test_emulation_focus.py
│   │   ├── test_expect_misc.py
│   │   ├── test_extension.py
│   │   ├── test_fetch_browser_context.py
│   │   ├── test_fetch_global.py
│   │   ├── test_fill.py
│   │   ├── test_focus.py
│   │   ├── test_frames.py
│   │   ├── test_geolocation.py
│   │   ├── test_har.py
│   │   ├── test_headful.py
│   │   ├── test_ignore_https_errors.py
│   │   ├── test_input.py
│   │   ├── test_issues.py
│   │   ├── test_jshandle.py
│   │   ├── test_keyboard.py
│   │   ├── test_launcher.py
│   │   ├── test_listeners.py
│   │   ├── test_locators.py
│   │   ├── test_navigation.py
│   │   ├── test_network.py
│   │   ├── test_page.py
│   │   ├── test_page_add_locator_handler.py
│   │   ├── test_page_aria_snapshot.py
│   │   ├── test_page_base_url.py
│   │   ├── test_page_clock.py
│   │   ├── test_page_evaluate.py
│   │   ├── test_page_event_console.py
│   │   ├── test_page_event_pageerror.py
│   │   ├── test_page_event_request.py
│   │   ├── test_page_network_request.py
│   │   ├── test_page_network_response.py
│   │   ├── test_page_request_fallback.py
│   │   ├── test_page_request_gc.py
│   │   ├── test_page_request_intercept.py
│   │   ├── test_page_route.py
│   │   ├── test_page_select_option.py
│   │   ├── test_pdf.py
│   │   ├── test_popup.py
│   │   ├── test_proxy.py
│   │   ├── test_queryselector.py
│   │   ├── test_request_continue.py
│   │   ├── test_request_fulfill.py
│   │   ├── test_request_intercept.py
│   │   ├── test_resource_timing.py
│   │   ├── test_route_web_socket.py
│   │   ├── test_screenshot.py
│   │   ├── test_selector_generator.py
│   │   ├── test_selectors_get_by.py
│   │   ├── test_selectors_misc.py
│   │   ├── test_selectors_text.py
│   │   ├── test_tap.py
│   │   ├── test_tracing.py
│   │   ├── test_unroute_behavior.py
│   │   ├── test_video.py
│   │   ├── test_wait_for_function.py
│   │   ├── test_wait_for_url.py
│   │   ├── test_websocket.py
│   │   ├── test_worker.py
│   │   └── utils.py
│   ├── common/
│   │   ├── __init__.py
│   │   ├── test_collect_handles.py
│   │   ├── test_events.py
│   │   ├── test_signals.py
│   │   └── test_threads.py
│   ├── conftest.py
│   ├── server.py
│   ├── sync/
│   │   ├── __init__.py
│   │   ├── conftest.py
│   │   ├── test_add_init_script.py
│   │   ├── test_assertions.py
│   │   ├── test_browser.py
│   │   ├── test_browsercontext_client_certificates.py
│   │   ├── test_browsercontext_events.py
│   │   ├── test_browsercontext_request_fallback.py
│   │   ├── test_browsercontext_request_intercept.py
│   │   ├── test_browsercontext_service_worker_policy.py
│   │   ├── test_browsercontext_storage_state.py
│   │   ├── test_browsertype_connect.py
│   │   ├── test_browsertype_connect_cdp.py
│   │   ├── test_cdp_session.py
│   │   ├── test_check.py
│   │   ├── test_console.py
│   │   ├── test_context_manager.py
│   │   ├── test_element_handle.py
│   │   ├── test_element_handle_wait_for_element_state.py
│   │   ├── test_expect_misc.py
│   │   ├── test_extension.py
│   │   ├── test_fetch_browser_context.py
│   │   ├── test_fetch_global.py
│   │   ├── test_fill.py
│   │   ├── test_har.py
│   │   ├── test_input.py
│   │   ├── test_launcher.py
│   │   ├── test_listeners.py
│   │   ├── test_locator_get_by.py
│   │   ├── test_locators.py
│   │   ├── test_network.py
│   │   ├── test_page.py
│   │   ├── test_page_add_locator_handler.py
│   │   ├── test_page_aria_snapshot.py
│   │   ├── test_page_clock.py
│   │   ├── test_page_event_console.py
│   │   ├── test_page_event_pageerror.py
│   │   ├── test_page_event_request.py
│   │   ├── test_page_network_response.py
│   │   ├── test_page_request_fallback.py
│   │   ├── test_page_request_gc.py
│   │   ├── test_page_request_intercept.py
│   │   ├── test_page_request_timeout.py
│   │   ├── test_page_select_option.py
│   │   ├── test_pdf.py
│   │   ├── test_queryselector.py
│   │   ├── test_request_fulfill.py
│   │   ├── test_request_intercept.py
│   │   ├── test_resource_timing.py
│   │   ├── test_route_web_socket.py
│   │   ├── test_selectors_misc.py
│   │   ├── test_sync.py
│   │   ├── test_tap.py
│   │   ├── test_tracing.py
│   │   ├── test_unroute_behavior.py
│   │   ├── test_video.py
│   │   └── utils.py
│   ├── test_installation.py
│   ├── test_reference_count_async.py
│   ├── testserver/
│   │   ├── cert.pem
│   │   └── key.pem
│   └── utils.py
└── utils/
    ├── docker/
    │   ├── .gitignore
    │   ├── Dockerfile.jammy
    │   ├── Dockerfile.noble
    │   ├── build.sh
    │   └── publish_docker.sh
    └── linting/
        └── check_file_header.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .azure-pipelines/guardian/SDL/.gdnsuppress
================================================
{
  "hydrated": false,
  "properties": {
    "helpUri": "https://eng.ms/docs/microsoft-security/security/azure-security/cloudai-security-fundamentals-engineering/security-integration/guardian-wiki/microsoft-guardian/general/suppressions",
    "hydrationStatus": "This file does not contain identifying data. It is safe to check into your repo. To hydrate this file with identifying data, run `guardian hydrate --help` and follow the guidance."
  },
  "version": "1.0.0",
  "suppressionSets": {
    "default": {
      "name": "default",
      "createdDate": "2024-02-06 21:00:02Z",
      "lastUpdatedDate": "2024-02-06 21:00:02Z"
    }
  },
  "results": {
    "bffa73d7410f5963f2538f06124ac5524c076da77867a0a19ccf60e508062dff": {
      "signature": "bffa73d7410f5963f2538f06124ac5524c076da77867a0a19ccf60e508062dff",
      "alternativeSignatures": [],
      "memberOf": [
        "default"
      ],
      "createdDate": "2024-02-06 21:00:02Z"
    },
    "964642e3cd0f022d5b63f5d3c467d034df4b1664e58dd132b6cd54c98bdae6a1": {
      "signature": "964642e3cd0f022d5b63f5d3c467d034df4b1664e58dd132b6cd54c98bdae6a1",
      "alternativeSignatures": [
        "f2d5560538c833834ca11e62fa6509618ab5454e1e71faf2847cb6fd07f4c4e0"
      ],
      "memberOf": [
        "default"
      ],
      "createdDate": "2024-02-06 21:00:02Z"
    },
    "5b0f97262e176cd67207fd63a2c74b9984829286e9229d10efc32d6b73130e37": {
      "signature": "5b0f97262e176cd67207fd63a2c74b9984829286e9229d10efc32d6b73130e37",
      "alternativeSignatures": [
        "29a18985690880b8caeebc339c7d2afd107510838cdc6561c1f5493478712581"
      ],
      "memberOf": [
        "default"
      ],
      "createdDate": "2024-02-06 21:00:02Z"
    },
    "636fe8a4848f24231e94dc13a238022f90a2894cd47a483e351e467eeb98de52": {
      "signature": "636fe8a4848f24231e94dc13a238022f90a2894cd47a483e351e467eeb98de52",
      "alternativeSignatures": [
        "e20632aa7941af4239fd857f802e05582c841fb9ae84e17c71ca6c7fc713246b"
      ],
      "memberOf": [
        "default"
      ],
      "createdDate": "2024-02-06 21:00:02Z"
    },
    "67ae7118600b0793ec3f0a58a753888e13ce4badcc15575614ee6aa622e5009c": {
      "signature": "67ae7118600b0793ec3f0a58a753888e13ce4badcc15575614ee6aa622e5009c",
      "alternativeSignatures": [
        "d1e68c2c7d9815f47331dd34c31db2634804b45b078a53d00843082747155ac9"
      ],
      "memberOf": [
        "default"
      ],
      "createdDate": "2024-02-06 21:00:02Z"
    },
    "9b7d0de03b9e0e0b2711e31df7c804528c357bf5aa2d689fb5a5f42750e84077": {
      "signature": "9b7d0de03b9e0e0b2711e31df7c804528c357bf5aa2d689fb5a5f42750e84077",
      "alternativeSignatures": [
        "e42bf5a49be2b1b815d1fde98ebf9d463fd2e70be1e8ca661f1210ce5b0c4953"
      ],
      "memberOf": [
        "default"
      ],
      "createdDate": "2024-02-06 21:00:02Z"
    },
    "06ecbceae8bfd10acf8c35f21af3926d172c7930f24a204cc58b61efc6c4c770": {
      "signature": "06ecbceae8bfd10acf8c35f21af3926d172c7930f24a204cc58b61efc6c4c770",
      "alternativeSignatures": [
        "035d6eb1444a809987923a39793fbb1ab9e4462405f38f94bc425c579705a9f2"
      ],
      "memberOf": [
        "default"
      ],
      "createdDate": "2024-02-06 21:00:02Z"
    },
    "c103671af429c32de81f2dc2e7a92999de88a517d916a8f75c8e37448bb2efe9": {
      "signature": "c103671af429c32de81f2dc2e7a92999de88a517d916a8f75c8e37448bb2efe9",
      "alternativeSignatures": [
        "3f904a503c12b62c2922900a2e689632e06272a815448939b1fdd435bcf74388"
      ],
      "memberOf": [
        "default"
      ],
      "createdDate": "2024-02-06 21:00:02Z"
    },
    "d1196285a4e64cf6f0f7f22a29bf5b33b540137da1a89ed2af0c880d2a8c1d64": {
      "signature": "d1196285a4e64cf6f0f7f22a29bf5b33b540137da1a89ed2af0c880d2a8c1d64",
      "alternativeSignatures": [
        "1c24094ca9e68a76a81c747853860e46fd139c9f47f0fdbad9133538e7d064b2"
      ],
      "memberOf": [
        "default"
      ],
      "createdDate": "2024-02-06 21:00:02Z"
    }
  }
}


================================================
FILE: .azure-pipelines/publish.yml
================================================
pr: none

trigger:
  tags:
    include:
    - '*'

resources:
  repositories:
  - repository: 1esPipelines
    type: git
    name: 1ESPipelineTemplates/1ESPipelineTemplates
    ref: refs/tags/release

extends:
  template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines
  parameters:
    pool:
      name: DevDivPlaywrightAzurePipelinesUbuntu2204
      os: linux
    sdl:
      sourceAnalysisPool:
        name: DevDivPlaywrightAzurePipelinesWindows2022
        # The image must be windows-based due to restrictions of the SDL tools. See: https://aka.ms/AAo6v8e
        # In the case of a windows build, this can be the same as the above pool image.
        os: windows
      suppression:
        suppressionFile: $(Build.SourcesDirectory)\.azure-pipelines\guardian\SDL\.gdnsuppress
    stages:
    - stage: Stage
      jobs:
      - job: Build
        templateContext:
          outputs:
          - output: pipelineArtifact
            path: $(Build.ArtifactStagingDirectory)/esrp-build
            artifact: esrp-build
        steps:
        - task: UsePythonVersion@0
          inputs:
            versionSpec: '3.9'
          displayName: 'Use Python'
        - script: |
            python -m pip install --upgrade pip
            pip install -r local-requirements.txt
            pip install -r requirements.txt
            pip install -e .
            for wheel in $(python setup.py --list-wheels); do
              PLAYWRIGHT_TARGET_WHEEL=$wheel python -m build --wheel --outdir $(Build.ArtifactStagingDirectory)/esrp-build
            done
          displayName: 'Install & Build'
      - job: Publish
        dependsOn: Build
        templateContext:
          type: releaseJob
          isProduction: true
          inputs:
          - input: pipelineArtifact
            artifactName: esrp-build
            targetPath: $(Build.ArtifactStagingDirectory)/esrp-build
        steps:
          - checkout: none
          - task: EsrpRelease@9
            inputs:
              connectedservicename: 'Playwright-ESRP-PME'
              usemanagedidentity: true
              keyvaultname: 'playwright-esrp-pme'
              signcertname: 'ESRP-Release-Sign'
              clientid: '13434a40-7de4-4c23-81a3-d843dc81c2c5'
              intent: 'PackageDistribution'
              contenttype: 'PyPi'
              # Keeping it commented out as a workaround for:
              # https://portal.microsofticm.com/imp/v3/incidents/incident/499972482/summary
              # contentsource: 'folder'
              folderlocation: '$(Build.ArtifactStagingDirectory)/esrp-build'
              waitforreleasecompletion: true
              owners: 'yurys@microsoft.com'
              approvers: 'yurys@microsoft.com'
              serviceendpointurl: 'https://api.esrp.microsoft.com'
              mainpublisher: 'Playwright'
              domaintenantid: '975f013f-7f24-47e8-a7d3-abc4752bf346'
            displayName: 'ESRP Release to PIP'


================================================
FILE: .claude/skills/playwright-roll/SKILL.md
================================================
---
name: playwright-roll
description: Roll Playwright Python to a new version
---

Help the user roll to a new version of Playwright.
../../../ROLLING.md contains general instructions and scripts.

Start with updating the version and generating the API to see the state of things.

Afterwards, work through the list of changes that need to be backported.
You can find a list of pull requests that might need to be taking into account in the issue titled "Backport changes".
Work through them one-by-one and check off the items that you have handled.
Not all of them will be relevant, some might have partially been reverted, etc. - so feel free to check with the upstream release branch.

Rolling includes:
- updating client implementation to match changes in the upstream JS implementation (see ../playwright/packages/playwright-core/src/client)
- adding a couple of new tests to verify new/changed functionality

## Tips & Tricks
- Project checkouts are in the parent directory (`../`).
- when updating checkboxes, store the issue content into /tmp and edit it there, then update the issue based on the file
- use the "gh" cli to interact with GitHub


================================================
FILE: .gitattributes
================================================
# text files must be lf for golden file tests to work
* text=auto eol=lf


================================================
FILE: .github/ISSUE_TEMPLATE/bug.yml
================================================
name: Bug Report 🪲
description: Create a bug report to help us improve
title: '[Bug]: '
body:
  - type: markdown
    attributes:
      value: |
        # Please follow these steps first:
  - type: markdown
    attributes:
      value: |
        ## Troubleshoot
        If Playwright is not behaving the way you expect, we'd ask you to look at the [documentation](https://playwright.dev/python/docs/intro) and search the issue tracker for evidence supporting your expectation.
        Please make reasonable efforts to troubleshoot and rule out issues with your code, the configuration, or any 3rd party libraries you might be using.
        Playwright offers [several debugging tools](https://playwright.dev/python/docs/debug) that you can use to troubleshoot your issues.
  - type: markdown
    attributes:
      value: |
        ## Ask for help through appropriate channels
        If you feel unsure about the cause of the problem, consider asking for help on for example [StackOverflow](https://stackoverflow.com/questions/ask) or our [Discord channel](https://aka.ms/playwright/discord) before posting a bug report. The issue tracker is not a help forum.
  - type: markdown
    attributes:
      value: |
        ## Make a minimal reproduction
        To file the report, you will need a GitHub repository with a minimal (but complete) example and simple/clear steps on how to reproduce the bug.
        The simpler you can make it, the more likely we are to successfully verify and fix the bug.
  - type: markdown
    attributes:
      value: |
        > [!IMPORTANT]
        > Bug reports without a minimal reproduction will be rejected.

        ---
  - type: input
    id: version
    attributes:
      label: Version
      description: |
        The version of Playwright you are using.
        Is it the [latest](https://github.com/microsoft/playwright-python/releases)? Test and see if the bug has already been fixed.
      placeholder: ex. 1.41.1
    validations:
      required: true
  - type: textarea
    id: reproduction
    attributes:
      label: Steps to reproduce
      description: Please link to a repository with a minimal reproduction and describe accurately how we can reproduce/verify the bug.
      value: |
        Example steps (replace with your own):
        1. Clone my repo at https://github.com/<myuser>/example
        2. pip install -r requirements.txt
        3. python test.py
        4. You should see the error come up
    validations:
      required: true
  - type: textarea
    id: expected
    attributes:
      label: Expected behavior
      description: A description of what you expect to happen.
      placeholder: I expect to see X or Y
    validations:
      required: true
  - type: textarea
    id: what-happened
    attributes:
      label: Actual behavior
      description: |
        A clear and concise description of the unexpected behavior.
        Please include any relevant output here, especially any error messages.
      placeholder: A bug happened!
    validations:
      required: true
  - type: textarea
    id: context
    attributes:
      label: Additional context
      description: Anything else that might be relevant
    validations:
      required: false
  - type: textarea
    id: envinfo
    attributes:
      label: Environment
      description: |
        Please provide information about the environment you are running in.
      value: |
        - Operating System: [Ubuntu 22.04]
        - CPU: [arm64]
        - Browser: [All, Chromium, Firefox, WebKit]
        - Python Version: [3.12]
        - Other info:
      render: Text
    validations:
      required: true


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
  - name: Join our Discord Server
    url: https://aka.ms/playwright/discord
    about: Ask questions and discuss with other community members


================================================
FILE: .github/ISSUE_TEMPLATE/documentation.yml
================================================
name: Documentation 📖
description: Submit a request to add or update documentation
title: '[Docs]: '
labels: ['Documentation :book:']
body:
  - type: markdown
    attributes:
      value: |
        ### Thank you for helping us improve our documentation!
        Please be sure you are looking at [the Next version of the documentation](https://playwright.dev/python/docs/next/intro) before opening an issue here.
  - type: textarea
    id: links
    attributes:
      label: Page(s)
      description: |
        Links to one or more documentation pages that should be modified.
        If you are reporting an issue with a specific section of a page, try to link directly to the nearest anchor.
        If you are suggesting that a new page be created, link to the parent of the proposed page.
    validations:
      required: true
  - type: textarea
    id: description
    attributes:
      label: Description
      description: |
        Describe the change you are requesting.
        If the issue pertains to a single function or matcher, be sure to specify the entire call signature.
    validations:
      required: true


================================================
FILE: .github/ISSUE_TEMPLATE/feature.yml
================================================
name: Feature Request 🚀
description: Submit a proposal for a new feature
title: '[Feature]: '
body:
  - type: markdown
    attributes:
      value: |
        ### Thank you for taking the time to suggest a new feature!
  - type: textarea
    id: description
    attributes:
      label: '🚀 Feature Request'
      description: A clear and concise description of what the feature is.
    validations:
      required: true
  - type: textarea
    id: example
    attributes:
      label: Example
      description: Describe how this feature would be used.
    validations:
      required: false
  - type: textarea
    id: motivation
    attributes:
      label: Motivation
      description: |
        Outline your motivation for the proposal. How will it make Playwright better?
    validations:
      required: true


================================================
FILE: .github/ISSUE_TEMPLATE/question.yml
================================================
name: 'Questions / Help 💬'
description: If you have questions, please check StackOverflow or Discord
title: '[Please read the message below]'
labels: [':speech_balloon: Question']
body:
  - type: markdown
    attributes:
      value: |
        ## Questions and Help 💬

        This issue tracker is reserved for bug reports and feature requests.

        For anything else, such as questions or getting help, please see:

        - [The Playwright documentation](https://playwright.dev)
        - [Our Discord server](https://aka.ms/playwright/discord)
  - type: checkboxes
    id: no-post
    attributes:
      label: |
        Please do not submit this issue.
      description: |
        > [!IMPORTANT]
        > This issue will be closed.
      options:
        - label: I understand
          required: true


================================================
FILE: .github/ISSUE_TEMPLATE/regression.yml
================================================
name: Report regression
description: Functionality that used to work and does not any more
title: "[Regression]: "

body:
  - type: markdown
    attributes:
      value: |
        # Please follow these steps first:
  - type: markdown
    attributes:
      value: |
        ## Make a minimal reproduction
        To file the report, you will need a GitHub repository with a minimal (but complete) example and simple/clear steps on how to reproduce the regression.
        The simpler you can make it, the more likely we are to successfully verify and fix the regression.
  - type: markdown
    attributes:
      value: |
        > [!IMPORTANT]
        > Regression reports without a minimal reproduction will be rejected.

        ---
  - type: input
    id: goodVersion
    attributes:
      label: Last Good Version
      description: |
        Last version of Playwright where the feature was working.
      placeholder: ex. 1.40.1
    validations:
      required: true
  - type: input
    id: badVersion
    attributes:
      label: First Bad Version
      description: |
        First version of Playwright where the feature was broken.
        Is it the [latest](https://github.com/microsoft/playwright-python/releases)? Test and see if the regression has already been fixed.
      placeholder: ex. 1.41.1
    validations:
      required: true
  - type: textarea
    id: reproduction
    attributes:
      label: Steps to reproduce
      description: Please link to a repository with a minimal reproduction and describe accurately how we can reproduce/verify the bug.
      value: |
        Example steps (replace with your own):
        1. Clone my repo at https://github.com/<myuser>/example
        2. pip -r requirements.txt
        3. python test.py
        4. You should see the error come up
    validations:
      required: true
  - type: textarea
    id: expected
    attributes:
      label: Expected behavior
      description: A description of what you expect to happen.
      placeholder: I expect to see X or Y
    validations:
      required: true
  - type: textarea
    id: what-happened
    attributes:
      label: Actual behavior
      description: A clear and concise description of the unexpected behavior.
      placeholder: A bug happened!
    validations:
      required: true
  - type: textarea
    id: context
    attributes:
      label: Additional context
      description: Anything else that might be relevant
    validations:
      required: false
  - type: textarea
    id: envinfo
    attributes:
      label: Environment
      description: |
        Please provide information about the environment you are running in.
      value: |
        - Operating System: [Ubuntu 22.04]
        - CPU: [arm64]
        - Browser: [All, Chromium, Firefox, WebKit]
        - Python Version: [3.12]
        - Other info:
      render: Text
    validations:
      required: true


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: "pip"
    directory: "/"
    schedule:
      interval: "weekly"
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    groups:
      actions:
        patterns:
          - "*"


================================================
FILE: .github/workflows/ci.yml
================================================
name: CI

on:
  push:
    branches:
      - main
      - release-*
  pull_request:
    branches:
      - main
      - release-*

concurrency:
  # For pull requests, cancel all currently-running jobs for this workflow
  # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#concurrency
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: true

jobs:
  infra:
    name: Lint
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v5
    - name: Set up Python
      uses: actions/setup-python@v6
      with:
        python-version: "3.10"
    - name: Install dependencies & browsers
      run: |
        python -m pip install --upgrade pip
        pip install -r local-requirements.txt
        pip install -r requirements.txt
        pip install -e .
        python -m build --wheel
        python -m playwright install --with-deps
    - name: Lint
      run: pre-commit run --show-diff-on-failure --color=always --all-files
    - name: Generate APIs
      run: bash scripts/update_api.sh
    - name: Verify generated API is up to date
      run: git diff --exit-code

  build:
    name: Build
    timeout-minutes: 45
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        python-version: ['3.9', '3.10']
        browser: [chromium, firefox, webkit]
        include:
        - os: windows-latest
          python-version: '3.11'
          browser: chromium
        - os: macos-latest
          python-version: '3.11'
          browser: chromium
        - os: ubuntu-latest
          python-version: '3.11'
          browser: chromium
        - os: windows-latest
          python-version: '3.12'
          browser: chromium
        - os: macos-latest
          python-version: '3.12'
          browser: chromium
        - os: ubuntu-latest
          python-version: '3.12'
          browser: chromium
        - os: windows-latest
          python-version: '3.13'
          browser: chromium
        - os: macos-latest
          python-version: '3.13'
          browser: chromium
        - os: ubuntu-latest
          python-version: '3.13'
          browser: chromium
    runs-on: ${{ matrix.os }}
    steps:
    - uses: actions/checkout@v5
    - name: Set up Python
      uses: actions/setup-python@v6
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install dependencies & browsers
      run: |
        python -m pip install --upgrade pip
        pip install -r local-requirements.txt
        pip install -r requirements.txt
        pip install -e .
        python -m build --wheel
        python -m playwright install --with-deps ${{ matrix.browser }}
    - name: Common Tests
      run: pytest tests/common --browser=${{ matrix.browser }} --timeout 90
    - name: Test Reference count
      run: pytest tests/test_reference_count_async.py --browser=${{ matrix.browser }}
    - name: Test Wheel Installation
      run: pytest tests/test_installation.py --browser=${{ matrix.browser }}
    - name: Test Sync API
      if: matrix.os != 'ubuntu-latest'
      run: pytest tests/sync --browser=${{ matrix.browser }} --timeout 90
    - name: Test Sync API
      if: matrix.os == 'ubuntu-latest'
      run: xvfb-run pytest tests/sync --browser=${{ matrix.browser }} --timeout 90
    - name: Test Async API
      if: matrix.os != 'ubuntu-latest'
      run: pytest tests/async --browser=${{ matrix.browser }} --timeout 90
    - name: Test Async API
      if: matrix.os == 'ubuntu-latest'
      run: xvfb-run pytest tests/async --browser=${{ matrix.browser }} --timeout 90

  test-stable:
    name: Stable
    timeout-minutes: 45
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        browser-channel: [chrome]
        include:
        - os: windows-latest
          browser-channel: msedge
        - os: macos-latest
          browser-channel: msedge
    runs-on: ${{ matrix.os }}
    steps:
    - uses: actions/checkout@v5
    - name: Set up Python
      uses: actions/setup-python@v6
      with:
        python-version: "3.10"
    - name: Install dependencies & browsers
      run: |
        python -m pip install --upgrade pip
        pip install -r local-requirements.txt
        pip install -r requirements.txt
        pip install -e .
        python -m build --wheel
        python -m playwright install ${{ matrix.browser-channel }} --with-deps
    - name: Common Tests
      run: pytest tests/common --browser=chromium --browser-channel=${{ matrix.browser-channel }} --timeout 90
    - name: Test Sync API
      if: matrix.os != 'ubuntu-latest'
      run: pytest tests/sync --browser=chromium --browser-channel=${{ matrix.browser-channel }} --timeout 90
    - name: Test Sync API
      if: matrix.os == 'ubuntu-latest'
      run: xvfb-run pytest tests/sync --browser=chromium --browser-channel=${{ matrix.browser-channel }} --timeout 90
    - name: Test Async API
      if: matrix.os != 'ubuntu-latest'
      run: pytest tests/async --browser=chromium --browser-channel=${{ matrix.browser-channel }} --timeout 90
    - name: Test Async API
      if: matrix.os == 'ubuntu-latest'
      run: xvfb-run pytest tests/async --browser=chromium --browser-channel=${{ matrix.browser-channel }} --timeout 90

  build-conda:
    name: Conda Build
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-22.04, macos-13, windows-2022]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v5
        with:
          fetch-depth: 0
      - name: Get conda
        uses: conda-incubator/setup-miniconda@v3
        with:
          python-version: 3.9
          channels: conda-forge
          miniconda-version: latest
      - name: Prepare
        run: conda install conda-build conda-verify
      - name: Build
        run: conda build .

  test_examples:
    name: Examples
    runs-on: ubuntu-22.04
    defaults:
      run:
        working-directory: examples/todomvc/
    steps:
    - uses: actions/checkout@v5
    - name: Set up Python
      uses: actions/setup-python@v6
      with:
        python-version: '3.10'
    - name: Install dependencies & browsers
      run: |
        pip install -r requirements.txt
        python -m playwright install --with-deps chromium
    - name: Common Tests
      run: pytest


================================================
FILE: .github/workflows/publish.yml
================================================
name: Upload Python Package
on:
  release:
    types: [published]
  workflow_dispatch:
jobs:
  deploy-conda:
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
            target-platform: linux-x86_64
          - os: ubuntu-latest
            target-platform: linux-aarch64
          - os: windows-latest
            target-platform: win-64
          - os: macos-latest-large
            target-platform: osx-intel
          - os: macos-latest-xlarge
            target-platform: osx-arm64
    runs-on: ${{ matrix.os }}
    defaults:
      run:
        # Required for conda-incubator/setup-miniconda@v3
        shell: bash -el {0}
    steps:
      - uses: actions/checkout@v5
        with:
          fetch-depth: 0
      - name: Get conda
        uses: conda-incubator/setup-miniconda@v3
        with:
          python-version: 3.9
          channels: conda-forge
          miniconda-version: latest
      - name: Prepare
        run: conda install anaconda-client conda-build conda-verify
      - name: Build and Upload
        env:
          ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }}
        run: |
          conda config --set anaconda_upload yes
          if [ "${{ matrix.target-platform }}" == "osx-arm64" ]; then
            conda build --user microsoft . -m conda_build_config_osx_arm64.yaml
          elif [ "${{ matrix.target-platform }}" == "linux-aarch64" ]; then
            conda build --user microsoft . -m conda_build_config_linux_aarch64.yaml
          else
            conda build --user microsoft .
          fi


================================================
FILE: .github/workflows/publish_docker.yml
================================================
name: "publish release - Docker"

on:
  workflow_dispatch:
  release:
    types: [published]

jobs:
  publish-docker-release:
    name: "publish to DockerHub"
    runs-on: ubuntu-22.04
    if: github.repository == 'microsoft/playwright-python'
    permissions:
      id-token: write   # This is required for OIDC login (azure/login) to succeed
      contents: read    # This is required for actions/checkout to succeed
    environment: Docker
    steps:
    - uses: actions/checkout@v5
    - name: Azure login
      uses: azure/login@v2
      with:
        client-id: ${{ secrets.AZURE_DOCKER_CLIENT_ID }}
        tenant-id: ${{ secrets.AZURE_DOCKER_TENANT_ID }}
        subscription-id: ${{ secrets.AZURE_DOCKER_SUBSCRIPTION_ID }}
    - name: Login to ACR via OIDC
      run: az acr login --name playwright
    - name: Set up Python
      uses: actions/setup-python@v6
      with:
        python-version: "3.10"
    - name: Set up Docker QEMU for arm64 docker builds
      uses: docker/setup-qemu-action@v3
      with:
        platforms: arm64
    - name: Install dependencies & browsers
      run: |
        python -m pip install --upgrade pip
        pip install -r local-requirements.txt
        pip install -r requirements.txt
        pip install -e .
    - run: ./utils/docker/publish_docker.sh stable


================================================
FILE: .github/workflows/test_docker.yml
================================================
name: Test Docker
on:
  push:
    paths:
      - '.github/workflows/test_docker.yml'
      - 'setup.py'
      - '**/Dockerfile.*'
    branches:
      - main
      - release-*
  pull_request:
    paths:
      - '.github/workflows/test_docker.yml'
      - 'setup.py'
      - '**/Dockerfile.*'
    branches:
      - main
      - release-*
jobs:
  build:
    timeout-minutes: 120
    runs-on: ${{ matrix.runs-on }}
    strategy:
      fail-fast: false
      matrix:
        docker-image-variant:
          - jammy
          - noble
        runs-on:
          - ubuntu-24.04
          - ubuntu-24.04-arm
    steps:
    - uses: actions/checkout@v5
    - name: Set up Python
      uses: actions/setup-python@v6
      with:
        python-version: "3.10"
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r local-requirements.txt
        pip install -r requirements.txt
        pip install -e .
    - name: Build Docker image
      run: |
        ARCH="${{ matrix.runs-on == 'ubuntu-24.04-arm' && 'arm64' || 'amd64' }}"
        bash utils/docker/build.sh --$ARCH ${{ matrix.docker-image-variant }} playwright-python:localbuild-${{ matrix.docker-image-variant }}
    - name: Test
      run: |
        CONTAINER_ID="$(docker run --rm -e CI -v $(pwd):/root/playwright --name playwright-docker-test --workdir /root/playwright/ -d -t playwright-python:localbuild-${{ matrix.docker-image-variant }} /bin/bash)"
        # Fix permissions for Git inside the container
        docker exec "${CONTAINER_ID}" chown -R root:root /root/playwright
        docker exec "${CONTAINER_ID}" pip install -r local-requirements.txt
        docker exec "${CONTAINER_ID}" pip install -r requirements.txt
        docker exec "${CONTAINER_ID}" pip install -e .
        docker exec "${CONTAINER_ID}" python -m build --wheel
        docker exec "${CONTAINER_ID}" xvfb-run pytest tests/sync/
        docker exec "${CONTAINER_ID}" xvfb-run pytest tests/async/


================================================
FILE: .gitignore
================================================
**/__pycache__/
driver/
playwright/driver/
playwright.egg-info/
build/
dist/
venv/
.idea/
**/*.pyc
env/
htmlcov/
.coverage*
.DS_Store
.vscode/
.eggs
_repo_version.py
coverage.xml
junit/
htmldocs/
utils/docker/dist/
Pipfile
Pipfile.lock
.venv/


================================================
FILE: .pre-commit-config.yaml
================================================
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v5.0.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
        exclude: tests/assets/har-sha1-main-response.txt
      - id: check-yaml
      - id: check-toml
      - id: requirements-txt-fixer
      - id: check-ast
      - id: check-builtin-literals
      - id: check-executables-have-shebangs
      - id: check-merge-conflict
  - repo: https://github.com/psf/black
    rev: 25.1.0
    hooks:
      - id: black
  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.17.0
    hooks:
      - id: mypy
        additional_dependencies: [types-pyOpenSSL==24.1.0.20240722, types-requests==2.32.4.20250611]
  - repo: https://github.com/pycqa/flake8
    rev: 7.3.0
    hooks:
      - id: flake8
  - repo: https://github.com/pycqa/isort
    rev: 6.0.1
    hooks:
      - id: isort
  - repo: local
    hooks:
      - id: pyright
        name: pyright
        entry: pyright
        language: node
        pass_filenames: false
        types: [python]
        additional_dependencies: ["pyright@1.1.403"]
  - repo: local
    hooks:
      - id: check-license-header
        name: Check License Header
        entry: ./utils/linting/check_file_header.py
        language: python
        types: [python]


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Microsoft Open Source Code of Conduct

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).

Resources:

- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

## How to Contribute

### Configuring python environment

The project development requires Python version 3.9+. To set it as default in the environment run the following commands:

```sh
# You may need to install python 3.9 venv if it's missing, on Ubuntu just run `sudo apt-get install python3.9-venv`
python3.9 -m venv env
source ./env/bin/activate
```

Install required dependencies:

```sh
python -m pip install --upgrade pip
pip install -r local-requirements.txt
```

Build and install drivers:

```sh
pip install -e .
python -m build --wheel
```

Run tests:

```sh
pytest --browser chromium
```

Checking for typing errors

```sh
mypy playwright
```

Format the code

```sh
pre-commit install
pre-commit run --all-files
```

For more details look at the [CI configuration](./.github/workflows/ci.yml).

Collect coverage

```sh
pytest --browser chromium --cov-report html --cov=playwright
open htmlcov/index.html
```

### Regenerating APIs

```bash
./scripts/update_api.sh
pre-commit run --all-files
```

## Contributor License Agreement

This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.

## Code of Conduct

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Portions Copyright (c) Microsoft Corporation.
   Portions Copyright 2017 Google Inc.

   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.


================================================
FILE: README.md
================================================
# 🎭 [Playwright](https://playwright.dev) for Python [![PyPI version](https://badge.fury.io/py/playwright.svg)](https://pypi.python.org/pypi/playwright/) [![Anaconda version](https://img.shields.io/conda/v/microsoft/playwright)](https://anaconda.org/Microsoft/playwright) [![Join Discord](https://img.shields.io/badge/join-discord-infomational)](https://aka.ms/playwright/discord)

Playwright is a Python library to automate [Chromium](https://www.chromium.org/Home), [Firefox](https://www.mozilla.org/en-US/firefox/new/) and [WebKit](https://webkit.org/) browsers with a single API. Playwright delivers automation that is **ever-green**, **capable**, **reliable** and **fast**. [See how Playwright is better](https://playwright.dev/python).

|          | Linux | macOS | Windows |
|   :---   | :---: | :---: | :---:   |
| Chromium <!-- GEN:chromium-version -->145.0.7632.6<!-- GEN:stop --> | ✅ | ✅ | ✅ |
| WebKit <!-- GEN:webkit-version -->26.0<!-- GEN:stop --> | ✅ | ✅ | ✅ |
| Firefox <!-- GEN:firefox-version -->146.0.1<!-- GEN:stop --> | ✅ | ✅ | ✅ |

## Documentation

[https://playwright.dev/python/docs/intro](https://playwright.dev/python/docs/intro)

## API Reference

[https://playwright.dev/python/docs/api/class-playwright](https://playwright.dev/python/docs/api/class-playwright)

## Example

```py
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    for browser_type in [p.chromium, p.firefox, p.webkit]:
        browser = browser_type.launch()
        page = browser.new_page()
        page.goto('http://playwright.dev')
        page.screenshot(path=f'example-{browser_type.name}.png')
        browser.close()
```

```py
import asyncio
from playwright.async_api import async_playwright

async def main():
    async with async_playwright() as p:
        for browser_type in [p.chromium, p.firefox, p.webkit]:
            browser = await browser_type.launch()
            page = await browser.new_page()
            await page.goto('http://playwright.dev')
            await page.screenshot(path=f'example-{browser_type.name}.png')
            await browser.close()

asyncio.run(main())
```

## Other languages

More comfortable in another programming language? [Playwright](https://playwright.dev) is also available in
- [Node.js (JavaScript / TypeScript)](https://playwright.dev/docs/intro),
- [.NET](https://playwright.dev/dotnet/docs/intro),
- [Java](https://playwright.dev/java/docs/intro).


================================================
FILE: ROLLING.md
================================================
# Rolling Playwright-Python to the latest Playwright driver

* checkout repo: `git clone https://github.com/microsoft/playwright-python`
* make sure local python is 3.9
    * create virtual environment, if don't have one: `python -m venv env`
* activate venv: `source env/bin/activate`
* install all deps:
```
python -m pip install --upgrade pip
pip install -r local-requirements.txt
pre-commit install
pip install -e .
```
* change driver version in `setup.py`
* download new driver: `python -m build --wheel`
* generate API: `./scripts/update_api.sh`
* commit changes & send PR
* wait for bots to pass & merge the PR


## Fix typing issues with Playwright ToT

1. `cd playwright`
1. `API_JSON_MODE=1 node utils/doclint/generateApiJson.js > ../playwright-python/playwright/driver/package/api.json`
1. `./scripts/update_api.sh`


================================================
FILE: SECURITY.md
================================================
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.5 BLOCK -->

## Security

Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).

If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below.

## Reporting Security Issues

**Please do not report security vulnerabilities through public GitHub issues.**

Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report).

If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com).  If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc).

You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).

Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:

  * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
  * Full paths of source file(s) related to the manifestation of the issue
  * The location of the affected source code (tag/branch/commit or direct URL)
  * Any special configuration required to reproduce the issue
  * Step-by-step instructions to reproduce the issue
  * Proof-of-concept or exploit code (if possible)
  * Impact of the issue, including how an attacker might exploit the issue

This information will help us triage your report more quickly.

If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs.

## Preferred Languages

We prefer all communications to be in English.

## Policy

Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd).

<!-- END MICROSOFT SECURITY.MD BLOCK -->


================================================
FILE: SUPPORT.md
================================================
# Support

## How to file issues and get help

This project uses GitHub issues to track bugs and feature requests. Please search the [existing issues][gh-issues] before filing new ones to avoid duplicates. For new issues, file your bug or feature request as a new issue using corresponding template.

For help and questions about using this project, please see the [docs site for Playwright for Python][docs].

Join our community [Discord Server][discord-server] to connect with other developers using Playwright and ask questions in our 'help-playwright' forum.

## Microsoft Support Policy

Support for Playwright for Python is limited to the resources listed above.

[gh-issues]: https://github.com/microsoft/playwright-python/issues/
[docs]: https://playwright.dev/python/
[discord-server]: https://aka.ms/playwright/discord


================================================
FILE: conda_build_config_linux_aarch64.yaml
================================================
target_platform:
- linux-aarch64


================================================
FILE: conda_build_config_osx_arm64.yaml
================================================
target_platform:
- osx-arm64


================================================
FILE: examples/todomvc/mvctests/__init__.py
================================================


================================================
FILE: examples/todomvc/mvctests/test_clear_completed_button.py
================================================
# 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.
from typing import Generator

import pytest

from playwright.sync_api import Page, expect

from .utils import TODO_ITEMS, create_default_todos


@pytest.fixture(autouse=True)
def run_around_tests(page: Page) -> Generator[None, None, None]:
    # setup before a test
    page.goto("https://demo.playwright.dev/todomvc")
    create_default_todos(page)
    # run the actual test
    yield
    # run any cleanup code


def test_should_display_the_correct_text(page: Page) -> None:
    page.locator(".todo-list li .toggle").first.check()
    expect(page.locator(".clear-completed")).to_have_text("Clear completed")


def test_should_clear_completed_items_when_clicked(page: Page) -> None:
    todo_items = page.locator(".todo-list li")
    todo_items.nth(1).locator(".toggle").check()
    page.locator(".clear-completed").click()
    expect(todo_items).to_have_count(2)
    expect(todo_items).to_have_text([TODO_ITEMS[0], TODO_ITEMS[2]])


def test_should_be_hidden_when_there_are_no_items_that_are_completed(
    page: Page,
) -> None:
    page.locator(".todo-list li .toggle").first.check()
    page.locator(".clear-completed").click()
    expect(page.locator(".clear-completed")).to_be_hidden()


================================================
FILE: examples/todomvc/mvctests/test_counter.py
================================================
# 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.
from typing import Generator

import pytest

from playwright.sync_api import Page, expect

from .utils import TODO_ITEMS, assert_number_of_todos_in_local_storage


@pytest.fixture(autouse=True)
def run_around_tests(page: Page) -> Generator[None, None, None]:
    # setup before a test
    page.goto("https://demo.playwright.dev/todomvc")
    # run the actual test
    yield
    # run any cleanup code


def test_should_display_the_current_number_of_todo_items(page: Page) -> None:
    page.locator(".new-todo").fill(TODO_ITEMS[0])
    page.locator(".new-todo").press("Enter")
    expect(page.locator(".todo-count")).to_contain_text("1")

    page.locator(".new-todo").fill(TODO_ITEMS[1])
    page.locator(".new-todo").press("Enter")
    expect(page.locator(".todo-count")).to_contain_text("2")

    assert_number_of_todos_in_local_storage(page, 2)


================================================
FILE: examples/todomvc/mvctests/test_editing.py
================================================
# 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.
from typing import Generator

import pytest

from playwright.sync_api import Page, expect

from .utils import (
    TODO_ITEMS,
    assert_number_of_todos_in_local_storage,
    check_todos_in_local_storage,
    create_default_todos,
)


@pytest.fixture(autouse=True)
def run_around_tests(page: Page) -> Generator[None, None, None]:
    # setup before a test
    page.goto("https://demo.playwright.dev/todomvc")
    create_default_todos(page)
    assert_number_of_todos_in_local_storage(page, 3)
    # run the actual test
    yield
    # run any cleanup code


def test_should_hide_other_controls_when_editing(page: Page) -> None:
    todo_item = page.locator(".todo-list li").nth(1)
    todo_item.dblclick()
    expect(todo_item.locator(".toggle")).not_to_be_visible()
    expect(todo_item.locator("label")).not_to_be_visible()
    assert_number_of_todos_in_local_storage(page, 3)


def test_should_save_edits_on_blur(page: Page) -> None:
    todo_items = page.locator(".todo-list li")
    todo_items.nth(1).dblclick()
    todo_items.nth(1).locator(".edit").fill("buy some sausages")
    todo_items.nth(1).locator(".edit").dispatch_event("blur")

    expect(todo_items).to_have_text(
        [
            TODO_ITEMS[0],
            "buy some sausages",
            TODO_ITEMS[2],
        ]
    )
    check_todos_in_local_storage(page, "buy some sausages")


def test_should_trim_entered_text(page: Page) -> None:
    todo_items = page.locator(".todo-list li")
    todo_items.nth(1).dblclick()
    todo_items.nth(1).locator(".edit").fill("    buy some sausages    ")
    todo_items.nth(1).locator(".edit").press("Enter")

    expect(todo_items).to_have_text(
        [
            TODO_ITEMS[0],
            "buy some sausages",
            TODO_ITEMS[2],
        ]
    )
    check_todos_in_local_storage(page, "buy some sausages")


def test_should_remove_the_item_if_an_empty_text_string_was_entered(page: Page) -> None:
    todo_items = page.locator(".todo-list li")
    todo_items.nth(1).dblclick()
    todo_items.nth(1).locator(".edit").fill("")
    todo_items.nth(1).locator(".edit").press("Enter")

    expect(todo_items).to_have_text(
        [
            TODO_ITEMS[0],
            TODO_ITEMS[2],
        ]
    )


def test_should_cancel_edits_on_escape(page: Page) -> None:
    todo_items = page.locator(".todo-list li")
    todo_items.nth(1).dblclick()
    todo_items.nth(1).locator(".edit").press("Escape")
    expect(todo_items).to_have_text(TODO_ITEMS)


================================================
FILE: examples/todomvc/mvctests/test_item.py
================================================
# 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.
from typing import Generator

import pytest

from playwright.sync_api import Page, expect

from .utils import (
    TODO_ITEMS,
    check_number_of_completed_todos_in_local_storage,
    check_todos_in_local_storage,
    create_default_todos,
)


@pytest.fixture(autouse=True)
def run_around_tests(page: Page) -> Generator[None, None, None]:
    # setup before a test
    page.goto("https://demo.playwright.dev/todomvc")
    # run the actual test
    yield
    # run any cleanup code


def test_should_allow_me_to_mark_items_as_completed(page: Page) -> None:
    # Create two items.
    for item in TODO_ITEMS[:2]:
        page.locator(".new-todo").fill(item)
        page.locator(".new-todo").press("Enter")

    # Check first item.
    firstTodo = page.locator(".todo-list li").nth(0)
    firstTodo.locator(".toggle").check()
    expect(firstTodo).to_have_class("completed")

    # Check second item.
    secondTodo = page.locator(".todo-list li").nth(1)
    expect(secondTodo).not_to_have_class("completed")
    secondTodo.locator(".toggle").check()

    # Assert completed class.
    expect(firstTodo).to_have_class("completed")
    expect(secondTodo).to_have_class("completed")


def test_should_allow_me_to_un_mark_items_as_completed(page: Page) -> None:
    # Create two items.
    for item in TODO_ITEMS[:2]:
        page.locator(".new-todo").fill(item)
        page.locator(".new-todo").press("Enter")

    firstTodo = page.locator(".todo-list li").nth(0)
    secondTodo = page.locator(".todo-list li").nth(1)
    firstTodo.locator(".toggle").check()
    expect(firstTodo).to_have_class("completed")
    expect(secondTodo).not_to_have_class("completed")
    check_number_of_completed_todos_in_local_storage(page, 1)

    firstTodo.locator(".toggle").uncheck()
    expect(firstTodo).not_to_have_class("completed")
    expect(secondTodo).not_to_have_class("completed")
    check_number_of_completed_todos_in_local_storage(page, 0)


def test_should_allow_me_to_edit_an_item(page: Page) -> None:
    create_default_todos(page)

    todo_items = page.locator(".todo-list li")
    secondTodo = todo_items.nth(1)
    secondTodo.dblclick()
    expect(secondTodo.locator(".edit")).to_have_value(TODO_ITEMS[1])
    secondTodo.locator(".edit").fill("buy some sausages")
    secondTodo.locator(".edit").press("Enter")

    # Explicitly assert the new text value.
    expect(todo_items).to_have_text([TODO_ITEMS[0], "buy some sausages", TODO_ITEMS[2]])
    check_todos_in_local_storage(page, "buy some sausages")


================================================
FILE: examples/todomvc/mvctests/test_mark_all_as_completed.py
================================================
# 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.
from typing import Generator

import pytest

from playwright.sync_api import Page, expect

from .utils import (
    assert_number_of_todos_in_local_storage,
    check_number_of_completed_todos_in_local_storage,
    create_default_todos,
)


@pytest.fixture(autouse=True)
def run_around_tests(page: Page) -> Generator[None, None, None]:
    # setup before a test
    page.goto("https://demo.playwright.dev/todomvc")
    # run the actual test
    yield
    # run any cleanup code


def test_should_allow_me_to_mark_all_items_as_completed(page: Page) -> None:
    create_default_todos(page)
    assert_number_of_todos_in_local_storage(page, 3)
    # Complete all todos.
    page.locator(".toggle-all").check()

    # Ensure all todos have 'completed' class.
    expect(page.locator(".todo-list li")).to_have_class(
        ["completed", "completed", "completed"]
    )
    check_number_of_completed_todos_in_local_storage(page, 3)
    assert_number_of_todos_in_local_storage(page, 3)


def test_should_allow_me_to_clear_the_complete_state_of_all_items(page: Page) -> None:
    create_default_todos(page)
    assert_number_of_todos_in_local_storage(page, 3)
    # Check and then immediately uncheck.
    page.locator(".toggle-all").check()
    page.locator(".toggle-all").uncheck()

    # Should be no completed classes.
    expect(page.locator(".todo-list li")).to_have_class(["", "", ""])
    assert_number_of_todos_in_local_storage(page, 3)


def test_complete_all_checkbox_should_update_state_when_items_are_completed_or_cleared(
    page: Page,
) -> None:
    create_default_todos(page)
    assert_number_of_todos_in_local_storage(page, 3)
    toggleAll = page.locator(".toggle-all")
    toggleAll.check()
    expect(toggleAll).to_be_checked()
    check_number_of_completed_todos_in_local_storage(page, 3)

    # Uncheck first todo.
    firstTodo = page.locator(".todo-list li").nth(0)
    firstTodo.locator(".toggle").uncheck()

    # Reuse toggleAll locator and make sure its not checked.
    expect(toggleAll).not_to_be_checked()

    firstTodo.locator(".toggle").check()
    check_number_of_completed_todos_in_local_storage(page, 3)

    # Assert the toggle all is checked again.
    expect(toggleAll).to_be_checked()
    assert_number_of_todos_in_local_storage(page, 3)


================================================
FILE: examples/todomvc/mvctests/test_new_todo.py
================================================
# 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 re
from typing import Generator

import pytest

from playwright.sync_api import Page, expect

from .utils import (
    TODO_ITEMS,
    assert_number_of_todos_in_local_storage,
    create_default_todos,
)


@pytest.fixture(autouse=True)
def run_around_tests(page: Page) -> Generator[None, None, None]:
    # setup before a test
    page.goto("https://demo.playwright.dev/todomvc")
    # run the actual test
    yield
    # run any cleanup code


def test_new_todo_test_should_allow_me_to_add_todo_items(page: Page) -> None:
    # Create 1st todo.
    page.locator(".new-todo").fill(TODO_ITEMS[0])
    page.locator(".new-todo").press("Enter")

    # Make sure the list only has one todo item.
    expect(page.locator(".view label")).to_have_text([TODO_ITEMS[0]])

    # Create 2nd todo.
    page.locator(".new-todo").fill(TODO_ITEMS[1])
    page.locator(".new-todo").press("Enter")

    # Make sure the list now has two todo items.
    expect(page.locator(".view label")).to_have_text([TODO_ITEMS[0], TODO_ITEMS[1]])

    assert_number_of_todos_in_local_storage(page, 2)


def test_new_todo_test_should_clear_text_input_field_when_an_item_is_added(
    page: Page,
) -> None:
    # Create one todo item.
    page.locator(".new-todo").fill(TODO_ITEMS[0])
    page.locator(".new-todo").press("Enter")

    # Check that input is empty.
    expect(page.locator(".new-todo")).to_be_empty()
    assert_number_of_todos_in_local_storage(page, 1)


def test_new_todo_test_should_append_new_items_to_the_bottom_of_the_list(
    page: Page,
) -> None:
    # Create 3 items.
    create_default_todos(page)

    # Check test using different methods.
    expect(page.locator(".todo-count")).to_have_text("3 items left")
    expect(page.locator(".todo-count")).to_contain_text("3")
    expect(page.locator(".todo-count")).to_have_text(re.compile("3"))

    # Check all items in one call.
    expect(page.locator(".view label")).to_have_text(TODO_ITEMS)
    assert_number_of_todos_in_local_storage(page, 3)


def test_new_todo_should_show_main_and_foter_when_items_added(page: Page) -> None:
    page.locator(".new-todo").fill(TODO_ITEMS[0])
    page.locator(".new-todo").press("Enter")

    expect(page.locator(".main")).to_be_visible()
    expect(page.locator(".footer")).to_be_visible()
    assert_number_of_todos_in_local_storage(page, 1)


================================================
FILE: examples/todomvc/mvctests/test_persistence.py
================================================
# 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.
from typing import Generator

import pytest

from playwright.sync_api import Page, expect

from .utils import TODO_ITEMS, check_number_of_completed_todos_in_local_storage


@pytest.fixture(autouse=True)
def run_around_tests(page: Page) -> Generator[None, None, None]:
    # setup before a test
    page.goto("https://demo.playwright.dev/todomvc")
    # run the actual test
    yield
    # run any cleanup code


def test_should_persist_its_data(page: Page) -> None:
    for item in TODO_ITEMS[:2]:
        page.locator(".new-todo").fill(item)
        page.locator(".new-todo").press("Enter")

    todo_items = page.locator(".todo-list li")
    todo_items.nth(0).locator(".toggle").check()
    expect(todo_items).to_have_text([TODO_ITEMS[0], TODO_ITEMS[1]])
    expect(todo_items).to_have_class(["completed", ""])

    # Ensure there is 1 completed item.
    check_number_of_completed_todos_in_local_storage(page, 1)

    # Now reload.
    page.reload()
    expect(todo_items).to_have_text([TODO_ITEMS[0], TODO_ITEMS[1]])
    expect(todo_items).to_have_class(["completed", ""])


================================================
FILE: examples/todomvc/mvctests/test_routing.py
================================================
# 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.
from typing import Generator

import pytest

from playwright.sync_api import Page, expect

from .utils import (
    TODO_ITEMS,
    check_number_of_completed_todos_in_local_storage,
    check_todos_in_local_storage,
    create_default_todos,
)


@pytest.fixture(autouse=True)
def run_around_tests(page: Page) -> Generator[None, None, None]:
    # setup before a test
    page.goto("https://demo.playwright.dev/todomvc")
    create_default_todos(page)
    # make sure the app had a chance to save updated todos in storage
    # before navigating to a new view, otherwise the items can get lost :(
    # in some frameworks like Durandal
    check_todos_in_local_storage(page, TODO_ITEMS[0])
    # run the actual test
    yield
    # run any cleanup code


def test_should_allow_me_to_display_active_item(page: Page) -> None:
    page.locator(".todo-list li .toggle").nth(1).check()
    check_number_of_completed_todos_in_local_storage(page, 1)
    page.locator(".filters >> text=Active").click()
    expect(page.locator(".todo-list li")).to_have_count(2)
    expect(page.locator(".todo-list li")).to_have_text([TODO_ITEMS[0], TODO_ITEMS[2]])


def test_should_respect_the_back_button(page: Page) -> None:
    page.locator(".todo-list li .toggle").nth(1).check()
    check_number_of_completed_todos_in_local_storage(page, 1)

    # Showing all items
    page.locator(".filters >> text=All").click()
    expect(page.locator(".todo-list li")).to_have_count(3)

    # Showing active items
    page.locator(".filters >> text=Active").click()

    # Showing completed items
    page.locator(".filters >> text=Completed").click()

    expect(page.locator(".todo-list li")).to_have_count(1)
    page.go_back()
    expect(page.locator(".todo-list li")).to_have_count(2)
    page.go_back()
    expect(page.locator(".todo-list li")).to_have_count(3)


def test_should_allow_me_to_display_completed_items(page: Page) -> None:
    page.locator(".todo-list li .toggle").nth(1).check()
    check_number_of_completed_todos_in_local_storage(page, 1)
    page.locator(".filters >> text=Completed").click()
    expect(page.locator(".todo-list li")).to_have_count(1)


def test_should_allow_me_to_display_all_items(page: Page) -> None:
    page.locator(".todo-list li .toggle").nth(1).check()
    check_number_of_completed_todos_in_local_storage(page, 1)
    page.locator(".filters >> text=Active").click()
    page.locator(".filters >> text=Completed").click()
    page.locator(".filters >> text=All").click()
    expect(page.locator(".todo-list li")).to_have_count(3)


def test_should_highlight_the_current_applied_filter(page: Page) -> None:
    expect(page.locator(".filters >> text=All")).to_have_class("selected")
    page.locator(".filters >> text=Active").click()
    # Page change - active items.
    expect(page.locator(".filters >> text=Active")).to_have_class("selected")
    page.locator(".filters >> text=Completed").click()
    # Page change - completed items.
    expect(page.locator(".filters >> text=Completed")).to_have_class("selected")


================================================
FILE: examples/todomvc/mvctests/utils.py
================================================
# 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.
from playwright.sync_api import Page

TODO_ITEMS = ["buy some cheese", "feed the cat", "book a doctors appointment"]


def create_default_todos(page: Page) -> None:
    for item in TODO_ITEMS:
        page.locator(".new-todo").fill(item)
        page.locator(".new-todo").press("Enter")


def check_number_of_completed_todos_in_local_storage(page: Page, expected: int) -> None:
    assert (
        page.evaluate(
            "JSON.parse(localStorage['react-todos']).filter(i => i.completed).length"
        )
        == expected
    )


def assert_number_of_todos_in_local_storage(page: Page, expected: int) -> None:
    assert len(page.evaluate("JSON.parse(localStorage['react-todos'])")) == expected


def check_todos_in_local_storage(page: Page, title: str) -> None:
    assert title in page.evaluate(
        "JSON.parse(localStorage['react-todos']).map(i => i.title)"
    )


================================================
FILE: examples/todomvc/requirements.txt
================================================
pytest-playwright


================================================
FILE: local-requirements.txt
================================================
autobahn==23.1.2
black==25.1.0
build==1.3.0
flake8==7.2.0
mypy==1.17.1
objgraph==3.6.2
Pillow==11.3.0
pixelmatch==0.3.0
pre-commit==3.5.0
pyOpenSSL==25.1.0
pytest==8.4.1
pytest-asyncio==1.1.0
pytest-cov==6.3.0
pytest-repeat==0.9.4
pytest-rerunfailures==15.1
pytest-timeout==2.4.0
pytest-xdist==3.8.0
requests==2.32.5
service_identity==24.2.0
twisted==25.5.0
types-pyOpenSSL==24.1.0.20240722
types-requests==2.32.4.20250809


================================================
FILE: meta.yaml
================================================
package:
  name: playwright
  version: "{{ environ.get('GIT_DESCRIBE_TAG') | replace('v', '') }}"

source:
  path: .

build:
  number: 0
  script: "{{ PYTHON }} -m pip install . --no-deps -vv"
  binary_relocation: False
  missing_dso_whitelist: "*"
  entry_points:
    - playwright = playwright.__main__:main

requirements:
  build:
    - python >=3.9                        # [build_platform != target_platform]
    - pip                                 # [build_platform != target_platform]
    - cross-python_{{ target_platform }}  # [build_platform != target_platform]
  host:
    - python >=3.9
    - wheel
    - pip
    - curl
    - setuptools_scm
  run:
    - python >=3.9
    # This should be the same as the dependencies in pyproject.toml
    - greenlet>=3.1.1,<4.0.0
    - pyee>=13,<14

test: # [build_platform == target_platform]
  files:
    - scripts/example_sync.py
    - scripts/example_async.py
  requires:
    - pip
  imports:
    - playwright
    - playwright.sync_api
    - playwright.async_api
  commands:
    - playwright --help
    - playwright install --with-deps
    - python scripts/example_sync.py
    - python scripts/example_async.py

about:
  home: https://github.com/microsoft/playwright-python
  license: Apache-2.0
  license_family: Apache
  license_file: LICENSE
  summary: Python version of the Playwright testing and automation library.
  description: |
    Playwright is a Python library to automate Chromium,
    Firefox and WebKit browsers with a single API. Playwright
    delivers automation that is ever-green, capable, reliable
    and fast.
  doc_url: https://playwright.dev/python/docs/intro/
  dev_url: https://github.com/microsoft/playwright-python


================================================
FILE: playwright/__init__.py
================================================
# 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.

"""
Python package `playwright` is a Python library to automate Chromium,
Firefox and WebKit with a single API. Playwright is built to enable cross-browser
web automation that is ever-green, capable, reliable and fast.
"""


================================================
FILE: playwright/__main__.py
================================================
# 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 subprocess
import sys

from playwright._impl._driver import compute_driver_executable, get_driver_env


def main() -> None:
    try:
        driver_executable, driver_cli = compute_driver_executable()
        completed_process = subprocess.run(
            [driver_executable, driver_cli, *sys.argv[1:]], env=get_driver_env()
        )
        sys.exit(completed_process.returncode)
    except KeyboardInterrupt:
        sys.exit(130)


if __name__ == "__main__":
    main()


================================================
FILE: playwright/_impl/__init__.py
================================================


================================================
FILE: playwright/_impl/__pyinstaller/__init__.py
================================================
# 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 os
from typing import List


def get_hook_dirs() -> List[str]:
    return [os.path.dirname(__file__)]


================================================
FILE: playwright/_impl/__pyinstaller/hook-playwright.async_api.py
================================================
# 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.

from PyInstaller.utils.hooks import collect_data_files  # type: ignore

datas = collect_data_files("playwright")


================================================
FILE: playwright/_impl/__pyinstaller/hook-playwright.sync_api.py
================================================
# 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.

from PyInstaller.utils.hooks import collect_data_files  # type: ignore

datas = collect_data_files("playwright")


================================================
FILE: playwright/_impl/_api_structures.py
================================================
# 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.

from pathlib import Path
from typing import Any, Dict, List, Literal, Optional, Sequence, TypedDict, Union

# These are the structures that we like keeping in a JSON form for their potential
# reuse between SDKs / services. They are public and are a part of the
# stable API.

# Explicitly mark optional params as such for the documentation
# If there is at least one optional param, set total=False for better mypy handling.


class Cookie(TypedDict, total=False):
    name: str
    value: str
    domain: str
    path: str
    expires: float
    httpOnly: bool
    secure: bool
    sameSite: Literal["Lax", "None", "Strict"]
    partitionKey: Optional[str]


class StorageStateCookie(TypedDict, total=False):
    name: str
    value: str
    domain: str
    path: str
    expires: float
    httpOnly: bool
    secure: bool
    sameSite: Literal["Lax", "None", "Strict"]


# TODO: We are waiting for PEP705 so SetCookieParam can be readonly and matches Cookie.
class SetCookieParam(TypedDict, total=False):
    name: str
    value: str
    url: Optional[str]
    domain: Optional[str]
    path: Optional[str]
    expires: Optional[float]
    httpOnly: Optional[bool]
    secure: Optional[bool]
    sameSite: Optional[Literal["Lax", "None", "Strict"]]
    partitionKey: Optional[str]


class FloatRect(TypedDict):
    x: float
    y: float
    width: float
    height: float


class Geolocation(TypedDict, total=False):
    latitude: float
    longitude: float
    accuracy: Optional[float]


class HttpCredentials(TypedDict, total=False):
    username: str
    password: str
    origin: Optional[str]
    send: Optional[Literal["always", "unauthorized"]]


class LocalStorageEntry(TypedDict):
    name: str
    value: str


class OriginState(TypedDict):
    origin: str
    localStorage: List[LocalStorageEntry]


class PdfMargins(TypedDict, total=False):
    top: Optional[Union[str, float]]
    right: Optional[Union[str, float]]
    bottom: Optional[Union[str, float]]
    left: Optional[Union[str, float]]


class Position(TypedDict):
    x: float
    y: float


class ProxySettings(TypedDict, total=False):
    server: str
    bypass: Optional[str]
    username: Optional[str]
    password: Optional[str]


class StorageState(TypedDict, total=False):
    cookies: List[StorageStateCookie]
    origins: List[OriginState]


class ClientCertificate(TypedDict, total=False):
    origin: str
    certPath: Optional[Union[str, Path]]
    cert: Optional[bytes]
    keyPath: Optional[Union[str, Path]]
    key: Optional[bytes]
    pfxPath: Optional[Union[str, Path]]
    pfx: Optional[bytes]
    passphrase: Optional[str]


class ResourceTiming(TypedDict):
    startTime: float
    domainLookupStart: float
    domainLookupEnd: float
    connectStart: float
    secureConnectionStart: float
    connectEnd: float
    requestStart: float
    responseStart: float
    responseEnd: float


class RequestSizes(TypedDict):
    requestBodySize: int
    requestHeadersSize: int
    responseBodySize: int
    responseHeadersSize: int


class ViewportSize(TypedDict):
    width: int
    height: int


class SourceLocation(TypedDict):
    url: str
    lineNumber: int
    columnNumber: int


class FilePayload(TypedDict):
    name: str
    mimeType: str
    buffer: bytes


class RemoteAddr(TypedDict):
    ipAddress: str
    port: int


class SecurityDetails(TypedDict):
    issuer: Optional[str]
    protocol: Optional[str]
    subjectName: Optional[str]
    validFrom: Optional[float]
    validTo: Optional[float]


class NameValue(TypedDict):
    name: str
    value: str


HeadersArray = List[NameValue]
Headers = Dict[str, str]


class ServerFilePayload(TypedDict):
    name: str
    mimeType: str
    buffer: str


class FormField(TypedDict, total=False):
    name: str
    value: Optional[str]
    file: Optional[ServerFilePayload]


class ExpectedTextValue(TypedDict, total=False):
    string: str
    regexSource: str
    regexFlags: str
    matchSubstring: bool
    normalizeWhiteSpace: bool
    ignoreCase: Optional[bool]


class FrameExpectOptions(TypedDict, total=False):
    expressionArg: Any
    expectedText: Optional[Sequence[ExpectedTextValue]]
    expectedNumber: Optional[float]
    expectedValue: Optional[Any]
    useInnerText: Optional[bool]
    isNot: bool
    timeout: Optional[float]


class FrameExpectResult(TypedDict):
    matches: bool
    received: Any
    log: List[str]
    errorMessage: Optional[str]


AriaRole = Literal[
    "alert",
    "alertdialog",
    "application",
    "article",
    "banner",
    "blockquote",
    "button",
    "caption",
    "cell",
    "checkbox",
    "code",
    "columnheader",
    "combobox",
    "complementary",
    "contentinfo",
    "definition",
    "deletion",
    "dialog",
    "directory",
    "document",
    "emphasis",
    "feed",
    "figure",
    "form",
    "generic",
    "grid",
    "gridcell",
    "group",
    "heading",
    "img",
    "insertion",
    "link",
    "list",
    "listbox",
    "listitem",
    "log",
    "main",
    "marquee",
    "math",
    "menu",
    "menubar",
    "menuitem",
    "menuitemcheckbox",
    "menuitemradio",
    "meter",
    "navigation",
    "none",
    "note",
    "option",
    "paragraph",
    "presentation",
    "progressbar",
    "radio",
    "radiogroup",
    "region",
    "row",
    "rowgroup",
    "rowheader",
    "scrollbar",
    "search",
    "searchbox",
    "separator",
    "slider",
    "spinbutton",
    "status",
    "strong",
    "subscript",
    "superscript",
    "switch",
    "tab",
    "table",
    "tablist",
    "tabpanel",
    "term",
    "textbox",
    "time",
    "timer",
    "toolbar",
    "tooltip",
    "tree",
    "treegrid",
    "treeitem",
]


class TracingGroupLocation(TypedDict):
    file: str
    line: Optional[int]
    column: Optional[int]


================================================
FILE: playwright/_impl/_artifact.py
================================================
# 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 pathlib
from pathlib import Path
from typing import Dict, Optional, Union, cast

from playwright._impl._connection import ChannelOwner, from_channel
from playwright._impl._helper import Error, make_dirs_for_file, patch_error_message
from playwright._impl._stream import Stream


class Artifact(ChannelOwner):
    def __init__(
        self, parent: ChannelOwner, type: str, guid: str, initializer: Dict
    ) -> None:
        super().__init__(parent, type, guid, initializer)
        self.absolute_path = initializer["absolutePath"]

    async def path_after_finished(self) -> pathlib.Path:
        if self._connection.is_remote:
            raise Error(
                "Path is not available when using browser_type.connect(). Use save_as() to save a local copy."
            )
        path = await self._channel.send(
            "pathAfterFinished",
            None,
        )
        return pathlib.Path(path)

    async def save_as(self, path: Union[str, Path]) -> None:
        stream = cast(
            Stream,
            from_channel(
                await self._channel.send(
                    "saveAsStream",
                    None,
                )
            ),
        )
        make_dirs_for_file(path)
        await stream.save_as(path)

    async def failure(self) -> Optional[str]:
        reason = await self._channel.send(
            "failure",
            None,
        )
        if reason is None:
            return None
        return patch_error_message(reason)

    async def delete(self) -> None:
        await self._channel.send(
            "delete",
            None,
        )

    async def read_info_buffer(self) -> bytes:
        stream = cast(
            Stream,
            from_channel(
                await self._channel.send(
                    "stream",
                    None,
                )
            ),
        )
        buffer = await stream.read_all()
        return buffer

    async def cancel(self) -> None:  # pyright: ignore[reportIncompatibleMethodOverride]
        await self._channel.send(
            "cancel",
            None,
        )


================================================
FILE: playwright/_impl/_assertions.py
================================================
# 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 collections.abc
from typing import Any, List, Optional, Pattern, Sequence, Union
from urllib.parse import urljoin

from playwright._impl._api_structures import (
    AriaRole,
    ExpectedTextValue,
    FrameExpectOptions,
    FrameExpectResult,
)
from playwright._impl._connection import format_call_log
from playwright._impl._errors import Error
from playwright._impl._fetch import APIResponse
from playwright._impl._helper import is_textual_mime_type
from playwright._impl._locator import Locator
from playwright._impl._page import Page
from playwright._impl._str_utils import escape_regex_flags


class AssertionsBase:
    def __init__(
        self,
        locator: Locator,
        timeout: float = None,
        is_not: bool = False,
        message: Optional[str] = None,
    ) -> None:
        self._actual_locator = locator
        self._loop = locator._loop
        self._dispatcher_fiber = locator._dispatcher_fiber
        self._timeout = timeout
        self._is_not = is_not
        self._custom_message = message

    async def _call_expect(
        self, expression: str, expect_options: FrameExpectOptions, title: Optional[str]
    ) -> FrameExpectResult:
        raise NotImplementedError(
            "_call_expect must be implemented in a derived class."
        )

    async def _expect_impl(
        self,
        expression: str,
        expect_options: FrameExpectOptions,
        expected: Any,
        message: str,
        title: str = None,
    ) -> None:
        __tracebackhide__ = True
        expect_options["isNot"] = self._is_not
        if expect_options.get("timeout") is None:
            expect_options["timeout"] = self._timeout or 5_000
        if expect_options["isNot"]:
            message = message.replace("expected to", "expected not to")
        if "useInnerText" in expect_options and expect_options["useInnerText"] is None:
            del expect_options["useInnerText"]
        result = await self._call_expect(expression, expect_options, title)
        if result["matches"] == self._is_not:
            actual = result.get("received")
            if self._custom_message:
                out_message = self._custom_message
                if expected is not None:
                    out_message += f"\nExpected value: '{expected or '<None>'}'"
            else:
                out_message = (
                    f"{message} '{expected}'" if expected is not None else f"{message}"
                )
            error_message = result.get("errorMessage")
            error_message = f"\n{error_message}" if error_message else ""
            raise AssertionError(
                f"{out_message}\nActual value: {actual}{error_message} {format_call_log(result.get('log'))}"
            )


class PageAssertions(AssertionsBase):
    def __init__(
        self,
        page: Page,
        timeout: float = None,
        is_not: bool = False,
        message: Optional[str] = None,
    ) -> None:
        super().__init__(page.locator(":root"), timeout, is_not, message)
        self._actual_page = page

    async def _call_expect(
        self, expression: str, expect_options: FrameExpectOptions, title: Optional[str]
    ) -> FrameExpectResult:
        __tracebackhide__ = True
        return await self._actual_page.main_frame._expect(
            None, expression, expect_options, title
        )

    @property
    def _not(self) -> "PageAssertions":
        return PageAssertions(
            self._actual_page, self._timeout, not self._is_not, self._custom_message
        )

    async def to_have_title(
        self, titleOrRegExp: Union[Pattern[str], str], timeout: float = None
    ) -> None:
        __tracebackhide__ = True
        expected_values = to_expected_text_values(
            [titleOrRegExp], normalize_white_space=True
        )
        await self._expect_impl(
            "to.have.title",
            FrameExpectOptions(expectedText=expected_values, timeout=timeout),
            titleOrRegExp,
            "Page title expected to be",
            'Expect "to_have_title"',
        )

    async def not_to_have_title(
        self, titleOrRegExp: Union[Pattern[str], str], timeout: float = None
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_have_title(titleOrRegExp, timeout)

    async def to_have_url(
        self,
        urlOrRegExp: Union[str, Pattern[str]],
        timeout: float = None,
        ignoreCase: bool = None,
    ) -> None:
        __tracebackhide__ = True
        base_url = self._actual_page.context._base_url
        if isinstance(urlOrRegExp, str) and base_url:
            urlOrRegExp = urljoin(base_url, urlOrRegExp)
        expected_text = to_expected_text_values([urlOrRegExp], ignoreCase=ignoreCase)
        await self._expect_impl(
            "to.have.url",
            FrameExpectOptions(expectedText=expected_text, timeout=timeout),
            urlOrRegExp,
            "Page URL expected to be",
            'Expect "to_have_url"',
        )

    async def not_to_have_url(
        self,
        urlOrRegExp: Union[Pattern[str], str],
        timeout: float = None,
        ignoreCase: bool = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_have_url(urlOrRegExp, timeout, ignoreCase)


class LocatorAssertions(AssertionsBase):
    def __init__(
        self,
        locator: Locator,
        timeout: float = None,
        is_not: bool = False,
        message: Optional[str] = None,
    ) -> None:
        super().__init__(locator, timeout, is_not, message)
        self._actual_locator = locator

    async def _call_expect(
        self, expression: str, expect_options: FrameExpectOptions, title: Optional[str]
    ) -> FrameExpectResult:
        __tracebackhide__ = True
        return await self._actual_locator._expect(expression, expect_options, title)

    @property
    def _not(self) -> "LocatorAssertions":
        return LocatorAssertions(
            self._actual_locator, self._timeout, not self._is_not, self._custom_message
        )

    async def to_contain_text(
        self,
        expected: Union[
            Sequence[str],
            Sequence[Pattern[str]],
            Sequence[Union[Pattern[str], str]],
            Pattern[str],
            str,
        ],
        useInnerText: bool = None,
        timeout: float = None,
        ignoreCase: bool = None,
    ) -> None:
        __tracebackhide__ = True
        if isinstance(expected, collections.abc.Sequence) and not isinstance(
            expected, str
        ):
            expected_text = to_expected_text_values(
                expected,
                match_substring=True,
                normalize_white_space=True,
                ignoreCase=ignoreCase,
            )
            await self._expect_impl(
                "to.contain.text.array",
                FrameExpectOptions(
                    expectedText=expected_text,
                    useInnerText=useInnerText,
                    timeout=timeout,
                ),
                expected,
                "Locator expected to contain text",
                'Expect "to_contain_text"',
            )
        else:
            expected_text = to_expected_text_values(
                [expected],
                match_substring=True,
                normalize_white_space=True,
                ignoreCase=ignoreCase,
            )
            await self._expect_impl(
                "to.have.text",
                FrameExpectOptions(
                    expectedText=expected_text,
                    useInnerText=useInnerText,
                    timeout=timeout,
                ),
                expected,
                "Locator expected to contain text",
                'Expect "to_contain_text"',
            )

    async def not_to_contain_text(
        self,
        expected: Union[
            Sequence[str],
            Sequence[Pattern[str]],
            Sequence[Union[Pattern[str], str]],
            Pattern[str],
            str,
        ],
        useInnerText: bool = None,
        timeout: float = None,
        ignoreCase: bool = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_contain_text(expected, useInnerText, timeout, ignoreCase)

    async def to_have_attribute(
        self,
        name: str,
        value: Union[str, Pattern[str]],
        ignoreCase: bool = None,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        expected_text = to_expected_text_values([value], ignoreCase=ignoreCase)
        await self._expect_impl(
            "to.have.attribute.value",
            FrameExpectOptions(
                expressionArg=name, expectedText=expected_text, timeout=timeout
            ),
            value,
            "Locator expected to have attribute",
            'Expect "to_have_attribute"',
        )

    async def not_to_have_attribute(
        self,
        name: str,
        value: Union[str, Pattern[str]],
        ignoreCase: bool = None,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_have_attribute(
            name, value, ignoreCase=ignoreCase, timeout=timeout
        )

    async def to_have_class(
        self,
        expected: Union[
            Sequence[str],
            Sequence[Pattern[str]],
            Sequence[Union[Pattern[str], str]],
            Pattern[str],
            str,
        ],
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        if isinstance(expected, collections.abc.Sequence) and not isinstance(
            expected, str
        ):
            expected_text = to_expected_text_values(expected)
            await self._expect_impl(
                "to.have.class.array",
                FrameExpectOptions(expectedText=expected_text, timeout=timeout),
                expected,
                "Locator expected to have class",
                'Expect "to_have_class"',
            )
        else:
            expected_text = to_expected_text_values([expected])
            await self._expect_impl(
                "to.have.class",
                FrameExpectOptions(expectedText=expected_text, timeout=timeout),
                expected,
                "Locator expected to have class",
                'Expect "to_have_class"',
            )

    async def not_to_have_class(
        self,
        expected: Union[
            Sequence[str],
            Sequence[Pattern[str]],
            Sequence[Union[Pattern[str], str]],
            Pattern[str],
            str,
        ],
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_have_class(expected, timeout)

    async def to_contain_class(
        self,
        expected: Union[
            Sequence[str],
            str,
        ],
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        if isinstance(expected, collections.abc.Sequence) and not isinstance(
            expected, str
        ):
            expected_text = to_expected_text_values(expected)
            await self._expect_impl(
                "to.contain.class.array",
                FrameExpectOptions(expectedText=expected_text, timeout=timeout),
                expected,
                "Locator expected to contain class names",
                'Expect "to_contain_class"',
            )
        else:
            expected_text = to_expected_text_values([expected])
            await self._expect_impl(
                "to.contain.class",
                FrameExpectOptions(expectedText=expected_text, timeout=timeout),
                expected,
                "Locator expected to contain class",
                'Expect "to_contain_class"',
            )

    async def not_to_contain_class(
        self,
        expected: Union[
            Sequence[str],
            str,
        ],
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_contain_class(expected, timeout)

    async def to_have_count(
        self,
        count: int,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._expect_impl(
            "to.have.count",
            FrameExpectOptions(expectedNumber=count, timeout=timeout),
            count,
            "Locator expected to have count",
            'Expect "to_have_count"',
        )

    async def not_to_have_count(
        self,
        count: int,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_have_count(count, timeout)

    async def to_have_css(
        self,
        name: str,
        value: Union[str, Pattern[str]],
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        expected_text = to_expected_text_values([value])
        await self._expect_impl(
            "to.have.css",
            FrameExpectOptions(
                expressionArg=name, expectedText=expected_text, timeout=timeout
            ),
            value,
            "Locator expected to have CSS",
            'Expect "to_have_css"',
        )

    async def not_to_have_css(
        self,
        name: str,
        value: Union[str, Pattern[str]],
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_have_css(name, value, timeout)

    async def to_have_id(
        self,
        id: Union[str, Pattern[str]],
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        expected_text = to_expected_text_values([id])
        await self._expect_impl(
            "to.have.id",
            FrameExpectOptions(expectedText=expected_text, timeout=timeout),
            id,
            "Locator expected to have ID",
            'Expect "to_have_id"',
        )

    async def not_to_have_id(
        self,
        id: Union[str, Pattern[str]],
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_have_id(id, timeout)

    async def to_have_js_property(
        self,
        name: str,
        value: Any,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._expect_impl(
            "to.have.property",
            FrameExpectOptions(
                expressionArg=name, expectedValue=value, timeout=timeout
            ),
            value,
            "Locator expected to have JS Property",
            'Expect "to_have_property"',
        )

    async def not_to_have_js_property(
        self,
        name: str,
        value: Any,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_have_js_property(name, value, timeout)

    async def to_have_value(
        self,
        value: Union[str, Pattern[str]],
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        expected_text = to_expected_text_values([value])
        await self._expect_impl(
            "to.have.value",
            FrameExpectOptions(expectedText=expected_text, timeout=timeout),
            value,
            "Locator expected to have Value",
            'Expect "to_have_value"',
        )

    async def not_to_have_value(
        self,
        value: Union[str, Pattern[str]],
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_have_value(value, timeout)

    async def to_have_values(
        self,
        values: Union[
            Sequence[str], Sequence[Pattern[str]], Sequence[Union[Pattern[str], str]]
        ],
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        expected_text = to_expected_text_values(values)
        await self._expect_impl(
            "to.have.values",
            FrameExpectOptions(expectedText=expected_text, timeout=timeout),
            values,
            "Locator expected to have Values",
            'Expect "to_have_values"',
        )

    async def not_to_have_values(
        self,
        values: Union[
            Sequence[str], Sequence[Pattern[str]], Sequence[Union[Pattern[str], str]]
        ],
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_have_values(values, timeout)

    async def to_have_text(
        self,
        expected: Union[
            Sequence[str],
            Sequence[Pattern[str]],
            Sequence[Union[Pattern[str], str]],
            Pattern[str],
            str,
        ],
        useInnerText: bool = None,
        timeout: float = None,
        ignoreCase: bool = None,
    ) -> None:
        __tracebackhide__ = True
        if isinstance(expected, collections.abc.Sequence) and not isinstance(
            expected, str
        ):
            expected_text = to_expected_text_values(
                expected,
                normalize_white_space=True,
                ignoreCase=ignoreCase,
            )
            await self._expect_impl(
                "to.have.text.array",
                FrameExpectOptions(
                    expectedText=expected_text,
                    useInnerText=useInnerText,
                    timeout=timeout,
                ),
                expected,
                "Locator expected to have text",
                'Expect "to_have_text"',
            )
        else:
            expected_text = to_expected_text_values(
                [expected], normalize_white_space=True, ignoreCase=ignoreCase
            )
            await self._expect_impl(
                "to.have.text",
                FrameExpectOptions(
                    expectedText=expected_text,
                    useInnerText=useInnerText,
                    timeout=timeout,
                ),
                expected,
                "Locator expected to have text",
                'Expect "to_have_text"',
            )

    async def not_to_have_text(
        self,
        expected: Union[
            Sequence[str],
            Sequence[Pattern[str]],
            Sequence[Union[Pattern[str], str]],
            Pattern[str],
            str,
        ],
        useInnerText: bool = None,
        timeout: float = None,
        ignoreCase: bool = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_have_text(expected, useInnerText, timeout, ignoreCase)

    async def to_be_attached(
        self,
        attached: bool = None,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        if attached is None:
            attached = True
        attached_string = "attached" if attached else "detached"
        await self._expect_impl(
            ("to.be.attached" if attached else "to.be.detached"),
            FrameExpectOptions(timeout=timeout),
            None,
            f"Locator expected to be {attached_string}",
            'Expect "to_be_attached"',
        )

    async def to_be_checked(
        self,
        timeout: float = None,
        checked: bool = None,
        indeterminate: bool = None,
    ) -> None:
        __tracebackhide__ = True
        expected_value = {}
        if indeterminate is not None:
            expected_value["indeterminate"] = indeterminate
        if checked is not None:
            expected_value["checked"] = checked
        checked_string: str
        if indeterminate:
            checked_string = "indeterminate"
        else:
            checked_string = "unchecked" if checked is False else "checked"
        await self._expect_impl(
            "to.be.checked",
            FrameExpectOptions(timeout=timeout, expectedValue=expected_value),
            None,
            f"Locator expected to be {checked_string}",
            'Expect "to_be_checked"',
        )

    async def not_to_be_attached(
        self,
        attached: bool = None,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_be_attached(attached=attached, timeout=timeout)

    async def not_to_be_checked(
        self,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_be_checked(timeout)

    async def to_be_disabled(
        self,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._expect_impl(
            "to.be.disabled",
            FrameExpectOptions(timeout=timeout),
            None,
            "Locator expected to be disabled",
            'Expect "to_be_disabled"',
        )

    async def not_to_be_disabled(
        self,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_be_disabled(timeout)

    async def to_be_editable(
        self,
        editable: bool = None,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        if editable is None:
            editable = True
        editable_string = "editable" if editable else "readonly"
        await self._expect_impl(
            "to.be.editable" if editable else "to.be.readonly",
            FrameExpectOptions(timeout=timeout),
            None,
            f"Locator expected to be {editable_string}",
            'Expect "to_be_editable"',
        )

    async def not_to_be_editable(
        self,
        editable: bool = None,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_be_editable(editable, timeout)

    async def to_be_empty(
        self,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._expect_impl(
            "to.be.empty",
            FrameExpectOptions(timeout=timeout),
            None,
            "Locator expected to be empty",
            'Expect "to_be_empty"',
        )

    async def not_to_be_empty(
        self,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_be_empty(timeout)

    async def to_be_enabled(
        self,
        enabled: bool = None,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        if enabled is None:
            enabled = True
        enabled_string = "enabled" if enabled else "disabled"
        await self._expect_impl(
            "to.be.enabled" if enabled else "to.be.disabled",
            FrameExpectOptions(timeout=timeout),
            None,
            f"Locator expected to be {enabled_string}",
            'Expect "to_be_enabled"',
        )

    async def not_to_be_enabled(
        self,
        enabled: bool = None,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_be_enabled(enabled, timeout)

    async def to_be_hidden(
        self,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._expect_impl(
            "to.be.hidden",
            FrameExpectOptions(timeout=timeout),
            None,
            "Locator expected to be hidden",
            'Expect "to_be_hidden"',
        )

    async def not_to_be_hidden(
        self,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_be_hidden(timeout)

    async def to_be_visible(
        self,
        visible: bool = None,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        if visible is None:
            visible = True
        visible_string = "visible" if visible else "hidden"
        await self._expect_impl(
            "to.be.visible" if visible else "to.be.hidden",
            FrameExpectOptions(timeout=timeout),
            None,
            f"Locator expected to be {visible_string}",
            'Expect "to_be_visible"',
        )

    async def not_to_be_visible(
        self,
        visible: bool = None,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_be_visible(visible, timeout)

    async def to_be_focused(
        self,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._expect_impl(
            "to.be.focused",
            FrameExpectOptions(timeout=timeout),
            None,
            "Locator expected to be focused",
            'Expect "to_be_focused"',
        )

    async def not_to_be_focused(
        self,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_be_focused(timeout)

    async def to_be_in_viewport(
        self,
        ratio: float = None,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._expect_impl(
            "to.be.in.viewport",
            FrameExpectOptions(timeout=timeout, expectedNumber=ratio),
            None,
            "Locator expected to be in viewport",
            'Expect "to_be_in_viewport"',
        )

    async def not_to_be_in_viewport(
        self, ratio: float = None, timeout: float = None
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_be_in_viewport(ratio=ratio, timeout=timeout)

    async def to_have_accessible_description(
        self,
        description: Union[str, Pattern[str]],
        ignoreCase: bool = None,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        expected_values = to_expected_text_values(
            [description], ignoreCase=ignoreCase, normalize_white_space=True
        )
        await self._expect_impl(
            "to.have.accessible.description",
            FrameExpectOptions(expectedText=expected_values, timeout=timeout),
            None,
            "Locator expected to have accessible description",
            'Expect "to_have_accessible_description"',
        )

    async def not_to_have_accessible_description(
        self,
        name: Union[str, Pattern[str]],
        ignoreCase: bool = None,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_have_accessible_description(name, ignoreCase, timeout)

    async def to_have_accessible_name(
        self,
        name: Union[str, Pattern[str]],
        ignoreCase: bool = None,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        expected_values = to_expected_text_values(
            [name], ignoreCase=ignoreCase, normalize_white_space=True
        )
        await self._expect_impl(
            "to.have.accessible.name",
            FrameExpectOptions(expectedText=expected_values, timeout=timeout),
            None,
            "Locator expected to have accessible name",
            'Expect "to_have_accessible_name"',
        )

    async def not_to_have_accessible_name(
        self,
        name: Union[str, Pattern[str]],
        ignoreCase: bool = None,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_have_accessible_name(name, ignoreCase, timeout)

    async def to_have_role(self, role: AriaRole, timeout: float = None) -> None:
        __tracebackhide__ = True
        if isinstance(role, Pattern):
            raise Error('"role" argument in to_have_role must be a string')
        expected_values = to_expected_text_values([role])
        await self._expect_impl(
            "to.have.role",
            FrameExpectOptions(expectedText=expected_values, timeout=timeout),
            None,
            "Locator expected to have accessible role",
            'Expect "to_have_role"',
        )

    async def to_have_accessible_error_message(
        self,
        errorMessage: Union[str, Pattern[str]],
        ignoreCase: bool = None,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        expected_values = to_expected_text_values(
            [errorMessage], ignoreCase=ignoreCase, normalize_white_space=True
        )
        await self._expect_impl(
            "to.have.accessible.error.message",
            FrameExpectOptions(expectedText=expected_values, timeout=timeout),
            None,
            "Locator expected to have accessible error message",
            'Expect "to_have_accessible_error_message"',
        )

    async def not_to_have_accessible_error_message(
        self,
        errorMessage: Union[str, Pattern[str]],
        ignoreCase: bool = None,
        timeout: float = None,
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_have_accessible_error_message(
            errorMessage=errorMessage, ignoreCase=ignoreCase, timeout=timeout
        )

    async def not_to_have_role(self, role: AriaRole, timeout: float = None) -> None:
        __tracebackhide__ = True
        await self._not.to_have_role(role, timeout)

    async def to_match_aria_snapshot(
        self, expected: str, timeout: float = None
    ) -> None:
        __tracebackhide__ = True
        await self._expect_impl(
            "to.match.aria",
            FrameExpectOptions(expectedValue=expected, timeout=timeout),
            expected,
            "Locator expected to match Aria snapshot",
            'Expect "to_match_aria_snapshot"',
        )

    async def not_to_match_aria_snapshot(
        self, expected: str, timeout: float = None
    ) -> None:
        __tracebackhide__ = True
        await self._not.to_match_aria_snapshot(expected, timeout)


class APIResponseAssertions:
    def __init__(
        self,
        response: APIResponse,
        timeout: float = None,
        is_not: bool = False,
        message: Optional[str] = None,
    ) -> None:
        self._loop = response._loop
        self._dispatcher_fiber = response._dispatcher_fiber
        self._timeout = timeout
        self._is_not = is_not
        self._actual = response
        self._custom_message = message

    @property
    def _not(self) -> "APIResponseAssertions":
        return APIResponseAssertions(
            self._actual, self._timeout, not self._is_not, self._custom_message
        )

    async def to_be_ok(
        self,
    ) -> None:
        __tracebackhide__ = True
        if self._is_not is not self._actual.ok:
            return
        message = f"Response status expected to be within [200..299] range, was '{self._actual.status}'"
        if self._is_not:
            message = message.replace("expected to", "expected not to")
        out_message = self._custom_message or message
        out_message += format_call_log(await self._actual._fetch_log())

        content_type = self._actual.headers.get("content-type")
        is_text_encoding = content_type and is_textual_mime_type(content_type)
        text = await self._actual.text() if is_text_encoding else None
        if text is not None:
            out_message += f"\n Response Text:\n{text[:1000]}"

        raise AssertionError(out_message)

    async def not_to_be_ok(self) -> None:
        __tracebackhide__ = True
        await self._not.to_be_ok()


def expected_regex(
    pattern: Pattern[str],
    match_substring: bool,
    normalize_white_space: bool,
    ignoreCase: Optional[bool] = None,
) -> ExpectedTextValue:
    expected = ExpectedTextValue(
        regexSource=pattern.pattern,
        regexFlags=escape_regex_flags(pattern),
        matchSubstring=match_substring,
        normalizeWhiteSpace=normalize_white_space,
        ignoreCase=ignoreCase,
    )
    if expected["ignoreCase"] is None:
        del expected["ignoreCase"]
    return expected


def to_expected_text_values(
    items: Union[
        Sequence[Pattern[str]], Sequence[str], Sequence[Union[str, Pattern[str]]]
    ],
    match_substring: bool = False,
    normalize_white_space: bool = False,
    ignoreCase: Optional[bool] = None,
) -> Sequence[ExpectedTextValue]:
    out: List[ExpectedTextValue] = []
    assert isinstance(items, (list, tuple))
    for item in items:
        if isinstance(item, str):
            o = ExpectedTextValue(
                string=item,
                matchSubstring=match_substring,
                normalizeWhiteSpace=normalize_white_space,
                ignoreCase=ignoreCase,
            )
            if o["ignoreCase"] is None:
                del o["ignoreCase"]
            out.append(o)
        elif isinstance(item, Pattern):
            out.append(
                expected_regex(item, match_substring, normalize_white_space, ignoreCase)
            )
        else:
            raise Error("value must be a string or regular expression")
    return out


================================================
FILE: playwright/_impl/_async_base.py
================================================
# 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 asyncio
from contextlib import AbstractAsyncContextManager
from types import TracebackType
from typing import Any, Callable, Generic, Optional, Type, TypeVar, Union

from playwright._impl._impl_to_api_mapping import ImplToApiMapping, ImplWrapper

mapping = ImplToApiMapping()


T = TypeVar("T")
Self = TypeVar("Self", bound="AsyncContextManager")


class AsyncEventInfo(Generic[T]):
    def __init__(self, future: "asyncio.Future[T]") -> None:
        self._future = future

    @property
    async def value(self) -> T:
        return mapping.from_maybe_impl(await self._future)

    def _cancel(self) -> None:
        self._future.cancel()

    def is_done(self) -> bool:
        return self._future.done()


class AsyncEventContextManager(Generic[T], AbstractAsyncContextManager):
    def __init__(self, future: "asyncio.Future[T]") -> None:
        self._event = AsyncEventInfo[T](future)

    async def __aenter__(self) -> AsyncEventInfo[T]:
        return self._event

    async def __aexit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc_val: Optional[BaseException],
        exc_tb: Optional[TracebackType],
    ) -> None:
        if exc_val:
            self._event._cancel()
        else:
            await self._event.value


class AsyncBase(ImplWrapper):
    def __init__(self, impl_obj: Any) -> None:
        super().__init__(impl_obj)
        self._loop = impl_obj._loop

    def __str__(self) -> str:
        return self._impl_obj.__str__()

    def _wrap_handler(
        self, handler: Union[Callable[..., Any], Any]
    ) -> Callable[..., None]:
        if callable(handler):
            return mapping.wrap_handler(handler)
        return handler

    def on(self, event: Any, f: Any) -> None:
        """Registers the function ``f`` to the event name ``event``."""
        self._impl_obj.on(event, self._wrap_handler(f))

    def once(self, event: Any, f: Any) -> None:
        """The same as ``self.on``, except that the listener is automatically
        removed after being called.
        """
        self._impl_obj.once(event, self._wrap_handler(f))

    def remove_listener(self, event: Any, f: Any) -> None:
        """Removes the function ``f`` from ``event``."""
        self._impl_obj.remove_listener(event, self._wrap_handler(f))


class AsyncContextManager(AsyncBase):
    async def __aenter__(self: Self) -> Self:
        return self

    async def __aexit__(
        self,
        exc_type: Optional[Type[BaseException]],
        exc_val: Optional[BaseException],
        traceback: Optional[TracebackType],
    ) -> None:
        await self.close()

    async def close(self) -> None: ...


================================================
FILE: playwright/_impl/_browser.py
================================================
# 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.

from pathlib import Path
from types import SimpleNamespace
from typing import (
    TYPE_CHECKING,
    Dict,
    List,
    Optional,
    Pattern,
    Sequence,
    Set,
    Union,
    cast,
)

from playwright._impl._api_structures import (
    ClientCertificate,
    Geolocation,
    HttpCredentials,
    ProxySettings,
    StorageState,
    ViewportSize,
)
from playwright._impl._artifact import Artifact
from playwright._impl._browser_context import BrowserContext
from playwright._impl._cdp_session import CDPSession
from playwright._impl._connection import ChannelOwner, from_channel
from playwright._impl._errors import is_target_closed_error
from playwright._impl._helper import (
    ColorScheme,
    Contrast,
    ForcedColors,
    HarContentPolicy,
    HarMode,
    ReducedMotion,
    ServiceWorkersPolicy,
    locals_to_params,
    make_dirs_for_file,
)
from playwright._impl._page import Page

if TYPE_CHECKING:  # pragma: no cover
    from playwright._impl._browser_type import BrowserType


class Browser(ChannelOwner):
    Events = SimpleNamespace(
        Disconnected="disconnected",
    )

    def __init__(
        self, parent: "BrowserType", type: str, guid: str, initializer: Dict
    ) -> None:
        super().__init__(parent, type, guid, initializer)
        self._browser_type: Optional["BrowserType"] = None
        self._is_connected = True
        self._should_close_connection_on_close = False
        self._cr_tracing_path: Optional[str] = None

        self._contexts: Set[BrowserContext] = set()
        self._traces_dir: Optional[str] = None
        self._channel.on(
            "context",
            lambda params: self._did_create_context(
                cast(BrowserContext, from_channel(params["context"]))
            ),
        )
        self._channel.on("close", lambda _: self._on_close())
        self._close_reason: Optional[str] = None

    def __repr__(self) -> str:
        return f"<Browser type={self._browser_type} version={self.version}>"

    def _connect_to_browser_type(
        self,
        browser_type: "BrowserType",
        traces_dir: Optional[str] = None,
    ) -> None:
        # Note: when using connect(), `browserType` is different from `this.parent`.
        # This is why browser type is not wired up in the constructor, and instead this separate method is called later on.
        self._browser_type = browser_type
        self._traces_dir = traces_dir
        for context in self._contexts:
            self._setup_browser_context(context)

    def _did_create_context(self, context: BrowserContext) -> None:
        context._browser = self
        self._contexts.add(context)
        # Note: when connecting to a browser, initial contexts arrive before `_browserType` is set,
        # and will be configured later in `ConnectToBrowserType`.
        if self._browser_type:
            self._setup_browser_context(context)

    def _setup_browser_context(self, context: BrowserContext) -> None:
        context._tracing._traces_dir = self._traces_dir
        assert self._browser_type is not None
        self._browser_type._playwright.selectors._contexts_for_selectors.add(context)

    def _on_close(self) -> None:
        self._is_connected = False
        self.emit(Browser.Events.Disconnected, self)

    @property
    def contexts(self) -> List[BrowserContext]:
        return list(self._contexts)

    @property
    def browser_type(self) -> "BrowserType":
        assert self._browser_type is not None
        return self._browser_type

    def is_connected(self) -> bool:
        return self._is_connected

    async def new_context(
        self,
        viewport: ViewportSize = None,
        screen: ViewportSize = None,
        noViewport: bool = None,
        ignoreHTTPSErrors: bool = None,
        javaScriptEnabled: bool = None,
        bypassCSP: bool = None,
        userAgent: str = None,
        locale: str = None,
        timezoneId: str = None,
        geolocation: Geolocation = None,
        permissions: Sequence[str] = None,
        extraHTTPHeaders: Dict[str, str] = None,
        offline: bool = None,
        httpCredentials: HttpCredentials = None,
        deviceScaleFactor: float = None,
        isMobile: bool = None,
        hasTouch: bool = None,
        colorScheme: ColorScheme = None,
        reducedMotion: ReducedMotion = None,
        forcedColors: ForcedColors = None,
        contrast: Contrast = None,
        acceptDownloads: bool = None,
        defaultBrowserType: str = None,
        proxy: ProxySettings = None,
        recordHarPath: Union[Path, str] = None,
        recordHarOmitContent: bool = None,
        recordVideoDir: Union[Path, str] = None,
        recordVideoSize: ViewportSize = None,
        storageState: Union[StorageState, str, Path] = None,
        baseURL: str = None,
        strictSelectors: bool = None,
        serviceWorkers: ServiceWorkersPolicy = None,
        recordHarUrlFilter: Union[Pattern[str], str] = None,
        recordHarMode: HarMode = None,
        recordHarContent: HarContentPolicy = None,
        clientCertificates: List[ClientCertificate] = None,
    ) -> BrowserContext:
        params = locals_to_params(locals())
        assert self._browser_type is not None
        await self._browser_type._prepare_browser_context_params(params)

        channel = await self._channel.send("newContext", None, params)
        context = cast(BrowserContext, from_channel(channel))
        await context._initialize_har_from_options(
            record_har_content=recordHarContent,
            record_har_mode=recordHarMode,
            record_har_omit_content=recordHarOmitContent,
            record_har_path=recordHarPath,
            record_har_url_filter=recordHarUrlFilter,
        )
        return context

    async def new_page(
        self,
        viewport: ViewportSize = None,
        screen: ViewportSize = None,
        noViewport: bool = None,
        ignoreHTTPSErrors: bool = None,
        javaScriptEnabled: bool = None,
        bypassCSP: bool = None,
        userAgent: str = None,
        locale: str = None,
        timezoneId: str = None,
        geolocation: Geolocation = None,
        permissions: Sequence[str] = None,
        extraHTTPHeaders: Dict[str, str] = None,
        offline: bool = None,
        httpCredentials: HttpCredentials = None,
        deviceScaleFactor: float = None,
        isMobile: bool = None,
        hasTouch: bool = None,
        colorScheme: ColorScheme = None,
        forcedColors: ForcedColors = None,
        contrast: Contrast = None,
        reducedMotion: ReducedMotion = None,
        acceptDownloads: bool = None,
        defaultBrowserType: str = None,
        proxy: ProxySettings = None,
        recordHarPath: Union[Path, str] = None,
        recordHarOmitContent: bool = None,
        recordVideoDir: Union[Path, str] = None,
        recordVideoSize: ViewportSize = None,
        storageState: Union[StorageState, str, Path] = None,
        baseURL: str = None,
        strictSelectors: bool = None,
        serviceWorkers: ServiceWorkersPolicy = None,
        recordHarUrlFilter: Union[Pattern[str], str] = None,
        recordHarMode: HarMode = None,
        recordHarContent: HarContentPolicy = None,
        clientCertificates: List[ClientCertificate] = None,
    ) -> Page:
        params = locals_to_params(locals())

        async def inner() -> Page:
            context = await self.new_context(**params)
            page = await context.new_page()
            page._owned_context = context
            context._owner_page = page
            return page

        return await self._connection.wrap_api_call(inner, title="Create page")

    async def close(self, reason: str = None) -> None:
        self._close_reason = reason
        try:
            if self._should_close_connection_on_close:
                await self._connection.stop_async()
            else:
                await self._channel.send("close", None, {"reason": reason})
        except Exception as e:
            if not is_target_closed_error(e):
                raise e

    @property
    def version(self) -> str:
        return self._initializer["version"]

    async def new_browser_cdp_session(self) -> CDPSession:
        return from_channel(await self._channel.send("newBrowserCDPSession", None))

    async def start_tracing(
        self,
        page: Page = None,
        path: Union[str, Path] = None,
        screenshots: bool = None,
        categories: Sequence[str] = None,
    ) -> None:
        params = locals_to_params(locals())
        if page:
            params["page"] = page._channel
        if path:
            self._cr_tracing_path = str(path)
            params["path"] = str(path)
        await self._channel.send("startTracing", None, params)

    async def stop_tracing(self) -> bytes:
        artifact = cast(
            Artifact, from_channel(await self._channel.send("stopTracing", None))
        )
        buffer = await artifact.read_info_buffer()
        await artifact.delete()
        if self._cr_tracing_path:
            make_dirs_for_file(self._cr_tracing_path)
            with open(self._cr_tracing_path, "wb") as f:
                f.write(buffer)
            self._cr_tracing_path = None
        return buffer


================================================
FILE: playwright/_impl/_browser_context.py
================================================
# 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 asyncio
import json
from pathlib import Path
from types import SimpleNamespace
from typing import (
    TYPE_CHECKING,
    Any,
    Callable,
    Dict,
    List,
    Literal,
    Optional,
    Pattern,
    Sequence,
    Set,
    Union,
    cast,
)

from playwright._impl._api_structures import (
    Cookie,
    Geolocation,
    SetCookieParam,
    StorageState,
)
from playwright._impl._artifact import Artifact
from playwright._impl._cdp_session import CDPSession
from playwright._impl._clock import Clock
from playwright._impl._connection import (
    ChannelOwner,
    from_channel,
    from_nullable_channel,
)
from playwright._impl._console_message import ConsoleMessage
from playwright._impl._dialog import Dialog
from playwright._impl._errors import Error, TargetClosedError
from playwright._impl._event_context_manager import EventContextManagerImpl
from playwright._impl._fetch import APIRequestContext
from playwright._impl._frame import Frame
from playwright._impl._har_router import HarRouter
from playwright._impl._helper import (
    HarContentPolicy,
    HarMode,
    HarRecordingMetadata,
    RouteFromHarNotFoundPolicy,
    RouteHandler,
    RouteHandlerCallback,
    TimeoutSettings,
    URLMatch,
    WebSocketRouteHandlerCallback,
    async_readfile,
    async_writefile,
    locals_to_params,
    parse_error,
    to_impl,
)
from playwright._impl._network import (
    Request,
    Response,
    Route,
    WebSocketRoute,
    WebSocketRouteHandler,
    serialize_headers,
)
from playwright._impl._page import BindingCall, Page, Worker
from playwright._impl._str_utils import escape_regex_flags
from playwright._impl._tracing import Tracing
from playwright._impl._waiter import Waiter
from playwright._impl._web_error import WebError

if TYPE_CHECKING:  # pragma: no cover
    from playwright._impl._browser import Browser


class BrowserContext(ChannelOwner):
    Events = SimpleNamespace(
        # Deprecated in v1.56, never emitted anymore.
        BackgroundPage="backgroundpage",
        Close="close",
        Console="console",
        Dialog="dialog",
        Page="page",
        WebError="weberror",
        ServiceWorker="serviceworker",
        Request="request",
        Response="response",
        RequestFailed="requestfailed",
        RequestFinished="requestfinished",
    )

    def __init__(
        self, parent: ChannelOwner, type: str, guid: str, initializer: Dict
    ) -> None:
        super().__init__(parent, type, guid, initializer)
        # Browser is null for browser contexts created outside of normal browser, e.g. android or electron.
        # circular import workaround:
        self._browser: Optional["Browser"] = None
        if parent.__class__.__name__ == "Browser":
            self._browser = cast("Browser", parent)
        self._pages: List[Page] = []
        self._routes: List[RouteHandler] = []
        self._web_socket_routes: List[WebSocketRouteHandler] = []
        self._bindings: Dict[str, Any] = {}
        self._timeout_settings = TimeoutSettings(None)
        self._owner_page: Optional[Page] = None
        self._options: Dict[str, Any] = initializer["options"]
        self._service_workers: Set[Worker] = set()
        self._base_url: Optional[str] = self._options.get("baseURL")
        self._videos_dir: Optional[str] = self._options.get("recordVideo")
        self._tracing = cast(Tracing, from_channel(initializer["tracing"]))
        self._har_recorders: Dict[str, HarRecordingMetadata] = {}
        self._request: APIRequestContext = from_channel(initializer["requestContext"])
        self._request._timeout_settings = self._timeout_settings
        self._clock = Clock(self)
        self._channel.on(
            "bindingCall",
            lambda params: self._on_binding(from_channel(params["binding"])),
        )
        self._channel.on("close", lambda _: self._on_close())
        self._channel.on(
            "page", lambda params: self._on_page(from_channel(params["page"]))
        )
        self._channel.on(
            "route",
            lambda params: self._loop.create_task(
                self._on_route(
                    from_channel(params.get("route")),
                )
            ),
        )
        self._channel.on(
            "webSocketRoute",
            lambda params: self._loop.create_task(
                self._on_web_socket_route(
                    from_channel(params["webSocketRoute"]),
                )
            ),
        )

        self._channel.on(
            "serviceWorker",
            lambda params: self._on_service_worker(from_channel(params["worker"])),
        )
        self._channel.on(
            "console",
            lambda event: self._on_console_message(event),
        )

        self._channel.on(
            "dialog", lambda params: self._on_dialog(from_channel(params["dialog"]))
        )
        self._channel.on(
            "pageError",
            lambda params: self._on_page_error(
                parse_error(params["error"]["error"]),
                from_nullable_channel(params["page"]),
            ),
        )
        self._channel.on(
            "request",
            lambda params: self._on_request(
                from_channel(params["request"]),
                from_nullable_channel(params.get("page")),
            ),
        )
        self._channel.on(
            "response",
            lambda params: self._on_response(
                from_channel(params["response"]),
                from_nullable_channel(params.get("page")),
            ),
        )
        self._channel.on(
            "requestFailed",
            lambda params: self._on_request_failed(
                from_channel(params["request"]),
                params["responseEndTiming"],
                params.get("failureText"),
                from_nullable_channel(params.get("page")),
            ),
        )
        self._channel.on(
            "requestFinished",
            lambda params: self._on_request_finished(
                from_channel(params["request"]),
                from_nullable_channel(params.get("response")),
                params["responseEndTiming"],
                from_nullable_channel(params.get("page")),
            ),
        )
        self._closed_future: asyncio.Future = asyncio.Future()
        self.once(
            self.Events.Close, lambda context: self._closed_future.set_result(True)
        )
        self._close_reason: Optional[str] = None
        self._har_routers: List[HarRouter] = []
        self._set_event_to_subscription_mapping(
            {
                BrowserContext.Events.Console: "console",
                BrowserContext.Events.Dialog: "dialog",
                BrowserContext.Events.Request: "request",
                BrowserContext.Events.Response: "response",
                BrowserContext.Events.RequestFinished: "requestFinished",
                BrowserContext.Events.RequestFailed: "requestFailed",
            }
        )
        self._closing_or_closed = False

    def __repr__(self) -> str:
        return f"<BrowserContext browser={self.browser}>"

    def _on_page(self, page: Page) -> None:
        self._pages.append(page)
        self.emit(BrowserContext.Events.Page, page)
        if page._opener and not page._opener.is_closed():
            page._opener.emit(Page.Events.Popup, page)

    async def _on_route(self, route: Route) -> None:
        route._context = self
        page = route.request._safe_page()
        route_handlers = self._routes.copy()
        for route_handler in route_handlers:
            # If the page or the context was closed we stall all requests right away.
            if (page and page._close_was_called) or self._closing_or_closed:
                return
            if not route_handler.matches(route.request.url):
                continue
            if route_handler not in self._routes:
                continue
            if route_handler.will_expire:
                self._routes.remove(route_handler)
            try:
                handled = await route_handler.handle(route)
            finally:
                if len(self._routes) == 0:
                    asyncio.create_task(
                        self._connection.wrap_api_call(
                            lambda: self._update_interception_patterns(), True
                        )
                    )
            if handled:
                return
        try:
            # If the page is closed or unrouteAll() was called without waiting and interception disabled,
            # the method will throw an error - silence it.
            await route._inner_continue(True)
        except Exception:
            pass

    async def _on_web_socket_route(self, web_socket_route: WebSocketRoute) -> None:
        route_handler = next(
            (
                route_handler
                for route_handler in self._web_socket_routes
                if route_handler.matches(web_socket_route.url)
            ),
            None,
        )
        if route_handler:
            await route_handler.handle(web_socket_route)
        else:
            web_socket_route.connect_to_server()

    def _on_binding(self, binding_call: BindingCall) -> None:
        func = self._bindings.get(binding_call._initializer["name"])
        if func is None:
            return
        asyncio.create_task(binding_call.call(func))

    def set_default_navigation_timeout(self, timeout: float) -> None:
        return self._set_default_navigation_timeout_impl(timeout)

    def _set_default_navigation_timeout_impl(self, timeout: Optional[float]) -> None:
        self._timeout_settings.set_default_navigation_timeout(timeout)

    def set_default_timeout(self, timeout: float) -> None:
        return self._set_default_timeout_impl(timeout)

    def _set_default_timeout_impl(self, timeout: Optional[float]) -> None:
        self._timeout_settings.set_default_timeout(timeout)

    @property
    def pages(self) -> List[Page]:
        return self._pages.copy()

    @property
    def browser(self) -> Optional["Browser"]:
        return self._browser

    async def _initialize_har_from_options(
        self,
        record_har_path: Optional[Union[Path, str]],
        record_har_content: Optional[HarContentPolicy],
        record_har_omit_content: Optional[bool],
        record_har_url_filter: Optional[Union[Pattern[str], str]],
        record_har_mode: Optional[HarMode],
    ) -> None:
        if not record_har_path:
            return
        record_har_path = str(record_har_path)
        default_policy: HarContentPolicy = (
            "attach" if record_har_path.endswith(".zip") else "embed"
        )
        content_policy: HarContentPolicy = record_har_content or (
            "omit" if record_har_omit_content is True else default_policy
        )
        await self._record_into_har(
            har=record_har_path,
            page=None,
            url=record_har_url_filter,
            update_content=content_policy,
            update_mode=(record_har_mode or "full"),
        )

    async def new_page(self) -> Page:
        if self._owner_page:
            raise Error("Please use browser.new_context()")
        return from_channel(await self._channel.send("newPage", None))

    async def cookies(self, urls: Union[str, Sequence[str]] = None) -> List[Cookie]:
        if urls is None:
            urls = []
        if isinstance(urls, str):
            urls = [urls]
        return await self._channel.send("cookies", None, dict(urls=urls))

    async def add_cookies(self, cookies: Sequence[SetCookieParam]) -> None:
        await self._channel.send("addCookies", None, dict(cookies=cookies))

    async def clear_cookies(
        self,
        name: Union[str, Pattern[str]] = None,
        domain: Union[str, Pattern[str]] = None,
        path: Union[str, Pattern[str]] = None,
    ) -> None:
        await self._channel.send(
            "clearCookies",
            None,
            {
                "name": name if isinstance(name, str) else None,
                "nameRegexSource": name.pattern if isinstance(name, Pattern) else None,
                "nameRegexFlags": (
                    escape_regex_flags(name) if isinstance(name, Pattern) else None
                ),
                "domain": domain if isinstance(domain, str) else None,
                "domainRegexSource": (
                    domain.pattern if isinstance(domain, Pattern) else None
                ),
                "domainRegexFlags": (
                    escape_regex_flags(domain) if isinstance(domain, Pattern) else None
                ),
                "path": path if isinstance(path, str) else None,
                "pathRegexSource": path.pattern if isinstance(path, Pattern) else None,
                "pathRegexFlags": (
                    escape_regex_flags(path) if isinstance(path, Pattern) else None
                ),
            },
        )

    async def grant_permissions(
        self, permissions: Sequence[str], origin: str = None
    ) -> None:
        await self._channel.send("grantPermissions", None, locals_to_params(locals()))

    async def clear_permissions(self) -> None:
        await self._channel.send("clearPermissions", None)

    async def set_geolocation(self, geolocation: Geolocation = None) -> None:
        await self._channel.send("setGeolocation", None, locals_to_params(locals()))

    async def set_extra_http_headers(self, headers: Dict[str, str]) -> None:
        await self._channel.send(
            "setExtraHTTPHeaders", None, dict(headers=serialize_headers(headers))
        )

    async def set_offline(self, offline: bool) -> None:
        await self._channel.send("setOffline", None, dict(offline=offline))

    async def add_init_script(
        self, script: str = None, path: Union[str, Path] = None
    ) -> None:
        if path:
            script = (await async_readfile(path)).decode()
        if not isinstance(script, str):
            raise Error("Either path or script parameter must be specified")
        await self._channel.send("addInitScript", None, dict(source=script))

    async def expose_binding(
        self, name: str, callback: Callable, handle: bool = None
    ) -> None:
        for page in self._pages:
            if name in page._bindings:
                raise Error(
                    f'Function "{name}" has been already registered in one of the pages'
                )
        if name in self._bindings:
            raise Error(f'Function "{name}" has been already registered')
        self._bindings[name] = callback
        await self._channel.send(
            "exposeBinding", None, dict(name=name, needsHandle=handle or False)
        )

    async def expose_function(self, name: str, callback: Callable) -> None:
        await self.expose_binding(name, lambda source, *args: callback(*args))

    async def route(
        self, url: URLMatch, handler: RouteHandlerCallback, times: int = None
    ) -> None:
        self._routes.insert(
            0,
            RouteHandler(
                self._base_url,
                url,
                handler,
                True if self._dispatcher_fiber else False,
                times,
            ),
        )
        await self._update_interception_patterns()

    async def unroute(
        self, url: URLMatch, handler: Optional[RouteHandlerCallback] = None
    ) -> None:
        removed = []
        remaining = []
        for route in self._routes:
            if route.url != url or (handler and route.handler != handler):
                remaining.append(route)
            else:
                removed.append(route)
        await self._unroute_internal(removed, remaining, "default")

    async def _unroute_internal(
        self,
        removed: List[RouteHandler],
        remaining: List[RouteHandler],
        behavior: Literal["default", "ignoreErrors", "wait"] = None,
    ) -> None:
        self._routes = remaining
        if behavior is not None and behavior != "default":
            await asyncio.gather(*map(lambda router: router.stop(behavior), removed))  # type: ignore
        await self._update_interception_patterns()

    async def route_web_socket(
        self, url: URLMatch, handler: WebSocketRouteHandlerCallback
    ) -> None:
        self._web_socket_routes.insert(
            0,
            WebSocketRouteHandler(self._base_url, url, handler),
        )
        await self._update_web_socket_interception_patterns()

    def _dispose_har_routers(self) -> None:
        for router in self._har_routers:
            router.dispose()
        self._har_routers = []

    async def unroute_all(
        self, behavior: Literal["default", "ignoreErrors", "wait"] = None
    ) -> None:
        await self._unroute_internal(self._routes, [], behavior)
        self._dispose_har_routers()

    async def _record_into_har(
        self,
        har: Union[Path, str],
        page: Optional[Page] = None,
        url: Union[Pattern[str], str] = None,
        update_content: HarContentPolicy = None,
        update_mode: HarMode = None,
    ) -> None:
        update_content = update_content or "attach"
        params: Dict[str, Any] = {
            "options": {
                "zip": str(har).endswith(".zip"),
                "content": update_content,
                "urlGlob": url if isinstance(url, str) else None,
                "urlRegexSource": url.pattern if isinstance(url, Pattern) else None,
                "urlRegexFlags": (
                    escape_regex_flags(url) if isinstance(url, Pattern) else None
                ),
                "mode": update_mode or "minimal",
            }
        }
        if page:
            params["page"] = page._channel
        har_id = await self._channel.send("harStart", None, params)
        self._har_recorders[har_id] = {
            "path": str(har),
            "content": update_content,
        }

    async def route_from_har(
        self,
        har: Union[Path, str],
        url: Union[Pattern[str], str] = None,
        notFound: RouteFromHarNotFoundPolicy = None,
        update: bool = None,
        updateContent: Literal["attach", "embed"] = None,
        updateMode: HarMode = None,
    ) -> None:
        if update:
            await self._record_into_har(
                har=har,
                page=None,
                url=url,
                update_content=updateContent,
                update_mode=updateMode,
            )
            return
        router = await HarRouter.create(
            local_utils=self._connection.local_utils,
            file=str(har),
            not_found_action=notFound or "abort",
            url_matcher=url,
        )
        self._har_routers.append(router)
        await router.add_context_route(self)

    async def _update_interception_patterns(self) -> None:
        patterns = RouteHandler.prepare_interception_patterns(self._routes)
        await self._channel.send(
            "setNetworkInterceptionPatterns", None, {"patterns": patterns}
        )

    async def _update_web_socket_interception_patterns(self) -> None:
        patterns = WebSocketRouteHandler.prepare_interception_patterns(
            self._web_socket_routes
        )
        await self._channel.send(
            "setWebSocketInterceptionPatterns", None, {"patterns": patterns}
        )

    def expect_event(
        self,
        event: str,
        predicate: Callable = None,
        timeout: float = None,
    ) -> EventContextManagerImpl:
        if timeout is None:
            timeout = self._timeout_settings.timeout()
        waiter = Waiter(self, f"browser_context.expect_event({event})")
        waiter.reject_on_timeout(
            timeout, f'Timeout {timeout}ms exceeded while waiting for event "{event}"'
        )
        if event != BrowserContext.Events.Close:
            waiter.reject_on_event(
                self, BrowserContext.Events.Close, lambda: TargetClosedError()
            )
        waiter.wait_for_event(self, event, predicate)
        return EventContextManagerImpl(waiter.result())

    def _on_close(self) -> None:
        self._closing_or_closed = True
        if self._browser:
            if self in self._browser._contexts:
                self._browser._contexts.remove(self)
            assert self._browser._browser_type is not None
            if (
                self
                in self._browser._browser_type._playwright.selectors._contexts_for_selectors
            ):
                self._browser._browser_type._playwright.selectors._contexts_for_selectors.remove(
                    self
                )

        self._dispose_har_routers()
        self._tracing._reset_stack_counter()
        self.emit(BrowserContext.Events.Close, self)

    async def close(self, reason: str = None) -> None:
        if self._closing_or_closed:
            return
        self._close_reason = reason
        self._closing_or_closed = True

        await self.request.dispose(reason=reason)

        async def _inner_close() -> None:
            for har_id, params in self._har_recorders.items():
                har = cast(
                    Artifact,
                    from_channel(
                        await self._channel.send("harExport", None, {"harId": har_id})
                    ),
                )
                # Server side will compress artifact if content is attach or if file is .zip.
                is_compressed = params.get("content") == "attach" or params[
                    "path"
                ].endswith(".zip")
                need_compressed = params["path"].endswith(".zip")
                if is_compressed and not need_compressed:
                    tmp_path = params["path"] + ".tmp"
                    await har.save_as(tmp_path)
                    await self._connection.local_utils.har_unzip(
                        zipFile=tmp_path, harFile=params["path"]
                    )
                else:
                    await har.save_as(params["path"])
                await har.delete()

        await self._channel._connection.wrap_api_call(_inner_close, True)
        await self._channel.send("close", None, {"reason": reason})
        await self._closed_future

    async def storage_state(
        self, path: Union[str, Path] = None, indexedDB: bool = None
    ) -> StorageState:
        result = await self._channel.send_return_as_dict(
            "storageState", None, {"indexedDB": indexedDB}
        )
        if path:
            await async_writefile(path, json.dumps(result))
        return result

    def _effective_close_reason(self) -> Optional[str]:
        if self._close_reason:
            return self._close_reason
        if self._browser:
            return self._browser._close_reason
        return None

    async def wait_for_event(
        self, event: str, predicate: Callable = None, timeout: float = None
    ) -> Any:
        async with self.expect_event(event, predicate, timeout) as event_info:
            pass
        return await event_info

    def expect_console_message(
        self,
        predicate: Callable[[ConsoleMessage], bool] = None,
        timeout: float = None,
    ) -> EventContextManagerImpl[ConsoleMessage]:
        return self.expect_event(Page.Events.Console, predicate, timeout)

    def expect_page(
        self,
        predicate: Callable[[Page], bool] = None,
        timeout: float = None,
    ) -> EventContextManagerImpl[Page]:
        return self.expect_event(BrowserContext.Events.Page, predicate, timeout)

    def _on_service_worker(self, worker: Worker) -> None:
        worker._context = self
        self._service_workers.add(worker)
        self.emit(BrowserContext.Events.ServiceWorker, worker)

    def _on_request_failed(
        self,
        request: Request,
        response_end_timing: float,
        failure_text: Optional[str],
        page: Optional[Page],
    ) -> None:
        request._failure_text = failure_text
        request._set_response_end_timing(response_end_timing)
        self.emit(BrowserContext.Events.RequestFailed, request)
        if page:
            page.emit(Page.Events.RequestFailed, request)

    def _on_request_finished(
        self,
        request: Request,
        response: Optional[Response],
        response_end_timing: float,
        page: Optional[Page],
    ) -> None:
        request._set_response_end_timing(response_end_timing)
        self.emit(BrowserContext.Events.RequestFinished, request)
        if page:
            page.emit(Page.Events.RequestFinished, request)
        if response:
            response._finished_future.set_result(True)

    def _on_console_message(self, event: Dict) -> None:
        message = ConsoleMessage(event, self._loop, self._dispatcher_fiber)
        worker = message.worker
        if worker:
            worker.emit(Worker.Events.Console, message)
        page = message.page
        if page:
            page.emit(Page.Events.Console, message)
        self.emit(BrowserContext.Events.Console, message)

    def _on_dialog(self, dialog: Dialog) -> None:
        has_listeners = self.emit(BrowserContext.Events.Dialog, dialog)
        page = dialog.page
        if page:
            has_listeners = page.emit(Page.Events.Dialog, dialog) or has_listeners
        if not has_listeners:
            # Although we do similar handling on the server side, we still need this logic
            # on the client side due to a possible race condition between two async calls:
            # a) removing "dialog" listener subscription (client->server)
            # b) actual "dialog" event (server->client)
            if dialog.type == "beforeunload":
                asyncio.create_task(dialog.accept())
            else:
                asyncio.create_task(dialog.dismiss())

    def _on_page_error(self, error: Error, page: Optional[Page]) -> None:
        self.emit(
            BrowserContext.Events.WebError,
            WebError(self._loop, self._dispatcher_fiber, page, error),
        )
        if page:
            page.emit(Page.Events.PageError, error)

    def _on_request(self, request: Request, page: Optional[Page]) -> None:
        self.emit(BrowserContext.Events.Request, request)
        if page:
            page.emit(Page.Events.Request, request)

    def _on_response(self, response: Response, page: Optional[Page]) -> None:
        self.emit(BrowserContext.Events.Response, response)
        if page:
            page.emit(Page.Events.Response, response)

    @property
    def background_pages(self) -> List[Page]:
        return []

    @property
    def service_workers(self) -> List[Worker]:
        return list(self._service_workers)

    async def new_cdp_session(self, page: Union[Page, Frame]) -> CDPSession:
        page = to_impl(page)
        params = {}
        if isinstance(page, Page):
            params["page"] = page._channel
        elif isinstance(page, Frame):
            params["frame"] = page._channel
        else:
            raise Error("page: expected Page or Frame")
        return from_channel(await self._channel.send("newCDPSession", None, params))

    @property
    def tracing(self) -> Tracing:
        return self._tracing

    @property
    def request(self) -> "APIRequestContext":
        return self._request

    @property
    def clock(self) -> Clock:
        return self._clock


================================================
FILE: playwright/_impl/_browser_type.py
================================================
# 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 asyncio
import json
import pathlib
import sys
from pathlib import Path
from typing import TYPE_CHECKING, Dict, List, Optional, Pattern, Sequence, Union, cast

from playwright._impl._api_structures import (
    ClientCertificate,
    Geolocation,
    HttpCredentials,
    ProxySettings,
    ViewportSize,
)
from playwright._impl._browser import Browser
from playwright._impl._browser_context import BrowserContext
from playwright._impl._connection import ChannelOwner, Connection, from_channel
from playwright._impl._errors import Error
from playwright._impl._helper import (
    PLAYWRIGHT_MAX_DEADLINE,
    ColorScheme,
    Contrast,
    Env,
    ForcedColors,
    HarContentPolicy,
    HarMode,
    ReducedMotion,
    ServiceWorkersPolicy,
    TimeoutSettings,
    async_readfile,
    locals_to_params,
)
from playwright._impl._json_pipe import JsonPipeTransport
from playwright._impl._network import serialize_headers, to_client_certificates_protocol
from playwright._impl._waiter import throw_on_timeout

if TYPE_CHECKING:
    from playwright._impl._playwright import Playwright


class BrowserType(ChannelOwner):
    def __init__(
        self, parent: ChannelOwner, type: str, guid: str, initializer: Dict
    ) -> None:
        super().__init__(parent, type, guid, initializer)
        self._playwright: "Playwright"

    def __repr__(self) -> str:
        return f"<BrowserType name={self.name} executable_path={self.executable_path}>"

    @property
    def name(self) -> str:
        return self._initializer["name"]

    @property
    def executable_path(self) -> str:
        return self._initializer["executablePath"]

    async def launch(
        self,
        executablePath: Union[str, Path] = None,
        channel: str = None,
        args: Sequence[str] = None,
        ignoreDefaultArgs: Union[bool, Sequence[str]] = None,
        handleSIGINT: bool = None,
        handleSIGTERM: bool = None,
        handleSIGHUP: bool = None,
        timeout: float = None,
        env: Env = None,
        headless: bool = None,
        proxy: ProxySettings = None,
        downloadsPath: Union[str, Path] = None,
        slowMo: float = None,
        tracesDir: Union[pathlib.Path, str] = None,
        chromiumSandbox: bool = None,
        firefoxUserPrefs: Dict[str, Union[str, float, bool]] = None,
    ) -> Browser:
        params = locals_to_params(locals())
        normalize_launch_params(params)
        browser = cast(
            Browser,
            from_channel(
                await self._channel.send(
                    "launch", TimeoutSettings.launch_timeout, params
                )
            ),
        )
        browser._connect_to_browser_type(
            self, str(tracesDir) if tracesDir is not None else None
        )
        return browser

    async def launch_persistent_context(
        self,
        userDataDir: Union[str, Path],
        channel: str = None,
        executablePath: Union[str, Path] = None,
        args: Sequence[str] = None,
        ignoreDefaultArgs: Union[bool, Sequence[str]] = None,
        handleSIGINT: bool = None,
        handleSIGTERM: bool = None,
        handleSIGHUP: bool = None,
        timeout: float = None,
        env: Env = None,
        headless: bool = None,
        proxy: ProxySettings = None,
        downloadsPath: Union[str, Path] = None,
        slowMo: float = None,
        viewport: ViewportSize = None,
        screen: ViewportSize = None,
        noViewport: bool = None,
        ignoreHTTPSErrors: bool = None,
        javaScriptEnabled: bool = None,
        bypassCSP: bool = None,
        userAgent: str = None,
        locale: str = None,
        timezoneId: str = None,
        geolocation: Geolocation = None,
        permissions: Sequence[str] = None,
        extraHTTPHeaders: Dict[str, str] = None,
        offline: bool = None,
        httpCredentials: HttpCredentials = None,
        deviceScaleFactor: float = None,
        isMobile: bool = None,
        hasTouch: bool = None,
        colorScheme: ColorScheme = None,
        reducedMotion: ReducedMotion = None,
        forcedColors: ForcedColors = None,
        contrast: Contrast = None,
        acceptDownloads: bool = None,
        tracesDir: Union[pathlib.Path, str] = None,
        chromiumSandbox: bool = None,
        firefoxUserPrefs: Dict[str, Union[str, float, bool]] = None,
        recordHarPath: Union[Path, str] = None,
        recordHarOmitContent: bool = None,
        recordVideoDir: Union[Path, str] = None,
        recordVideoSize: ViewportSize = None,
        baseURL: str = None,
        strictSelectors: bool = None,
        serviceWorkers: ServiceWorkersPolicy = None,
        recordHarUrlFilter: Union[Pattern[str], str] = None,
        recordHarMode: HarMode = None,
        recordHarContent: HarContentPolicy = None,
        clientCertificates: List[ClientCertificate] = None,
    ) -> BrowserContext:
        userDataDir = self._user_data_dir(userDataDir)
        params = locals_to_params(locals())
        await self._prepare_browser_context_params(params)
        normalize_launch_params(params)
        result = await self._channel.send_return_as_dict(
            "launchPersistentContext", TimeoutSettings.launch_timeout, params
        )
        browser = cast(
            Browser,
            from_channel(result["browser"]),
        )
        browser._connect_to_browser_type(
            self, str(tracesDir) if tracesDir is not None else None
        )
        context = cast(BrowserContext, from_channel(result["context"]))
        await context._initialize_har_from_options(
            record_har_content=recordHarContent,
            record_har_mode=recordHarMode,
            record_har_omit_content=recordHarOmitContent,
            record_har_path=recordHarPath,
            record_har_url_filter=recordHarUrlFilter,
        )
        return context

    def _user_data_dir(self, userDataDir: Optional[Union[str, Path]]) -> str:
        if not userDataDir:
            return ""
        if not Path(userDataDir).is_absolute():
            # Can be dropped once we drop Python 3.9 support (10/2025):
            # https://github.com/python/cpython/issues/82852
            if sys.platform == "win32" and sys.version_info[:2] < (3, 10):
                return str(pathlib.Path.cwd() / userDataDir)
            return str(Path(userDataDir).resolve())
        return str(Path(userDataDir))

    async def connect_over_cdp(
        self,
        endpointURL: str,
        timeout: float = None,
        slowMo: float = None,
        headers: Dict[str, str] = None,
        isLocal: bool = None,
    ) -> Browser:
        params = locals_to_params(locals())
        if params.get("headers"):
            params["headers"] = serialize_headers(params["headers"])
        response = await self._channel.send_return_as_dict(
            "connectOverCDP", TimeoutSettings.launch_timeout, params
        )
        browser = cast(Browser, from_channel(response["browser"]))
        browser._connect_to_browser_type(self, None)

        return browser

    async def connect(
        self,
        wsEndpoint: str,
        timeout: float = None,
        slowMo: float = None,
        headers: Dict[str, str] = None,
        exposeNetwork: str = None,
    ) -> Browser:
        if slowMo is None:
            slowMo = 0

        headers = {**(headers if headers else {}), "x-playwright-browser": self.name}
        local_utils = self._connection.local_utils
        pipe_channel = (
            await local_utils._channel.send_return_as_dict(
                "connect",
                None,
                {
                    "wsEndpoint": wsEndpoint,
                    "headers": headers,
                    "slowMo": slowMo,
                    "timeout": timeout if timeout is not None else 0,
                    "exposeNetwork": exposeNetwork,
                },
            )
        )["pipe"]
        transport = JsonPipeTransport(self._connection._loop, pipe_channel)

        connection = Connection(
            self._connection._dispatcher_fiber,
            self._connection._object_factory,
            transport,
            self._connection._loop,
            local_utils=self._connection.local_utils,
        )
        connection.mark_as_remote()

        browser = None

        def handle_transport_close(reason: Optional[str]) -> None:
            if browser:
                for context in browser.contexts:
                    for page in context.pages:
                        page._on_close()
                    context._on_close()
                browser._on_close()
            connection.cleanup(reason)
            # TODO: Backport https://github.com/microsoft/playwright/commit/d8d5289e8692c9b1265d23ee66988d1ac5122f33
            # Give a chance to any API call promises to reject upon page/context closure.
            # This happens naturally when we receive page.onClose and browser.onClose from the server
            # in separate tasks. However, upon pipe closure we used to dispatch them all synchronously
            # here and promises did not have a chance to reject.
            # The order of rejects vs closure is a part of the API contract and our test runner
            # relies on it to attribute rejections to the right test.

        transport.once("close", handle_transport_close)

        connection._is_sync = self._connection._is_sync
        connection._loop.create_task(connection.run())
        playwright_future = connection.playwright_future

        timeout_future = throw_on_timeout(
            timeout if timeout is not None else PLAYWRIGHT_MAX_DEADLINE,
            Error("Connection timed out"),
        )
        done, pending = await asyncio.wait(
            {transport.on_error_future, playwright_future, timeout_future},
            return_when=asyncio.FIRST_COMPLETED,
        )
        if not playwright_future.done():
            playwright_future.cancel()
        if not timeout_future.done():
            timeout_future.cancel()
        playwright: "Playwright" = next(iter(done)).result()
        playwright._set_selectors(self._playwright.selectors)
        self._connection._child_ws_connections.append(connection)
        pre_launched_browser = playwright._initializer.get("preLaunchedBrowser")
        assert pre_launched_browser
        browser = cast(Browser, from_channel(pre_launched_browser))
        browser._should_close_connection_on_close = True
        browser._connect_to_browser_type(self, None)

        return browser

    async def _prepare_browser_context_params(self, params: Dict) -> None:
        if params.get("noViewport"):
            del params["noViewport"]
            params["noDefaultViewport"] = True
        if "defaultBrowserType" in params:
            del params["defaultBrowserType"]
        if "extraHTTPHeaders" in params:
            params["extraHTTPHeaders"] = serialize_headers(params["extraHTTPHeaders"])
        if "recordVideoDir" in params:
            params["recordVideo"] = {"dir": Path(params["recordVideoDir"]).absolute()}
            if "recordVideoSize" in params:
                params["recordVideo"]["size"] = params["recordVideoSize"]
                del params["recordVideoSize"]
            del params["recordVideoDir"]
        if "storageState" in params:
            storageState = params["storageState"]
            if not isinstance(storageState, dict):
                params["storageState"] = json.loads(
                    (await async_readfile(storageState)).decode()
                )
        if params.get("colorScheme", None) == "null":
            params["colorScheme"] = "no-override"
        if params.get("reducedMotion", None) == "null":
            params["reducedMotion"] = "no-override"
        if params.get("forcedColors", None) == "null":
            params["forcedColors"] = "no-override"
        if params.get("contrast", None) == "null":
            params["contrast"] = "no-override"
        if "acceptDownloads" in params:
            params["acceptDownloads"] = (
                "accept" if params["acceptDownloads"] else "deny"
            )

        if "clientCertificates" in params:
            params["clientCertificates"] = await to_client_certificates_protocol(
                params["clientCertificates"]
            )
        params["selectorEngines"] = self._playwright.selectors._selector_engines
        params["testIdAttributeName"] = (
            self._playwright.selectors._test_id_attribute_name
        )

        # Remove HAR options
        params.pop("recordHarPath", None)
        params.pop("recordHarOmitContent", None)
        params.pop("recordHarUrlFilter", None)
        params.pop("recordHarMode", None)
        params.pop("recordHarContent", None)


def normalize_launch_params(params: Dict) -> None:
    if "env" in params:
        params["env"] = [
            {"name": name, "value": str(value)}
            for [name, value] in params["env"].items()
        ]
    if "ignoreDefaultArgs" in params:
        if params["ignoreDefaultArgs"] is True:
            params["ignoreAllDefaultArgs"] = True
            del params["ignoreDefaultArgs"]
    if "executablePath" in params:
        params["executablePath"] = str(Path(params["executablePath"]))
    if "downloadsPath" in params:
        params["downloadsPath"] = str(Path(params["downloadsPath"]))
    if "tracesDir" in params:
        params["tracesDir"] = str(Path(params["tracesDir"]))


================================================
FILE: playwright/_impl/_cdp_session.py
================================================
# 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.

from typing import Any, Dict

from playwright._impl._connection import ChannelOwner
from playwright._impl._helper import locals_to_params


class CDPSession(ChannelOwner):
    def __init__(
        self, parent: ChannelOwner, type: str, guid: str, initializer: Dict
    ) -> None:
        super().__init__(parent, type, guid, initializer)
        self._channel.on("event", lambda params: self._on_event(params))

    def _on_event(self, params: Any) -> None:
        self.emit(params["method"], params.get("params"))

    async def send(self, method: str, params: Dict = None) -> Dict:
        return await self._channel.send("send", None, locals_to_params(locals()))

    async def detach(self) -> None:
        await self._channel.send(
            "detach",
            None,
        )


================================================
FILE: playwright/_impl/_clock.py
================================================
# 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 datetime
from typing import TYPE_CHECKING, Dict, Union

if TYPE_CHECKING:
    from playwright._impl._browser_context import BrowserContext


class Clock:
    def __init__(self, browser_context: "BrowserContext") -> None:
        self._browser_context = browser_context
        self._loop = browser_context._loop
        self._dispatcher_fiber = browser_context._dispatcher_fiber

    async def install(self, time: Union[float, str, datetime.datetime] = None) -> None:
        await self._browser_context._channel.send(
            "clockInstall",
            None,
            parse_time(time) if time is not None else {},
        )

    async def fast_forward(
        self,
        ticks: Union[int, str],
    ) -> None:
        await self._browser_context._channel.send(
            "clockFastForward",
            None,
            parse_ticks(ticks),
        )

    async def pause_at(
        self,
        time: Union[float, str, datetime.datetime],
    ) -> None:
        await self._browser_context._channel.send(
            "clockPauseAt",
            None,
            parse_time(time),
        )

    async def resume(
        self,
    ) -> None:
        await self._browser_context._channel.send("clockResume", None)

    async def run_for(
        self,
        ticks: Union[int, str],
    ) -> None:
        await self._browser_context._channel.send(
            "clockRunFor",
            None,
            parse_ticks(ticks),
        )

    async def set_fixed_time(
        self,
        time: Union[float, str, datetime.datetime],
    ) -> None:
        await self._browser_context._channel.send(
            "clockSetFixedTime",
            None,
            parse_time(time),
        )

    async def set_system_time(
        self,
        time: Union[float, str, datetime.datetime],
    ) -> None:
        await self._browser_context._channel.send(
            "clockSetSystemTime",
            None,
            parse_time(time),
        )


def parse_time(
    time: Union[float, str, datetime.datetime],
) -> Dict[str, Union[int, str]]:
    if isinstance(time, (float, int)):
        return {"timeNumber": int(time * 1_000)}
    if isinstance(time, str):
        return {"timeString": time}
    return {"timeNumber": int(time.timestamp() * 1_000)}


def parse_ticks(ticks: Union[int, str]) -> Dict[str, Union[int, str]]:
    if isinstance(ticks, int):
        return {"ticksNumber": ticks}
    return {"ticksString": ticks}


================================================
FILE: playwright/_impl/_connection.py
================================================
# 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 asyncio
import collections.abc
import contextvars
import datetime
import inspect
import sys
import traceback
from pathlib import Path
from typing import (
    TYPE_CHECKING,
    Any,
    Callable,
    Dict,
    List,
    Mapping,
    Optional,
    TypedDict,
    Union,
    cast,
)

from pyee import EventEmitter
from pyee.asyncio import AsyncIOEventEmitter

import playwright
import playwright._impl._impl_to_api_mapping
from playwright._impl._errors import TargetClosedError, rewrite_error
from playwright._impl._greenlets import EventGreenlet
from playwright._impl._helper import Error, ParsedMessagePayload, parse_error
from playwright._impl._transport import Transport

if TYPE_CHECKING:
    from playwright._impl._local_utils import LocalUtils
    from playwright._impl._playwright import Playwright

TimeoutCalculator = Optional[Callable[[Optional[float]], float]]


class Channel(AsyncIOEventEmitter):
    def __init__(self, connection: "Connection", object: "ChannelOwner") -> None:
        super().__init__()
        self._connection = connection
        self._guid = object._guid
        self._object = object
        self.on("error", lambda exc: self._connection._on_event_listener_error(exc))

    async def send(
        self,
        method: str,
        timeout_calculator: TimeoutCalculator,
        params: Dict = None,
        is_internal: bool = False,
        title: str = None,
    ) -> Any:
        return await self._connection.wrap_api_call(
            lambda: self._inner_send(method, timeout_calculator, params, False),
            is_internal,
            title,
        )

    async def send_return_as_dict(
        self,
        method: str,
        timeout_calculator: TimeoutCalculator,
        params: Dict = None,
        is_internal: bool = False,
        title: str = None,
    ) -> Any:
        return await self._connection.wrap_api_call(
            lambda: self._inner_send(method, timeout_calculator, params, True),
            is_internal,
            title,
        )

    def send_no_reply(
        self,
        method: str,
        timeout_calculator: TimeoutCalculator,
        params: Dict = None,
        is_internal: bool = False,
        title: str = None,
    ) -> None:
        # No reply messages are used to e.g. waitForEventInfo(after).
        self._connection.wrap_api_call_sync(
            lambda: self._connection._send_message_to_server(
                self._object,
                method,
                _augment_params(params, timeout_calculator),
                True,
            ),
            is_internal,
            title,
        )

    async def _inner_send(
        self,
        method: str,
        timeout_calculator: TimeoutCalculator,
        params: Optional[Dict],
        return_as_dict: bool,
    ) -> Any:
        if self._connection._error:
            error = self._connection._error
            self._connection._error = None
            raise error
        callback = self._connection._send_message_to_server(
            self._object, method, _augment_params(params, timeout_calculator)
        )
        done, _ = await asyncio.wait(
            {
                self._connection._transport.on_error_future,
                callback.future,
            },
            return_when=asyncio.FIRST_COMPLETED,
        )
        if not callback.future.done():
            callback.future.cancel()
        result = next(iter(done)).result()
        # Protocol now has named return values, assume result is one level deeper unless
        # there is explicit ambiguity.
        if not result:
            return None
        assert isinstance(result, dict)
        if return_as_dict:
            return result
        if len(result) == 0:
            return None
        assert len(result) == 1
        key = next(iter(result))
        return result[key]


class ChannelOwner(AsyncIOEventEmitter):
    def __init__(
        self,
        parent: Union["ChannelOwner", "Connection"],
        type: str,
        guid: str,
        initializer: Dict,
    ) -> None:
        super().__init__(loop=parent._loop)
        self._loop: asyncio.AbstractEventLoop = parent._loop
        self._dispatcher_fiber: Any = parent._dispatcher_fiber
        self._type = type
        self._guid: str = guid
        self._connection: Connection = (
            parent._connection if isinstance(parent, ChannelOwner) else parent
        )
        self._parent: Optional[ChannelOwner] = (
            parent if isinstance(parent, ChannelOwner) else None
        )
        self._objects: Dict[str, "ChannelOwner"] = {}
        self._channel: Channel = Channel(self._connection, self)
        self._initializer = initializer
        self._was_collected = False

        self._connection._objects[guid] = self
        if self._parent:
            self._parent._objects[guid] = self

        self._event_to_subscription_mapping: Dict[str, str] = {}

    def _dispose(self, reason: Optional[str]) -> None:
        # Clean up from parent and connection.
        if self._parent:
            del self._parent._objects[self._guid]
        del self._connection._objects[self._guid]
        self._was_collected = reason == "gc"

        # Dispose all children.
        for object in list(self._objects.values()):
            object._dispose(reason)
        self._objects.clear()

    def _adopt(self, child: "ChannelOwner") -> None:
        del cast("ChannelOwner", child._parent)._objects[child._guid]
        self._objects[child._guid] = child
        child._parent = self

    def _set_event_to_subscription_mapping(self, mapping: Dict[str, str]) -> None:
        self._event_to_subscription_mapping = mapping

    def _update_subscription(self, event: str, enabled: bool) -> None:
        protocol_event = self._event_to_subscription_mapping.get(event)
        if protocol_event:
            self._connection.wrap_api_call_sync(
                lambda: self._channel.send_no_reply(
                    "updateSubscription",
                    None,
                    {"event": protocol_event, "enabled": enabled},
                ),
                True,
            )

    def _add_event_handler(self, event: str, k: Any, v: Any) -> None:
        if not self.listeners(event):
            self._update_subscription(event, True)
        super()._add_event_handler(event, k, v)

    def remove_listener(self, event: str, f: Any) -> None:
        super().remove_listener(event, f)
        if not self.listeners(event):
            self._update_subscription(event, False)


class ProtocolCallback:
    def __init__(self, loop: asyncio.AbstractEventLoop, no_reply: bool = False) -> None:
        self.stack_trace: traceback.StackSummary
        self.no_reply = no_reply
        self.future = loop.create_future()
        if no_reply:
            self.future.set_result(None)
        # The outer task can get cancelled by the user, this forwards the cancellation to the inner task.
        current_task = asyncio.current_task()

        def cb(task: asyncio.Task) -> None:
            if current_task:
                current_task.remove_done_callback(cb)
            if task.cancelled():
                self.future.cancel()

        if current_task:
            current_task.add_done_callback(cb)
            self.future.add_done_callback(
                lambda _: (
                    current_task.remove_done_callback(cb) if current_task else None
                )
            )


class RootChannelOwner(ChannelOwner):
    def __init__(self, connection: "Connection") -> None:
        super().__init__(connection, "Root", "", {})

    async def initialize(self) -> "Playwright":
        return from_channel(
            await self._channel.send(
                "initialize",
                None,
                {
                    "sdkLanguage": "python",
                },
            )
        )


class Connection(EventEmitter):
    def __init__(
        self,
        dispatcher_fiber: Any,
        object_factory: Callable[[ChannelOwner, str, str, Dict], ChannelOwner],
        transport: Transport,
        loop: asyncio.AbstractEventLoop,
        local_utils: Optional["LocalUtils"] = None,
    ) -> None:
        super().__init__()
        self._dispatcher_fiber = dispatcher_fiber
        self._transport = transport
        self._transport.on_message = lambda msg: self.dispatch(msg)
        self._waiting_for_object: Dict[str, Callable[[ChannelOwner], None]] = {}
        self._last_id = 0
        self._objects: Dict[str, ChannelOwner] = {}
        self._callbacks: Dict[int, ProtocolCallback] = {}
        self._object_factory = object_factory
        self._is_sync = False
        self._child_ws_connections: List["Connection"] = []
        self._loop = loop
        self.playwright_future: asyncio.Future["Playwright"] = loop.create_future()
        self._error: Optional[BaseException] = None
        self.is_remote = False
        self._init_task: Optional[asyncio.Task] = None
        self._api_zone: contextvars.ContextVar[Optional[ParsedStackTrace]] = (
            contextvars.ContextVar("ApiZone", default=None)
        )
        self._local_utils: Optional["LocalUtils"] = local_utils
        self._tracing_count = 0
        self._closed_error: Optional[Exception] = None

    @property
    def local_utils(self) -> "LocalUtils":
        assert self._local_utils
        return self._local_utils

    def mark_as_remote(self) -> None:
        self.is_remote = True

    async def run_as_sync(self) -> None:
        self._is_sync = True
        await self.run()

    async def run(self) -> None:
        self._loop = asyncio.get_running_loop()
        self._root_object = RootChannelOwner(self)

        async def init() -> None:
            self.playwright_future.set_result(await self._root_object.initialize())

        await self._transport.connect()
        self._init_task = self._loop.create_task(init())
        await self._transport.run()

    def stop_sync(self) -> None:
        self._transport.request_stop()
        self._dispatcher_fiber.switch()
        self._loop.run_until_complete(self._transport.wait_until_stopped())
        self.cleanup()

    async def stop_async(self) -> None:
        self._transport.request_stop()
        await self._transport.wait_until_stopped()
        self.cleanup()

    def cleanup(self, cause: str = None) -> None:
        self._closed_error = TargetClosedError(cause) if cause else TargetClosedError()
        if self._init_task and not self._init_task.done():
            self._init_task.cancel()
        for ws_connection in self._child_ws_connections:
            ws_connection._transport.dispose()
        for callback in self._cal
Download .txt
gitextract_t_9ditla/

├── .azure-pipelines/
│   ├── guardian/
│   │   └── SDL/
│   │       └── .gdnsuppress
│   └── publish.yml
├── .claude/
│   └── skills/
│       └── playwright-roll/
│           └── SKILL.md
├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug.yml
│   │   ├── config.yml
│   │   ├── documentation.yml
│   │   ├── feature.yml
│   │   ├── question.yml
│   │   └── regression.yml
│   ├── dependabot.yml
│   └── workflows/
│       ├── ci.yml
│       ├── publish.yml
│       ├── publish_docker.yml
│       └── test_docker.yml
├── .gitignore
├── .pre-commit-config.yaml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── ROLLING.md
├── SECURITY.md
├── SUPPORT.md
├── conda_build_config_linux_aarch64.yaml
├── conda_build_config_osx_arm64.yaml
├── examples/
│   └── todomvc/
│       ├── mvctests/
│       │   ├── __init__.py
│       │   ├── test_clear_completed_button.py
│       │   ├── test_counter.py
│       │   ├── test_editing.py
│       │   ├── test_item.py
│       │   ├── test_mark_all_as_completed.py
│       │   ├── test_new_todo.py
│       │   ├── test_persistence.py
│       │   ├── test_routing.py
│       │   └── utils.py
│       └── requirements.txt
├── local-requirements.txt
├── meta.yaml
├── playwright/
│   ├── __init__.py
│   ├── __main__.py
│   ├── _impl/
│   │   ├── __init__.py
│   │   ├── __pyinstaller/
│   │   │   ├── __init__.py
│   │   │   ├── hook-playwright.async_api.py
│   │   │   └── hook-playwright.sync_api.py
│   │   ├── _api_structures.py
│   │   ├── _artifact.py
│   │   ├── _assertions.py
│   │   ├── _async_base.py
│   │   ├── _browser.py
│   │   ├── _browser_context.py
│   │   ├── _browser_type.py
│   │   ├── _cdp_session.py
│   │   ├── _clock.py
│   │   ├── _connection.py
│   │   ├── _console_message.py
│   │   ├── _dialog.py
│   │   ├── _download.py
│   │   ├── _driver.py
│   │   ├── _element_handle.py
│   │   ├── _errors.py
│   │   ├── _event_context_manager.py
│   │   ├── _fetch.py
│   │   ├── _file_chooser.py
│   │   ├── _frame.py
│   │   ├── _glob.py
│   │   ├── _greenlets.py
│   │   ├── _har_router.py
│   │   ├── _helper.py
│   │   ├── _impl_to_api_mapping.py
│   │   ├── _input.py
│   │   ├── _js_handle.py
│   │   ├── _json_pipe.py
│   │   ├── _local_utils.py
│   │   ├── _locator.py
│   │   ├── _map.py
│   │   ├── _network.py
│   │   ├── _object_factory.py
│   │   ├── _page.py
│   │   ├── _path_utils.py
│   │   ├── _playwright.py
│   │   ├── _selectors.py
│   │   ├── _set_input_files_helpers.py
│   │   ├── _str_utils.py
│   │   ├── _stream.py
│   │   ├── _sync_base.py
│   │   ├── _tracing.py
│   │   ├── _transport.py
│   │   ├── _video.py
│   │   ├── _waiter.py
│   │   ├── _web_error.py
│   │   └── _writable_stream.py
│   ├── async_api/
│   │   ├── __init__.py
│   │   ├── _context_manager.py
│   │   └── _generated.py
│   ├── py.typed
│   └── sync_api/
│       ├── __init__.py
│       ├── _context_manager.py
│       └── _generated.py
├── pyproject.toml
├── requirements.txt
├── scripts/
│   ├── documentation_provider.py
│   ├── example_async.py
│   ├── example_sync.py
│   ├── expected_api_mismatch.txt
│   ├── generate_api.py
│   ├── generate_async_api.py
│   ├── generate_sync_api.py
│   ├── update_api.sh
│   └── update_versions.py
├── setup.cfg
├── setup.py
├── tests/
│   ├── __init__.py
│   ├── assets/
│   │   ├── beforeunload.html
│   │   ├── client-certificates/
│   │   │   ├── README.md
│   │   │   ├── client/
│   │   │   │   ├── localhost/
│   │   │   │   │   ├── localhost.csr
│   │   │   │   │   ├── localhost.ext
│   │   │   │   │   ├── localhost.key
│   │   │   │   │   └── localhost.pem
│   │   │   │   ├── self-signed/
│   │   │   │   │   ├── cert.pem
│   │   │   │   │   ├── csr.pem
│   │   │   │   │   └── key.pem
│   │   │   │   └── trusted/
│   │   │   │       ├── cert-legacy.pfx
│   │   │   │       ├── cert.pem
│   │   │   │       ├── cert.pfx
│   │   │   │       ├── csr.pem
│   │   │   │       └── key.pem
│   │   │   ├── generate.sh
│   │   │   └── server/
│   │   │       ├── server_cert.pem
│   │   │       └── server_key.pem
│   │   ├── client.py
│   │   ├── consolelog.html
│   │   ├── csp.html
│   │   ├── dom.html
│   │   ├── download-blob.html
│   │   ├── drag-n-drop.html
│   │   ├── dummy_bad_browser_executable.js
│   │   ├── empty.html
│   │   ├── error.html
│   │   ├── es6/
│   │   │   ├── .eslintrc
│   │   │   ├── es6import.js
│   │   │   ├── es6module.js
│   │   │   └── es6pathimport.js
│   │   ├── extension-mv3-simple/
│   │   │   ├── content-script.js
│   │   │   ├── index.js
│   │   │   └── manifest.json
│   │   ├── extension-mv3-with-logging/
│   │   │   ├── background.js
│   │   │   ├── content.js
│   │   │   └── manifest.json
│   │   ├── file-to-upload-2.txt
│   │   ├── file-to-upload.txt
│   │   ├── frames/
│   │   │   ├── child-redirect.html
│   │   │   ├── frame.html
│   │   │   ├── frameset.html
│   │   │   ├── nested-frames.html
│   │   │   ├── one-frame.html
│   │   │   ├── redirect-my-parent.html
│   │   │   ├── script.js
│   │   │   ├── style.css
│   │   │   └── two-frames.html
│   │   ├── geolocation.html
│   │   ├── global-var.html
│   │   ├── grid.html
│   │   ├── har-fulfill.har
│   │   ├── har-redirect.har
│   │   ├── har-sha1-main-response.txt
│   │   ├── har-sha1.har
│   │   ├── har.html
│   │   ├── headings.html
│   │   ├── historyapi.html
│   │   ├── injectedfile.js
│   │   ├── injectedstyle.css
│   │   ├── input/
│   │   │   ├── animating-button.html
│   │   │   ├── button.html
│   │   │   ├── checkbox.html
│   │   │   ├── fileupload-multi.html
│   │   │   ├── fileupload.html
│   │   │   ├── folderupload.html
│   │   │   ├── handle-locator.html
│   │   │   ├── keyboard.html
│   │   │   ├── mouse-helper.js
│   │   │   ├── rotatedButton.html
│   │   │   ├── scrollable.html
│   │   │   ├── select.html
│   │   │   ├── textarea.html
│   │   │   └── touches.html
│   │   ├── mobile.html
│   │   ├── networkidle.html
│   │   ├── networkidle.js
│   │   ├── offscreenbuttons.html
│   │   ├── one-style.css
│   │   ├── one-style.html
│   │   ├── playground.html
│   │   ├── popup/
│   │   │   ├── popup.html
│   │   │   └── window-open.html
│   │   ├── react.html
│   │   ├── sectionselectorengine.js
│   │   ├── self-request.html
│   │   ├── serviceworkers/
│   │   │   ├── empty/
│   │   │   │   ├── sw.html
│   │   │   │   └── sw.js
│   │   │   ├── fetch/
│   │   │   │   ├── style.css
│   │   │   │   ├── sw.html
│   │   │   │   └── sw.js
│   │   │   └── fetchdummy/
│   │   │       ├── sw.html
│   │   │       └── sw.js
│   │   ├── shadow.html
│   │   ├── simple.json
│   │   ├── title.html
│   │   ├── worker/
│   │   │   ├── worker.html
│   │   │   └── worker.js
│   │   └── wrappedlink.html
│   ├── async/
│   │   ├── __init__.py
│   │   ├── conftest.py
│   │   ├── test_add_init_script.py
│   │   ├── test_assertions.py
│   │   ├── test_asyncio.py
│   │   ├── test_browser.py
│   │   ├── test_browsercontext.py
│   │   ├── test_browsercontext_add_cookies.py
│   │   ├── test_browsercontext_clearcookies.py
│   │   ├── test_browsercontext_client_certificates.py
│   │   ├── test_browsercontext_cookies.py
│   │   ├── test_browsercontext_events.py
│   │   ├── test_browsercontext_proxy.py
│   │   ├── test_browsercontext_request_fallback.py
│   │   ├── test_browsercontext_request_intercept.py
│   │   ├── test_browsercontext_route.py
│   │   ├── test_browsercontext_service_worker_policy.py
│   │   ├── test_browsercontext_storage_state.py
│   │   ├── test_browsertype_connect.py
│   │   ├── test_browsertype_connect_cdp.py
│   │   ├── test_cdp_session.py
│   │   ├── test_check.py
│   │   ├── test_chromium_tracing.py
│   │   ├── test_click.py
│   │   ├── test_console.py
│   │   ├── test_context_manager.py
│   │   ├── test_defaultbrowsercontext.py
│   │   ├── test_device_descriptors.py
│   │   ├── test_dialog.py
│   │   ├── test_dispatch_event.py
│   │   ├── test_download.py
│   │   ├── test_element_handle.py
│   │   ├── test_element_handle_wait_for_element_state.py
│   │   ├── test_emulation_focus.py
│   │   ├── test_expect_misc.py
│   │   ├── test_extension.py
│   │   ├── test_fetch_browser_context.py
│   │   ├── test_fetch_global.py
│   │   ├── test_fill.py
│   │   ├── test_focus.py
│   │   ├── test_frames.py
│   │   ├── test_geolocation.py
│   │   ├── test_har.py
│   │   ├── test_headful.py
│   │   ├── test_ignore_https_errors.py
│   │   ├── test_input.py
│   │   ├── test_issues.py
│   │   ├── test_jshandle.py
│   │   ├── test_keyboard.py
│   │   ├── test_launcher.py
│   │   ├── test_listeners.py
│   │   ├── test_locators.py
│   │   ├── test_navigation.py
│   │   ├── test_network.py
│   │   ├── test_page.py
│   │   ├── test_page_add_locator_handler.py
│   │   ├── test_page_aria_snapshot.py
│   │   ├── test_page_base_url.py
│   │   ├── test_page_clock.py
│   │   ├── test_page_evaluate.py
│   │   ├── test_page_event_console.py
│   │   ├── test_page_event_pageerror.py
│   │   ├── test_page_event_request.py
│   │   ├── test_page_network_request.py
│   │   ├── test_page_network_response.py
│   │   ├── test_page_request_fallback.py
│   │   ├── test_page_request_gc.py
│   │   ├── test_page_request_intercept.py
│   │   ├── test_page_route.py
│   │   ├── test_page_select_option.py
│   │   ├── test_pdf.py
│   │   ├── test_popup.py
│   │   ├── test_proxy.py
│   │   ├── test_queryselector.py
│   │   ├── test_request_continue.py
│   │   ├── test_request_fulfill.py
│   │   ├── test_request_intercept.py
│   │   ├── test_resource_timing.py
│   │   ├── test_route_web_socket.py
│   │   ├── test_screenshot.py
│   │   ├── test_selector_generator.py
│   │   ├── test_selectors_get_by.py
│   │   ├── test_selectors_misc.py
│   │   ├── test_selectors_text.py
│   │   ├── test_tap.py
│   │   ├── test_tracing.py
│   │   ├── test_unroute_behavior.py
│   │   ├── test_video.py
│   │   ├── test_wait_for_function.py
│   │   ├── test_wait_for_url.py
│   │   ├── test_websocket.py
│   │   ├── test_worker.py
│   │   └── utils.py
│   ├── common/
│   │   ├── __init__.py
│   │   ├── test_collect_handles.py
│   │   ├── test_events.py
│   │   ├── test_signals.py
│   │   └── test_threads.py
│   ├── conftest.py
│   ├── server.py
│   ├── sync/
│   │   ├── __init__.py
│   │   ├── conftest.py
│   │   ├── test_add_init_script.py
│   │   ├── test_assertions.py
│   │   ├── test_browser.py
│   │   ├── test_browsercontext_client_certificates.py
│   │   ├── test_browsercontext_events.py
│   │   ├── test_browsercontext_request_fallback.py
│   │   ├── test_browsercontext_request_intercept.py
│   │   ├── test_browsercontext_service_worker_policy.py
│   │   ├── test_browsercontext_storage_state.py
│   │   ├── test_browsertype_connect.py
│   │   ├── test_browsertype_connect_cdp.py
│   │   ├── test_cdp_session.py
│   │   ├── test_check.py
│   │   ├── test_console.py
│   │   ├── test_context_manager.py
│   │   ├── test_element_handle.py
│   │   ├── test_element_handle_wait_for_element_state.py
│   │   ├── test_expect_misc.py
│   │   ├── test_extension.py
│   │   ├── test_fetch_browser_context.py
│   │   ├── test_fetch_global.py
│   │   ├── test_fill.py
│   │   ├── test_har.py
│   │   ├── test_input.py
│   │   ├── test_launcher.py
│   │   ├── test_listeners.py
│   │   ├── test_locator_get_by.py
│   │   ├── test_locators.py
│   │   ├── test_network.py
│   │   ├── test_page.py
│   │   ├── test_page_add_locator_handler.py
│   │   ├── test_page_aria_snapshot.py
│   │   ├── test_page_clock.py
│   │   ├── test_page_event_console.py
│   │   ├── test_page_event_pageerror.py
│   │   ├── test_page_event_request.py
│   │   ├── test_page_network_response.py
│   │   ├── test_page_request_fallback.py
│   │   ├── test_page_request_gc.py
│   │   ├── test_page_request_intercept.py
│   │   ├── test_page_request_timeout.py
│   │   ├── test_page_select_option.py
│   │   ├── test_pdf.py
│   │   ├── test_queryselector.py
│   │   ├── test_request_fulfill.py
│   │   ├── test_request_intercept.py
│   │   ├── test_resource_timing.py
│   │   ├── test_route_web_socket.py
│   │   ├── test_selectors_misc.py
│   │   ├── test_sync.py
│   │   ├── test_tap.py
│   │   ├── test_tracing.py
│   │   ├── test_unroute_behavior.py
│   │   ├── test_video.py
│   │   └── utils.py
│   ├── test_installation.py
│   ├── test_reference_count_async.py
│   ├── testserver/
│   │   ├── cert.pem
│   │   └── key.pem
│   └── utils.py
└── utils/
    ├── docker/
    │   ├── .gitignore
    │   ├── Dockerfile.jammy
    │   ├── Dockerfile.noble
    │   ├── build.sh
    │   └── publish_docker.sh
    └── linting/
        └── check_file_header.py
Download .txt
Showing preview only (479K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (4795 symbols across 234 files)

FILE: examples/todomvc/mvctests/test_clear_completed_button.py
  function run_around_tests (line 24) | def run_around_tests(page: Page) -> Generator[None, None, None]:
  function test_should_display_the_correct_text (line 33) | def test_should_display_the_correct_text(page: Page) -> None:
  function test_should_clear_completed_items_when_clicked (line 38) | def test_should_clear_completed_items_when_clicked(page: Page) -> None:
  function test_should_be_hidden_when_there_are_no_items_that_are_completed (line 46) | def test_should_be_hidden_when_there_are_no_items_that_are_completed(

FILE: examples/todomvc/mvctests/test_counter.py
  function run_around_tests (line 24) | def run_around_tests(page: Page) -> Generator[None, None, None]:
  function test_should_display_the_current_number_of_todo_items (line 32) | def test_should_display_the_current_number_of_todo_items(page: Page) -> ...

FILE: examples/todomvc/mvctests/test_editing.py
  function run_around_tests (line 29) | def run_around_tests(page: Page) -> Generator[None, None, None]:
  function test_should_hide_other_controls_when_editing (line 39) | def test_should_hide_other_controls_when_editing(page: Page) -> None:
  function test_should_save_edits_on_blur (line 47) | def test_should_save_edits_on_blur(page: Page) -> None:
  function test_should_trim_entered_text (line 63) | def test_should_trim_entered_text(page: Page) -> None:
  function test_should_remove_the_item_if_an_empty_text_string_was_entered (line 79) | def test_should_remove_the_item_if_an_empty_text_string_was_entered(page...
  function test_should_cancel_edits_on_escape (line 93) | def test_should_cancel_edits_on_escape(page: Page) -> None:

FILE: examples/todomvc/mvctests/test_item.py
  function run_around_tests (line 29) | def run_around_tests(page: Page) -> Generator[None, None, None]:
  function test_should_allow_me_to_mark_items_as_completed (line 37) | def test_should_allow_me_to_mark_items_as_completed(page: Page) -> None:
  function test_should_allow_me_to_un_mark_items_as_completed (line 58) | def test_should_allow_me_to_un_mark_items_as_completed(page: Page) -> None:
  function test_should_allow_me_to_edit_an_item (line 77) | def test_should_allow_me_to_edit_an_item(page: Page) -> None:

FILE: examples/todomvc/mvctests/test_mark_all_as_completed.py
  function run_around_tests (line 28) | def run_around_tests(page: Page) -> Generator[None, None, None]:
  function test_should_allow_me_to_mark_all_items_as_completed (line 36) | def test_should_allow_me_to_mark_all_items_as_completed(page: Page) -> N...
  function test_should_allow_me_to_clear_the_complete_state_of_all_items (line 50) | def test_should_allow_me_to_clear_the_complete_state_of_all_items(page: ...
  function test_complete_all_checkbox_should_update_state_when_items_are_completed_or_cleared (line 62) | def test_complete_all_checkbox_should_update_state_when_items_are_comple...

FILE: examples/todomvc/mvctests/test_new_todo.py
  function run_around_tests (line 29) | def run_around_tests(page: Page) -> Generator[None, None, None]:
  function test_new_todo_test_should_allow_me_to_add_todo_items (line 37) | def test_new_todo_test_should_allow_me_to_add_todo_items(page: Page) -> ...
  function test_new_todo_test_should_clear_text_input_field_when_an_item_is_added (line 55) | def test_new_todo_test_should_clear_text_input_field_when_an_item_is_added(
  function test_new_todo_test_should_append_new_items_to_the_bottom_of_the_list (line 67) | def test_new_todo_test_should_append_new_items_to_the_bottom_of_the_list(
  function test_new_todo_should_show_main_and_foter_when_items_added (line 83) | def test_new_todo_should_show_main_and_foter_when_items_added(page: Page...

FILE: examples/todomvc/mvctests/test_persistence.py
  function run_around_tests (line 24) | def run_around_tests(page: Page) -> Generator[None, None, None]:
  function test_should_persist_its_data (line 32) | def test_should_persist_its_data(page: Page) -> None:

FILE: examples/todomvc/mvctests/test_routing.py
  function run_around_tests (line 29) | def run_around_tests(page: Page) -> Generator[None, None, None]:
  function test_should_allow_me_to_display_active_item (line 42) | def test_should_allow_me_to_display_active_item(page: Page) -> None:
  function test_should_respect_the_back_button (line 50) | def test_should_respect_the_back_button(page: Page) -> None:
  function test_should_allow_me_to_display_completed_items (line 71) | def test_should_allow_me_to_display_completed_items(page: Page) -> None:
  function test_should_allow_me_to_display_all_items (line 78) | def test_should_allow_me_to_display_all_items(page: Page) -> None:
  function test_should_highlight_the_current_applied_filter (line 87) | def test_should_highlight_the_current_applied_filter(page: Page) -> None:

FILE: examples/todomvc/mvctests/utils.py
  function create_default_todos (line 19) | def create_default_todos(page: Page) -> None:
  function check_number_of_completed_todos_in_local_storage (line 25) | def check_number_of_completed_todos_in_local_storage(page: Page, expecte...
  function assert_number_of_todos_in_local_storage (line 34) | def assert_number_of_todos_in_local_storage(page: Page, expected: int) -...
  function check_todos_in_local_storage (line 38) | def check_todos_in_local_storage(page: Page, title: str) -> None:

FILE: playwright/__main__.py
  function main (line 21) | def main() -> None:

FILE: playwright/_impl/__pyinstaller/__init__.py
  function get_hook_dirs (line 19) | def get_hook_dirs() -> List[str]:

FILE: playwright/_impl/_api_structures.py
  class Cookie (line 26) | class Cookie(TypedDict, total=False):
  class StorageStateCookie (line 38) | class StorageStateCookie(TypedDict, total=False):
  class SetCookieParam (line 50) | class SetCookieParam(TypedDict, total=False):
  class FloatRect (line 63) | class FloatRect(TypedDict):
  class Geolocation (line 70) | class Geolocation(TypedDict, total=False):
  class HttpCredentials (line 76) | class HttpCredentials(TypedDict, total=False):
  class LocalStorageEntry (line 83) | class LocalStorageEntry(TypedDict):
  class OriginState (line 88) | class OriginState(TypedDict):
  class PdfMargins (line 93) | class PdfMargins(TypedDict, total=False):
  class Position (line 100) | class Position(TypedDict):
  class ProxySettings (line 105) | class ProxySettings(TypedDict, total=False):
  class StorageState (line 112) | class StorageState(TypedDict, total=False):
  class ClientCertificate (line 117) | class ClientCertificate(TypedDict, total=False):
  class ResourceTiming (line 128) | class ResourceTiming(TypedDict):
  class RequestSizes (line 140) | class RequestSizes(TypedDict):
  class ViewportSize (line 147) | class ViewportSize(TypedDict):
  class SourceLocation (line 152) | class SourceLocation(TypedDict):
  class FilePayload (line 158) | class FilePayload(TypedDict):
  class RemoteAddr (line 164) | class RemoteAddr(TypedDict):
  class SecurityDetails (line 169) | class SecurityDetails(TypedDict):
  class NameValue (line 177) | class NameValue(TypedDict):
  class ServerFilePayload (line 186) | class ServerFilePayload(TypedDict):
  class FormField (line 192) | class FormField(TypedDict, total=False):
  class ExpectedTextValue (line 198) | class ExpectedTextValue(TypedDict, total=False):
  class FrameExpectOptions (line 207) | class FrameExpectOptions(TypedDict, total=False):
  class FrameExpectResult (line 217) | class FrameExpectResult(TypedDict):
  class TracingGroupLocation (line 310) | class TracingGroupLocation(TypedDict):

FILE: playwright/_impl/_artifact.py
  class Artifact (line 24) | class Artifact(ChannelOwner):
    method __init__ (line 25) | def __init__(
    method path_after_finished (line 31) | async def path_after_finished(self) -> pathlib.Path:
    method save_as (line 42) | async def save_as(self, path: Union[str, Path]) -> None:
    method failure (line 55) | async def failure(self) -> Optional[str]:
    method delete (line 64) | async def delete(self) -> None:
    method read_info_buffer (line 70) | async def read_info_buffer(self) -> bytes:
    method cancel (line 83) | async def cancel(self) -> None:  # pyright: ignore[reportIncompatibleM...

FILE: playwright/_impl/_assertions.py
  class AssertionsBase (line 34) | class AssertionsBase:
    method __init__ (line 35) | def __init__(
    method _call_expect (line 49) | async def _call_expect(
    method _expect_impl (line 56) | async def _expect_impl(
  class PageAssertions (line 90) | class PageAssertions(AssertionsBase):
    method __init__ (line 91) | def __init__(
    method _call_expect (line 101) | async def _call_expect(
    method _not (line 110) | def _not(self) -> "PageAssertions":
    method to_have_title (line 115) | async def to_have_title(
    method not_to_have_title (line 130) | async def not_to_have_title(
    method to_have_url (line 136) | async def to_have_url(
    method not_to_have_url (line 155) | async def not_to_have_url(
  class LocatorAssertions (line 165) | class LocatorAssertions(AssertionsBase):
    method __init__ (line 166) | def __init__(
    method _call_expect (line 176) | async def _call_expect(
    method _not (line 183) | def _not(self) -> "LocatorAssertions":
    method to_contain_text (line 188) | async def to_contain_text(
    method not_to_contain_text (line 241) | async def not_to_contain_text(
    method to_have_attribute (line 257) | async def to_have_attribute(
    method not_to_have_attribute (line 276) | async def not_to_have_attribute(
    method to_have_class (line 288) | async def to_have_class(
    method not_to_have_class (line 321) | async def not_to_have_class(
    method to_contain_class (line 335) | async def to_contain_class(
    method not_to_contain_class (line 365) | async def not_to_contain_class(
    method to_have_count (line 376) | async def to_have_count(
    method not_to_have_count (line 390) | async def not_to_have_count(
    method to_have_css (line 398) | async def to_have_css(
    method not_to_have_css (line 416) | async def not_to_have_css(
    method to_have_id (line 425) | async def to_have_id(
    method not_to_have_id (line 440) | async def not_to_have_id(
    method to_have_js_property (line 448) | async def to_have_js_property(
    method not_to_have_js_property (line 465) | async def not_to_have_js_property(
    method to_have_value (line 474) | async def to_have_value(
    method not_to_have_value (line 489) | async def not_to_have_value(
    method to_have_values (line 497) | async def to_have_values(
    method not_to_have_values (line 514) | async def not_to_have_values(
    method to_have_text (line 524) | async def to_have_text(
    method not_to_have_text (line 573) | async def not_to_have_text(
    method to_be_attached (line 589) | async def to_be_attached(
    method to_be_checked (line 606) | async def to_be_checked(
    method not_to_be_attached (line 631) | async def not_to_be_attached(
    method not_to_be_checked (line 639) | async def not_to_be_checked(
    method to_be_disabled (line 646) | async def to_be_disabled(
    method not_to_be_disabled (line 659) | async def not_to_be_disabled(
    method to_be_editable (line 666) | async def to_be_editable(
    method not_to_be_editable (line 683) | async def not_to_be_editable(
    method to_be_empty (line 691) | async def to_be_empty(
    method not_to_be_empty (line 704) | async def not_to_be_empty(
    method to_be_enabled (line 711) | async def to_be_enabled(
    method not_to_be_enabled (line 728) | async def not_to_be_enabled(
    method to_be_hidden (line 736) | async def to_be_hidden(
    method not_to_be_hidden (line 749) | async def not_to_be_hidden(
    method to_be_visible (line 756) | async def to_be_visible(
    method not_to_be_visible (line 773) | async def not_to_be_visible(
    method to_be_focused (line 781) | async def to_be_focused(
    method not_to_be_focused (line 794) | async def not_to_be_focused(
    method to_be_in_viewport (line 801) | async def to_be_in_viewport(
    method not_to_be_in_viewport (line 815) | async def not_to_be_in_viewport(
    method to_have_accessible_description (line 821) | async def to_have_accessible_description(
    method not_to_have_accessible_description (line 839) | async def not_to_have_accessible_description(
    method to_have_accessible_name (line 848) | async def to_have_accessible_name(
    method not_to_have_accessible_name (line 866) | async def not_to_have_accessible_name(
    method to_have_role (line 875) | async def to_have_role(self, role: AriaRole, timeout: float = None) ->...
    method to_have_accessible_error_message (line 888) | async def to_have_accessible_error_message(
    method not_to_have_accessible_error_message (line 906) | async def not_to_have_accessible_error_message(
    method not_to_have_role (line 917) | async def not_to_have_role(self, role: AriaRole, timeout: float = None...
    method to_match_aria_snapshot (line 921) | async def to_match_aria_snapshot(
    method not_to_match_aria_snapshot (line 933) | async def not_to_match_aria_snapshot(
  class APIResponseAssertions (line 940) | class APIResponseAssertions:
    method __init__ (line 941) | def __init__(
    method _not (line 956) | def _not(self) -> "APIResponseAssertions":
    method to_be_ok (line 961) | async def to_be_ok(
    method not_to_be_ok (line 981) | async def not_to_be_ok(self) -> None:
  function expected_regex (line 986) | def expected_regex(
  function to_expected_text_values (line 1004) | def to_expected_text_values(

FILE: playwright/_impl/_async_base.py
  class AsyncEventInfo (line 29) | class AsyncEventInfo(Generic[T]):
    method __init__ (line 30) | def __init__(self, future: "asyncio.Future[T]") -> None:
    method value (line 34) | async def value(self) -> T:
    method _cancel (line 37) | def _cancel(self) -> None:
    method is_done (line 40) | def is_done(self) -> bool:
  class AsyncEventContextManager (line 44) | class AsyncEventContextManager(Generic[T], AbstractAsyncContextManager):
    method __init__ (line 45) | def __init__(self, future: "asyncio.Future[T]") -> None:
    method __aenter__ (line 48) | async def __aenter__(self) -> AsyncEventInfo[T]:
    method __aexit__ (line 51) | async def __aexit__(
  class AsyncBase (line 63) | class AsyncBase(ImplWrapper):
    method __init__ (line 64) | def __init__(self, impl_obj: Any) -> None:
    method __str__ (line 68) | def __str__(self) -> str:
    method _wrap_handler (line 71) | def _wrap_handler(
    method on (line 78) | def on(self, event: Any, f: Any) -> None:
    method once (line 82) | def once(self, event: Any, f: Any) -> None:
    method remove_listener (line 88) | def remove_listener(self, event: Any, f: Any) -> None:
  class AsyncContextManager (line 93) | class AsyncContextManager(AsyncBase):
    method __aenter__ (line 94) | async def __aenter__(self: Self) -> Self:
    method __aexit__ (line 97) | async def __aexit__(
    method close (line 105) | async def close(self) -> None: ...

FILE: playwright/_impl/_browser.py
  class Browser (line 59) | class Browser(ChannelOwner):
    method __init__ (line 64) | def __init__(
    method __repr__ (line 84) | def __repr__(self) -> str:
    method _connect_to_browser_type (line 87) | def _connect_to_browser_type(
    method _did_create_context (line 99) | def _did_create_context(self, context: BrowserContext) -> None:
    method _setup_browser_context (line 107) | def _setup_browser_context(self, context: BrowserContext) -> None:
    method _on_close (line 112) | def _on_close(self) -> None:
    method contexts (line 117) | def contexts(self) -> List[BrowserContext]:
    method browser_type (line 121) | def browser_type(self) -> "BrowserType":
    method is_connected (line 125) | def is_connected(self) -> bool:
    method new_context (line 128) | async def new_context(
    method new_page (line 182) | async def new_page(
    method close (line 232) | async def close(self, reason: str = None) -> None:
    method version (line 244) | def version(self) -> str:
    method new_browser_cdp_session (line 247) | async def new_browser_cdp_session(self) -> CDPSession:
    method start_tracing (line 250) | async def start_tracing(
    method stop_tracing (line 265) | async def stop_tracing(self) -> bytes:

FILE: playwright/_impl/_browser_context.py
  class BrowserContext (line 89) | class BrowserContext(ChannelOwner):
    method __init__ (line 105) | def __init__(
    method __repr__ (line 223) | def __repr__(self) -> str:
    method _on_page (line 226) | def _on_page(self, page: Page) -> None:
    method _on_route (line 232) | async def _on_route(self, route: Route) -> None:
    method _on_web_socket_route (line 264) | async def _on_web_socket_route(self, web_socket_route: WebSocketRoute)...
    method _on_binding (line 278) | def _on_binding(self, binding_call: BindingCall) -> None:
    method set_default_navigation_timeout (line 284) | def set_default_navigation_timeout(self, timeout: float) -> None:
    method _set_default_navigation_timeout_impl (line 287) | def _set_default_navigation_timeout_impl(self, timeout: Optional[float...
    method set_default_timeout (line 290) | def set_default_timeout(self, timeout: float) -> None:
    method _set_default_timeout_impl (line 293) | def _set_default_timeout_impl(self, timeout: Optional[float]) -> None:
    method pages (line 297) | def pages(self) -> List[Page]:
    method browser (line 301) | def browser(self) -> Optional["Browser"]:
    method _initialize_har_from_options (line 304) | async def _initialize_har_from_options(
    method new_page (line 329) | async def new_page(self) -> Page:
    method cookies (line 334) | async def cookies(self, urls: Union[str, Sequence[str]] = None) -> Lis...
    method add_cookies (line 341) | async def add_cookies(self, cookies: Sequence[SetCookieParam]) -> None:
    method clear_cookies (line 344) | async def clear_cookies(
    method grant_permissions (line 374) | async def grant_permissions(
    method clear_permissions (line 379) | async def clear_permissions(self) -> None:
    method set_geolocation (line 382) | async def set_geolocation(self, geolocation: Geolocation = None) -> None:
    method set_extra_http_headers (line 385) | async def set_extra_http_headers(self, headers: Dict[str, str]) -> None:
    method set_offline (line 390) | async def set_offline(self, offline: bool) -> None:
    method add_init_script (line 393) | async def add_init_script(
    method expose_binding (line 402) | async def expose_binding(
    method expose_function (line 417) | async def expose_function(self, name: str, callback: Callable) -> None:
    method route (line 420) | async def route(
    method unroute (line 435) | async def unroute(
    method _unroute_internal (line 447) | async def _unroute_internal(
    method route_web_socket (line 458) | async def route_web_socket(
    method _dispose_har_routers (line 467) | def _dispose_har_routers(self) -> None:
    method unroute_all (line 472) | async def unroute_all(
    method _record_into_har (line 478) | async def _record_into_har(
    method route_from_har (line 507) | async def route_from_har(
    method _update_interception_patterns (line 534) | async def _update_interception_patterns(self) -> None:
    method _update_web_socket_interception_patterns (line 540) | async def _update_web_socket_interception_patterns(self) -> None:
    method expect_event (line 548) | def expect_event(
    method _on_close (line 567) | def _on_close(self) -> None:
    method close (line 585) | async def close(self, reason: str = None) -> None:
    method storage_state (line 620) | async def storage_state(
    method _effective_close_reason (line 630) | def _effective_close_reason(self) -> Optional[str]:
    method wait_for_event (line 637) | async def wait_for_event(
    method expect_console_message (line 644) | def expect_console_message(
    method expect_page (line 651) | def expect_page(
    method _on_service_worker (line 658) | def _on_service_worker(self, worker: Worker) -> None:
    method _on_request_failed (line 663) | def _on_request_failed(
    method _on_request_finished (line 676) | def _on_request_finished(
    method _on_console_message (line 690) | def _on_console_message(self, event: Dict) -> None:
    method _on_dialog (line 700) | def _on_dialog(self, dialog: Dialog) -> None:
    method _on_page_error (line 715) | def _on_page_error(self, error: Error, page: Optional[Page]) -> None:
    method _on_request (line 723) | def _on_request(self, request: Request, page: Optional[Page]) -> None:
    method _on_response (line 728) | def _on_response(self, response: Response, page: Optional[Page]) -> None:
    method background_pages (line 734) | def background_pages(self) -> List[Page]:
    method service_workers (line 738) | def service_workers(self) -> List[Worker]:
    method new_cdp_session (line 741) | async def new_cdp_session(self, page: Union[Page, Frame]) -> CDPSession:
    method tracing (line 753) | def tracing(self) -> Tracing:
    method request (line 757) | def request(self) -> "APIRequestContext":
    method clock (line 761) | def clock(self) -> Clock:

FILE: playwright/_impl/_browser_type.py
  class BrowserType (line 55) | class BrowserType(ChannelOwner):
    method __init__ (line 56) | def __init__(
    method __repr__ (line 62) | def __repr__(self) -> str:
    method name (line 66) | def name(self) -> str:
    method executable_path (line 70) | def executable_path(self) -> str:
    method launch (line 73) | async def launch(
    method launch_persistent_context (line 107) | async def launch_persistent_context(
    method _user_data_dir (line 184) | def _user_data_dir(self, userDataDir: Optional[Union[str, Path]]) -> str:
    method connect_over_cdp (line 195) | async def connect_over_cdp(
    method connect (line 214) | async def connect(
    method _prepare_browser_context_params (line 298) | async def _prepare_browser_context_params(self, params: Dict) -> None:
  function normalize_launch_params (line 348) | def normalize_launch_params(params: Dict) -> None:

FILE: playwright/_impl/_cdp_session.py
  class CDPSession (line 21) | class CDPSession(ChannelOwner):
    method __init__ (line 22) | def __init__(
    method _on_event (line 28) | def _on_event(self, params: Any) -> None:
    method send (line 31) | async def send(self, method: str, params: Dict = None) -> Dict:
    method detach (line 34) | async def detach(self) -> None:

FILE: playwright/_impl/_clock.py
  class Clock (line 22) | class Clock:
    method __init__ (line 23) | def __init__(self, browser_context: "BrowserContext") -> None:
    method install (line 28) | async def install(self, time: Union[float, str, datetime.datetime] = N...
    method fast_forward (line 35) | async def fast_forward(
    method pause_at (line 45) | async def pause_at(
    method resume (line 55) | async def resume(
    method run_for (line 60) | async def run_for(
    method set_fixed_time (line 70) | async def set_fixed_time(
    method set_system_time (line 80) | async def set_system_time(
  function parse_time (line 91) | def parse_time(
  function parse_ticks (line 101) | def parse_ticks(ticks: Union[int, str]) -> Dict[str, Union[int, str]]:

FILE: playwright/_impl/_connection.py
  class Channel (line 53) | class Channel(AsyncIOEventEmitter):
    method __init__ (line 54) | def __init__(self, connection: "Connection", object: "ChannelOwner") -...
    method send (line 61) | async def send(
    method send_return_as_dict (line 75) | async def send_return_as_dict(
    method send_no_reply (line 89) | def send_no_reply(
    method _inner_send (line 109) | async def _inner_send(
  class ChannelOwner (line 147) | class ChannelOwner(AsyncIOEventEmitter):
    method __init__ (line 148) | def __init__(
    method _dispose (line 177) | def _dispose(self, reason: Optional[str]) -> None:
    method _adopt (line 189) | def _adopt(self, child: "ChannelOwner") -> None:
    method _set_event_to_subscription_mapping (line 194) | def _set_event_to_subscription_mapping(self, mapping: Dict[str, str]) ...
    method _update_subscription (line 197) | def _update_subscription(self, event: str, enabled: bool) -> None:
    method _add_event_handler (line 209) | def _add_event_handler(self, event: str, k: Any, v: Any) -> None:
    method remove_listener (line 214) | def remove_listener(self, event: str, f: Any) -> None:
  class ProtocolCallback (line 220) | class ProtocolCallback:
    method __init__ (line 221) | def __init__(self, loop: asyncio.AbstractEventLoop, no_reply: bool = F...
  class RootChannelOwner (line 245) | class RootChannelOwner(ChannelOwner):
    method __init__ (line 246) | def __init__(self, connection: "Connection") -> None:
    method initialize (line 249) | async def initialize(self) -> "Playwright":
  class Connection (line 261) | class Connection(EventEmitter):
    method __init__ (line 262) | def __init__(
    method local_utils (line 294) | def local_utils(self) -> "LocalUtils":
    method mark_as_remote (line 298) | def mark_as_remote(self) -> None:
    method run_as_sync (line 301) | async def run_as_sync(self) -> None:
    method run (line 305) | async def run(self) -> None:
    method stop_sync (line 316) | def stop_sync(self) -> None:
    method stop_async (line 322) | async def stop_async(self) -> None:
    method cleanup (line 327) | def cleanup(self, cause: str = None) -> None:
    method call_on_object_with_known_name (line 343) | def call_on_object_with_known_name(
    method set_is_tracing (line 348) | def set_is_tracing(self, is_tracing: bool) -> None:
    method _send_message_to_server (line 354) | def _send_message_to_server(
    method dispatch (line 408) | def dispatch(self, msg: ParsedMessagePayload) -> None:
    method _on_event_listener_error (line 494) | def _on_event_listener_error(self, exc: BaseException) -> None:
    method _create_remote_object (line 500) | def _create_remote_object(
    method _replace_channels_with_guids (line 509) | def _replace_channels_with_guids(
    method _replace_guids_with_channels (line 530) | def _replace_guids_with_channels(self, payload: Any) -> Any:
    method wrap_api_call (line 544) | async def wrap_api_call(
    method wrap_api_call_sync (line 563) | def wrap_api_call_sync(
  function from_channel (line 582) | def from_channel(channel: Channel) -> Any:
  function from_nullable_channel (line 586) | def from_nullable_channel(channel: Optional[Channel]) -> Optional[Any]:
  class StackFrame (line 590) | class StackFrame(TypedDict):
  class ParsedStackTrace (line 597) | class ParsedStackTrace(TypedDict):
  function _extract_stack_trace_information_from_stack (line 603) | def _extract_stack_trace_information_from_stack(
  function _augment_params (line 648) | def _augment_params(
  function _filter_none (line 659) | def _filter_none(d: Mapping) -> Dict:
  function format_call_log (line 668) | def format_call_log(log: Optional[List[str]]) -> str:

FILE: playwright/_impl/_console_message.py
  class ConsoleMessage (line 27) | class ConsoleMessage:
    method __init__ (line 28) | def __init__(
    method __repr__ (line 37) | def __repr__(self) -> str:
    method __str__ (line 40) | def __str__(self) -> str:
    method type (line 44) | def type(self) -> Union[
    method text (line 68) | def text(self) -> str:
    method args (line 72) | def args(self) -> List[JSHandle]:
    method location (line 76) | def location(self) -> SourceLocation:
    method page (line 80) | def page(self) -> Optional["Page"]:
    method worker (line 84) | def worker(self) -> Optional["Worker"]:

FILE: playwright/_impl/_dialog.py
  class Dialog (line 24) | class Dialog(ChannelOwner):
    method __init__ (line 25) | def __init__(
    method __repr__ (line 31) | def __repr__(self) -> str:
    method type (line 35) | def type(self) -> str:
    method message (line 39) | def message(self) -> str:
    method default_value (line 43) | def default_value(self) -> str:
    method page (line 47) | def page(self) -> Optional["Page"]:
    method accept (line 50) | async def accept(self, promptText: str = None) -> None:
    method dismiss (line 53) | async def dismiss(self) -> None:

FILE: playwright/_impl/_download.py
  class Download (line 25) | class Download:
    method __init__ (line 26) | def __init__(
    method __repr__ (line 36) | def __repr__(self) -> str:
    method page (line 40) | def page(self) -> "Page":
    method url (line 44) | def url(self) -> str:
    method suggested_filename (line 48) | def suggested_filename(self) -> str:
    method delete (line 51) | async def delete(self) -> None:
    method failure (line 54) | async def failure(self) -> Optional[str]:
    method path (line 57) | async def path(self) -> pathlib.Path:
    method save_as (line 60) | async def save_as(self, path: Union[str, Path]) -> None:
    method cancel (line 63) | async def cancel(self) -> None:

FILE: playwright/_impl/_driver.py
  function compute_driver_executable (line 25) | def compute_driver_executable() -> Tuple[str, str]:
  function get_driver_env (line 36) | def get_driver_env() -> dict:

FILE: playwright/_impl/_element_handle.py
  class ElementHandle (line 54) | class ElementHandle(JSHandle):
    method __init__ (line 55) | def __init__(
    method _createSelectorForTest (line 61) | async def _createSelectorForTest(self, name: str) -> Optional[str]:
    method as_element (line 66) | def as_element(self) -> Optional["ElementHandle"]:
    method owner_frame (line 69) | async def owner_frame(self) -> Optional["Frame"]:
    method content_frame (line 72) | async def content_frame(self) -> Optional["Frame"]:
    method get_attribute (line 75) | async def get_attribute(self, name: str) -> Optional[str]:
    method text_content (line 78) | async def text_content(self) -> Optional[str]:
    method inner_text (line 81) | async def inner_text(self) -> str:
    method inner_html (line 84) | async def inner_html(self) -> str:
    method is_checked (line 87) | async def is_checked(self) -> bool:
    method is_disabled (line 90) | async def is_disabled(self) -> bool:
    method is_editable (line 93) | async def is_editable(self) -> bool:
    method is_enabled (line 96) | async def is_enabled(self) -> bool:
    method is_hidden (line 99) | async def is_hidden(self) -> bool:
    method is_visible (line 102) | async def is_visible(self) -> bool:
    method dispatch_event (line 105) | async def dispatch_event(self, type: str, eventInit: Dict = None) -> N...
    method scroll_into_view_if_needed (line 112) | async def scroll_into_view_if_needed(self, timeout: float = None) -> N...
    method hover (line 117) | async def hover(
    method click (line 130) | async def click(
    method dblclick (line 147) | async def dblclick(
    method select_option (line 163) | async def select_option(
    method tap (line 182) | async def tap(
    method fill (line 195) | async def fill(
    method select_text (line 206) | async def select_text(self, force: bool = None, timeout: float = None)...
    method input_value (line 211) | async def input_value(self, timeout: float = None) -> str:
    method set_input_files (line 216) | async def set_input_files(
    method focus (line 237) | async def focus(self) -> None:
    method type (line 240) | async def type(
    method press (line 251) | async def press(
    method set_checked (line 262) | async def set_checked(
    method check (line 286) | async def check(
    method uncheck (line 298) | async def uncheck(
    method bounding_box (line 310) | async def bounding_box(self) -> Optional[FloatRect]:
    method screenshot (line 313) | async def screenshot(
    method query_selector (line 353) | async def query_selector(self, selector: str) -> Optional["ElementHand...
    method query_selector_all (line 358) | async def query_selector_all(self, selector: str) -> List["ElementHand...
    method eval_on_selector (line 368) | async def eval_on_selector(
    method eval_on_selector_all (line 386) | async def eval_on_selector_all(
    method wait_for_element_state (line 404) | async def wait_for_element_state(
    method wait_for_selector (line 415) | async def wait_for_selector(
  function convert_select_option_values (line 429) | def convert_select_option_values(
  function determine_screenshot_type (line 460) | def determine_screenshot_type(path: Union[str, Path]) -> Literal["jpeg",...

FILE: playwright/_impl/_errors.py
  function is_target_closed_error (line 22) | def is_target_closed_error(error: Exception) -> bool:
  class Error (line 26) | class Error(Exception):
    method __init__ (line 27) | def __init__(self, message: str) -> None:
    method message (line 34) | def message(self) -> str:
    method name (line 38) | def name(self) -> Optional[str]:
    method stack (line 42) | def stack(self) -> Optional[str]:
  class TimeoutError (line 46) | class TimeoutError(Error):
  class TargetClosedError (line 50) | class TargetClosedError(Error):
    method __init__ (line 51) | def __init__(self, message: str = None) -> None:
  function rewrite_error (line 55) | def rewrite_error(error: Exception, message: str) -> Exception:

FILE: playwright/_impl/_event_context_manager.py
  class EventContextManagerImpl (line 21) | class EventContextManagerImpl(Generic[T]):
    method __init__ (line 22) | def __init__(self, future: asyncio.Future) -> None:
    method future (line 26) | def future(self) -> asyncio.Future:
    method __aenter__ (line 29) | async def __aenter__(self) -> asyncio.Future:
    method __aexit__ (line 32) | async def __aexit__(self, *args: Any) -> None:

FILE: playwright/_impl/_fetch.py
  class APIRequest (line 60) | class APIRequest:
    method __init__ (line 61) | def __init__(self, playwright: "Playwright") -> None:
    method new_context (line 66) | async def new_context(
  class APIRequestContext (line 102) | class APIRequestContext(ChannelOwner):
    method __init__ (line 103) | def __init__(
    method dispose (line 111) | async def dispose(self, reason: str = None) -> None:
    method delete (line 121) | async def delete(
    method head (line 150) | async def head(
    method get (line 179) | async def get(
    method patch (line 208) | async def patch(
    method put (line 237) | async def put(
    method post (line 266) | async def post(
    method fetch (line 295) | async def fetch(
    method _inner_fetch (line 335) | async def _inner_fetch(
    method storage_state (line 432) | async def storage_state(
  function file_payload_to_json (line 445) | def file_payload_to_json(payload: FilePayload) -> ServerFilePayload:
  class APIResponse (line 453) | class APIResponse:
    method __init__ (line 454) | def __init__(self, context: APIRequestContext, initializer: Dict) -> N...
    method __repr__ (line 461) | def __repr__(self) -> str:
    method ok (line 465) | def ok(self) -> bool:
    method url (line 469) | def url(self) -> str:
    method status (line 473) | def status(self) -> int:
    method status_text (line 477) | def status_text(self) -> str:
    method headers (line 481) | def headers(self) -> Headers:
    method headers_array (line 485) | def headers_array(self) -> network.HeadersArray:
    method body (line 488) | async def body(self) -> bytes:
    method text (line 508) | async def text(self) -> str:
    method json (line 512) | async def json(self) -> Any:
    method dispose (line 516) | async def dispose(self) -> None:
    method _fetch_uid (line 526) | def _fetch_uid(self) -> str:
    method _fetch_log (line 529) | async def _fetch_log(self) -> List[str]:
  function is_json_content_type (line 539) | def is_json_content_type(headers: network.HeadersArray = None) -> bool:
  function is_json_parsable (line 548) | def is_json_parsable(value: Any) -> bool:

FILE: playwright/_impl/_file_chooser.py
  class FileChooser (line 25) | class FileChooser:
    method __init__ (line 26) | def __init__(
    method __repr__ (line 35) | def __repr__(self) -> str:
    method page (line 39) | def page(self) -> "Page":
    method element (line 43) | def element(self) -> "ElementHandle":
    method is_multiple (line 46) | def is_multiple(self) -> bool:
    method set_files (line 49) | async def set_files(

FILE: playwright/_impl/_frame.py
  class Frame (line 88) | class Frame(ChannelOwner):
    method __init__ (line 89) | def __init__(
    method __repr__ (line 112) | def __repr__(self) -> str:
    method _on_load_state (line 115) | def _on_load_state(
    method _on_frame_navigated (line 128) | def _on_frame_navigated(self, event: FrameNavigatedEvent) -> None:
    method _query_count (line 135) | async def _query_count(self, selector: str) -> int:
    method page (line 139) | def page(self) -> "Page":
    method goto (line 143) | async def goto(
    method _setup_navigation_waiter (line 159) | def _setup_navigation_waiter(self, wait_name: str, timeout: float = No...
    method _expect (line 180) | async def _expect(
    method expect_navigation (line 203) | def expect_navigation(
    method wait_for_url (line 253) | async def wait_for_url(
    method wait_for_load_state (line 268) | async def wait_for_load_state(
    method _wait_for_load_state_impl (line 275) | async def _wait_for_load_state_impl(
    method _timeout (line 303) | def _timeout(self, timeout: Optional[float]) -> float:
    method _navigation_timeout (line 309) | def _navigation_timeout(self, timeout: Optional[float]) -> float:
    method frame_element (line 315) | async def frame_element(self) -> ElementHandle:
    method evaluate (line 318) | async def evaluate(self, expression: str, arg: Serializable = None) ->...
    method evaluate_handle (line 330) | async def evaluate_handle(
    method query_selector (line 344) | async def query_selector(
    method query_selector_all (line 351) | async def query_selector_all(self, selector: str) -> List[ElementHandle]:
    method wait_for_selector (line 361) | async def wait_for_selector(
    method is_checked (line 374) | async def is_checked(
    method is_disabled (line 381) | async def is_disabled(
    method is_editable (line 388) | async def is_editable(
    method is_enabled (line 395) | async def is_enabled(
    method is_hidden (line 402) | async def is_hidden(self, selector: str, strict: bool = None) -> bool:
    method is_visible (line 407) | async def is_visible(self, selector: str, strict: bool = None) -> bool:
    method dispatch_event (line 412) | async def dispatch_event(
    method eval_on_selector (line 434) | async def eval_on_selector(
    method eval_on_selector_all (line 456) | async def eval_on_selector_all(
    method content (line 474) | async def content(self) -> str:
    method set_content (line 477) | async def set_content(
    method name (line 488) | def name(self) -> str:
    method url (line 492) | def url(self) -> str:
    method parent_frame (line 496) | def parent_frame(self) -> Optional["Frame"]:
    method child_frames (line 500) | def child_frames(self) -> List["Frame"]:
    method is_detached (line 503) | def is_detached(self) -> bool:
    method add_script_tag (line 506) | async def add_script_tag(
    method add_style_tag (line 521) | async def add_style_tag(
    method click (line 535) | async def click(
    method _click (line 551) | async def _click(
    method dblclick (line 568) | async def dblclick(
    method tap (line 585) | async def tap(
    method fill (line 598) | async def fill(
    method _fill (line 609) | async def _fill(
    method locator (line 621) | def locator(
    method get_by_alt_text (line 638) | def get_by_alt_text(
    method get_by_label (line 643) | def get_by_label(
    method get_by_placeholder (line 648) | def get_by_placeholder(
    method get_by_role (line 653) | def get_by_role(
    method get_by_test_id (line 681) | def get_by_test_id(self, testId: Union[str, Pattern[str]]) -> "Locator":
    method get_by_text (line 684) | def get_by_text(
    method get_by_title (line 689) | def get_by_title(
    method frame_locator (line 694) | def frame_locator(self, selector: str) -> FrameLocator:
    method focus (line 697) | async def focus(
    method text_content (line 702) | async def text_content(
    method inner_text (line 709) | async def inner_text(
    method inner_html (line 716) | async def inner_html(
    method get_attribute (line 723) | async def get_attribute(
    method hover (line 730) | async def hover(
    method drag_and_drop (line 743) | async def drag_and_drop(
    method select_option (line 760) | async def select_option(
    method input_value (line 783) | async def input_value(
    method set_input_files (line 793) | async def set_input_files(
    method type (line 815) | async def type(
    method press (line 826) | async def press(
    method check (line 837) | async def check(
    method uncheck (line 849) | async def uncheck(
    method wait_for_timeout (line 861) | async def wait_for_timeout(self, timeout: float) -> None:
    method wait_for_function (line 864) | async def wait_for_function(
    method title (line 881) | async def title(self) -> str:
    method set_checked (line 884) | async def set_checked(
    method _highlight (line 914) | async def _highlight(self, selector: str) -> None:

FILE: playwright/_impl/_glob.py
  function glob_to_regex_pattern (line 19) | def glob_to_regex_pattern(glob: str) -> str:

FILE: playwright/_impl/_greenlets.py
  function _greenlet_trace_callback (line 20) | def _greenlet_trace_callback(
  class MainGreenlet (line 32) | class MainGreenlet(greenlet.greenlet):
    method __str__ (line 33) | def __str__(self) -> str:
  class RouteGreenlet (line 37) | class RouteGreenlet(greenlet.greenlet):
    method __str__ (line 38) | def __str__(self) -> str:
  class LocatorHandlerGreenlet (line 42) | class LocatorHandlerGreenlet(greenlet.greenlet):
    method __str__ (line 43) | def __str__(self) -> str:
  class EventGreenlet (line 47) | class EventGreenlet(greenlet.greenlet):
    method __str__ (line 48) | def __str__(self) -> str:

FILE: playwright/_impl/_har_router.py
  class HarRouter (line 32) | class HarRouter:
    method __init__ (line 33) | def __init__(
    method create (line 46) | async def create(
    method _handle (line 60) | async def _handle(self, route: "Route") -> None:
    method add_context_route (line 107) | async def add_context_route(self, context: "BrowserContext") -> None:
    method add_page_route (line 113) | async def add_page_route(self, page: "Page") -> None:
    method dispose (line 119) | def dispose(self) -> None:

FILE: playwright/_impl/_helper.py
  class ErrorPayload (line 77) | class ErrorPayload(TypedDict, total=False):
  class HarRecordingMetadata (line 84) | class HarRecordingMetadata(TypedDict, total=False):
  function prepare_record_har_options (line 89) | def prepare_record_har_options(params: Dict) -> Dict[str, Any]:
  class ParsedMessageParams (line 118) | class ParsedMessageParams(TypedDict):
  class ParsedMessagePayload (line 124) | class ParsedMessagePayload(TypedDict, total=False):
  class Document (line 133) | class Document(TypedDict):
  class FrameNavigatedEvent (line 137) | class FrameNavigatedEvent(TypedDict):
  function url_matches (line 147) | def url_matches(
  function resolve_glob_to_regex_pattern (line 164) | def resolve_glob_to_regex_pattern(
  function to_websocket_base_url (line 173) | def to_websocket_base_url(base_url: Optional[str]) -> Optional[str]:
  function resolve_glob_base (line 179) | def resolve_glob_base(base_url: Optional[str], match: str) -> str:
  function resolve_base_url (line 240) | def resolve_base_url(
  function nodelike_urlparse (line 260) | def nodelike_urlparse(url: str) -> ParseResult:
  class HarLookupResult (line 274) | class HarLookupResult(TypedDict, total=False):
  class TimeoutSettings (line 288) | class TimeoutSettings:
    method launch_timeout (line 291) | def launch_timeout(timeout: Optional[float] = None) -> float:
    method __init__ (line 298) | def __init__(self, parent: Optional["TimeoutSettings"]) -> None:
    method set_default_timeout (line 303) | def set_default_timeout(self, timeout: Optional[float]) -> None:
    method timeout (line 306) | def timeout(self, timeout: float = None) -> float:
    method set_default_navigation_timeout (line 315) | def set_default_navigation_timeout(
    method default_navigation_timeout (line 320) | def default_navigation_timeout(self) -> Optional[float]:
    method default_timeout (line 323) | def default_timeout(self) -> Optional[float]:
    method navigation_timeout (line 326) | def navigation_timeout(self, timeout: float = None) -> float:
  function serialize_error (line 338) | def serialize_error(ex: Exception, tb: Optional[TracebackType]) -> Error...
  function parse_error (line 344) | def parse_error(error: ErrorPayload, log: Optional[str] = None) -> Error:
  function patch_error_message (line 358) | def patch_error_message(message: str) -> str:
  function locals_to_params (line 368) | def locals_to_params(args: Dict) -> Dict:
  function monotonic_time (line 382) | def monotonic_time() -> int:
  class RouteHandlerInvocation (line 386) | class RouteHandlerInvocation:
    method __init__ (line 390) | def __init__(self, complete: "asyncio.Future", route: "Route") -> None:
  class RouteHandler (line 395) | class RouteHandler:
    method __init__ (line 396) | def __init__(
    method matches (line 413) | def matches(self, request_url: str) -> bool:
    method handle (line 416) | async def handle(self, route: "Route") -> bool:
    method _handle_internal (line 440) | async def _handle_internal(self, route: "Route") -> bool:
    method stop (line 466) | async def stop(self, behavior: Literal["ignoreErrors", "wait"]) -> None:
    method will_expire (line 481) | def will_expire(self) -> bool:
    method prepare_interception_patterns (line 485) | def prepare_interception_patterns(
  function to_snake_case (line 510) | def to_snake_case(name: str) -> str:
  function make_dirs_for_file (line 514) | def make_dirs_for_file(path: Union[Path, str]) -> None:
  function async_writefile (line 520) | async def async_writefile(file: Union[str, Path], data: Union[str, bytes...
  function async_readfile (line 529) | async def async_readfile(file: Union[str, Path]) -> bytes:
  function to_impl (line 541) | def to_impl(obj: T) -> T:
  function object_to_array (line 547) | def object_to_array(obj: Optional[Dict]) -> Optional[List[NameValue]]:
  function is_file_payload (line 556) | def is_file_payload(value: Optional[Any]) -> bool:
  function is_textual_mime_type (line 570) | def is_textual_mime_type(mime_type: str) -> bool:

FILE: playwright/_impl/_impl_to_api_mapping.py
  class ImplWrapper (line 25) | class ImplWrapper:
    method __init__ (line 26) | def __init__(self, impl_obj: Any) -> None:
    method __repr__ (line 29) | def __repr__(self) -> str:
  class ImplToApiMapping (line 33) | class ImplToApiMapping:
    method __init__ (line 34) | def __init__(self) -> None:
    method register (line 37) | def register(self, impl_class: type, api_class: type) -> None:
    method from_maybe_impl (line 40) | def from_maybe_impl(
    method from_impl (line 75) | def from_impl(self, obj: Any) -> Any:
    method from_impl_nullable (line 81) | def from_impl_nullable(self, obj: Any = None) -> Optional[Any]:
    method from_impl_list (line 84) | def from_impl_list(self, items: Sequence[Any]) -> List[Any]:
    method from_impl_dict (line 87) | def from_impl_dict(self, map: Dict[str, Any]) -> Dict[str, Any]:
    method to_impl (line 90) | def to_impl(
    method wrap_handler (line 120) | def wrap_handler(self, handler: Callable[..., Any]) -> Callable[..., N...

FILE: playwright/_impl/_input.py
  class Keyboard (line 19) | class Keyboard:
    method __init__ (line 20) | def __init__(self, channel: Channel) -> None:
    method down (line 25) | async def down(self, key: str) -> None:
    method up (line 28) | async def up(self, key: str) -> None:
    method insert_text (line 31) | async def insert_text(self, text: str) -> None:
    method type (line 34) | async def type(self, text: str, delay: float = None) -> None:
    method press (line 37) | async def press(self, key: str, delay: float = None) -> None:
  class Mouse (line 41) | class Mouse:
    method __init__ (line 42) | def __init__(self, channel: Channel) -> None:
    method move (line 47) | async def move(self, x: float, y: float, steps: int = None) -> None:
    method down (line 50) | async def down(
    method up (line 57) | async def up(
    method _click (line 64) | async def _click(
    method click (line 77) | async def click(
    method dblclick (line 89) | async def dblclick(
    method wheel (line 100) | async def wheel(self, deltaX: float, deltaY: float) -> None:
  class Touchscreen (line 104) | class Touchscreen:
    method __init__ (line 105) | def __init__(self, channel: Channel) -> None:
    method tap (line 110) | async def tap(self, x: float, y: float) -> None:

FILE: playwright/_impl/_js_handle.py
  class VisitorInfo (line 36) | class VisitorInfo:
    method __init__ (line 40) | def __init__(self) -> None:
    method visit (line 44) | def visit(self, obj: Any) -> int:
  class JSHandle (line 51) | class JSHandle(ChannelOwner):
    method __init__ (line 52) | def __init__(
    method __repr__ (line 61) | def __repr__(self) -> str:
    method __str__ (line 64) | def __str__(self) -> str:
    method _on_preview_updated (line 67) | def _on_preview_updated(self, preview: str) -> None:
    method evaluate (line 70) | async def evaluate(self, expression: str, arg: Serializable = None) ->...
    method evaluate_handle (line 82) | async def evaluate_handle(
    method get_property (line 96) | async def get_property(self, propertyName: str) -> "JSHandle":
    method get_properties (line 101) | async def get_properties(self) -> Dict[str, "JSHandle"]:
    method as_element (line 110) | def as_element(self) -> Optional["ElementHandle"]:
    method dispose (line 113) | async def dispose(self) -> None:
    method json_value (line 123) | async def json_value(self) -> Any:
  function serialize_value (line 132) | def serialize_value(
  function serialize_argument (line 207) | def serialize_argument(arg: Serializable = None) -> Any:
  function parse_value (line 213) | def parse_value(value: Any, refs: Optional[Dict[int, Any]] = None) -> Any:
  function parse_result (line 331) | def parse_result(result: Any) -> Any:
  function add_source_url_to_script (line 335) | def add_source_url_to_script(source: str, path: Union[str, Path]) -> str:

FILE: playwright/_impl/_json_pipe.py
  class JsonPipeTransport (line 26) | class JsonPipeTransport(AsyncIOEventEmitter, Transport):
    method __init__ (line 27) | def __init__(
    method request_stop (line 37) | def request_stop(self) -> None:
    method dispose (line 41) | def dispose(self) -> None:
    method wait_until_stopped (line 45) | async def wait_until_stopped(self) -> None:
    method connect (line 48) | async def connect(self) -> None:
    method run (line 71) | async def run(self) -> None:
    method send (line 74) | def send(self, message: Dict) -> None:

FILE: playwright/_impl/_local_utils.py
  class LocalUtils (line 23) | class LocalUtils(ChannelOwner):
    method __init__ (line 24) | def __init__(
    method zip (line 33) | async def zip(self, params: Dict) -> None:
    method har_open (line 36) | async def har_open(self, file: str) -> None:
    method har_lookup (line 40) | async def har_lookup(
    method har_close (line 57) | async def har_close(self, harId: str) -> None:
    method har_unzip (line 61) | async def har_unzip(self, zipFile: str, harFile: str) -> None:
    method tracing_started (line 65) | async def tracing_started(self, tracesDir: Optional[str], traceName: s...
    method trace_discarded (line 69) | async def trace_discarded(self, stacks_id: str) -> None:
    method add_stack_to_tracing_no_reply (line 72) | def add_stack_to_tracing_no_reply(self, id: int, frames: List[StackFra...
  function parse_device_descriptor (line 85) | def parse_device_descriptor(dict: Dict) -> Dict:

FILE: playwright/_impl/_locator.py
  class Locator (line 65) | class Locator:
    method __init__ (line 66) | def __init__(
    method __repr__ (line 103) | def __repr__(self) -> str:
    method _with_element (line 106) | async def _with_element(
    method _equals (line 124) | def _equals(self, locator: "Locator") -> bool:
    method page (line 128) | def page(self) -> "Page":
    method bounding_box (line 131) | async def bounding_box(self, timeout: float = None) -> Optional[FloatR...
    method check (line 137) | async def check(
    method click (line 148) | async def click(
    method dblclick (line 164) | async def dblclick(
    method dispatch_event (line 179) | async def dispatch_event(
    method evaluate (line 188) | async def evaluate(
    method evaluate_all (line 196) | async def evaluate_all(self, expression: str, arg: Serializable = None...
    method evaluate_handle (line 200) | async def evaluate_handle(
    method fill (line 207) | async def fill(
    method clear (line 217) | async def clear(
    method locator (line 226) | def locator(
    method get_by_alt_text (line 255) | def get_by_alt_text(
    method get_by_label (line 260) | def get_by_label(
    method get_by_placeholder (line 265) | def get_by_placeholder(
    method get_by_role (line 270) | def get_by_role(
    method get_by_test_id (line 298) | def get_by_test_id(self, testId: Union[str, Pattern[str]]) -> "Locator":
    method get_by_text (line 301) | def get_by_text(
    method get_by_title (line 306) | def get_by_title(
    method frame_locator (line 311) | def frame_locator(self, selector: str) -> "FrameLocator":
    method element_handle (line 314) | async def element_handle(
    method element_handles (line 325) | async def element_handles(self) -> List[ElementHandle]:
    method first (line 329) | def first(self) -> "Locator":
    method last (line 333) | def last(self) -> "Locator":
    method nth (line 336) | def nth(self, index: int) -> "Locator":
    method content_frame (line 340) | def content_frame(self) -> "FrameLocator":
    method describe (line 343) | def describe(self, description: str) -> "Locator":
    method description (line 350) | def description(self) -> Optional[str]:
    method filter (line 363) | def filter(
    method or_ (line 381) | def or_(self, locator: "Locator") -> "Locator":
    method and_ (line 389) | def and_(self, locator: "Locator") -> "Locator":
    method focus (line 397) | async def focus(self, timeout: float = None) -> None:
    method blur (line 401) | async def blur(self, timeout: float = None) -> None:
    method all (line 412) | async def all(
    method count (line 420) | async def count(
    method drag_to (line 425) | async def drag_to(
    method get_attribute (line 442) | async def get_attribute(self, name: str, timeout: float = None) -> Opt...
    method hover (line 450) | async def hover(
    method inner_html (line 466) | async def inner_html(self, timeout: float = None) -> str:
    method inner_text (line 474) | async def inner_text(self, timeout: float = None) -> str:
    method input_value (line 482) | async def input_value(self, timeout: float = None) -> str:
    method is_checked (line 490) | async def is_checked(self, timeout: float = None) -> bool:
    method is_disabled (line 498) | async def is_disabled(self, timeout: float = None) -> bool:
    method is_editable (line 506) | async def is_editable(self, timeout: float = None) -> bool:
    method is_enabled (line 514) | async def is_enabled(self, timeout: float = None) -> bool:
    method is_hidden (line 522) | async def is_hidden(self, timeout: float = None) -> bool:
    method is_visible (line 529) | async def is_visible(self, timeout: float = None) -> bool:
    method press (line 536) | async def press(
    method screenshot (line 546) | async def screenshot(
    method aria_snapshot (line 567) | async def aria_snapshot(self, timeout: float = None) -> str:
    method scroll_into_view_if_needed (line 577) | async def scroll_into_view_if_needed(
    method select_option (line 586) | async def select_option(
    method select_text (line 603) | async def select_text(self, force: bool = None, timeout: float = None)...
    method set_input_files (line 610) | async def set_input_files(
    method tap (line 629) | async def tap(
    method text_content (line 645) | async def text_content(self, timeout: float = None) -> Optional[str]:
    method type (line 653) | async def type(
    method press_sequentially (line 667) | async def press_sequentially(
    method uncheck (line 676) | async def uncheck(
    method all_inner_texts (line 691) | async def all_inner_texts(
    method all_text_contents (line 698) | async def all_text_contents(
    method wait_for (line 705) | async def wait_for(
    method set_checked (line 714) | async def set_checked(
    method _expect (line 738) | async def _expect(
    method highlight (line 746) | async def highlight(self) -> None:
  class FrameLocator (line 750) | class FrameLocator:
    method __init__ (line 751) | def __init__(self, frame: "Frame", frame_selector: str) -> None:
    method locator (line 757) | def locator(
    method get_by_alt_text (line 786) | def get_by_alt_text(
    method get_by_label (line 791) | def get_by_label(
    method get_by_placeholder (line 796) | def get_by_placeholder(
    method get_by_role (line 801) | def get_by_role(
    method get_by_test_id (line 829) | def get_by_test_id(self, testId: Union[str, Pattern[str]]) -> "Locator":
    method get_by_text (line 832) | def get_by_text(
    method get_by_title (line 837) | def get_by_title(
    method frame_locator (line 842) | def frame_locator(self, selector: str) -> "FrameLocator":
    method first (line 849) | def first(self) -> "FrameLocator":
    method last (line 853) | def last(self) -> "FrameLocator":
    method owner (line 857) | def owner(self) -> "Locator":
    method nth (line 860) | def nth(self, index: int) -> "FrameLocator":
    method __repr__ (line 863) | def __repr__(self) -> str:
  function test_id_attribute_name (line 870) | def test_id_attribute_name() -> str:
  function set_test_id_attribute_name (line 874) | def set_test_id_attribute_name(attribute_name: str) -> None:
  function get_by_test_id_selector (line 879) | def get_by_test_id_selector(
  function get_by_attribute_text_selector (line 885) | def get_by_attribute_text_selector(
  function get_by_label_selector (line 891) | def get_by_label_selector(text: Union[str, Pattern[str]], exact: bool = ...
  function get_by_alt_text_selector (line 895) | def get_by_alt_text_selector(text: Union[str, Pattern[str]], exact: bool...
  function get_by_title_selector (line 899) | def get_by_title_selector(text: Union[str, Pattern[str]], exact: bool = ...
  function get_by_placeholder_selector (line 903) | def get_by_placeholder_selector(
  function get_by_text_selector (line 909) | def get_by_text_selector(text: Union[str, Pattern[str]], exact: bool = N...
  function bool_to_js_bool (line 913) | def bool_to_js_bool(value: bool) -> str:
  function get_by_role_selector (line 917) | def get_by_role_selector(

FILE: playwright/_impl/_map.py
  class Map (line 20) | class Map(Generic[K, V]):
    method __init__ (line 21) | def __init__(self) -> None:
    method __contains__ (line 24) | def __contains__(self, item: K) -> bool:
    method __setitem__ (line 27) | def __setitem__(self, idx: K, value: V) -> None:
    method __getitem__ (line 30) | def __getitem__(self, obj: K) -> V:

FILE: playwright/_impl/_network.py
  class FallbackOverrideParameters (line 72) | class FallbackOverrideParameters(TypedDict, total=False):
  class SerializedFallbackOverrides (line 79) | class SerializedFallbackOverrides:
    method __init__ (line 80) | def __init__(self) -> None:
  function serialize_headers (line 87) | def serialize_headers(headers: Dict[str, str]) -> HeadersArray:
  function to_client_certificates_protocol (line 95) | async def to_client_certificates_protocol(
  class Request (line 129) | class Request(ChannelOwner):
    method __init__ (line 130) | def __init__(
    method __repr__ (line 158) | def __repr__(self) -> str:
    method _apply_fallback_overrides (line 161) | def _apply_fallback_overrides(self, overrides: FallbackOverrideParamet...
    method url (line 180) | def url(self) -> str:
    method resource_type (line 184) | def resource_type(self) -> str:
    method service_worker (line 188) | def service_worker(self) -> Optional["Worker"]:
    method method (line 195) | def method(self) -> str:
    method sizes (line 198) | async def sizes(self) -> RequestSizes:
    method post_data (line 208) | def post_data(self) -> Optional[str]:
    method post_data_json (line 218) | def post_data_json(self) -> Optional[Any]:
    method post_data_buffer (line 231) | def post_data_buffer(self) -> Optional[bytes]:
    method response (line 238) | async def response(self) -> Optional["Response"]:
    method frame (line 247) | def frame(self) -> "Frame":
    method is_navigation_request (line 263) | def is_navigation_request(self) -> bool:
    method redirected_from (line 267) | def redirected_from(self) -> Optional["Request"]:
    method redirected_to (line 271) | def redirected_to(self) -> Optional["Request"]:
    method failure (line 275) | def failure(self) -> Optional[str]:
    method timing (line 279) | def timing(self) -> ResourceTiming:
    method _set_response_end_timing (line 282) | def _set_response_end_timing(self, response_end_timing: float) -> None:
    method headers (line 288) | def headers(self) -> Headers:
    method all_headers (line 294) | async def all_headers(self) -> Headers:
    method headers_array (line 297) | async def headers_array(self) -> HeadersArray:
    method header_value (line 300) | async def header_value(self, name: str) -> Optional[str]:
    method _actual_headers (line 303) | async def _actual_headers(self) -> "RawHeaders":
    method _target_closed_future (line 315) | def _target_closed_future(self) -> asyncio.Future:
    method _safe_page (line 326) | def _safe_page(self) -> "Optional[Page]":
  class Route (line 333) | class Route(ChannelOwner):
    method __init__ (line 334) | def __init__(
    method _start_handling (line 342) | def _start_handling(self) -> "asyncio.Future[bool]":
    method _report_handled (line 346) | def _report_handled(self, done: bool) -> None:
    method _check_not_handled (line 352) | def _check_not_handled(self) -> None:
    method __repr__ (line 356) | def __repr__(self) -> str:
    method request (line 360) | def request(self) -> Request:
    method abort (line 363) | async def abort(self, errorCode: str = None) -> None:
    method fulfill (line 376) | async def fulfill(
    method _inner_fulfill (line 392) | async def _inner_fulfill(
    method _handle_route (line 456) | async def _handle_route(self, callback: Callable) -> None:
    method fetch (line 465) | async def fetch(
    method fallback (line 488) | async def fallback(
    method continue_ (line 500) | async def continue_(
    method _inner_continue (line 515) | async def _inner_continue(self, is_fallback: bool = False) -> None:
    method _redirected_navigation_request (line 537) | async def _redirected_navigation_request(self, url: str) -> None:
    method _race_with_page_close (line 544) | async def _race_with_page_close(self, future: Coroutine) -> None:
  function _create_task_and_ignore_exception (line 563) | def _create_task_and_ignore_exception(
  class ServerWebSocketRoute (line 575) | class ServerWebSocketRoute:
    method __init__ (line 576) | def __init__(self, ws: "WebSocketRoute"):
    method on_message (line 579) | def on_message(self, handler: Callable[[Union[str, bytes]], Any]) -> N...
    method on_close (line 582) | def on_close(self, handler: Callable[[Optional[int], Optional[str]], A...
    method connect_to_server (line 585) | def connect_to_server(self) -> None:
    method url (line 591) | def url(self) -> str:
    method close (line 594) | def close(self, code: int = None, reason: str = None) -> None:
    method send (line 608) | def send(self, message: Union[str, bytes]) -> None:
  class WebSocketRoute (line 627) | class WebSocketRoute(ChannelOwner):
    method __init__ (line 628) | def __init__(
    method _channel_message_from_page (line 648) | def _channel_message_from_page(self, event: Dict) -> None:
    method _channel_message_from_server (line 660) | def _channel_message_from_server(self, event: Dict) -> None:
    method _channel_close_page (line 672) | def _channel_close_page(self, event: Dict) -> None:
    method _channel_close_server (line 680) | def _channel_close_server(self, event: Dict) -> None:
    method url (line 689) | def url(self) -> str:
    method close (line 692) | async def close(self, code: int = None, reason: str = None) -> None:
    method connect_to_server (line 700) | def connect_to_server(self) -> "WebSocketRoute":
    method send (line 712) | def send(self, message: Union[str, bytes]) -> None:
    method on_message (line 733) | def on_message(self, handler: Callable[[Union[str, bytes]], Any]) -> N...
    method on_close (line 736) | def on_close(self, handler: Callable[[Optional[int], Optional[str]], A...
    method _after_handle (line 739) | async def _after_handle(self) -> None:
  class WebSocketRouteHandler (line 752) | class WebSocketRouteHandler:
    method __init__ (line 753) | def __init__(
    method prepare_interception_patterns (line 764) | def prepare_interception_patterns(
    method matches (line 786) | def matches(self, ws_url: str) -> bool:
    method handle (line 789) | async def handle(self, websocket_route: "WebSocketRoute") -> None:
  class Response (line 796) | class Response(ChannelOwner):
    method __init__ (line 797) | def __init__(
    method __repr__ (line 817) | def __repr__(self) -> str:
    method url (line 821) | def url(self) -> str:
    method ok (line 825) | def ok(self) -> bool:
    method status (line 832) | def status(self) -> int:
    method status_text (line 836) | def status_text(self) -> str:
    method headers (line 840) | def headers(self) -> Headers:
    method from_service_worker (line 844) | def from_service_worker(self) -> bool:
    method all_headers (line 847) | async def all_headers(self) -> Headers:
    method headers_array (line 850) | async def headers_array(self) -> HeadersArray:
    method header_value (line 853) | async def header_value(self, name: str) -> Optional[str]:
    method header_values (line 856) | async def header_values(self, name: str) -> List[str]:
    method _actual_headers (line 859) | async def _actual_headers(self) -> "RawHeaders":
    method server_addr (line 872) | async def server_addr(self) -> Optional[RemoteAddr]:
    method security_details (line 878) | async def security_details(self) -> Optional[SecurityDetails]:
    method finished (line 884) | async def finished(self) -> None:
    method body (line 900) | async def body(self) -> bytes:
    method text (line 907) | async def text(self) -> str:
    method json (line 911) | async def json(self) -> Any:
    method request (line 915) | def request(self) -> Request:
    method frame (line 919) | def frame(self) -> "Frame":
  class WebSocket (line 923) | class WebSocket(ChannelOwner):
    method __init__ (line 931) | def __init__(
    method __repr__ (line 951) | def __repr__(self) -> str:
    method url (line 955) | def url(self) -> str:
    method expect_event (line 958) | def expect_event(
    method wait_for_event (line 981) | async def wait_for_event(
    method _on_frame_sent (line 988) | def _on_frame_sent(self, opcode: int, data: str) -> None:
    method _on_frame_received (line 994) | def _on_frame_received(self, opcode: int, data: str) -> None:
    method is_closed (line 1000) | def is_closed(self) -> bool:
    method _on_close (line 1003) | def _on_close(self) -> None:
  class RawHeaders (line 1008) | class RawHeaders:
    method __init__ (line 1009) | def __init__(self, headers: HeadersArray) -> None:
    method _from_headers_dict_lossy (line 1016) | def _from_headers_dict_lossy(headers: Dict[str, str]) -> "RawHeaders":
    method get (line 1019) | def get(self, name: str) -> Optional[str]:
    method get_all (line 1026) | def get_all(self, name: str) -> List[str]:
    method headers (line 1029) | def headers(self) -> Dict[str, str]:
    method headers_array (line 1035) | def headers_array(self) -> HeadersArray:

FILE: playwright/_impl/_object_factory.py
  class DummyObject (line 43) | class DummyObject(ChannelOwner):
    method __init__ (line 44) | def __init__(
  function create_remote_object (line 50) | def create_remote_object(

FILE: playwright/_impl/_page.py
  class LocatorHandler (line 111) | class LocatorHandler:
    method __init__ (line 116) | def __init__(
    method __call__ (line 123) | def __call__(self) -> Any:
  class Page (line 130) | class Page(ChannelOwner):
    method __init__ (line 156) | def __init__(
    method __repr__ (line 270) | def __repr__(self) -> str:
    method _on_frame_attached (line 273) | def _on_frame_attached(self, frame: Frame) -> None:
    method _on_frame_detached (line 278) | def _on_frame_detached(self, frame: Frame) -> None:
    method _on_route (line 283) | async def _on_route(self, route: Route) -> None:
    method _on_web_socket_route (line 316) | async def _on_web_socket_route(self, web_socket_route: WebSocketRoute)...
    method _on_binding (line 330) | def _on_binding(self, binding_call: "BindingCall") -> None:
    method _on_worker (line 336) | def _on_worker(self, worker: "Worker") -> None:
    method _on_close (line 341) | def _on_close(self) -> None:
    method _on_crash (line 348) | def _on_crash(self) -> None:
    method _on_download (line 351) | def _on_download(self, params: Any) -> None:
    method _on_video (line 359) | def _on_video(self, params: Any) -> None:
    method _on_viewport_size_changed (line 363) | def _on_viewport_size_changed(self, params: Any) -> None:
    method context (line 367) | def context(self) -> "BrowserContext":
    method clock (line 371) | def clock(self) -> Clock:
    method opener (line 374) | async def opener(self) -> Optional["Page"]:
    method main_frame (line 380) | def main_frame(self) -> Frame:
    method frame (line 383) | def frame(self, name: str = None, url: URLMatch = None) -> Optional[Fr...
    method frames (line 393) | def frames(self) -> List[Frame]:
    method set_default_navigation_timeout (line 396) | def set_default_navigation_timeout(self, timeout: float) -> None:
    method set_default_timeout (line 399) | def set_default_timeout(self, timeout: float) -> None:
    method query_selector (line 402) | async def query_selector(
    method query_selector_all (line 409) | async def query_selector_all(self, selector: str) -> List[ElementHandle]:
    method wait_for_selector (line 412) | async def wait_for_selector(
    method is_checked (line 421) | async def is_checked(
    method is_disabled (line 426) | async def is_disabled(
    method is_editable (line 431) | async def is_editable(
    method is_enabled (line 436) | async def is_enabled(
    method is_hidden (line 441) | async def is_hidden(
    method is_visible (line 447) | async def is_visible(
    method dispatch_event (line 453) | async def dispatch_event(
    method evaluate (line 463) | async def evaluate(self, expression: str, arg: Serializable = None) ->...
    method evaluate_handle (line 466) | async def evaluate_handle(
    method eval_on_selector (line 471) | async def eval_on_selector(
    method eval_on_selector_all (line 482) | async def eval_on_selector_all(
    method add_script_tag (line 490) | async def add_script_tag(
    method add_style_tag (line 499) | async def add_style_tag(
    method expose_function (line 504) | async def expose_function(self, name: str, callback: Callable) -> None:
    method expose_binding (line 507) | async def expose_binding(
    method set_extra_http_headers (line 523) | async def set_extra_http_headers(self, headers: Dict[str, str]) -> None:
    method url (line 531) | def url(self) -> str:
    method content (line 534) | async def content(self) -> str:
    method set_content (line 537) | async def set_content(
    method goto (line 545) | async def goto(
    method reload (line 554) | async def reload(
    method wait_for_load_state (line 567) | async def wait_for_load_state(
    method wait_for_url (line 574) | async def wait_for_url(
    method wait_for_event (line 582) | async def wait_for_event(
    method go_back (line 589) | async def go_back(
    method go_forward (line 602) | async def go_forward(
    method request_gc (line 615) | async def request_gc(self) -> None:
    method emulate_media (line 618) | async def emulate_media(
    method set_viewport_size (line 647) | async def set_viewport_size(self, viewportSize: ViewportSize) -> None:
    method viewport_size (line 656) | def viewport_size(self) -> Optional[ViewportSize]:
    method bring_to_front (line 659) | async def bring_to_front(self) -> None:
    method add_init_script (line 662) | async def add_init_script(
    method route (line 673) | async def route(
    method unroute (line 688) | async def unroute(
    method _unroute_internal (line 700) | async def _unroute_internal(
    method route_web_socket (line 716) | async def route_web_socket(
    method _dispose_har_routers (line 725) | def _dispose_har_routers(self) -> None:
    method unroute_all (line 730) | async def unroute_all(
    method route_from_har (line 736) | async def route_from_har(
    method _update_interception_patterns (line 763) | async def _update_interception_patterns(self) -> None:
    method _update_web_socket_interception_patterns (line 771) | async def _update_web_socket_interception_patterns(self) -> None:
    method screenshot (line 781) | async def screenshot(
    method title (line 823) | async def title(self) -> str:
    method close (line 826) | async def close(self, runBeforeUnload: bool = None, reason: str = None...
    method is_closed (line 837) | def is_closed(self) -> bool:
    method click (line 840) | async def click(
    method dblclick (line 856) | async def dblclick(
    method tap (line 871) | async def tap(
    method fill (line 884) | async def fill(
    method locator (line 895) | def locator(
    method get_by_alt_text (line 911) | def get_by_alt_text(
    method get_by_label (line 916) | def get_by_label(
    method get_by_placeholder (line 921) | def get_by_placeholder(
    method get_by_role (line 926) | def get_by_role(
    method get_by_test_id (line 952) | def get_by_test_id(self, testId: Union[str, Pattern[str]]) -> "Locator":
    method get_by_text (line 955) | def get_by_text(
    method get_by_title (line 960) | def get_by_title(
    method frame_locator (line 965) | def frame_locator(self, selector: str) -> "FrameLocator":
    method focus (line 968) | async def focus(
    method text_content (line 973) | async def text_content(
    method inner_text (line 978) | async def inner_text(
    method inner_html (line 983) | async def inner_html(
    method get_attribute (line 988) | async def get_attribute(
    method hover (line 993) | async def hover(
    method drag_and_drop (line 1006) | async def drag_and_drop(
    method select_option (line 1021) | async def select_option(
    method input_value (line 1036) | async def input_value(
    method set_input_files (line 1042) | async def set_input_files(
    method type (line 1054) | async def type(
    method press (line 1065) | async def press(
    method check (line 1076) | async def check(
    method uncheck (line 1088) | async def uncheck(
    method wait_for_timeout (line 1100) | async def wait_for_timeout(self, timeout: float) -> None:
    method wait_for_function (line 1103) | async def wait_for_function(
    method workers (line 1113) | def workers(self) -> List["Worker"]:
    method request (line 1117) | def request(self) -> "APIRequestContext":
    method pause (line 1120) | async def pause(self) -> None:
    method pdf (line 1143) | async def pdf(
    method _force_video (line 1171) | def _force_video(self) -> Video:
    method video (line 1177) | def video(
    method _close_error_with_reason (line 1187) | def _close_error_with_reason(self) -> TargetClosedError:
    method expect_event (line 1192) | def expect_event(
    method _expect_event (line 1202) | def _expect_event(
    method expect_console_message (line 1226) | def expect_console_message(
    method expect_download (line 1233) | def expect_download(
    method expect_file_chooser (line 1240) | def expect_file_chooser(
    method expect_navigation (line 1247) | def expect_navigation(
    method expect_popup (line 1255) | def expect_popup(
    method expect_request (line 1262) | def expect_request(
    method expect_request_finished (line 1285) | def expect_request_finished(
    method expect_response (line 1294) | def expect_response(
    method expect_websocket (line 1317) | def expect_websocket(
    method expect_worker (line 1324) | def expect_worker(
    method set_checked (line 1331) | async def set_checked(
    method add_locator_handler (line 1361) | async def add_locator_handler(
    method _on_locator_handler_triggered (line 1384) | async def _on_locator_handler_triggered(self, uid: str) -> None:
    method remove_locator_handler (line 1424) | async def remove_locator_handler(self, locator: "Locator") -> None:
    method requests (line 1434) | async def requests(self) -> List[Request]:
    method console_messages (line 1438) | async def console_messages(self) -> List[ConsoleMessage]:
    method page_errors (line 1447) | async def page_errors(self) -> List[Error]:
  class Worker (line 1452) | class Worker(ChannelOwner):
    method __init__ (line 1455) | def __init__(
    method __repr__ (line 1464) | def __repr__(self) -> str:
    method _on_close (line 1467) | def _on_close(self) -> None:
    method url (line 1475) | def url(self) -> str:
    method evaluate (line 1478) | async def evaluate(self, expression: str, arg: Serializable = None) ->...
    method evaluate_handle (line 1490) | async def evaluate_handle(
    method expect_event (line 1504) | def expect_event(
  class BindingCall (line 1530) | class BindingCall(ChannelOwner):
    method __init__ (line 1531) | def __init__(
    method call (line 1536) | async def call(self, func: Callable) -> None:
  function trim_url (line 1559) | def trim_url(param: Union[URLMatchRequest, URLMatchResponse]) -> Optiona...
  function trim_end (line 1567) | def trim_end(s: str) -> str:

FILE: playwright/_impl/_path_utils.py
  function get_file_dirname (line 21) | def get_file_dirname() -> Path:

FILE: playwright/_impl/_playwright.py
  class Playwright (line 23) | class Playwright(ChannelOwner):
    method __init__ (line 31) | def __init__(
    method __getitem__ (line 47) | def __getitem__(self, value: str) -> "BrowserType":
    method _set_selectors (line 56) | def _set_selectors(self, selectors: Selectors) -> None:
    method stop (line 59) | async def stop(self) -> None:

FILE: playwright/_impl/_selectors.py
  class Selectors (line 25) | class Selectors:
    method __init__ (line 26) | def __init__(self, loop: asyncio.AbstractEventLoop, dispatcher_fiber: ...
    method register (line 33) | async def register(
    method set_test_id_attribute (line 59) | def set_test_id_attribute(self, attributeName: str) -> None:

FILE: playwright/_impl/_set_input_files_helpers.py
  class InputFilesList (line 43) | class InputFilesList(TypedDict, total=False):
  function _list_files (line 51) | def _list_files(directory: str) -> List[str]:
  function convert_input_files (line 59) | async def convert_input_files(
  function resolve_paths_and_directory_for_input_files (line 142) | def resolve_paths_and_directory_for_input_files(

FILE: playwright/_impl/_str_utils.py
  function escape_regex_flags (line 20) | def escape_regex_flags(pattern: Pattern) -> str:
  function escape_for_regex (line 38) | def escape_for_regex(text: str) -> str:
  function escape_regex_for_selector (line 42) | def escape_regex_for_selector(text: Pattern) -> str:
  function escape_for_text_selector (line 54) | def escape_for_text_selector(
  function escape_for_attribute_selector (line 62) | def escape_for_attribute_selector(

FILE: playwright/_impl/_stream.py
  class Stream (line 22) | class Stream(ChannelOwner):
    method __init__ (line 23) | def __init__(
    method save_as (line 28) | async def save_as(self, path: Union[str, Path]) -> None:
    method read_all (line 39) | async def read_all(self) -> bytes:

FILE: playwright/_impl/_sync_base.py
  class EventInfo (line 45) | class EventInfo(Generic[T]):
    method __init__ (line 46) | def __init__(self, sync_base: "SyncBase", future: "asyncio.Future[T]")...
    method value (line 53) | def value(self) -> T:
    method _cancel (line 62) | def _cancel(self) -> None:
    method is_done (line 65) | def is_done(self) -> bool:
  class EventContextManager (line 69) | class EventContextManager(Generic[T], AbstractContextManager):
    method __init__ (line 70) | def __init__(self, sync_base: "SyncBase", future: "asyncio.Future[T]")...
    method __enter__ (line 73) | def __enter__(self) -> EventInfo[T]:
    method __exit__ (line 76) | def __exit__(
  class SyncBase (line 88) | class SyncBase(ImplWrapper):
    method __init__ (line 89) | def __init__(self, impl_obj: Any) -> None:
    method __str__ (line 94) | def __str__(self) -> str:
    method _sync (line 97) | def _sync(
    method _wrap_handler (line 117) | def _wrap_handler(
    method on (line 124) | def on(self, event: Any, f: Any) -> None:
    method once (line 128) | def once(self, event: Any, f: Any) -> None:
    method remove_listener (line 134) | def remove_listener(self, event: Any, f: Any) -> None:
  class SyncContextManager (line 139) | class SyncContextManager(SyncBase):
    method __enter__ (line 140) | def __enter__(self: Self) -> Self:
    method __exit__ (line 143) | def __exit__(
    method close (line 151) | def close(self) -> None: ...

FILE: playwright/_impl/_tracing.py
  class Tracing (line 24) | class Tracing(ChannelOwner):
    method __init__ (line 25) | def __init__(
    method start (line 34) | async def start(
    method start_chunk (line 51) | async def start_chunk(self, title: str = None, name: str = None) -> None:
    method _start_collecting_stacks (line 56) | async def _start_collecting_stacks(self, trace_name: str) -> None:
    method stop_chunk (line 64) | async def stop_chunk(self, path: Union[pathlib.Path, str] = None) -> N...
    method stop (line 67) | async def stop(self, path: Union[pathlib.Path, str] = None) -> None:
    method _do_stop_chunk (line 74) | async def _do_stop_chunk(self, file_path: Union[pathlib.Path, str] = N...
    method _reset_stack_counter (line 134) | def _reset_stack_counter(self) -> None:
    method group (line 139) | async def group(self, name: str, location: TracingGroupLocation = None...
    method group_end (line 142) | async def group_end(self) -> None:

FILE: playwright/_impl/_transport.py
  function _get_stderr_fileno (line 29) | def _get_stderr_fileno() -> Optional[int]:
  class Transport (line 48) | class Transport(ABC):
    method __init__ (line 49) | def __init__(self, loop: asyncio.AbstractEventLoop) -> None:
    method request_stop (line 55) | def request_stop(self) -> None:
    method dispose (line 58) | def dispose(self) -> None:
    method wait_until_stopped (line 62) | async def wait_until_stopped(self) -> None:
    method connect (line 66) | async def connect(self) -> None:
    method run (line 70) | async def run(self) -> None:
    method send (line 74) | def send(self, message: Dict) -> None:
    method serialize_message (line 77) | def serialize_message(self, message: Dict) -> bytes:
    method deserialize_message (line 83) | def deserialize_message(self, data: Union[str, bytes]) -> ParsedMessag...
  class PipeTransport (line 91) | class PipeTransport(Transport):
    method __init__ (line 92) | def __init__(self, loop: asyncio.AbstractEventLoop) -> None:
    method request_stop (line 96) | def request_stop(self) -> None:
    method wait_until_stopped (line 101) | async def wait_until_stopped(self) -> None:
    method connect (line 104) | async def connect(self) -> None:
    method run (line 137) | async def run(self) -> None:
    method send (line 173) | def send(self, message: Dict) -> None:

FILE: playwright/_impl/_video.py
  class Video (line 25) | class Video:
    method __init__ (line 26) | def __init__(self, page: "Page") -> None:
    method __repr__ (line 36) | def __repr__(self) -> str:
    method _page_closed (line 39) | def _page_closed(self) -> None:
    method _artifact_ready (line 43) | def _artifact_ready(self, artifact: Artifact) -> None:
    method path (line 47) | async def path(self) -> pathlib.Path:
    method save_as (line 57) | async def save_as(self, path: Union[str, pathlib.Path]) -> None:
    method delete (line 67) | async def delete(self) -> None:

FILE: playwright/_impl/_waiter.py
  class Waiter (line 27) | class Waiter:
    method __init__ (line 28) | def __init__(self, channel_owner: ChannelOwner, event: str) -> None:
    method _wait_for_event_info_before (line 38) | def _wait_for_event_info_before(self, wait_id: str, event: str) -> None:
    method _wait_for_event_info_after (line 51) | def _wait_for_event_info_after(self, wait_id: str, error: Exception = ...
    method reject_on_event (line 67) | def reject_on_event(
    method reject_on_timeout (line 81) | def reject_on_timeout(self, timeout: float, message: str) -> None:
    method _cleanup (line 91) | def _cleanup(self) -> None:
    method _fulfill (line 98) | def _fulfill(self, result: Any) -> None:
    method _reject (line 104) | def _reject(self, exception: Exception) -> None:
    method wait_for_event (line 113) | def wait_for_event(
    method result (line 126) | def result(self) -> asyncio.Future:
    method log (line 129) | def log(self, message: str) -> None:
  function throw_on_timeout (line 150) | def throw_on_timeout(timeout: float, exception: Exception) -> asyncio.Task:
  function format_log_recording (line 158) | def format_log_recording(log: List[str]) -> str:

FILE: playwright/_impl/_web_error.py
  class WebError (line 22) | class WebError:
    method __init__ (line 23) | def __init__(
    method page (line 36) | def page(self) -> Optional[Page]:
    method error (line 40) | def error(self) -> Error:

FILE: playwright/_impl/_writable_stream.py
  class WritableStream (line 27) | class WritableStream(ChannelOwner):
    method __init__ (line 28) | def __init__(
    method copy (line 33) | async def copy(self, path: Union[str, Path]) -> None:

FILE: playwright/async_api/__init__.py
  function async_playwright (line 88) | def async_playwright() -> PlaywrightContextManager:
  class Expect (line 92) | class Expect:
    method __init__ (line 95) | def __init__(self) -> None:
    method set_options (line 98) | def set_options(self, timeout: Optional[float] = _unset) -> None:
    method __call__ (line 112) | def __call__(
    method __call__ (line 117) | def __call__(
    method __call__ (line 122) | def __call__(
    method __call__ (line 126) | def __call__(

FILE: playwright/async_api/_context_manager.py
  class PlaywrightContextManager (line 24) | class PlaywrightContextManager:
    method __init__ (line 25) | def __init__(self) -> None:
    method __aenter__ (line 29) | async def __aenter__(self) -> AsyncPlaywright:
    method start (line 50) | async def start(self) -> AsyncPlaywright:
    method __aexit__ (line 53) | async def __aexit__(self, *args: Any) -> None:

FILE: playwright/async_api/_generated.py
  class Request (line 88) | class Request(AsyncBase):
    method url (line 91) | def url(self) -> str:
    method resource_type (line 103) | def resource_type(self) -> str:
    method service_worker (line 117) | def service_worker(self) -> typing.Optional["Worker"]:
    method method (line 135) | def method(self) -> str:
    method post_data (line 147) | def post_data(self) -> typing.Optional[str]:
    method post_data_json (line 159) | def post_data_json(self) -> typing.Optional[typing.Any]:
    method post_data_buffer (line 174) | def post_data_buffer(self) -> typing.Optional[bytes]:
    method frame (line 186) | def frame(self) -> "Frame":
    method redirected_from (line 213) | def redirected_from(self) -> typing.Optional["Request"]:
    method redirected_to (line 245) | def redirected_to(self) -> typing.Optional["Request"]:
    method failure (line 265) | def failure(self) -> typing.Optional[str]:
    method timing (line 285) | def timing(self) -> ResourceTiming:
    method headers (line 308) | def headers(self) -> typing.Dict[str, str]:
    method sizes (line 321) | async def sizes(self) -> RequestSizes:
    method response (line 333) | async def response(self) -> typing.Optional["Response"]:
    method is_navigation_request (line 345) | def is_navigation_request(self) -> bool:
    method all_headers (line 360) | async def all_headers(self) -> typing.Dict[str, str]:
    method headers_array (line 372) | async def headers_array(self) -> typing.List[NameValue]:
    method header_value (line 386) | async def header_value(self, name: str) -> typing.Optional[str]:
  class Response (line 407) | class Response(AsyncBase):
    method url (line 410) | def url(self) -> str:
    method ok (line 422) | def ok(self) -> bool:
    method status (line 434) | def status(self) -> int:
    method status_text (line 446) | def status_text(self) -> str:
    method headers (line 458) | def headers(self) -> typing.Dict[str, str]:
    method from_service_worker (line 472) | def from_service_worker(self) -> bool:
    method request (line 485) | def request(self) -> "Request":
    method frame (line 497) | def frame(self) -> "Frame":
    method all_headers (line 508) | async def all_headers(self) -> typing.Dict[str, str]:
    method headers_array (line 520) | async def headers_array(self) -> typing.List[NameValue]:
    method header_value (line 534) | async def header_value(self, name: str) -> typing.Optional[str]:
    method header_values (line 553) | async def header_values(self, name: str) -> typing.List[str]:
    method server_addr (line 570) | async def server_addr(self) -> typing.Optional[RemoteAddr]:
    method security_details (line 582) | async def security_details(self) -> typing.Optional[SecurityDetails]:
    method finished (line 594) | async def finished(self) -> None:
    method body (line 602) | async def body(self) -> bytes:
    method text (line 614) | async def text(self) -> str:
    method json (line 626) | async def json(self) -> typing.Any:
  class Route (line 644) | class Route(AsyncBase):
    method request (line 647) | def request(self) -> "Request":
    method abort (line 658) | async def abort(self, error_code: typing.Optional[str] = None) -> None:
    method fulfill (line 687) | async def fulfill(
    method fetch (line 751) | async def fetch(
    method fallback (line 823) | async def fallback(
    method continue_ (line 914) | async def continue_(
  class WebSocket (line 981) | class WebSocket(AsyncBase):
    method on (line 984) | def on(
    method on (line 993) | def on(
    method on (line 1004) | def on(
    method on (line 1015) | def on(
    method on (line 1023) | def on(
    method once (line 1031) | def once(
    method once (line 1040) | def once(
    method once (line 1051) | def once(
    method once (line 1062) | def once(
    method once (line 1070) | def once(
    method url (line 1078) | def url(self) -> str:
    method expect_event (line 1089) | def expect_event(
    method wait_for_event (line 1122) | async def wait_for_event(
    method is_closed (line 1158) | def is_closed(self) -> bool:
  class WebSocketRoute (line 1174) | class WebSocketRoute(AsyncBase):
    method url (line 1177) | def url(self) -> str:
    method close (line 1188) | async def close(
    method connect_to_server (line 1207) | def connect_to_server(self) -> "WebSocketRoute":
    method send (line 1230) | def send(self, message: typing.Union[str, bytes]) -> None:
    method on_message (line 1245) | def on_message(
    method on_close (line 1271) | def on_close(
  class Keyboard (line 1301) | class Keyboard(AsyncBase):
    method down (line 1303) | async def down(self, key: str) -> None:
    method up (line 1342) | async def up(self, key: str) -> None:
    method insert_text (line 1355) | async def insert_text(self, text: str) -> None:
    method type (line 1377) | async def type(self, text: str, *, delay: typing.Optional[float] = Non...
    method press (line 1410) | async def press(self, key: str, *, delay: typing.Optional[float] = Non...
  class Mouse (line 1465) | class Mouse(AsyncBase):
    method move (line 1467) | async def move(
    method down (line 1487) | async def down(
    method up (line 1509) | async def up(
    method click (line 1531) | async def click(
    method dblclick (line 1564) | async def dblclick(
    method wheel (line 1593) | async def wheel(self, delta_x: float, delta_y: float) -> None:
  class Touchscreen (line 1618) | class Touchscreen(AsyncBase):
    method tap (line 1620) | async def tap(self, x: float, y: float) -> None:
  class JSHandle (line 1641) | class JSHandle(AsyncBase):
    method evaluate (line 1643) | async def evaluate(
    method evaluate_handle (line 1681) | async def evaluate_handle(
    method get_property (line 1717) | async def get_property(self, property_name: str) -> "JSHandle":
    method get_properties (line 1736) | async def get_properties(self) -> typing.Dict[str, "JSHandle"]:
    method as_element (line 1758) | def as_element(self) -> typing.Optional["ElementHandle"]:
    method dispose (line 1770) | async def dispose(self) -> None:
    method json_value (line 1778) | async def json_value(self) -> typing.Any:
  class ElementHandle (line 1797) | class ElementHandle(JSHandle):
    method as_element (line 1799) | def as_element(self) -> typing.Optional["ElementHandle"]:
    method owner_frame (line 1811) | async def owner_frame(self) -> typing.Optional["Frame"]:
    method content_frame (line 1823) | async def content_frame(self) -> typing.Optional["Frame"]:
    method get_attribute (line 1835) | async def get_attribute(self, name: str) -> typing.Optional[str]:
    method text_content (line 1852) | async def text_content(self) -> typing.Optional[str]:
    method inner_text (line 1864) | async def inner_text(self) -> str:
    method inner_html (line 1876) | async def inner_html(self) -> str:
    method is_checked (line 1888) | async def is_checked(self) -> bool:
    method is_disabled (line 1900) | async def is_disabled(self) -> bool:
    method is_editable (line 1912) | async def is_editable(self) -> bool:
    method is_enabled (line 1924) | async def is_enabled(self) -> bool:
    method is_hidden (line 1936) | async def is_hidden(self) -> bool:
    method is_visible (line 1948) | async def is_visible(self) -> bool:
    method dispatch_event (line 1960) | async def dispatch_event(
    method scroll_into_view_if_needed (line 2012) | async def scroll_into_view_if_needed(
    method hover (line 2037) | async def hover(
    method click (line 2094) | async def click(
    method dblclick (line 2171) | async def dblclick(
    method select_option (line 2243) | async def select_option(
    method tap (line 2319) | async def tap(
    method fill (line 2378) | async def fill(
    method select_text (line 2418) | async def select_text(
    method input_value (line 2446) | async def input_value(self, *, timeout: typing.Optional[float] = None)...
    method set_input_files (line 2470) | async def set_input_files(
    method focus (line 2511) | async def focus(self) -> None:
    method type (line 2519) | async def type(
    method press (line 2556) | async def press(
    method set_checked (line 2610) | async def set_checked(
    method check (line 2665) | async def check(
    method uncheck (line 2717) | async def uncheck(
    method bounding_box (line 2769) | async def bounding_box(self) -> typing.Optional[FloatRect]:
    method screenshot (line 2799) | async def screenshot(
    method query_selector (line 2891) | async def query_selector(self, selector: str) -> typing.Optional["Elem...
    method query_selector_all (line 2911) | async def query_selector_all(self, selector: str) -> typing.List["Elem...
    method eval_on_selector (line 2931) | async def eval_on_selector(
    method eval_on_selector_all (line 2973) | async def eval_on_selector_all(
    method wait_for_element_state (line 3021) | async def wait_for_element_state(
    method wait_for_selector (line 3059) | async def wait_for_selector(
  class FileChooser (line 3124) | class FileChooser(AsyncBase):
    method page (line 3127) | def page(self) -> "Page":
    method element (line 3139) | def element(self) -> "ElementHandle":
    method is_multiple (line 3150) | def is_multiple(self) -> bool:
    method set_files (line 3162) | async def set_files(
  class Frame (line 3201) | class Frame(AsyncBase):
    method page (line 3204) | def page(self) -> "Page":
    method name (line 3216) | def name(self) -> str:
    method url (line 3233) | def url(self) -> str:
    method parent_frame (line 3245) | def parent_frame(self) -> typing.Optional["Frame"]:
    method child_frames (line 3257) | def child_frames(self) -> typing.List["Frame"]:
    method goto (line 3266) | async def goto(
    method expect_navigation (line 3330) | def expect_navigation(
    method wait_for_url (line 3392) | async def wait_for_url(
    method wait_for_load_state (line 3439) | async def wait_for_load_state(
    method frame_element (line 3485) | async def frame_element(self) -> "ElementHandle":
    method evaluate (line 3510) | async def evaluate(
    method evaluate_handle (line 3566) | async def evaluate_handle(
    method query_selector (line 3620) | async def query_selector(
    method query_selector_all (line 3649) | async def query_selector_all(self, selector: str) -> typing.List["Elem...
    method wait_for_selector (line 3673) | async def wait_for_selector(
    method is_checked (line 3749) | async def is_checked(
    method is_disabled (line 3783) | async def is_disabled(
    method is_editable (line 3817) | async def is_editable(
    method is_enabled (line 3851) | async def is_enabled(
    method is_hidden (line 3885) | async def is_hidden(
    method is_visible (line 3911) | async def is_visible(
    method dispatch_event (line 3937) | async def dispatch_event(
    method eval_on_selector (line 4008) | async def eval_on_selector(
    method eval_on_selector_all (line 4061) | async def eval_on_selector_all(
    method content (line 4101) | async def content(self) -> str:
    method set_content (line 4113) | async def set_content(
    method is_detached (line 4152) | def is_detached(self) -> bool:
    method add_script_tag (line 4164) | async def add_script_tag(
    method add_style_tag (line 4202) | async def add_style_tag(
    method click (line 4235) | async def click(
    method dblclick (line 4319) | async def dblclick(
    method tap (line 4399) | async def tap(
    method fill (line 4470) | async def fill(
    method locator (line 4524) | def locator(
    method get_by_alt_text (line 4585) | def get_by_alt_text(
    method get_by_label (line 4622) | def get_by_label(
    method get_by_placeholder (line 4663) | def get_by_placeholder(
    method get_by_role (line 4704) | def get_by_role(
    method get_by_test_id (line 4905) | def get_by_test_id(
    method get_by_text (line 4943) | def get_by_text(
    method get_by_title (line 5007) | def get_by_title(
    method frame_locator (line 5046) | def frame_locator(self, selector: str) -> "FrameLocator":
    method focus (line 5074) | async def focus(
    method text_content (line 5105) | async def text_content(
    method inner_text (line 5139) | async def inner_text(
    method inner_html (line 5173) | async def inner_html(
    method get_attribute (line 5207) | async def get_attribute(
    method hover (line 5244) | async def hover(
    method drag_and_drop (line 5313) | async def drag_and_drop(
    method select_option (line 5377) | async def select_option(
    method input_value (line 5462) | async def input_value(
    method set_input_files (line 5500) | async def set_input_files(
    method type (line 5552) | async def type(
    method press (line 5602) | async def press(
    method check (line 5667) | async def check(
    method uncheck (line 5729) | async def uncheck(
    method wait_for_timeout (line 5791) | async def wait_for_timeout(self, timeout: float) -> None:
    method wait_for_function (line 5809) | async def wait_for_function(
    method title (line 5880) | async def title(self) -> str:
    method set_checked (line 5892) | async def set_checked(
  class FrameLocator (line 5962) | class FrameLocator(AsyncBase):
    method first (line 5965) | def first(self) -> "FrameLocator":
    method last (line 5977) | def last(self) -> "FrameLocator":
    method owner (line 5989) | def owner(self) -> "Locator":
    method locator (line 6014) | def locator(
    method get_by_alt_text (line 6072) | def get_by_alt_text(
    method get_by_label (line 6109) | def get_by_label(
    method get_by_placeholder (line 6150) | def get_by_placeholder(
    method get_by_role (line 6191) | def get_by_role(
    method get_by_test_id (line 6392) | def get_by_test_id(
    method get_by_text (line 6430) | def get_by_text(
    method get_by_title (line 6494) | def get_by_title(
    method frame_locator (line 6533) | def frame_locator(self, selector: str) -> "FrameLocator":
    method nth (line 6551) | def nth(self, index: int) -> "FrameLocator":
  class Worker (line 6571) | class Worker(AsyncBase):
    method on (line 6574) | def on(
    method on (line 6584) | def on(
    method on (line 6595) | def on(
    method once (line 6603) | def once(
    method once (line 6613) | def once(
    method once (line 6624) | def once(
    method url (line 6632) | def url(self) -> str:
    method evaluate (line 6641) | async def evaluate(
    method evaluate_handle (line 6674) | async def evaluate_handle(
    method expect_event (line 6706) | def expect_event(
  class Selectors (line 6751) | class Selectors(AsyncBase):
    method register (line 6753) | async def register(
    method set_test_id_attribute (line 6830) | def set_test_id_attribute(self, attribute_name: str) -> None:
  class Clock (line 6849) | class Clock(AsyncBase):
    method install (line 6851) | async def install(
    method fast_forward (line 6882) | async def fast_forward(self, ticks: typing.Union[int, str]) -> None:
    method pause_at (line 6904) | async def pause_at(self, time: typing.Union[float, str, datetime.datet...
    method resume (line 6941) | async def resume(self) -> None:
    method run_for (line 6949) | async def run_for(self, ticks: typing.Union[int, str]) -> None:
    method set_fixed_time (line 6970) | async def set_fixed_time(
    method set_system_time (line 6996) | async def set_system_time(
  class ConsoleMessage (line 7024) | class ConsoleMessage(AsyncBase):
    method type (line 7027) | def type(
    method text (line 7059) | def text(self) -> str:
    method args (line 7071) | def args(self) -> typing.List["JSHandle"]:
    method location (line 7083) | def location(self) -> SourceLocation:
    method page (line 7093) | def page(self) -> typing.Optional["Page"]:
    method worker (line 7105) | def worker(self) -> typing.Optional["Worker"]:
  class Dialog (line 7121) | class Dialog(AsyncBase):
    method type (line 7124) | def type(self) -> str:
    method message (line 7136) | def message(self) -> str:
    method default_value (line 7148) | def default_value(self) -> str:
    method page (line 7160) | def page(self) -> typing.Optional["Page"]:
    method accept (line 7171) | async def accept(self, prompt_text: typing.Optional[str] = None) -> None:
    method dismiss (line 7186) | async def dismiss(self) -> None:
  class Download (line 7198) | class Download(AsyncBase):
    method page (line 7201) | def page(self) -> "Page":
    method url (line 7213) | def url(self) -> str:
    method suggested_filename (line 7225) | def suggested_filename(self) -> str:
    method delete (line 7239) | async def delete(self) -> None:
    method failure (line 7247) | async def failure(self) -> typing.Optional[str]:
    method path (line 7259) | async def path(self) -> pathlib.Path:
    method save_as (line 7275) | async def save_as(self, path: typing.Union[str, pathlib.Path]) -> None:
    method cancel (line 7295) | async def cancel(self) -> None:
  class Video (line 7308) | class Video(AsyncBase):
    method path (line 7310) | async def path(self) -> pathlib.Path:
    method save_as (line 7323) | async def save_as(self, path: typing.Union[str, pathlib.Path]) -> None:
    method delete (line 7337) | async def delete(self) -> None:
  class Page (line 7349) | class Page(AsyncContextManager):
    method on (line 7352) | def on(
    method on (line 7361) | def on(
    method on (line 7387) | def on(
    method on (line 7410) | def on(
    method on (line 7431) | def on(
    method on (line 7442) | def on(
    method on (line 7452) | def on(
    method on (line 7468) | def on(
    method on (line 7477) | def on(
    method on (line 7486) | def on(
    method on (line 7495) | def on(
    method on (line 7505) | def on(
    method on (line 7522) | def on(
    method on (line 7548) | def on(
    method on (line 7558) | def on(
    method on (line 7576) | def on(
    method on (line 7586) | def on(
    method on (line 7596) | def on(
    method on (line 7605) | def on(
    method on (line 7614) | def on(
    method once (line 7622) | def once(
    method once (line 7631) | def once(
    method once (line 7657) | def once(
    method once (line 7680) | def once(
    method once (line 7701) | def once(
    method once (line 7712) | def once(
    method once (line 7722) | def once(
    method once (line 7738) | def once(
    method once (line 7747) | def once(
    method once (line 7756) | def once(
    method once (line 7765) | def once(
    method once (line 7775) | def once(
    method once (line 7792) | def once(
    method once (line 7818) | def once(
    method once (line 7828) | def once(
    method once (line 7846) | def once(
    method once (line 7856) | def once(
    method once (line 7866) | def once(
    method once (line 7875) | def once(
    method once (line 7884) | def once(
    method keyboard (line 7892) | def keyboard(self) -> "Keyboard":
    method mouse (line 7902) | def mouse(self) -> "Mouse":
    method touchscreen (line 7912) | def touchscreen(self) -> "Touchscreen":
    method context (line 7922) | def context(self) -> "BrowserContext":
    method clock (line 7934) | def clock(self) -> "Clock":
    method main_frame (line 7946) | def main_frame(self) -> "Frame":
    method frames (line 7958) | def frames(self) -> typing.List["Frame"]:
    method url (line 7970) | def url(self) -> str:
    method viewport_size (line 7980) | def viewport_size(self) -> typing.Optional[ViewportSize]:
    method workers (line 7990) | def workers(self) -> typing.List["Worker"]:
    method request (line 8005) | def request(self) -> "APIRequestContext":
    method video (line 8019) | def video(self) -> typing.Optional["Video"]:
    method opener (line 8030) | async def opener(self) -> typing.Optional["Page"]:
    method frame (line 8042) | def frame(
    method set_default_navigation_timeout (line 8076) | def set_default_navigation_timeout(self, timeout: float) -> None:
    method set_default_timeout (line 8101) | def set_default_timeout(self, timeout: float) -> None:
    method query_selector (line 8118) | async def query_selector(
    method query_selector_all (line 8143) | async def query_selector_all(self, selector: str) -> typing.List["Elem...
    method wait_for_selector (line 8163) | async def wait_for_selector(
    method is_checked (line 8239) | async def is_checked(
    method is_disabled (line 8273) | async def is_disabled(
    method is_editable (line 8307) | async def is_editable(
    method is_enabled (line 8341) | async def is_enabled(
    method is_hidden (line 8375) | async def is_hidden(
    method is_visible (line 8409) | async def is_visible(
    method dispatch_event (line 8443) | async def dispatch_event(
    method evaluate (line 8514) | async def evaluate(
    method evaluate_handle (line 8572) | async def evaluate_handle(
    method eval_on_selector (line 8626) | async def eval_on_selector(
    method eval_on_selector_all (line 8677) | async def eval_on_selector_all(
    method add_script_tag (line 8715) | async def add_script_tag(
    method add_style_tag (line 8752) | async def add_style_tag(
    method expose_function (line 8783) | async def expose_function(self, name: str, callback: typing.Callable) ...
    method expose_binding (line 8845) | async def expose_binding(
    method set_extra_http_headers (line 8914) | async def set_extra_http_headers(self, headers: typing.Dict[str, str])...
    method content (line 8933) | async def content(self) -> str:
    method set_content (line 8945) | async def set_content(
    method goto (line 8984) | async def goto(
    method reload (line 9050) | async def reload(
    method wait_for_load_state (line 9089) | async def wait_for_load_state(
    method wait_for_url (line 9144) | async def wait_for_url(
    method wait_for_event (line 9191) | async def wait_for_event(
    method go_back (line 9227) | async def go_back(
    method go_forward (line 9267) | async def go_forward(
    method request_gc (line 9307) | async def request_gc(self) -> None:
    method emulate_media (line 9329) | async def emulate_media(
    method set_viewport_size (line 9402) | async def set_viewport_size(self, viewport_size: ViewportSize) -> None:
    method bring_to_front (line 9430) | async def bring_to_front(self) -> None:
    method add_init_script (line 9438) | async def add_init_script(
    method route (line 9479) | async def route(
    method unroute (line 9564) | async def unroute(
    method route_web_socket (line 9593) | async def route_web_socket(
    method unroute_all (line 9636) | async def unroute_all(
    method route_from_har (line 9660) | async def route_from_har(
    method screenshot (line 9715) | async def screenshot(
    method title (line 9809) | async def title(self) -> str:
    method close (line 9821) | async def close(
    method is_closed (line 9850) | def is_closed(self) -> bool:
    method click (line 9862) | async def click(
    method dblclick (line 9946) | async def dblclick(
    method tap (line 10025) | async def tap(
    method fill (line 10096) | async def fill(
    method locator (line 10150) | def locator(
    method get_by_alt_text (line 10209) | def get_by_alt_text(
    method get_by_label (line 10246) | def get_by_label(
    method get_by_placeholder (line 10287) | def get_by_placeholder(
    method get_by_role (line 10328) | def get_by_role(
    method get_by_test_id (line 10529) | def get_by_test_id(
    method get_by_text (line 10567) | def get_by_text(
    method get_by_title (line 10631) | def get_by_title(
    method frame_locator (line 10670) | def frame_locator(self, selector: str) -> "FrameLocator":
    method focus (line 10698) | async def focus(
    method text_content (line 10729) | async def text_content(
    method inner_text (line 10763) | async def inner_text(
    method inner_html (line 10797) | async def inner_html(
    method get_attribute (line 10831) | async def get_attribute(
    method hover (line 10868) | async def hover(
    method drag_and_drop (line 10937) | async def drag_and_drop(
    method select_option (line 11017) | async def select_option(
    method input_value (line 11103) | async def input_value(
    method set_input_files (line 11141) | async def set_input_files(
    method type (line 11194) | async def type(
    method press (line 11244) | async def press(
    method check (line 11325) | async def check(
    method uncheck (line 11387) | async def uncheck(
    method wait_for_timeout (line 11449) | async def wait_for_timeout(self, timeout: float) -> None:
    method wait_for_function (line 11474) | async def wait_for_function(
    method pause (line 11545) | async def pause(self) -> None:
    method pdf (line 11559) | async def pdf(
    method expect_event (line 11693) | def expect_event(
    method expect_console_message (line 11734) | def expect_console_message(
    method expect_download (line 11765) | def expect_download(
    method expect_file_chooser (line 11796) | def expect_file_chooser(
    method expect_navigation (line 11827) | def expect_navigation(
    method expect_popup (line 11891) | def expect_popup(
    method expect_request (line 11922) | def expect_request(
    method expect_request_finished (line 11969) | def expect_request_finished(
    method expect_response (line 12000) | def expect_response(
    method expect_websocket (line 12049) | def expect_websocket(
    method expect_worker (line 12080) | def expect_worker(
    method set_checked (line 12111) | async def set_checked(
    method add_locator_handler (line 12177) | async def add_locator_handler(
    method remove_locator_handler (line 12300) | async def remove_locator_handler(self, locator: "Locator") -> None:
    method requests (line 12315) | async def requests(self) -> typing.List["Request"]:
    method console_messages (line 12334) | async def console_messages(self) -> typing.List["ConsoleMessage"]:
    method page_errors (line 12346) | async def page_errors(self) -> typing.List["Error"]:
  class WebError (line 12362) | class WebError(AsyncBase):
    method page (line 12365) | def page(self) -> typing.Optional["Page"]:
    method error (line 12377) | def error(self) -> "Error":
  class BrowserContext (line 12392) | class BrowserContext(AsyncContextManager):
    method on (line 12395) | def on(
    method on (line 12404) | def on(
    method on (line 12418) | def on(
    method on (line 12444) | def on(
    method on (line 12465) | def on(
    method on (line 12492) | def on(
    method on (line 12502) | def on(
    method on (line 12515) | def on(
    method on (line 12529) | def on(
    method on (line 12540) | def on(
    method on (line 12551) | def on(
    method on (line 12561) | def on(
    method once (line 12569) | def once(
    method once (line 12578) | def once(
    method once (line 12592) | def once(
    method once (line 12618) | def once(
    method once (line 12639) | def once(
    method once (line 12666) | def once(
    method once (line 12676) | def once(
    method once (line 12689) | def once(
    method once (line 12703) | def once(
    method once (line 12714) | def once(
    method once (line 12725) | def once(
    method once (line 12735) | def once(
    method pages (line 12743) | def pages(self) -> typing.List["Page"]:
    method browser (line 12755) | def browser(self) -> typing.Optional["Browser"]:
    method background_pages (line 12768) | def background_pages(self) -> typing.List["Page"]:
    method service_workers (line 12780) | def service_workers(self) -> typing.List["Worker"]:
    method tracing (line 12794) | def tracing(self) -> "Tracing":
    method request (line 12804) | def request(self) -> "APIRequestContext":
    method clock (line 12816) | def clock(self) -> "Clock":
    method set_default_navigation_timeout (line 12827) | def set_default_navigation_timeout(self, timeout: float) -> None:
    method set_default_timeout (line 12851) | def set_default_timeout(self, timeout: float) -> None:
    method new_page (line 12870) | async def new_page(self) -> "Page":
    method cookies (line 12882) | async def cookies(
    method add_cookies (line 12904) | async def add_cookies(self, cookies: typing.Sequence[SetCookieParam]) ...
    method clear_cookies (line 12925) | async def clear_cookies(
    method grant_permissions (line 12960) | async def grant_permissions(
    method clear_permissions (line 13004) | async def clear_permissions(self) -> None:
    method set_geolocation (line 13021) | async def set_geolocation(
    method set_extra_http_headers (line 13046) | async def set_extra_http_headers(self, headers: typing.Dict[str, str])...
    method set_offline (line 13068) | async def set_offline(self, offline: bool) -> None:
    method add_init_script (line 13081) | async def add_init_script(
    method expose_binding (line 13122) | async def expose_binding(
    method expose_function (line 13189) | async def expose_function(self, name: str, callback: typing.Callable) ...
    method route (line 13250) | async def route(
    method unroute (line 13331) | async def unroute(
    method route_web_socket (line 13361) | async def route_web_socket(
    method unroute_all (line 13406) | async def unroute_all(
    method route_from_har (line 13430) | async def route_from_har(
    method expect_event (line 13485) | def expect_event(
    method close (line 13526) | async def close(self, *, reason: typing.Optional[str] = None) -> None:
    method storage_state (line 13541) | async def storage_state(
    method wait_for_event (line 13571) | async def wait_for_event(
    method expect_console_message (line 13607) | def expect_console_message(
    method expect_page (line 13639) | def expect_page(
    method new_cdp_session (line 13670) | async def new_cdp_session(
  class CDPSession (line 13696) | class CDPSession(AsyncBase):
    method send (line 13698) | async def send(
    method detach (line 13719) | async def detach(self) -> None:
  class Browser (line 13732) | class Browser(AsyncContextManager):
    method on (line 13734) | def on(
    method once (line 13746) | def once(
    method contexts (line 13759) | def contexts(self) -> typing.List["BrowserContext"]:
    method browser_type (line 13780) | def browser_type(self) -> "BrowserType":
    method version (line 13792) | def version(self) -> str:
    method is_connected (line 13803) | def is_connected(self) -> bool:
    method new_context (line 13815) | async def new_context(
    method new_page (line 14066) | async def new_page(
    method close (line 14301) | async def close(self, *, reason: typing.Optional[str] = None) -> None:
    method new_browser_cdp_session (line 14324) | async def new_browser_cdp_session(self) -> "CDPSession":
    method start_tracing (line 14338) | async def start_tracing(
    method stop_tracing (line 14385) | async def stop_tracing(self) -> bytes:
  class BrowserType (line 14406) | class BrowserType(AsyncBase):
    method name (line 14409) | def name(self) -> str:
    method executable_path (line 14421) | def executable_path(self) -> str:
    method launch (line 14432) | async def launch(
    method launch_persistent_context (line 14567) | async def launch_persistent_context(
    method connect_over_cdp (line 14894) | async def connect_over_cdp(
    method connect (line 14955) | async def connect(
  class Playwright (line 15016) | class Playwright(AsyncBase):
    method devices (line 15019) | def devices(self) -> typing.Dict:
    method selectors (line 15051) | def selectors(self) -> "Selectors":
    method chromium (line 15064) | def chromium(self) -> "BrowserType":
    method firefox (line 15076) | def firefox(self) -> "BrowserType":
    method webkit (line 15088) | def webkit(self) -> "BrowserType":
    method request (line 15100) | def request(self) -> "APIRequest":
    method __getitem__ (line 15111) | def __getitem__(self, value: str) -> "BrowserType":
    method stop (line 15115) | async def stop(self) -> None:
  class Tracing (line 15142) | class Tracing(AsyncBase):
    method start (line 15144) | async def start(
    method start_chunk (line 15203) | async def start_chunk(
    method stop_chunk (line 15244) | async def stop_chunk(
    method stop (line 15259) | async def stop(
    method group (line 15274) | async def group(
    method group_end (line 15308) | async def group_end(self) -> None:
  class Locator (line 15320) | class Locator(AsyncBase):
    method page (line 15323) | def page(self) -> "Page":
    method first (line 15335) | def first(self) -> "Locator":
    method last (line 15347) | def last(self) -> "Locator":
    method content_frame (line 15365) | def content_frame(self) -> "FrameLocator":
    method description (line 15391) | def description(self) -> typing.Optional[str]:
    method bounding_box (line 15413) | async def bounding_box(
    method check (line 15456) | async def check(
    method click (line 15518) | async def click(
    method dblclick (line 15617) | async def dblclick(
    method dispatch_event (line 15695) | async def dispatch_event(
    method evaluate (line 15757) | async def evaluate(
    method evaluate_all (line 15808) | async def evaluate_all(
    method evaluate_handle (line 15850) | async def evaluate_handle(
    method fill (line 15898) | async def fill(
    method clear (line 15948) | async def clear(
    method locator (line 15993) | def locator(
    method get_by_alt_text (line 16051) | def get_by_alt_text(
    method get_by_label (line 16088) | def get_by_label(
    method get_by_placeholder (line 16129) | def get_by_placeholder(
    method get_by_role (line 16170) | def get_by_role(
    method get_by_test_id (line 16371) | def get_by_test_id(
    method get_by_text (line 16409) | def get_by_text(
    method get_by_title (line 16473) | def get_by_title(
    method frame_locator (line 16512) | def frame_locator(self, selector: str) -> "FrameLocator":
    method element_handle (line 16537) | async def element_handle(
    method element_handles (line 16558) | async def element_handles(self) -> typing.List["ElementHandle"]:
    method nth (line 16570) | def nth(self, index: int) -> "Locator":
    method describe (line 16592) | def describe(self, description: str) -> "Locator":
    method filter (line 16617) | def filter(
    method or_ (line 16684) | def or_(self, locator: "Locator") -> "Locator":
    method and_ (line 16722) | def and_(self, locator: "Locator") -> "Locator":
    method focus (line 16747) | async def focus(self, *, timeout: typing.Optional[float] = None) -> None:
    method blur (line 16761) | async def blur(self, *, timeout: typing.Optional[float] = None) -> None:
    method all (line 16775) | async def all(self) -> typing.List["Locator"]:
    method count (line 16804) | async def count(self) -> int:
    method drag_to (line 16825) | async def drag_to(
    method get_attribute (line 16900) | async def get_attribute(
    method hover (line 16927) | async def hover(
    method inner_html (line 16996) | async def inner_html(self, *, timeout: typing.Optional[float] = None) ...
    method inner_text (line 17014) | async def inner_text(self, *, timeout: typing.Optional[float] = None) ...
    method input_value (line 17035) | async def input_value(self, *, timeout: typing.Optional[float] = None)...
    method is_checked (line 17071) | async def is_checked(self, *, timeout: typing.Optional[float] = None) ...
    method is_disabled (line 17098) | async def is_disabled(self, *, timeout: typing.Optional[float] = None)...
    method is_editable (line 17127) | async def is_editable(self, *, timeout: typing.Optional[float] = None)...
    method is_enabled (line 17158) | async def is_enabled(self, *, timeout: typing.Optional[float] = None) ...
    method is_hidden (line 17185) | async def is_hidden(self, *, timeout: typing.Optional[float] = None) -...
    method is_visible (line 17211) | async def is_visible(self, *, timeout: typing.Optional[float] = None) ...
    method press (line 17237) | async def press(
    method screenshot (line 17301) | async def screenshot(
    method aria_snapshot (line 17409) | async def aria_snapshot(self, *, timeout: typing.Optional[float] = Non...
    method scroll_into_view_if_needed (line 17464) | async def scroll_into_view_if_needed(
    method select_option (line 17486) | async def select_option(
    method select_text (line 17574) | async def select_text(
    method set_input_files (line 17602) | async def set_input_files(
    method tap (line 17670) | async def tap(
    method text_content (line 17736) | async def text_content(
    method type (line 17761) | async def type(
    method press_sequentially (line 17798) | async def press_sequentially(
    method uncheck (line 17851) | async def uncheck(
    method all_inner_texts (line 17913) | async def all_inner_texts(self) -> typing.List[str]:
    method all_text_contents (line 17934) | async def all_text_contents(self) -> typing.List[str]:
    method wait_for (line 17955) | async def wait_for(
    method set_checked (line 17996) | async def set_checked(
    method highlight (line 18061) | async def highlight(self) -> None:
  class APIResponse (line 18074) | class APIResponse(AsyncBase):
    method ok (line 18077) | def ok(self) -> bool:
    method url (line 18089) | def url(self) -> str:
    method status (line 18101) | def status(self) -> int:
    method status_text (line 18113) | def status_text(self) -> str:
    method headers (line 18125) | def headers(self) -> typing.Dict[str, str]:
    method headers_array (line 18137) | def headers_array(self) -> typing.List[NameValue]:
    method body (line 18149) | async def body(self) -> bytes:
    method text (line 18161) | async def text(self) -> str:
    method json (line 18173) | async def json(self) -> typing.Any:
    method dispose (line 18187) | async def dispose(self) -> None:
  class APIRequestContext (line 18199) | class APIRequestContext(AsyncBase):
    method dispose (line 18201) | async def dispose(self, *, reason: typing.Optional[str] = None) -> None:
    method delete (line 18216) | async def delete(
    method head (line 18297) | async def head(
    method get (line 18378) | async def get(
    method patch (line 18471) | async def patch(
    method put (line 18552) | async def put(
    method post (line 18633) | async def post(
    method fetch (line 18745) | async def fetch(
    method storage_state (line 18845) | async def storage_state(
  class APIRequest (line 18877) | class APIRequest(AsyncBase):
    method new_context (line 18879) | async def new_context(
  class PageAssertions (line 18980) | class PageAssertions(AsyncBase):
    method to_have_title (line 18982) | async def to_have_title(
    method not_to_have_title (line 19017) | async def not_to_have_title(
    method to_have_url (line 19042) | async def to_have_url(
    method not_to_have_url (line 19081) | async def not_to_have_url(
  class LocatorAssertions (line 19114) | class LocatorAssertions(AsyncBase):
    method to_contain_text (line 19116) | async def to_contain_text(
    method not_to_contain_text (line 19208) | async def not_to_contain_text(
    method to_have_attribute (line 19249) | async def to_have_attribute(
    method not_to_have_attribute (line 19290) | async def not_to_have_attribute(
    method to_have_class (line 19322) | async def to_have_class(
    method not_to_have_class (line 19379) | async def not_to_have_class(
    method to_contain_class (line 19410) | async def to_contain_class(
    method not_to_contain_class (line 19471) | async def not_to_contain_class(
    method to_have_count (line 19496) | async def to_have_count(
    method not_to_have_count (line 19525) | async def not_to_have_count(
    method to_have_css (line 19545) | async def to_have_css(
    method not_to_have_css (line 19580) | async def not_to_have_css(
    method to_have_id (line 19608) | async def to_have_id(
    method not_to_have_id (line 19640) | async def not_to_have_id(
    method to_have_js_property (line 19663) | async def to_have_js_property(
    method not_to_have_js_property (line 19697) | async def not_to_have_js_property(
    method to_have_value (line 19721) | async def to_have_value(
    method not_to_have_value (line 19755) | async def not_to_have_value(
    method to_have_values (line 19778) | async def to_have_values(
    method not_to_have_values (line 19829) | async def not_to_have_values(
    method to_have_text (line 19858) | async def to_have_text(
    method not_to_have_text (line 19949) | async def not_to_have_text(
    method to_be_attached (line 19990) | async def to_be_attached(
    method to_be_checked (line 20019) | async def to_be_checked(
    method not_to_be_attached (line 20058) | async def not_to_be_attached(
    method not_to_be_checked (line 20080) | async def not_to_be_checked(
    method to_be_disabled (line 20098) | async def to_be_disabled(self, *, timeout: typing.Optional[float] = No...
    method not_to_be_disabled (line 20127) | async def not_to_be_disabled(
    method to_be_editable (line 20145) | async def to_be_editable(
    method not_to_be_editable (line 20176) | async def not_to_be_editable(
    method to_be_empty (line 20198) | async def to_be_empty(self, *, timeout: typing.Optional[float] = None)...
    method not_to_be_empty (line 20223) | async def not_to_be_empty(self, *, timeout: typing.Optional[float] = N...
    method to_be_enabled (line 20239) | async def to_be_enabled(
    method not_to_be_enabled (line 20270) | async def not_to_be_enabled(
    method to_be_hidden (line 20292) | async def to_be_hidden(self, *, timeout: typing.Optional[float] = None...
    method not_to_be_hidden (line 20318) | async def not_to_be_hidden(self, *, timeout: typing.Optional[float] = ...
    method to_be_visible (line 20334) | async def to_be_visible(
    method not_to_be_visible (line 20375) | async def not_to_be_visible(
    method to_be_focused (line 20397) | async def to_be_focused(self, *, timeout: typing.Optional[float] = Non...
    method not_to_be_focused (line 20422) | async def not_to_be_focused(
    method to_be_in_viewport (line 20440) | async def to_be_in_viewport(
    method not_to_be_in_viewport (line 20479) | async def not_to_be_in_viewport(
    method to_have_accessible_description (line 20501) | async def to_have_accessible_description(
    method not_to_have_accessible_description (line 20538) | async def not_to_have_accessible_description(
    method to_have_accessible_name (line 20567) | async def to_have_accessible_name(
    method not_to_have_accessible_name (line 20604) | async def not_to_have_accessible_name(
    method to_have_role (line 20633) | async def to_have_role(
    method to_have_accessible_error_message (line 20749) | async def to_have_accessible_error_message(
    method not_to_have_accessible_error_message (line 20786) | async def not_to_have_accessible_error_message(
    method not_to_have_role (line 20815) | async def not_to_have_role(
    method to_match_aria_snapshot (line 20921) | async def to_match_aria_snapshot(
    method not_to_match_aria_snapshot (line 20952) | async def not_to_match_aria_snapshot(
  class APIResponseAssertions (line 20977) | class APIResponseAssertions(AsyncBase):
    method to_be_ok (line 20979) | async def to_be_ok(self) -> None:
    method not_to_be_ok (line 20997) | async def not_to_be_ok(self) -> None:

FILE: playwright/sync_api/__init__.py
  function sync_playwright (line 88) | def sync_playwright() -> PlaywrightContextManager:
  class Expect (line 92) | class Expect:
    method __init__ (line 95) | def __init__(self) -> None:
    method set_options (line 98) | def set_options(self, timeout: Optional[float] = _unset) -> None:
    method __call__ (line 112) | def __call__(
    method __call__ (line 117) | def __call__(
    method __call__ (line 122) | def __call__(
    method __call__ (line 126) | def __call__(

FILE: playwright/sync_api/_context_manager.py
  class PlaywrightContextManager (line 32) | class PlaywrightContextManager:
    method __init__ (line 33) | def __init__(self) -> None:
    method __enter__ (line 40) | def __enter__(self) -> SyncPlaywright:
    method start (line 83) | def start(self) -> SyncPlaywright:
    method __exit__ (line 86) | def __exit__(self, *args: Any) -> None:

FILE: playwright/sync_api/_generated.py
  class Request (line 88) | class Request(SyncBase):
    method url (line 91) | def url(self) -> str:
    method resource_type (line 103) | def resource_type(self) -> str:
    method service_worker (line 117) | def service_worker(self) -> typing.Optional["Worker"]:
    method method (line 135) | def method(self) -> str:
    method post_data (line 147) | def post_data(self) -> typing.Optional[str]:
    method post_data_json (line 159) | def post_data_json(self) -> typing.Optional[typing.Any]:
    method post_data_buffer (line 174) | def post_data_buffer(self) -> typing.Optional[bytes]:
    method frame (line 186) | def frame(self) -> "Frame":
    method redirected_from (line 213) | def redirected_from(self) -> typing.Optional["Request"]:
    method redirected_to (line 245) | def redirected_to(self) -> typing.Optional["Request"]:
    method failure (line 265) | def failure(self) -> typing.Optional[str]:
    method timing (line 285) | def timing(self) -> ResourceTiming:
    method headers (line 308) | def headers(self) -> typing.Dict[str, str]:
    method sizes (line 321) | def sizes(self) -> RequestSizes:
    method response (line 333) | def response(self) -> typing.Optional["Response"]:
    method is_navigation_request (line 345) | def is_navigation_request(self) -> bool:
    method all_headers (line 360) | def all_headers(self) -> typing.Dict[str, str]:
    method headers_array (line 372) | def headers_array(self) -> typing.List[NameValue]:
    method header_value (line 386) | def header_value(self, name: str) -> typing.Optional[str]:
  class Response (line 409) | class Response(SyncBase):
    method url (line 412) | def url(self) -> str:
    method ok (line 424) | def ok(self) -> bool:
    method status (line 436) | def status(self) -> int:
    method status_text (line 448) | def status_text(self) -> str:
    method headers (line 460) | def headers(self) -> typing.Dict[str, str]:
    method from_service_worker (line 474) | def from_service_worker(self) -> bool:
    method request (line 487) | def request(self) -> "Request":
    method frame (line 499) | def frame(self) -> "Frame":
    method all_headers (line 510) | def all_headers(self) -> typing.Dict[str, str]:
    method headers_array (line 522) | def headers_array(self) -> typing.List[NameValue]:
    method header_value (line 536) | def header_value(self, name: str) -> typing.Optional[str]:
    method header_values (line 557) | def header_values(self, name: str) -> typing.List[str]:
    method server_addr (line 576) | def server_addr(self) -> typing.Optional[RemoteAddr]:
    method security_details (line 588) | def security_details(self) -> typing.Optional[SecurityDetails]:
    method finished (line 600) | def finished(self) -> None:
    method body (line 608) | def body(self) -> bytes:
    method text (line 620) | def text(self) -> str:
    method json (line 632) | def json(self) -> typing.Any:
  class Route (line 650) | class Route(SyncBase):
    method request (line 653) | def request(self) -> "Request":
    method abort (line 664) | def abort(self, error_code: typing.Optional[str] = None) -> None:
    method fulfill (line 695) | def fulfill(
    method fetch (line 761) | def fetch(
    method fallback (line 835) | def fallback(
    method continue_ (line 928) | def continue_(
  class WebSocket (line 997) | class WebSocket(SyncBase):
    method on (line 1000) | def on(
    method on (line 1007) | def on(
    method on (line 1016) | def on(
    method on (line 1025) | def on(
    method on (line 1031) | def on(self, event: str, f: typing.Callable[..., None]) -> None:
    method once (line 1035) | def once(
    method once (line 1042) | def once(
    method once (line 1051) | def once(
    method once (line 1060) | def once(
    method once (line 1066) | def once(self, event: str, f: typing.Callable[..., None]) -> None:
    method url (line 1070) | def url(self) -> str:
    method expect_event (line 1081) | def expect_event(
    method wait_for_event (line 1114) | def wait_for_event(
    method is_closed (line 1154) | def is_closed(self) -> bool:
  class WebSocketRoute (line 1170) | class WebSocketRoute(SyncBase):
    method url (line 1173) | def url(self) -> str:
    method close (line 1184) | def close(
    method connect_to_server (line 1203) | def connect_to_server(self) -> "WebSocketRoute":
    method send (line 1226) | def send(self, message: typing.Union[str, bytes]) -> None:
    method on_message (line 1241) | def on_message(
    method on_close (line 1267) | def on_close(
  class Keyboard (line 1297) | class Keyboard(SyncBase):
    method down (line 1299) | def down(self, key: str) -> None:
    method up (line 1338) | def up(self, key: str) -> None:
    method insert_text (line 1351) | def insert_text(self, text: str) -> None:
    method type (line 1375) | def type(self, text: str, *, delay: typing.Optional[float] = None) -> ...
    method press (line 1408) | def press(self, key: str, *, delay: typing.Optional[float] = None) -> ...
  class Mouse (line 1465) | class Mouse(SyncBase):
    method move (line 1467) | def move(self, x: float, y: float, *, steps: typing.Optional[int] = No...
    method down (line 1487) | def down(
    method up (line 1509) | def up(
    method click (line 1531) | def click(
    method dblclick (line 1566) | def dblclick(
    method wheel (line 1595) | def wheel(self, delta_x: float, delta_y: float) -> None:
  class Touchscreen (line 1620) | class Touchscreen(SyncBase):
    method tap (line 1622) | def tap(self, x: float, y: float) -> None:
  class JSHandle (line 1643) | class JSHandle(SyncBase):
    method evaluate (line 1645) | def evaluate(
    method evaluate_handle (line 1683) | def evaluate_handle(
    method get_property (line 1721) | def get_property(self, property_name: str) -> "JSHandle":
    method get_properties (line 1740) | def get_properties(self) -> typing.Dict[str, "JSHandle"]:
    method as_element (line 1762) | def as_element(self) -> typing.Optional["ElementHandle"]:
    method dispose (line 1774) | def dispose(self) -> None:
    method json_value (line 1782) | def json_value(self) -> typing.Any:
  class ElementHandle (line 1801) | class ElementHandle(JSHandle):
    method as_element (line 1803) | def as_element(self) -> typing.Optional["ElementHandle"]:
    method owner_frame (line 1815) | def owner_frame(self) -> typing.Optional["Frame"]:
    method content_frame (line 1827) | def content_frame(self) -> typing.Optional["Frame"]:
    method get_attribute (line 1839) | def get_attribute(self, name: str) -> typing.Optional[str]:
    method text_content (line 1858) | def text_content(self) -> typing.Optional[str]:
    method inner_text (line 1870) | def inner_text(self) -> str:
    method inner_html (line 1882) | def inner_html(self) -> str:
    method is_checked (line 1894) | def is_checked(self) -> bool:
    method is_disabled (line 1906) | def is_disabled(self) -> bool:
    method is_editable (line 1918) | def is_editable(self) -> bool:
    method is_enabled (line 1930) | def is_enabled(self) -> bool:
    method is_hidden (line 1942) | def is_hidden(self) -> bool:
    method is_visible (line 1954) | def is_visible(self) -> bool:
    method dispatch_event (line 1966) | def dispatch_event(
    method scroll_into_view_if_needed (line 2020) | def scroll_into_view_if_needed(
    method hover (line 2045) | def hover(
    method click (line 2104) | def click(
    method dblclick (line 2183) | def dblclick(
    method select_option (line 2257) | def select_option(
    method tap (line 2335) | def tap(
    method fill (line 2396) | def fill(
    method select_text (line 2438) | def select_text(
    method input_value (line 2466) | def input_value(self, *, timeout: typing.Optional[float] = None) -> str:
    method set_input_files (line 2490) | def set_input_files(
    method focus (line 2535) | def focus(self) -> None:
    method type (line 2543) | def type(
    method press (line 2582) | def press(
    method set_checked (line 2638) | def set_checked(
    method check (line 2695) | def check(
    method uncheck (line 2749) | def uncheck(
    method bounding_box (line 2803) | def bounding_box(self) -> typing.Optional[FloatRect]:
    method screenshot (line 2833) | def screenshot(
    method query_selector (line 2927) | def query_selector(self, selector: str) -> typing.Optional["ElementHan...
    method query_selector_all (line 2947) | def query_selector_all(self, selector: str) -> typing.List["ElementHan...
    method eval_on_selector (line 2967) | def eval_on_selector(
    method eval_on_selector_all (line 3011) | def eval_on_selector_all(
    method wait_for_element_state (line 3061) | def wait_for_element_state(
    method wait_for_selector (line 3101) | def wait_for_selector(
  class FileChooser (line 3168) | class FileChooser(SyncBase):
    method page (line 3171) | def page(self) -> "Page":
    method element (line 3183) | def element(self) -> "ElementHandle":
    method is_multiple (line 3194) | def is_multiple(self) -> bool:
    method set_files (line 3206) | def set_files(
  class Frame (line 3249) | class Frame(SyncBase):
    method page (line 3252) | def page(self) -> "Page":
    method name (line 3264) | def name(self) -> str:
    method url (line 3281) | def url(self) -> str:
    method parent_frame (line 3293) | def parent_frame(self) -> typing.Optional["Frame"]:
    method child_frames (line 3305) | def child_frames(self) -> typing.List["Frame"]:
    method goto (line 3314) | def goto(
    method expect_navigation (line 3380) | def expect_navigation(
    method wait_for_url (line 3442) | def wait_for_url(
    method wait_for_load_state (line 3491) | def wait_for_load_state(
    method frame_element (line 3537) | def frame_element(self) -> "ElementHandle":
    method evaluate (line 3562) | def evaluate(
    method evaluate_handle (line 3618) | def evaluate_handle(
    method query_selector (line 3674) | def query_selector(
    method query_selector_all (line 3703) | def query_selector_all(self, selector: str) -> typing.List["ElementHan...
    method wait_for_selector (line 3727) | def wait_for_selector(
    method is_checked (line 3802) | def is_checked(
    method is_disabled (line 3838) | def is_disabled(
    method is_editable (line 3874) | def is_editable(
    method is_enabled (line 3910) | def is_enabled(
    method is_hidden (line 3946) | def is_hidden(self, selector: str, *, strict: typing.Optional[bool] = ...
    method is_visible (line 3970) | def is_visible(
    method dispatch_event (line 3996) | def dispatch_event(
    method eval_on_selector (line 4069) | def eval_on_selector(
    method eval_on_selector_all (line 4124) | def eval_on_selector_all(
    method content (line 4166) | def content(self) -> str:
    method set_content (line 4178) | def set_content(
    method is_detached (line 4219) | def is_detached(self) -> bool:
    method add_script_tag (line 4231) | def add_script_tag(
    method add_style_tag (line 4271) | def add_style_tag(
    method click (line 4306) | def click(
    method dblclick (line 4392) | def dblclick(
    method tap (line 4474) | def tap(
    method fill (line 4547) | def fill(
    method locator (line 4603) | def locator(
    method get_by_alt_text (line 4664) | def get_by_alt_text(
    method get_by_label (line 4701) | def get_by_label(
    method get_by_placeholder (line 4742) | def get_by_placeholder(
    method get_by_role (line 4783) | def get_by_role(
    method get_by_test_id (line 4984) | def get_by_test_id(
    method get_by_text (line 5022) | def get_by_text(
    method get_by_title (line 5086) | def get_by_title(
    method frame_locator (line 5125) | def frame_locator(self, selector: str) -> "FrameLocator":
    method focus (line 5153) | def focus(
    method text_content (line 5184) | def text_content(
    method inner_text (line 5220) | def inner_text(
    method inner_html (line 5256) | def inner_html(
    method get_attribute (line 5292) | def get_attribute(
    method hover (line 5331) | def hover(
    method drag_and_drop (line 5402) | def drag_and_drop(
    method select_option (line 5468) | def select_option(
    method input_value (line 5555) | def input_value(
    method set_input_files (line 5595) | def set_input_files(
    method type (line 5649) | def type(
    method press (line 5701) | def press(
    method check (line 5768) | def check(
    method uncheck (line 5832) | def uncheck(
    method wait_for_timeout (line 5896) | def wait_for_timeout(self, timeout: float) -> None:
    method wait_for_function (line 5914) | def wait_for_function(
    method title (line 5984) | def title(self) -> str:
    method set_checked (line 5996) | def set_checked(
  class FrameLocator (line 6068) | class FrameLocator(SyncBase):
    method first (line 6071) | def first(self) -> "FrameLocator":
    method last (line 6083) | def last(self) -> "FrameLocator":
    method owner (line 6095) | def owner(self) -> "Locator":
    method locator (line 6120) | def locator(
    method get_by_alt_text (line 6178) | def get_by_alt_text(
    method get_by_label (line 6215) | def get_by_label(
    method get_by_placeholder (line 6256) | def get_by_placeholder(
    method get_by_role (line 6297) | def get_by_role(
    method get_by_test_id (line 6498) | def get_by_test_id(
    method get_by_text (line 6536) | def get_by_text(
    method get_by_title (line 6600) | def get_by_title(
    method frame_locator (line 6639) | def frame_locator(self, selector: str) -> "FrameLocator":
    method nth (line 6657) | def nth(self, index: int) -> "FrameLocator":
  class Worker (line 6677) | class Worker(SyncBase):
    method on (line 6680) | def on(
    method on (line 6688) | def on(
    method on (line 6695) | def on(self, event: str, f: typing.Callable[..., None]) -> None:
    method once (line 6699) | def once(
    method once (line 6707) | def once(
    method once (line 6714) | def once(self, event: str, f: typing.Callable[..., None]) -> None:
    method url (line 6718) | def url(self) -> str:
    method evaluate (line 6727) | def evaluate(
    method evaluate_handle (line 6760) | def evaluate_handle(
    method expect_event (line 6794) | def expect_event(
  class Selectors (line 6839) | class Selectors(SyncBase):
    method register (line 6841) | def register(
    method set_test_id_attribute (line 6916) | def set_test_id_attribute(self, attribute_name: str) -> None:
  class Clock (line 6935) | class Clock(SyncBase):
    method install (line 6937) | def install(
    method fast_forward (line 6968) | def fast_forward(self, ticks: typing.Union[int, str]) -> None:
    method pause_at (line 6992) | def pause_at(self, time: typing.Union[float, str, datetime.datetime]) ...
    method resume (line 7029) | def resume(self) -> None:
    method run_for (line 7037) | def run_for(self, ticks: typing.Union[int, str]) -> None:
    method set_fixed_time (line 7058) | def set_fixed_time(self, time: typing.Union[float, str, datetime.datet...
    method set_system_time (line 7084) | def set_system_time(
  class ConsoleMessage (line 7114) | class ConsoleMessage(SyncBase):
    method type (line 7117) | def type(
    method text (line 7149) | def text(self) -> str:
    method args (line 7161) | def args(self) -> typing.List["JSHandle"]:
    method location (line 7173) | def location(self) -> SourceLocation:
    method page (line 7183) | def page(self) -> typing.Optional["Page"]:
    method worker (line 7195) | def worker(self) -> typing.Optional["Worker"]:
  class Dialog (line 7211) | class Dialog(SyncBase):
    method type (line 7214) | def type(self) -> str:
    method message (line 7226) | def message(self) -> str:
    method default_value (line 7238) | def default_value(self) -> str:
    method page (line 7250) | def page(self) -> typing.Optional["Page"]:
    method accept (line 7261) | def accept(self, prompt_text: typing.Optional[str] = None) -> None:
    method dismiss (line 7276) | def dismiss(self) -> None:
  class Download (line 7288) | class Download(SyncBase):
    method page (line 7291) | def page(self) -> "Page":
    method url (line 7303) | def url(self) -> str:
    method suggested_filename (line 7315) | def suggested_filename(self) -> str:
    method delete (line 7329) | def delete(self) -> None:
    method failure (line 7337) | def failure(self) -> typing.Optional[str]:
    method path (line 7349) | def path(self) -> pathlib.Path:
    method save_as (line 7365) | def save_as(self, path: typing.Union[str, pathlib.Path]) -> None:
    method cancel (line 7385) | def cancel(self) -> None:
  class Video (line 7398) | class Video(SyncBase):
    method path (line 7400) | def path(self) -> pathlib.Path:
    method save_as (line 7413) | def save_as(self, path: typing.Union[str, pathlib.Path]) -> None:
    method delete (line 7427) | def delete(self) -> None:
  class Page (line 7439) | class Page(SyncContextManager):
    method on (line 7442) | def on(self, event: Literal["close"], f: typing.Callable[["Page"], "No...
    method on (line 7447) | def on(
    method on (line 7467) | def on(self, event: Literal["crash"], f: typing.Callable[["Page"], "No...
    method on (line 7486) | def on(
    method on (line 7505) | def on(
    method on (line 7514) | def on(
    method on (line 7522) | def on(
    method on (line 7534) | def on(
    method on (line 7541) | def on(
    method on (line 7548) | def on(
    method on (line 7555) | def on(self, event: Literal["load"], f: typing.Callable[["Page"], "Non...
    method on (line 7561) | def on(
    method on (line 7576) | def on(self, event: Literal["popup"], f: typing.Callable[["Page"], "No...
    method on (line 7598) | def on(
    method on (line 7606) | def on(
    method on (line 7622) | def on(
    method on (line 7630) | def on(
    method on (line 7638) | def on(
    method on (line 7645) | def on(
    method on (line 7652) | def on(self, event: str, f: typing.Callable[..., None]) -> None:
    method once (line 7656) | def once(
    method once (line 7663) | def once(
    method once (line 7683) | def once(
    method once (line 7704) | def once(
    method once (line 7723) | def once(
    method once (line 7732) | def once(
    method once (line 7740) | def once(
    method once (line 7752) | def once(
    method once (line 7759) | def once(
    method once (line 7766) | def once(
    method once (line 7773) | def once(
    method once (line 7781) | def once(
    method once (line 7796) | def once(
    method once (line 7820) | def once(
    method once (line 7828) | def once(
    method once (line 7844) | def once(
    method once (line 7852) | def once(
    method once (line 7860) | def once(
    method once (line 7867) | def once(
    method once (line 7874) | def once(self, event: str, f: typing.Callable[..., None]) -> None:
    method keyboard (line 7878) | def keyboard(self) -> "Keyboard":
    method mouse (line 7888) | def mouse(self) -> "Mouse":
    method touchscreen (line 7898) | def touchscreen(self) -> "Touchscreen":
    method context (line 7908) | def context(self) -> "BrowserContext":
    method clock (line 7920) | def clock(self) -> "Clock":
    method main_frame (line 7932) | def main_frame(self) -> "Frame":
    method frames (line 7944) | def frames(self) -> typing.List["Frame"]:
    method url (line 7956) | def url(self) -> str:
    method viewport_size (line 7966) | def viewport_size(self) -> typing.Optional[ViewportSize]:
    method workers (line 7976) | def workers(self) -> typing.List["Worker"]:
    method request (line 7991) | def request(self) -> "APIRequestContext":
    method video (line 8005) | def video(self) -> typing.Optional["Video"]:
    method opener (line 8016) | def opener(self) -> typing.Optional["Page"]:
    method frame (line 8028) | def frame(
    method set_default_navigation_timeout (line 8062) | def set_default_navigation_timeout(self, timeout: float) -> None:
    method set_default_timeout (line 8087) | def set_default_timeout(self, timeout: float) -> None:
    method query_selector (line 8104) | def query_selector(
    method query_selector_all (line 8129) | def query_selector_all(self, selector: str) -> typing.List["ElementHan...
    method wait_for_selector (line 8149) | def wait_for_selector(
    method is_checked (line 8224) | def is_checked(
    method is_disabled (line 8260) | def is_disabled(
    method is_editable (line 8296) | def is_editable(
    method is_enabled (line 8332) | def is_enabled(
    method is_hidden (line 8368) | def is_hidden(
    method is_visible (line 8404) | def is_visible(
    method dispatch_event (line 8440) | def dispatch_event(
    method evaluate (line 8513) | def evaluate(
    method evaluate_handle (line 8571) | def evaluate_handle(
    method eval_on_selector (line 8627) | def eval_on_selector(
    method eval_on_selector_all (line 8680) | def eval_on_selector_all(
    method add_script_tag (line 8720) | def add_script_tag(
    method add_style_tag (line 8759) | def add_style_tag(
    method expose_function (line 8792) | def expose_function(self, name: str, callback: typing.Callable) -> None:
    method expose_binding (line 8853) | def expose_binding(
    method set_extra_http_headers (line 8921) | def set_extra_http_headers(self, headers: typing.Dict[str, str]) -> None:
    method content (line 8940) | def content(self) -> str:
    method set_content (line 8952) | def set_content(
    method goto (line 8993) | def goto(
    method reload (line 9061) | def reload(
    method wait_for_load_state (line 9100) | def wait_for_load_state(
    method wait_for_url (line 9155) | def wait_for_url(
    method wait_for_event (line 9204) | def wait_for_event(
    method go_back (line 9244) | def go_back(
    method go_forward (line 9284) | def go_forward(
    method request_gc (line 9324) | def request_gc(self) -> None:
    method emulate_media (line 9346) | def emulate_media(
    method set_viewport_size (line 9421) | def set_viewport_size(self, viewport_size: ViewportSize) -> None:
    method bring_to_front (line 9449) | def bring_to_front(self) -> None:
    method add_init_script (line 9457) | def add_init_script(
    method route (line 9498) | def route(
    method unroute (line 9585) | def unroute(
    method route_web_socket (line 9616) | def route_web_socket(
    method unroute_all (line 9661) | def unroute_all(
    method route_from_har (line 9685) | def route_from_har(
    method screenshot (line 9742) | def screenshot(
    method title (line 9838) | def title(self) -> str:
    method close (line 9850) | def close(
    method is_closed (line 9881) | def is_closed(self) -> bool:
    method click (line 9893) | def click(
    method dblclick (line 9979) | def dblclick(
    method tap (line 10060) | def tap(
    method fill (line 10133) | def fill(
    method locator (line 10189) | def locator(
    method get_by_alt_text (line 10248) | def get_by_alt_text(
    method get_by_label (line 10285) | def get_by_label(
    method get_by_placeholder (line 10326) | def get_by_placeholder(
    method get_by_role (line 10367) | def get_by_role(
    method get_by_test_id (line 10568) | def get_by_test_id(
    method get_by_text (line 10606) | def get_by_text(
    method get_by_title (line 10670) | def get_by_title(
    method frame_locator (line 10709) | def frame_locator(self, selector: str) -> "FrameLocator":
    method focus (line 10737) | def focus(
    method text_content (line 10768) | def text_content(
    method inner_text (line 10804) | def inner_text(
    method inner_html (line 10840) | def inner_html(
    method get_attribute (line 10876) | def get_attribute(
    method hover (line 10915) | def hover(
    method drag_and_drop (line 10986) | def drag_and_drop(
    method select_option (line 11068) | def select_option(
    method input_value (line 11156) | def input_value(
    method set_input_files (line 11196) | def set_input_files(
    method type (line 11251) | def type(
    method press (line 11303) | def press(
    method check (line 11386) | def check(
    method uncheck (line 11450) | def uncheck(
    method wait_for_timeout (line 11514) | def wait_for_timeout(self, timeout: float) -> None:
    method wait_for_function (line 11539) | def wait_for_function(
    method pause (line 11609) | def pause(self) -> None:
    method pdf (line 11623) | def pdf(
    method expect_event (line 11759) | def expect_event(
    method expect_console_message (line 11800) | def expect_console_message(
    method expect_download (line 11831) | def expect_download(
    method expect_file_chooser (line 11862) | def expect_file_chooser(
    method expect_navigation (line 11893) | def expect_navigation(
    method expect_popup (line 11957) | def expect_popup(
    method expect_request (line 11988) | def expect_request(
    method expect_request_finished (line 12035) | def expect_request_finished(
    method expect_response (line 12066) | def expect_response(
    method expect_websocket (line 12115) | def expect_websocket(
    method expect_worker (line 12146) | def expect_worker(
    method set_checked (line 12177) | def set_checked(
    method add_locator_handler (line 12245) | def add_locator_handler(
    method remove_locator_handler (line 12370) | def remove_locator_handler(self, locator: "Locator") -> None:
    method requests (line 12385) | def requests(self) -> typing.List["Request"]:
    method console_messages (line 12404) | def console_messages(self) -> typing.List["ConsoleMessage"]:
    method page_errors (line 12416) | def page_errors(self) -> typing.List["Error"]:
  class WebError (line 12432) | class WebError(SyncBase):
    method page (line 12435) | def page(self) -> typing.Optional["Page"]:
    method error (line 12447) | def error(self) -> "Error":
  class BrowserContext (line 12462) | class BrowserContext(SyncContextManager):
    method on (line 12465) | def on(
    method on (line 12472) | def on(
    method on (line 12482) | def on(
    method on (line 12502) | def on(
    method on (line 12521) | def on(self, event: Literal["page"], f: typing.Callable[["Page"], "Non...
    method on (line 12544) | def on(
    method on (line 12552) | def on(
    method on (line 12563) | def on(
    method on (line 12575) | def on(
    method on (line 12584) | def on(
    method on (line 12593) | def on(
    method on (line 12601) | def on(self, event: str, f: typing.Callable[..., None]) -> None:
    method once (line 12605) | def once(
    method once (line 12612) | def once(
    method once (line 12622) | def once(
    method once (line 12642) | def once(
    method once (line 12661) | def once(
    method once (line 12686) | def once(
    method once (line 12694) | def once(
    method once (line 12705) | def once(
    method once (line 12717) | def once(
    method once (line 12726) | def once(
    method once (line 12735) | def once(
    method once (line 12743) | def once(self, event: str, f: typing.Callable[..., None]) -> None:
    method pages (line 12747) | def pages(self) -> typing.List["Page"]:
    method browser (line 12759) | def browser(self) -> typing.Optional["Browser"]:
    method background_pages (line 12772) | def background_pages(self) -> typing.List["Page"]:
    method service_workers (line 12784) | def service_workers(self) -> typing.List["Worker"]:
    method tracing (line 12798) | def tracing(self) -> "Tracing":
    method request (line 12808) | def request(self) -> "APIRequestContext":
    method clock (line 12820) | def clock(self) -> "Clock":
    method set_default_navigation_timeout (line 12831) | def set_default_navigation_timeout(self, timeout: float) -> None:
    method set_default_timeout (line 12855) | def set_default_timeout(self, timeout: float) -> None:
    method new_page (line 12874) | def new_page(self) -> "Page":
    method cookies (line 12886) | def cookies(
    method add_cookies (line 12908) | def add_cookies(self, cookies: typing.Sequence[SetCookieParam]) -> None:
    method clear_cookies (line 12929) | def clear_cookies(
    method grant_permissions (line 12966) | def grant_permissions(
    method clear_permissions (line 13012) | def clear_permissions(self) -> None:
    method set_geolocation (line 13029) | def set_geolocation(self, geolocation: typing.Optional[Geolocation] = ...
    method set_extra_http_headers (line 13052) | def set_extra_http_headers(self, headers: typing.Dict[str, str]) -> None:
    method set_offline (line 13074) | def set_offline(self, offline: bool) -> None:
    method add_init_script (line 13087) | def add_init_script(
    method expose_binding (line 13128) | def expose_binding(
    method expose_function (line 13194) | def expose_function(self, name: str, callback: typing.Callable) -> None:
    method route (line 13254) | def route(
    method unroute (line 13338) | def unroute(
    method route_web_socket (line 13370) | def route_web_socket(
    method unroute_all (line 13417) | def unroute_all(
    method route_from_har (line 13441) | def route_from_har(
    method expect_event (line 13498) | def expect_event(
    method close (line 13539) | def close(self, *, reason: typing.Optional[str] = None) -> None:
    method storage_state (line 13554) | def storage_state(
    method wait_for_event (line 13584) | def wait_for_event(
    method expect_console_message (line 13624) | def expect_console_message(
    method expect_page (line 13656) | def expect_page(
    method new_cdp_session (line 13687) | def new_cdp_session(self, page: typing.Union["Page", "Frame"]) -> "CDP...
  class CDPSession (line 13711) | class CDPSession(SyncBase):
    method send (line 13713) | def send(
    method detach (line 13736) | def detach(self) -> None:
  class Browser (line 13749) | class Browser(SyncContextManager):
    method on (line 13751) | def on(
    method once (line 13761) | def once(
    method contexts (line 13772) | def contexts(self) -> typing.List["BrowserContext"]:
    method browser_type (line 13793) | def browser_type(self) -> "BrowserType":
    method version (line 13805) | def version(self) -> str:
    method is_connected (line 13816) | def is_connected(self) -> bool:
    method new_context (line 13828) | def new_context(
    method new_page (line 14081) | def new_page(
    method close (line 14318) | def close(self, *, reason: typing.Optional[str] = None) -> None:
    method new_browser_cdp_session (line 14341) | def new_browser_cdp_session(self) -> "CDPSession":
    method start_tracing (line 14355) | def start_tracing(
    method stop_tracing (line 14404) | def stop_tracing(self) -> bytes:
  class BrowserType (line 14425) | class BrowserType(SyncBase):
    method name (line 14428) | def name(self) -> str:
    method executable_path (line 14440) | def executable_path(self) -> str:
    method launch (line 14451) | def launch(
    method launch_persistent_context (line 14588) | def launch_persistent_context(
    method connect_over_cdp (line 14917) | def connect_over_cdp(
    method connect (line 14980) | def connect(
  class Playwright (line 15043) | class Playwright(SyncBase):
    method devices (line 15046) | def devices(self) -> typing.Dict:
    method selectors (line 15075) | def selectors(self) -> "Selectors":
    method chromium (line 15088) | def chromium(self) -> "BrowserType":
    method firefox (line 15100) | def firefox(self) -> "BrowserType":
    method webkit (line 15112) | def webkit(self) -> "BrowserType":
    method request (line 15124) | def request(self) -> "APIRequest":
    method __getitem__ (line 15135) | def __getitem__(self, value: str) -> "BrowserType":
    method stop (line 15139) | def stop(self) -> None:
  class Tracing (line 15166) | class Tracing(SyncBase):
    method start (line 15168) | def start(
    method start_chunk (line 15229) | def start_chunk(
    method stop_chunk (line 15270) | def stop_chunk(
    method stop (line 15285) | def stop(
    method group (line 15300) | def group(
    method group_end (line 15334) | def group_end(self) -> None:
  class Locator (line 15346) | class Locator(SyncBase):
    method page (line 15349) | def page(self) -> "Page":
    method first (line 15361) | def first(self) -> "Locator":
    method last (line 15373) | def last(self) -> "Locator":
    method content_frame (line 15391) | def content_frame(self) -> "FrameLocator":
    method description (line 15417) | def description(self) -> typing.Optional[str]:
    method bounding_box (line 15439) | def bounding_box(
    method check (line 15482) | def check(
    method click (line 15546) | def click(
    method dblclick (line 15647) | def dblclick(
    method dispatch_event (line 15727) | def dispatch_event(
    method evaluate (line 15791) | def evaluate(
    method evaluate_all (line 15844) | def evaluate_all(
    method evaluate_handle (line 15888) | def evaluate_handle(
    method fill (line 15938) | def fill(
    method clear (line 15990) | def clear(
    method locator (line 16037) | def locator(
    method get_by_alt_text (line 16095) | def get_by_alt_text(
    method get_by_label (line 16132) | def get_by_label(
    method get_by_placeholder (line 16173) | def get_by_placeholder(
    method get_by_role (line 16214) | def get_by_role(
    method get_by_test_id (line 16415) | def get_by_test_id(
    method get_by_text (line 16453) | def get_by_text(
    method get_by_title (line 16517) | def get_by_title(
    method frame_locator (line 16556) | def frame_locator(self, selector: str) -> "FrameLocator":
    method element_handle (line 16581) | def element_handle(
    method element_handles (line 16604) | def element_handles(self) -> typing.List["ElementHandle"]:
    method nth (line 16616) | def nth(self, index: int) -> "Locator":
    method describe (line 16638) | def describe(self, description: str) -> "Locator":
    method filter (line 16663) | def filter(
    method or_ (line 16729) | def or_(self, locator: "Locator") -> "Locator":
    method and_ (line 16767) | def and_(self, locator: "Locator") -> "Locator":
    method focus (line 16792) | def focus(self, *, timeout: typing.Optional[float] = None) -> None:
    method blur (line 16808) | def blur(self, *, timeout: typing.Optional[float] = None) -> None:
    method all (line 16822) | def all(self) -> typing.List["Locator"]:
    method count (line 16851) | def count(self) -> int:
    method drag_to (line 16872) | def drag_to(
    method get_attribute (line 16949) | def get_attribute(
    method hover (line 16976) | def hover(
    method inner_html (line 17047) | def inner_html(self, *, timeout: typing.Optional[float] = None) -> str:
    method inner_text (line 17067) | def inner_text(self, *, timeout: typing.Optional[float] = None) -> str:
    method input_value (line 17090) | def input_value(self, *, timeout: typing.Optional[float] = None) -> str:
    method is_checked (line 17126) | def is_checked(self, *, timeout: typing.Optional[float] = None) -> bool:
    method is_disabled (line 17155) | def is_disabled(self, *, timeout: typing.Optional[float] = None) -> bool:
    method is_editable (line 17184) | def is_editable(self, *, timeout: typing.Optional[float] = None) -> bool:
    method is_enabled (line 17215) | def is_enabled(self, *, timeout: typing.Optional[float] = None) -> bool:
    method is_hidden (line 17244) | def is_hidden(self, *, timeout: typing.Optional[float] = None) -> bool:
    method is_visible (line 17272) | def is_visible(self, *, timeout: typing.Optional[float] = None) -> bool:
    method press (line 17300) | def press(
    method screenshot (line 17366) | def screenshot(
    method aria_snapshot (line 17476) | def aria_snapshot(self, *, timeout: typing.Optional[float] = None) -> ...
    method scroll_into_view_if_needed (line 17531) | def scroll_into_view_if_needed(
    method select_option (line 17553) | def select_option(
    method select_text (line 17643) | def select_text(
    method set_input_files (line 17671) | def set_input_files(
    method tap (line 17743) | def tap(
    method text_content (line 17811) | def text_content(
    method type (line 17836) | def type(
    method press_sequentially (line 17875) | def press_sequentially(
    method uncheck (line 17930) | def uncheck(
    method all_inner_texts (line 17994) | def all_inner_texts(self) -> typing.List[str]:
    method all_text_contents (line 18015) | def all_text_contents(self) -> typing.List[str]:
    method wait_for (line 18036) | def wait_for(
    method set_checked (line 18077) | def set_checked(
    method highlight (line 18144) | def highlight(self) -> None:
  class APIResponse (line 18157) | class APIResponse(SyncBase):
    method ok (line 18160) | def ok(self) -> bool:
    method url (line 18172) | def url(self) -> str:
    method status (line 18184) | def status(self) -> int:
    method status_text (line 18196) | def status_text(self) -> str:
    method headers (line 18208) | def headers(self) -> typing.Dict[str, str]:
    method headers_array (line 18220) | def headers_array(self) -> typing.List[NameValue]:
    method body (line 18232) | def body(self) -> bytes:
    method text (line 18244) | def text(self) -> str:
    method json (line 18256) | def json(self) -> typing.Any:
    method dispose (line 18270) | def dispose(self) -> None:
  class APIRequestContext (line 18282) | class APIRequestContext(SyncBase):
    method dispose (line 18284) | def dispose(self, *, reason: typing.Optional[str] = None) -> None:
    method delete (line 18301) | def delete(
    method head (line 18384) | def head(
    method get (line 18467) | def get(
    method patch (line 18562) | def patch(
    method put (line 18645) | def put(
    method post (line 18728) | def post(
    method fetch (line 18842) | def fetch(
    method storage_state (line 18948) | def storage_state(
  class APIRequest (line 18980) | class APIRequest(SyncBase):
    method new_context (line 18982) | def new_context(
  class PageAssertions (line 19085) | class PageAssertions(SyncBase):
    method to_have_title (line 19087) | def to_have_title(
    method not_to_have_title (line 19124) | def not_to_have_title(
    method to_have_url (line 19151) | def to_have_url(
    method not_to_have_url (line 19192) | def not_to_have_url(
  class LocatorAssertions (line 19227) | class LocatorAssertions(SyncBase):
    method to_contain_text (line 19229) | def to_contain_text(
    method not_to_contain_text (line 19323) | def not_to_contain_text(
    method to_have_attribute (line 19366) | def to_have_attribute(
    method not_to_have_attribute (line 19409) | def not_to_have_attribute(
    method to_have_class (line 19443) | def to_have_class(
    method not_to_have_class (line 19502) | def not_to_have_class(
    method to_contain_class (line 19535) | def to_contain_class(
    method not_to_contain_class (line 19598) | def not_to_contain_class(
    method to_have_count (line 19625) | def to_have_count(
    method not_to_have_count (line 19654) | def not_to_have_count(
    method to_have_css (line 19674) | def to_have_css(
    method not_to_have_css (line 19711) | def not_to_have_css(
    method to_have_id (line 19739) | def to_have_id(
    method not_to_have_id (line 19771) | def not_to_have_id(
    method to_have_js_property (line 19794) | def to_have_js_property(
    method not_to_have_js_property (line 19830) | def not_to_have_js_property(
    method to_have_value (line 19856) | def to_have_value(
    method not_to_have_value (line 19890) | def not_to_have_value(
    method to_have_values (line 19913) | def to_have_values(
    method not_to_have_values (line 19966) | def not_to_have_values(
    method to_have_text (line 19997) | def to_have_text(
    method not_to_have_text (line 20090) | def not_to_have_text(
    method to_be_attached (line 20133) | def to_be_attached(
    method to_be_checked (line 20164) | def to_be_checked(
    method not_to_be_attached (line 20205) | def not_to_be_attached(
    method not_to_be_checked (line 20229) | def not_to_be_checked(self, *, timeout: typing.Optional[float] = None)...
    method to_be_disabled (line 20245) | def to_be_disabled(self, *, timeout: typing.Optional[float] = None) ->...
    method not_to_be_disabled (line 20274) | def not_to_be_disabled(self, *, timeout: typing.Optional[float] = None...
    method to_be_editable (line 20290) | def to_be_editable(
    method not_to_be_editable (line 20323) | def not_to_be_editable(
    method to_be_empty (line 20347) | def to_be_empty(self, *, timeout: typing.Optional[float] = None) -> None:
    method not_to_be_empty (line 20372) | def not_to_be_empty(self, *, timeout: typing.Optional[float] = None) -...
    method to_be_enabled (line 20388) | def to_be_enabled(
    method not_to_be_enabled (line 20419) | def not_to_be_enabled(
    method to_be_hidden (line 20443) | def to_be_hidden(self, *, timeout: typing.Optional[float] = None) -> N...
    method not_to_be_hidden (line 20469) | def not_to_be_hidden(self, *, timeout: typing.Optional[float] = None) ...
    method to_be_visible (line 20485) | def to_be_visible(
    method not_to_be_visible (line 20526) | def not_to_be_visible(
    method to_be_focused (line 20550) | def to_be_focused(self, *, timeout: typing.Optional[float] = None) -> ...
    method not_to_be_focused (line 20575) | def not_to_be_focused(self, *, timeout: typing.Optional[float] = None)...
    method to_be_in_viewport (line 20591) | def to_be_in_viewport(
    method not_to_be_in_viewport (line 20630) | def not_to_be_in_viewport(
    method to_have_accessible_description (line 20654) | def to_have_accessible_description(
    method not_to_have_accessible_description (line 20693) | def not_to_have_accessible_description(
    method to_have_accessible_name (line 20724) | def to_have_accessible_name(
    method not_to_have_accessible_name (line 20763) | def not_to_have_accessible_name(
    method to_have_role (line 20794) | def to_have_role(
    method to_have_accessible_error_message (line 20910) | def to_have_accessible_error_message(
    method not_to_have_accessible_error_message (line 20949) | def not_to_have_accessible_error_message(
    method not_to_have_role (line 20980) | def not_to_have_role(
    method to_match_aria_snapshot (line 21086) | def to_match_aria_snapshot(
    method not_to_match_aria_snapshot (line 21119) | def not_to_match_aria_snapshot(
  class APIResponseAssertions (line 21146) | class APIResponseAssertions(SyncBase):
    method to_be_ok (line 21148) | def to_be_ok(self) -> None:
    method not_to_be_ok (line 21167) | def not_to_be_ok(self) -> None:

FILE: scripts/documentation_provider.py
  class DocumentationProvider (line 29) | class DocumentationProvider:
    method __init__ (line 30) | def __init__(self, is_async: bool) -> None:
    method _patch_case (line 44) | def _patch_case(self) -> None:
    method _add_link (line 92) | def _add_link(self, kind: str, clazz: str, member: str, alias: str) ->...
    method print_entry (line 108) | def print_entry(
    method print_events (line 204) | def print_events(self, class_name: str) -> None:
    method indent_paragraph (line 240) | def indent_paragraph(self, p: str, indent: str) -> str:
    method beautify_method_comment (line 247) | def beautify_method_comment(self, comment: str, indent: str) -> str:
    method filter_out_redudant_python_code_snippets (line 279) | def filter_out_redudant_python_code_snippets(self, comment: str) -> str:
    method resolve_playwright_dev_links (line 310) | def resolve_playwright_dev_links(self, comment: str) -> str:
    method render_links (line 323) | def render_links(self, comment: str) -> str:
    method make_optional (line 328) | def make_optional(self, text: str) -> str:
    method compare_types (line 335) | def compare_types(
    method serialize_python_type (line 350) | def serialize_python_type(self, value: Any, direction: str) -> str:
    method serialize_doc_type (line 434) | def serialize_doc_type(self, type: Any, direction: str) -> str:
    method inner_serialize_doc_type (line 438) | def inner_serialize_doc_type(self, type: Any, direction: str) -> str:
    method print_remainder (line 515) | def print_remainder(self) -> None:
  function works_for_python (line 542) | def works_for_python(item: Any) -> bool:
  function name_or_alias (line 546) | def name_or_alias(item: Any) -> str:
  function self_or_override (line 555) | def self_or_override(item: Any) -> Any:
  function apply_type_or_override (line 564) | def apply_type_or_override(member: Any) -> Any:

FILE: scripts/example_async.py
  function main (line 20) | async def main() -> None:

FILE: scripts/example_sync.py
  function main (line 18) | def main() -> None:

FILE: scripts/generate_api.py
  function process_type (line 57) | def process_type(value: Any, param: bool = False) -> str:
  function is_positional_exception (line 101) | def is_positional_exception(key: str) -> bool:
  function signature (line 108) | def signature(func: FunctionType, indent: int) -> str:
  function arguments (line 135) | def arguments(func: FunctionType, indent: int) -> str:
  function return_type (line 172) | def return_type(func: FunctionType) -> str:
  function short_name (line 177) | def short_name(t: Any) -> str:
  function return_value (line 184) | def return_value(value: Any) -> List[str]:
  function get_type_hints (line 303) | def get_type_hints(func: Any, globalns: Any) -> Dict[str, Any]:
  function _get_defaults (line 313) | def _get_defaults(func: Any) -> Dict[str, Any]:

FILE: scripts/generate_async_api.py
  function generate (line 38) | def generate(t: Any) -> None:
  function main (line 128) | def main() -> None:

FILE: scripts/generate_sync_api.py
  function generate (line 39) | def generate(t: Any) -> None:
  function main (line 127) | def main() -> None:

FILE: scripts/update_versions.py
  function main (line 20) | def main() -> None:

FILE: setup.py
  function extractall (line 91) | def extractall(zip: zipfile.ZipFile, path: str) -> None:
  function download_driver (line 100) | def download_driver(zip_name: str) -> None:
  class PlaywrightBDistWheelCommand (line 120) | class PlaywrightBDistWheelCommand(BDistWheelCommand):
    method run (line 121) | def run(self) -> None:
    method _build_wheel (line 147) | def _build_wheel(
    method _download_and_extract_local_driver (line 184) | def _download_and_extract_local_driver(

FILE: tests/assets/client.py
  function main (line 21) | def main(playwright: Playwright, browser_name: str) -> None:

FILE: tests/assets/input/mouse-helper.js
  function updateButtons (line 58) | function updateButtons(buttons) {

FILE: tests/assets/networkidle.js
  function main (line 1) | async function main() {

FILE: tests/assets/sectionselectorengine.js
  method create (line 2) | create(root, target) {
  method query (line 4) | query(root, selector) {
  method queryAll (line 7) | queryAll(root, selector) {

FILE: tests/assets/worker/worker.js
  function workerFunction (line 3) | function workerFunction() {

FILE: tests/async/conftest.py
  function utils (line 41) | def utils() -> Generator[Utils, None, None]:
  function playwright (line 46) | async def playwright() -> AsyncGenerator[Playwright, None]:
  function browser_type (line 52) | def browser_type(playwright: Playwright, browser_name: str) -> BrowserType:
  function browser_factory (line 63) | async def browser_factory(
  function browser (line 79) | async def browser(
  function browser_version (line 88) | def browser_version(browser: Browser) -> str:
  function context_factory (line 93) | async def context_factory(
  function default_same_site_cookie_value (line 109) | def default_same_site_cookie_value(browser_name: str, is_linux: bool) ->...
  function context (line 122) | async def context(
  function page (line 131) | async def page(context: BrowserContext) -> AsyncGenerator[Page, None]:
  function selectors (line 138) | def selectors(playwright: Playwright) -> Selectors:
  class TraceViewerPage (line 142) | class TraceViewerPage:
    method __init__ (line 143) | def __init__(self, page: Page):
    method actions_tree (line 147) | def actions_tree(self) -> Locator:
    method action_titles (line 151) | def action_titles(self) -> Locator:
    method stack_frames (line 155) | def stack_frames(self) -> Locator:
    method select_action (line 158) | async def select_action(self, title: str, ordinal: int = 0) -> None:
    method select_snapshot (line 161) | async def select_snapshot(self, name: str) -> None:
    method snapshot_frame (line 166) | async def snapshot_frame(
    method show_source_tab (line 175) | async def show_source_tab(self) -> None:
    method expand_action (line 178) | async def expand_action(self, title: str, ordinal: int = 0) -> None:
  function show_trace_viewer (line 185) | async def show_trace_viewer(browser: Browser) -> AsyncGenerator[Callable...

FILE: tests/async/test_add_init_script.py
  function test_add_init_script_evaluate_before_anything_else_on_the_page (line 21) | async def test_add_init_script_evaluate_before_anything_else_on_the_page(
  function test_add_init_script_work_with_a_path (line 29) | async def test_add_init_script_work_with_a_path(page: Page, assetdir: Pa...
  function test_add_init_script_work_with_content (line 35) | async def test_add_init_script_work_with_content(page: Page) -> None:
  function test_add_init_script_throw_without_path_and_content (line 41) | async def test_add_init_script_throw_without_path_and_content(page: Page...
  function test_add_init_script_work_with_browser_context_scripts (line 51) | async def test_add_init_script_work_with_browser_context_scripts(
  function test_add_init_script_work_with_browser_context_scripts_with_a_path (line 61) | async def test_add_init_script_work_with_browser_context_scripts_with_a_...
  function test_add_init_script_work_with_browser_context_scripts_for_already_created_pages (line 70) | async def test_add_init_script_work_with_browser_context_scripts_for_alr...
  function test_add_init_script_support_multiple_scripts (line 79) | async def test_add_init_script_support_multiple_scripts(page: Page) -> N...
  function test_should_work_with_trailing_comments (line 87) | async def test_should_work_with_trailing_comments(page: Page) -> None:

FILE: tests/async/test_assertions.py
  function test_assertions_page_to_have_title (line 25) | async def test_assertions_page_to_have_title(page: Page, server: Server)...
  function test_assertions_page_to_have_url (line 52) | async def test_assertions_page_to_have_url(page: Page, server: Server) -...
  function test_assertions_page_to_have_url_with_base_url (line 77) | async def test_assertions_page_to_have_url_with_base_url(
  function test_assertions_page_to_have_url_support_ignore_case (line 87) | async def test_assertions_page_to_have_url_support_ignore_case(page: Pag...
  function test_assertions_locator_to_contain_text (line 92) | async def test_assertions_locator_to_contain_text(page: Page, server: Se...
  function test_assertions_locator_to_contain_text_should_throw_if_arg_is_unsupported_type (line 104) | async def test_assertions_locator_to_contain_text_should_throw_if_arg_is...
  function test_assertions_locator_to_have_attribute (line 111) | async def test_assertions_locator_to_have_attribute(page: Page, server: ...
  function test_assertions_locator_to_have_attribute_ignore_case (line 127) | async def test_assertions_locator_to_have_attribute_ignore_case(
  function test_assertions_locator_to_have_class (line 136) | async def test_assertions_locator_to_have_class(page: Page, server: Serv...
  function test_assertions_locator_to_contain_class (line 148) | async def test_assertions_locator_to_contain_class(page: Page, server: S...
  function test_assertions_locator_to_have_count (line 174) | async def test_assertions_locator_to_have_count(page: Page, server: Serv...
  function test_assertions_locator_to_have_css (line 183) | async def test_assertions_locator_to_have_css(page: Page, server: Server...
  function test_assertions_locator_to_have_id (line 198) | async def test_assertions_locator_to_have_id(page: Page, server: Server)...
  function test_assertions_locator_to_have_js_property (line 207) | async def test_assertions_locator_to_have_js_property(
  function test_to_have_js_property_pass_string (line 225) | async def test_to_have_js_property_pass_string(page: Page) -> None:
  function test_to_have_js_property_fail_string (line 232) | async def test_to_have_js_property_fail_string(page: Page) -> None:
  function test_to_have_js_property_pass_number (line 240) | async def test_to_have_js_property_pass_number(page: Page) -> None:
  function test_to_have_js_property_fail_number (line 247) | async def test_to_have_js_property_fail_number(page: Page) -> None:
  function test_to_have_js_property_pass_boolean (line 255) | async def test_to_have_js_property_pass_boolean(page: Page) -> None:
  function test_to_have_js_property_fail_boolean (line 262) | async def test_to_have_js_property_fail_boolean(page: Page) -> None:
  function test_to_have_js_property_pass_boolean_2 (line 270) | async def test_to_have_js_property_pass_boolean_2(page: Page) -> None:
  function test_to_have_js_property_fail_boolean_2 (line 277) | async def test_to_have_js_property_fail_boolean_2(page: Page) -> None:
  function test_to_have_js_property_pass_null (line 285) | async def test_to_have_js_property_pass_null(page: Page) -> None:
  function test_assertions_locator_to_have_text (line 292) | async def test_assertions_locator_to_have_text(page: Page, server: Serve...
  function test_ignore_case (line 313) | async def test_ignore_case(page: Page, server: Server, method: str) -> N...
  function test_ignore_case_regex (line 353) | async def test_ignore_case_regex(page: Page, server: Server, method: str...
  function test_assertions_locator_to_have_value (line 412) | async def test_assertions_locator_to_have_value(page: Page, server: Serv...
  function test_to_have_values_works_with_text (line 422) | async def test_to_have_values_works_with_text(page: Page, server: Server...
  function test_to_have_values_follows_labels (line 437) | async def test_to_have_values_follows_labels(page: Page, server: Server)...
  function test_to_have_values_exact_match_with_text (line 453) | async def test_to_have_values_exact_match_with_text(page: Page, server: ...
  function test_to_have_values_works_with_regex (line 470) | async def test_to_have_values_works_with_regex(page: Page, server: Serve...
  function test_to_have_values_fails_when_items_not_selected (line 485) | async def test_to_have_values_fails_when_items_not_selected(
  function test_to_have_values_fails_when_multiple_not_specified (line 505) | async def test_to_have_values_fails_when_multiple_not_specified(
  function test_to_have_values_fails_when_not_a_select_element (line 524) | async def test_to_have_values_fails_when_not_a_select_element(
  function test_assertions_locator_to_be_checked (line 538) | async def test_assertions_locator_to_be_checked(page: Page, server: Serv...
  function test_assertions_boolean_checked_with_intermediate_true (line 555) | async def test_assertions_boolean_checked_with_intermediate_true(page: P...
  function test_assertions_boolean_checked_with_intermediate_true_and_checked (line 561) | async def test_assertions_boolean_checked_with_intermediate_true_and_che...
  function test_assertions_boolean_fail_with_indeterminate_true (line 574) | async def test_assertions_boolean_fail_with_indeterminate_true(page: Pag...
  function test_assertions_locator_to_be_disabled_enabled (line 584) | async def test_assertions_locator_to_be_disabled_enabled(
  function test_assertions_locator_to_be_enabled_with_true (line 600) | async def test_assertions_locator_to_be_enabled_with_true(page: Page) ->...
  function test_assertions_locator_to_be_enabled_with_false_throws_good_exception (line 605) | async def test_assertions_locator_to_be_enabled_with_false_throws_good_e...
  function test_assertions_locator_to_be_enabled_with_false (line 613) | async def test_assertions_locator_to_be_enabled_with_false(page: Page) -...
  function test_assertions_locator_to_be_enabled_with_not_and_false (line 618) | async def test_assertions_locator_to_be_enabled_with_not_and_false(page:...
  function test_assertions_locator_to_be_enabled_eventually (line 623) | async def test_assertions_locator_to_be_enabled_eventually(page: Page) -...
  function test_assertions_locator_to_be_enabled_eventually_with_not (line 636) | async def test_assertions_locator_to_be_enabled_eventually_with_not(page...
  function test_assertions_locator_to_be_editable (line 649) | async def test_assertions_locator_to_be_editable(page: Page, server: Ser...
  function test_assertions_locator_to_be_editable_throws (line 655) | async def test_assertions_locator_to_be_editable_throws(
  function test_assertions_locator_to_be_editable_with_true (line 667) | async def test_assertions_locator_to_be_editable_with_true(page: Page) -...
  function test_assertions_locator_to_be_editable_with_false (line 672) | async def test_assertions_locator_to_be_editable_with_false(page: Page) ...
  function test_assertions_locator_to_be_editable_with_false_and_throw_good_exception (line 677) | async def test_assertions_locator_to_be_editable_with_false_and_throw_go...
  function test_assertions_locator_to_be_editable_with_not_and_false (line 685) | async def test_assertions_locator_to_be_editable_with_not_and_false(page...
  function test_assertions_locator_to_be_empty (line 690) | async def test_assertions_locator_to_be_empty(page: Page, server: Server...
  function test_assertions_locator_to_be_focused (line 701) | async def test_assertions_locator_to_be_focused(page: Page, server: Serv...
  function test_assertions_locator_to_be_hidden_visible (line 711) | async def test_assertions_locator_to_be_hidden_visible(
  function test_assertions_locator_to_be_visible_with_true (line 726) | async def test_assertions_locator_to_be_visible_with_true(page: Page) ->...
  function test_assertions_locator_to_be_visible_with_false (line 731) | async def test_assertions_locator_to_be_visible_with_false(page: Page) -...
  function test_assertions_locator_to_be_visible_with_false_throws_good_exception (line 736) | async def test_assertions_locator_to_be_visible_with_false_throws_good_e...
  function test_assertions_locator_to_be_visible_with_not_and_false (line 744) | async def test_assertions_locator_to_be_visible_with_not_and_false(page:...
  function test_assertions_locator_to_be_visible_eventually (line 749) | async def test_assertions_locator_to_be_visible_eventually(page: Page) -...
  function test_assertions_locator_to_be_visible_eventually_with_not (line 762) | async def test_assertions_locator_to_be_visible_eventually_with_not(page...
  function test_assertions_should_serialize_regexp_correctly (line 775) | async def test_assertions_should_serialize_regexp_correctly(
  function test_assertions_response_is_ok_pass (line 799) | async def test_assertions_response_is_ok_pass(page: Page, server: Server...
  function test_assertions_response_is_ok_pass_with_not (line 804) | async def test_assertions_response_is_ok_pass_with_not(
  function test_assertions_response_is_ok_fail (line 811) | async def test_assertions_response_is_ok_fail(page: Page, server: Server...
  function test_should_print_response_with_text_content_type_if_to_be_ok_fails (line 820) | async def test_should_print_response_with_text_content_type_if_to_be_ok_...
  function test_should_print_users_message_for_page_based_assertion (line 878) | async def test_should_print_users_message_for_page_based_assertion(
  function test_should_print_expected_value_with_custom_message (line 891) | async def test_should_print_expected_value_with_custom_message(
  function test_should_be_attached_default (line 908) | async def test_should_be_attached_default(page: Page) -> None:
  function test_should_be_attached_with_hidden_element (line 914) | async def test_should_be_attached_with_hidden_element(page: Page) -> None:
  function test_should_be_attached_with_not (line 920) | async def test_should_be_attached_with_not(page: Page) -> None:
  function test_should_be_attached_with_attached_true (line 926) | async def test_should_be_attached_with_attached_true(page: Page) -> None:
  function test_should_be_attached_with_attached_false (line 932) | async def test_should_be_attached_with_attached_false(page: Page) -> None:
  function test_should_be_attached_with_attached_false_and_throw_good_error (line 938) | async def test_should_be_attached_with_attached_false_and_throw_good_error(
  function test_should_be_attached_with_not_and_attached_false (line 947) | async def test_should_be_attached_with_not_and_attached_false(page: Page...
  function test_should_be_attached_eventually (line 953) | async def test_should_be_attached_eventually(page: Page) -> None:
  function test_should_be_attached_eventually_with_not (line 962) | async def test_should_be_attached_eventually_with_not(page: Page) -> None:
  function test_should_be_attached_fail (line 971) | async def test_should_be_attached_fail(page: Page) -> None:
  function test_should_be_attached_fail_with_not (line 981) | async def test_should_be_attached_fail_with_not(page: Page) -> None:
  function test_should_be_attached_with_impossible_timeout (line 989) | async def test_should_be_attached_with_impossible_timeout(page: Page) ->...
  function test_should_be_attached_with_impossible_timeout_not (line 994) | async def test_should_be_attached_with_impossible_timeout_not(page: Page...
  function test_should_be_attached_with_frame_locator (line 999) | async def test_should_be_attached_with_frame_locator(page: Page) -> None:
  function test_should_be_attached_over_navigation (line 1010) | async def test_should_be_attached_over_navigation(page: Page, server: Se...
  function test_should_be_able_to_set_custom_timeout (line 1020) | async def test_should_be_able_to_set_custom_timeout(page: Page) -> None:
  function test_should_be_able_to_set_custom_global_timeout (line 1026) | async def test_should_be_able_to_set_custom_global_timeout(page: Page) -...
  function test_to_have_accessible_name (line 1036) | async def test_to_have_accessible_name(page: Page) -> None:
  function test_to_have_accessible_error_message (line 1052) | async def test_to_have_accessible_error_message(page: Page) -> None:
  function test_to_have_accessible_error_message_should_handle_multiple_aria_error_message_references (line 1077) | async def test_to_have_accessible_error_message_should_handle_multiple_a...
  function test_to_have_accessible_description (line 1107) | async def test_to_have_accessible_description(page: Page) -> None:
  function test_to_have_role (line 1128) | async def test_to_have_role(page: Page) -> None:

FILE: tests/async/test_asyncio.py
  function test_should_cancel_underlying_protocol_calls (line 26) | async def test_should_cancel_underlying_protocol_calls(
  function test_async_playwright_stop_multiple_times (line 56) | async def test_async_playwright_stop_multiple_times() -> None:
  function test_cancel_pending_protocol_call_on_playwright_stop (line 62) | async def test_cancel_pending_protocol_call_on_playwright_stop(server: S...
  function test_should_not_throw_with_taskgroup (line 73) | async def test_should_not_throw_with_taskgroup(page: Page) -> None:
  function test_should_return_proper_api_name_on_error (line 92) | async def test_should_return_proper_api_name_on_error(page: Page) -> None:

FILE: tests/async/test_browser.py
  function test_should_create_new_page (line 22) | async def test_should_create_new_page(browser: Browser) -> None:
  function test_should_throw_upon_second_create_new_page (line 36) | async def test_should_throw_upon_second_create_new_page(browser: Browser...
  function test_version_should_work (line 44) | async def test_version_should_work(browser: Browser, is_chromium: bool) ...
  function test_should_return_browser_type (line 52) | async def test_should_return_browser_type(

FILE: tests/async/test_browsercontext.py
  function fails_on_401 (line 36) | def fails_on_401(browser_name: str, is_headless_shell: bool) -> bool:
  function test_page_event_should_create_new_context (line 40) | async def test_page_event_should_create_new_context(browser: Browser) ->...
  function test_window_open_should_use_parent_tab_context (line 50) | async def test_window_open_should_use_parent_tab_context(
  function test_page_event_should_isolate_localStorage_and_cookies (line 63) | async def test_page_event_should_isolate_localStorage_and_cookies(
  function test_page_event_should_propagate_default_viewport_to_the_page (line 111) | async def test_page_event_should_propagate_default_viewport_to_the_page(
  function test_page_event_should_respect_device_scale_factor (line 120) | async def test_page_event_should_respect_device_scale_factor(browser: Br...
  function test_page_event_should_not_allow_device_scale_factor_with_null_viewport (line 127) | async def test_page_event_should_not_allow_device_scale_factor_with_null...
  function test_page_event_should_not_allow_is_mobile_with_null_viewport (line 138) | async def test_page_event_should_not_allow_is_mobile_with_null_viewport(
  function test_close_should_work_for_empty_context (line 149) | async def test_close_should_work_for_empty_context(browser: Browser) -> ...
  function test_close_should_abort_wait_for_event (line 154) | async def test_close_should_abort_wait_for_event(browser: Browser) -> None:
  function test_close_should_be_callable_twice (line 162) | async def test_close_should_be_callable_twice(browser: Browser) -> None:
  function test_user_agent_should_work (line 171) | async def test_user_agent_should_work(browser: Browser, server: Server) ...
  function test_user_agent_should_work_for_subframes (line 193) | async def test_user_agent_should_work_for_subframes(
  function test_user_agent_should_emulate_device_user_agent (line 206) | async def test_user_agent_should_emulate_device_user_agent(
  function test_user_agent_should_make_a_copy_of_default_options (line 218) | async def test_user_agent_should_make_a_copy_of_default_options(
  function test_page_event_should_bypass_csp_meta_tag (line 233) | async def test_page_event_should_bypass_csp_meta_tag(
  function test_page_event_should_bypass_csp_header (line 261) | async def test_page_event_should_bypass_csp_header(
  function test_page_event_should_bypass_after_cross_process_navigation (line 292) | async def test_page_event_should_bypass_after_cross_process_navigation(
  function test_page_event_should_bypass_csp_in_iframes_as_well (line 307) | async def test_page_event_should_bypass_csp_in_iframes_as_well(
  function test_csp_should_work (line 341) | async def test_csp_should_work(browser: Browser, is_webkit: bool) -> None:
  function test_csp_should_be_able_to_navigate_after_disabling_javascript (line 366) | async def test_csp_should_be_able_to_navigate_after_disabling_javascript(
  function test_pages_should_return_all_of_the_pages (line 375) | async def test_pages_should_return_all_of_the_pages(
  function test_pages_should_close_all_belonging_pages_once_closing_context (line 386) | async def test_pages_should_close_all_belonging_pages_once_closing_context(
  function test_expose_binding_should_work (line 395) | async def test_expose_binding_should_work(context: BrowserContext) -> None:
  function test_expose_function_should_work (line 412) | async def test_expose_function_should_work(context: BrowserContext) -> N...
  function test_expose_function_should_throw_for_duplicate_registrations (line 426) | async def test_expose_function_should_throw_for_duplicate_registrations(
  function test_expose_function_should_be_callable_from_inside_add_init_script (line 450) | async def test_expose_function_should_be_callable_from_inside_add_init_s...
  function test_expose_bindinghandle_should_work (line 465) | async def test_expose_bindinghandle_should_work(context: BrowserContext)...
  function test_auth_should_fail_without_credentials (line 479) | async def test_auth_should_fail_without_credentials(
  function test_auth_should_work_with_correct_credentials (line 493) | async def test_auth_should_work_with_correct_c
Condensed preview — 379 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,930K chars).
[
  {
    "path": ".azure-pipelines/guardian/SDL/.gdnsuppress",
    "chars": 3962,
    "preview": "{\n  \"hydrated\": false,\n  \"properties\": {\n    \"helpUri\": \"https://eng.ms/docs/microsoft-security/security/azure-security/"
  },
  {
    "path": ".azure-pipelines/publish.yml",
    "chars": 2942,
    "preview": "pr: none\n\ntrigger:\n  tags:\n    include:\n    - '*'\n\nresources:\n  repositories:\n  - repository: 1esPipelines\n    type: git"
  },
  {
    "path": ".claude/skills/playwright-roll/SKILL.md",
    "chars": 1154,
    "preview": "---\nname: playwright-roll\ndescription: Roll Playwright Python to a new version\n---\n\nHelp the user roll to a new version "
  },
  {
    "path": ".gitattributes",
    "chars": 73,
    "preview": "# text files must be lf for golden file tests to work\n* text=auto eol=lf\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug.yml",
    "chars": 3650,
    "preview": "name: Bug Report 🪲\ndescription: Create a bug report to help us improve\ntitle: '[Bug]: '\nbody:\n  - type: markdown\n    att"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 186,
    "preview": "blank_issues_enabled: false\ncontact_links:\n  - name: Join our Discord Server\n    url: https://aka.ms/playwright/discord\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/documentation.yml",
    "chars": 1128,
    "preview": "name: Documentation 📖\ndescription: Submit a request to add or update documentation\ntitle: '[Docs]: '\nlabels: ['Documenta"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature.yml",
    "chars": 813,
    "preview": "name: Feature Request 🚀\ndescription: Submit a proposal for a new feature\ntitle: '[Feature]: '\nbody:\n  - type: markdown\n "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/question.yml",
    "chars": 813,
    "preview": "name: 'Questions / Help 💬'\ndescription: If you have questions, please check StackOverflow or Discord\ntitle: '[Please rea"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/regression.yml",
    "chars": 2903,
    "preview": "name: Report regression\ndescription: Functionality that used to work and does not any more\ntitle: \"[Regression]: \"\n\nbody"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 266,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: \"pip\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n  - package-e"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 6376,
    "preview": "name: CI\n\non:\n  push:\n    branches:\n      - main\n      - release-*\n  pull_request:\n    branches:\n      - main\n      - re"
  },
  {
    "path": ".github/workflows/publish.yml",
    "chars": 1591,
    "preview": "name: Upload Python Package\non:\n  release:\n    types: [published]\n  workflow_dispatch:\njobs:\n  deploy-conda:\n    strateg"
  },
  {
    "path": ".github/workflows/publish_docker.yml",
    "chars": 1308,
    "preview": "name: \"publish release - Docker\"\n\non:\n  workflow_dispatch:\n  release:\n    types: [published]\n\njobs:\n  publish-docker-rel"
  },
  {
    "path": ".github/workflows/test_docker.yml",
    "chars": 1983,
    "preview": "name: Test Docker\non:\n  push:\n    paths:\n      - '.github/workflows/test_docker.yml'\n      - 'setup.py'\n      - '**/Dock"
  },
  {
    "path": ".gitignore",
    "chars": 243,
    "preview": "**/__pycache__/\ndriver/\nplaywright/driver/\nplaywright.egg-info/\nbuild/\ndist/\nvenv/\n.idea/\n**/*.pyc\nenv/\nhtmlcov/\n.covera"
  },
  {
    "path": ".pre-commit-config.yaml",
    "chars": 1403,
    "preview": "# See https://pre-commit.com for more information\n# See https://pre-commit.com/hooks.html for more hooks\nrepos:\n  - repo"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 444,
    "preview": "# Microsoft Open Source Code of Conduct\n\nThis project has adopted the [Microsoft Open Source Code of Conduct](https://op"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 1996,
    "preview": "# Contributing\n\n## How to Contribute\n\n### Configuring python environment\n\nThe project development requires Python versio"
  },
  {
    "path": "LICENSE",
    "chars": 11399,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 2437,
    "preview": "# 🎭 [Playwright](https://playwright.dev) for Python [![PyPI version](https://badge.fury.io/py/playwright.svg)](https://p"
  },
  {
    "path": "ROLLING.md",
    "chars": 828,
    "preview": "# Rolling Playwright-Python to the latest Playwright driver\n\n* checkout repo: `git clone https://github.com/microsoft/pl"
  },
  {
    "path": "SECURITY.md",
    "chars": 2780,
    "preview": "<!-- BEGIN MICROSOFT SECURITY.MD V0.0.5 BLOCK -->\n\n## Security\n\nMicrosoft takes the security of our software products an"
  },
  {
    "path": "SUPPORT.md",
    "chars": 829,
    "preview": "# Support\n\n## How to file issues and get help\n\nThis project uses GitHub issues to track bugs and feature requests. Pleas"
  },
  {
    "path": "conda_build_config_linux_aarch64.yaml",
    "chars": 33,
    "preview": "target_platform:\n- linux-aarch64\n"
  },
  {
    "path": "conda_build_config_osx_arm64.yaml",
    "chars": 29,
    "preview": "target_platform:\n- osx-arm64\n"
  },
  {
    "path": "examples/todomvc/mvctests/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "examples/todomvc/mvctests/test_clear_completed_button.py",
    "chars": 1774,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "examples/todomvc/mvctests/test_counter.py",
    "chars": 1429,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "examples/todomvc/mvctests/test_editing.py",
    "chars": 3049,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "examples/todomvc/mvctests/test_item.py",
    "chars": 3090,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "examples/todomvc/mvctests/test_mark_all_as_completed.py",
    "chars": 2857,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "examples/todomvc/mvctests/test_new_todo.py",
    "chars": 2913,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "examples/todomvc/mvctests/test_persistence.py",
    "chars": 1658,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "examples/todomvc/mvctests/test_routing.py",
    "chars": 3617,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "examples/todomvc/mvctests/utils.py",
    "chars": 1461,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "examples/todomvc/requirements.txt",
    "chars": 18,
    "preview": "pytest-playwright\n"
  },
  {
    "path": "local-requirements.txt",
    "chars": 423,
    "preview": "autobahn==23.1.2\nblack==25.1.0\nbuild==1.3.0\nflake8==7.2.0\nmypy==1.17.1\nobjgraph==3.6.2\nPillow==11.3.0\npixelmatch==0.3.0\n"
  },
  {
    "path": "meta.yaml",
    "chars": 1695,
    "preview": "package:\n  name: playwright\n  version: \"{{ environ.get('GIT_DESCRIBE_TAG') | replace('v', '') }}\"\n\nsource:\n  path: .\n\nbu"
  },
  {
    "path": "playwright/__init__.py",
    "chars": 805,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/__main__.py",
    "chars": 1064,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "playwright/_impl/__pyinstaller/__init__.py",
    "chars": 691,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/__pyinstaller/hook-playwright.async_api.py",
    "chars": 695,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/__pyinstaller/hook-playwright.sync_api.py",
    "chars": 695,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_api_structures.py",
    "chars": 6376,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_artifact.py",
    "chars": 2702,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_assertions.py",
    "chars": 33103,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_async_base.py",
    "chars": 3242,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_browser.py",
    "chars": 9846,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_browser_context.py",
    "chars": 27943,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_browser_type.py",
    "chars": 14029,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_cdp_session.py",
    "chars": 1371,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_clock.py",
    "chars": 3040,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_connection.py",
    "chars": 24234,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_console_message.py",
    "chars": 2635,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_dialog.py",
    "chars": 1877,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_download.py",
    "chars": 1977,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_driver.py",
    "chars": 1399,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_element_handle.py",
    "chars": 14568,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_errors.py",
    "chars": 1761,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_event_context_manager.py",
    "chars": 1044,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_fetch.py",
    "chars": 18308,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_file_chooser.py",
    "chars": 1859,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_frame.py",
    "chars": 28731,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_glob.py",
    "chars": 2269,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_greenlets.py",
    "chars": 1410,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_har_router.py",
    "chars": 4504,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_helper.py",
    "chars": 18840,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_impl_to_api_mapping.py",
    "chars": 4866,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_input.py",
    "chars": 3753,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_js_handle.py",
    "chars": 10159,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_json_pipe.py",
    "chars": 2616,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_local_utils.py",
    "chars": 3354,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_locator.py",
    "chars": 29670,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_map.py",
    "chars": 1045,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_network.py",
    "chars": 35270,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_object_factory.py",
    "chars": 4134,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_page.py",
    "chars": 52615,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_path_utils.py",
    "chars": 958,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_playwright.py",
    "chars": 2091,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_selectors.py",
    "chars": 2636,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_set_input_files_helpers.py",
    "chars": 5605,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_str_utils.py",
    "chars": 2403,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_stream.py",
    "chars": 1673,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_sync_base.py",
    "chars": 4608,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_tracing.py",
    "chars": 5134,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_transport.py",
    "chars": 6227,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_video.py",
    "chars": 2629,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_waiter.py",
    "chars": 5637,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_web_error.py",
    "chars": 1199,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/_impl/_writable_stream.py",
    "chars": 1472,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/async_api/__init__.py",
    "chars": 5489,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/async_api/_context_manager.py",
    "chars": 2041,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/async_api/_generated.py",
    "chars": 846369,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/py.typed",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "playwright/sync_api/__init__.py",
    "chars": 5484,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/sync_api/_context_manager.py",
    "chars": 3643,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "playwright/sync_api/_generated.py",
    "chars": 847667,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "pyproject.toml",
    "chars": 2753,
    "preview": "[build-system]\r\nrequires = [\"setuptools==80.9.0\", \"setuptools-scm==8.3.1\", \"wheel==0.45.1\", \"auditwheel==6.2.0\"]\r\nbuild-"
  },
  {
    "path": "requirements.txt",
    "chars": 264,
    "preview": "# This file was autogenerated by uv via the following command:\n#    uv pip compile pyproject.toml -o requirements.txt\ngr"
  },
  {
    "path": "scripts/documentation_provider.py",
    "chars": 22673,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "scripts/example_async.py",
    "chars": 1023,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "scripts/example_sync.py",
    "chars": 955,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "scripts/expected_api_mismatch.txt",
    "chars": 1933,
    "preview": "# Playwright Python API\n\n# Hidden property\nParameter not documented: Browser.new_context(default_browser_type=)\nParamete"
  },
  {
    "path": "scripts/generate_api.py",
    "chars": 12009,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "scripts/generate_async_api.py",
    "chars": 5127,
    "preview": "#!/usr/bin/env python\n# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Li"
  },
  {
    "path": "scripts/generate_sync_api.py",
    "chars": 5028,
    "preview": "#!/usr/bin/env python\n# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Li"
  },
  {
    "path": "scripts/update_api.sh",
    "chars": 594,
    "preview": "#!/bin/bash\n\nfunction update_api {\n    echo \"Generating $1\"\n    file_name=\"$1\"\n    generate_script=\"$2\"\n    git checkout"
  },
  {
    "path": "scripts/update_versions.py",
    "chars": 1364,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "setup.cfg",
    "chars": 125,
    "preview": "[flake8]\nignore =\n    E501\n    W503\n    E302\n    # Conflicts with black https://github.com/PyCQA/flake8/issues/1921\n    "
  },
  {
    "path": "setup.py",
    "chars": 6832,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "tests/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "tests/assets/beforeunload.html",
    "chars": 208,
    "preview": "<div>beforeunload demo.</div>\n<script>\nwindow.addEventListener('beforeunload', event => {\n  // Chromium & WebKit way.\n  "
  },
  {
    "path": "tests/assets/client-certificates/README.md",
    "chars": 106,
    "preview": "# Client Certificate test-certificates\n\nRegenerate all certificates by running:\n\n```\nbash generate.sh\n```\n"
  },
  {
    "path": "tests/assets/client-certificates/client/localhost/localhost.csr",
    "chars": 1651,
    "preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIIEizCCAnMCAQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0B\nAQEFAAOCAg8AMIICCgK"
  },
  {
    "path": "tests/assets/client-certificates/client/localhost/localhost.ext",
    "chars": 43,
    "preview": "subjectAltName=DNS:localhost,DNS:127.0.0.1\n"
  },
  {
    "path": "tests/assets/client-certificates/client/localhost/localhost.key",
    "chars": 3268,
    "preview": "-----BEGIN PRIVATE KEY-----\nMIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQC7FMh85NYnOwtJ\nhP9Fe7p5Rh73mgUDSAwzql1ADCx"
  },
  {
    "path": "tests/assets/client-certificates/client/localhost/localhost.pem",
    "chars": 1850,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIFKDCCAxCgAwIBAgIBATANBgkqhkiG9w0BAQsFADA2MRIwEAYDVQQDDAlsb2Nh\nbGhvc3QxIDAeBgNVBAoMF0NsaWV"
  },
  {
    "path": "tests/assets/client-certificates/client/self-signed/cert.pem",
    "chars": 1724,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIEyzCCArOgAwIBAgIUUo60oaPj20QM6oeGSn+2CT5j7GYwDQYJKoZIhvcNAQEL\nBQAwDjEMMAoGA1UEAwwDQm9iMB4"
  },
  {
    "path": "tests/assets/client-certificates/client/self-signed/csr.pem",
    "chars": 1578,
    "preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIIEUzCCAjsCAQAwDjEMMAoGA1UEAwwDQm9iMIICIjANBgkqhkiG9w0BAQEFAAOC\nAg8AMIICCgKCAgEAzQM"
  },
  {
    "path": "tests/assets/client-certificates/client/self-signed/key.pem",
    "chars": 3272,
    "preview": "-----BEGIN PRIVATE KEY-----\nMIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDNAxdg5nPcguts\nX2qkOeDanDbAl/VQWil6HBpjK7u"
  },
  {
    "path": "tests/assets/client-certificates/client/trusted/cert.pem",
    "chars": 1797,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIFAzCCAuugAwIBAgIBATANBgkqhkiG9w0BAQsFADA2MRIwEAYDVQQDDAlsb2Nh\nbGhvc3QxIDAeBgNVBAoMF0NsaWV"
  },
  {
    "path": "tests/assets/client-certificates/client/trusted/csr.pem",
    "chars": 1578,
    "preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIIEVTCCAj0CAQAwEDEOMAwGA1UEAwwFQWxpY2UwggIiMA0GCSqGSIb3DQEBAQUA\nA4ICDwAwggIKAoICAQC"
  },
  {
    "path": "tests/assets/client-certificates/client/trusted/key.pem",
    "chars": 3272,
    "preview": "-----BEGIN PRIVATE KEY-----\nMIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQC4ggn74iAHLgOW\nOiOvB2CPe+Hr7W6STYJLZOoqPdh"
  },
  {
    "path": "tests/assets/client-certificates/generate.sh",
    "chars": 2056,
    "preview": "#!/bin/bash\n\n# Client Certificate test-certificates\n\ncd \"$(dirname \"$0\")\"\n\n## Server\n\nopenssl req \\\n\t-x509 \\\n\t-newkey rs"
  },
  {
    "path": "tests/assets/client-certificates/server/server_cert.pem",
    "chars": 1952,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIFdTCCA12gAwIBAgIUFhAlW/DnHoHOFg2CXKBAvwYN4BIwDQYJKoZIhvcNAQEL\nBQAwNjESMBAGA1UEAwwJbG9jYWx"
  },
  {
    "path": "tests/assets/client-certificates/server/server_key.pem",
    "chars": 3272,
    "preview": "-----BEGIN PRIVATE KEY-----\nMIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDYDbBlM8ILtq2x\nKLFUZwU4n7+0VHsO0skCfyNwpSZ"
  },
  {
    "path": "tests/assets/client.py",
    "chars": 1117,
    "preview": "# Copyright (c) Microsoft Corporation.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not"
  },
  {
    "path": "tests/assets/consolelog.html",
    "chars": 160,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>console.log test</title>\n  </head>\n  <body>\n    <script>\n      console.log('y"
  },
  {
    "path": "tests/assets/csp.html",
    "chars": 73,
    "preview": "<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self'\">\n"
  },
  {
    "path": "tests/assets/dom.html",
    "chars": 192,
    "preview": "<div id=\"outer\" name=\"value\"><div id=\"inner\">Text,\nmore text</div></div><input id=\"check\" type=checkbox checked foo=\"bar"
  },
  {
    "path": "tests/assets/download-blob.html",
    "chars": 732,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Blob Download Example</title>\n  </head>\n  <body>\n    <script>\n      const dow"
  },
  {
    "path": "tests/assets/drag-n-drop.html",
    "chars": 881,
    "preview": "<style>\ndiv:not(.mouse-helper) {\n  margin: 0em;\n  padding: 2em;\n}\n#source {\n  color: blue;\n  border: 1px solid black;\n}\n"
  },
  {
    "path": "tests/assets/dummy_bad_browser_executable.js",
    "chars": 38,
    "preview": "#!/usr/bin/env node\n\nprocess.exit(1);\n"
  },
  {
    "path": "tests/assets/empty.html",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "tests/assets/error.html",
    "chars": 208,
    "preview": "<!DOCTYPE html> <script>\nconsole.error('Not a JS error');\na();\n\nfunction a() {\n    b();\n}\n\nfunction b() {\n    c();\n}\n\nfu"
  },
  {
    "path": "tests/assets/es6/.eslintrc",
    "chars": 64,
    "preview": "{\n    \"parserOptions\": {\n        \"sourceType\": \"module\"\n    }\n}\n"
  },
  {
    "path": "tests/assets/es6/es6import.js",
    "chars": 62,
    "preview": "import num from './es6module.js';\nwindow.__es6injected = num;\n"
  },
  {
    "path": "tests/assets/es6/es6module.js",
    "chars": 19,
    "preview": "export default 42;\n"
  },
  {
    "path": "tests/assets/es6/es6pathimport.js",
    "chars": 66,
    "preview": "import num from './es6/es6module.js';\nwindow.__es6injected = num;\n"
  },
  {
    "path": "tests/assets/extension-mv3-simple/content-script.js",
    "chars": 80,
    "preview": "console.log('hey from the content-script');\nself.thisIsTheContentScript = true;\n"
  },
  {
    "path": "tests/assets/extension-mv3-simple/index.js",
    "chars": 63,
    "preview": "// Mock script for background extension\nglobalThis.MAGIC = 42;\n"
  },
  {
    "path": "tests/assets/extension-mv3-simple/manifest.json",
    "chars": 288,
    "preview": "{\n  \"name\": \"Simple extension\",\n  \"version\": \"0.1\",\n  \"background\": {\n    \"service_worker\": \"index.js\"\n  },\n  \"content_s"
  },
  {
    "path": "tests/assets/extension-mv3-with-logging/background.js",
    "chars": 135,
    "preview": "console.log(\"Service worker script loaded\");\n\nchrome.runtime.onInstalled.addListener(() => {\n  console.log(\"Extension in"
  },
  {
    "path": "tests/assets/extension-mv3-with-logging/content.js",
    "chars": 70,
    "preview": "console.log(\"Test console log from a third-party execution context\");\n"
  },
  {
    "path": "tests/assets/extension-mv3-with-logging/manifest.json",
    "chars": 311,
    "preview": "{\n    \"manifest_version\": 3,\n    \"name\": \"Console Log Extension\",\n    \"version\": \"1.0\",\n    \"background\": {\n      \"servi"
  },
  {
    "path": "tests/assets/file-to-upload-2.txt",
    "chars": 21,
    "preview": "contents of the file\n"
  },
  {
    "path": "tests/assets/file-to-upload.txt",
    "chars": 21,
    "preview": "contents of the file\n"
  },
  {
    "path": "tests/assets/frames/child-redirect.html",
    "chars": 50,
    "preview": "<iframe src='./redirect-my-parent.html'></iframe>\n"
  },
  {
    "path": "tests/assets/frames/frame.html",
    "chars": 254,
    "preview": "<link rel='stylesheet' href='./style.css'>\n<script src='./script.js' type='text/javascript'></script>\n<style>\nbody {\n  h"
  },
  {
    "path": "tests/assets/frames/frameset.html",
    "chars": 181,
    "preview": "<frameset>\n  <frameset>\n    <frame src='./frame.html'></frame>\n    <frame src='about:blank'></frame>\n  </frameset>\n  <fr"
  },
  {
    "path": "tests/assets/frames/nested-frames.html",
    "chars": 595,
    "preview": "<style>\nbody {\n    display: flex;\n    height: 500px;\n    margin: 8px;\n}\n\nbody iframe {\n    flex-grow: 1;\n    flex-shrink"
  },
  {
    "path": "tests/assets/frames/one-frame.html",
    "chars": 37,
    "preview": "<iframe src='./frame.html'></iframe>\n"
  },
  {
    "path": "tests/assets/frames/redirect-my-parent.html",
    "chars": 66,
    "preview": "<script>\n  window.parent.location = './one-frame.html';\n</script>\n"
  },
  {
    "path": "tests/assets/frames/script.js",
    "chars": 24,
    "preview": "console.log('Cheers!');\n"
  },
  {
    "path": "tests/assets/frames/style.css",
    "chars": 25,
    "preview": "div {\n    color: blue;\n}\n"
  },
  {
    "path": "tests/assets/frames/two-frames.html",
    "chars": 275,
    "preview": "<style>\nbody {\n    display: flex;\n    flex-direction: column;\n    height: 400px;\n    margin: 8px;\n}\n\nbody iframe {\n    f"
  },
  {
    "path": "tests/assets/geolocation.html",
    "chars": 230,
    "preview": "<script>\n\twindow.geolocationPromise = new Promise(resolve => {\n\t\tnavigator.geolocation.getCurrentPosition(position => {\n"
  },
  {
    "path": "tests/assets/global-var.html",
    "chars": 42,
    "preview": "<script>\n  var globalVar = 123;\n</script>\n"
  },
  {
    "path": "tests/assets/grid.html",
    "chars": 1211,
    "preview": "<script>\ndocument.addEventListener('DOMContentLoaded', function() {\n    function generatePalette(amount) {\n        var r"
  },
  {
    "path": "tests/assets/har-fulfill.har",
    "chars": 10288,
    "preview": "{\n  \"log\": {\n    \"version\": \"1.2\",\n    \"creator\": {\n      \"name\": \"Playwright\",\n      \"version\": \"1.23.0-next\"\n    },\n  "
  },
  {
    "path": "tests/assets/har-redirect.har",
    "chars": 18527,
    "preview": "{\n  \"log\": {\n    \"version\": \"1.2\",\n    \"creator\": {\n      \"name\": \"Playwright\",\n      \"version\": \"1.23.0-next\"\n    },\n  "
  },
  {
    "path": "tests/assets/har-sha1-main-response.txt",
    "chars": 12,
    "preview": "Hello, world"
  },
  {
    "path": "tests/assets/har-sha1.har",
    "chars": 2540,
    "preview": "{\n  \"log\": {\n    \"version\": \"1.2\",\n    \"creator\": {\n      \"name\": \"Playwright\",\n      \"version\": \"1.23.0-next\"\n    },\n  "
  },
  {
    "path": "tests/assets/har.html",
    "chars": 96,
    "preview": "<title>HAR Page</title>\n<link rel='stylesheet' href='./one-style.css'>\n<div>hello, world!</div>\n"
  },
  {
    "path": "tests/assets/headings.html",
    "chars": 180,
    "preview": "<!DOCTYPE html>\n<html>\n\n<head>\n    <title>Headings</title>\n</head>\n\n<body>\n    <h1>Title</h1>\n    <h2>Subtitle</h2>\n    "
  },
  {
    "path": "tests/assets/historyapi.html",
    "chars": 110,
    "preview": "<script>\nwindow.addEventListener('DOMContentLoaded', () => {\n  history.pushState({}, '', '#1');\n});\n</script>\n"
  },
  {
    "path": "tests/assets/injectedfile.js",
    "chars": 89,
    "preview": "window.__injected = 42;\nwindow.injected = 123;\nwindow.__injectedError = new Error('hi');\n"
  },
  {
    "path": "tests/assets/injectedstyle.css",
    "chars": 34,
    "preview": "body {\n  background-color: red;\n}\n"
  },
  {
    "path": "tests/assets/input/animating-button.html",
    "chars": 979,
    "preview": "<style>\n  body, html { margin: 0; padding: 0; }\n  @keyframes move {\n    from { marign-left: 0; }\n    to   { margin-left:"
  },
  {
    "path": "tests/assets/input/button.html",
    "chars": 862,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Button test</title>\n  </head>\n  <body>\n    <script src=\"mouse-helper.js\"></sc"
  },
  {
    "path": "tests/assets/input/checkbox.html",
    "chars": 881,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Selection Test</title>\n  </head>\n  <body>\n    <label for=\"agree\">Remember Me<"
  },
  {
    "path": "tests/assets/input/fileupload-multi.html",
    "chars": 265,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>File upload test</title>\n  </head>\n  <body>\n    <form action=\"/upload\" method"
  },
  {
    "path": "tests/assets/input/fileupload.html",
    "chars": 256,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>File upload test</title>\n  </head>\n  <body>\n    <form action=\"/upload\" method"
  },
  {
    "path": "tests/assets/input/folderupload.html",
    "chars": 274,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Folder upload test</title>\n  </head>\n  <body>\n    <form action=\"/upload\" meth"
  },
  {
    "path": "tests/assets/input/handle-locator.html",
    "chars": 2571,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Interstitial test</title>\n  </head>\n  <body>\n    <style>\n      body {\n       "
  },
  {
    "path": "tests/assets/input/keyboard.html",
    "chars": 1201,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Keyboard test</title>\n  </head>\n  <body>\n    <textarea></textarea>\n    <scrip"
  },
  {
    "path": "tests/assets/input/mouse-helper.js",
    "chars": 1729,
    "preview": "// This injects a box into the page that moves with the mouse;\n// Useful for debugging\n(function(){\n  const box = docume"
  },
  {
    "path": "tests/assets/input/rotatedButton.html",
    "chars": 422,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Rotated button test</title>\n  </head>\n  <body>\n    <script src=\"mouse-helper."
  },
  {
    "path": "tests/assets/input/scrollable.html",
    "chars": 709,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Scrollable test</title>\n  </head>\n  <body>\n    <script src='mouse-helper.js'>"
  },
  {
    "path": "tests/assets/input/select.html",
    "chars": 2099,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Selection Test</title>\n  </head>\n  <body>\n    <select>\n      <option value=\"b"
  },
  {
    "path": "tests/assets/input/textarea.html",
    "chars": 604,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Textarea test</title>\n  </head>\n  <body>\n    <textarea spellcheck=\"false\"></t"
  },
  {
    "path": "tests/assets/input/touches.html",
    "chars": 1101,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Touch test</title>\n  </head>\n  <body>\n    <script src=\"mouse-helper.js\"></scr"
  },
  {
    "path": "tests/assets/mobile.html",
    "chars": 75,
    "preview": "<meta name = \"viewport\" content = \"initial-scale = 1, user-scalable = no\">\n"
  },
  {
    "path": "tests/assets/networkidle.html",
    "chars": 39,
    "preview": "<script src='networkidle.js'></script>\n"
  },
  {
    "path": "tests/assets/networkidle.js",
    "chars": 314,
    "preview": "async function main() {\n  window.ws = new WebSocket('ws://localhost:' + window.location.port + '/ws');\n  window.ws.addEv"
  },
  {
    "path": "tests/assets/offscreenbuttons.html",
    "chars": 1296,
    "preview": "<style>\n  button {\n    position: absolute;\n    width: 100px;\n    height: 20px;\n    margin: 0;\n  }\n\n  body, html {\n    ma"
  },
  {
    "path": "tests/assets/one-style.css",
    "chars": 37,
    "preview": "body {\n    background-color: pink;\n}\n"
  },
  {
    "path": "tests/assets/one-style.html",
    "chars": 72,
    "preview": "<link rel='stylesheet' href='./one-style.css'>\n<div>hello, world!</div>\n"
  },
  {
    "path": "tests/assets/playground.html",
    "chars": 300,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Playground</title>\n  </head>\n  <body>\n    <button>A button</button>\n    <text"
  },
  {
    "path": "tests/assets/popup/popup.html",
    "chars": 191,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Popup</title>\n    <script>\n      window.initialUserAgent = navigator.userAgen"
  },
  {
    "path": "tests/assets/popup/window-open.html",
    "chars": 161,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Popup test</title>\n  </head>\n  <body>\n    <script>\n      window.open('./popup"
  },
  {
    "path": "tests/assets/react.html",
    "chars": 1011,
    "preview": "<head>\n  <script src=\"./react/react@16.13.1.production.min.js\"></script>\n  <script src=\"./react/react-dom@16.13.1.produc"
  },
  {
    "path": "tests/assets/sectionselectorengine.js",
    "chars": 199,
    "preview": "({\n  create(root, target) {\n  },\n  query(root, selector) {\n    return root.querySelector('section');\n  },\n  queryAll(roo"
  },
  {
    "path": "tests/assets/self-request.html",
    "chars": 106,
    "preview": "<script>\nvar req = new XMLHttpRequest();\nreq.open('GET', '/self-request.html');\nreq.send(null);\n</script>\n"
  },
  {
    "path": "tests/assets/serviceworkers/empty/sw.html",
    "chars": 93,
    "preview": "<script>\n  window.registrationPromise = navigator.serviceWorker.register('sw.js');\n</script>\n"
  },
  {
    "path": "tests/assets/serviceworkers/empty/sw.js",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "tests/assets/serviceworkers/fetch/style.css",
    "chars": 37,
    "preview": "body {\n    background-color: pink;\n}\n"
  },
  {
    "path": "tests/assets/serviceworkers/fetch/sw.html",
    "chars": 243,
    "preview": "<link rel=\"stylesheet\" href=\"./style.css\">\n<script>\n  window.registrationPromise = navigator.serviceWorker.register('sw."
  }
]

// ... and 179 more files (download for full content)

About this extraction

This page contains the full source code of the microsoft/playwright-python GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 379 files (3.6 MB), approximately 953.0k tokens, and a symbol index with 4795 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!