From fd1e62b8c559d5015d1b4e70b4b5ed1227134bb2 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Sat, 15 May 2021 14:02:07 -0700 Subject: [PATCH] docs(dotnet): examples for dialogs, fixes (#6599) --- docs/src/api/class-browsercontext.md | 19 ++++++++++--------- docs/src/api/class-download.md | 7 ++++--- docs/src/api/class-filechooser.md | 7 ++++--- docs/src/api/class-frame.md | 6 ++++-- docs/src/api/class-page.md | 18 ++++++++++-------- docs/src/api/class-request.md | 7 ++++--- docs/src/dialogs.md | 19 +++++++++++++++++++ docs/src/events.md | 17 +++++------------ docs/src/handles.md | 12 ++++++------ docs/src/input.md | 8 +++----- docs/src/multi-pages.md | 15 ++++++--------- docs/src/navigations.md | 8 +++----- docs/src/network.md | 21 ++++++--------------- docs/src/verification.md | 15 ++++++--------- 14 files changed, 90 insertions(+), 89 deletions(-) diff --git a/docs/src/api/class-browsercontext.md b/docs/src/api/class-browsercontext.md index 64bad34d2c..71bf315577 100644 --- a/docs/src/api/class-browsercontext.md +++ b/docs/src/api/class-browsercontext.md @@ -25,7 +25,7 @@ BrowserContext context = browser.newContext(); // Create a new page inside context. Page page = context.newPage(); page.navigate("https://example.com"); -// Dispose context once it"s no longer needed. +// Dispose context once it is no longer needed. context.close(); ``` @@ -35,7 +35,7 @@ context = await browser.new_context() # create a new page inside context. page = await context.new_page() await page.goto("https://example.com") -# dispose context once it"s no longer needed. +# dispose context once it is no longer needed. await context.close() ``` @@ -45,7 +45,7 @@ context = browser.new_context() # create a new page inside context. page = context.new_page() page.goto("https://example.com") -# dispose context once it"s no longer needed. +# dispose context once it is no longer needed. context.close() ``` @@ -57,7 +57,7 @@ var context = await browser.NewContextAsync(); // Create a new page inside context. var page = await context.NewPageAsync(); await page.GotoAsync("https://bing.com"); -// Dispose context once it"s no longer needed. +// Dispose context once it is no longer needed. await context.CloseAsync(); ``` @@ -133,9 +133,9 @@ print(page.evaluate("location.href")) ```csharp var popupTask = context.WaitForPageAsync(); -await Task.WhenAll(popupTask, page.ClickAsync("a")); - -Console.WriteLine(popupTask.Result.EvaluateAsync("location.href")); +await page.ClickAsync("a"); +var popup = await popupTask; +Console.WriteLine(await popup.EvaluateAsync("location.href")); ``` :::note @@ -1226,8 +1226,9 @@ page = event_info.value ``` ```csharp -var t = page.WaitForEventAsync("page"); -await Task.WhenAll(t, page.ClickAsync("button")); +var waitForPageEvent = context.WaitForPageAsync(); +await page.ClickAsync("button"); +var page = await waitForPageEvent; ``` ### param: BrowserContext.waitForEvent.event diff --git a/docs/src/api/class-download.md b/docs/src/api/class-download.md index d92c26663e..0be2061f22 100644 --- a/docs/src/api/class-download.md +++ b/docs/src/api/class-download.md @@ -49,9 +49,10 @@ path = download.path() ``` ```csharp -var downloadTask = page.WaitForDownloadAsync(); -await Task.WhenAll(downloadTask, page.ClickAsync("#downloadButton")); -Console.WriteLine(await downloadTask.Result.PathAsync()); +var waitForDownloadTask = page.WaitForDownloadAsync(); +await page.ClickAsync("#downloadButton"); +var download = await waitForDownloadTask; +Console.WriteLine(await download.PathAsync()); ``` :::note diff --git a/docs/src/api/class-filechooser.md b/docs/src/api/class-filechooser.md index c571c856c0..571655b816 100644 --- a/docs/src/api/class-filechooser.md +++ b/docs/src/api/class-filechooser.md @@ -30,9 +30,10 @@ file_chooser.set_files("myfile.pdf") ``` ```csharp -var fileChooserTask = page.WaitForFileChooserAsync(); -await Task.WhenAll(fileChooserTask, page.ClickAsync("upload")); -await fileChooserTask.Result.SetFilesAsync("temp.txt"); +var waitForFileChooserTask = page.WaitForFileChooserAsync(); +await page.ClickAsync("upload"); +var fileChooser = await waitForFileChooserTask; +await fileChooser.SetFilesAsync("temp.txt"); ``` ## method: FileChooser.element diff --git a/docs/src/api/class-frame.md b/docs/src/api/class-frame.md index 958ba79040..4e3c860f67 100644 --- a/docs/src/api/class-frame.md +++ b/docs/src/api/class-frame.md @@ -1424,8 +1424,10 @@ with frame.expect_navigation(): ``` ```csharp -Task.WaitAll(frame.WaitForNavigationAsync(), - frame.ClickAsync("a.delayed-navigation")); // clicking the link will indirectly cause a navigation +await Task.WhenAll( + frame.WaitForNavigationAsync(), + // clicking the link will indirectly cause a navigation + frame.ClickAsync("a.delayed-navigation")); // Resolves after navigation has finished ``` diff --git a/docs/src/api/class-page.md b/docs/src/api/class-page.md index 308ffbc1c2..8af8ed65ca 100644 --- a/docs/src/api/class-page.md +++ b/docs/src/api/class-page.md @@ -397,9 +397,10 @@ 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("location.href")); +var waitForPopupTask = page.WaitForPopupAsync(); +await page.EvaluateAsync("() => window.open('https://microsoft.com')"); +var popup = await waitForPopupTask; +Console.WriteLine(await popup.EvaluateAsync("location.href")); ``` :::note @@ -2965,8 +2966,8 @@ frame = event_info.value ```csharp var waitTask = page.WaitForEventAsync(PageEvent.FrameNavigated); -await Task.WhenAll(waitTask, page.ClickAsync("button")); -var frame = waitTask.Result; +await page.ClickAsync("button"); +var frame = await waitTask; ``` ### param: Page.waitForEvent.event = %%-wait-for-event-event-%% @@ -3194,9 +3195,10 @@ 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. +await page.ClickAsync("button"); // click triggers the popup/ +var popup = await popupTask; +await popup.WaitForLoadStateAsync(LoadState.DOMContentLoaded); +Console.WriteLine(await popup.TitleAsync()); // popup is ready to use. ``` Shortcut for main frame's [`method: Frame.waitForLoadState`]. diff --git a/docs/src/api/class-request.md b/docs/src/api/class-request.md index be29a5a69e..ebf6a475e2 100644 --- a/docs/src/api/class-request.md +++ b/docs/src/api/class-request.md @@ -239,9 +239,10 @@ print(request.timing) ``` ```csharp -var requestFinishedTask = page.WaitForEventAsync(PageEvent.RequestFinished); -await Task.WhenAll(requestFinishedTask, page.GotoAsync("https://www.microsoft.com")); -Console.WriteLine(requestFinishedTask.Result.Timing.ResponseEnd); +var waitForEventTask = page.WaitForEventAsync(PageEvent.RequestFinished); +await page.GotoAsync("https://www.microsoft.com"); +var request = await waitForEventTask; +Console.WriteLine(request.Timing.ResponseEnd); ``` ## method: Request.url diff --git a/docs/src/dialogs.md b/docs/src/dialogs.md index baa6823d9b..cc5e88e427 100644 --- a/docs/src/dialogs.md +++ b/docs/src/dialogs.md @@ -31,6 +31,11 @@ page.on("dialog", lambda dialog: dialog.accept()) page.click("button") ``` +```csharp +page.Dialog += (_, dialog) => dialog.AcceptAsync(); +await page.ClickAsync("button"); +``` + :::note [`event: Page.dialog`] listener **must handle** the dialog. Otherwise your action will stall, be it [`method: Page.click`], [`method: Page.evaluate`] or any other. That's because dialogs in Web are modal and block further page execution until they are handled. ::: @@ -61,6 +66,11 @@ page.on("dialog", lambda dialog: print(dialog.message)) page.click("button") # Will hang here ``` +```csharp +page.Dialog += (_, dialog) => Console.WriteLine(dialog.Message); +await page.ClickAsync("button"); // Will hang here +``` + :::note If there is no listener for [`event: Page.dialog`], all dialogs are automatically dismissed. ::: @@ -110,3 +120,12 @@ def handle_dialog(dialog): page.on('dialog', lambda: handle_dialog) page.close(run_before_unload=True) ``` + +```csharp +page.Dialog += (_, dialog) => +{ + Assert.Equal("beforeunload", dialog.Type); + dialog.DismissAsync(); +}; +await page.CloseAsync(runBeforeUnload: true); +``` diff --git a/docs/src/events.md b/docs/src/events.md index cce12fb37f..550af74806 100644 --- a/docs/src/events.md +++ b/docs/src/events.md @@ -50,8 +50,6 @@ print(first.value.url) ``` ```csharp -// The callback lambda defines scope of the code that is expected to -// trigger request. var waitForRequestTask = page.WaitForRequestAsync("**/*logo*.png"); await page.GotoAsync("https://wikipedia.org"); var request = await waitForRequestTask; @@ -94,8 +92,6 @@ popup.value.goto("https://wikipedia.org") ``` ```csharp -// The callback lambda defines scope of the code that is expected to -// create popup window. var waitForPopupTask = page.WaitForPopupAsync(); await page.EvaluateAsync("window.open()"); var popup = await waitForPopupTask; @@ -160,18 +156,20 @@ page.goto("https://www.openstreetmap.org/") ```csharp page.Request += (_, request) => Console.WriteLine("Request sent: " + request.Url); -EventHandler listener = (_, request) => { - Console.WriteLine("Request finished: " + request.Url); +void listener(object sender, IRequest request) +{ + Console.WriteLine("Request finished: " + request.Url); }; page.RequestFinished += listener; await page.GotoAsync("https://wikipedia.org"); -// Remove previously added listener, each on* method has corresponding off* +// Remove previously added listener. page.RequestFinished -= listener; await page.GotoAsync("https://www.openstreetmap.org/"); ``` ## Adding one-off listeners +* langs: js, python, java If certain event needs to be handled once, there is a convenience API for that: @@ -195,11 +193,6 @@ page.once("dialog", lambda dialog: dialog.accept("2021")) page.evaluate("prompt('Enter a number:')") ``` -```csharp -page.Dialog += (_, dialog) => dialog.AcceptAsync("2021"); -await page.EvaluateAsync("prompt('Enter a number:')"); -``` - ### API reference - [Browser] diff --git a/docs/src/handles.md b/docs/src/handles.md index d72a6c67a0..faef662f16 100644 --- a/docs/src/handles.md +++ b/docs/src/handles.md @@ -193,7 +193,7 @@ arg.put("myArray", myArrayHandle); arg.put("newElement", 2); page.evaluate("arg => arg.myArray.add(arg.newElement)", arg); -// Release the object when it"s no longer needed. +// Release the object when it is no longer needed. myArrayHandle.dispose(); ``` @@ -239,10 +239,10 @@ my_array_handle.dispose() ```csharp // Create new array in page. -var myArrayHandle = await page.EvaluateHandleAsync("() => {\n" + - " window.myArray = [1];\n" + - " return myArray;\n" + - "}"); +var myArrayHandle = await page.EvaluateHandleAsync(@"() => { + window.myArray = [1]; + return myArray; +}"); // Get the length of the array. var length = await page.EvaluateAsync("a => a.length", myArrayHandle); @@ -251,7 +251,7 @@ var length = await page.EvaluateAsync("a => a.length", myArrayHandle); await page.EvaluateAsync("arg => arg.myArray.add(arg.newElement)", new { myArray = myArrayHandle, newElement = 2 }); -// Release the object when it"s no longer needed. +// Release the object when it is no longer needed. await myArrayHandle.DisposeAsync(); ``` diff --git a/docs/src/input.md b/docs/src/input.md index 2f94f579a4..f8ee546116 100644 --- a/docs/src/input.md +++ b/docs/src/input.md @@ -751,11 +751,9 @@ file_chooser.set_files("myfile.pdf") ```csharp var waitForChooserTask = page.WaitForFileChooserAsync(); -await Task.WhenAll( - waitForChooserTask, - page.ClickAsync("upload") -); -await waitForChooserTask.Result.SetFilesAsync("myfile.pdf"); +await page.ClickAsync("upload"); +var fileChooser = await waitForChooserTask; +await fileChooser.SetFilesAsync("myfile.pdf"); ``` ### API reference diff --git a/docs/src/multi-pages.md b/docs/src/multi-pages.md index c45d1acaea..c6b6dfb52e 100644 --- a/docs/src/multi-pages.md +++ b/docs/src/multi-pages.md @@ -210,11 +210,9 @@ print(new_page.title()) ```csharp // Get page after a specific action (e.g. clicking a link) var waitForPageTask = context.WaitForPageAsync(); -await Task.WhenAll( - waitForPageTask, - page.ClickAsync("a[target='_blank']") -); -await waitForPageTask.Result.WaitForLoadStateAsync(); +await page.ClickAsync("a[target='_blank']"); +var newPage = await waitForPageTask; +await page.WaitForLoadStateAsync(); Console.WriteLine(await newPage.TitleAsync()); ``` @@ -312,10 +310,9 @@ print(popup.title()) ```csharp // Get popup after a specific action (e.g., click) -var newPage = await Task.WhenAll( - page.WaitForPopupAsync(), - page.ClickAsync("#open") -); +var waitForPopupTask = page.WaitForPopupAsync(); +await page.ClickAsync("#open"); +var newPage = await waitForPopupTask; await newPage.WaitForLoadStateAsync(); Console.WriteLine(await newPage.TitleAsync()); ``` diff --git a/docs/src/navigations.md b/docs/src/navigations.md index 4428c645f9..85746e51d2 100644 --- a/docs/src/navigations.md +++ b/docs/src/navigations.md @@ -435,11 +435,9 @@ popup.wait_for_load_state("load") ```csharp var waitForPopupTask = page.WaitForPopupAsync(); -await Task.WhenAll( - waitForPopupTask, - page.ClickAsync("a[target='_blank']") // Opens popup -); -await waitForPopupTask.Result.WaitForLoadStateAsync(LoadState.Load); +await page.ClickAsync("a[target='_blank']"); // Opens popup +var popup = await waitForPopupTask; +popup.WaitForLoadStateAsync(LoadState.Load); ``` ### API reference diff --git a/docs/src/network.md b/docs/src/network.md index 95296f7702..c6d4e9a544 100644 --- a/docs/src/network.md +++ b/docs/src/network.md @@ -282,11 +282,8 @@ response = response_info.value ```csharp // Use a glob URL pattern var waitForResponseTask = page.WaitForResponseAsync("**/api/fetch_data"); -await Task.WhenAll( - waitForResponseTask, - page.ClickAsync("button#update") -); -var response = waitForResponseTask.Result; +await page.ClickAsync("button#update"); +var response = await waitForResponseTask; ``` #### Variations @@ -344,19 +341,13 @@ response = response_info.value ```csharp // Use a regular expression var waitForResponseTask = page.WaitForResponseAsync(new Regex("\\.jpeg$")); -await Task.WhenAll( - waitForResponseTask, - page.ClickAsync("button#update") -); -var response = waitForResponseTask.Result; +await page.ClickAsync("button#update"); +var response = await waitForResponseTask; // Use a predicate taking a Response object var waitForResponseTask = page.WaitForResponseAsync(r => r.Url.Contains(token)); -await Task.WhenAll( - waitForResponseTask, - page.ClickAsync("button#update") -); -var response = waitForResponseTask.Result; +await page.ClickAsync("button#update"); +var response = await waitForResponseTask; ``` ### API reference diff --git a/docs/src/verification.md b/docs/src/verification.md index d1625497d2..3b09fb711b 100644 --- a/docs/src/verification.md +++ b/docs/src/verification.md @@ -103,14 +103,11 @@ page.Console += (_, msg) => // Get the next System.out.println var waitForMessageTask = page.WaitForConsoleMessageAsync(); -await Task.WhenAll( - waitForMessageTask, - page.EvaluateAsync("console.log('hello', 42, { foo: 'bar' });") -); - +await page.EvaluateAsync("console.log('hello', 42, { foo: 'bar' });"); +var message = await waitForMessageTask; // Deconstruct console.log arguments -await waitForMessageTask.Result.Args.ElementAt(0).JsonValueAsync(); // hello -await waitForMessageTask.Result.Args.ElementAt(1).JsonValueAsync(); // 42 +await message.Args.ElementAt(0).JsonValueAsync(); // hello +await message.Args.ElementAt(1).JsonValueAsync(); // 42 ``` ### API reference @@ -248,8 +245,8 @@ popup = popup_info.value ```csharp var waitForPopupTask = page.WaitForPopupAsync(); -await Task.WhenAll(waitForPopupTask, page.ClickAsync("#open")); -var popup = waitForPopupTask.Result; +await page.ClickAsync("#open"); +var popup = await waitForPopupTask; ``` ### API reference