refactor!: remove $x and waitForXpath (#11782)

This commit is contained in:
Nikolay Vitkov 2024-02-02 13:18:43 +01:00 committed by GitHub
parent 1900fa9418
commit 53c9134809
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 193 additions and 689 deletions

View File

@ -1,33 +0,0 @@
---
sidebar_label: ElementHandle.$x
---
# ElementHandle.$x() method
> Warning: This API is now obsolete.
>
> Use [ElementHandle.$$()](./puppeteer.elementhandle.__.md) with the `xpath` prefix.
>
> Example: `await elementHandle.$$('xpath/' + xpathExpression)`
>
> The method evaluates the XPath expression relative to the elementHandle. If `xpath` starts with `//` instead of `.//`, the dot will be appended automatically.
>
> If there are no such elements, the method will resolve to an empty array.
#### Signature:
```typescript
class ElementHandle {
$x(expression: string): Promise<Array<ElementHandle<Node>>>;
}
```
## Parameters
| Parameter | Type | Description |
| ---------- | ------ | -------------------------------------------------------------------------------------------- |
| expression | string | Expression to [evaluate](https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate) |
**Returns:**
Promise&lt;Array&lt;[ElementHandle](./puppeteer.elementhandle.md)&lt;Node&gt;&gt;&gt;

View File

@ -53,7 +53,6 @@ The constructor for this class is marked as internal. Third-party code should no
| [$$(selector)](./puppeteer.elementhandle.__.md) | | Queries the current element for all elements matching the given selector. |
| [$$eval(selector, pageFunction, args)](./puppeteer.elementhandle.__eval.md) | | <p>Runs the given function on an array of elements matching the given selector in the current element.</p><p>If the given function returns a promise, then this method will wait till the promise resolves.</p> |
| [$eval(selector, pageFunction, args)](./puppeteer.elementhandle._eval.md) | | <p>Runs the given function on the first element matching the given selector in the current element.</p><p>If the given function returns a promise, then this method will wait till the promise resolves.</p> |
| [$x(expression)](./puppeteer.elementhandle._x.md) | | |
| [autofill(data)](./puppeteer.elementhandle.autofill.md) | | If the element is a form input, you can use [ElementHandle.autofill()](./puppeteer.elementhandle.autofill.md) to test if the form is compatible with the browser's autofill implementation. Throws an error if the form cannot be autofilled. |
| [boundingBox()](./puppeteer.elementhandle.boundingbox.md) | | This method returns the bounding box of the element (relative to the main frame), or <code>null</code> if the element is [not part of the layout](https://drafts.csswg.org/css-display-4/#box-generation) (example: <code>display: none</code>). |
| [boxModel()](./puppeteer.elementhandle.boxmodel.md) | | This method returns boxes of the element, or <code>null</code> if the element is [not part of the layout](https://drafts.csswg.org/css-display-4/#box-generation) (example: <code>display: none</code>). |
@ -85,4 +84,3 @@ The constructor for this class is marked as internal. Third-party code should no
| [type(text, options)](./puppeteer.elementhandle.type.md) | | <p>Focuses the element, and then sends a <code>keydown</code>, <code>keypress</code>/<code>input</code>, and <code>keyup</code> event for each character in the text.</p><p>To press a special key, like <code>Control</code> or <code>ArrowDown</code>, use [ElementHandle.press()](./puppeteer.elementhandle.press.md).</p> |
| [uploadFile(this, paths)](./puppeteer.elementhandle.uploadfile.md) | | Sets the value of an [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) to the given file paths. |
| [waitForSelector(selector, options)](./puppeteer.elementhandle.waitforselector.md) | | <p>Wait for an element matching the given selector to appear in the current element.</p><p>Unlike [Frame.waitForSelector()](./puppeteer.frame.waitforselector.md), this method does not work across navigations or if the element is detached from DOM.</p> |
| [waitForXPath(xpath, options)](./puppeteer.elementhandle.waitforxpath.md) | | |

View File

@ -1,79 +0,0 @@
---
sidebar_label: ElementHandle.waitForXPath
---
# ElementHandle.waitForXPath() method
> Warning: This API is now obsolete.
>
> Use [ElementHandle.waitForSelector()](./puppeteer.elementhandle.waitforselector.md) with the `xpath` prefix.
>
> Example: `await elementHandle.waitForSelector('xpath/' + xpathExpression)`
>
> The method evaluates the XPath expression relative to the elementHandle.
>
> Wait for the `xpath` within the element. If at the moment of calling the method the `xpath` already exists, the method will return immediately. If the `xpath` doesn't appear after the `timeout` milliseconds of waiting, the function will throw.
>
> If `xpath` starts with `//` instead of `.//`, the dot will be appended automatically.
#### Signature:
```typescript
class ElementHandle {
waitForXPath(
xpath: string,
options?: {
visible?: boolean;
hidden?: boolean;
timeout?: number;
}
): Promise<ElementHandle<Node> | null>;
}
```
## Parameters
| Parameter | Type | Description |
| --------- | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| xpath | string | A [xpath](https://developer.mozilla.org/en-US/docs/Web/XPath) of an element to wait for |
| options | &#123; visible?: boolean; hidden?: boolean; timeout?: number; &#125; | _(Optional)_ Optional waiting parameters |
**Returns:**
Promise&lt;[ElementHandle](./puppeteer.elementhandle.md)&lt;Node&gt; \| null&gt;
Promise which resolves when element specified by xpath string is added to DOM. Resolves to `null` if waiting for `hidden: true` and xpath is not found in DOM, otherwise resolves to `ElementHandle`.
## Remarks
The optional Argument `options` have properties:
- `visible`: A boolean to wait for element to be present in DOM and to be visible, i.e. to not have `display: none` or `visibility: hidden` CSS properties. Defaults to `false`.
- `hidden`: A boolean wait for element to not be found in the DOM or to be hidden, i.e. have `display: none` or `visibility: hidden` CSS properties. Defaults to `false`.
- `timeout`: A number which is maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can be changed by using the [Page.setDefaultTimeout()](./puppeteer.page.setdefaulttimeout.md) method.
## Example
This method works across navigation.
```ts
import puppeteer from 'puppeteer';
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
let currentURL;
page
.waitForXPath('//img')
.then(() => console.log('First URL with image: ' + currentURL));
for (currentURL of [
'https://example.com',
'https://google.com',
'https://bbc.com',
]) {
await page.goto(currentURL);
}
await browser.close();
})();
```

View File

@ -1,31 +0,0 @@
---
sidebar_label: Frame.$x
---
# Frame.$x() method
> Warning: This API is now obsolete.
>
> Use [Frame.$$()](./puppeteer.frame.__.md) with the `xpath` prefix.
>
> Example: `await frame.$$('xpath/' + xpathExpression)`
>
> This method evaluates the given XPath expression and returns the results. If `xpath` starts with `//` instead of `.//`, the dot will be appended automatically.
#### Signature:
```typescript
class Frame {
$x(expression: string): Promise<Array<ElementHandle<Node>>>;
}
```
## Parameters
| Parameter | Type | Description |
| ---------- | ------ | --------------------------------- |
| expression | string | the XPath expression to evaluate. |
**Returns:**
Promise&lt;Array&lt;[ElementHandle](./puppeteer.elementhandle.md)&lt;Node&gt;&gt;&gt;

View File

@ -75,7 +75,6 @@ console.log(text);
| [$$(selector)](./puppeteer.frame.__.md) | | Queries the frame for all elements matching the given selector. |
| [$$eval(selector, pageFunction, args)](./puppeteer.frame.__eval.md) | | <p>Runs the given function on an array of elements matching the given selector in the frame.</p><p>If the given function returns a promise, then this method will wait till the promise resolves.</p> |
| [$eval(selector, pageFunction, args)](./puppeteer.frame._eval.md) | | <p>Runs the given function on the first element matching the given selector in the frame.</p><p>If the given function returns a promise, then this method will wait till the promise resolves.</p> |
| [$x(expression)](./puppeteer.frame._x.md) | | |
| [addScriptTag(options)](./puppeteer.frame.addscripttag.md) | | Adds a <code>&lt;script&gt;</code> tag into the page with the desired url or content. |
| [addStyleTag(options)](./puppeteer.frame.addstyletag.md) | | Adds a <code>HTMLStyleElement</code> into the frame with the desired URL |
| [addStyleTag(options)](./puppeteer.frame.addstyletag_1.md) | | Adds a <code>HTMLLinkElement</code> into the frame with the desired URL |
@ -103,4 +102,3 @@ console.log(text);
| [waitForFunction(pageFunction, options, args)](./puppeteer.frame.waitforfunction.md) | | |
| [waitForNavigation(options)](./puppeteer.frame.waitfornavigation.md) | | <p>Waits for the frame to navigate. It is useful for when you run code which will indirectly cause the frame to navigate.</p><p>Usage of the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API) to change the URL is considered a navigation.</p> |
| [waitForSelector(selector, options)](./puppeteer.frame.waitforselector.md) | | <p>Waits for an element matching the given selector to appear in the frame.</p><p>This method works across navigations.</p> |
| [waitForXPath(xpath, options)](./puppeteer.frame.waitforxpath.md) | | |

View File

@ -1,39 +0,0 @@
---
sidebar_label: Frame.waitForXPath
---
# Frame.waitForXPath() method
> Warning: This API is now obsolete.
>
> Use [Frame.waitForSelector()](./puppeteer.frame.waitforselector.md) with the `xpath` prefix.
>
> Example: `await frame.waitForSelector('xpath/' + xpathExpression)`
>
> The method evaluates the XPath expression relative to the Frame. If `xpath` starts with `//` instead of `.//`, the dot will be appended automatically.
>
> Wait for the `xpath` to appear in page. If at the moment of calling the method the `xpath` already exists, the method will return immediately. If the xpath doesn't appear after the `timeout` milliseconds of waiting, the function will throw.
>
> For a code example, see the example for [Frame.waitForSelector()](./puppeteer.frame.waitforselector.md). That function behaves identically other than taking a CSS selector rather than an XPath.
#### Signature:
```typescript
class Frame {
waitForXPath(
xpath: string,
options?: WaitForSelectorOptions
): Promise<ElementHandle<Node> | null>;
}
```
## Parameters
| Parameter | Type | Description |
| --------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| xpath | string | the XPath expression to wait for. |
| options | [WaitForSelectorOptions](./puppeteer.waitforselectoroptions.md) | _(Optional)_ options to configure the visibility of the element and how long to wait before timing out. |
**Returns:**
Promise&lt;[ElementHandle](./puppeteer.elementhandle.md)&lt;Node&gt; \| null&gt;

View File

@ -1,29 +0,0 @@
---
sidebar_label: Page.$x
---
# Page.$x() method
The method evaluates the XPath expression relative to the page document as its context node. If there are no such elements, the method resolves to an empty array.
#### Signature:
```typescript
class Page {
$x(expression: string): Promise<Array<ElementHandle<Node>>>;
}
```
## Parameters
| Parameter | Type | Description |
| ---------- | ------ | ---------------------- |
| expression | string | Expression to evaluate |
**Returns:**
Promise&lt;Array&lt;[ElementHandle](./puppeteer.elementhandle.md)&lt;Node&gt;&gt;&gt;
## Remarks
Shortcut for [Page.mainFrame().$x(expression)](./puppeteer.frame._x.md).

View File

@ -80,7 +80,6 @@ page.off('request', logRequest);
| [$$(selector)](./puppeteer.page.__.md) | | The method runs <code>document.querySelectorAll</code> within the page. If no elements match the selector, the return value resolves to <code>[]</code>. |
| [$$eval(selector, pageFunction, args)](./puppeteer.page.__eval.md) | | This method runs <code>Array.from(document.querySelectorAll(selector))</code> within the page and passes the result as the first argument to the <code>pageFunction</code>. |
| [$eval(selector, pageFunction, args)](./puppeteer.page._eval.md) | | This method runs <code>document.querySelector</code> within the page and passes the result as the first argument to the <code>pageFunction</code>. |
| [$x(expression)](./puppeteer.page._x.md) | | The method evaluates the XPath expression relative to the page document as its context node. If there are no such elements, the method resolves to an empty array. |
| [addScriptTag(options)](./puppeteer.page.addscripttag.md) | | Adds a <code>&lt;script&gt;</code> tag into the page with the desired URL or content. |
| [addStyleTag(options)](./puppeteer.page.addstyletag.md) | | <p>Adds a <code>&lt;link rel=&quot;stylesheet&quot;&gt;</code> tag into the page with the desired URL or a <code>&lt;style type=&quot;text/css&quot;&gt;</code> tag with the content.</p><p>Shortcut for [page.mainFrame().addStyleTag(options)](./puppeteer.frame.addstyletag_1.md).</p> |
| [addStyleTag(options)](./puppeteer.page.addstyletag_1.md) | | |
@ -161,5 +160,4 @@ page.off('request', logRequest);
| [waitForRequest(urlOrPredicate, options)](./puppeteer.page.waitforrequest.md) | | |
| [waitForResponse(urlOrPredicate, options)](./puppeteer.page.waitforresponse.md) | | |
| [waitForSelector(selector, options)](./puppeteer.page.waitforselector.md) | | Wait for the <code>selector</code> to appear in page. If at the moment of calling the method the <code>selector</code> already exists, the method will return immediately. If the <code>selector</code> doesn't appear after the <code>timeout</code> milliseconds of waiting, the function will throw. |
| [waitForXPath(xpath, options)](./puppeteer.page.waitforxpath.md) | | Wait for the <code>xpath</code> to appear in page. If at the moment of calling the method the <code>xpath</code> already exists, the method will return immediately. If the <code>xpath</code> doesn't appear after the <code>timeout</code> milliseconds of waiting, the function will throw. |
| [workers()](./puppeteer.page.workers.md) | | All of the dedicated [WebWorkers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) associated with the page. |

View File

@ -1,65 +0,0 @@
---
sidebar_label: Page.waitForXPath
---
# Page.waitForXPath() method
Wait for the `xpath` to appear in page. If at the moment of calling the method the `xpath` already exists, the method will return immediately. If the `xpath` doesn't appear after the `timeout` milliseconds of waiting, the function will throw.
#### Signature:
```typescript
class Page {
waitForXPath(
xpath: string,
options?: WaitForSelectorOptions
): Promise<ElementHandle<Node> | null>;
}
```
## Parameters
| Parameter | Type | Description |
| --------- | --------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| xpath | string | A [xpath](https://developer.mozilla.org/en-US/docs/Web/XPath) of an element to wait for |
| options | [WaitForSelectorOptions](./puppeteer.waitforselectoroptions.md) | _(Optional)_ Optional waiting parameters |
**Returns:**
Promise&lt;[ElementHandle](./puppeteer.elementhandle.md)&lt;Node&gt; \| null&gt;
Promise which resolves when element specified by xpath string is added to DOM. Resolves to `null` if waiting for `hidden: true` and xpath is not found in DOM, otherwise resolves to `ElementHandle`.
## Remarks
The optional Argument `options` have properties:
- `visible`: A boolean to wait for element to be present in DOM and to be visible, i.e. to not have `display: none` or `visibility: hidden` CSS properties. Defaults to `false`.
- `hidden`: A boolean wait for element to not be found in the DOM or to be hidden, i.e. have `display: none` or `visibility: hidden` CSS properties. Defaults to `false`.
- `timeout`: A number which is maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default value can be changed by using the [Page.setDefaultTimeout()](./puppeteer.page.setdefaulttimeout.md) method.
## Example
This method works across navigation
```ts
import puppeteer from 'puppeteer';
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
let currentURL;
page
.waitForXPath('//img')
.then(() => console.log('First URL with image: ' + currentURL));
for (currentURL of [
'https://example.com',
'https://google.com',
'https://bbc.com',
]) {
await page.goto(currentURL);
}
await browser.close();
})();
```

View File

@ -476,27 +476,6 @@ export abstract class ElementHandle<
return result;
}
/**
* @deprecated Use {@link ElementHandle.$$} with the `xpath` prefix.
*
* Example: `await elementHandle.$$('xpath/' + xpathExpression)`
*
* The method evaluates the XPath expression relative to the elementHandle.
* If `xpath` starts with `//` instead of `.//`, the dot will be appended
* automatically.
*
* If there are no such elements, the method will resolve to an empty array.
* @param expression - Expression to {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate | evaluate}
*/
@throwIfDisposed()
@ElementHandle.bindIsolatedHandle
async $x(expression: string): Promise<Array<ElementHandle<Node>>> {
if (expression.startsWith('//')) {
expression = `.${expression}`;
}
return await this.$$(`xpath/${expression}`);
}
/**
* Wait for an element matching the given selector to appear in the current
* element.
@ -581,84 +560,6 @@ export abstract class ElementHandle<
return await this.#checkVisibility(false);
}
/**
* @deprecated Use {@link ElementHandle.waitForSelector} with the `xpath`
* prefix.
*
* Example: `await elementHandle.waitForSelector('xpath/' + xpathExpression)`
*
* The method evaluates the XPath expression relative to the elementHandle.
*
* Wait for the `xpath` within the element. If at the moment of calling the
* method the `xpath` already exists, the method will return immediately. If
* the `xpath` doesn't appear after the `timeout` milliseconds of waiting, the
* function will throw.
*
* If `xpath` starts with `//` instead of `.//`, the dot will be appended
* automatically.
*
* @example
* This method works across navigation.
*
* ```ts
* import puppeteer from 'puppeteer';
* (async () => {
* const browser = await puppeteer.launch();
* const page = await browser.newPage();
* let currentURL;
* page
* .waitForXPath('//img')
* .then(() => console.log('First URL with image: ' + currentURL));
* for (currentURL of [
* 'https://example.com',
* 'https://google.com',
* 'https://bbc.com',
* ]) {
* await page.goto(currentURL);
* }
* await browser.close();
* })();
* ```
*
* @param xpath - A
* {@link https://developer.mozilla.org/en-US/docs/Web/XPath | xpath} of an
* element to wait for
* @param options - Optional waiting parameters
* @returns Promise which resolves when element specified by xpath string is
* added to DOM. Resolves to `null` if waiting for `hidden: true` and xpath is
* not found in DOM, otherwise resolves to `ElementHandle`.
* @remarks
* The optional Argument `options` have properties:
*
* - `visible`: A boolean to wait for element to be present in DOM and to be
* visible, i.e. to not have `display: none` or `visibility: hidden` CSS
* properties. Defaults to `false`.
*
* - `hidden`: A boolean wait for element to not be found in the DOM or to be
* hidden, i.e. have `display: none` or `visibility: hidden` CSS properties.
* Defaults to `false`.
*
* - `timeout`: A number which is maximum time to wait for in milliseconds.
* Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The
* default value can be changed by using the {@link Page.setDefaultTimeout}
* method.
*/
@throwIfDisposed()
@ElementHandle.bindIsolatedHandle
async waitForXPath(
xpath: string,
options: {
visible?: boolean;
hidden?: boolean;
timeout?: number;
} = {}
): Promise<ElementHandle<Node> | null> {
if (xpath.startsWith('//')) {
xpath = `.${xpath}`;
}
return await this.waitForSelector(`xpath/${xpath}`, options);
}
/**
* Converts the current handle to the given element type.
*

View File

@ -623,23 +623,6 @@ export abstract class Frame extends EventEmitter<FrameEvents> {
return await document.$$eval(selector, pageFunction, ...args);
}
/**
* @deprecated Use {@link Frame.$$} with the `xpath` prefix.
*
* Example: `await frame.$$('xpath/' + xpathExpression)`
*
* This method evaluates the given XPath expression and returns the results.
* If `xpath` starts with `//` instead of `.//`, the dot will be appended
* automatically.
* @param expression - the XPath expression to evaluate.
*/
@throwIfDetached
async $x(expression: string): Promise<Array<ElementHandle<Node>>> {
// eslint-disable-next-line rulesdir/use-using -- This is cached.
const document = await this.#document();
return await document.$x(expression);
}
/**
* Waits for an element matching the given selector to appear in the frame.
*
@ -689,39 +672,6 @@ export abstract class Frame extends EventEmitter<FrameEvents> {
)) as ElementHandle<NodeFor<Selector>> | null;
}
/**
* @deprecated Use {@link Frame.waitForSelector} with the `xpath` prefix.
*
* Example: `await frame.waitForSelector('xpath/' + xpathExpression)`
*
* The method evaluates the XPath expression relative to the Frame.
* If `xpath` starts with `//` instead of `.//`, the dot will be appended
* automatically.
*
* Wait for the `xpath` to appear in page. If at the moment of calling the
* method the `xpath` already exists, the method will return immediately. If
* the xpath doesn't appear after the `timeout` milliseconds of waiting, the
* function will throw.
*
* For a code example, see the example for {@link Frame.waitForSelector}. That
* function behaves identically other than taking a CSS selector rather than
* an XPath.
*
* @param xpath - the XPath expression to wait for.
* @param options - options to configure the visibility of the element and how
* long to wait before timing out.
*/
@throwIfDetached
async waitForXPath(
xpath: string,
options: WaitForSelectorOptions = {}
): Promise<ElementHandle<Node> | null> {
if (xpath.startsWith('//')) {
xpath = `.${xpath}`;
}
return await this.waitForSelector(`xpath/${xpath}`, options);
}
/**
* @example
* The `waitForFunction` can be used to observe viewport size change:

View File

@ -1290,20 +1290,6 @@ export abstract class Page extends EventEmitter<PageEvents> {
return await this.mainFrame().$$eval(selector, pageFunction, ...args);
}
/**
* The method evaluates the XPath expression relative to the page document as
* its context node. If there are no such elements, the method resolves to an
* empty array.
*
* @remarks
* Shortcut for {@link Frame.$x | Page.mainFrame().$x(expression) }.
*
* @param expression - Expression to evaluate
*/
async $x(expression: string): Promise<Array<ElementHandle<Node>>> {
return await this.mainFrame().$x(expression);
}
/**
* If no URLs are specified, this method returns cookies for the current page
* URL. If URLs are specified, only cookies for those URLs are returned.
@ -2843,64 +2829,6 @@ export abstract class Page extends EventEmitter<PageEvents> {
return await this.mainFrame().waitForSelector(selector, options);
}
/**
* Wait for the `xpath` to appear in page. If at the moment of calling the
* method the `xpath` already exists, the method will return immediately. If
* the `xpath` doesn't appear after the `timeout` milliseconds of waiting, the
* function will throw.
*
* @example
* This method works across navigation
*
* ```ts
* import puppeteer from 'puppeteer';
* (async () => {
* const browser = await puppeteer.launch();
* const page = await browser.newPage();
* let currentURL;
* page
* .waitForXPath('//img')
* .then(() => console.log('First URL with image: ' + currentURL));
* for (currentURL of [
* 'https://example.com',
* 'https://google.com',
* 'https://bbc.com',
* ]) {
* await page.goto(currentURL);
* }
* await browser.close();
* })();
* ```
*
* @param xpath - A
* {@link https://developer.mozilla.org/en-US/docs/Web/XPath | xpath} of an
* element to wait for
* @param options - Optional waiting parameters
* @returns Promise which resolves when element specified by xpath string is
* added to DOM. Resolves to `null` if waiting for `hidden: true` and xpath is
* not found in DOM, otherwise resolves to `ElementHandle`.
* @remarks
* The optional Argument `options` have properties:
*
* - `visible`: A boolean to wait for element to be present in DOM and to be
* visible, i.e. to not have `display: none` or `visibility: hidden` CSS
* properties. Defaults to `false`.
*
* - `hidden`: A boolean wait for element to not be found in the DOM or to be
* hidden, i.e. have `display: none` or `visibility: hidden` CSS properties.
* Defaults to `false`.
*
* - `timeout`: A number which is maximum time to wait for in milliseconds.
* Defaults to `30000` (30 seconds). Pass `0` to disable timeout. The default
* value can be changed by using the {@link Page.setDefaultTimeout} method.
*/
waitForXPath(
xpath: string,
options?: WaitForSelectorOptions
): Promise<ElementHandle<Node> | null> {
return this.mainFrame().waitForXPath(xpath, options);
}
/**
* Waits for the provided function, `pageFunction`, to return a truthy value when
* evaluated in the page's context.

View File

@ -3704,25 +3704,25 @@
"expectations": ["SKIP"]
},
{
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForXPath should run in specified frame",
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector xpath should run in specified frame",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["PASS"]
},
{
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForXPath should run in specified frame",
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector xpath should run in specified frame",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
"expectations": ["SKIP"]
},
{
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForXPath should throw when frame is detached",
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector xpath should throw when frame is detached",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["PASS"]
},
{
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForXPath should throw when frame is detached",
"testIdPattern": "[waittask.spec] waittask specs Frame.waitForSelector xpath should throw when frame is detached",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
"expectations": ["SKIP"]

View File

@ -472,10 +472,8 @@ describe('ElementHandle specs', function () {
})
).toStrictEqual('bar1');
});
});
describe('Element.waitForXPath', () => {
it('should wait correctly with waitForXPath on an element', async () => {
it('should wait correctly with waitForSelector and xpath on an element', async () => {
const {page} = await getTestState();
// Set the page content after the waitFor has been started.
await page.setContent(
@ -490,20 +488,18 @@ describe('ElementHandle specs', function () {
</div>`
);
using el1 = (await page.waitForSelector(
using elById = (await page.waitForSelector(
'#el1'
)) as ElementHandle<HTMLDivElement>;
for (const path of ['//div', './/div']) {
using e = (await el1.waitForXPath(
path
using elByXpath = (await elById.waitForSelector(
'xpath/.//div'
)) as ElementHandle<HTMLDivElement>;
expect(
await e.evaluate(el => {
await elByXpath.evaluate(el => {
return el.id;
})
).toStrictEqual('el2');
}
});
});

View File

@ -174,31 +174,31 @@ describe('querySelector', function () {
const elements = await page.$$('div');
expect(elements).toHaveLength(0);
});
});
describe('Page.$x', function () {
describe('xpath', function () {
it('should query existing element', async () => {
const {page} = await getTestState();
await page.setContent('<section>test</section>');
const elements = await page.$x('/html/body/section');
const elements = await page.$$('xpath/html/body/section');
expect(elements[0]).toBeTruthy();
expect(elements).toHaveLength(1);
});
it('should return empty array for non-existing element', async () => {
const {page} = await getTestState();
const element = await page.$x('/html/body/non-existing-element');
const element = await page.$$('xpath/html/body/non-existing-element');
expect(element).toEqual([]);
});
it('should return multiple elements', async () => {
const {page} = await getTestState();
await page.setContent('<div></div><div></div>');
const elements = await page.$x('/html/body/div');
const elements = await page.$$('xpath/html/body/div');
expect(elements).toHaveLength(2);
});
});
});
describe('ElementHandle.$', function () {
it('should query existing element', async () => {
@ -347,9 +347,8 @@ describe('querySelector', function () {
const elements = await html.$$('div');
expect(elements).toHaveLength(0);
});
});
describe('ElementHandle.$x', function () {
describe('xpath', function () {
it('should query existing element', async () => {
const {page, server} = await getTestState();
@ -358,8 +357,12 @@ describe('querySelector', function () {
'<html><body><div class="second"><div class="inner">A</div></div></body></html>'
);
using html = (await page.$('html'))!;
const second = await html.$x(`./body/div[contains(@class, 'second')]`);
const inner = await second[0]!.$x(`./div[contains(@class, 'inner')]`);
const second = await html.$$(
`xpath/./body/div[contains(@class, 'second')]`
);
const inner = await second[0]!.$$(
`xpath/./div[contains(@class, 'inner')]`
);
const content = await page.evaluate(e => {
return e.textContent;
}, inner[0]!);
@ -373,11 +376,11 @@ describe('querySelector', function () {
'<html><body><div class="second"><div class="inner">B</div></div></body></html>'
);
using html = (await page.$('html'))!;
const second = await html.$x(`/div[contains(@class, 'third')]`);
const second = await html.$$(`xpath/div[contains(@class, 'third')]`);
expect(second).toEqual([]);
});
});
});
// This is the same tests for `$$eval` and `$$` as above, but with a queryAll
// handler that returns an array instead of a list of nodes.
describe('QueryAll', function () {

View File

@ -693,9 +693,8 @@ describe('waittask specs', function () {
// The extension is ts here as Mocha maps back via sourcemaps.
expect(error?.stack).toContain('WaitTask.ts');
});
});
describe('Frame.waitForXPath', function () {
describe('xpath', function () {
const addElement = (tag: string) => {
return document.body.appendChild(document.createElement(tag));
};
@ -704,15 +703,15 @@ describe('waittask specs', function () {
const {page} = await getTestState();
await page.setContent(`<p>red herring</p><p>hello world </p>`);
const waitForXPath = page.waitForXPath(
'//p[normalize-space(.)="hello world"]'
const waitForSelector = page.waitForSelector(
'xpath/.//p[normalize-space(.)="hello world"]'
);
expect(
await page.evaluate(
x => {
return x?.textContent;
},
await waitForXPath
await waitForSelector
)
).toBe('hello world ');
});
@ -720,7 +719,9 @@ describe('waittask specs', function () {
const {page} = await getTestState();
let error!: Error;
await page.waitForXPath('//div', {timeout: 10}).catch(error_ => {
await page
.waitForSelector('xpath/.//div', {timeout: 10})
.catch(error_ => {
return (error = error_);
});
expect(error).toBeInstanceOf(TimeoutError);
@ -733,10 +734,10 @@ describe('waittask specs', function () {
await attachFrame(page, 'frame2', server.EMPTY_PAGE);
const frame1 = page.frames()[1]!;
const frame2 = page.frames()[2]!;
const waitForXPathPromise = frame2.waitForXPath('//div');
const waitForSelector = frame2.waitForSelector('xpath/.//div');
await frame1.evaluate(addElement, 'div');
await frame2.evaluate(addElement, 'div');
using eHandle = await waitForXPathPromise;
using eHandle = await waitForSelector;
expect(eHandle?.frame).toBe(frame2);
});
it('should throw when frame is detached', async () => {
@ -746,7 +747,7 @@ describe('waittask specs', function () {
const frame = page.frames()[1]!;
let waitError: Error | undefined;
const waitPromise = frame
.waitForXPath('//*[@class="box"]')
.waitForSelector('xpath/.//*[@class="box"]')
.catch(error => {
return (waitError = error);
});
@ -762,48 +763,54 @@ describe('waittask specs', function () {
let divHidden = false;
await page.setContent(`<div style='display: block;'>text</div>`);
const waitForXPath = page
.waitForXPath('//div', {hidden: true})
const waitForSelector = page
.waitForSelector('xpath/.//div', {hidden: true})
.then(() => {
return (divHidden = true);
});
await page.waitForXPath('//div'); // do a round trip
await page.waitForSelector('xpath/.//div'); // do a round trip
expect(divHidden).toBe(false);
await page.evaluate(() => {
return document
.querySelector('div')
?.style.setProperty('display', 'none');
});
expect(await waitForXPath).toBe(true);
expect(await waitForSelector).toBe(true);
expect(divHidden).toBe(true);
});
it('hidden should return null if the element is not found', async () => {
const {page} = await getTestState();
using waitForXPath = await page.waitForXPath('//div', {hidden: true});
using waitForSelector = await page.waitForSelector('xpath/.//div', {
hidden: true,
});
expect(waitForXPath).toBe(null);
expect(waitForSelector).toBe(null);
});
it('hidden should return an empty element handle if the element is found', async () => {
const {page} = await getTestState();
await page.setContent(`<div style='display: none;'>text</div>`);
using waitForXPath = await page.waitForXPath('//div', {hidden: true});
using waitForSelector = await page.waitForSelector('xpath/.//div', {
hidden: true,
});
expect(waitForXPath).toBeInstanceOf(ElementHandle);
expect(waitForSelector).toBeInstanceOf(ElementHandle);
});
it('should return the element handle', async () => {
const {page} = await getTestState();
const waitForXPath = page.waitForXPath('//*[@class="zombo"]');
const waitForSelector = page.waitForSelector(
'xpath/.//*[@class="zombo"]'
);
await page.setContent(`<div class='zombo'>anything</div>`);
expect(
await page.evaluate(
x => {
return x?.textContent;
},
await waitForXPath
await waitForSelector
)
).toBe('anything');
});
@ -811,7 +818,7 @@ describe('waittask specs', function () {
const {page} = await getTestState();
await page.setContent(`<div>some text</div>`);
using text = await page.waitForXPath('//div/text()');
using text = await page.waitForSelector('xpath/.//div/text()');
expect(await (await text!.getProperty('nodeType')!).jsonValue()).toBe(
3 /* Node.TEXT_NODE */
);
@ -820,15 +827,16 @@ describe('waittask specs', function () {
const {page} = await getTestState();
await page.setContent(`<div>some text</div>`);
const waitForXPath = page.waitForXPath('/html/body/div');
const waitForSelector = page.waitForSelector('xpath/html/body/div');
expect(
await page.evaluate(
x => {
return x?.textContent;
},
await waitForXPath
await waitForSelector
)
).toBe('some text');
});
});
});
});

