feat: implement Locator.prototype.wait (#10629)

This commit is contained in:
jrandolf 2023-07-25 16:43:18 +02:00 committed by GitHub
parent 0e40f3e143
commit 5d34d42d15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 76 additions and 30 deletions

View File

@ -37,3 +37,4 @@ export declare abstract class Locator<T> extends EventEmitter
| [setVisibility(this, visibility)](./puppeteer.locator.setvisibility.md) | | |
| [setWaitForEnabled(this, value)](./puppeteer.locator.setwaitforenabled.md) | | |
| [setWaitForStableBoundingBox(this, value)](./puppeteer.locator.setwaitforstableboundingbox.md) | | |
| [wait(options)](./puppeteer.locator.wait.md) | | <p>Waits for the locator to get the serialized value from the page.</p><p>Note this requires the value to be JSON-serializable.</p> |

View File

@ -0,0 +1,27 @@
---
sidebar_label: Locator.wait
---
# Locator.wait() method
Waits for the locator to get the serialized value from the page.
Note this requires the value to be JSON-serializable.
#### Signature:
```typescript
class Locator {
wait(options?: Readonly<ActionOptions>): Promise<T>;
}
```
## Parameters
| Parameter | Type | Description |
| --------- | ------------------------------------------------------------- | ------------ |
| options | Readonly&lt;[ActionOptions](./puppeteer.actionoptions.md)&gt; | _(Optional)_ |
**Returns:**
Promise&lt;T&gt;

View File

@ -635,6 +635,26 @@ export abstract class Locator<T> extends EventEmitter {
*/
abstract _wait(options?: Readonly<ActionOptions>): Observable<HandleFor<T>>;
/**
* Waits for the locator to get the serialized value from the page.
*
* Note this requires the value to be JSON-serializable.
*
* @public
*/
async wait(options?: Readonly<ActionOptions>): Promise<T> {
const handle = await firstValueFrom(
this._wait(options).pipe(
this.operators.retryAndRaceWithSignalAndTimer(options?.signal)
)
);
try {
return await handle.jsonValue();
} finally {
void handle.dispose().catch(debugError);
}
}
/**
* Creates an expectation that is evaluated against located values.
*

View File

@ -115,12 +115,9 @@ export class JSHandle<T = unknown> extends BaseJSHandle<T> {
}
override async jsonValue(): Promise<T> {
const value = BidiSerializer.deserialize(this.#remoteValue);
if (this.#remoteValue.type !== 'undefined' && value === undefined) {
throw new Error('Could not serialize referenced object');
}
return value;
return await this.evaluate(value => {
return value;
});
}
override asElement(): ElementHandle<Node> | null {

View File

@ -23,6 +23,12 @@
"parameters": ["webDriverBiDi"],
"expectations": ["PASS"]
},
{
"testIdPattern": "[jshandle.spec] JSHandle JSHandle.jsonValue should not throw for circular objects",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp"],
"expectations": ["FAIL"]
},
{
"testIdPattern": "[elementhandle.spec] ElementHandle specs Custom queries *",
"platforms": ["darwin", "linux", "win32"],

View File

@ -345,24 +345,6 @@ describe('Evaluation specs', function () {
});
expect(result).toBe(undefined);
});
it('should be able to throw a tricky error', async () => {
const {page} = await getTestState();
const windowHandle = await page.evaluateHandle(() => {
return window;
});
const errorText = await windowHandle.jsonValue().catch(error_ => {
return error_.message;
});
const error = await page
.evaluate(errorText => {
throw new Error(errorText);
}, errorText)
.catch(error_ => {
return error_;
});
expect(error.message).toContain(errorText);
});
it('should accept a string', async () => {
const {page} = await getTestState();

View File

@ -163,7 +163,7 @@ describe('JSHandle', function () {
expect(date).toBeInstanceOf(Date);
expect(date.toISOString()).toEqual('2017-09-26T00:00:00.000Z');
});
it('should throw for circular objects', async () => {
it('should not throw for circular objects', async () => {
const {page} = await getTestState();
const handle = await page.evaluateHandle(() => {
@ -171,11 +171,7 @@ describe('JSHandle', function () {
t.t = t;
return t;
});
let error!: Error;
await handle.jsonValue().catch(error_ => {
return (error = error_);
});
expect(error.message).toContain('Could not serialize referenced object');
await handle.jsonValue();
});
});

View File

@ -569,4 +569,21 @@ describe('Locator', function () {
}
});
});
describe('Locator.prototype.wait', () => {
it('should work', async () => {
const {page} = await getTestState();
page.setContent(`
<script>
setTimeout(() => {
const element = document.createElement("div");
element.innerText = "test2"
document.body.append(element);
}, 50);
</script>
`);
// This shouldn't throw.
await page.locator('div').wait();
});
});
});