docs(dotnet): examples for input, intro, languages, multi-pages (#6596)

This commit is contained in:
Pavel Feldman 2021-05-15 10:56:10 -07:00 committed by GitHub
parent ffa83f1f17
commit bbc3ebd512
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 240 additions and 35 deletions

View file

@ -77,6 +77,23 @@ page.fill('#local', '2020-03-02T05:15')
page.fill('text=First Name', 'Peter') page.fill('text=First Name', 'Peter')
``` ```
```csharp
// Text input
await page.FillAsync("#name", "Peter");
// Date input
await page.FillAsync("#date", "2020-02-02");
// Time input
await page.FillAsync("#time", "13-15");
// Local datetime input
await page.FillAsync("#local", "2020-03-02T05:15");
// Input through label
await page.FillAsync("text=First Name", "Peter");
```
### API reference ### API reference
- [`method: Page.fill`] - [`method: Page.fill`]
@ -145,6 +162,20 @@ page.uncheck('#subscribe-label')
page.check('text=XL') page.check('text=XL')
``` ```
```csharp
// Check the checkbox
await page.CheckAsync("#agree");
// Assert the checked state
Assert.True(await page.IsCheckedAsync("#agree"));
// Uncheck by input <label>.
await page.UncheckAsync("#subscribe-label");
// Select the radio button
await page.CheckAsync("text=XL");
```
### API reference ### API reference
- [`method: Page.check`] - [`method: Page.check`]
@ -221,6 +252,21 @@ option = page.query_selector('#best-option')
page.select_option('select#colors', option) page.select_option('select#colors', option)
``` ```
```csharp
// Single selection matching the value
await page.SelectOptionAsync("select#colors", "blue");
// Single selection matching the label
await page.SelectOptionAsync("select#colors", new SelectOptionValue { Label = "blue" }));
// Multiple selected items
await page.SelectOptionAsync("select#colors", new[] { "blue", "green", "red" });
// Select the option via element handle
var option = await page.QuerySelectorAsync("#best-option");
await page.SelectOptionAsync("select#colors", option);
```
### API reference ### API reference
- [`method: Page.selectOption`] - [`method: Page.selectOption`]
@ -313,6 +359,26 @@ page.hover('#item')
page.click('#item', position={ 'x': 0, 'y': 0}) page.click('#item', position={ 'x': 0, 'y': 0})
``` ```
```csharp
// Generic click
await page.ClickAsync("button#submit");
// Double click
await page.DblClickAsync("#item");
// Right click
await page.ClickAsync("#item", button: MouseButton.Right);
// Shift + click
await page.ClickAsync("#item", modifiers: new[] { KeyboardModifier.Shift });
// Hover over element
await page.HoverAsync("#item");
// Click the top left corner
await page.ClickAsync("#item", position: new Position { X = 0, Y = 0 });
```
Under the hood, this and other pointer-related methods: Under the hood, this and other pointer-related methods:
- wait for element with given selector to be in DOM - wait for element with given selector to be in DOM
@ -342,6 +408,10 @@ await page.click('button#submit', force=True)
page.click('button#submit', force=True) page.click('button#submit', force=True)
``` ```
```csharp
await page.ClickAsync("button#submit", force: true);
```
#### Programmatic click #### Programmatic click
If you are not interested in testing your app under the real conditions and want to simulate the click by any means possible, you can trigger the [`HTMLElement.click()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click) behavior via simply dispatching a click event on the element: If you are not interested in testing your app under the real conditions and want to simulate the click by any means possible, you can trigger the [`HTMLElement.click()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click) behavior via simply dispatching a click event on the element:
@ -362,6 +432,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");
```
### API reference ### API reference
- [`method: Page.click`] - [`method: Page.click`]
@ -403,6 +477,11 @@ await page.type('#area', 'Hello World!')
page.type('#area', 'Hello World!') page.type('#area', 'Hello World!')
``` ```
```csharp
// Type character by character
await page.TypeAsync("#area", "Hello World!");
```
This method will emit all the necessary keyboard events, with all the `keydown`, `keyup`, `keypress` events in place. You can even specify the optional `delay` between the key presses to simulate real user behavior. This method will emit all the necessary keyboard events, with all the `keydown`, `keyup`, `keypress` events in place. You can even specify the optional `delay` between the key presses to simulate real user behavior.
:::note :::note
@ -464,6 +543,17 @@ page.press('#name', 'Control+ArrowRight')
page.press('#value', '$') page.press('#value', '$')
``` ```
```csharp
// Hit Enter
await page.PressAsync("#submit", "Enter");
// Dispatch Control+Right
await page.PressAsync("#name", "Control+ArrowRight");
// Press $ sign on keyboard
await page.PressAsync("#value", "$");
```
This method focuses the selected element and produces a single keystroke. It accepts the logical key names that are emitted in the [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) property of the keyboard events: This method focuses the selected element and produces a single keystroke. It accepts the logical key names that are emitted in the [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) property of the keyboard events:
``` ```
@ -511,6 +601,14 @@ page.press('#name', 'Shift+A')
page.press('#name', 'Shift+ArrowLeft') page.press('#name', 'Shift+ArrowLeft')
``` ```
```csharp
// <input id=name>
await page.PressAsync("#name", "Shift+A");
// <input id=name>
await page.PressAsync("#name", "Shift+ArrowLeft");
```
Shortcuts such as `"Control+o"` or `"Control+Shift+T"` are supported as well. When specified with the modifier, modifier is pressed and being held while the subsequent key is being pressed. Shortcuts such as `"Control+o"` or `"Control+Shift+T"` are supported as well. When specified with the modifier, modifier is pressed and being held while the subsequent key is being pressed.
Note that you still need to specify the capital `A` in `Shift-A` to produce the capital character. `Shift-a` produces a lower-case one as if you had the `CapsLock` toggled. Note that you still need to specify the capital `A` in `Shift-A` to produce the capital character. `Shift-a` produces a lower-case one as if you had the `CapsLock` toggled.
@ -600,6 +698,25 @@ page.set_input_files(
) )
``` ```
```csharp
// Select one file
await page.SetInputFilesAsync("input#upload", "myfile.pdf");
// Select multiple files
await page.SetInputFilesAsync("input#upload", new[] { "file1.txt", "file12.txt" });
// Remove all the selected files
await page.SetInputFilesAsync("input#upload", new[] {});
// Upload buffer from memory
await page.SetInputFilesAsync("input#upload", new FilePayload
{
Name = "file.txt",
MimeType = "text/plain",
Buffer = "this is a test".getBytes(StandardCharsets.UTF_8),
});
```
If you don't have input element in hand (it is created dynamically), you can handle the [`event: Page.fileChooser`] event If you don't have input element in hand (it is created dynamically), you can handle the [`event: Page.fileChooser`] event
or use a corresponding waiting method upon your action: or use a corresponding waiting method upon your action:
@ -632,6 +749,14 @@ file_chooser = fc_info.value
file_chooser.set_files("myfile.pdf") file_chooser.set_files("myfile.pdf")
``` ```
```csharp
var fileChooser = await Task.WhenAll(
page.WaitForFileChooserAsync(),
page.ClickAsync("upload")
);
await fileChooser.SetFilesAsync("myfile.pdf");
```
### API reference ### API reference
- [FileChooser] - [FileChooser]
- [`method: Page.setInputFiles`] - [`method: Page.setInputFiles`]
@ -660,6 +785,10 @@ await page.focus('input#name')
page.focus('input#name') page.focus('input#name')
``` ```
```csharp
await page.FocusAsync("input#name");
```
### API reference ### API reference
- [`method: Page.focus`] - [`method: Page.focus`]

View file

@ -8,20 +8,27 @@ title: "Getting Started"
## Installation ## Installation
Install PlaywrightSharp package from NuGet in Visual Studio or from the CLI in your project root directory: Install Microsoft.Playwright package from NuGet in Visual Studio or from the CLI in your project root directory:
```sh ```sh
dotnet add package PlaywrightSharp dotnet add package Microsoft.Playwright
``` ```
## Usage ## Usage
```csharp ```csharp
using var playwright = await Playwright.CreateAsync(); using Microsoft.Playwright;
await using var browser = await playwright.Chromium.LaunchAsync(); using System.Threading.Tasks;
var page = await browser.NewPageAsync();
await page.GotoAsync("http://www.bing.com"); class Example
await page.ScreenshotAsync(path: outputFile); {
public static async Task Main()
{
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchAsync();
// Create pages, interact with UI elements, assert values
}
}
``` ```
## First script ## First script
@ -29,13 +36,26 @@ await page.ScreenshotAsync(path: outputFile);
In our first script, we will navigate to `whatsmyuseragent.org` and take a screenshot in WebKit. In our first script, we will navigate to `whatsmyuseragent.org` and take a screenshot in WebKit.
```csharp ```csharp
// FIXME: using Microsoft.Playwright;
using System.Threading.Tasks;
class Example
{
public static async Task Main()
{
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchAsync();
var page = await browser.NewPageAsync();
await page.GotoAsync("whatsmyuseragent.org");
await page.ScreenshotAsync(path: "screenshot.png");
}
}
``` ```
By default, Playwright runs the browsers in headless mode. To see the browser UI, pass the `headless=False` flag while launching the browser. You can also use [`option: slowMo`] to slow down execution. Learn more in the debugging tools [section](./debug.md). By default, Playwright runs the browsers in headless mode. To see the browser UI, pass the `headless: false` flag while launching the browser. You can also use [`option: slowMo`] to slow down execution. Learn more in the debugging tools [section](./debug.md).
```csharp ```csharp
// FIXME: await playwright.Firefox.LaunchAsync(headless: false, slowMo: 50);
``` ```
## Record scripts ## Record scripts

View file

@ -36,11 +36,13 @@ The Playwright API is available in multiple languages.
## C# ## C#
Playwright for C# is available in preview. [Playwright for .NET](https://playwright.dev/dotnet/docs/intro/) is available.
``` * [Documentation](https://playwright.dev/dotnet/docs/intro/)
dotnet add package PlaywrightSharp * [API](https://playwright.dev/dotnet/docs/api/class-playwright)
```
* [Playwright on NuGet](https://www.nuget.org/packages/PlaywrightSharp/)
* [GitHub repo](https://github.com/microsoft/playwright-sharp) * [GitHub repo](https://github.com/microsoft/playwright-sharp)
* [Playwright on NuGet](https://www.nuget.org/packages/Microsoft.Playwright)
```
dotnet add package Microsoft.Playwright
```

View file

@ -23,13 +23,10 @@ const browser = await chromium.launch();
const userContext = await browser.newContext(); const userContext = await browser.newContext();
const adminContext = await browser.newContext(); const adminContext = await browser.newContext();
// Load user and admin cookies // Create pages and interact with contexts independently
await userContext.addCookies(userCookies);
await adminContext.addCookies(adminCookies);
``` ```
```java ```java
// FIXME
import com.microsoft.playwright.*; import com.microsoft.playwright.*;
public class Example { public class Example {
@ -41,9 +38,7 @@ public class Example {
// Create two isolated browser contexts // Create two isolated browser contexts
BrowserContext userContext = browser.newContext(); BrowserContext userContext = browser.newContext();
BrowserContext adminContext = browser.newContext(); BrowserContext adminContext = browser.newContext();
// Load user and admin cookies // Create pages and interact with contexts independently
userContext.addCookies(userCookies);
adminContext.addCookies(adminCookies);
} }
} }
} }
@ -62,9 +57,7 @@ async def run(playwright):
user_context = await browser.new_context() user_context = await browser.new_context()
admin_context = await browser.new_context() admin_context = await browser.new_context()
# load user and admin cookies # create pages and interact with contexts independently
await user_context.add_cookies(user_cookies)
await admin_context.add_cookies(admin_cookies)
async def main(): async def main():
async with async_playwright() as playwright: async with async_playwright() as playwright:
@ -84,14 +77,30 @@ def run(playwright):
user_context = browser.new_context() user_context = browser.new_context()
admin_context = browser.new_context() admin_context = browser.new_context()
# load user and admin cookies # create pages and interact with contexts independently
user_context.add_cookies(user_cookies)
admin_context.add_cookies(admin_cookies)
with sync_playwright() as playwright: with sync_playwright() as playwright:
run(playwright) run(playwright)
``` ```
```csharp
using Microsoft.Playwright;
using System.Threading.Tasks;
class Example
{
public static async Task Main()
{
using var playwright = await Playwright.CreateAsync();
// Create a Chromium browser instance
await using var browser = await playwright.Chromium.LaunchAsync();
await using var userContext = await browser.NewContextAsync();
await using var adminContext = await browser.NewContextAsync();
// Create pages and interact with contexts independently.
}
}
```
### API reference ### API reference
- [BrowserContext] - [BrowserContext]
- [`method: Browser.newContext`] - [`method: Browser.newContext`]
@ -140,6 +149,15 @@ page_two = context.new_page()
all_pages = context.pages() all_pages = context.pages()
``` ```
```csharp
// Create two pages
var pageOne = await context.NewPageAsync();
var pageTwo = await context.NewPageAsync();
// Get pages of a brower context
var allPages = context.Pages;
```
### API reference ### API reference
- [Page] - [Page]
- [`method: BrowserContext.newPage`] - [`method: BrowserContext.newPage`]
@ -189,6 +207,16 @@ new_page.wait_for_load_state()
print(new_page.title()) print(new_page.title())
``` ```
```csharp
// Get page after a specific action (e.g. clicking a link)
var newPage = await Task.WhenAll(
context.WaitForPageAsync(),
page.ClickAsync("a[target='_blank']")
);
await newPage.WaitForLoadStateAsync();
Console.WriteLine(await newPage.TitleAsync());
```
If the action that triggers the new page is unknown, the following pattern can be used. If the action that triggers the new page is unknown, the following pattern can be used.
```js ```js
@ -225,6 +253,14 @@ def handle_page(page):
context.on("page", handle_page) context.on("page", handle_page)
``` ```
```csharp
// Get all new pages (including popups) in the context
context.Page += async (_, page) => {
await page.WaitForLoadStateAsync();
Console.WriteLine(await page.TitleAsync());
};
```
### API reference ### API reference
- [`event: BrowserContext.page`] - [`event: BrowserContext.page`]
@ -273,6 +309,16 @@ popup.wait_for_load_state()
print(popup.title()) print(popup.title())
``` ```
```csharp
// Get popup after a specific action (e.g., click)
var newPage = await Task.WhenAll(
page.WaitForPopupAsync(),
page.ClickAsync("#open")
);
await newPage.WaitForLoadStateAsync();
Console.WriteLine(await newPage.TitleAsync());
```
If the action that triggers the popup is unknown, the following pattern can be used. If the action that triggers the popup is unknown, the following pattern can be used.
```js ```js
@ -309,5 +355,13 @@ def handle_popup(popup):
page.on("popup", handle_popup) page.on("popup", handle_popup)
``` ```
```csharp
// Get all popups when they open
page.Popup += async (_, popup) => {
await popup.WaitForLoadStateAsync();
Console.WriteLine(await page.TitleAsync());
};
```
### API reference ### API reference
- [`event: Page.popup`] - [`event: Page.popup`]

View file

@ -344,7 +344,7 @@ with page.expect_navigation():
```csharp ```csharp
// Using waitForNavigation with a callback prevents a race condition // Using waitForNavigation with a callback prevents a race condition
// between clicking and waiting for a navigation. // between clicking and waiting for a navigation.
await TaskUtils.WhenAll( await Task.WhenAll(
page.WaitForNavigationAsync(), // Waits for the next navigation page.WaitForNavigationAsync(), // Waits for the next navigation
page.ClickAsync("div.delayed-navigation"); // Triggers a navigation after a timeout page.ClickAsync("div.delayed-navigation"); // Triggers a navigation after a timeout
); );
@ -393,7 +393,7 @@ with page.expect_navigation(url="**/login"):
```csharp ```csharp
// Running action in the callback of waitForNavigation prevents a race // Running action in the callback of waitForNavigation prevents a race
// condition between clicking and waiting for a navigation. // condition between clicking and waiting for a navigation.
await TaskUtils.WhenAll( await Task.WhenAll(
page.WaitForNavigationAsync("**/login"), // Waits for the next navigation page.WaitForNavigationAsync("**/login"), // Waits for the next navigation
page.ClickAsync("a") // Triggers a navigation with a script redirect page.ClickAsync("a") // Triggers a navigation with a script redirect
); );
@ -434,7 +434,7 @@ popup.wait_for_load_state("load")
``` ```
```csharp ```csharp
var popup = await TaskUtils.WhenAll( var popup = await Task.WhenAll(
page.WaitForPopupAsync(), page.WaitForPopupAsync(),
page.ClickAsync("a[target='_blank']") // Opens popup page.ClickAsync("a[target='_blank']") // Opens popup
); );

View file

@ -281,7 +281,7 @@ response = response_info.value
```csharp ```csharp
// Use a glob URL pattern // Use a glob URL pattern
var response = await TaskUtils.WhenAll( var response = await Task.WhenAll(
page.WaitForResponseAsync("**/api/fetch_data"), page.WaitForResponseAsync("**/api/fetch_data"),
page.ClickAsync("button#update") page.ClickAsync("button#update")
); );
@ -341,13 +341,13 @@ response = response_info.value
```csharp ```csharp
// Use a regular expression // Use a regular expression
var response = await TaskUtils.WhenAll( var response = await Task.WhenAll(
page.WaitForResponseAsync(new Regex("\\.jpeg$")), page.WaitForResponseAsync(new Regex("\\.jpeg$")),
page.ClickAsync("button#update") page.ClickAsync("button#update")
); );
// Use a predicate taking a Response object // Use a predicate taking a Response object
var response = await TaskUtils.WhenAll( var response = await Task.WhenAll(
page.WaitForResponseAsync(r => r.Url.Contains(token)), page.WaitForResponseAsync(r => r.Url.Contains(token)),
page.ClickAsync("button#update") page.ClickAsync("button#update")
); );