diff --git a/playwright/async_api/_generated.py b/playwright/async_api/_generated.py index 59a92a296..831d8dcfb 100644 --- a/playwright/async_api/_generated.py +++ b/playwright/async_api/_generated.py @@ -210,11 +210,6 @@ def redirected_from(self) -> typing.Optional["Request"]: 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 @@ -222,11 +217,6 @@ def redirected_from(self) -> typing.Optional["Request"]: print(response.request.redirected_from) # None ``` - ```py - response = page.goto(\"https://google.com\") - print(response.request.redirected_from) # None - ``` - Returns ------- Union[Request, None] @@ -290,13 +280,6 @@ def timing(self) -> ResourceTiming: 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} @@ -707,23 +690,12 @@ async def fulfill( 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] @@ -783,16 +755,6 @@ async def handle(route): 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 @@ -856,12 +818,6 @@ async def fallback( 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. @@ -886,27 +842,6 @@ def handle_post(route): 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. @@ -923,19 +858,6 @@ async def handle(route, request): 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] @@ -985,19 +907,6 @@ async def handle(route, request): 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 @@ -1284,10 +1193,6 @@ async def insert_text(self, text: str) -> None: 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. @@ -1316,11 +1221,6 @@ async def type(self, text: str, *, delay: typing.Optional[float] = None) -> None 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. @@ -1375,18 +1275,6 @@ async def press(self, key: str, *, delay: typing.Optional[float] = None) -> None 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 @@ -1587,11 +1475,6 @@ async def evaluate( 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 @@ -1681,14 +1564,6 @@ async def get_properties(self) -> typing.Dict[str, "JSHandle"]: 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] @@ -1912,10 +1787,6 @@ async def dispatch_event( 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. @@ -1939,12 +1810,6 @@ async def dispatch_event( 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 @@ -2217,15 +2082,6 @@ async def select_option( await handle.select_option(value=[\"red\", \"green\", \"blue\"]) ``` - ```py - # Single selection matching the value or label - handle.select_option(\"blue\") - # single selection matching both the label - handle.select_option(label=\"blue\") - # multiple selection - handle.select_option(value=[\"red\", \"green\", \"blue\"]) - ``` - Parameters ---------- value : Union[Sequence[str], str, None] @@ -2745,11 +2601,6 @@ async def bounding_box(self) -> typing.Optional[FloatRect]: await page.mouse.click(box[\"x\"] + box[\"width\"] / 2, box[\"y\"] + box[\"height\"] / 2) ``` - ```py - box = element_handle.bounding_box() - page.mouse.click(box[\"x\"] + box[\"width\"] / 2, box[\"y\"] + box[\"height\"] / 2) - ``` - Returns ------- Union[{x: float, y: float, width: float, height: float}, None] @@ -2908,12 +2759,6 @@ async def eval_on_selector( assert await tweet_handle.eval_on_selector(\".retweets\", \"node => node.innerText\") == \"10\" ``` - ```py - tweet_handle = page.query_selector(\".tweet\") - assert tweet_handle.eval_on_selector(\".like\", \"node => node.innerText\") == \"100\" - assert tweet_handle.eval_on_selector(\".retweets\", \"node => node.innerText\") == \"10\" - ``` - Parameters ---------- selector : str @@ -2962,11 +2807,6 @@ async def eval_on_selector_all( assert await feed_handle.eval_on_selector_all(\".tweet\", \"nodes => nodes.map(n => n.innerText)\") == [\"hello!\", \"hi!\"] ``` - ```py - feed_handle = page.query_selector(\".feed\") - assert feed_handle.eval_on_selector_all(\".tweet\", \"nodes => nodes.map(n => n.innerText)\") == [\"hello!\", \"hi!\"] - ``` - Parameters ---------- selector : str @@ -3055,13 +2895,6 @@ async def wait_for_selector( span = await div.wait_for_selector(\"span\", state=\"attached\") ``` - ```py - page.set_content(\"
\") - div = page.query_selector(\"div\") - # waiting for the \"span\" selector relative to the div. - span = div.wait_for_selector(\"span\", state=\"attached\") - ``` - **NOTE** This method does not work across navigations, use `page.wait_for_selector()` instead. Parameters @@ -3123,11 +2956,6 @@ async def snapshot( print(snapshot) ``` - ```py - snapshot = page.accessibility.snapshot() - print(snapshot) - ``` - An example of logging the focused node's name: ```py @@ -3146,22 +2974,6 @@ def find_focused_node(node): print(node[\"name\"]) ``` - ```py - def find_focused_node(node): - if node.get(\"focused\"): - return node - for child in (node.get(\"children\") or []): - found_node = find_focused_node(child) - if found_node: - return found_node - return None - - snapshot = page.accessibility.snapshot() - node = find_focused_node(snapshot) - if node: - print(node[\"name\"]) - ``` - Parameters ---------- interesting_only : Union[bool, None] @@ -3417,12 +3229,6 @@ def expect_navigation( # Resolves after navigation has finished ``` - ```py - with frame.expect_navigation(): - frame.click(\"a.delayed-navigation\") # clicking the link will indirectly cause a navigation - # Resolves after navigation has finished - ``` - **NOTE** Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is considered a navigation. @@ -3477,11 +3283,6 @@ async def wait_for_url( await frame.wait_for_url(\"**/target.html\") ``` - ```py - frame.click(\"a.delayed-navigation\") # clicking the link will indirectly cause a navigation - frame.wait_for_url(\"**/target.html\") - ``` - Parameters ---------- url : Union[Callable[[str], bool], Pattern[str], str] @@ -3532,11 +3333,6 @@ async def wait_for_load_state( await frame.wait_for_load_state() # the promise resolves after \"load\" event. ``` - ```py - frame.click(\"button\") # click triggers navigation. - frame.wait_for_load_state() # the promise resolves after \"load\" event. - ``` - Parameters ---------- state : Union["domcontentloaded", "load", "networkidle", None] @@ -3575,12 +3371,6 @@ async def frame_element(self) -> "ElementHandle": assert frame == content_frame ``` - ```py - frame_element = frame.frame_element() - content_frame = frame_element.content_frame() - assert frame == content_frame - ``` - Returns ------- ElementHandle @@ -3609,11 +3399,6 @@ async def evaluate( print(result) # prints \"56\" ``` - ```py - result = frame.evaluate(\"([x, y]) => Promise.resolve(x * y)\", [7, 8]) - print(result) # prints \"56\" - ``` - A string can also be passed in instead of a function. ```py @@ -3622,12 +3407,6 @@ async def evaluate( print(await frame.evaluate(f\"1 + {x}\")) # prints \"11\" ``` - ```py - print(frame.evaluate(\"1 + 2\")) # prints \"3\" - x = 10 - print(frame.evaluate(f\"1 + {x}\")) # prints \"11\" - ``` - `ElementHandle` instances can be passed as an argument to the `frame.evaluate()`: ```py @@ -3636,12 +3415,6 @@ async def evaluate( await body_handle.dispose() ``` - ```py - body_handle = frame.evaluate(\"document.body\") - html = frame.evaluate(\"([body, suffix]) => body.innerHTML + suffix\", [body_handle, \"hello\"]) - body_handle.dispose() - ``` - Parameters ---------- expression : str @@ -3681,21 +3454,12 @@ async def evaluate_handle( a_window_handle # handle for the window object. ``` - ```py - a_window_handle = frame.evaluate_handle(\"Promise.resolve(window)\") - a_window_handle # handle for the window object. - ``` - A string can also be passed in instead of a function. ```py a_handle = await page.evaluate_handle(\"document\") # handle for the \"document\" ``` - ```py - a_handle = page.evaluate_handle(\"document\") # handle for the \"document\" - ``` - `JSHandle` instances can be passed as an argument to the `frame.evaluate_handle()`: ```py @@ -3705,13 +3469,6 @@ async def evaluate_handle( await result_handle.dispose() ``` - ```py - a_handle = page.evaluate_handle(\"document.body\") - result_handle = page.evaluate_handle(\"body => body.innerHTML\", a_handle) - print(result_handle.json_value()) - result_handle.dispose() - ``` - Parameters ---------- expression : str @@ -3830,23 +3587,6 @@ async def main(): asyncio.run(main()) ``` - ```py - from playwright.sync_api import sync_playwright, Playwright - - def run(playwright: Playwright): - chromium = playwright.chromium - browser = chromium.launch() - page = browser.new_page() - for current_url in [\"https://google.com\", \"https://bbc.com\"]: - page.goto(current_url, wait_until=\"domcontentloaded\") - element = page.main_frame.wait_for_selector(\"img\") - print(\"Loaded image: \" + str(element.get_attribute(\"src\"))) - browser.close() - - with sync_playwright() as playwright: - run(playwright) - ``` - Parameters ---------- selector : str @@ -4102,10 +3842,6 @@ async def dispatch_event( await frame.dispatch_event(\"button#submit\", \"click\") ``` - ```py - frame.dispatch_event(\"button#submit\", \"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. @@ -4129,12 +3865,6 @@ async def dispatch_event( await frame.dispatch_event(\"#source\", \"dragstart\", { \"dataTransfer\": data_transfer }) ``` - ```py - # note you can only create data_transfer in chromium and firefox - data_transfer = frame.evaluate_handle(\"new DataTransfer()\") - frame.dispatch_event(\"#source\", \"dragstart\", { \"dataTransfer\": data_transfer }) - ``` - Parameters ---------- selector : str @@ -4188,12 +3918,6 @@ async def eval_on_selector( html = await frame.eval_on_selector(\".main-container\", \"(e, suffix) => e.outerHTML + suffix\", \"hello\") ``` - ```py - search_value = frame.eval_on_selector(\"#search\", \"el => el.value\") - preload_href = frame.eval_on_selector(\"link[rel=preload]\", \"el => el.href\") - html = frame.eval_on_selector(\".main-container\", \"(e, suffix) => e.outerHTML + suffix\", \"hello\") - ``` - Parameters ---------- selector : str @@ -4240,10 +3964,6 @@ async def eval_on_selector_all( divs_counts = await frame.eval_on_selector_all(\"div\", \"(divs, min) => divs.length >= min\", 10) ``` - ```py - divs_counts = frame.eval_on_selector_all(\"div\", \"(divs, min) => divs.length >= min\", 10) - ``` - Parameters ---------- selector : str @@ -4766,10 +4486,6 @@ def get_by_alt_text( await page.get_by_alt_text(\"Playwright logo\").click() ``` - ```py - page.get_by_alt_text(\"Playwright logo\").click() - ``` - Parameters ---------- text : Union[Pattern[str], str] @@ -4811,11 +4527,6 @@ def get_by_label( await page.get_by_label(\"Password\").fill(\"secret\") ``` - ```py - page.get_by_label(\"Username\").fill(\"john\") - page.get_by_label(\"Password\").fill(\"secret\") - ``` - Parameters ---------- text : Union[Pattern[str], str] @@ -4855,10 +4566,6 @@ def get_by_placeholder( await page.get_by_placeholder(\"name@example.com\").fill(\"playwright@microsoft.com\") ``` - ```py - page.get_by_placeholder(\"name@example.com\").fill(\"playwright@microsoft.com\") - ``` - Parameters ---------- text : Union[Pattern[str], str] @@ -5002,14 +4709,6 @@ def get_by_role( await page.get_by_role(\"button\", name=re.compile(\"submit\", re.IGNORECASE)).click() ``` - ```py - expect(page.get_by_role(\"heading\", name=\"Sign up\")).to_be_visible() - - page.get_by_role(\"checkbox\", name=\"Subscribe\").check() - - page.get_by_role(\"button\", name=re.compile(\"submit\", re.IGNORECASE)).click() - ``` - **Details** Role selector **does not replace** accessibility audits and conformance tests, but rather gives early feedback @@ -5105,10 +4804,6 @@ def get_by_test_id( await page.get_by_test_id(\"directions\").click() ``` - ```py - page.get_by_test_id(\"directions\").click() - ``` - **Details** By default, the `data-testid` attribute is used as a test id. Use `selectors.set_test_id_attribute()` to @@ -5167,23 +4862,6 @@ def get_by_text( page.get_by_text(re.compile(\"^hello$\", re.IGNORECASE)) ``` - ```py - # Matches - page.get_by_text(\"world\") - - # Matches first
- page.get_by_text(\"Hello world\") - - # Matches second
- page.get_by_text(\"Hello\", exact=True) - - # Matches both
s - page.get_by_text(re.compile(\"Hello\")) - - # Matches second
- page.get_by_text(re.compile(\"^hello$\", re.IGNORECASE)) - ``` - **Details** Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into @@ -5231,10 +4909,6 @@ def get_by_title( await expect(page.get_by_title(\"Issues count\")).to_have_text(\"25 issues\") ``` - ```py - expect(page.get_by_title(\"Issues count\")).to_have_text(\"25 issues\") - ``` - Parameters ---------- text : Union[Pattern[str], str] @@ -5266,11 +4940,6 @@ def frame_locator(self, selector: str) -> "FrameLocator": await locator.click() ``` - ```py - locator = frame.frame_locator(\"#my-iframe\").get_by_text(\"Submit\") - locator.click() - ``` - Parameters ---------- selector : str @@ -5621,15 +5290,6 @@ async def select_option( await frame.select_option(\"select#colors\", value=[\"red\", \"green\", \"blue\"]) ``` - ```py - # Single selection matching the value or label - frame.select_option(\"select#colors\", \"blue\") - # single selection matching both the label - frame.select_option(\"select#colors\", label=\"blue\") - # multiple selection - frame.select_option(\"select#colors\", value=[\"red\", \"green\", \"blue\"]) - ``` - Parameters ---------- selector : str @@ -6061,21 +5721,6 @@ async def main(): asyncio.run(main()) ``` - ```py - from playwright.sync_api import sync_playwright, Playwright - - def run(playwright: Playwright): - webkit = playwright.webkit - browser = webkit.launch() - page = browser.new_page() - page.evaluate(\"window.x = 0; setTimeout(() => { window.x = 100 }, 1000);\") - page.main_frame.wait_for_function(\"() => window.x > 0\") - browser.close() - - with sync_playwright() as playwright: - run(playwright) - ``` - To pass an argument to the predicate of `frame.waitForFunction` function: ```py @@ -6083,11 +5728,6 @@ def run(playwright: Playwright): await frame.wait_for_function(\"selector => !!document.querySelector(selector)\", selector) ``` - ```py - selector = \".foo\" - frame.wait_for_function(\"selector => !!document.querySelector(selector)\", selector) - ``` - Parameters ---------- expression : str @@ -6307,10 +5947,6 @@ def get_by_alt_text( await page.get_by_alt_text(\"Playwright logo\").click() ``` - ```py - page.get_by_alt_text(\"Playwright logo\").click() - ``` - Parameters ---------- text : Union[Pattern[str], str] @@ -6352,11 +5988,6 @@ def get_by_label( await page.get_by_label(\"Password\").fill(\"secret\") ``` - ```py - page.get_by_label(\"Username\").fill(\"john\") - page.get_by_label(\"Password\").fill(\"secret\") - ``` - Parameters ---------- text : Union[Pattern[str], str] @@ -6396,10 +6027,6 @@ def get_by_placeholder( await page.get_by_placeholder(\"name@example.com\").fill(\"playwright@microsoft.com\") ``` - ```py - page.get_by_placeholder(\"name@example.com\").fill(\"playwright@microsoft.com\") - ``` - Parameters ---------- text : Union[Pattern[str], str] @@ -6543,14 +6170,6 @@ def get_by_role( await page.get_by_role(\"button\", name=re.compile(\"submit\", re.IGNORECASE)).click() ``` - ```py - expect(page.get_by_role(\"heading\", name=\"Sign up\")).to_be_visible() - - page.get_by_role(\"checkbox\", name=\"Subscribe\").check() - - page.get_by_role(\"button\", name=re.compile(\"submit\", re.IGNORECASE)).click() - ``` - **Details** Role selector **does not replace** accessibility audits and conformance tests, but rather gives early feedback @@ -6646,10 +6265,6 @@ def get_by_test_id( await page.get_by_test_id(\"directions\").click() ``` - ```py - page.get_by_test_id(\"directions\").click() - ``` - **Details** By default, the `data-testid` attribute is used as a test id. Use `selectors.set_test_id_attribute()` to @@ -6708,23 +6323,6 @@ def get_by_text( page.get_by_text(re.compile(\"^hello$\", re.IGNORECASE)) ``` - ```py - # Matches - page.get_by_text(\"world\") - - # Matches first
- page.get_by_text(\"Hello world\") - - # Matches second
- page.get_by_text(\"Hello\", exact=True) - - # Matches both
s - page.get_by_text(re.compile(\"Hello\")) - - # Matches second
- page.get_by_text(re.compile(\"^hello$\", re.IGNORECASE)) - ``` - **Details** Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into @@ -6772,10 +6370,6 @@ def get_by_title( await expect(page.get_by_title(\"Issues count\")).to_have_text(\"25 issues\") ``` - ```py - expect(page.get_by_title(\"Issues count\")).to_have_text(\"25 issues\") - ``` - Parameters ---------- text : Union[Pattern[str], str] @@ -6985,41 +6579,6 @@ async def main(): asyncio.run(main()) ``` - ```py - from playwright.sync_api import sync_playwright, Playwright - - def run(playwright: Playwright): - tag_selector = \"\"\" - { - // Returns the first element matching given selector in the root's subtree. - query(root, selector) { - return root.querySelector(selector); - }, - // Returns all elements matching given selector in the root's subtree. - queryAll(root, selector) { - return Array.from(root.querySelectorAll(selector)); - } - }\"\"\" - - # Register the engine. Selectors will be prefixed with \"tag=\". - playwright.selectors.register(\"tag\", tag_selector) - browser = playwright.chromium.launch() - page = browser.new_page() - page.set_content('
') - - # Use the selector prefixed with its name. - button = page.locator('tag=button') - # Combine it with built-in locators. - page.locator('tag=div').get_by_text('Click me').click() - # Can use it in any methods supporting selectors. - button_count = page.locator('tag=button').count() - print(button_count) - browser.close() - - with sync_playwright() as playwright: - run(playwright) - ``` - Parameters ---------- name : str @@ -7290,10 +6849,6 @@ async def save_as(self, path: typing.Union[str, pathlib.Path]) -> None: await download.save_as(\"/path/to/save/at/\" + download.suggested_filename) ``` - ```py - download.save_as(\"/path/to/save/at/\" + download.suggested_filename) - ``` - Parameters ---------- path : Union[pathlib.Path, str] @@ -7390,15 +6945,6 @@ async def print_args(msg): page.on(\"console\", print_args) await page.evaluate(\"console.log('hello', 5, { foo: 'bar' })\") - ``` - - ```py - def print_args(msg): - for arg in msg.args: - print(arg.json_value()) - - page.on(\"console\", print_args) - page.evaluate(\"console.log('hello', 5, { foo: 'bar' })\") ```""" @typing.overload @@ -7422,17 +6968,6 @@ def on( except Error as e: pass # when the page crashes, exception message contains \"crash\". - ``` - - ```py - try: - # crash might happen during a click. - page.click(\"button\") - # or while waiting for an event. - page.wait_for_event(\"popup\") - except Error as e: - pass - # when the page crashes, exception message contains \"crash\". ```""" @typing.overload @@ -7545,14 +7080,6 @@ def on( # Navigate to a page with an exception. await page.goto(\"data:text/html,\") - ``` - - ```py - # Log all uncaught errors to the terminal - page.on(\"pageerror\", lambda exc: print(f\"uncaught exception: {exc}\")) - - # Navigate to a page with an exception. - page.goto(\"data:text/html,\") ```""" @typing.overload @@ -7576,13 +7103,6 @@ def on( print(await popup.evaluate(\"location.href\")) ``` - ```py - with page.expect_event(\"popup\") as page_info: - page.get_by_text(\"open the popup\").click() - popup = page_info.value - print(popup.evaluate(\"location.href\")) - ``` - **NOTE** Use `page.wait_for_load_state()` to wait until the page gets to a particular state (you should not need it in most cases).""" @@ -7694,15 +7214,6 @@ async def print_args(msg): page.on(\"console\", print_args) await page.evaluate(\"console.log('hello', 5, { foo: 'bar' })\") - ``` - - ```py - def print_args(msg): - for arg in msg.args: - print(arg.json_value()) - - page.on(\"console\", print_args) - page.evaluate(\"console.log('hello', 5, { foo: 'bar' })\") ```""" @typing.overload @@ -7726,17 +7237,6 @@ def once( except Error as e: pass # when the page crashes, exception message contains \"crash\". - ``` - - ```py - try: - # crash might happen during a click. - page.click(\"button\") - # or while waiting for an event. - page.wait_for_event(\"popup\") - except Error as e: - pass - # when the page crashes, exception message contains \"crash\". ```""" @typing.overload @@ -7849,14 +7349,6 @@ def once( # Navigate to a page with an exception. await page.goto(\"data:text/html,\") - ``` - - ```py - # Log all uncaught errors to the terminal - page.on(\"pageerror\", lambda exc: print(f\"uncaught exception: {exc}\")) - - # Navigate to a page with an exception. - page.goto(\"data:text/html,\") ```""" @typing.overload @@ -7880,13 +7372,6 @@ def once( print(await popup.evaluate(\"location.href\")) ``` - ```py - with page.expect_event(\"popup\") as page_info: - page.get_by_text(\"open the popup\").click() - popup = page_info.value - print(popup.evaluate(\"location.href\")) - ``` - **NOTE** Use `page.wait_for_load_state()` to wait until the page gets to a particular state (you should not need it in most cases).""" @@ -8131,10 +7616,6 @@ def frame( frame = page.frame(name=\"frame-name\") ``` - ```py - frame = page.frame(url=r\".*domain.*\") - ``` - Parameters ---------- name : Union[str, None] @@ -8284,23 +7765,6 @@ async def main(): asyncio.run(main()) ``` - ```py - from playwright.sync_api import sync_playwright, Playwright - - def run(playwright: Playwright): - chromium = playwright.chromium - browser = chromium.launch() - page = browser.new_page() - for current_url in [\"https://google.com\", \"https://bbc.com\"]: - page.goto(current_url, wait_until=\"domcontentloaded\") - element = page.wait_for_selector(\"img\") - print(\"Loaded image: \" + str(element.get_attribute(\"src\"))) - browser.close() - - with sync_playwright() as playwright: - run(playwright) - ``` - Parameters ---------- selector : str @@ -8556,10 +8020,6 @@ async def dispatch_event( await page.dispatch_event(\"button#submit\", \"click\") ``` - ```py - page.dispatch_event(\"button#submit\", \"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. @@ -8583,12 +8043,6 @@ async def dispatch_event( await page.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()\") - page.dispatch_event(\"#source\", \"dragstart\", { \"dataTransfer\": data_transfer }) - ``` - Parameters ---------- selector : str @@ -8639,11 +8093,6 @@ async def evaluate( print(result) # prints \"56\" ``` - ```py - result = page.evaluate(\"([x, y]) => Promise.resolve(x * y)\", [7, 8]) - print(result) # prints \"56\" - ``` - A string can also be passed in instead of a function: ```py @@ -8652,12 +8101,6 @@ async def evaluate( print(await page.evaluate(f\"1 + {x}\")) # prints \"11\" ``` - ```py - print(page.evaluate(\"1 + 2\")) # prints \"3\" - x = 10 - print(page.evaluate(f\"1 + {x}\")) # prints \"11\" - ``` - `ElementHandle` instances can be passed as an argument to the `page.evaluate()`: ```py @@ -8666,12 +8109,6 @@ async def evaluate( await body_handle.dispose() ``` - ```py - body_handle = page.evaluate(\"document.body\") - html = page.evaluate(\"([body, suffix]) => body.innerHTML + suffix\", [body_handle, \"hello\"]) - body_handle.dispose() - ``` - Parameters ---------- expression : str @@ -8711,21 +8148,12 @@ async def evaluate_handle( a_window_handle # handle for the window object. ``` - ```py - a_window_handle = page.evaluate_handle(\"Promise.resolve(window)\") - a_window_handle # handle for the window object. - ``` - A string can also be passed in instead of a function: ```py a_handle = await page.evaluate_handle(\"document\") # handle for the \"document\" ``` - ```py - a_handle = page.evaluate_handle(\"document\") # handle for the \"document\" - ``` - `JSHandle` instances can be passed as an argument to the `page.evaluate_handle()`: ```py @@ -8735,13 +8163,6 @@ async def evaluate_handle( await result_handle.dispose() ``` - ```py - a_handle = page.evaluate_handle(\"document.body\") - result_handle = page.evaluate_handle(\"body => body.innerHTML\", a_handle) - print(result_handle.json_value()) - result_handle.dispose() - ``` - Parameters ---------- expression : str @@ -8785,12 +8206,6 @@ async def eval_on_selector( html = await page.eval_on_selector(\".main-container\", \"(e, suffix) => e.outer_html + suffix\", \"hello\") ``` - ```py - search_value = page.eval_on_selector(\"#search\", \"el => el.value\") - preload_href = page.eval_on_selector(\"link[rel=preload]\", \"el => el.href\") - html = page.eval_on_selector(\".main-container\", \"(e, suffix) => e.outer_html + suffix\", \"hello\") - ``` - Parameters ---------- selector : str @@ -8835,10 +8250,6 @@ async def eval_on_selector_all( div_counts = await page.eval_on_selector_all(\"div\", \"(divs, min) => divs.length >= min\", 10) ``` - ```py - div_counts = page.eval_on_selector_all(\"div\", \"(divs, min) => divs.length >= min\", 10) - ``` - Parameters ---------- selector : str @@ -8976,35 +8387,6 @@ async def main(): asyncio.run(main()) ``` - ```py - import hashlib - from playwright.sync_api import sync_playwright, Playwright - - def sha256(text): - m = hashlib.sha256() - m.update(bytes(text, \"utf8\")) - return m.hexdigest() - - def run(playwright: Playwright): - webkit = playwright.webkit - browser = webkit.launch(headless=False) - page = browser.new_page() - page.expose_function(\"sha256\", sha256) - page.set_content(\"\"\" - - -
- \"\"\") - page.click(\"button\") - - with sync_playwright() as playwright: - run(playwright) - ``` - Parameters ---------- name : str @@ -9070,30 +8452,6 @@ async def main(): asyncio.run(main()) ``` - ```py - from playwright.sync_api import sync_playwright, Playwright - - def run(playwright: Playwright): - webkit = playwright.webkit - browser = webkit.launch(headless=False) - context = browser.new_context() - page = context.new_page() - page.expose_binding(\"pageURL\", lambda source: source[\"page\"].url) - page.set_content(\"\"\" - - -
- \"\"\") - page.click(\"button\") - - with sync_playwright() as playwright: - run(playwright) - ``` - An example of passing an element handle: ```py @@ -9110,20 +8468,6 @@ async def print(source, element): \"\"\") ``` - ```py - def print(source, element): - print(element.text_content()) - - page.expose_binding(\"clicked\", print, handle=true) - page.set_content(\"\"\" - -
Click me
-
Or click me
- \"\"\") - ``` - Parameters ---------- name : str @@ -9339,11 +8683,6 @@ async def wait_for_load_state( await page.wait_for_load_state() # the promise resolves after \"load\" event. ``` - ```py - page.get_by_role(\"button\").click() # click triggers navigation. - page.wait_for_load_state() # the promise resolves after \"load\" event. - ``` - ```py async with page.expect_popup() as page_info: await page.get_by_role(\"button\").click() # click triggers a popup. @@ -9353,15 +8692,6 @@ async def wait_for_load_state( print(await popup.title()) # popup is ready to use. ``` - ```py - with page.expect_popup() as page_info: - page.get_by_role(\"button\").click() # click triggers a popup. - popup = page_info.value - # Wait for the \"DOMContentLoaded\" event. - popup.wait_for_load_state(\"domcontentloaded\") - print(popup.title()) # popup is ready to use. - ``` - Parameters ---------- state : Union["domcontentloaded", "load", "networkidle", None] @@ -9402,11 +8732,6 @@ async def wait_for_url( await page.wait_for_url(\"**/target.html\") ``` - ```py - page.click(\"a.delayed-navigation\") # clicking the link will indirectly cause a navigation - page.wait_for_url(\"**/target.html\") - ``` - Parameters ---------- url : Union[Callable[[str], bool], Pattern[str], str] @@ -9588,25 +8913,6 @@ async def emulate_media( # → False ``` - ```py - page.evaluate(\"matchMedia('screen').matches\") - # → True - page.evaluate(\"matchMedia('print').matches\") - # → False - - page.emulate_media(media=\"print\") - page.evaluate(\"matchMedia('screen').matches\") - # → False - page.evaluate(\"matchMedia('print').matches\") - # → True - - page.emulate_media() - page.evaluate(\"matchMedia('screen').matches\") - # → True - page.evaluate(\"matchMedia('print').matches\") - # → False - ``` - ```py await page.emulate_media(color_scheme=\"dark\") await page.evaluate(\"matchMedia('(prefers-color-scheme: dark)').matches\") @@ -9617,15 +8923,6 @@ async def emulate_media( # → False ``` - ```py - page.emulate_media(color_scheme=\"dark\") - page.evaluate(\"matchMedia('(prefers-color-scheme: dark)').matches\") - # → True - page.evaluate(\"matchMedia('(prefers-color-scheme: light)').matches\") - # → False - page.evaluate(\"matchMedia('(prefers-color-scheme: no-preference)').matches\") - ``` - Parameters ---------- media : Union["null", "print", "screen", None] @@ -9668,12 +8965,6 @@ async def set_viewport_size(self, viewport_size: ViewportSize) -> None: await page.goto(\"https://example.com\") ``` - ```py - page = browser.new_page() - page.set_viewport_size({\"width\": 640, \"height\": 480}) - page.goto(\"https://example.com\") - ``` - Parameters ---------- viewport_size : {width: int, height: int} @@ -9716,11 +9007,6 @@ async def add_init_script( await page.add_init_script(path=\"./preload.js\") ``` - ```py - # in your playwright script, assuming the preload.js file is in same directory - page.add_init_script(path=\"./preload.js\") - ``` - **NOTE** The order of evaluation of multiple scripts installed via `browser_context.add_init_script()` and `page.add_init_script()` is not defined. @@ -9771,13 +9057,6 @@ async def route( await browser.close() ``` - ```py - page = browser.new_page() - page.route(\"**/*.{png,jpg,jpeg}\", lambda route: route.abort()) - page.goto(\"https://example.com\") - browser.close() - ``` - or the same snippet using a regex pattern instead: ```py @@ -9787,13 +9066,6 @@ async def route( await browser.close() ``` - ```py - page = browser.new_page() - page.route(re.compile(r\"(\\.png$)|(\\.jpg$)\"), lambda route: route.abort()) - page.goto(\"https://example.com\") - browser.close() - ``` - It is possible to examine the request to decide the route action. For example, mocking all requests that contain some post data, and leaving all other requests as is: @@ -9806,15 +9078,6 @@ def handle_route(route): await page.route(\"/api/**\", handle_route) ``` - ```py - def handle_route(route): - if (\"my-string\" in route.request.post_data): - route.fulfill(body=\"mocked-data\") - else: - route.continue_() - page.route(\"/api/**\", handle_route) - ``` - Page routes take precedence over browser context routes (set up with `browser_context.route()`) when request matches both handlers. @@ -10459,10 +9722,6 @@ def get_by_alt_text( await page.get_by_alt_text(\"Playwright logo\").click() ``` - ```py - page.get_by_alt_text(\"Playwright logo\").click() - ``` - Parameters ---------- text : Union[Pattern[str], str] @@ -10504,11 +9763,6 @@ def get_by_label( await page.get_by_label(\"Password\").fill(\"secret\") ``` - ```py - page.get_by_label(\"Username\").fill(\"john\") - page.get_by_label(\"Password\").fill(\"secret\") - ``` - Parameters ---------- text : Union[Pattern[str], str] @@ -10548,10 +9802,6 @@ def get_by_placeholder( await page.get_by_placeholder(\"name@example.com\").fill(\"playwright@microsoft.com\") ``` - ```py - page.get_by_placeholder(\"name@example.com\").fill(\"playwright@microsoft.com\") - ``` - Parameters ---------- text : Union[Pattern[str], str] @@ -10695,14 +9945,6 @@ def get_by_role( await page.get_by_role(\"button\", name=re.compile(\"submit\", re.IGNORECASE)).click() ``` - ```py - expect(page.get_by_role(\"heading\", name=\"Sign up\")).to_be_visible() - - page.get_by_role(\"checkbox\", name=\"Subscribe\").check() - - page.get_by_role(\"button\", name=re.compile(\"submit\", re.IGNORECASE)).click() - ``` - **Details** Role selector **does not replace** accessibility audits and conformance tests, but rather gives early feedback @@ -10798,10 +10040,6 @@ def get_by_test_id( await page.get_by_test_id(\"directions\").click() ``` - ```py - page.get_by_test_id(\"directions\").click() - ``` - **Details** By default, the `data-testid` attribute is used as a test id. Use `selectors.set_test_id_attribute()` to @@ -10860,23 +10098,6 @@ def get_by_text( page.get_by_text(re.compile(\"^hello$\", re.IGNORECASE)) ``` - ```py - # Matches - page.get_by_text(\"world\") - - # Matches first
- page.get_by_text(\"Hello world\") - - # Matches second
- page.get_by_text(\"Hello\", exact=True) - - # Matches both
s - page.get_by_text(re.compile(\"Hello\")) - - # Matches second
- page.get_by_text(re.compile(\"^hello$\", re.IGNORECASE)) - ``` - **Details** Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into @@ -10924,10 +10145,6 @@ def get_by_title( await expect(page.get_by_title(\"Issues count\")).to_have_text(\"25 issues\") ``` - ```py - expect(page.get_by_title(\"Issues count\")).to_have_text(\"25 issues\") - ``` - Parameters ---------- text : Union[Pattern[str], str] @@ -10959,11 +10176,6 @@ def frame_locator(self, selector: str) -> "FrameLocator": await locator.click() ``` - ```py - locator = page.frame_locator(\"#my-iframe\").get_by_text(\"Submit\") - locator.click() - ``` - Parameters ---------- selector : str @@ -11245,17 +10457,6 @@ async def drag_and_drop( ) ``` - ```py - page.drag_and_drop(\"#source\", \"#target\") - # or specify exact positions relative to the top-left corners of the elements: - page.drag_and_drop( - \"#source\", - \"#target\", - source_position={\"x\": 34, \"y\": 7}, - target_position={\"x\": 10, \"y\": 20} - ) - ``` - Parameters ---------- source : str @@ -11341,15 +10542,6 @@ async def select_option( await page.select_option(\"select#colors\", value=[\"red\", \"green\", \"blue\"]) ``` - ```py - # Single selection matching the value or label - page.select_option(\"select#colors\", \"blue\") - # single selection matching both the label - page.select_option(\"select#colors\", label=\"blue\") - # multiple selection - page.select_option(\"select#colors\", value=[\"red\", \"green\", \"blue\"]) - ``` - Parameters ---------- selector : str @@ -11586,18 +10778,6 @@ async def press( await browser.close() ``` - ```py - page = browser.new_page() - page.goto(\"https://keycode.info\") - page.press(\"body\", \"A\") - page.screenshot(path=\"a.png\") - page.press(\"body\", \"ArrowLeft\") - page.screenshot(path=\"arrow_left.png\") - page.press(\"body\", \"Shift+O\") - page.screenshot(path=\"o.png\") - browser.close() - ``` - Parameters ---------- selector : str @@ -11773,11 +10953,6 @@ async def wait_for_timeout(self, timeout: float) -> None: await page.wait_for_timeout(1000) ``` - ```py - # wait for 1 second - page.wait_for_timeout(1000) - ``` - Parameters ---------- timeout : float @@ -11822,21 +10997,6 @@ async def main(): asyncio.run(main()) ``` - ```py - from playwright.sync_api import sync_playwright, Playwright - - def run(playwright: Playwright): - webkit = playwright.webkit - browser = webkit.launch() - page = browser.new_page() - page.evaluate(\"window.x = 0; setTimeout(() => { window.x = 100 }, 1000);\") - page.wait_for_function(\"() => window.x > 0\") - browser.close() - - with sync_playwright() as playwright: - run(playwright) - ``` - To pass an argument to the predicate of `page.wait_for_function()` function: ```py @@ -11844,11 +11004,6 @@ def run(playwright: Playwright): await page.wait_for_function(\"selector => !!document.querySelector(selector)\", selector) ``` - ```py - selector = \".foo\" - page.wait_for_function(\"selector => !!document.querySelector(selector)\", selector) - ``` - Parameters ---------- expression : str @@ -11932,12 +11087,6 @@ async def pdf( await page.pdf(path=\"page.pdf\") ``` - ```py - # generates a pdf with \"screen\" media type. - page.emulate_media(media=\"screen\") - page.pdf(path=\"page.pdf\") - ``` - The `width`, `height`, and `margin` options accept values labeled with units. Unlabeled values are treated as pixels. @@ -12048,12 +11197,6 @@ def expect_event( frame = await event_info.value ``` - ```py - with page.expect_event(\"framenavigated\") as event_info: - page.get_by_role(\"button\") - frame = event_info.value - ``` - Parameters ---------- event : str @@ -12198,13 +11341,6 @@ def expect_navigation( # Resolves after navigation has finished ``` - ```py - with page.expect_navigation(): - # This action triggers the navigation after a timeout. - page.get_by_text(\"Navigate after timeout\").click() - # Resolves after navigation has finished - ``` - **NOTE** Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is considered a navigation. @@ -12296,17 +11432,6 @@ def expect_request( second_request = await second.value ``` - ```py - with page.expect_request(\"http://example.com/resource\") as first: - page.get_by_text(\"trigger request\").click() - first_request = first.value - - # or with a lambda - with page.expect_request(lambda request: request.url == \"http://example.com\" and request.method == \"get\") as second: - page.get_by_text(\"trigger request\").click() - second_request = second.value - ``` - Parameters ---------- url_or_predicate : Union[Callable[[Request], bool], Pattern[str], str] @@ -12387,19 +11512,6 @@ def expect_response( return response.ok ``` - ```py - with page.expect_response(\"https://example.com/resource\") as response_info: - page.get_by_text(\"trigger response\").click() - response = response_info.value - return response.ok - - # or with a lambda - with page.expect_response(lambda response: response.url == \"https://example.com\" and response.status == 200) as response_info: - page.get_by_text(\"trigger response\").click() - response = response_info.value - return response.ok - ``` - Parameters ---------- url_or_predicate : Union[Callable[[Response], bool], Pattern[str], str] @@ -12598,10 +11710,6 @@ def on( ```py background_page = await context.wait_for_event(\"backgroundpage\") - ``` - - ```py - background_page = context.wait_for_event(\"backgroundpage\") ```""" @typing.overload @@ -12643,15 +11751,6 @@ async def print_args(msg): context.on(\"console\", print_args) await page.evaluate(\"console.log('hello', 5, { foo: 'bar' })\") - ``` - - ```py - def print_args(msg): - for arg in msg.args: - print(arg.json_value()) - - context.on(\"console\", print_args) - page.evaluate(\"console.log('hello', 5, { foo: 'bar' })\") ```""" @typing.overload @@ -12697,13 +11796,6 @@ def on( print(await page.evaluate(\"location.href\")) ``` - ```py - with context.expect_page() as page_info: - page.get_by_text(\"open new page\").click(), - page = page_info.value - print(page.evaluate(\"location.href\")) - ``` - **NOTE** Use `page.wait_for_load_state()` to wait until the page gets to a particular state (you should not need it in most cases).""" @@ -12797,10 +11889,6 @@ def once( ```py background_page = await context.wait_for_event(\"backgroundpage\") - ``` - - ```py - background_page = context.wait_for_event(\"backgroundpage\") ```""" @typing.overload @@ -12842,15 +11930,6 @@ async def print_args(msg): context.on(\"console\", print_args) await page.evaluate(\"console.log('hello', 5, { foo: 'bar' })\") - ``` - - ```py - def print_args(msg): - for arg in msg.args: - print(arg.json_value()) - - context.on(\"console\", print_args) - page.evaluate(\"console.log('hello', 5, { foo: 'bar' })\") ```""" @typing.overload @@ -12896,13 +11975,6 @@ def once( print(await page.evaluate(\"location.href\")) ``` - ```py - with context.expect_page() as page_info: - page.get_by_text(\"open new page\").click(), - page = page_info.value - print(page.evaluate(\"location.href\")) - ``` - **NOTE** Use `page.wait_for_load_state()` to wait until the page gets to a particular state (you should not need it in most cases).""" @@ -13146,10 +12218,6 @@ async def add_cookies(self, cookies: typing.Sequence[SetCookieParam]) -> None: await browser_context.add_cookies([cookie_object1, cookie_object2]) ``` - ```py - browser_context.add_cookies([cookie_object1, cookie_object2]) - ``` - Parameters ---------- cookies : Sequence[{name: str, value: str, url: Union[str, None], domain: Union[str, None], path: Union[str, None], expires: Union[float, None], httpOnly: Union[bool, None], secure: Union[bool, None], sameSite: Union["Lax", "None", "Strict", None]}] @@ -13220,13 +12288,6 @@ async def clear_permissions(self) -> None: # do stuff .. context.clear_permissions() ``` - - ```py - context = browser.new_context() - context.grant_permissions([\"clipboard-read\"]) - # do stuff .. - context.clear_permissions() - ``` """ return mapping.from_maybe_impl(await self._impl_obj.clear_permissions()) @@ -13244,10 +12305,6 @@ async def set_geolocation( await browser_context.set_geolocation({\"latitude\": 59.95, \"longitude\": 30.31667}) ``` - ```py - browser_context.set_geolocation({\"latitude\": 59.95, \"longitude\": 30.31667}) - ``` - **NOTE** Consider using `browser_context.grant_permissions()` to grant permissions for the browser context pages to read its geolocation. @@ -13320,11 +12377,6 @@ async def add_init_script( await browser_context.add_init_script(path=\"preload.js\") ``` - ```py - # in your playwright script, assuming the preload.js file is in same directory. - browser_context.add_init_script(path=\"preload.js\") - ``` - **NOTE** The order of evaluation of multiple scripts installed via `browser_context.add_init_script()` and `page.add_init_script()` is not defined. @@ -13390,30 +12442,6 @@ async def main(): asyncio.run(main()) ``` - ```py - from playwright.sync_api import sync_playwright, Playwright - - def run(playwright: Playwright): - webkit = playwright.webkit - browser = webkit.launch(headless=False) - context = browser.new_context() - context.expose_binding(\"pageURL\", lambda source: source[\"page\"].url) - page = context.new_page() - page.set_content(\"\"\" - - -
- \"\"\") - page.get_by_role(\"button\").click() - - with sync_playwright() as playwright: - run(playwright) - ``` - An example of passing an element handle: ```py @@ -13430,20 +12458,6 @@ async def print(source, element): \"\"\") ``` - ```py - def print(source, element): - print(element.text_content()) - - context.expose_binding(\"clicked\", print, handle=true) - page.set_content(\"\"\" - -
Click me
-
Or click me
- \"\"\") - ``` - Parameters ---------- name : str @@ -13508,36 +12522,6 @@ async def main(): asyncio.run(main()) ``` - ```py - import hashlib - from playwright.sync_api import sync_playwright - - def sha256(text: str) -> str: - m = hashlib.sha256() - m.update(bytes(text, \"utf8\")) - return m.hexdigest() - - def run(playwright: Playwright): - webkit = playwright.webkit - browser = webkit.launch(headless=False) - context = browser.new_context() - context.expose_function(\"sha256\", sha256) - page = context.new_page() - page.set_content(\"\"\" - - -
- \"\"\") - page.get_by_role(\"button\").click() - - with sync_playwright() as playwright: - run(playwright) - ``` - Parameters ---------- name : str @@ -13583,14 +12567,6 @@ async def route( await browser.close() ``` - ```py - context = browser.new_context() - page = context.new_page() - context.route(\"**/*.{png,jpg,jpeg}\", lambda route: route.abort()) - page.goto(\"https://example.com\") - browser.close() - ``` - or the same snippet using a regex pattern instead: ```py @@ -13602,16 +12578,6 @@ async def route( await browser.close() ``` - ```py - context = browser.new_context() - page = context.new_page() - context.route(re.compile(r\"(\\.png$)|(\\.jpg$)\"), lambda route: route.abort()) - page = await context.new_page() - page = context.new_page() - page.goto(\"https://example.com\") - browser.close() - ``` - It is possible to examine the request to decide the route action. For example, mocking all requests that contain some post data, and leaving all other requests as is: @@ -13624,15 +12590,6 @@ def handle_route(route): await context.route(\"/api/**\", handle_route) ``` - ```py - def handle_route(route): - if (\"my-string\" in route.request.post_data): - route.fulfill(body=\"mocked-data\") - else: - route.continue_() - context.route(\"/api/**\", handle_route) - ``` - Page routes (set up with `page.route()`) take precedence over browser context routes when request matches both handlers. @@ -13789,12 +12746,6 @@ def expect_event( page = await event_info.value ``` - ```py - with context.expect_event(\"page\") as event_info: - page.get_by_role(\"button\").click() - page = event_info.value - ``` - Parameters ---------- event : str @@ -14051,13 +13002,6 @@ def contexts(self) -> typing.List["BrowserContext"]: print(len(browser.contexts())) # prints `1` ``` - ```py - browser = pw.webkit.launch() - print(len(browser.contexts())) # prints `0` - context = browser.new_context() - print(len(browser.contexts())) # prints `1` - ``` - Returns ------- List[BrowserContext] @@ -14170,19 +13114,6 @@ async def new_context( await browser.close() ``` - ```py - browser = playwright.firefox.launch() # or \"chromium\" or \"webkit\". - # create a new incognito browser context. - context = browser.new_context() - # create a new page in a pristine context. - page = context.new_page() - page.goto(\"https://example.com\") - - # gracefully close up everything - context.close() - browser.close() - ``` - Parameters ---------- viewport : Union[{width: int, height: int}, None] @@ -14620,12 +13551,6 @@ async def start_tracing( await browser.stop_tracing() ``` - ```py - browser.start_tracing(page, path=\"trace.json\") - page.goto(\"https://www.google.com\") - browser.stop_tracing() - ``` - Parameters ---------- page : Union[Page, None] @@ -14732,12 +13657,6 @@ async def launch( ) ``` - ```py - browser = playwright.chromium.launch( # or \"firefox\" or \"webkit\". - ignore_default_args=[\"--mute-audio\"] - ) - ``` - > **Chromium-only** Playwright can also be used to control the Google Chrome or Microsoft Edge browsers, but it works best with the version of Chromium it is bundled with. There is no guarantee it will work with any other version. Use `executablePath` option with extreme caution. @@ -15149,12 +14068,6 @@ async def connect_over_cdp( page = default_context.pages[0] ``` - ```py - browser = playwright.chromium.connect_over_cdp(\"http://localhost:9222\") - default_context = browser.contexts[0] - page = default_context.pages[0] - ``` - Parameters ---------- endpoint_url : str @@ -15270,23 +14183,6 @@ async def main(): asyncio.run(main()) ``` - ```py - from playwright.sync_api import sync_playwright, Playwright - - def run(playwright: Playwright): - webkit = playwright.webkit - iphone = playwright.devices[\"iPhone 6\"] - browser = webkit.launch() - context = browser.new_context(**iphone) - page = context.new_page() - page.goto(\"http://example.com\") - # other actions... - browser.close() - - with sync_playwright() as playwright: - run(playwright) - ``` - Returns ------- Dict @@ -15407,13 +14303,6 @@ async def start( await context.tracing.stop(path = \"trace.zip\") ``` - ```py - context.tracing.start(screenshots=True, snapshots=True) - page = context.new_page() - page.goto(\"https://playwright.dev\") - context.tracing.stop(path = \"trace.zip\") - ``` - Parameters ---------- name : Union[str, None] @@ -15469,22 +14358,6 @@ async def start_chunk( await context.tracing.stop_chunk(path = \"trace2.zip\") ``` - ```py - context.tracing.start(screenshots=True, snapshots=True) - page = context.new_page() - page.goto(\"https://playwright.dev\") - - context.tracing.start_chunk() - page.get_by_text(\"Get Started\").click() - # Everything between start_chunk and stop_chunk will be recorded in the trace. - context.tracing.stop_chunk(path = \"trace1.zip\") - - context.tracing.start_chunk() - page.goto(\"http://example.com\") - # Save a second trace file with different actions. - context.tracing.stop_chunk(path = \"trace2.zip\") - ``` - Parameters ---------- title : Union[str, None] @@ -15570,10 +14443,6 @@ def last(self) -> "Locator": banana = await page.get_by_role(\"listitem\").last ``` - ```py - banana = page.get_by_role(\"listitem\").last - ``` - Returns ------- Locator @@ -15608,11 +14477,6 @@ async def bounding_box( await page.mouse.click(box[\"x\"] + box[\"width\"] / 2, box[\"y\"] + box[\"height\"] / 2) ``` - ```py - box = page.get_by_role(\"button\").bounding_box() - page.mouse.click(box[\"x\"] + box[\"width\"] / 2, box[\"y\"] + box[\"height\"] / 2) - ``` - Parameters ---------- timeout : Union[float, None] @@ -15663,10 +14527,6 @@ async def check( await page.get_by_role(\"checkbox\").check() ``` - ```py - page.get_by_role(\"checkbox\").check() - ``` - Parameters ---------- position : Union[{x: float, y: float}, None] @@ -15736,10 +14596,6 @@ async def click( await page.get_by_role(\"button\").click() ``` - ```py - page.get_by_role(\"button\").click() - ``` - Shift-right-click at a specific position on a canvas: ```py @@ -15748,12 +14604,6 @@ async def click( ) ``` - ```py - page.locator(\"canvas\").click( - button=\"right\", modifiers=[\"Shift\"], position={\"x\": 23, \"y\": 32} - ) - ``` - Parameters ---------- modifiers : Union[Sequence[Union["Alt", "Control", "Meta", "Shift"]], None] @@ -15886,10 +14736,6 @@ async def dispatch_event( await locator.dispatch_event(\"click\") ``` - ```py - locator.dispatch_event(\"click\") - ``` - **Details** The snippet above dispatches the `click` event on the element. Regardless of the visibility state of the element, @@ -15919,12 +14765,6 @@ async def dispatch_event( await locator.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()\") - locator.dispatch_event(\"#source\", \"dragstart\", {\"dataTransfer\": data_transfer}) - ``` - Parameters ---------- type : str @@ -15969,11 +14809,6 @@ async def evaluate( assert await tweets.evaluate(\"node => node.innerText\") == \"10 retweets\" ``` - ```py - tweets = page.locator(\".tweet .retweets\") - assert tweets.evaluate(\"node => node.innerText\") == \"10 retweets\" - ``` - Parameters ---------- expression : str @@ -16019,11 +14854,6 @@ async def evaluate_all( more_than_ten = await locator.evaluate_all(\"(divs, min) => divs.length > min\", 10) ``` - ```py - locator = page.locator(\"div\") - more_than_ten = locator.evaluate_all(\"(divs, min) => divs.length > min\", 10) - ``` - Parameters ---------- expression : str @@ -16109,10 +14939,6 @@ async def fill( await page.get_by_role(\"textbox\").fill(\"example value\") ``` - ```py - page.get_by_role(\"textbox\").fill(\"example value\") - ``` - **Details** This method waits for [actionability](https://playwright.dev/python/docs/actionability) checks, focuses the element, fills it and triggers an @@ -16173,10 +14999,6 @@ async def clear( await page.get_by_role(\"textbox\").clear() ``` - ```py - page.get_by_role(\"textbox\").clear() - ``` - Parameters ---------- timeout : Union[float, None] @@ -16276,10 +15098,6 @@ def get_by_alt_text( await page.get_by_alt_text(\"Playwright logo\").click() ``` - ```py - page.get_by_alt_text(\"Playwright logo\").click() - ``` - Parameters ---------- text : Union[Pattern[str], str] @@ -16321,11 +15139,6 @@ def get_by_label( await page.get_by_label(\"Password\").fill(\"secret\") ``` - ```py - page.get_by_label(\"Username\").fill(\"john\") - page.get_by_label(\"Password\").fill(\"secret\") - ``` - Parameters ---------- text : Union[Pattern[str], str] @@ -16365,10 +15178,6 @@ def get_by_placeholder( await page.get_by_placeholder(\"name@example.com\").fill(\"playwright@microsoft.com\") ``` - ```py - page.get_by_placeholder(\"name@example.com\").fill(\"playwright@microsoft.com\") - ``` - Parameters ---------- text : Union[Pattern[str], str] @@ -16512,14 +15321,6 @@ def get_by_role( await page.get_by_role(\"button\", name=re.compile(\"submit\", re.IGNORECASE)).click() ``` - ```py - expect(page.get_by_role(\"heading\", name=\"Sign up\")).to_be_visible() - - page.get_by_role(\"checkbox\", name=\"Subscribe\").check() - - page.get_by_role(\"button\", name=re.compile(\"submit\", re.IGNORECASE)).click() - ``` - **Details** Role selector **does not replace** accessibility audits and conformance tests, but rather gives early feedback @@ -16615,10 +15416,6 @@ def get_by_test_id( await page.get_by_test_id(\"directions\").click() ``` - ```py - page.get_by_test_id(\"directions\").click() - ``` - **Details** By default, the `data-testid` attribute is used as a test id. Use `selectors.set_test_id_attribute()` to @@ -16677,23 +15474,6 @@ def get_by_text( page.get_by_text(re.compile(\"^hello$\", re.IGNORECASE)) ``` - ```py - # Matches - page.get_by_text(\"world\") - - # Matches first
- page.get_by_text(\"Hello world\") - - # Matches second
- page.get_by_text(\"Hello\", exact=True) - - # Matches both
s - page.get_by_text(re.compile(\"Hello\")) - - # Matches second
- page.get_by_text(re.compile(\"^hello$\", re.IGNORECASE)) - ``` - **Details** Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into @@ -16741,10 +15521,6 @@ def get_by_title( await expect(page.get_by_title(\"Issues count\")).to_have_text(\"25 issues\") ``` - ```py - expect(page.get_by_title(\"Issues count\")).to_have_text(\"25 issues\") - ``` - Parameters ---------- text : Union[Pattern[str], str] @@ -16773,11 +15549,6 @@ def frame_locator(self, selector: str) -> "FrameLocator": await locator.click() ``` - ```py - locator = page.frame_locator(\"iframe\").get_by_text(\"Submit\") - locator.click() - ``` - Parameters ---------- selector : str @@ -16834,10 +15605,6 @@ def nth(self, index: int) -> "Locator": banana = await page.get_by_role(\"listitem\").nth(2) ``` - ```py - banana = page.get_by_role(\"listitem\").nth(2) - ``` - Parameters ---------- index : int @@ -16873,14 +15640,6 @@ def filter( ``` - ```py - row_locator = page.locator(\"tr\") - # ... - row_locator.filter(has_text=\"text in column 1\").filter( - has=page.get_by_role(\"button\", name=\"column 2 button\") - ).screenshot() - ``` - Parameters ---------- has_text : Union[Pattern[str], str, None] @@ -16939,15 +15698,6 @@ def or_(self, locator: "Locator") -> "Locator": await new_email.click() ``` - ```py - new_email = page.get_by_role(\"button\", name=\"New\") - dialog = page.get_by_text(\"Confirm security settings\") - expect(new_email.or_(dialog)).to_be_visible() - if (dialog.is_visible()): - page.get_by_role(\"button\", name=\"Dismiss\").click() - new_email.click() - ``` - Parameters ---------- locator : Locator @@ -16973,10 +15723,6 @@ def and_(self, locator: "Locator") -> "Locator": button = page.get_by_role(\"button\").and_(page.getByTitle(\"Subscribe\")) ``` - ```py - button = page.get_by_role(\"button\").and_(page.getByTitle(\"Subscribe\")) - ``` - Parameters ---------- locator : Locator @@ -17035,11 +15781,6 @@ async def all(self) -> typing.List["Locator"]: await li.click(); ``` - ```py - for li in page.get_by_role('listitem').all(): - li.click(); - ``` - Returns ------- List[Locator] @@ -17061,10 +15802,6 @@ async def count(self) -> int: count = await page.get_by_role(\"listitem\").count() ``` - ```py - count = page.get_by_role(\"listitem\").count() - ``` - Returns ------- int @@ -17107,19 +15844,6 @@ async def drag_to( ) ``` - ```py - source = page.locator(\"#source\") - target = page.locator(\"#target\") - - source.drag_to(target) - # or specify exact positions relative to the top-left corners of the elements: - source.drag_to( - target, - source_position={\"x\": 34, \"y\": 7}, - target_position={\"x\": 10, \"y\": 20} - ) - ``` - Parameters ---------- target : Locator @@ -17205,10 +15929,6 @@ async def hover( await page.get_by_role(\"link\").hover() ``` - ```py - page.get_by_role(\"link\").hover() - ``` - **Details** This method hovers over the element by performing the following steps: @@ -17308,10 +16028,6 @@ async def input_value(self, *, timeout: typing.Optional[float] = None) -> str: value = await page.get_by_role(\"textbox\").input_value() ``` - ```py - value = page.get_by_role(\"textbox\").input_value() - ``` - **Details** Throws elements that are not an input, textarea or a select. However, if the element is inside the `
``` - ```py - feed_handle = await page.query_selector(\".feed\") - assert await feed_handle.eval_on_selector_all(\".tweet\", \"nodes => nodes.map(n => n.innerText)\") == [\"hello!\", \"hi!\"] - ``` - ```py feed_handle = page.query_selector(\".feed\") assert feed_handle.eval_on_selector_all(\".tweet\", \"nodes => nodes.map(n => n.innerText)\") == [\"hello!\", \"hi!\"] @@ -3090,13 +2930,6 @@ def wait_for_selector( **Usage** - ```py - await page.set_content(\"
\") - div = await page.query_selector(\"div\") - # waiting for the \"span\" selector relative to the div. - span = await div.wait_for_selector(\"span\", state=\"attached\") - ``` - ```py page.set_content(\"
\") div = page.query_selector(\"div\") @@ -3162,11 +2995,6 @@ def snapshot( An example of dumping the entire accessibility tree: - ```py - snapshot = await page.accessibility.snapshot() - print(snapshot) - ``` - ```py snapshot = page.accessibility.snapshot() print(snapshot) @@ -3174,22 +3002,6 @@ def snapshot( An example of logging the focused node's name: - ```py - def find_focused_node(node): - if node.get(\"focused\"): - return node - for child in (node.get(\"children\") or []): - found_node = find_focused_node(child) - if found_node: - return found_node - return None - - snapshot = await page.accessibility.snapshot() - node = find_focused_node(snapshot) - if node: - print(node[\"name\"]) - ``` - ```py def find_focused_node(node): if node.get(\"focused\"): @@ -3463,12 +3275,6 @@ def expect_navigation( This method waits for the frame to navigate to a new URL. It is useful for when you run code which will indirectly cause the frame to navigate. Consider this example: - ```py - async with frame.expect_navigation(): - await frame.click(\"a.delayed-navigation\") # clicking the link will indirectly cause a navigation - # Resolves after navigation has finished - ``` - ```py with frame.expect_navigation(): frame.click(\"a.delayed-navigation\") # clicking the link will indirectly cause a navigation @@ -3524,11 +3330,6 @@ def wait_for_url( **Usage** - ```py - await frame.click(\"a.delayed-navigation\") # clicking the link will indirectly cause a navigation - await frame.wait_for_url(\"**/target.html\") - ``` - ```py frame.click(\"a.delayed-navigation\") # clicking the link will indirectly cause a navigation frame.wait_for_url(\"**/target.html\") @@ -3581,11 +3382,6 @@ def wait_for_load_state( **Usage** - ```py - await frame.click(\"button\") # click triggers navigation. - await frame.wait_for_load_state() # the promise resolves after \"load\" event. - ``` - ```py frame.click(\"button\") # click triggers navigation. frame.wait_for_load_state() # the promise resolves after \"load\" event. @@ -3623,12 +3419,6 @@ def frame_element(self) -> "ElementHandle": **Usage** - ```py - frame_element = await frame.frame_element() - content_frame = await frame_element.content_frame() - assert frame == content_frame - ``` - ```py frame_element = frame.frame_element() content_frame = frame_element.content_frame() @@ -3658,11 +3448,6 @@ def evaluate( **Usage** - ```py - result = await frame.evaluate(\"([x, y]) => Promise.resolve(x * y)\", [7, 8]) - print(result) # prints \"56\" - ``` - ```py result = frame.evaluate(\"([x, y]) => Promise.resolve(x * y)\", [7, 8]) print(result) # prints \"56\" @@ -3670,12 +3455,6 @@ def evaluate( A string can also be passed in instead of a function. - ```py - print(await frame.evaluate(\"1 + 2\")) # prints \"3\" - x = 10 - print(await frame.evaluate(f\"1 + {x}\")) # prints \"11\" - ``` - ```py print(frame.evaluate(\"1 + 2\")) # prints \"3\" x = 10 @@ -3684,12 +3463,6 @@ def evaluate( `ElementHandle` instances can be passed as an argument to the `frame.evaluate()`: - ```py - body_handle = await frame.evaluate(\"document.body\") - html = await frame.evaluate(\"([body, suffix]) => body.innerHTML + suffix\", [body_handle, \"hello\"]) - await body_handle.dispose() - ``` - ```py body_handle = frame.evaluate(\"document.body\") html = frame.evaluate(\"([body, suffix]) => body.innerHTML + suffix\", [body_handle, \"hello\"]) @@ -3730,11 +3503,6 @@ def evaluate_handle( **Usage** - ```py - a_window_handle = await frame.evaluate_handle(\"Promise.resolve(window)\") - a_window_handle # handle for the window object. - ``` - ```py a_window_handle = frame.evaluate_handle(\"Promise.resolve(window)\") a_window_handle # handle for the window object. @@ -3742,23 +3510,12 @@ def evaluate_handle( A string can also be passed in instead of a function. - ```py - a_handle = await page.evaluate_handle(\"document\") # handle for the \"document\" - ``` - ```py a_handle = page.evaluate_handle(\"document\") # handle for the \"document\" ``` `JSHandle` instances can be passed as an argument to the `frame.evaluate_handle()`: - ```py - a_handle = await page.evaluate_handle(\"document.body\") - result_handle = await page.evaluate_handle(\"body => body.innerHTML\", a_handle) - print(await result_handle.json_value()) - await result_handle.dispose() - ``` - ```py a_handle = page.evaluate_handle(\"document.body\") result_handle = page.evaluate_handle(\"body => body.innerHTML\", a_handle) @@ -3866,26 +3623,6 @@ def wait_for_selector( This method works across navigations: - ```py - import asyncio - from playwright.async_api import async_playwright, Playwright - - async def run(playwright: Playwright): - chromium = playwright.chromium - browser = await chromium.launch() - page = await browser.new_page() - for current_url in [\"https://google.com\", \"https://bbc.com\"]: - await page.goto(current_url, wait_until=\"domcontentloaded\") - element = await page.main_frame.wait_for_selector(\"img\") - print(\"Loaded image: \" + str(await element.get_attribute(\"src\"))) - await browser.close() - - async def main(): - async with async_playwright() as playwright: - await run(playwright) - asyncio.run(main()) - ``` - ```py from playwright.sync_api import sync_playwright, Playwright @@ -4168,10 +3905,6 @@ def dispatch_event( **Usage** - ```py - await frame.dispatch_event(\"button#submit\", \"click\") - ``` - ```py frame.dispatch_event(\"button#submit\", \"click\") ``` @@ -4193,12 +3926,6 @@ def dispatch_event( 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 frame.evaluate_handle(\"new DataTransfer()\") - await frame.dispatch_event(\"#source\", \"dragstart\", { \"dataTransfer\": data_transfer }) - ``` - ```py # note you can only create data_transfer in chromium and firefox data_transfer = frame.evaluate_handle(\"new DataTransfer()\") @@ -4254,12 +3981,6 @@ def eval_on_selector( **Usage** - ```py - search_value = await frame.eval_on_selector(\"#search\", \"el => el.value\") - preload_href = await frame.eval_on_selector(\"link[rel=preload]\", \"el => el.href\") - html = await frame.eval_on_selector(\".main-container\", \"(e, suffix) => e.outerHTML + suffix\", \"hello\") - ``` - ```py search_value = frame.eval_on_selector(\"#search\", \"el => el.value\") preload_href = frame.eval_on_selector(\"link[rel=preload]\", \"el => el.href\") @@ -4310,10 +4031,6 @@ def eval_on_selector_all( **Usage** - ```py - divs_counts = await frame.eval_on_selector_all(\"div\", \"(divs, min) => divs.length >= min\", 10) - ``` - ```py divs_counts = frame.eval_on_selector_all(\"div\", \"(divs, min) => divs.length >= min\", 10) ``` @@ -4852,10 +4569,6 @@ def get_by_alt_text( Playwright logo ``` - ```py - await page.get_by_alt_text(\"Playwright logo\").click() - ``` - ```py page.get_by_alt_text(\"Playwright logo\").click() ``` @@ -4896,11 +4609,6 @@ def get_by_label( ``` - ```py - await page.get_by_label(\"Username\").fill(\"john\") - await page.get_by_label(\"Password\").fill(\"secret\") - ``` - ```py page.get_by_label(\"Username\").fill(\"john\") page.get_by_label(\"Password\").fill(\"secret\") @@ -4941,10 +4649,6 @@ def get_by_placeholder( You can fill the input after locating it by the placeholder text: - ```py - await page.get_by_placeholder(\"name@example.com\").fill(\"playwright@microsoft.com\") - ``` - ```py page.get_by_placeholder(\"name@example.com\").fill(\"playwright@microsoft.com\") ``` @@ -5084,14 +4788,6 @@ def get_by_role( You can locate each element by it's implicit role: - ```py - await expect(page.get_by_role(\"heading\", name=\"Sign up\")).to_be_visible() - - await page.get_by_role(\"checkbox\", name=\"Subscribe\").check() - - await page.get_by_role(\"button\", name=re.compile(\"submit\", re.IGNORECASE)).click() - ``` - ```py expect(page.get_by_role(\"heading\", name=\"Sign up\")).to_be_visible() @@ -5191,10 +4887,6 @@ def get_by_test_id( You can locate the element by it's test id: - ```py - await page.get_by_test_id(\"directions\").click() - ``` - ```py page.get_by_test_id(\"directions\").click() ``` @@ -5257,23 +4949,6 @@ def get_by_text( page.get_by_text(re.compile(\"^hello$\", re.IGNORECASE)) ``` - ```py - # Matches - page.get_by_text(\"world\") - - # Matches first
- page.get_by_text(\"Hello world\") - - # Matches second
- page.get_by_text(\"Hello\", exact=True) - - # Matches both
s - page.get_by_text(re.compile(\"Hello\")) - - # Matches second
- page.get_by_text(re.compile(\"^hello$\", re.IGNORECASE)) - ``` - **Details** Matching by text always normalizes whitespace, even with exact match. For example, it turns multiple spaces into @@ -5317,10 +4992,6 @@ def get_by_title( You can check the issues count after locating it by the title text: - ```py - await expect(page.get_by_title(\"Issues count\")).to_have_text(\"25 issues\") - ``` - ```py expect(page.get_by_title(\"Issues count\")).to_have_text(\"25 issues\") ``` @@ -5351,11 +5022,6 @@ def frame_locator(self, selector: str) -> "FrameLocator": Following snippet locates element with text \"Submit\" in the iframe with id `my-frame`, like `