# 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 import pathlib import typing from typing import Literal from playwright._impl._accessibility import Accessibility as AccessibilityImpl from playwright._impl._api_structures import ( ClientCertificate, Cookie, FilePayload, FloatRect, Geolocation, HttpCredentials, NameValue, PdfMargins, Position, ProxySettings, RemoteAddr, RequestSizes, ResourceTiming, SecurityDetails, SetCookieParam, SourceLocation, StorageState, TracingGroupLocation, 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._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._clock import Clock as ClockImpl 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._network import WebSocketRoute as WebSocketRouteImpl 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._sync_base import ( EventContextManager, SyncBase, SyncContextManager, mapping, ) 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(SyncBase): @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 = 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 = 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 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) 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(self._sync(self._impl_obj.sizes())) 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(self._sync(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()) 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(self._sync(self._impl_obj.all_headers())) 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(self._sync(self._impl_obj.headers_array())) 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( self._sync(self._impl_obj.header_value(name=name)) ) mapping.register(RequestImpl, Request) class Response(SyncBase): @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) 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(self._sync(self._impl_obj.all_headers())) 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(self._sync(self._impl_obj.headers_array())) 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( self._sync(self._impl_obj.header_value(name=name)) ) 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( self._sync(self._impl_obj.header_values(name=name)) ) 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(self._sync(self._impl_obj.server_addr())) 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(self._sync(self._impl_obj.security_details())) def finished(self) -> None: """Response.finished Waits for this response to finish, returns always `null`. """ return mapping.from_maybe_impl(self._sync(self._impl_obj.finished())) def body(self) -> bytes: """Response.body Returns the buffer with response body. Returns ------- bytes """ return mapping.from_maybe_impl(self._sync(self._impl_obj.body())) def text(self) -> str: """Response.text Returns the text representation of response body. Returns ------- str """ return mapping.from_maybe_impl(self._sync(self._impl_obj.text())) 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(self._sync(self._impl_obj.json())) mapping.register(ResponseImpl, Response) class Route(SyncBase): @property def request(self) -> "Request": """Route.request A request to be routed. Returns ------- Request """ return mapping.from_impl(self._impl_obj.request) 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( self._sync(self._impl_obj.abort(errorCode=error_code)) ) 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 page.route(\"**/*\", lambda route: route.fulfill( status=404, content_type=\"text/plain\", body=\"not found!\")) ``` An example of serving static file: ```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( self._sync( 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, ) ) ) 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, max_retries: 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 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. max_retries : Union[int, None] Maximum number of times network errors should be retried. Currently only `ECONNRESET` error is retried. Does not retry based on HTTP response codes. An error will be thrown if the limit is exceeded. Defaults to `0` - no retries. timeout : Union[float, None] Request timeout in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. Returns ------- APIResponse """ return mapping.from_impl( self._sync( self._impl_obj.fetch( url=url, method=method, headers=mapping.to_impl(headers), postData=mapping.to_impl(post_data), maxRedirects=max_redirects, maxRetries=max_retries, timeout=timeout, ) ) ) 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 Continues route's request with optional overrides. The method is similar to `route.continue_()` with the difference that other matching handlers will be invoked before sending the request. **Usage** 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. ```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. # ... 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 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) ``` Use `route.continue_()` to immediately send the request to the network, other matching handlers won't be invoked in that case. 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( self._sync( self._impl_obj.fallback( url=url, method=method, headers=mapping.to_impl(headers), postData=mapping.to_impl(post_data), ) ) ) 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_ Sends route's request to the network with optional overrides. **Usage** ```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** The `headers` option applies to both the routed request and any redirects it initiates. However, `url`, `method`, and `postData` only apply to the original request and are not carried over to redirected requests. `route.continue_()` will immediately send the request to the network, other matching handlers won't be invoked. Use `route.fallback()` If you want next matching handler in the chain to be invoked. **NOTE** The `Cookie` header cannot be overridden using this method. If a value is provided, it will be ignored, and the cookie will be loaded from the browser's cookie store. To set custom cookies, use `browser_context.add_cookies()`. 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( self._sync( 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(SyncBase): @typing.overload def on( self, event: Literal["close"], f: typing.Callable[["WebSocket"], "None"] ) -> None: """ Fired when the websocket closes.""" @typing.overload def on( self, event: Literal["framereceived"], f: typing.Callable[["typing.Union[bytes, str]"], "None"], ) -> None: """ Fired when the websocket receives a frame.""" @typing.overload def on( self, event: Literal["framesent"], f: typing.Callable[["typing.Union[bytes, str]"], "None"], ) -> None: """ Fired when the websocket sends a frame.""" @typing.overload def on( self, event: Literal["socketerror"], f: typing.Callable[["str"], "None"] ) -> None: """ Fired when the websocket has an error.""" def on(self, event: str, f: typing.Callable[..., None]) -> None: return super().on(event=event, f=f) @typing.overload def once( self, event: Literal["close"], f: typing.Callable[["WebSocket"], "None"] ) -> None: """ Fired when the websocket closes.""" @typing.overload def once( self, event: Literal["framereceived"], f: typing.Callable[["typing.Union[bytes, str]"], "None"], ) -> None: """ Fired when the websocket receives a frame.""" @typing.overload def once( self, event: Literal["framesent"], f: typing.Callable[["typing.Union[bytes, str]"], "None"], ) -> None: """ Fired when the websocket sends a frame.""" @typing.overload def once( self, event: Literal["socketerror"], f: typing.Callable[["str"], "None"] ) -> None: """ Fired when the websocket has an error.""" def once(self, event: str, f: typing.Callable[..., 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, ) -> EventContextManager: """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 EventContextManager( self, self._impl_obj.expect_event( event=event, predicate=self._wrap_handler(predicate), timeout=timeout ).future, ) 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( self._sync( 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 WebSocketRoute(SyncBase): @property def url(self) -> str: """WebSocketRoute.url URL of the WebSocket created in the page. Returns ------- str """ return mapping.from_maybe_impl(self._impl_obj.url) def close( self, *, code: typing.Optional[int] = None, reason: typing.Optional[str] = None ) -> None: """WebSocketRoute.close Closes one side of the WebSocket connection. Parameters ---------- code : Union[int, None] Optional [close code](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close#code). reason : Union[str, None] Optional [close reason](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close#reason). """ return mapping.from_maybe_impl( self._sync(self._impl_obj.close(code=code, reason=reason)) ) def connect_to_server(self) -> "WebSocketRoute": """WebSocketRoute.connect_to_server By default, routed WebSocket does not connect to the server, so you can mock entire WebSocket communication. This method connects to the actual WebSocket server, and returns the server-side `WebSocketRoute` instance, giving the ability to send and receive messages from the server. Once connected to the server: - Messages received from the server will be **automatically forwarded** to the WebSocket in the page, unless `web_socket_route.on_message()` is called on the server-side `WebSocketRoute`. - Messages sent by the [`WebSocket.send()`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send) call in the page will be **automatically forwarded** to the server, unless `web_socket_route.on_message()` is called on the original `WebSocketRoute`. See examples at the top for more details. Returns ------- WebSocketRoute """ return mapping.from_impl(self._impl_obj.connect_to_server()) def send(self, message: typing.Union[str, bytes]) -> None: """WebSocketRoute.send Sends a message to the WebSocket. When called on the original WebSocket, sends the message to the page. When called on the result of `web_socket_route.connect_to_server()`, sends the message to the server. See examples at the top for more details. Parameters ---------- message : Union[bytes, str] Message to send. """ return mapping.from_maybe_impl(self._impl_obj.send(message=message)) def on_message( self, handler: typing.Callable[[typing.Union[str, bytes]], typing.Any] ) -> None: """WebSocketRoute.on_message This method allows to handle messages that are sent by the WebSocket, either from the page or from the server. When called on the original WebSocket route, this method handles messages sent from the page. You can handle this messages by responding to them with `web_socket_route.send()`, forwarding them to the server-side connection returned by `web_socket_route.connect_to_server()` or do something else. Once this method is called, messages are not automatically forwarded to the server or to the page - you should do that manually by calling `web_socket_route.send()`. See examples at the top for more details. Calling this method again will override the handler with a new one. Parameters ---------- handler : Callable[[Union[bytes, str]], Any] Function that will handle messages. """ return mapping.from_maybe_impl( self._impl_obj.on_message(handler=self._wrap_handler(handler)) ) def on_close( self, handler: typing.Callable[ [typing.Optional[int], typing.Optional[str]], typing.Any ], ) -> None: """WebSocketRoute.on_close Allows to handle [`WebSocket.close`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close). By default, closing one side of the connection, either in the page or on the server, will close the other side. However, when `web_socket_route.on_close()` handler is set up, the default forwarding of closure is disabled, and handler should take care of it. Parameters ---------- handler : Callable[[Union[int, None], Union[str, None]], Any] Function that will handle WebSocket closure. Received an optional [close code](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close#code) and an optional [close reason](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close#reason). """ return mapping.from_maybe_impl( self._impl_obj.on_close(handler=self._wrap_handler(handler)) ) mapping.register(WebSocketRouteImpl, WebSocketRoute) class Keyboard(SyncBase): 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`, `ControlOrMeta`. `ControlOrMeta` resolves to `Control` on Windows and Linux and to `Meta` on macOS. 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(self._sync(self._impl_obj.down(key=key))) 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(self._sync(self._impl_obj.up(key=key))) 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 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( self._sync(self._impl_obj.insert_text(text=text)) ) 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 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( self._sync(self._impl_obj.type(text=text, delay=delay)) ) 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`, `ControlOrMeta`. `ControlOrMeta` resolves to `Control` on Windows and Linux and to `Meta` on macOS. 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\"`, `key: \"Control++` 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 = 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( self._sync(self._impl_obj.press(key=key, delay=delay)) ) mapping.register(KeyboardImpl, Keyboard) class Mouse(SyncBase): def move(self, x: float, y: float, *, steps: typing.Optional[int] = None) -> None: """Mouse.move Dispatches a `mousemove` event. Parameters ---------- x : float X coordinate relative to the main frame's viewport in CSS pixels. y : float Y coordinate relative to the main frame's viewport in CSS pixels. steps : Union[int, None] Defaults to 1. Sends intermediate `mousemove` events. """ return mapping.from_maybe_impl( self._sync(self._impl_obj.move(x=x, y=y, steps=steps)) ) 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( self._sync(self._impl_obj.down(button=button, clickCount=click_count)) ) 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( self._sync(self._impl_obj.up(button=button, clickCount=click_count)) ) 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 X coordinate relative to the main frame's viewport in CSS pixels. y : float Y coordinate relative to the main frame's viewport in CSS pixels. 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( self._sync( self._impl_obj.click( x=x, y=y, delay=delay, button=button, clickCount=click_count ) ) ) 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 X coordinate relative to the main frame's viewport in CSS pixels. y : float Y coordinate relative to the main frame's viewport in CSS pixels. 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( self._sync(self._impl_obj.dblclick(x=x, y=y, delay=delay, button=button)) ) def wheel(self, delta_x: float, delta_y: float) -> None: """Mouse.wheel Dispatches a `wheel` event. This method is usually used to manually scroll the page. See [scrolling](https://playwright.dev/python/docs/input#scrolling) for alternative ways to scroll. **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( self._sync(self._impl_obj.wheel(deltaX=delta_x, deltaY=delta_y)) ) mapping.register(MouseImpl, Mouse) class Touchscreen(SyncBase): 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 X coordinate relative to the main frame's viewport in CSS pixels. y : float Y coordinate relative to the main frame's viewport in CSS pixels. """ return mapping.from_maybe_impl(self._sync(self._impl_obj.tap(x=x, y=y))) mapping.register(TouchscreenImpl, Touchscreen) class JSHandle(SyncBase): 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 = 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( self._sync( self._impl_obj.evaluate(expression=expression, arg=mapping.to_impl(arg)) ) ) 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( self._sync( self._impl_obj.evaluate_handle( expression=expression, arg=mapping.to_impl(arg) ) ) ) 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( self._sync(self._impl_obj.get_property(propertyName=property_name)) ) 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 = 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(self._sync(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()) def dispose(self) -> None: """JSHandle.dispose The `jsHandle.dispose` method stops referencing the element handle. """ return mapping.from_maybe_impl(self._sync(self._impl_obj.dispose())) 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(self._sync(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()) 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(self._sync(self._impl_obj.owner_frame())) 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(self._sync(self._impl_obj.content_frame())) 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( self._sync(self._impl_obj.get_attribute(name=name)) ) def text_content(self) -> typing.Optional[str]: """ElementHandle.text_content Returns the `node.textContent`. Returns ------- Union[str, None] """ return mapping.from_maybe_impl(self._sync(self._impl_obj.text_content())) def inner_text(self) -> str: """ElementHandle.inner_text Returns the `element.innerText`. Returns ------- str """ return mapping.from_maybe_impl(self._sync(self._impl_obj.inner_text())) def inner_html(self) -> str: """ElementHandle.inner_html Returns the `element.innerHTML`. Returns ------- str """ return mapping.from_maybe_impl(self._sync(self._impl_obj.inner_html())) 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(self._sync(self._impl_obj.is_checked())) 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(self._sync(self._impl_obj.is_disabled())) 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(self._sync(self._impl_obj.is_editable())) 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(self._sync(self._impl_obj.is_enabled())) 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(self._sync(self._impl_obj.is_hidden())) 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(self._sync(self._impl_obj.is_visible())) 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 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 = 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( self._sync( self._impl_obj.dispatch_event( type=type, eventInit=mapping.to_impl(event_init) ) ) ) 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. See [scrolling](https://playwright.dev/python/docs/input#scrolling) for alternative ways to scroll. 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( self._sync(self._impl_obj.scroll_into_view_if_needed(timeout=timeout)) ) def hover( self, *, modifiers: typing.Optional[ typing.Sequence[Literal["Alt", "Control", "ControlOrMeta", "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`. 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[Sequence[Union["Alt", "Control", "ControlOrMeta", "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. "ControlOrMeta" resolves to "Control" on Windows and Linux and to "Meta" on macOS. 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] This option has no effect. Deprecated: This option has no effect. 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( self._sync( self._impl_obj.hover( modifiers=mapping.to_impl(modifiers), position=position, timeout=timeout, noWaitAfter=no_wait_after, force=force, trial=trial, ) ) ) def click( self, *, modifiers: typing.Optional[ typing.Sequence[Literal["Alt", "Control", "ControlOrMeta", "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[Sequence[Union["Alt", "Control", "ControlOrMeta", "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. "ControlOrMeta" resolves to "Control" on Windows and Linux and to "Meta" on macOS. 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`. Deprecated: This option will default to `true` in the future. 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( self._sync( 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, ) ) ) def dblclick( self, *, modifiers: typing.Optional[ typing.Sequence[Literal["Alt", "Control", "ControlOrMeta", "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`. 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[Sequence[Union["Alt", "Control", "ControlOrMeta", "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. "ControlOrMeta" resolves to "Control" on Windows and Linux and to "Meta" on macOS. 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] This option has no effect. Deprecated: This option has no effect. 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( self._sync( 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, ) ) ) def select_option( self, value: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, *, index: typing.Optional[typing.Union[int, typing.Sequence[int]]] = None, label: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, element: typing.Optional[ typing.Union["ElementHandle", typing.Sequence["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 `