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 ## async method: BrowserContext.waitForEvent
* langs: csharp, js, python * langs: csharp, js, python
- alias-python: expect_event - alias-python: expect_event
- alias-csharp: RunAndWaitForEventAsync
- returns: <[any]> - returns: <[any]>
Waits for event to fire and passes its value into the predicate function. Returns when the predicate returns truthy 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 ```csharp
var waitForPageEvent = context.WaitForPageAsync(); var page = await context.RunAndWaitForEventAsync(ContextEvent.Page, async () =>
await page.ClickAsync("button"); {
var page = await waitForPageEvent; await page.ClickAsync("button");
});
``` ```
### param: BrowserContext.waitForEvent.event ### 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. Either a predicate that receives an event or an options object. Optional.
## async method: BrowserContext.waitForPage ## async method: BrowserContext.waitForPage
* langs: csharp, java, python * langs: java, python
- alias-python: expect_page - alias-python: expect_page
- returns: <[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. Receives the [Page] object and resolves to truthy value when the waiting should resolve.
### option: BrowserContext.waitForPage.timeout = %%-wait-for-event-timeout-%% ### 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. - `height` <[int]> page height in pixels.
## async method: Page.waitForClose ## async method: Page.waitForClose
* langs: csharp, java * langs: java
- returns: <[Page]> - returns: <[Page]>
Performs action and waits for the Page to close. 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-%% ### option: Page.waitForClose.timeout = %%-wait-for-event-timeout-%%
## async method: Page.waitForConsoleMessage ## async method: Page.waitForConsoleMessage
* langs: csharp, java, python * langs: java, python
- alias-python: expect_console_message - alias-python: expect_console_message
- returns: <[ConsoleMessage]> - 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-%% ### option: Page.waitForConsoleMessage.timeout = %%-wait-for-event-timeout-%%
## async method: Page.waitForDownload ## async method: Page.waitForDownload
* langs: csharp, java, python * langs: java, python
- alias-python: expect_download - alias-python: expect_download
- returns: <[Download]> - returns: <[Download]>
@ -2937,6 +2937,7 @@ Receives the [Download] object and resolves to truthy value when the waiting sho
## async method: Page.waitForEvent ## async method: Page.waitForEvent
* langs: csharp, js, python * langs: csharp, js, python
- alias-python: expect_event - alias-python: expect_event
- alias-csharp: RunAndWaitForEventAsync
- returns: <[any]> - returns: <[any]>
Waits for event to fire and passes its value into the predicate function. Returns when the predicate returns truthy 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. Either a predicate that receives an event or an options object. Optional.
## async method: Page.waitForFileChooser ## async method: Page.waitForFileChooser
* langs: csharp, java, python * langs: java, python
- alias-python: expect_file_chooser - alias-python: expect_file_chooser
- returns: <[FileChooser]> - returns: <[FileChooser]>
@ -3263,7 +3264,7 @@ Shortcut for main frame's [`method: Frame.waitForNavigation`].
### option: Page.waitForNavigation.timeout = %%-navigation-timeout-%% ### option: Page.waitForNavigation.timeout = %%-navigation-timeout-%%
## async method: Page.waitForPopup ## async method: Page.waitForPopup
* langs: csharp, java, python * langs: java, python
- alias-python: expect_popup - alias-python: expect_popup
- returns: <[Page]> - returns: <[Page]>
@ -3655,7 +3656,7 @@ Shortcut for main frame's [`method: Frame.waitForURL`].
### option: Page.waitForURL.waitUntil = %%-navigation-wait-until-%% ### option: Page.waitForURL.waitUntil = %%-navigation-wait-until-%%
## async method: Page.waitForWebSocket ## async method: Page.waitForWebSocket
* langs: csharp, java * langs: java
- returns: <[WebSocket]> - returns: <[WebSocket]>
Performs action and waits for a new [WebSocket]. If predicate is provided, it passes 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-%% ### option: Page.waitForWebSocket.timeout = %%-wait-for-event-timeout-%%
## async method: Page.waitForWorker ## async method: Page.waitForWorker
* langs: csharp, java, python * langs: java, python
- alias-python: expect_worker - alias-python: expect_worker
- returns: <[Worker]> - returns: <[Worker]>
@ -3694,3 +3695,21 @@ associated with the page.
:::note :::note
This does not contain ServiceWorkers 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. Contains the URL of the WebSocket.
## async method: WebSocket.waitForEvent ## async method: WebSocket.waitForEvent
* langs: csharp, js, python * langs: js, python
- alias-python: expect_event - alias-python: expect_event
- returns: <[any]> - 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. Either a predicate that receives an event or an options object. Optional.
## async method: WebSocket.waitForFrameReceived ## async method: WebSocket.waitForFrameReceived
* langs: csharp, java * langs: java
- returns: <[WebSocketFrame]> - returns: <[WebSocketFrame]>
Performs action and waits for a frame to be sent. If predicate is provided, it passes 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-%% ### option: WebSocket.waitForFrameReceived.timeout = %%-wait-for-event-timeout-%%
## async method: WebSocket.waitForFrameSent ## async method: WebSocket.waitForFrameSent
* langs: csharp, java * langs: java
- returns: <[WebSocketFrame]> - returns: <[WebSocketFrame]>
Performs action and waits for a frame to be sent. If predicate is provided, it passes 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. Receives the [WebSocketFrame] object and resolves to truthy value when the waiting should resolve.
### option: WebSocket.waitForFrameSent.timeout = %%-wait-for-event-timeout-%% ### 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]> - returns: <[string]>
## async method: Worker.waitForClose ## async method: Worker.waitForClose
* langs: csharp, java * langs: java
- returns: <[Worker]> - returns: <[Worker]>
Performs action and waits for the Worker to close. 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. A glob pattern, regex pattern or predicate receiving [URL] to match while waiting for the navigation.
## wait-for-event-event ## wait-for-event-event
* langs: js, java, python
- `event` <[string]> - `event` <[string]>
Event name, same one typically passed into `*.on(event)`. 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 ## wait-for-load-state-state
- `state` <[LoadState]<"load"|"domcontentloaded"|"networkidle">> - `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 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. only the first option matching one of the passed options is selected. Optional.
## python-wait-for-event-predicate ## wait-for-event-predicate
* langs: python
- `predicate` <[function]> - `predicate` <[function]>
Receives the event data and resolves to truthy value when the waiting should resolve. 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 ## async method: Page.waitForEvent
* langs: python * langs: python
- returns: <[EventContextManager]> - 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-%% ### option: Page.waitForEvent.timeout = %%-wait-for-event-timeout-%%
## async method: BrowserContext.waitForEvent ## async method: BrowserContext.waitForEvent
* langs: python * langs: python
- returns: <[EventContextManager]> - 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-%% ### option: BrowserContext.waitForEvent.timeout = %%-wait-for-event-timeout-%%
## async method: WebSocket.waitForEvent ## async method: WebSocket.waitForEvent
* langs: python * langs: python
- returns: <[EventContextManager]> - 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-%% ### option: WebSocket.waitForEvent.timeout = %%-wait-for-event-timeout-%%
## async method: Page.waitForDownload ## async method: Page.waitForDownload
@ -138,54 +138,3 @@ Raw script content.
## async method: Page.waitForResponse ## async method: Page.waitForResponse
* langs: python * langs: python
- returns: <[EventContextManager]<[Response]>> - 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") { if (process.argv[3] !== "--skip-format") {
// run the formatting tool for .net, to ensure the files are prepped // run the formatting tool for .net, to ensure the files are prepped
execSync(`dotnet format -f "${typesDir}" --include-generated --fix-whitespace`); 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; const omitAsync = options && options.omitAsync;
if (!omitAsync && member.kind === 'method' && member.async && !assumedName.endsWith('Async')) if (!omitAsync && member.kind === 'method' && member.async && !assumedName.endsWith('Async'))
return `${assumedName}Async`; return `${assumedName}Async`;
if (omitAsync && assumedName.endsWith('Async'))
return assumedName.substring(0, assumedName.length - 'Async'.length);
return assumedName; return assumedName;
} }
@ -456,6 +449,9 @@ function generateEnumNameIfApplicable(type) {
* @param {string[]} out * @param {string[]} out
*/ */
function renderMethod(member, parent, name, options, out) { function renderMethod(member, parent, name, options, out) {
// These are hard-coded in C#.
if (name.includes('WaitForEventAsync'))
return;
out.push(''); out.push('');
/** /**
@ -567,7 +563,7 @@ function renderMethod(member, parent, name, options, out) {
function processArg(arg) { function processArg(arg) {
if (arg.name === 'options') { if (arg.name === 'options') {
if (options.mode === 'options' || options.mode === 'base') { 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); optionTypes.set(optionsType, arg.type);
args.push(`${optionsType} options = default`); args.push(`${optionsType} options = default`);
argTypeMap.set(`${optionsType} options = default`, 'options'); argTypeMap.set(`${optionsType} options = default`, 'options');
@ -634,14 +630,7 @@ function renderMethod(member, parent, name, options, out) {
member.argsArray member.argsArray
.sort((a, b) => b.alias === 'options' ? -1 : 0) //move options to the back to the arguments list .sort((a, b) => b.alias === 'options' ? -1 : 0) //move options to the back to the arguments list
.forEach(processArg); .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 = ';'; let body = ';';
if (options.mode === 'base') { if (options.mode === 'base') {
// Generate options -> named transition. // Generate options -> named transition.
@ -651,8 +640,6 @@ function renderMethod(member, parent, name, options, out) {
tokens.push(toArgumentName(arg.name)); tokens.push(toArgumentName(arg.name));
continue; continue;
} }
if (hasAction)
tokens.push('action');
for (const opt of arg.type.properties) { for (const opt of arg.type.properties) {
// TODO: use translate type here? // 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]') { if (opt.type.union && !opt.type.union[0].name.startsWith('"') && opt.type.union[0].name !== 'null' && opt.type.expression !== '[string]|[Buffer]') {