Skip to content

Commit 1f22673

Browse files
authored
api(dotnet): introduce RunAndWaitForAsync (#6660)
1 parent 202511d commit 1f22673

File tree

7 files changed

+90
-91
lines changed

7 files changed

+90
-91
lines changed

docs/src/api/class-browsercontext.md

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,6 +1195,7 @@ Optional handler function used to register a routing with [`method: BrowserConte
11951195
## async method: BrowserContext.waitForEvent
11961196
* langs: csharp, js, python
11971197
- alias-python: expect_event
1198+
- alias-csharp: RunAndWaitForEventAsync
11981199
- returns: <[any]>
11991200

12001201
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
12241225
```
12251226

12261227
```csharp
1227-
var waitForPageEvent = context.WaitForPageAsync();
1228-
await page.ClickAsync("button");
1229-
var page = await waitForPageEvent;
1228+
var page = await context.RunAndWaitForEventAsync(ContextEvent.Page, async () =>
1229+
{
1230+
await page.ClickAsync("button");
1231+
});
12301232
```
12311233

12321234
### param: BrowserContext.waitForEvent.event
@@ -1244,7 +1246,7 @@ Event name, same one would pass into `browserContext.on(event)`.
12441246
Either a predicate that receives an event or an options object. Optional.
12451247

12461248
## async method: BrowserContext.waitForPage
1247-
* langs: csharp, java, python
1249+
* langs: java, python
12481250
- alias-python: expect_page
12491251
- returns: <[Page]>
12501252

@@ -1259,3 +1261,21 @@ Will throw an error if the context closes before new [Page] is created.
12591261
Receives the [Page] object and resolves to truthy value when the waiting should resolve.
12601262

12611263
### option: BrowserContext.waitForPage.timeout = %%-wait-for-event-timeout-%%
1264+
1265+
## async method: BrowserContext.waitForEvent2
1266+
* langs: python, csharp
1267+
- alias-python: wait_for_event
1268+
- alias-csharp: WaitForEventAsync
1269+
- returns: <[any]>
1270+
1271+
:::note
1272+
In most cases, you should use [`method: BrowserContext.waitForEvent`].
1273+
:::
1274+
1275+
Waits for given `event` to fire. If predicate is provided, it passes
1276+
event's value into the `predicate` function and waits for `predicate(event)` to return a truthy value.
1277+
Will throw an error if the browser context is closed before the `event` is fired.
1278+
1279+
### param: BrowserContext.waitForEvent2.event = %%-wait-for-event-event-%%
1280+
### option: BrowserContext.waitForEvent2.predicate = %%-wait-for-event-predicate-%%
1281+
### option: BrowserContext.waitForEvent2.timeout = %%-wait-for-event-timeout-%%

docs/src/api/class-page.md

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2895,15 +2895,15 @@ Video object associated with this page.
28952895
- `height` <[int]> page height in pixels.
28962896

28972897
## async method: Page.waitForClose
2898-
* langs: csharp, java
2898+
* langs: java
28992899
- returns: <[Page]>
29002900

29012901
Performs action and waits for the Page to close.
29022902

29032903
### option: Page.waitForClose.timeout = %%-wait-for-event-timeout-%%
29042904

29052905
## async method: Page.waitForConsoleMessage
2906-
* langs: csharp, java, python
2906+
* langs: java, python
29072907
- alias-python: expect_console_message
29082908
- returns: <[ConsoleMessage]>
29092909

@@ -2919,7 +2919,7 @@ Receives the [ConsoleMessage] object and resolves to truthy value when the waiti
29192919
### option: Page.waitForConsoleMessage.timeout = %%-wait-for-event-timeout-%%
29202920

29212921
## async method: Page.waitForDownload
2922-
* langs: csharp, java, python
2922+
* langs: java, python
29232923
- alias-python: expect_download
29242924
- returns: <[Download]>
29252925

@@ -2937,6 +2937,7 @@ Receives the [Download] object and resolves to truthy value when the waiting sho
29372937
## async method: Page.waitForEvent
29382938
* langs: csharp, js, python
29392939
- alias-python: expect_event
2940+
- alias-csharp: RunAndWaitForEventAsync
29402941
- returns: <[any]>
29412942

29422943
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;
29792980
Either a predicate that receives an event or an options object. Optional.
29802981

29812982
## async method: Page.waitForFileChooser
2982-
* langs: csharp, java, python
2983+
* langs: java, python
29832984
- alias-python: expect_file_chooser
29842985
- returns: <[FileChooser]>
29852986

@@ -3263,7 +3264,7 @@ Shortcut for main frame's [`method: Frame.waitForNavigation`].
32633264
### option: Page.waitForNavigation.timeout = %%-navigation-timeout-%%
32643265
32653266
## async method: Page.waitForPopup
3266-
* langs: csharp, java, python
3267+
* langs: java, python
32673268
- alias-python: expect_popup
32683269
- returns: <[Page]>
32693270
@@ -3655,7 +3656,7 @@ Shortcut for main frame's [`method: Frame.waitForURL`].
36553656
### option: Page.waitForURL.waitUntil = %%-navigation-wait-until-%%
36563657

36573658
## async method: Page.waitForWebSocket
3658-
* langs: csharp, java
3659+
* langs: java
36593660
- returns: <[WebSocket]>
36603661

36613662
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
36703671
### option: Page.waitForWebSocket.timeout = %%-wait-for-event-timeout-%%
36713672

36723673
## async method: Page.waitForWorker
3673-
* langs: csharp, java, python
3674+
* langs: java, python
36743675
- alias-python: expect_worker
36753676
- returns: <[Worker]>
36763677

@@ -3694,3 +3695,21 @@ associated with the page.
36943695
:::note
36953696
This does not contain ServiceWorkers
36963697
:::
3698+
3699+
## async method: Page.waitForEvent2
3700+
* langs: python, csharp
3701+
- alias-python: wait_for_event
3702+
- alias-csharp: WaitForEventAsync
3703+
- returns: <[any]>
3704+
3705+
:::note
3706+
In most cases, you should use [`method: Page.waitForEvent`].
3707+
:::
3708+
3709+
Waits for given `event` to fire. If predicate is provided, it passes
3710+
event's value into the `predicate` function and waits for `predicate(event)` to return a truthy value.
3711+
Will throw an error if the page is closed before the `event` is fired.
3712+
3713+
### param: Page.waitForEvent2.event = %%-wait-for-event-event-%%
3714+
### option: Page.waitForEvent2.predicate = %%-wait-for-event-predicate-%%
3715+
### option: Page.waitForEvent2.timeout = %%-wait-for-event-timeout-%%

docs/src/api/class-websocket.md

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ Indicates that the web socket has been closed.
4343
Contains the URL of the WebSocket.
4444

4545
## async method: WebSocket.waitForEvent
46-
* langs: csharp, js, python
46+
* langs: js, python
4747
- alias-python: expect_event
4848
- returns: <[any]>
4949

@@ -64,7 +64,7 @@ Event name, same one would pass into `webSocket.on(event)`.
6464
Either a predicate that receives an event or an options object. Optional.
6565

6666
## async method: WebSocket.waitForFrameReceived
67-
* langs: csharp, java
67+
* langs: java
6868
- returns: <[WebSocketFrame]>
6969

7070
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
7979
### option: WebSocket.waitForFrameReceived.timeout = %%-wait-for-event-timeout-%%
8080

8181
## async method: WebSocket.waitForFrameSent
82-
* langs: csharp, java
82+
* langs: java
8383
- returns: <[WebSocketFrame]>
8484

8585
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.
9292
Receives the [WebSocketFrame] object and resolves to truthy value when the waiting should resolve.
9393

9494
### option: WebSocket.waitForFrameSent.timeout = %%-wait-for-event-timeout-%%
95+
96+
## async method: WebSocket.waitForEvent2
97+
* langs: python
98+
- alias-python: wait_for_event
99+
- alias-csharp: WaitForEventAsync
100+
- returns: <[any]>
101+
102+
:::note
103+
In most cases, you should use [`method: WebSocket.waitForEvent`].
104+
:::
105+
106+
Waits for given `event` to fire. If predicate is provided, it passes
107+
event's value into the `predicate` function and waits for `predicate(event)` to return a truthy value.
108+
Will throw an error if the socket is closed before the `event` is fired.
109+
110+
### param: WebSocket.waitForEvent2.event = %%-wait-for-event-event-%%
111+
### option: WebSocket.waitForEvent2.predicate = %%-wait-for-event-predicate-%%
112+
### option: WebSocket.waitForEvent2.timeout = %%-wait-for-event-timeout-%%

docs/src/api/class-worker.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ Optional argument to pass to [`param: expression`].
9797
- returns: <[string]>
9898

9999
## async method: Worker.waitForClose
100-
* langs: csharp, java
100+
* langs: java
101101
- returns: <[Worker]>
102102

103103
Performs action and waits for the Worker to close.

docs/src/api/params.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,10 +480,17 @@ is considered matching if all specified properties match.
480480
A glob pattern, regex pattern or predicate receiving [URL] to match while waiting for the navigation.
481481

482482
## wait-for-event-event
483+
* langs: js, java, python
483484
- `event` <[string]>
484485

485486
Event name, same one typically passed into `*.on(event)`.
486487

488+
## csharp-wait-for-event-event
489+
* langs: csharp
490+
- `playwrightEvent` <[PlaywrightEvent<T>]>
491+
492+
Event type, same one typically passed into `WaitForEventAsync`.
493+
487494
## wait-for-load-state-state
488495
- `state` <[LoadState]<"load"|"domcontentloaded"|"networkidle">>
489496

@@ -530,8 +537,7 @@ only the first option matching one of the passed options is selected. Optional.
530537
Options to select by label. If the `<select>` has the `multiple` attribute, all given options are selected, otherwise
531538
only the first option matching one of the passed options is selected. Optional.
532539

533-
## python-wait-for-event-predicate
534-
* langs: python
540+
## wait-for-event-predicate
535541
- `predicate` <[function]>
536542

537543
Receives the event data and resolves to truthy value when the waiting should resolve.

docs/src/api/python.md

Lines changed: 3 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -84,19 +84,19 @@ Raw script content.
8484
## async method: Page.waitForEvent
8585
* langs: python
8686
- returns: <[EventContextManager]>
87-
### option: Page.waitForEvent.predicate = %%-python-wait-for-event-predicate-%%
87+
### option: Page.waitForEvent.predicate = %%-wait-for-event-predicate-%%
8888
### option: Page.waitForEvent.timeout = %%-wait-for-event-timeout-%%
8989

9090
## async method: BrowserContext.waitForEvent
9191
* langs: python
9292
- returns: <[EventContextManager]>
93-
### option: BrowserContext.waitForEvent.predicate = %%-python-wait-for-event-predicate-%%
93+
### option: BrowserContext.waitForEvent.predicate = %%-wait-for-event-predicate-%%
9494
### option: BrowserContext.waitForEvent.timeout = %%-wait-for-event-timeout-%%
9595

9696
## async method: WebSocket.waitForEvent
9797
* langs: python
9898
- returns: <[EventContextManager]>
99-
### option: WebSocket.waitForEvent.predicate = %%-python-wait-for-event-predicate-%%
99+
### option: WebSocket.waitForEvent.predicate = %%-wait-for-event-predicate-%%
100100
### option: WebSocket.waitForEvent.timeout = %%-wait-for-event-timeout-%%
101101

102102
## async method: Page.waitForDownload
@@ -138,54 +138,3 @@ Raw script content.
138138
## async method: Page.waitForResponse
139139
* langs: python
140140
- returns: <[EventContextManager]<[Response]>>
141-
142-
## async method: BrowserContext.waitForEvent2
143-
* langs: python
144-
- alias-python: wait_for_event
145-
- returns: <[Any]>
146-
147-
:::note
148-
In most cases, you should use [`method: BrowserContext.waitForEvent`].
149-
:::
150-
151-
Waits for given `event` to fire. If predicate is provided, it passes
152-
event's value into the `predicate` function and waits for `predicate(event)` to return a truthy value.
153-
Will throw an error if the socket is closed before the `event` is fired.
154-
155-
### param: BrowserContext.waitForEvent2.event = %%-wait-for-event-event-%%
156-
### option: BrowserContext.waitForEvent2.predicate = %%-python-wait-for-event-predicate-%%
157-
### option: BrowserContext.waitForEvent2.timeout = %%-wait-for-event-timeout-%%
158-
159-
## async method: Page.waitForEvent2
160-
* langs: python
161-
- alias-python: wait_for_event
162-
- returns: <[Any]>
163-
164-
:::note
165-
In most cases, you should use [`method: Page.waitForEvent`].
166-
:::
167-
168-
Waits for given `event` to fire. If predicate is provided, it passes
169-
event's value into the `predicate` function and waits for `predicate(event)` to return a truthy value.
170-
Will throw an error if the socket is closed before the `event` is fired.
171-
172-
### param: Page.waitForEvent2.event = %%-wait-for-event-event-%%
173-
### option: Page.waitForEvent2.predicate = %%-python-wait-for-event-predicate-%%
174-
### option: Page.waitForEvent2.timeout = %%-wait-for-event-timeout-%%
175-
176-
## async method: WebSocket.waitForEvent2
177-
* langs: python
178-
- alias-python: wait_for_event
179-
- returns: <[Any]>
180-
181-
:::note
182-
In most cases, you should use [`method: WebSocket.waitForEvent`].
183-
:::
184-
185-
Waits for given `event` to fire. If predicate is provided, it passes
186-
event's value into the `predicate` function and waits for `predicate(event)` to return a truthy value.
187-
Will throw an error if the socket is closed before the `event` is fired.
188-
189-
### param: WebSocket.waitForEvent2.event = %%-wait-for-event-event-%%
190-
### option: WebSocket.waitForEvent2.predicate = %%-python-wait-for-event-predicate-%%
191-
### option: WebSocket.waitForEvent2.timeout = %%-wait-for-event-timeout-%%

utils/doclint/generateDotnetApi.js

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -259,15 +259,6 @@ for (let [name, type] of optionTypes)
259259
if (process.argv[3] !== "--skip-format") {
260260
// run the formatting tool for .net, to ensure the files are prepped
261261
execSync(`dotnet format -f "${typesDir}" --include-generated --fix-whitespace`);
262-
if (process.platform !== 'win32') {
263-
for (const folder of [typesDir, path.join(typesDir, 'Models'), path.join(typesDir, 'Enums'), path.join(typesDir, 'Extensions'), path.join(typesDir, 'Constants')])
264-
for (const name of fs.readdirSync(folder)) {
265-
if (!name.includes('\.cs'))
266-
continue;
267-
const content = fs.readFileSync(path.join(folder, name), 'utf-8');
268-
fs.writeFileSync(path.join(folder, name), content.split('\r\n').join('\n'));
269-
}
270-
}
271262
}
272263

273264
/**
@@ -288,6 +279,8 @@ function toMemberName(member, options) {
288279
const omitAsync = options && options.omitAsync;
289280
if (!omitAsync && member.kind === 'method' && member.async && !assumedName.endsWith('Async'))
290281
return `${assumedName}Async`;
282+
if (omitAsync && assumedName.endsWith('Async'))
283+
return assumedName.substring(0, assumedName.length - 'Async'.length);
291284
return assumedName;
292285
}
293286

@@ -456,6 +449,9 @@ function generateEnumNameIfApplicable(type) {
456449
* @param {string[]} out
457450
*/
458451
function renderMethod(member, parent, name, options, out) {
452+
// These are hard-coded in C#.
453+
if (name.includes('WaitForEventAsync'))
454+
return;
459455
out.push('');
460456

461457
/**
@@ -567,7 +563,7 @@ function renderMethod(member, parent, name, options, out) {
567563
function processArg(arg) {
568564
if (arg.name === 'options') {
569565
if (options.mode === 'options' || options.mode === 'base') {
570-
const optionsType = member.clazz.name + toTitleCase(member.name) + 'Options';
566+
const optionsType = member.clazz.name + toMemberName(member, { omitAsync: true }) + 'Options';
571567
optionTypes.set(optionsType, arg.type);
572568
args.push(`${optionsType} options = default`);
573569
argTypeMap.set(`${optionsType} options = default`, 'options');
@@ -634,14 +630,7 @@ function renderMethod(member, parent, name, options, out) {
634630
member.argsArray
635631
.sort((a, b) => b.alias === 'options' ? -1 : 0) //move options to the back to the arguments list
636632
.forEach(processArg);
637-
638-
const hasAction = name.includes('WaitFor') && !['WaitForTimeoutAsync', 'WaitForFunctionAsync', 'WaitForLoadStateAsync', 'WaitForURLAsync', 'WaitForSelectorAsync', 'WaitForElementStateAsync'].includes(name);
639-
if (hasAction) {
640-
args.push('Func<Task> action = default');
641-
argTypeMap.set('Func<Task> action = default', 'action');
642-
addParamsDoc('action', ['Action to perform while waiting']);
643-
}
644-
633+
645634
let body = ';';
646635
if (options.mode === 'base') {
647636
// Generate options -> named transition.
@@ -651,8 +640,6 @@ function renderMethod(member, parent, name, options, out) {
651640
tokens.push(toArgumentName(arg.name));
652641
continue;
653642
}
654-
if (hasAction)
655-
tokens.push('action');
656643
for (const opt of arg.type.properties) {
657644
// TODO: use translate type here?
658645
if (opt.type.union && !opt.type.union[0].name.startsWith('"') && opt.type.union[0].name !== 'null' && opt.type.expression !== '[string]|[Buffer]') {

0 commit comments

Comments
 (0)