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>
|
||||
<tr><td>
|
||||
|
||||
<span id="queryoptions">[QueryOptions](./puppeteer.queryoptions.md)</span>
|
||||
|
||||
</td><td>
|
||||
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
|
||||
<span id="remoteaddress">[RemoteAddress](./puppeteer.remoteaddress.md)</span>
|
||||
|
||||
</td><td>
|
||||
|
@ -11,7 +11,8 @@ Queries the current element for all elements matching the given selector.
|
||||
```typescript
|
||||
class ElementHandle {
|
||||
$$<Selector extends string>(
|
||||
selector: Selector
|
||||
selector: Selector,
|
||||
options?: QueryOptions
|
||||
): Promise<Array<ElementHandle<NodeFor<Selector>>>>;
|
||||
}
|
||||
```
|
||||
@ -43,6 +44,19 @@ Selector
|
||||
|
||||
The selector to query for.
|
||||
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
|
||||
options
|
||||
|
||||
</td><td>
|
||||
|
||||
[QueryOptions](./puppeteer.queryoptions.md)
|
||||
|
||||
</td><td>
|
||||
|
||||
_(Optional)_
|
||||
|
||||
</td></tr>
|
||||
</tbody></table>
|
||||
**Returns:**
|
||||
|
@ -105,7 +105,7 @@ Queries the current element for an element matching the given selector.
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
|
||||
<span id="__">[$$(selector)](./puppeteer.elementhandle.__.md)</span>
|
||||
<span id="__">[$$(selector, options)](./puppeteer.elementhandle.__.md)</span>
|
||||
|
||||
</td><td>
|
||||
|
||||
|
@ -11,7 +11,8 @@ Queries the frame for all elements matching the given selector.
|
||||
```typescript
|
||||
class Frame {
|
||||
$$<Selector extends string>(
|
||||
selector: Selector
|
||||
selector: Selector,
|
||||
options?: QueryOptions
|
||||
): 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).
|
||||
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
|
||||
options
|
||||
|
||||
</td><td>
|
||||
|
||||
[QueryOptions](./puppeteer.queryoptions.md)
|
||||
|
||||
</td><td>
|
||||
|
||||
_(Optional)_
|
||||
|
||||
</td></tr>
|
||||
</tbody></table>
|
||||
**Returns:**
|
||||
|
@ -125,7 +125,7 @@ Queries the frame for an element matching the given selector.
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
|
||||
<span id="__">[$$(selector)](./puppeteer.frame.__.md)</span>
|
||||
<span id="__">[$$(selector, options)](./puppeteer.frame.__.md)</span>
|
||||
|
||||
</td><td>
|
||||
|
||||
|
@ -11,7 +11,8 @@ Finds elements on the page that match the selector. If no elements match the sel
|
||||
```typescript
|
||||
class Page {
|
||||
$$<Selector extends string>(
|
||||
selector: Selector
|
||||
selector: Selector,
|
||||
options?: QueryOptions
|
||||
): 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).
|
||||
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
|
||||
options
|
||||
|
||||
</td><td>
|
||||
|
||||
[QueryOptions](./puppeteer.queryoptions.md)
|
||||
|
||||
</td><td>
|
||||
|
||||
_(Optional)_
|
||||
|
||||
</td></tr>
|
||||
</tbody></table>
|
||||
**Returns:**
|
||||
|
@ -250,7 +250,7 @@ Shortcut for [Page.mainFrame().$(selector)](./puppeteer.frame._.md).
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
|
||||
<span id="__">[$$(selector)](./puppeteer.page.__.md)</span>
|
||||
<span id="__">[$$(selector, options)](./puppeteer.page.__.md)</span>
|
||||
|
||||
</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,
|
||||
} from './Input.js';
|
||||
import {JSHandle} from './JSHandle.js';
|
||||
import type {ScreenshotOptions, WaitForSelectorOptions} from './Page.js';
|
||||
import type {
|
||||
QueryOptions,
|
||||
ScreenshotOptions,
|
||||
WaitForSelectorOptions,
|
||||
} from './Page.js';
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -371,8 +375,34 @@ export abstract class ElementHandle<
|
||||
* elements matching the given selector.
|
||||
*/
|
||||
@throwIfDisposed()
|
||||
@ElementHandle.bindIsolatedHandle
|
||||
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
|
||||
): Promise<Array<ElementHandle<NodeFor<Selector>>>> {
|
||||
const {updatedSelector, QueryHandler} =
|
||||
|
@ -10,6 +10,7 @@ import type {ClickOptions, ElementHandle} from '../api/ElementHandle.js';
|
||||
import type {HTTPResponse} from '../api/HTTPResponse.js';
|
||||
import type {
|
||||
Page,
|
||||
QueryOptions,
|
||||
WaitForSelectorOptions,
|
||||
WaitTimeoutOptions,
|
||||
} from '../api/Page.js';
|
||||
@ -564,11 +565,12 @@ export abstract class Frame extends EventEmitter<FrameEvents> {
|
||||
*/
|
||||
@throwIfDetached
|
||||
async $$<Selector extends string>(
|
||||
selector: Selector
|
||||
selector: Selector,
|
||||
options?: QueryOptions
|
||||
): Promise<Array<ElementHandle<NodeFor<Selector>>>> {
|
||||
// eslint-disable-next-line rulesdir/use-using -- This is cached.
|
||||
const document = await this.#document();
|
||||
return await document.$$(selector);
|
||||
return await document.$$(selector, options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -346,6 +346,21 @@ export interface ScreencastOptions {
|
||||
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.
|
||||
*
|
||||
@ -1081,9 +1096,10 @@ export abstract class Page extends EventEmitter<PageEvents> {
|
||||
* Shortcut for {@link Frame.$$ | Page.mainFrame().$$(selector) }.
|
||||
*/
|
||||
async $$<Selector extends string>(
|
||||
selector: Selector
|
||||
selector: Selector,
|
||||
options?: QueryOptions
|
||||
): 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']);
|
||||
});
|
||||
|
||||
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 () => {
|
||||
const {page, server} = await getTestState();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user