async def path(self) -> pathlib.Path: if self._page._connection.is_remote: raise Error( "Path is not available when using browserType.connect(). Use save_as() to save a local copy." ) artifact = await self._artifact_future if not artifact: raise Error("Page did not produce any video frames") return artifact.absolute_path
async def body(self) -> bytes: try: result = await self._request._channel.send_return_as_dict( "fetchResponseBody", { "fetchUid": self._fetch_uid(), }, ) if result is None: raise Error("Response has been disposed") return base64.b64decode(result["binary"]) except Error as exc: if is_safe_close_error(exc): raise Error("Response has been disposed") raise exc
def __init__( self, frame: "Frame", selector: str, has_text: Union[str, Pattern[str]] = None, has: "Locator" = None, ) -> None: self._frame = frame self._selector = selector self._loop = frame._loop self._dispatcher_fiber = frame._connection._dispatcher_fiber if has_text: if isinstance(has_text, Pattern): js_regex = f"/{has_text.pattern}/{escape_regex_flags(has_text)}" self._selector += ( f' >> has={json.dumps("text=" + js_regex, ensure_ascii=False)}' ) else: escaped = escape_with_quotes(has_text, '"') self._selector += f" >> :scope:has-text({escaped})" if has: if has._frame != frame: raise Error( 'Inner "has" locator must belong to the same frame.') self._selector += " >> has=" + json.dumps(has._selector, ensure_ascii=False)
def __init__( self, frame: "Frame", selector: str, has_text: Union[str, Pattern] = None, has: "Locator" = None, ) -> None: self._frame = frame self._selector = selector self._loop = frame._loop self._dispatcher_fiber = frame._connection._dispatcher_fiber if has_text: if isinstance(has_text, Pattern): pattern = escape_with_quotes(has_text.pattern, '"') flags = escape_regex_flags(has_text) self._selector += f' >> :scope:text-matches({pattern}, "{flags}")' else: escaped = escape_with_quotes(has_text, '"') self._selector += f" >> :scope:has-text({escaped})" if has: if has._frame != frame: raise Error( 'Inner "has" locator must belong to the same frame.') self._selector += " >> has=" + json.dumps(has._selector)
async def _with_element( self, task: Callable[[ElementHandle, float], Awaitable[T]], timeout: float = None, ) -> T: timeout = self._frame.page._timeout_settings.timeout(timeout) deadline = (monotonic_time() + timeout) if timeout else 0 handle = await self.element_handle(timeout=timeout) if not handle: raise Error(f"Could not resolve {self._selector} to DOM Element") try: return await task( handle, (deadline - monotonic_time()) if deadline else 0, ) finally: await handle.dispose()
async def set_input_files( self, files: Union[str, Path, FilePayload, List[Union[str, Path]], List[FilePayload]], timeout: float = None, noWaitAfter: bool = None, ) -> None: params = locals_to_params(locals()) frame = await self.owner_frame() if not frame: raise Error("Cannot set input files to detached element") converted = await convert_input_files(files, frame.page.context) if converted["files"] is not None: await self._channel.send( "setInputFiles", {**params, "files": converted["files"]} ) else: await self._channel.send( "setInputFilePaths", locals_to_params({**params, **converted, "files": None}), )
async def convert_input_files( files: Union[str, Path, FilePayload, List[Union[str, Path]], List[FilePayload]], context: "BrowserContext", ) -> InputFilesList: file_list = files if isinstance(files, list) else [files] has_large_buffer = any([ len(f.get("buffer", "")) > SIZE_LIMIT_IN_BYTES for f in file_list if not isinstance(f, (str, Path)) ]) if has_large_buffer: raise Error( "Cannot set buffer larger than 50Mb, please write it to a file and pass its path instead." ) has_large_file = any([ os.stat(f).st_size > SIZE_LIMIT_IN_BYTES for f in file_list if isinstance(f, (str, Path)) ]) if has_large_file: if context._channel._connection.is_remote: streams = [] for file in file_list: assert isinstance(file, (str, Path)) stream: WritableStream = from_channel( await context._channel.send("createTempFile", {"name": os.path.basename(file)})) await stream.copy(file) streams.append(stream._channel) return InputFilesList(streams=streams, localPaths=None, files=None) local_paths = [] for p in file_list: assert isinstance(p, (str, Path)) local_paths.append(str(Path(p).absolute().resolve())) return InputFilesList(streams=None, localPaths=local_paths, files=None) return InputFilesList(streams=None, localPaths=None, files=await _normalize_file_payloads(files))
async def delete(self) -> None: artifact = await self._artifact_future if not artifact: raise Error("Page did not produce any video frames") await artifact.delete()
async def save_as(self, path: Union[str, pathlib.Path]) -> None: artifact = await self._artifact_future if not artifact: raise Error("Page did not produce any video frames") await artifact.save_as(path)
async def path(self) -> pathlib.Path: artifact = await self._artifact_future if not artifact: raise Error("Page did not produce any video frames") return artifact.absolute_path
def _page_closed(self) -> None: if not self._artifact_future.done(): self._artifact_future.set_exception(Error("Page closed"))
async def fetch( self, urlOrRequest: Union[str, network.Request], params: Dict[str, Union[bool, float, str]] = None, method: str = None, headers: Headers = None, data: Union[Any, bytes, str] = None, form: Dict[str, Union[bool, float, str]] = None, multipart: Dict[str, Union[bytes, bool, float, str, FilePayload]] = None, timeout: float = None, failOnStatusCode: bool = None, ignoreHTTPSErrors: bool = None, ) -> "APIResponse": request = urlOrRequest if isinstance(urlOrRequest, network.Request) else None assert request or isinstance( urlOrRequest, str), "First argument must be either URL string or Request" assert ( (1 if data else 0) + (1 if form else 0) + (1 if multipart else 0) ) <= 1, "Only one of 'data', 'form' or 'multipart' can be specified" url = request.url if request else urlOrRequest method = method or (request.method if request else "GET") # Cannot call allHeaders() here as the request may be paused inside route handler. headers_obj = headers or (request.headers if request else None) serialized_headers = serialize_headers( headers_obj) if headers_obj else None json_data = None form_data: Optional[List[NameValue]] = None multipart_data: Optional[List[FormField]] = None post_data_buffer: Optional[bytes] = None if data: if isinstance(data, str): post_data_buffer = data.encode() elif isinstance(data, bytes): post_data_buffer = data elif isinstance(data, (dict, list)): json_data = data else: raise Error(f"Unsupported 'data' type: {type(data)}") elif form: form_data = object_to_array(form) elif multipart: multipart_data = [] # Convert file-like values to ServerFilePayload structs. for name, value in multipart.items(): if is_file_payload(value): payload = cast(FilePayload, value) assert isinstance( payload["buffer"], bytes), f"Unexpected buffer type of 'data.{name}'" multipart_data.append( FormField(name=name, file=file_payload_to_json(payload))) elif isinstance(value, str): multipart_data.append(FormField(name=name, value=value)) if (post_data_buffer is None and json_data is None and form_data is None and multipart_data is None): post_data_buffer = request.post_data_buffer if request else None post_data = (base64.b64encode(post_data_buffer).decode() if post_data_buffer else None) def filter_none(input: Dict) -> Dict: return {k: v for k, v in input.items() if v is not None} result = await self._channel.send_return_as_dict( "fetch", filter_none({ "url": url, "params": object_to_array(params), "method": method, "headers": serialized_headers, "postData": post_data, "jsonData": json_data, "formData": form_data, "multipartData": multipart_data, "timeout": timeout, "failOnStatusCode": failOnStatusCode, "ignoreHTTPSErrors": ignoreHTTPSErrors, }), ) if result.get("error"): raise Error(result["error"]) return APIResponse(self, result["response"])
async def path_after_finished(self) -> Optional[pathlib.Path]: if self._is_remote: raise Error( "Path is not available when using browser_type.connect(). Use save_as() to save a local copy." ) return pathlib.Path(await self._channel.send("pathAfterFinished"))