api(dotnet): introduce RunAndWaitForAsync (#6660)

This commit is contained in:
Pavel Feldman 2021-05-19 15:49:44 -07:00 committed by GitHub
parent 202511d60a
commit 1f22673c29
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 90 additions and 91 deletions

View file

@ -1195,6 +1195,7 @@ Optional handler function used to register a routing with [`method: BrowserConte
## async method: BrowserContext.waitForEvent
* langs: csharp, js, python
- alias-python: expect_event
- alias-csharp: RunAndWaitForEventAsync
- returns: <[any]>
Waits for event to fire and passes its value into the predicate function. Returns when the predicate returns truthy
@ -1224,9 +1225,10 @@ page = event_info.value
```
```csharp
var waitForPageEvent = context.WaitForPageAsync();
await page.ClickAsync("button");
var page = await waitForPageEvent;
var page = await context.RunAndWaitForEventAsync(ContextEvent.Page, async () =>
{
await page.ClickAsync("button");
});
```
### param: BrowserContext.waitForEvent.event
@ -1244,7 +1246,7 @@ Event name, same one would pass into `browserContext.on(event)`.
Either a predicate that receives an event or an options object. Optional.
## async method: BrowserContext.waitForPage
* langs: csharp, java, python
* langs: java, python
- alias-python: expect_page
- returns: <[Page]>
@ -1259,3 +1261,21 @@ Will throw an error if the context closes before new [Page] is created.
Receives the [Page] object and resolves to truthy value when the waiting should resolve.
### option: BrowserContext.waitForPage.timeout = %%-wait-for-event-timeout-%%
## async method: BrowserContext.waitForEvent2
* langs: python, csharp
- alias-python: wait_for_event
- alias-csharp: WaitForEventAsync
- returns: <[any]>
:::note
In most cases, you should use [`method: BrowserContext.waitForEvent`].
:::
Waits for given `event` to fire. If predicate is provided, it passes
event's value into the `predicate` function and waits for `predicate(event)` to return a truthy value.
Will throw an error if the browser context is closed before the `event` is fired.
### param: BrowserContext.waitForEvent2.event = %%-wait-for-event-event-%%
### option: BrowserContext.waitForEvent2.predicate = %%-wait-for-event-predicate-%%
### option: BrowserContext.waitForEvent2.timeout = %%-wait-for-event-timeout-%%

View file

@ -2895,7 +2895,7 @@ Video object associated with this page.
- `height` <[int]> page height in pixels.
## async method: Page.waitForClose
* langs: csharp, java
* langs: java
- returns: <[Page]>
Performs action and waits for the Page to close.
@ -2903,7 +2903,7 @@ Performs action and waits for the Page to close.
### option: Page.waitForClose.timeout = %%-wait-for-event-timeout-%%
## async method: Page.waitForConsoleMessage
* langs: csharp, java, python
* langs: java, python
- alias-python: expect_console_message
- returns: <[ConsoleMessage]>
@ -2919,7 +2919,7 @@ Receives the [ConsoleMessage] object and resolves to truthy value when the waiti
### option: Page.waitForConsoleMessage.timeout = %%-wait-for-event-timeout-%%
## async method: Page.waitForDownload
* langs: csharp, java, python
* langs: java, python
- alias-python: expect_download
- returns: <[Download]>
@ -2937,6 +2937,7 @@ Receives the [Download] object and resolves to truthy value when the waiting sho
## async method: Page.waitForEvent
* langs: csharp, js, python
- alias-python: expect_event
- alias-csharp: RunAndWaitForEventAsync
- returns: <[any]>
Waits for event to fire and passes its value into the predicate function. Returns when the predicate returns truthy
@ -2979,7 +2980,7 @@ var frame = await waitTask;
Either a predicate that receives an event or an options object. Optional.
## async method: Page.waitForFileChooser
* langs: csharp, java, python
* langs: java, python
- alias-python: expect_file_chooser
- returns: <[FileChooser]>
@ -3263,7 +3264,7 @@ Shortcut for main frame's [`method: Frame.waitForNavigation`].
### option: Page.waitForNavigation.timeout = %%-navigation-timeout-%%
## async method: Page.waitForPopup
* langs: csharp, java, python
* langs: java, python
- alias-python: expect_popup
- returns: <[Page]>
@ -3655,7 +3656,7 @@ Shortcut for main frame's [`method: Frame.waitForURL`].
### option: Page.waitForURL.waitUntil = %%-navigation-wait-until-%%
## async method: Page.waitForWebSocket
* langs: csharp, java
* langs: java
- returns: <[WebSocket]>
Performs action and waits for a new [WebSocket]. If predicate is provided, it passes
@ -3670,7 +3671,7 @@ Receives the [WebSocket] object and resolves to truthy value when the waiting sh
### option: Page.waitForWebSocket.timeout = %%-wait-for-event-timeout-%%
## async method: Page.waitForWorker
* langs: csharp, java, python
* langs: java, python
- alias-python: expect_worker
- returns: <[Worker]>
@ -3694,3 +3695,21 @@ associated with the page.
:::note
This does not contain ServiceWorkers
:::
## async method: Page.waitForEvent2
* langs: python, csharp
- alias-python: wait_for_event
- alias-csharp: WaitForEventAsync
- returns: <[any]>
:::note
In most cases, you should use [`method: Page.waitForEvent`].
:::
Waits for given `event` to fire. If predicate is provided, it passes
event's value into the `predicate` function and waits for `predicate(event)` to return a truthy value.
Will throw an error if the page is closed before the `event` is fired.
### param: Page.waitForEvent2.event = %%-wait-for-event-event-%%
### option: Page.waitForEvent2.predicate = %%-wait-for-event-predicate-%%
### option: Page.waitForEvent2.timeout = %%-wait-for-event-timeout-%%

View file

@ -43,7 +43,7 @@ Indicates that the web socket has been closed.
Contains the URL of the WebSocket.
## async method: WebSocket.waitForEvent
* langs: csharp, js, python
* langs: js, python
- alias-python: expect_event
- returns: <[any]>
@ -64,7 +64,7 @@ Event name, same one would pass into `webSocket.on(event)`.
Either a predicate that receives an event or an options object. Optional.
## async method: WebSocket.waitForFrameReceived
* langs: csharp, java
* langs: java
- returns: <[WebSocketFrame]>
Performs action and waits for a frame to be sent. If predicate is provided, it passes
@ -79,7 +79,7 @@ Receives the [WebSocketFrame] object and resolves to truthy value when the waiti
### option: WebSocket.waitForFrameReceived.timeout = %%-wait-for-event-timeout-%%
## async method: WebSocket.waitForFrameSent
* langs: csharp, java
* langs: java
- returns: <[WebSocketFrame]>
Performs action and waits for a frame to be sent. If predicate is provided, it passes
@ -92,3 +92,21 @@ Will throw an error if the WebSocket or Page is closed before the frame is sent.
Receives the [WebSocketFrame] object and resolves to truthy value when the waiting should resolve.
### option: WebSocket.waitForFrameSent.timeout = %%-wait-for-event-timeout-%%
## async method: WebSocket.waitForEvent2
* langs: python
- alias-python: wait_for_event
- alias-csharp: WaitForEventAsync
- returns: <[any]>
:::note
In most cases, you should use [`method: WebSocket.waitForEvent`].
:::
Waits for given `event` to fire. If predicate is provided, it passes
event's value into the `predicate` function and waits for `predicate(event)` to return a truthy value.
Will throw an error if the socket is closed before the `event` is fired.
### param: WebSocket.waitForEvent2.event = %%-wait-for-event-event-%%
### option: WebSocket.waitForEvent2.predicate = %%-wait-for-event-predicate-%%
### option: WebSocket.waitForEvent2.timeout = %%-wait-for-event-timeout-%%

View file

@ -97,7 +97,7 @@ Optional argument to pass to [`param: expression`].
- returns: <[string]>
## async method: Worker.waitForClose
* langs: csharp, java
* langs: java
- returns: <[Worker]>
Performs action and waits for the Worker to close.

View file

@ -480,10 +480,17 @@ is considered matching if all specified properties match.
A glob pattern, regex pattern or predicate receiving [URL] to match while waiting for the navigation.
## wait-for-event-event
* langs: js, java, python
- `event` <[string]>
Event name, same one typically passed into `*.on(event)`.
## csharp-wait-for-event-event
* langs: csharp
- `playwrightEvent` <[PlaywrightEvent<T>]>
Event type, same one typically passed into `WaitForEventAsync`.
## wait-for-load-state-state
- `state` <[LoadState]<"load"|"domcontentloaded"|"networkidle">>
@ -530,8 +537,7 @@ only the first option matching one of the passed options is selected. Optional.
Options to select by label. If the `<select>` has the `multiple` attribute, all given options are selected, otherwise
only the first option matching one of the passed options is selected. Optional.
## python-wait-for-event-predicate
* langs: python
## wait-for-event-predicate
- `predicate` <[function]>
Receives the event data and resolves to truthy value when the waiting should resolve.

View file

@ -84,19 +84,19 @@ Raw script content.
## async method: Page.waitForEvent
* langs: python
- returns: <[EventContextManager]>
### option: Page.waitForEvent.predicate = %%-python-wait-for-event-predicate-%%
### option: Page.waitForEvent.predicate = %%-wait-for-event-predicate-%%
### option: Page.waitForEvent.timeout = %%-wait-for-event-timeout-%%
## async method: BrowserContext.waitForEvent
* langs: python
- returns: <[EventContextManager]>
### option: BrowserContext.waitForEvent.predicate = %%-python-wait-for-event-predicate-%%
### option: BrowserContext.waitForEvent.predicate = %%-wait-for-event-predicate-%%
### option: BrowserContext.waitForEvent.timeout = %%-wait-for-event-timeout-%%
## async method: WebSocket.waitForEvent
* langs: python
- returns: <[EventContextManager]>
### option: WebSocket.waitForEvent.predicate = %%-python-wait-for-event-predicate-%%
### option: WebSocket.waitForEvent.predicate = %%-wait-for-event-predicate-%%
### option: WebSocket.waitForEvent.timeout = %%-wait-for-event-timeout-%%
## async method: Page.waitForDownload
@ -138,54 +138,3 @@ Raw script content.
## async method: Page.waitForResponse
* langs: python
- returns: <[EventContextManager]<[Response]>>
## async method: BrowserContext.waitForEvent2
* langs: python
- alias-python: wait_for_event
- returns: <[Any]>
:::note
In most cases, you should use [`method: BrowserContext.waitForEvent`].
:::
Waits for given `event` to fire. If predicate is provided, it passes
event's value into the `predicate` function and waits for `predicate(event)` to return a truthy value.
Will throw an error if the socket is closed before the `event` is fired.
### param: BrowserContext.waitForEvent2.event = %%-wait-for-event-event-%%
### option: BrowserContext.waitForEvent2.predicate = %%-python-wait-for-event-predicate-%%
### option: BrowserContext.waitForEvent2.timeout = %%-wait-for-event-timeout-%%
## async method: Page.waitForEvent2
* langs: python
- alias-python: wait_for_event
- returns: <[Any]>
:::note
In most cases, you should use [`method: Page.waitForEvent`].
:::
Waits for given `event` to fire. If predicate is provided, it passes
event's value into the `predicate` function and waits for `predicate(event)` to return a truthy value.
Will throw an error if the socket is closed before the `event` is fired.
### param: Page.waitForEvent2.event = %%-wait-for-event-event-%%
### option: Page.waitForEvent2.predicate = %%-python-wait-for-event-predicate-%%
### option: Page.waitForEvent2.timeout = %%-wait-for-event-timeout-%%
## async method: WebSocket.waitForEvent2
* langs: python
- alias-python: wait_for_event
- returns: <[Any]>
:::note
In most cases, you should use [`method: WebSocket.waitForEvent`].
:::
Waits for given `event` to fire. If predicate is provided, it passes
event's value into the `predicate` function and waits for `predicate(event)` to return a truthy value.
Will throw an error if the socket is closed before the `event` is fired.
### param: WebSocket.waitForEvent2.event = %%-wait-for-event-event-%%
### option: WebSocket.waitForEvent2.predicate = %%-python-wait-for-event-predicate-%%
### option: WebSocket.waitForEvent2.timeout = %%-wait-for-event-timeout-%%

View file

@ -259,15 +259,6 @@ for (let [name, type] of optionTypes)
if (process.argv[3] !== "--skip-format") {
// run the formatting tool for .net, to ensure the files are prepped
execSync(`dotnet format -f "${typesDir}" --include-generated --fix-whitespace`);
if (process.platform !== 'win32') {
for (const folder of [typesDir, path.join(typesDir, 'Models'), path.join(typesDir, 'Enums'), path.join(typesDir, 'Extensions'), path.join(typesDir, 'Constants')])
for (const name of fs.readdirSync(folder)) {
if (!name.includes('\.cs'))
continue;
const content = fs.readFileSync(path.join(folder, name), 'utf-8');
fs.writeFileSync(path.join(folder, name), content.split('\r\n').join('\n'));
}
}
}
/**
@ -288,6 +279,8 @@ function toMemberName(member, options) {
const omitAsync = options && options.omitAsync;
if (!omitAsync && member.kind === 'method' && member.async && !assumedName.endsWith('Async'))
return `${assumedName}Async`;
if (omitAsync && assumedName.endsWith('Async'))
return assumedName.substring(0, assumedName.length - 'Async'.length);
return assumedName;
}
@ -456,6 +449,9 @@ function generateEnumNameIfApplicable(type) {
* @param {string[]} out
*/
function renderMethod(member, parent, name, options, out) {
// These are hard-coded in C#.
if (name.includes('WaitForEventAsync'))
return;
out.push('');
/**
@ -567,7 +563,7 @@ function renderMethod(member, parent, name, options, out) {
function processArg(arg) {
if (arg.name === 'options') {
if (options.mode === 'options' || options.mode === 'base') {
const optionsType = member.clazz.name + toTitleCase(member.name) + 'Options';
const optionsType = member.clazz.name + toMemberName(member, { omitAsync: true }) + 'Options';
optionTypes.set(optionsType, arg.type);
args.push(`${optionsType} options = default`);
argTypeMap.set(`${optionsType} options = default`, 'options');
@ -634,14 +630,7 @@ function renderMethod(member, parent, name, options, out) {
member.argsArray
.sort((a, b) => b.alias === 'options' ? -1 : 0) //move options to the back to the arguments list
.forEach(processArg);
const hasAction = name.includes('WaitFor') && !['WaitForTimeoutAsync', 'WaitForFunctionAsync', 'WaitForLoadStateAsync', 'WaitForURLAsync', 'WaitForSelectorAsync', 'WaitForElementStateAsync'].includes(name);
if (hasAction) {
args.push('Func<Task> action = default');
argTypeMap.set('Func<Task> action = default', 'action');
addParamsDoc('action', ['Action to perform while waiting']);
}
let body = ';';
if (options.mode === 'base') {
// Generate options -> named transition.
@ -651,8 +640,6 @@ function renderMethod(member, parent, name, options, out) {
tokens.push(toArgumentName(arg.name));
continue;
}
if (hasAction)
tokens.push('action');
for (const opt of arg.type.properties) {
// TODO: use translate type here?
if (opt.type.union && !opt.type.union[0].name.startsWith('"') && opt.type.union[0].name !== 'null' && opt.type.expression !== '[string]|[Buffer]') {