docs(dotnet): Page examples (#6556)

This commit is contained in:
Anže Vodovnik 2021-05-13 19:19:47 +02:00 committed by GitHub
parent ea59fd8f83
commit ddfbffa111
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -73,6 +73,23 @@ with sync_playwright() as playwright:
run(playwright) run(playwright)
``` ```
```csharp
using Microsoft.Playwright;
using System.Threading.Tasks;
class PageExamples
{
public static async Task Run()
{
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Webkit.LaunchAsync();
var page = await browser.NewPageAsync();
await page.GoToAsync("https://www.theverge.com");
await page.ScreenshotAsync("theverge.png");
}
}
```
The Page class emits various events (described below) which can be handled using any of Node's native The Page class emits various events (described below) which can be handled using any of Node's native
[`EventEmitter`](https://nodejs.org/api/events.html#events_class_eventemitter) methods, such as `on`, `once` or [`EventEmitter`](https://nodejs.org/api/events.html#events_class_eventemitter) methods, such as `on`, `once` or
`removeListener`. `removeListener`.
@ -91,6 +108,10 @@ page.onLoad(p -> System.out.println("Page loaded!"));
page.once("load", lambda: print("page loaded!")) page.once("load", lambda: print("page loaded!"))
``` ```
```csharp
page.Load += (_, _) => { Console.WriteLine("Page loaded!"); };
```
To unsubscribe from events use the `removeListener` method: To unsubscribe from events use the `removeListener` method:
```js ```js
@ -119,6 +140,16 @@ page.on("request", log_request)
page.remove_listener("request", log_request) page.remove_listener("request", log_request)
``` ```
```csharp
void PageLoadHandler(object _, IPage p) {
Console.WriteLine("Page loaded!");
};
page.Load += PageLoadHandler;
// Do some work...
page.Load -= PageLoadHandler;
```
## event: Page.close ## event: Page.close
- argument: <[Page]> - argument: <[Page]>
@ -170,6 +201,16 @@ page.on("console", print_args)
page.evaluate("console.log('hello', 5, {foo: 'bar'})") page.evaluate("console.log('hello', 5, {foo: 'bar'})")
``` ```
```csharp
page.Console += async (_, msg) =>
{
foreach (var arg in msg.Args)
Console.WriteLine(await arg.JsonValueAsync<object>());
};
await page.EvaluateAsync("console.log('hello', 5, { foo: 'bar' })");
```
## event: Page.crash ## event: Page.crash
- argument: <[Page]> - argument: <[Page]>
@ -220,6 +261,17 @@ except Error as e:
# when the page crashes, exception message contains "crash". # when the page crashes, exception message contains "crash".
``` ```
```csharp
try {
// Crash might happen during a click.
await page.ClickAsync("button");
// Or while waiting for an event.
await page.WaitForPopupAsync(() -> {});
} catch (PlaywrightException e) {
// When the page crashes, exception message contains "crash".
}
```
## event: Page.dialog ## event: Page.dialog
- argument: <[Dialog]> - argument: <[Dialog]>
@ -269,6 +321,13 @@ page.onFileChooser(fileChooser -> {
page.on("filechooser", lambda file_chooser: file_chooser.set_files("/tmp/myfile.pdf")) page.on("filechooser", lambda file_chooser: file_chooser.set_files("/tmp/myfile.pdf"))
``` ```
```csharp
page.FileChooser += (_, fileChooser) =>
{
fileChooser.SetFilesAsync(@"C:\temp\myfile.pdf");
};
```
## event: Page.frameAttached ## event: Page.frameAttached
- argument: <[Frame]> - argument: <[Frame]>
@ -337,6 +396,12 @@ popup = page_info.value
print(popup.evaluate("location.href")) print(popup.evaluate("location.href"))
``` ```
```csharp
var popupTask = page.WaitForPopupAsync();
await Task.WhenAll(popupTask, page.EvaluateAsync("() => window.open('https://microsoft.com')"));
Console.WriteLine(await popupTask.Result.EvaluateAsync<string>("location.href"));
```
:::note :::note
Use [`method: Page.waitForLoadState`] to wait until the page gets to a particular state (you should not need it in most Use [`method: Page.waitForLoadState`] to wait until the page gets to a particular state (you should not need it in most
cases). cases).
@ -422,6 +487,10 @@ await page.add_init_script(path="./preload.js")
page.add_init_script(path="./preload.js") page.add_init_script(path="./preload.js")
``` ```
```csharp
await page.AddInitScriptAsync(scriptPath: "./preload.js");
```
:::note :::note
The order of evaluation of multiple scripts installed via [`method: BrowserContext.addInitScript`] and The order of evaluation of multiple scripts installed via [`method: BrowserContext.addInitScript`] and
[`method: Page.addInitScript`] is not defined. [`method: Page.addInitScript`] is not defined.
@ -674,6 +743,10 @@ await page.dispatch_event("button#submit", "click")
page.dispatch_event("button#submit", "click") page.dispatch_event("button#submit", "click")
``` ```
```csharp
await page.DispatchEventAsync("button#submit", "click");
```
Under the hood, it creates an instance of an event based on the given [`param: type`], initializes it with Under the hood, it creates an instance of an event based on the given [`param: type`], initializes it with
[`param: eventInit`] properties and dispatches it on the element. Events are `composed`, `cancelable` and bubble by [`param: eventInit`] properties and dispatches it on the element. Events are `composed`, `cancelable` and bubble by
default. default.
@ -716,6 +789,11 @@ data_transfer = page.evaluate_handle("new DataTransfer()")
page.dispatch_event("#source", "dragstart", { "dataTransfer": data_transfer }) page.dispatch_event("#source", "dragstart", { "dataTransfer": data_transfer })
``` ```
```csharp
var dataTransfer = await page.EvaluateHandleAsync("() => new DataTransfer()");
await page.DispatchEventAsync("#source", "dragstart", new { dataTransfer });
```
### param: Page.dispatchEvent.selector = %%-input-selector-%% ### param: Page.dispatchEvent.selector = %%-input-selector-%%
### param: Page.dispatchEvent.type ### param: Page.dispatchEvent.type
@ -810,6 +888,25 @@ page.evaluate("matchMedia('print').matches")
# → False # → False
``` ```
```csharp
await page.EvaluateAsync("() => matchMedia('screen').matches");
// → true
await page.EvaluateAsync("() => matchMedia('print').matches");
// → false
await page.EmulateMediaAsync(Media.Print);
await page.EvaluateAsync("() => matchMedia('screen').matches");
// → false
await page.EvaluateAsync("() => matchMedia('print').matches");
// → true
await page.EmulateMediaAsync(Media.Screen);
await page.EvaluateAsync("() => matchMedia('screen').matches");
// → true
await page.EvaluateAsync("() => matchMedia('print').matches");
// → false
```
```js ```js
await page.emulateMedia({ colorScheme: 'dark' }); await page.emulateMedia({ colorScheme: 'dark' });
await page.evaluate(() => matchMedia('(prefers-color-scheme: dark)').matches); await page.evaluate(() => matchMedia('(prefers-color-scheme: dark)').matches);
@ -849,6 +946,16 @@ page.evaluate("matchMedia('(prefers-color-scheme: light)').matches")
page.evaluate("matchMedia('(prefers-color-scheme: no-preference)').matches") page.evaluate("matchMedia('(prefers-color-scheme: no-preference)').matches")
``` ```
```csharp
await page.EmulateMediaAsync(colorScheme: ColorScheme.Dark);
await page.EvaluateAsync("matchMedia('(prefers-color-scheme: dark)').matches");
// → true
await page.EvaluateAsync("matchMedia('(prefers-color-scheme: light)').matches");
// → false
await page.EvaluateAsync("matchMedia('(prefers-color-scheme: no-preference)').matches");
// → false
```
### option: Page.emulateMedia.media ### option: Page.emulateMedia.media
- `media` <null|[Media]<"screen"|"print">> - `media` <null|[Media]<"screen"|"print">>
@ -900,6 +1007,12 @@ 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") html = page.eval_on_selector(".main-container", "(e, suffix) => e.outer_html + suffix", "hello")
``` ```
```csharp
var searchValue = await page.EvalOnSelectorAsync<string>("#search", "el => el.value");
var preloadHref = await page.EvalOnSelectorAsync<string>("link[rel=preload]", "el => el.href");
var html = await page.EvalOnSelectorAsync(".main-container", "(e, suffix) => e.outerHTML + suffix", "hello");
```
Shortcut for main frame's [`method: Frame.evalOnSelector`]. Shortcut for main frame's [`method: Frame.evalOnSelector`].
### param: Page.evalOnSelector.selector = %%-query-selector-%% ### param: Page.evalOnSelector.selector = %%-query-selector-%%
@ -941,6 +1054,10 @@ div_counts = await page.eval_on_selector_all("div", "(divs, min) => divs.length
div_counts = page.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10) div_counts = page.eval_on_selector_all("div", "(divs, min) => divs.length >= min", 10)
``` ```
```csharp
var divsCount = await page.EvalOnSelectorAllAsync<bool>("div", "(divs, min) => divs.length >= min", 10);
```
### param: Page.evalOnSelectorAll.selector = %%-query-selector-%% ### param: Page.evalOnSelectorAll.selector = %%-query-selector-%%
### param: Page.evalOnSelectorAll.expression = %%-evaluate-expression-%% ### param: Page.evalOnSelectorAll.expression = %%-evaluate-expression-%%
@ -988,6 +1105,11 @@ result = page.evaluate("([x, y]) => Promise.resolve(x * y)", [7, 8])
print(result) # prints "56" print(result) # prints "56"
``` ```
```csharp
var result = await page.EvaluateAsync<int>("([x, y]) => Promise.resolve(x * y)", new[] { 7, 8 });
Console.WriteLine(result);
```
A string can also be passed in instead of a function: A string can also be passed in instead of a function:
```js ```js
@ -1012,6 +1134,10 @@ x = 10
print(page.evaluate(f"1 + {x}")) # prints "11" print(page.evaluate(f"1 + {x}")) # prints "11"
``` ```
```csharp
Console.WriteLine(await page.EvaluateAsync<int>("1 + 2")); // prints "3"
```
[ElementHandle] instances can be passed as an argument to the [`method: Page.evaluate`]: [ElementHandle] instances can be passed as an argument to the [`method: Page.evaluate`]:
```js ```js
@ -1038,6 +1164,12 @@ html = page.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle
body_handle.dispose() body_handle.dispose()
``` ```
```csharp
var bodyHandle = await page.QuerySelectorAsync("body");
var html = await page.EvaluateAsync<string>("([body, suffix]) => body.innerHTML + suffix", new object [] { bodyHandle, "hello" });
await bodyHandle.DisposeAsync();
```
Shortcut for main frame's [`method: Frame.evaluate`]. Shortcut for main frame's [`method: Frame.evaluate`].
### param: Page.evaluate.expression = %%-evaluate-expression-%% ### param: Page.evaluate.expression = %%-evaluate-expression-%%
@ -1077,6 +1209,11 @@ a_window_handle = page.evaluate_handle("Promise.resolve(window)")
a_window_handle # handle for the window object. a_window_handle # handle for the window object.
``` ```
```csharp
// Handle for the window object.
var aWindowHandle = await page.EvaluateHandleAsync("() => Promise.resolve(window)");
```
A string can also be passed in instead of a function: A string can also be passed in instead of a function:
```js ```js
@ -1095,6 +1232,10 @@ a_handle = await page.evaluate_handle("document") # handle for the "document"
a_handle = page.evaluate_handle("document") # handle for the "document" a_handle = page.evaluate_handle("document") # handle for the "document"
``` ```
```csharp
var docHandle = await page.EvalueHandleAsync("document"); // Handle for the `document`
```
[JSHandle] instances can be passed as an argument to the [`method: Page.evaluateHandle`]: [JSHandle] instances can be passed as an argument to the [`method: Page.evaluateHandle`]:
```js ```js
@ -1125,6 +1266,13 @@ print(result_handle.json_value())
result_handle.dispose() result_handle.dispose()
``` ```
```csharp
var handle = await page.EvaluateHandleAsync("() => document.body");
var resultHandle = await page.EvaluateHandleAsync("([body, suffix]) => body.innerHTML + suffix", new object[] { handle, "hello" });
Console.WriteLine(await resultHandle.JsonValueAsync<string>());
await resultHandle.DisposeAsync();
```
### param: Page.evaluateHandle.expression = %%-evaluate-expression-%% ### param: Page.evaluateHandle.expression = %%-evaluate-expression-%%
### param: Page.evaluateHandle.arg ### param: Page.evaluateHandle.arg
@ -1245,6 +1393,32 @@ with sync_playwright() as playwright:
run(playwright) run(playwright)
``` ```
```csharp
using Microsoft.Playwright;
using System.Threading.Tasks;
class PageExamples
{
public static async Task Main()
{
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Webkit.LaunchAsync(headless: false);
var page = await browser.NewPageAsync();
await page.ExposeBindingAsync("pageUrl", (source) => source.Page.Url);
await page.SetContentAsync("<script>\n" +
" async function onClick() {\n" +
" document.querySelector('div').textContent = await window.pageURL();\n" +
" }\n" +
"</script>\n" +
"<button onclick=\"onClick()\">Click me</button>\n" +
"<div></div>");
await page.ClickAsync("button");
}
}
```
An example of passing an element handle: An example of passing an element handle:
```js ```js
@ -1302,6 +1476,23 @@ page.set_content("""
""") """)
``` ```
```csharp
var result = new TaskCompletionSource<string>();
await page.ExposeBindingAsync("clicked", async (BindingSource _, IJSHandle t) =>
{
return result.TrySetResult(await t.AsElement.TextContentAsync());
});
await page.SetContentAsync("<script>\n" +
" document.addEventListener('click', event => window.clicked(event.target));\n" +
"</script>\n" +
"<div>Click me</div>\n" +
"<div>Or click me</div>\n");
await page.ClickAsync("div");
Console.WriteLine(await result.Task);
```
### param: Page.exposeBinding.name ### param: Page.exposeBinding.name
- `name` <[string]> - `name` <[string]>
@ -1455,6 +1646,42 @@ with sync_playwright() as playwright:
run(playwright) run(playwright)
``` ```
```csharp
using Microsoft.Playwright;
using System;
using System.Security.Cryptography;
using System.Threading.Tasks;
class PageExamples
{
public static async Task Main()
{
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Webkit.LaunchAsync(headless: false);
var page = await browser.NewPageAsync();
// NOTE: md5 is inherently insecure, and we strongly discourage using
// this in production in any shape or form
await page.ExposeFunctionAsync("sha1", (string input) =>
{
return Convert.ToBase64String(
MD5.Create().ComputeHash(System.Text.Encoding.UTF8.GetBytes(input)));
});
await page.SetContentAsync("<script>\n" +
" async function onClick() {\n" +
" document.querySelector('div').textContent = await window.sha1('PLAYWRIGHT');\n" +
" }\n" +
"</script>\n" +
"<button onclick=\"onClick()\">Click me</button>\n" +
"<div></div>");
await page.ClickAsync("button");
Console.WriteLine(await page.TextContentAsync("div"));
}
}
```
### param: Page.exposeFunction.name ### param: Page.exposeFunction.name
- `name` <[string]> - `name` <[string]>
@ -1514,6 +1741,10 @@ Frame frame = page.frame("frame-name");
frame = page.frame(name="frame-name") frame = page.frame(name="frame-name")
``` ```
```csharp
var frame = page.Frame("frame-name");
```
```js ```js
const frame = page.frame({ url: /.*domain.*/ }); const frame = page.frame({ url: /.*domain.*/ });
``` ```
@ -1526,6 +1757,10 @@ Frame frame = page.frameByUrl(Pattern.compile(".*domain.*");
frame = page.frame(url=r".*domain.*") frame = page.frame(url=r".*domain.*")
``` ```
```csharp
var frame = page.FrameByUrl(".*domain.*");
```
### param: Page.frame.frameSelector ### param: Page.frame.frameSelector
* langs: js * langs: js
- `frameSelector` <[string]|[Object]> - `frameSelector` <[string]|[Object]>
@ -1818,6 +2053,12 @@ page.emulate_media(media="screen")
page.pdf(path="page.pdf") page.pdf(path="page.pdf")
``` ```
```csharp
// Generates a PDF with 'screen' media type
await page.EmulateMediaAsync(Media.Screen);
await page.PdfAsync("page.pdf");
```
The [`option: width`], [`option: height`], and [`option: margin`] options accept values labeled with units. Unlabeled The [`option: width`], [`option: height`], and [`option: margin`] options accept values labeled with units. Unlabeled
values are treated as pixels. values are treated as pixels.
@ -2022,6 +2263,18 @@ page.screenshot(path="o.png")
browser.close() browser.close()
``` ```
```csharp
await using var browser = await playwright.Webkit.LaunchAsync(headless: false);
var page = await browser.NewPageAsync();
await page.GoToAsync("https://keycode.info");
await page.PressAsync("body", "A");
await page.ScreenshotAsync("A.png");
await page.PressAsync("body", "ArrowLeft");
await page.ScreenshotAsync("ArrowLeft.png");
await page.PressAsync("body", "Shift+O");
await page.ScreenshotAsync("O.png");
```
### param: Page.press.selector = %%-input-selector-%% ### param: Page.press.selector = %%-input-selector-%%
### param: Page.press.key ### param: Page.press.key
@ -2114,6 +2367,13 @@ page.goto("https://example.com")
browser.close() browser.close()
``` ```
```csharp
await using var browser = await playwright.Webkit.LaunchAsync();
var page = await browser.NewPageAsync();
await page.RouteAsync("**/*.{png,jpg,jpeg}", async r => await r.AbortAsync());
await page.GoToAsync("https://www.microsoft.com");
```
or the same snippet using a regex pattern instead: or the same snippet using a regex pattern instead:
```js ```js
@ -2144,6 +2404,13 @@ page.goto("https://example.com")
browser.close() browser.close()
``` ```
```csharp
await using var browser = await playwright.Webkit.LaunchAsync();
var page = await browser.NewPageAsync();
await page.RouteAsync(new Regex("(\\.png$)|(\\.jpg$)"), async r => await r.AbortAsync());
await page.GoToAsync("https://www.microsoft.com");
```
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: 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:
```js ```js
@ -2182,6 +2449,16 @@ def handle_route(route):
page.route("/api/**", handle_route) page.route("/api/**", handle_route)
``` ```
```csharp
await page.RouteAsync("/api/**", async r =>
{
if (r.Request.PostData.Contains("my-string"))
await r.FulfillAsync(body: "mocked-data");
else
await r.ResumeAsync();
});
```
Page routes take precedence over browser context routes (set up with [`method: BrowserContext.route`]) when request Page routes take precedence over browser context routes (set up with [`method: BrowserContext.route`]) when request
matches both handlers. matches both handlers.
@ -2300,6 +2577,15 @@ page.select_option("select#colors", label="blue")
page.select_option("select#colors", value=["red", "green", "blue"]) page.select_option("select#colors", value=["red", "green", "blue"])
``` ```
```csharp
// single selection matching the value
await page.SelectOptionAsync("select#colors", new[] { "blue" });
// single selection matching both the value and the label
await page.SelectOptionAsync("select#colors", new[] { new SelectOptionValue() { Label = "blue" } });
// multiple
await page.SelectOptionAsync("select#colors", new[] { "red", "green", "blue" });
```
Shortcut for main frame's [`method: Frame.selectOption`]. Shortcut for main frame's [`method: Frame.selectOption`].
### param: Page.selectOption.selector = %%-input-selector-%% ### param: Page.selectOption.selector = %%-input-selector-%%
@ -2419,6 +2705,12 @@ page.set_viewport_size({"width": 640, "height": 480})
page.goto("https://example.com") page.goto("https://example.com")
``` ```
```csharp
var page = await browser.NewPageAsync();
await page.SetViewportSizeAsync(640, 480);
await page.GoToAsync("https://www.microsoft.com");
```
### param: Page.setViewportSize.viewportSize ### param: Page.setViewportSize.viewportSize
* langs: js, python * langs: js, python
- `viewportSize` <[Object]> - `viewportSize` <[Object]>
@ -2513,6 +2805,11 @@ page.type("#mytextarea", "hello") # types instantly
page.type("#mytextarea", "world", delay=100) # types slower, like a user page.type("#mytextarea", "world", delay=100) # types slower, like a user
``` ```
```csharp
await page.TypeAsync("#mytextarea", "hello"); // types instantly
await page.TypeAsync("#mytextarea", "world"); // types slower, like a user
```
Shortcut for main frame's [`method: Frame.type`]. Shortcut for main frame's [`method: Frame.type`].
### param: Page.type.selector = %%-input-selector-%% ### param: Page.type.selector = %%-input-selector-%%
@ -2666,6 +2963,12 @@ with page.expect_event("framenavigated") as event_info:
frame = event_info.value frame = event_info.value
``` ```
```csharp
var waitTask = page.WaitForEventAsync(PageEvent.FrameNavigated);
await Task.WhenAll(waitTask, page.ClickAsync("button"));
var frame = waitTask.Result;
```
### param: Page.waitForEvent.event = %%-wait-for-event-event-%% ### param: Page.waitForEvent.event = %%-wait-for-event-event-%%
### param: Page.waitForEvent.optionsOrPredicate ### param: Page.waitForEvent.optionsOrPredicate
@ -2763,6 +3066,23 @@ with sync_playwright() as playwright:
run(playwright) run(playwright)
``` ```
```csharp
using Microsoft.Playwright;
using System.Threading.Tasks;
class FrameExamples
{
public static async Task WaitForFunction()
{
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Webkit.LaunchAsync();
var page = await browser.NewPageAsync();
await page.SetViewportSizeAsync(50, 50);
await page.MainFrame.WaitForFunctionAsync("window.innerWidth < 100");
}
}
```
To pass an argument to the predicate of [`method: Page.waitForFunction`] function: To pass an argument to the predicate of [`method: Page.waitForFunction`] function:
```js ```js
@ -2785,6 +3105,11 @@ selector = ".foo"
page.wait_for_function("selector => !!document.querySelector(selector)", selector) page.wait_for_function("selector => !!document.querySelector(selector)", selector)
``` ```
```csharp
var selector = ".foo";
await page.WaitForFunctionAsync("selector => !!document.querySelector(selector)", selector);
```
Shortcut for main frame's [`method: Frame.waitForFunction`]. Shortcut for main frame's [`method: Frame.waitForFunction`].
### param: Page.waitForFunction.expression = %%-evaluate-expression-%% ### param: Page.waitForFunction.expression = %%-evaluate-expression-%%
@ -2827,6 +3152,11 @@ page.click("button") # click triggers navigation.
page.wait_for_load_state() # the promise resolves after "load" event. page.wait_for_load_state() # the promise resolves after "load" event.
``` ```
```csharp
await page.ClickAsync("button"); // Click triggers navigation.
await page.WaitForLoadStateAsync(); // The promise resolves after 'load' event.
```
```js ```js
const [popup] = await Promise.all([ const [popup] = await Promise.all([
page.waitForEvent('popup'), page.waitForEvent('popup'),
@ -2862,6 +3192,13 @@ popup.wait_for_load_state("domcontentloaded")
print(popup.title()) # popup is ready to use. print(popup.title()) # popup is ready to use.
``` ```
```csharp
var popupTask = page.WaitForPopupAsync();
await Task.WhenAll(popupTask, page.ClickAsync("button")); // click triggers the popup/
await popupTask.Result.WaitForLoadStateAsync(LoadState.DOMContentLoaded);
Console.WriteLine(await popupTask.Result.TitleAsync()); // popup is ready to use.
```
Shortcut for main frame's [`method: Frame.waitForLoadState`]. Shortcut for main frame's [`method: Frame.waitForLoadState`].
### param: Page.waitForLoadState.state = %%-wait-for-load-state-state-%% ### param: Page.waitForLoadState.state = %%-wait-for-load-state-state-%%
@ -2907,6 +3244,12 @@ with page.expect_navigation():
# Resolves after navigation has finished # Resolves after navigation has finished
``` ```
```csharp
await Task.WhenAll(page.WaitForNavigationAsync(),
frame.ClickAsync("a.delayed-navigation")); // clicking the link will indirectly cause a navigation
// The method continues after navigation has finished
```
:::note :::note
Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is considered Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is considered
a navigation. a navigation.
@ -2998,6 +3341,16 @@ with page.expect_request(lambda request: request.url == "http://example.com" and
second_request = second.value second_request = second.value
``` ```
```csharp
// Waits for the next response with the specified url
await Task.WhenAll(page.WaitForRequestAsync("https://example.com/resource"),
page.ClickAsync("button.triggers-request"));
// Waits for the next request matching some conditions
await Task.WhenAll(page.WaitForRequestAsync(r => "https://example.com".Equals(r.Url) && "GET" == r.Method),
page.ClickAsync("button.triggers-request"));
```
```js ```js
await page.waitForRequest(request => request.url().searchParams.get('foo') === 'bar' && request.url().searchParams.get('foo2') === 'bar2'); await page.waitForRequest(request => request.url().searchParams.get('foo') === 'bar' && request.url().searchParams.get('foo2') === 'bar2');
``` ```
@ -3085,6 +3438,16 @@ response = response_info.value
return response.ok return response.ok
``` ```
```csharp
// Waits for the next response with the specified url
await Task.WhenAll(page.WaitForResponseAsync("https://example.com/resource"),
page.ClickAsync("button.triggers-response"));
// Waits for the next response matching some conditions
await Task.WhenAll(page.WaitForResponseAsync(r => "https://example.com".Equals(r.Url) && r.Status == 200),
page.ClickAsync("button.triggers-response"));
```
### param: Page.waitForResponse.urlOrPredicate ### param: Page.waitForResponse.urlOrPredicate
- `urlOrPredicate` <[string]|[RegExp]|[function]\([Response]\):[boolean]> - `urlOrPredicate` <[string]|[RegExp]|[function]\([Response]\):[boolean]>
@ -3187,6 +3550,31 @@ with sync_playwright() as playwright:
run(playwright) run(playwright)
``` ```
```csharp
using Microsoft.Playwright;
using System;
using System.Threading.Tasks;
class FrameExamples
{
public static async Task Images()
{
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchAsync();
var page = await browser.NewPageAsync();
foreach (var currentUrl in new[] { "https://www.google.com", "https://bbc.com" })
{
await page.GoToAsync(currentUrl);
var element = await page.WaitForSelectorAsync("img");
Console.WriteLine($"Loaded image: {await element.GetAttributeAsync("src")}");
}
await browser.CloseAsync();
}
}
```
### param: Page.waitForSelector.selector = %%-query-selector-%% ### param: Page.waitForSelector.selector = %%-query-selector-%%
### option: Page.waitForSelector.state = %%-wait-for-selector-state-%% ### option: Page.waitForSelector.state = %%-wait-for-selector-state-%%
@ -3220,6 +3608,11 @@ await page.wait_for_timeout(1000)
page.wait_for_timeout(1000) page.wait_for_timeout(1000)
``` ```
```csharp
// Wait for 1 second
await page.WaitForTimeoutAsync(1000);
```
Shortcut for main frame's [`method: Frame.waitForTimeout`]. Shortcut for main frame's [`method: Frame.waitForTimeout`].
### param: Page.waitForTimeout.timeout ### param: Page.waitForTimeout.timeout
@ -3251,6 +3644,11 @@ page.click("a.delayed-navigation") # clicking the link will indirectly cause a n
page.wait_for_url("**/target.html") page.wait_for_url("**/target.html")
``` ```
```csharp
await page.ClickAsync("a.delayed-navigation"); // clicking the link will indirectly cause a navigation
await page.WaitForURLAsync("**/target.html");
```
Shortcut for main frame's [`method: Frame.waitForURL`]. Shortcut for main frame's [`method: Frame.waitForURL`].
### param: Page.waitForURL.url = %%-wait-for-navigation-url-%% ### param: Page.waitForURL.url = %%-wait-for-navigation-url-%%