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)
```
```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
[`EventEmitter`](https://nodejs.org/api/events.html#events_class_eventemitter) methods, such as `on`, `once` or
`removeListener`.
@ -91,6 +108,10 @@ page.onLoad(p -> System.out.println("Page loaded!"));
page.once("load", lambda: print("page loaded!"))
```
```csharp
page.Load += (_, _) => { Console.WriteLine("Page loaded!"); };
```
To unsubscribe from events use the `removeListener` method:
```js
@ -119,6 +140,16 @@ page.on("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
- argument: <[Page]>
@ -170,6 +201,16 @@ page.on("console", print_args)
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
- argument: <[Page]>
@ -220,6 +261,17 @@ except Error as e:
# 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
- argument: <[Dialog]>
@ -269,6 +321,13 @@ page.onFileChooser(fileChooser -> {
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
- argument: <[Frame]>
@ -337,6 +396,12 @@ popup = page_info.value
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
Use [`method: Page.waitForLoadState`] to wait until the page gets to a particular state (you should not need it in most
cases).
@ -422,6 +487,10 @@ await page.add_init_script(path="./preload.js")
page.add_init_script(path="./preload.js")
```
```csharp
await page.AddInitScriptAsync(scriptPath: "./preload.js");
```
:::note
The order of evaluation of multiple scripts installed via [`method: BrowserContext.addInitScript`] and
[`method: Page.addInitScript`] is not defined.
@ -674,6 +743,10 @@ await 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
[`param: eventInit`] properties and dispatches it on the element. Events are `composed`, `cancelable` and bubble by
default.
@ -716,6 +789,11 @@ data_transfer = page.evaluate_handle("new DataTransfer()")
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.type
@ -810,6 +888,25 @@ page.evaluate("matchMedia('print').matches")
# → 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
await page.emulateMedia({ colorScheme: 'dark' });
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")
```
```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
- `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")
```
```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`].
### 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)
```
```csharp
var divsCount = await page.EvalOnSelectorAllAsync<bool>("div", "(divs, min) => divs.length >= min", 10);
```
### param: Page.evalOnSelectorAll.selector = %%-query-selector-%%
### 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"
```
```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:
```js
@ -1012,6 +1134,10 @@ x = 10
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`]:
```js
@ -1038,6 +1164,12 @@ html = page.evaluate("([body, suffix]) => body.innerHTML + suffix", [body_handle
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`].
### 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.
```
```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:
```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"
```
```csharp
var docHandle = await page.EvalueHandleAsync("document"); // Handle for the `document`
```
[JSHandle] instances can be passed as an argument to the [`method: Page.evaluateHandle`]:
```js
@ -1125,6 +1266,13 @@ print(result_handle.json_value())
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.arg
@ -1245,6 +1393,32 @@ with sync_playwright() as 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:
```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
- `name` <[string]>
@ -1455,6 +1646,42 @@ with sync_playwright() as 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
- `name` <[string]>
@ -1514,6 +1741,10 @@ Frame frame = page.frame("frame-name");
frame = page.frame(name="frame-name")
```
```csharp
var frame = page.Frame("frame-name");
```
```js
const frame = page.frame({ url: /.*domain.*/ });
```
@ -1526,6 +1757,10 @@ Frame frame = page.frameByUrl(Pattern.compile(".*domain.*");
frame = page.frame(url=r".*domain.*")
```
```csharp
var frame = page.FrameByUrl(".*domain.*");
```
### param: Page.frame.frameSelector
* langs: js
- `frameSelector` <[string]|[Object]>
@ -1818,6 +2053,12 @@ page.emulate_media(media="screen")
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
values are treated as pixels.
@ -2022,6 +2263,18 @@ page.screenshot(path="o.png")
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.key
@ -2114,6 +2367,13 @@ page.goto("https://example.com")
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:
```js
@ -2144,6 +2404,13 @@ page.goto("https://example.com")
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:
```js
@ -2182,6 +2449,16 @@ def handle_route(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
matches both handlers.
@ -2300,6 +2577,15 @@ page.select_option("select#colors", label="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`].
### param: Page.selectOption.selector = %%-input-selector-%%
@ -2419,6 +2705,12 @@ page.set_viewport_size({"width": 640, "height": 480})
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
* langs: js, python
- `viewportSize` <[Object]>
@ -2513,6 +2805,11 @@ page.type("#mytextarea", "hello") # types instantly
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`].
### param: Page.type.selector = %%-input-selector-%%
@ -2666,6 +2963,12 @@ with page.expect_event("framenavigated") as event_info:
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.optionsOrPredicate
@ -2763,6 +3066,23 @@ with sync_playwright() as 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:
```js
@ -2785,6 +3105,11 @@ selector = ".foo"
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`].
### 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.
```
```csharp
await page.ClickAsync("button"); // Click triggers navigation.
await page.WaitForLoadStateAsync(); // The promise resolves after 'load' event.
```
```js
const [popup] = await Promise.all([
page.waitForEvent('popup'),
@ -2862,6 +3192,13 @@ popup.wait_for_load_state("domcontentloaded")
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`].
### param: Page.waitForLoadState.state = %%-wait-for-load-state-state-%%
@ -2907,6 +3244,12 @@ with page.expect_navigation():
# 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
Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is considered
a navigation.
@ -2998,6 +3341,16 @@ with page.expect_request(lambda request: request.url == "http://example.com" and
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
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
```
```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
- `urlOrPredicate` <[string]|[RegExp]|[function]\([Response]\):[boolean]>
@ -3187,6 +3550,31 @@ with sync_playwright() as 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-%%
### option: Page.waitForSelector.state = %%-wait-for-selector-state-%%
@ -3220,6 +3608,11 @@ await 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`].
### 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")
```
```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`].
### param: Page.waitForURL.url = %%-wait-for-navigation-url-%%