mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
fix: add a way to run page.$$ without the isolation (#12539)
This commit is contained in:
parent
97451731da
commit
03e10a7559
@ -1172,6 +1172,13 @@ Valid options to configure PDF generation via [Page.pdf()](./puppeteer.page.pdf.
|
|||||||
</td></tr>
|
</td></tr>
|
||||||
<tr><td>
|
<tr><td>
|
||||||
|
|
||||||
|
<span id="queryoptions">[QueryOptions](./puppeteer.queryoptions.md)</span>
|
||||||
|
|
||||||
|
</td><td>
|
||||||
|
|
||||||
|
</td></tr>
|
||||||
|
<tr><td>
|
||||||
|
|
||||||
<span id="remoteaddress">[RemoteAddress](./puppeteer.remoteaddress.md)</span>
|
<span id="remoteaddress">[RemoteAddress](./puppeteer.remoteaddress.md)</span>
|
||||||
|
|
||||||
</td><td>
|
</td><td>
|
||||||
|
@ -11,7 +11,8 @@ Queries the current element for all elements matching the given selector.
|
|||||||
```typescript
|
```typescript
|
||||||
class ElementHandle {
|
class ElementHandle {
|
||||||
$$<Selector extends string>(
|
$$<Selector extends string>(
|
||||||
selector: Selector
|
selector: Selector,
|
||||||
|
options?: QueryOptions
|
||||||
): Promise<Array<ElementHandle<NodeFor<Selector>>>>;
|
): Promise<Array<ElementHandle<NodeFor<Selector>>>>;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -43,6 +44,19 @@ Selector
|
|||||||
|
|
||||||
The selector to query for.
|
The selector to query for.
|
||||||
|
|
||||||
|
</td></tr>
|
||||||
|
<tr><td>
|
||||||
|
|
||||||
|
options
|
||||||
|
|
||||||
|
</td><td>
|
||||||
|
|
||||||
|
[QueryOptions](./puppeteer.queryoptions.md)
|
||||||
|
|
||||||
|
</td><td>
|
||||||
|
|
||||||
|
_(Optional)_
|
||||||
|
|
||||||
</td></tr>
|
</td></tr>
|
||||||
</tbody></table>
|
</tbody></table>
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
@ -105,7 +105,7 @@ Queries the current element for an element matching the given selector.
|
|||||||
</td></tr>
|
</td></tr>
|
||||||
<tr><td>
|
<tr><td>
|
||||||
|
|
||||||
<span id="__">[$$(selector)](./puppeteer.elementhandle.__.md)</span>
|
<span id="__">[$$(selector, options)](./puppeteer.elementhandle.__.md)</span>
|
||||||
|
|
||||||
</td><td>
|
</td><td>
|
||||||
|
|
||||||
|
@ -11,7 +11,8 @@ Queries the frame for all elements matching the given selector.
|
|||||||
```typescript
|
```typescript
|
||||||
class Frame {
|
class Frame {
|
||||||
$$<Selector extends string>(
|
$$<Selector extends string>(
|
||||||
selector: Selector
|
selector: Selector,
|
||||||
|
options?: QueryOptions
|
||||||
): Promise<Array<ElementHandle<NodeFor<Selector>>>>;
|
): Promise<Array<ElementHandle<NodeFor<Selector>>>>;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -43,6 +44,19 @@ Selector
|
|||||||
|
|
||||||
[selector](https://pptr.dev/guides/page-interactions#query-selectors) to query page for. [CSS selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors) can be passed as-is and a [Puppeteer-specific seletor syntax](https://pptr.dev/guides/page-interactions#p-selectors) allows quering by [text](https://pptr.dev/guides/page-interactions#text-selectors--p-text), [a11y role and name](https://pptr.dev/guides/page-interactions#aria-selectors--p-aria), and [xpath](https://pptr.dev/guides/page-interactions#xpath-selectors--p-xpath) and [combining these queries across shadow roots](https://pptr.dev/guides/page-interactions#-and--combinators). Alternatively, you can specify a selector type using a prefix [prefix](https://pptr.dev/guides/page-interactions#built-in-selectors).
|
[selector](https://pptr.dev/guides/page-interactions#query-selectors) to query page for. [CSS selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors) can be passed as-is and a [Puppeteer-specific seletor syntax](https://pptr.dev/guides/page-interactions#p-selectors) allows quering by [text](https://pptr.dev/guides/page-interactions#text-selectors--p-text), [a11y role and name](https://pptr.dev/guides/page-interactions#aria-selectors--p-aria), and [xpath](https://pptr.dev/guides/page-interactions#xpath-selectors--p-xpath) and [combining these queries across shadow roots](https://pptr.dev/guides/page-interactions#-and--combinators). Alternatively, you can specify a selector type using a prefix [prefix](https://pptr.dev/guides/page-interactions#built-in-selectors).
|
||||||
|
|
||||||
|
</td></tr>
|
||||||
|
<tr><td>
|
||||||
|
|
||||||
|
options
|
||||||
|
|
||||||
|
</td><td>
|
||||||
|
|
||||||
|
[QueryOptions](./puppeteer.queryoptions.md)
|
||||||
|
|
||||||
|
</td><td>
|
||||||
|
|
||||||
|
_(Optional)_
|
||||||
|
|
||||||
</td></tr>
|
</td></tr>
|
||||||
</tbody></table>
|
</tbody></table>
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
@ -125,7 +125,7 @@ Queries the frame for an element matching the given selector.
|
|||||||
</td></tr>
|
</td></tr>
|
||||||
<tr><td>
|
<tr><td>
|
||||||
|
|
||||||
<span id="__">[$$(selector)](./puppeteer.frame.__.md)</span>
|
<span id="__">[$$(selector, options)](./puppeteer.frame.__.md)</span>
|
||||||
|
|
||||||
</td><td>
|
</td><td>
|
||||||
|
|
||||||
|
@ -11,7 +11,8 @@ Finds elements on the page that match the selector. If no elements match the sel
|
|||||||
```typescript
|
```typescript
|
||||||
class Page {
|
class Page {
|
||||||
$$<Selector extends string>(
|
$$<Selector extends string>(
|
||||||
selector: Selector
|
selector: Selector,
|
||||||
|
options?: QueryOptions
|
||||||
): Promise<Array<ElementHandle<NodeFor<Selector>>>>;
|
): Promise<Array<ElementHandle<NodeFor<Selector>>>>;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -43,6 +44,19 @@ Selector
|
|||||||
|
|
||||||
[selector](https://pptr.dev/guides/page-interactions#query-selectors) to query page for. [CSS selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors) can be passed as-is and a [Puppeteer-specific seletor syntax](https://pptr.dev/guides/page-interactions#p-selectors) allows quering by [text](https://pptr.dev/guides/page-interactions#text-selectors--p-text), [a11y role and name](https://pptr.dev/guides/page-interactions#aria-selectors--p-aria), and [xpath](https://pptr.dev/guides/page-interactions#xpath-selectors--p-xpath) and [combining these queries across shadow roots](https://pptr.dev/guides/page-interactions#-and--combinators). Alternatively, you can specify a selector type using a prefix [prefix](https://pptr.dev/guides/page-interactions#built-in-selectors).
|
[selector](https://pptr.dev/guides/page-interactions#query-selectors) to query page for. [CSS selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors) can be passed as-is and a [Puppeteer-specific seletor syntax](https://pptr.dev/guides/page-interactions#p-selectors) allows quering by [text](https://pptr.dev/guides/page-interactions#text-selectors--p-text), [a11y role and name](https://pptr.dev/guides/page-interactions#aria-selectors--p-aria), and [xpath](https://pptr.dev/guides/page-interactions#xpath-selectors--p-xpath) and [combining these queries across shadow roots](https://pptr.dev/guides/page-interactions#-and--combinators). Alternatively, you can specify a selector type using a prefix [prefix](https://pptr.dev/guides/page-interactions#built-in-selectors).
|
||||||
|
|
||||||
|
</td></tr>
|
||||||
|
<tr><td>
|
||||||
|
|
||||||
|
options
|
||||||
|
|
||||||
|
</td><td>
|
||||||
|
|
||||||
|
[QueryOptions](./puppeteer.queryoptions.md)
|
||||||
|
|
||||||
|
</td><td>
|
||||||
|
|
||||||
|
_(Optional)_
|
||||||
|
|
||||||
</td></tr>
|
</td></tr>
|
||||||
</tbody></table>
|
</tbody></table>
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
@ -250,7 +250,7 @@ Shortcut for [Page.mainFrame().$(selector)](./puppeteer.frame._.md).
|
|||||||
</td></tr>
|
</td></tr>
|
||||||
<tr><td>
|
<tr><td>
|
||||||
|
|
||||||
<span id="__">[$$(selector)](./puppeteer.page.__.md)</span>
|
<span id="__">[$$(selector, options)](./puppeteer.page.__.md)</span>
|
||||||
|
|
||||||
</td><td>
|
</td><td>
|
||||||
|
|
||||||
|
55
docs/api/puppeteer.queryoptions.md
Normal file
55
docs/api/puppeteer.queryoptions.md
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
---
|
||||||
|
sidebar_label: QueryOptions
|
||||||
|
---
|
||||||
|
|
||||||
|
# QueryOptions interface
|
||||||
|
|
||||||
|
#### Signature:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export interface QueryOptions
|
||||||
|
```
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
<table><thead><tr><th>
|
||||||
|
|
||||||
|
Property
|
||||||
|
|
||||||
|
</th><th>
|
||||||
|
|
||||||
|
Modifiers
|
||||||
|
|
||||||
|
</th><th>
|
||||||
|
|
||||||
|
Type
|
||||||
|
|
||||||
|
</th><th>
|
||||||
|
|
||||||
|
Description
|
||||||
|
|
||||||
|
</th><th>
|
||||||
|
|
||||||
|
Default
|
||||||
|
|
||||||
|
</th></tr></thead>
|
||||||
|
<tbody><tr><td>
|
||||||
|
|
||||||
|
<span id="isolate">isolate</span>
|
||||||
|
|
||||||
|
</td><td>
|
||||||
|
|
||||||
|
</td><td>
|
||||||
|
|
||||||
|
boolean
|
||||||
|
|
||||||
|
</td><td>
|
||||||
|
|
||||||
|
Whether to run the query in isolation. When returning many elements from [Page.$$()](./puppeteer.page.__.md) or similar methods, it might be useful to turn off the isolation to improve performance. By default, the querying code will be executed in a separate sandbox realm.
|
||||||
|
|
||||||
|
</td><td>
|
||||||
|
|
||||||
|
`true`
|
||||||
|
|
||||||
|
</td></tr>
|
||||||
|
</tbody></table>
|
@ -31,7 +31,11 @@ import type {
|
|||||||
MouseClickOptions,
|
MouseClickOptions,
|
||||||
} from './Input.js';
|
} from './Input.js';
|
||||||
import {JSHandle} from './JSHandle.js';
|
import {JSHandle} from './JSHandle.js';
|
||||||
import type {ScreenshotOptions, WaitForSelectorOptions} from './Page.js';
|
import type {
|
||||||
|
QueryOptions,
|
||||||
|
ScreenshotOptions,
|
||||||
|
WaitForSelectorOptions,
|
||||||
|
} from './Page.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
@ -371,8 +375,34 @@ export abstract class ElementHandle<
|
|||||||
* elements matching the given selector.
|
* elements matching the given selector.
|
||||||
*/
|
*/
|
||||||
@throwIfDisposed()
|
@throwIfDisposed()
|
||||||
@ElementHandle.bindIsolatedHandle
|
|
||||||
async $$<Selector extends string>(
|
async $$<Selector extends string>(
|
||||||
|
selector: Selector,
|
||||||
|
options?: QueryOptions
|
||||||
|
): Promise<Array<ElementHandle<NodeFor<Selector>>>> {
|
||||||
|
if (options?.isolate === false) {
|
||||||
|
return await this.#$$impl(selector);
|
||||||
|
}
|
||||||
|
return await this.#$$(selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Isolates {@link ElementHandle.$$} if needed.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
@ElementHandle.bindIsolatedHandle
|
||||||
|
async #$$<Selector extends string>(
|
||||||
|
selector: Selector
|
||||||
|
): Promise<Array<ElementHandle<NodeFor<Selector>>>> {
|
||||||
|
return await this.#$$impl(selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation for {@link ElementHandle.$$}.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
async #$$impl<Selector extends string>(
|
||||||
selector: Selector
|
selector: Selector
|
||||||
): Promise<Array<ElementHandle<NodeFor<Selector>>>> {
|
): Promise<Array<ElementHandle<NodeFor<Selector>>>> {
|
||||||
const {updatedSelector, QueryHandler} =
|
const {updatedSelector, QueryHandler} =
|
||||||
|
@ -10,6 +10,7 @@ import type {ClickOptions, ElementHandle} from '../api/ElementHandle.js';
|
|||||||
import type {HTTPResponse} from '../api/HTTPResponse.js';
|
import type {HTTPResponse} from '../api/HTTPResponse.js';
|
||||||
import type {
|
import type {
|
||||||
Page,
|
Page,
|
||||||
|
QueryOptions,
|
||||||
WaitForSelectorOptions,
|
WaitForSelectorOptions,
|
||||||
WaitTimeoutOptions,
|
WaitTimeoutOptions,
|
||||||
} from '../api/Page.js';
|
} from '../api/Page.js';
|
||||||
@ -564,11 +565,12 @@ export abstract class Frame extends EventEmitter<FrameEvents> {
|
|||||||
*/
|
*/
|
||||||
@throwIfDetached
|
@throwIfDetached
|
||||||
async $$<Selector extends string>(
|
async $$<Selector extends string>(
|
||||||
selector: Selector
|
selector: Selector,
|
||||||
|
options?: QueryOptions
|
||||||
): Promise<Array<ElementHandle<NodeFor<Selector>>>> {
|
): Promise<Array<ElementHandle<NodeFor<Selector>>>> {
|
||||||
// eslint-disable-next-line rulesdir/use-using -- This is cached.
|
// eslint-disable-next-line rulesdir/use-using -- This is cached.
|
||||||
const document = await this.#document();
|
const document = await this.#document();
|
||||||
return await document.$$(selector);
|
return await document.$$(selector, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -346,6 +346,21 @@ export interface ScreencastOptions {
|
|||||||
ffmpegPath?: string;
|
ffmpegPath?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export interface QueryOptions {
|
||||||
|
/**
|
||||||
|
* Whether to run the query in isolation. When returning many elements
|
||||||
|
* from {@link Page.$$} or similar methods, it might be useful to turn
|
||||||
|
* off the isolation to improve performance. By default, the querying
|
||||||
|
* code will be executed in a separate sandbox realm.
|
||||||
|
*
|
||||||
|
* @defaultValue `true`
|
||||||
|
*/
|
||||||
|
isolate: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All the events that a page instance may emit.
|
* All the events that a page instance may emit.
|
||||||
*
|
*
|
||||||
@ -1081,9 +1096,10 @@ export abstract class Page extends EventEmitter<PageEvents> {
|
|||||||
* Shortcut for {@link Frame.$$ | Page.mainFrame().$$(selector) }.
|
* Shortcut for {@link Frame.$$ | Page.mainFrame().$$(selector) }.
|
||||||
*/
|
*/
|
||||||
async $$<Selector extends string>(
|
async $$<Selector extends string>(
|
||||||
selector: Selector
|
selector: Selector,
|
||||||
|
options?: QueryOptions
|
||||||
): Promise<Array<ElementHandle<NodeFor<Selector>>>> {
|
): Promise<Array<ElementHandle<NodeFor<Selector>>>> {
|
||||||
return await this.mainFrame().$$(selector);
|
return await this.mainFrame().$$(selector, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -167,6 +167,23 @@ describe('querySelector', function () {
|
|||||||
});
|
});
|
||||||
expect(await Promise.all(promises)).toEqual(['A', 'B']);
|
expect(await Promise.all(promises)).toEqual(['A', 'B']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should query existing elements without isolation', async () => {
|
||||||
|
const {page} = await getTestState();
|
||||||
|
|
||||||
|
await page.setContent('<div>A</div><br/><div>B</div>');
|
||||||
|
const elements = await page.$$('div', {
|
||||||
|
isolate: false,
|
||||||
|
});
|
||||||
|
expect(elements).toHaveLength(2);
|
||||||
|
const promises = elements.map(element => {
|
||||||
|
return page.evaluate(e => {
|
||||||
|
return e.textContent;
|
||||||
|
}, element);
|
||||||
|
});
|
||||||
|
expect(await Promise.all(promises)).toEqual(['A', 'B']);
|
||||||
|
});
|
||||||
|
|
||||||
it('should return empty array if nothing is found', async () => {
|
it('should return empty array if nothing is found', async () => {
|
||||||
const {page, server} = await getTestState();
|
const {page, server} = await getTestState();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user