# 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 import sys import typing if sys.version_info >= (3, 8): # pragma: no cover from typing import Literal else: # pragma: no cover from typing_extensions import Literal from playwright._impl._accessibility import Accessibility as AccessibilityImpl from playwright._impl._api_structures import ( Cookie, FilePayload, FloatRect, Geolocation, HttpCredentials, NameValue, PdfMargins, Position, ProxySettings, RemoteAddr, RequestSizes, ResourceTiming, SecurityDetails, SetCookieParam, SourceLocation, StorageState, ViewportSize, ) from playwright._impl._assertions import ( APIResponseAssertions as APIResponseAssertionsImpl, ) from playwright._impl._assertions import LocatorAssertions as LocatorAssertionsImpl from playwright._impl._assertions import PageAssertions as PageAssertionsImpl from playwright._impl._async_base import ( AsyncBase, AsyncContextManager, AsyncEventContextManager, mapping, ) from playwright._impl._browser import Browser as BrowserImpl from playwright._impl._browser_context import BrowserContext as BrowserContextImpl from playwright._impl._browser_type import BrowserType as BrowserTypeImpl from playwright._impl._cdp_session import CDPSession as CDPSessionImpl from playwright._impl._console_message import ConsoleMessage as ConsoleMessageImpl from playwright._impl._dialog import Dialog as DialogImpl from playwright._impl._download import Download as DownloadImpl from playwright._impl._element_handle import ElementHandle as ElementHandleImpl from playwright._impl._errors import Error from playwright._impl._fetch import APIRequest as APIRequestImpl from playwright._impl._fetch import APIRequestContext as APIRequestContextImpl from playwright._impl._fetch import APIResponse as APIResponseImpl from playwright._impl._file_chooser import FileChooser as FileChooserImpl from playwright._impl._frame import Frame as FrameImpl from playwright._impl._input import Keyboard as KeyboardImpl from playwright._impl._input import Mouse as MouseImpl from playwright._impl._input import Touchscreen as TouchscreenImpl from playwright._impl._js_handle import JSHandle as JSHandleImpl from playwright._impl._locator import FrameLocator as FrameLocatorImpl from playwright._impl._locator import Locator as LocatorImpl from playwright._impl._network import Request as RequestImpl from playwright._impl._network import Response as ResponseImpl from playwright._impl._network import Route as RouteImpl from playwright._impl._network import WebSocket as WebSocketImpl from playwright._impl._page import Page as PageImpl from playwright._impl._page import Worker as WorkerImpl from playwright._impl._playwright import Playwright as PlaywrightImpl from playwright._impl._selectors import Selectors as SelectorsImpl from playwright._impl._tracing import Tracing as TracingImpl from playwright._impl._video import Video as VideoImpl from playwright._impl._web_error import WebError as WebErrorImpl class Request(AsyncBase): @property def url(self) -> str: """Request.url URL of the request. Returns ------- str """ return mapping.from_maybe_impl(self._impl_obj.url) @property def resource_type(self) -> str: """Request.resource_type Contains the request's resource type as it was perceived by the rendering engine. ResourceType will be one of the following: `document`, `stylesheet`, `image`, `media`, `font`, `script`, `texttrack`, `xhr`, `fetch`, `eventsource`, `websocket`, `manifest`, `other`. Returns ------- str """ return mapping.from_maybe_impl(self._impl_obj.resource_type) @property def method(self) -> str: """Request.method Request's method (GET, POST, etc.) Returns ------- str """ return mapping.from_maybe_impl(self._impl_obj.method) @property def post_data(self) -> typing.Optional[str]: """Request.post_data Request's post body, if any. Returns ------- Union[str, None] """ return mapping.from_maybe_impl(self._impl_obj.post_data) @property def post_data_json(self) -> typing.Optional[typing.Any]: """Request.post_data_json Returns parsed request's body for `form-urlencoded` and JSON as a fallback if any. When the response is `application/x-www-form-urlencoded` then a key/value object of the values will be returned. Otherwise it will be parsed as JSON. Returns ------- Union[Any, None] """ return mapping.from_maybe_impl(self._impl_obj.post_data_json) @property def post_data_buffer(self) -> typing.Optional[bytes]: """Request.post_data_buffer Request's post body in a binary form, if any. Returns ------- Union[bytes, None] """ return mapping.from_maybe_impl(self._impl_obj.post_data_buffer) @property def frame(self) -> "Frame": """Request.frame Returns the `Frame` that initiated this request. **Usage** ```py frame_url = request.frame.url ``` **Details** Note that in some cases the frame is not available, and this method will throw. - When request originates in the Service Worker. You can use `request.serviceWorker()` to check that. - When navigation request is issued before the corresponding frame is created. You can use `request.is_navigation_request()` to check that. Here is an example that handles all the cases: Returns ------- Frame """ return mapping.from_impl(self._impl_obj.frame) @property def redirected_from(self) -> typing.Optional["Request"]: """Request.redirected_from Request that was redirected by the server to this one, if any. When the server responds with a redirect, Playwright creates a new `Request` object. The two requests are connected by `redirectedFrom()` and `redirectedTo()` methods. When multiple server redirects has happened, it is possible to construct the whole redirect chain by repeatedly calling `redirectedFrom()`. **Usage** For example, if the website `http://example.com` redirects to `https://example.com`: ```py response = await page.goto(\"http://example.com\") print(response.request.redirected_from.url) # \"http://example.com\" ``` ```py response = page.goto(\"http://example.com\") print(response.request.redirected_from.url) # \"http://example.com\" ``` If the website `https://google.com` has no redirects: ```py response = await page.goto(\"https://google.com\") print(response.request.redirected_from) # None ``` ```py response = page.goto(\"https://google.com\") print(response.request.redirected_from) # None ``` Returns ------- Union[Request, None] """ return mapping.from_impl_nullable(self._impl_obj.redirected_from) @property def redirected_to(self) -> typing.Optional["Request"]: """Request.redirected_to New request issued by the browser if the server responded with redirect. **Usage** This method is the opposite of `request.redirected_from()`: ```py assert request.redirected_from.redirected_to == request ``` Returns ------- Union[Request, None] """ return mapping.from_impl_nullable(self._impl_obj.redirected_to) @property def failure(self) -> typing.Optional[str]: """Request.failure The method returns `null` unless this request has failed, as reported by `requestfailed` event. **Usage** Example of logging of all the failed requests: ```py page.on(\"requestfailed\", lambda request: print(request.url + \" \" + request.failure)) ``` Returns ------- Union[str, None] """ return mapping.from_maybe_impl(self._impl_obj.failure) @property def timing(self) -> ResourceTiming: """Request.timing Returns resource timing information for given request. Most of the timing values become available upon the response, `responseEnd` becomes available when request finishes. Find more information at [Resource Timing API](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming). **Usage** ```py async with page.expect_event(\"requestfinished\") as request_info: await page.goto(\"http://example.com\") request = await request_info.value print(request.timing) ``` ```py with page.expect_event(\"requestfinished\") as request_info: page.goto(\"http://example.com\") request = request_info.value print(request.timing) ``` Returns ------- {startTime: float, domainLookupStart: float, domainLookupEnd: float, connectStart: float, secureConnectionStart: float, connectEnd: float, requestStart: float, responseStart: float, responseEnd: float} """ return mapping.from_impl(self._impl_obj.timing) @property def headers(self) -> typing.Dict[str, str]: """Request.headers An object with the request HTTP headers. The header names are lower-cased. Note that this method does not return security-related headers, including cookie-related ones. You can use `request.all_headers()` for complete list of headers that include `cookie` information. Returns ------- Dict[str, str] """ return mapping.from_maybe_impl(self._impl_obj.headers) async def sizes(self) -> RequestSizes: """Request.sizes Returns resource size information for given request. Returns ------- {requestBodySize: int, requestHeadersSize: int, responseBodySize: int, responseHeadersSize: int} """ return mapping.from_impl(await self._impl_obj.sizes()) async def response(self) -> typing.Optional["Response"]: """Request.response Returns the matching `Response` object, or `null` if the response was not received due to error. Returns ------- Union[Response, None] """ return mapping.from_impl_nullable(await self._impl_obj.response()) def is_navigation_request(self) -> bool: """Request.is_navigation_request Whether this request is driving frame's navigation. Some navigation requests are issued before the corresponding frame is created, and therefore do not have `request.frame()` available. Returns ------- bool """ return mapping.from_maybe_impl(self._impl_obj.is_navigation_request()) async def all_headers(self) -> typing.Dict[str, str]: """Request.all_headers An object with all the request HTTP headers associated with this request. The header names are lower-cased. Returns ------- Dict[str, str] """ return mapping.from_maybe_impl(await self._impl_obj.all_headers()) async def headers_array(self) -> typing.List[NameValue]: """Request.headers_array An array with all the request HTTP headers associated with this request. Unlike `request.all_headers()`, header names are NOT lower-cased. Headers with multiple entries, such as `Set-Cookie`, appear in the array multiple times. Returns ------- List[{name: str, value: str}] """ return mapping.from_impl_list(await self._impl_obj.headers_array()) async def header_value(self, name: str) -> typing.Optional[str]: """Request.header_value Returns the value of the header matching the name. The name is case insensitive. Parameters ---------- name : str Name of the header. Returns ------- Union[str, None] """ return mapping.from_maybe_impl(await self._impl_obj.header_value(name=name)) mapping.register(RequestImpl, Request) class Response(AsyncBase): @property def url(self) -> str: """Response.url Contains the URL of the response. Returns ------- str """ return mapping.from_maybe_impl(self._impl_obj.url) @property def ok(self) -> bool: """Response.ok Contains a boolean stating whether the response was successful (status in the range 200-299) or not. Returns ------- bool """ return mapping.from_maybe_impl(self._impl_obj.ok) @property def status(self) -> int: """Response.status Contains the status code of the response (e.g., 200 for a success). Returns ------- int """ return mapping.from_maybe_impl(self._impl_obj.status) @property def status_text(self) -> str: """Response.status_text Contains the status text of the response (e.g. usually an \"OK\" for a success). Returns ------- str """ return mapping.from_maybe_impl(self._impl_obj.status_text) @property def headers(self) -> typing.Dict[str, str]: """Response.headers An object with the response HTTP headers. The header names are lower-cased. Note that this method does not return security-related headers, including cookie-related ones. You can use `response.all_headers()` for complete list of headers that include `cookie` information. Returns ------- Dict[str, str] """ return mapping.from_maybe_impl(self._impl_obj.headers) @property def from_service_worker(self) -> bool: """Response.from_service_worker Indicates whether this Response was fulfilled by a Service Worker's Fetch Handler (i.e. via [FetchEvent.respondWith](https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent/respondWith)). Returns ------- bool """ return mapping.from_maybe_impl(self._impl_obj.from_service_worker) @property def request(self) -> "Request": """Response.request Returns the matching `Request` object. Returns ------- Request """ return mapping.from_impl(self._impl_obj.request) @property def frame(self) -> "Frame": """Response.frame Returns the `Frame` that initiated this response. Returns ------- Frame """ return mapping.from_impl(self._impl_obj.frame) async def all_headers(self) -> typing.Dict[str, str]: """Response.all_headers An object with all the response HTTP headers associated with this response. Returns ------- Dict[str, str] """ return mapping.from_maybe_impl(await self._impl_obj.all_headers()) async def headers_array(self) -> typing.List[NameValue]: """Response.headers_array An array with all the request HTTP headers associated with this response. Unlike `response.all_headers()`, header names are NOT lower-cased. Headers with multiple entries, such as `Set-Cookie`, appear in the array multiple times. Returns ------- List[{name: str, value: str}] """ return mapping.from_impl_list(await self._impl_obj.headers_array()) async def header_value(self, name: str) -> typing.Optional[str]: """Response.header_value Returns the value of the header matching the name. The name is case insensitive. If multiple headers have the same name (except `set-cookie`), they are returned as a list separated by `, `. For `set-cookie`, the `\\n` separator is used. If no headers are found, `null` is returned. Parameters ---------- name : str Name of the header. Returns ------- Union[str, None] """ return mapping.from_maybe_impl(await self._impl_obj.header_value(name=name)) async def header_values(self, name: str) -> typing.List[str]: """Response.header_values Returns all values of the headers matching the name, for example `set-cookie`. The name is case insensitive. Parameters ---------- name : str Name of the header. Returns ------- List[str] """ return mapping.from_maybe_impl(await self._impl_obj.header_values(name=name)) async def server_addr(self) -> typing.Optional[RemoteAddr]: """Response.server_addr Returns the IP address and port of the server. Returns ------- Union[{ipAddress: str, port: int}, None] """ return mapping.from_impl_nullable(await self._impl_obj.server_addr()) async def security_details(self) -> typing.Optional[SecurityDetails]: """Response.security_details Returns SSL and other security information. Returns ------- Union[{issuer: Union[str, None], protocol: Union[str, None], subjectName: Union[str, None], validFrom: Union[float, None], validTo: Union[float, None]}, None] """ return mapping.from_impl_nullable(await self._impl_obj.security_details()) async def finished(self) -> None: """Response.finished Waits for this response to finish, returns always `null`. """ return mapping.from_maybe_impl(await self._impl_obj.finished()) async def body(self) -> bytes: """Response.body Returns the buffer with response body. Returns ------- bytes """ return mapping.from_maybe_impl(await self._impl_obj.body()) async def text(self) -> str: """Response.text Returns the text representation of response body. Returns ------- str """ return mapping.from_maybe_impl(await self._impl_obj.text()) async def json(self) -> typing.Any: """Response.json Returns the JSON representation of response body. This method will throw if the response body is not parsable via `JSON.parse`. Returns ------- Any """ return mapping.from_maybe_impl(await self._impl_obj.json()) mapping.register(ResponseImpl, Response) class Route(AsyncBase): @property def request(self) -> "Request": """Route.request A request to be routed. Returns ------- Request """ return mapping.from_impl(self._impl_obj.request) async def abort(self, error_code: typing.Optional[str] = None) -> None: """Route.abort Aborts the route's request. Parameters ---------- error_code : Union[str, None] Optional error code. Defaults to `failed`, could be one of the following: - `'aborted'` - An operation was aborted (due to user action) - `'accessdenied'` - Permission to access a resource, other than the network, was denied - `'addressunreachable'` - The IP address is unreachable. This usually means that there is no route to the specified host or network. - `'blockedbyclient'` - The client chose to block the request. - `'blockedbyresponse'` - The request failed because the response was delivered along with requirements which are not met ('X-Frame-Options' and 'Content-Security-Policy' ancestor checks, for instance). - `'connectionaborted'` - A connection timed out as a result of not receiving an ACK for data sent. - `'connectionclosed'` - A connection was closed (corresponding to a TCP FIN). - `'connectionfailed'` - A connection attempt failed. - `'connectionrefused'` - A connection attempt was refused. - `'connectionreset'` - A connection was reset (corresponding to a TCP RST). - `'internetdisconnected'` - The Internet connection has been lost. - `'namenotresolved'` - The host name could not be resolved. - `'timedout'` - An operation timed out. - `'failed'` - A generic failure occurred. """ return mapping.from_maybe_impl(await self._impl_obj.abort(errorCode=error_code)) async def fulfill( self, *, status: typing.Optional[int] = None, headers: typing.Optional[typing.Dict[str, str]] = None, body: typing.Optional[typing.Union[str, bytes]] = None, json: typing.Optional[typing.Any] = None, path: typing.Optional[typing.Union[str, pathlib.Path]] = None, content_type: typing.Optional[str] = None, response: typing.Optional["APIResponse"] = None ) -> None: """Route.fulfill Fulfills route's request with given response. **Usage** An example of fulfilling all requests with 404 responses: ```py await page.route(\"**/*\", lambda route: route.fulfill( status=404, content_type=\"text/plain\", body=\"not found!\")) ``` ```py page.route(\"**/*\", lambda route: route.fulfill( status=404, content_type=\"text/plain\", body=\"not found!\")) ``` An example of serving static file: ```py await page.route(\"**/xhr_endpoint\", lambda route: route.fulfill(path=\"mock_data.json\")) ``` ```py page.route(\"**/xhr_endpoint\", lambda route: route.fulfill(path=\"mock_data.json\")) ``` Parameters ---------- status : Union[int, None] Response status code, defaults to `200`. headers : Union[Dict[str, str], None] Response headers. Header values will be converted to a string. body : Union[bytes, str, None] Response body. json : Union[Any, None] JSON response. This method will set the content type to `application/json` if not set. path : Union[pathlib.Path, str, None] File path to respond with. The content type will be inferred from file extension. If `path` is a relative path, then it is resolved relative to the current working directory. content_type : Union[str, None] If set, equals to setting `Content-Type` response header. response : Union[APIResponse, None] `APIResponse` to fulfill route's request with. Individual fields of the response (such as headers) can be overridden using fulfill options. """ return mapping.from_maybe_impl( await self._impl_obj.fulfill( status=status, headers=mapping.to_impl(headers), body=body, json=mapping.to_impl(json), path=path, contentType=content_type, response=response._impl_obj if response else None, ) ) async def fetch( self, *, url: typing.Optional[str] = None, method: typing.Optional[str] = None, headers: typing.Optional[typing.Dict[str, str]] = None, post_data: typing.Optional[typing.Union[typing.Any, str, bytes]] = None, max_redirects: typing.Optional[int] = None, timeout: typing.Optional[float] = None ) -> "APIResponse": """Route.fetch Performs the request and fetches result without fulfilling it, so that the response could be modified and then fulfilled. **Usage** ```py async def handle(route): response = await route.fetch() json = await response.json() json[\"message\"][\"big_red_dog\"] = [] await route.fulfill(response=response, json=json) await page.route(\"https://dog.ceo/api/breeds/list/all\", handle) ``` ```py def handle(route): response = route.fetch() json = response.json() json[\"message\"][\"big_red_dog\"] = [] route.fulfill(response=response, json=json) page.route(\"https://dog.ceo/api/breeds/list/all\", handle) ``` **Details** Note that `headers` option will apply to the fetched request as well as any redirects initiated by it. If you want to only apply `headers` to the original request, but not to redirects, look into `route.continue_()` instead. Parameters ---------- url : Union[str, None] If set changes the request URL. New URL must have same protocol as original one. method : Union[str, None] If set changes the request method (e.g. GET or POST). headers : Union[Dict[str, str], None] If set changes the request HTTP headers. Header values will be converted to a string. post_data : Union[Any, bytes, str, None] Allows to set post data of the request. If the data parameter is an object, it will be serialized to json string and `content-type` header will be set to `application/json` if not explicitly set. Otherwise the `content-type` header will be set to `application/octet-stream` if not explicitly set. max_redirects : Union[int, None] Maximum number of request redirects that will be followed automatically. An error will be thrown if the number is exceeded. Defaults to `20`. Pass `0` to not follow redirects. timeout : Union[float, None] Request timeout in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. Returns ------- APIResponse """ return mapping.from_impl( await self._impl_obj.fetch( url=url, method=method, headers=mapping.to_impl(headers), postData=mapping.to_impl(post_data), maxRedirects=max_redirects, timeout=timeout, ) ) async def fallback( self, *, url: typing.Optional[str] = None, method: typing.Optional[str] = None, headers: typing.Optional[typing.Dict[str, str]] = None, post_data: typing.Optional[typing.Union[typing.Any, str, bytes]] = None ) -> None: """Route.fallback When several routes match the given pattern, they run in the order opposite to their registration. That way the last registered route can always override all the previous ones. In the example below, request will be handled by the bottom-most handler first, then it'll fall back to the previous one and in the end will be aborted by the first registered route. **Usage** ```py await page.route(\"**/*\", lambda route: route.abort()) # Runs last. await page.route(\"**/*\", lambda route: route.fallback()) # Runs second. await page.route(\"**/*\", lambda route: route.fallback()) # Runs first. ``` ```py page.route(\"**/*\", lambda route: route.abort()) # Runs last. page.route(\"**/*\", lambda route: route.fallback()) # Runs second. page.route(\"**/*\", lambda route: route.fallback()) # Runs first. ``` Registering multiple routes is useful when you want separate handlers to handle different kinds of requests, for example API calls vs page resources or GET requests vs POST requests as in the example below. ```py # Handle GET requests. def handle_get(route): if route.request.method != \"GET\": route.fallback() return # Handling GET only. # ... # Handle POST requests. def handle_post(route): if route.request.method != \"POST\": route.fallback() return # Handling POST only. # ... await page.route(\"**/*\", handle_get) await page.route(\"**/*\", handle_post) ``` ```py # Handle GET requests. def handle_get(route): if route.request.method != \"GET\": route.fallback() return # Handling GET only. # ... # Handle POST requests. def handle_post(route): if route.request.method != \"POST\": route.fallback() return # Handling POST only. # ... page.route(\"**/*\", handle_get) page.route(\"**/*\", handle_post) ``` One can also modify request while falling back to the subsequent handler, that way intermediate route handler can modify url, method, headers and postData of the request. ```py async def handle(route, request): # override headers headers = { **request.headers, \"foo\": \"foo-value\", # set \"foo\" header \"bar\": None # remove \"bar\" header } await route.fallback(headers=headers) await page.route(\"**/*\", handle) ``` ```py def handle(route, request): # override headers headers = { **request.headers, \"foo\": \"foo-value\", # set \"foo\" header \"bar\": None # remove \"bar\" header } route.fallback(headers=headers) page.route(\"**/*\", handle) ``` Parameters ---------- url : Union[str, None] If set changes the request URL. New URL must have same protocol as original one. Changing the URL won't affect the route matching, all the routes are matched using the original request URL. method : Union[str, None] If set changes the request method (e.g. GET or POST). headers : Union[Dict[str, str], None] If set changes the request HTTP headers. Header values will be converted to a string. post_data : Union[Any, bytes, str, None] If set changes the post data of request. """ return mapping.from_maybe_impl( await self._impl_obj.fallback( url=url, method=method, headers=mapping.to_impl(headers), postData=mapping.to_impl(post_data), ) ) async def continue_( self, *, url: typing.Optional[str] = None, method: typing.Optional[str] = None, headers: typing.Optional[typing.Dict[str, str]] = None, post_data: typing.Optional[typing.Union[typing.Any, str, bytes]] = None ) -> None: """Route.continue_ Continues route's request with optional overrides. **Usage** ```py async def handle(route, request): # override headers headers = { **request.headers, \"foo\": \"foo-value\", # set \"foo\" header \"bar\": None # remove \"bar\" header } await route.continue_(headers=headers) await page.route(\"**/*\", handle) ``` ```py def handle(route, request): # override headers headers = { **request.headers, \"foo\": \"foo-value\", # set \"foo\" header \"bar\": None # remove \"bar\" header } route.continue_(headers=headers) page.route(\"**/*\", handle) ``` **Details** Note that any overrides such as `url` or `headers` only apply to the request being routed. If this request results in a redirect, overrides will not be applied to the new redirected request. If you want to propagate a header through redirects, use the combination of `route.fetch()` and `route.fulfill()` instead. Parameters ---------- url : Union[str, None] If set changes the request URL. New URL must have same protocol as original one. method : Union[str, None] If set changes the request method (e.g. GET or POST). headers : Union[Dict[str, str], None] If set changes the request HTTP headers. Header values will be converted to a string. post_data : Union[Any, bytes, str, None] If set changes the post data of request. """ return mapping.from_maybe_impl( await self._impl_obj.continue_( url=url, method=method, headers=mapping.to_impl(headers), postData=mapping.to_impl(post_data), ) ) mapping.register(RouteImpl, Route) class WebSocket(AsyncBase): @typing.overload def on( self, event: Literal["close"], f: typing.Callable[["WebSocket"], "typing.Union[typing.Awaitable[None], None]"], ) -> None: """ Fired when the websocket closes.""" @typing.overload def on( self, event: Literal["framereceived"], f: typing.Callable[ ["typing.Union[bytes, str]"], "typing.Union[typing.Awaitable[None], None]" ], ) -> None: """ Fired when the websocket receives a frame.""" @typing.overload def on( self, event: Literal["framesent"], f: typing.Callable[ ["typing.Union[bytes, str]"], "typing.Union[typing.Awaitable[None], None]" ], ) -> None: """ Fired when the websocket sends a frame.""" @typing.overload def on( self, event: Literal["socketerror"], f: typing.Callable[["str"], "typing.Union[typing.Awaitable[None], None]"], ) -> None: """ Fired when the websocket has an error.""" def on( self, event: str, f: typing.Callable[..., typing.Union[typing.Awaitable[None], None]], ) -> None: return super().on(event=event, f=f) @typing.overload def once( self, event: Literal["close"], f: typing.Callable[["WebSocket"], "typing.Union[typing.Awaitable[None], None]"], ) -> None: """ Fired when the websocket closes.""" @typing.overload def once( self, event: Literal["framereceived"], f: typing.Callable[ ["typing.Union[bytes, str]"], "typing.Union[typing.Awaitable[None], None]" ], ) -> None: """ Fired when the websocket receives a frame.""" @typing.overload def once( self, event: Literal["framesent"], f: typing.Callable[ ["typing.Union[bytes, str]"], "typing.Union[typing.Awaitable[None], None]" ], ) -> None: """ Fired when the websocket sends a frame.""" @typing.overload def once( self, event: Literal["socketerror"], f: typing.Callable[["str"], "typing.Union[typing.Awaitable[None], None]"], ) -> None: """ Fired when the websocket has an error.""" def once( self, event: str, f: typing.Callable[..., typing.Union[typing.Awaitable[None], None]], ) -> None: return super().once(event=event, f=f) @property def url(self) -> str: """WebSocket.url Contains the URL of the WebSocket. Returns ------- str """ return mapping.from_maybe_impl(self._impl_obj.url) def expect_event( self, event: str, predicate: typing.Optional[typing.Callable] = None, *, timeout: typing.Optional[float] = None ) -> AsyncEventContextManager: """WebSocket.expect_event Waits for event to fire and passes its value into the predicate function. Returns when the predicate returns truthy value. Will throw an error if the webSocket is closed before the event is fired. Returns the event data value. Parameters ---------- event : str Event name, same one would pass into `webSocket.on(event)`. predicate : Union[Callable, None] Receives the event data and resolves to truthy value when the waiting should resolve. timeout : Union[float, None] Maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can be changed by using the `browser_context.set_default_timeout()`. Returns ------- EventContextManager """ return AsyncEventContextManager( self._impl_obj.expect_event( event=event, predicate=self._wrap_handler(predicate), timeout=timeout ).future ) async def wait_for_event( self, event: str, predicate: typing.Optional[typing.Callable] = None, *, timeout: typing.Optional[float] = None ) -> typing.Any: """WebSocket.wait_for_event **NOTE** In most cases, you should use `web_socket.expect_event()`. Waits for given `event` to fire. If predicate is provided, it passes event's value into the `predicate` function and waits for `predicate(event)` to return a truthy value. Will throw an error if the socket is closed before the `event` is fired. Parameters ---------- event : str Event name, same one typically passed into `*.on(event)`. predicate : Union[Callable, None] Receives the event data and resolves to truthy value when the waiting should resolve. timeout : Union[float, None] Maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can be changed by using the `browser_context.set_default_timeout()`. Returns ------- Any """ return mapping.from_maybe_impl( await self._impl_obj.wait_for_event( event=event, predicate=self._wrap_handler(predicate), timeout=timeout ) ) def is_closed(self) -> bool: """WebSocket.is_closed Indicates that the web socket has been closed. Returns ------- bool """ return mapping.from_maybe_impl(self._impl_obj.is_closed()) mapping.register(WebSocketImpl, WebSocket) class Keyboard(AsyncBase): async def down(self, key: str) -> None: """Keyboard.down Dispatches a `keydown` event. `key` can specify the intended [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to generate the text for. A superset of the `key` values can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values). Examples of the keys are: `F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`, `Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrowRight`, `ArrowUp`, etc. Following modification shortcuts are also supported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`. Holding down `Shift` will type the text that corresponds to the `key` in the upper case. If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different respective texts. If `key` is a modifier key, `Shift`, `Meta`, `Control`, or `Alt`, subsequent key presses will be sent with that modifier active. To release the modifier key, use `keyboard.up()`. After the key is pressed once, subsequent calls to `keyboard.down()` will have [repeat](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat) set to true. To release the key, use `keyboard.up()`. **NOTE** Modifier keys DO influence `keyboard.down`. Holding down `Shift` will type the text in upper case. Parameters ---------- key : str Name of the key to press or a character to generate, such as `ArrowLeft` or `a`. """ return mapping.from_maybe_impl(await self._impl_obj.down(key=key)) async def up(self, key: str) -> None: """Keyboard.up Dispatches a `keyup` event. Parameters ---------- key : str Name of the key to press or a character to generate, such as `ArrowLeft` or `a`. """ return mapping.from_maybe_impl(await self._impl_obj.up(key=key)) async def insert_text(self, text: str) -> None: """Keyboard.insert_text Dispatches only `input` event, does not emit the `keydown`, `keyup` or `keypress` events. **Usage** ```py await page.keyboard.insert_text(\"嗨\") ``` ```py page.keyboard.insert_text(\"嗨\") ``` **NOTE** Modifier keys DO NOT effect `keyboard.insertText`. Holding down `Shift` will not type the text in upper case. Parameters ---------- text : str Sets input to the specified text value. """ return mapping.from_maybe_impl(await self._impl_obj.insert_text(text=text)) async def type(self, text: str, *, delay: typing.Optional[float] = None) -> None: """Keyboard.type **NOTE** In most cases, you should use `locator.fill()` instead. You only need to press keys one by one if there is special keyboard handling on the page - in this case use `locator.press_sequentially()`. Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text. To press a special key, like `Control` or `ArrowDown`, use `keyboard.press()`. **Usage** ```py await page.keyboard.type(\"Hello\") # types instantly await page.keyboard.type(\"World\", delay=100) # types slower, like a user ``` ```py page.keyboard.type(\"Hello\") # types instantly page.keyboard.type(\"World\", delay=100) # types slower, like a user ``` **NOTE** Modifier keys DO NOT effect `keyboard.type`. Holding down `Shift` will not type the text in upper case. **NOTE** For characters that are not on a US keyboard, only an `input` event will be sent. Parameters ---------- text : str A text to type into a focused element. delay : Union[float, None] Time to wait between key presses in milliseconds. Defaults to 0. """ return mapping.from_maybe_impl( await self._impl_obj.type(text=text, delay=delay) ) async def press(self, key: str, *, delay: typing.Optional[float] = None) -> None: """Keyboard.press **NOTE** In most cases, you should use `locator.press()` instead. `key` can specify the intended [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to generate the text for. A superset of the `key` values can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values). Examples of the keys are: `F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`, `Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrowRight`, `ArrowUp`, etc. Following modification shortcuts are also supported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`. Holding down `Shift` will type the text that corresponds to the `key` in the upper case. If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different respective texts. Shortcuts such as `key: \"Control+o\"` or `key: \"Control+Shift+T\"` are supported as well. When specified with the modifier, modifier is pressed and being held while the subsequent key is being pressed. **Usage** ```py page = await browser.new_page() await page.goto(\"https://keycode.info\") await page.keyboard.press(\"a\") await page.screenshot(path=\"a.png\") await page.keyboard.press(\"ArrowLeft\") await page.screenshot(path=\"arrow_left.png\") await page.keyboard.press(\"Shift+O\") await page.screenshot(path=\"o.png\") await browser.close() ``` ```py page = browser.new_page() page.goto(\"https://keycode.info\") page.keyboard.press(\"a\") page.screenshot(path=\"a.png\") page.keyboard.press(\"ArrowLeft\") page.screenshot(path=\"arrow_left.png\") page.keyboard.press(\"Shift+O\") page.screenshot(path=\"o.png\") browser.close() ``` Shortcut for `keyboard.down()` and `keyboard.up()`. Parameters ---------- key : str Name of the key to press or a character to generate, such as `ArrowLeft` or `a`. delay : Union[float, None] Time to wait between `keydown` and `keyup` in milliseconds. Defaults to 0. """ return mapping.from_maybe_impl(await self._impl_obj.press(key=key, delay=delay)) mapping.register(KeyboardImpl, Keyboard) class Mouse(AsyncBase): async def move( self, x: float, y: float, *, steps: typing.Optional[int] = None ) -> None: """Mouse.move Dispatches a `mousemove` event. Parameters ---------- x : float y : float steps : Union[int, None] Defaults to 1. Sends intermediate `mousemove` events. """ return mapping.from_maybe_impl(await self._impl_obj.move(x=x, y=y, steps=steps)) async def down( self, *, button: typing.Optional[Literal["left", "middle", "right"]] = None, click_count: typing.Optional[int] = None ) -> None: """Mouse.down Dispatches a `mousedown` event. Parameters ---------- button : Union["left", "middle", "right", None] Defaults to `left`. click_count : Union[int, None] defaults to 1. See [UIEvent.detail]. """ return mapping.from_maybe_impl( await self._impl_obj.down(button=button, clickCount=click_count) ) async def up( self, *, button: typing.Optional[Literal["left", "middle", "right"]] = None, click_count: typing.Optional[int] = None ) -> None: """Mouse.up Dispatches a `mouseup` event. Parameters ---------- button : Union["left", "middle", "right", None] Defaults to `left`. click_count : Union[int, None] defaults to 1. See [UIEvent.detail]. """ return mapping.from_maybe_impl( await self._impl_obj.up(button=button, clickCount=click_count) ) async def click( self, x: float, y: float, *, delay: typing.Optional[float] = None, button: typing.Optional[Literal["left", "middle", "right"]] = None, click_count: typing.Optional[int] = None ) -> None: """Mouse.click Shortcut for `mouse.move()`, `mouse.down()`, `mouse.up()`. Parameters ---------- x : float y : float delay : Union[float, None] Time to wait between `mousedown` and `mouseup` in milliseconds. Defaults to 0. button : Union["left", "middle", "right", None] Defaults to `left`. click_count : Union[int, None] defaults to 1. See [UIEvent.detail]. """ return mapping.from_maybe_impl( await self._impl_obj.click( x=x, y=y, delay=delay, button=button, clickCount=click_count ) ) async def dblclick( self, x: float, y: float, *, delay: typing.Optional[float] = None, button: typing.Optional[Literal["left", "middle", "right"]] = None ) -> None: """Mouse.dblclick Shortcut for `mouse.move()`, `mouse.down()`, `mouse.up()`, `mouse.down()` and `mouse.up()`. Parameters ---------- x : float y : float delay : Union[float, None] Time to wait between `mousedown` and `mouseup` in milliseconds. Defaults to 0. button : Union["left", "middle", "right", None] Defaults to `left`. """ return mapping.from_maybe_impl( await self._impl_obj.dblclick(x=x, y=y, delay=delay, button=button) ) async def wheel(self, delta_x: float, delta_y: float) -> None: """Mouse.wheel Dispatches a `wheel` event. **NOTE** Wheel events may cause scrolling if they are not handled, and this method does not wait for the scrolling to finish before returning. Parameters ---------- delta_x : float Pixels to scroll horizontally. delta_y : float Pixels to scroll vertically. """ return mapping.from_maybe_impl( await self._impl_obj.wheel(deltaX=delta_x, deltaY=delta_y) ) mapping.register(MouseImpl, Mouse) class Touchscreen(AsyncBase): async def tap(self, x: float, y: float) -> None: """Touchscreen.tap Dispatches a `touchstart` and `touchend` event with a single touch at the position (`x`,`y`). **NOTE** `page.tap()` the method will throw if `hasTouch` option of the browser context is false. Parameters ---------- x : float y : float """ return mapping.from_maybe_impl(await self._impl_obj.tap(x=x, y=y)) mapping.register(TouchscreenImpl, Touchscreen) class JSHandle(AsyncBase): async def evaluate( self, expression: str, arg: typing.Optional[typing.Any] = None ) -> typing.Any: """JSHandle.evaluate Returns the return value of `expression`. This method passes this handle as the first argument to `expression`. If `expression` returns a [Promise], then `handle.evaluate` would wait for the promise to resolve and return its value. **Usage** ```py tweet_handle = await page.query_selector(\".tweet .retweets\") assert await tweet_handle.evaluate(\"node => node.innerText\") == \"10 retweets\" ``` ```py tweet_handle = page.query_selector(\".tweet .retweets\") assert tweet_handle.evaluate(\"node => node.innerText\") == \"10 retweets\" ``` Parameters ---------- expression : str JavaScript expression to be evaluated in the browser context. If the expression evaluates to a function, the function is automatically invoked. arg : Union[Any, None] Optional argument to pass to `expression`. Returns ------- Any """ return mapping.from_maybe_impl( await self._impl_obj.evaluate( expression=expression, arg=mapping.to_impl(arg) ) ) async def evaluate_handle( self, expression: str, arg: typing.Optional[typing.Any] = None ) -> "JSHandle": """JSHandle.evaluate_handle Returns the return value of `expression` as a `JSHandle`. This method passes this handle as the first argument to `expression`. The only difference between `jsHandle.evaluate` and `jsHandle.evaluateHandle` is that `jsHandle.evaluateHandle` returns `JSHandle`. If the function passed to the `jsHandle.evaluateHandle` returns a [Promise], then `jsHandle.evaluateHandle` would wait for the promise to resolve and return its value. See `page.evaluate_handle()` for more details. Parameters ---------- expression : str JavaScript expression to be evaluated in the browser context. If the expression evaluates to a function, the function is automatically invoked. arg : Union[Any, None] Optional argument to pass to `expression`. Returns ------- JSHandle """ return mapping.from_impl( await self._impl_obj.evaluate_handle( expression=expression, arg=mapping.to_impl(arg) ) ) async def get_property(self, property_name: str) -> "JSHandle": """JSHandle.get_property Fetches a single property from the referenced object. Parameters ---------- property_name : str property to get Returns ------- JSHandle """ return mapping.from_impl( await self._impl_obj.get_property(propertyName=property_name) ) async def get_properties(self) -> typing.Dict[str, "JSHandle"]: """JSHandle.get_properties The method returns a map with **own property names** as keys and JSHandle instances for the property values. **Usage** ```py handle = await page.evaluate_handle(\"({ window, document })\") properties = await handle.get_properties() window_handle = properties.get(\"window\") document_handle = properties.get(\"document\") await handle.dispose() ``` ```py handle = page.evaluate_handle(\"({ window, document })\") properties = handle.get_properties() window_handle = properties.get(\"window\") document_handle = properties.get(\"document\") handle.dispose() ``` Returns ------- Dict[str, JSHandle] """ return mapping.from_impl_dict(await self._impl_obj.get_properties()) def as_element(self) -> typing.Optional["ElementHandle"]: """JSHandle.as_element Returns either `null` or the object handle itself, if the object handle is an instance of `ElementHandle`. Returns ------- Union[ElementHandle, None] """ return mapping.from_impl_nullable(self._impl_obj.as_element()) async def dispose(self) -> None: """JSHandle.dispose The `jsHandle.dispose` method stops referencing the element handle. """ return mapping.from_maybe_impl(await self._impl_obj.dispose()) async def json_value(self) -> typing.Any: """JSHandle.json_value Returns a JSON representation of the object. If the object has a `toJSON` function, it **will not be called**. **NOTE** The method will return an empty JSON object if the referenced object is not stringifiable. It will throw an error if the object has circular references. Returns ------- Any """ return mapping.from_maybe_impl(await self._impl_obj.json_value()) mapping.register(JSHandleImpl, JSHandle) class ElementHandle(JSHandle): def as_element(self) -> typing.Optional["ElementHandle"]: """ElementHandle.as_element Returns either `null` or the object handle itself, if the object handle is an instance of `ElementHandle`. Returns ------- Union[ElementHandle, None] """ return mapping.from_impl_nullable(self._impl_obj.as_element()) async def owner_frame(self) -> typing.Optional["Frame"]: """ElementHandle.owner_frame Returns the frame containing the given element. Returns ------- Union[Frame, None] """ return mapping.from_impl_nullable(await self._impl_obj.owner_frame()) async def content_frame(self) -> typing.Optional["Frame"]: """ElementHandle.content_frame Returns the content frame for element handles referencing iframe nodes, or `null` otherwise Returns ------- Union[Frame, None] """ return mapping.from_impl_nullable(await self._impl_obj.content_frame()) async def get_attribute(self, name: str) -> typing.Optional[str]: """ElementHandle.get_attribute Returns element attribute value. Parameters ---------- name : str Attribute name to get the value for. Returns ------- Union[str, None] """ return mapping.from_maybe_impl(await self._impl_obj.get_attribute(name=name)) async def text_content(self) -> typing.Optional[str]: """ElementHandle.text_content Returns the `node.textContent`. Returns ------- Union[str, None] """ return mapping.from_maybe_impl(await self._impl_obj.text_content()) async def inner_text(self) -> str: """ElementHandle.inner_text Returns the `element.innerText`. Returns ------- str """ return mapping.from_maybe_impl(await self._impl_obj.inner_text()) async def inner_html(self) -> str: """ElementHandle.inner_html Returns the `element.innerHTML`. Returns ------- str """ return mapping.from_maybe_impl(await self._impl_obj.inner_html()) async def is_checked(self) -> bool: """ElementHandle.is_checked Returns whether the element is checked. Throws if the element is not a checkbox or radio input. Returns ------- bool """ return mapping.from_maybe_impl(await self._impl_obj.is_checked()) async def is_disabled(self) -> bool: """ElementHandle.is_disabled Returns whether the element is disabled, the opposite of [enabled](https://playwright.dev/python/docs/actionability#enabled). Returns ------- bool """ return mapping.from_maybe_impl(await self._impl_obj.is_disabled()) async def is_editable(self) -> bool: """ElementHandle.is_editable Returns whether the element is [editable](https://playwright.dev/python/docs/actionability#editable). Returns ------- bool """ return mapping.from_maybe_impl(await self._impl_obj.is_editable()) async def is_enabled(self) -> bool: """ElementHandle.is_enabled Returns whether the element is [enabled](https://playwright.dev/python/docs/actionability#enabled). Returns ------- bool """ return mapping.from_maybe_impl(await self._impl_obj.is_enabled()) async def is_hidden(self) -> bool: """ElementHandle.is_hidden Returns whether the element is hidden, the opposite of [visible](https://playwright.dev/python/docs/actionability#visible). Returns ------- bool """ return mapping.from_maybe_impl(await self._impl_obj.is_hidden()) async def is_visible(self) -> bool: """ElementHandle.is_visible Returns whether the element is [visible](https://playwright.dev/python/docs/actionability#visible). Returns ------- bool """ return mapping.from_maybe_impl(await self._impl_obj.is_visible()) async def dispatch_event( self, type: str, event_init: typing.Optional[typing.Dict] = None ) -> None: """ElementHandle.dispatch_event The snippet below dispatches the `click` event on the element. Regardless of the visibility state of the element, `click` is dispatched. This is equivalent to calling [element.click()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click). **Usage** ```py await element_handle.dispatch_event(\"click\") ``` ```py element_handle.dispatch_event(\"click\") ``` Under the hood, it creates an instance of an event based on the given `type`, initializes it with `eventInit` properties and dispatches it on the element. Events are `composed`, `cancelable` and bubble by default. Since `eventInit` is event-specific, please refer to the events documentation for the lists of initial properties: - [DeviceMotionEvent](https://developer.mozilla.org/en-US/docs/Web/API/DeviceMotionEvent/DeviceMotionEvent) - [DeviceOrientationEvent](https://developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent/DeviceOrientationEvent) - [DragEvent](https://developer.mozilla.org/en-US/docs/Web/API/DragEvent/DragEvent) - [Event](https://developer.mozilla.org/en-US/docs/Web/API/Event/Event) - [FocusEvent](https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent/FocusEvent) - [KeyboardEvent](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/KeyboardEvent) - [MouseEvent](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/MouseEvent) - [PointerEvent](https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/PointerEvent) - [TouchEvent](https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/TouchEvent) - [WheelEvent](https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent/WheelEvent) You can also specify `JSHandle` as the property value if you want live objects to be passed into the event: ```py # note you can only create data_transfer in chromium and firefox data_transfer = await page.evaluate_handle(\"new DataTransfer()\") await element_handle.dispatch_event(\"#source\", \"dragstart\", {\"dataTransfer\": data_transfer}) ``` ```py # note you can only create data_transfer in chromium and firefox data_transfer = page.evaluate_handle(\"new DataTransfer()\") element_handle.dispatch_event(\"#source\", \"dragstart\", {\"dataTransfer\": data_transfer}) ``` Parameters ---------- type : str DOM event type: `"click"`, `"dragstart"`, etc. event_init : Union[Dict, None] Optional event-specific initialization properties. """ return mapping.from_maybe_impl( await self._impl_obj.dispatch_event( type=type, eventInit=mapping.to_impl(event_init) ) ) async def scroll_into_view_if_needed( self, *, timeout: typing.Optional[float] = None ) -> None: """ElementHandle.scroll_into_view_if_needed This method waits for [actionability](https://playwright.dev/python/docs/actionability) checks, then tries to scroll element into view, unless it is completely visible as defined by [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)'s `ratio`. Throws when `elementHandle` does not point to an element [connected](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected) to a Document or a ShadowRoot. Parameters ---------- timeout : Union[float, None] Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can be changed by using the `browser_context.set_default_timeout()` or `page.set_default_timeout()` methods. """ return mapping.from_maybe_impl( await self._impl_obj.scroll_into_view_if_needed(timeout=timeout) ) async def hover( self, *, modifiers: typing.Optional[ typing.List[Literal["Alt", "Control", "Meta", "Shift"]] ] = None, position: typing.Optional[Position] = None, timeout: typing.Optional[float] = None, no_wait_after: typing.Optional[bool] = None, force: typing.Optional[bool] = None, trial: typing.Optional[bool] = None ) -> None: """ElementHandle.hover This method hovers over the element by performing the following steps: 1. Wait for [actionability](https://playwright.dev/python/docs/actionability) checks on the element, unless `force` option is set. 1. Scroll the element into view if needed. 1. Use `page.mouse` to hover over the center of the element, or the specified `position`. 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set. If the element is detached from the DOM at any moment during the action, this method throws. When all steps combined have not finished during the specified `timeout`, this method throws a `TimeoutError`. Passing zero timeout disables this. Parameters ---------- modifiers : Union[List[Union["Alt", "Control", "Meta", "Shift"]], None] Modifier keys to press. Ensures that only these modifiers are pressed during the operation, and then restores current modifiers back. If not specified, currently pressed modifiers are used. position : Union[{x: float, y: float}, None] A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of the element. timeout : Union[float, None] Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can be changed by using the `browser_context.set_default_timeout()` or `page.set_default_timeout()` methods. no_wait_after : Union[bool, None] Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as navigating to inaccessible pages. Defaults to `false`. force : Union[bool, None] Whether to bypass the [actionability](../actionability.md) checks. Defaults to `false`. trial : Union[bool, None] When set, this method only performs the [actionability](../actionability.md) checks and skips the action. Defaults to `false`. Useful to wait until the element is ready for the action without performing it. """ return mapping.from_maybe_impl( await self._impl_obj.hover( modifiers=mapping.to_impl(modifiers), position=position, timeout=timeout, noWaitAfter=no_wait_after, force=force, trial=trial, ) ) async def click( self, *, modifiers: typing.Optional[ typing.List[Literal["Alt", "Control", "Meta", "Shift"]] ] = None, position: typing.Optional[Position] = None, delay: typing.Optional[float] = None, button: typing.Optional[Literal["left", "middle", "right"]] = None, click_count: typing.Optional[int] = None, timeout: typing.Optional[float] = None, force: typing.Optional[bool] = None, no_wait_after: typing.Optional[bool] = None, trial: typing.Optional[bool] = None ) -> None: """ElementHandle.click This method clicks the element by performing the following steps: 1. Wait for [actionability](https://playwright.dev/python/docs/actionability) checks on the element, unless `force` option is set. 1. Scroll the element into view if needed. 1. Use `page.mouse` to click in the center of the element, or the specified `position`. 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set. If the element is detached from the DOM at any moment during the action, this method throws. When all steps combined have not finished during the specified `timeout`, this method throws a `TimeoutError`. Passing zero timeout disables this. Parameters ---------- modifiers : Union[List[Union["Alt", "Control", "Meta", "Shift"]], None] Modifier keys to press. Ensures that only these modifiers are pressed during the operation, and then restores current modifiers back. If not specified, currently pressed modifiers are used. position : Union[{x: float, y: float}, None] A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of the element. delay : Union[float, None] Time to wait between `mousedown` and `mouseup` in milliseconds. Defaults to 0. button : Union["left", "middle", "right", None] Defaults to `left`. click_count : Union[int, None] defaults to 1. See [UIEvent.detail]. timeout : Union[float, None] Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can be changed by using the `browser_context.set_default_timeout()` or `page.set_default_timeout()` methods. force : Union[bool, None] Whether to bypass the [actionability](../actionability.md) checks. Defaults to `false`. no_wait_after : Union[bool, None] Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as navigating to inaccessible pages. Defaults to `false`. trial : Union[bool, None] When set, this method only performs the [actionability](../actionability.md) checks and skips the action. Defaults to `false`. Useful to wait until the element is ready for the action without performing it. """ return mapping.from_maybe_impl( await self._impl_obj.click( modifiers=mapping.to_impl(modifiers), position=position, delay=delay, button=button, clickCount=click_count, timeout=timeout, force=force, noWaitAfter=no_wait_after, trial=trial, ) ) async def dblclick( self, *, modifiers: typing.Optional[ typing.List[Literal["Alt", "Control", "Meta", "Shift"]] ] = None, position: typing.Optional[Position] = None, delay: typing.Optional[float] = None, button: typing.Optional[Literal["left", "middle", "right"]] = None, timeout: typing.Optional[float] = None, force: typing.Optional[bool] = None, no_wait_after: typing.Optional[bool] = None, trial: typing.Optional[bool] = None ) -> None: """ElementHandle.dblclick This method double clicks the element by performing the following steps: 1. Wait for [actionability](https://playwright.dev/python/docs/actionability) checks on the element, unless `force` option is set. 1. Scroll the element into view if needed. 1. Use `page.mouse` to double click in the center of the element, or the specified `position`. 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set. Note that if the first click of the `dblclick()` triggers a navigation event, this method will throw. If the element is detached from the DOM at any moment during the action, this method throws. When all steps combined have not finished during the specified `timeout`, this method throws a `TimeoutError`. Passing zero timeout disables this. **NOTE** `elementHandle.dblclick()` dispatches two `click` events and a single `dblclick` event. Parameters ---------- modifiers : Union[List[Union["Alt", "Control", "Meta", "Shift"]], None] Modifier keys to press. Ensures that only these modifiers are pressed during the operation, and then restores current modifiers back. If not specified, currently pressed modifiers are used. position : Union[{x: float, y: float}, None] A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of the element. delay : Union[float, None] Time to wait between `mousedown` and `mouseup` in milliseconds. Defaults to 0. button : Union["left", "middle", "right", None] Defaults to `left`. timeout : Union[float, None] Maximum time in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can be changed by using the `browser_context.set_default_timeout()` or `page.set_default_timeout()` methods. force : Union[bool, None] Whether to bypass the [actionability](../actionability.md) checks. Defaults to `false`. no_wait_after : Union[bool, None] Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as navigating to inaccessible pages. Defaults to `false`. trial : Union[bool, None] When set, this method only performs the [actionability](../actionability.md) checks and skips the action. Defaults to `false`. Useful to wait until the element is ready for the action without performing it. """ return mapping.from_maybe_impl( await self._impl_obj.dblclick( modifiers=mapping.to_impl(modifiers), position=position, delay=delay, button=button, timeout=timeout, force=force, noWaitAfter=no_wait_after, trial=trial, ) ) async def select_option( self, value: typing.Optional[typing.Union[str, typing.List[str]]] = None, *, index: typing.Optional[typing.Union[int, typing.List[int]]] = None, label: typing.Optional[typing.Union[str, typing.List[str]]] = None, element: typing.Optional[ typing.Union["ElementHandle", typing.List["ElementHandle"]] ] = None, timeout: typing.Optional[float] = None, force: typing.Optional[bool] = None, no_wait_after: typing.Optional[bool] = None ) -> typing.List[str]: """ElementHandle.select_option This method waits for [actionability](https://playwright.dev/python/docs/actionability) checks, waits until all specified options are present in the `` element, this method throws an error. However, if the element is inside the `