View File

@ -30,7 +30,7 @@ Promise&lt;void&gt;
## Remarks
It's generally recommended to not wait for a number of seconds, but instead use [Frame.waitForSelector()](./puppeteer.frame.waitforselector.md), [Frame.waitForXPath()](./puppeteer.frame.waitforxpath.md) or [Frame.waitForFunction()](./puppeteer.frame.waitforfunction.md) to wait for exactly the conditions you want.
It's generally recommended to not wait for a number of seconds, but instead use [Frame.waitForSelector()](./puppeteer.frame.waitforselector.md), or [Frame.waitForFunction()](./puppeteer.frame.waitforfunction.md) to wait for exactly the conditions you want.
## Example

View File

@ -30,7 +30,7 @@ Promise&lt;void&gt;
## Remarks
It's generally recommended to not wait for a number of seconds, but instead use [Frame.waitForSelector()](./puppeteer.frame.waitforselector.md), [Frame.waitForXPath()](./puppeteer.frame.waitforxpath.md) or [Frame.waitForFunction()](./puppeteer.frame.waitforfunction.md) to wait for exactly the conditions you want.
It's generally recommended to not wait for a number of seconds, but instead use [Frame.waitForSelector()](./puppeteer.frame.waitforselector.md), or [Frame.waitForFunction()](./puppeteer.frame.waitforfunction.md) to wait for exactly the conditions you want.
## Example