feat(locators): introduce allTextContents, allInnerTexts (#7920)

This commit is contained in:
Pavel Feldman 2021-07-29 14:09:35 -07:00 committed by GitHub
parent dd0b089d13
commit 2c095294c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 12 deletions

View File

@ -95,6 +95,16 @@ await locator.HoverAsync();
await locator.ClickAsync();
```
## async method: Locator.allInnerTexts
- returns: <[Array]<[string]>>
Returns an array of `node.innerText` values for all matching nodes.
## async method: Locator.allTextContents
- returns: <[Array]<[string]>>
Returns an array of `node.textContent` values for all matching nodes.
## async method: Locator.boundingBox
- returns: <[null]|[Object]>
- `x` <[float]> the x coordinate of the element in pixels.

View File

@ -200,6 +200,14 @@ export class Locator implements api.Locator {
return this._frame.uncheck(this._selector, { strict: true, ...options });
}
async allInnerTexts(): Promise<string[]> {
return this._frame.$$eval(this._selector, ee => ee.map(e => (e as HTMLElement).innerText));
}
async allTextContents(): Promise<string[]> {
return this._frame.$$eval(this._selector, ee => ee.map(e => e.textContent || ''));
}
[(util.inspect as any).custom]() {
return this.toString();
}

View File

@ -47,25 +47,25 @@ it('inputValue should work', async ({ page, server }) => {
await page.fill('#input', 'input value');
expect(await page.inputValue('#input')).toBe('input value');
const handle = page.locator('#input');
expect(await handle.inputValue()).toBe('input value');
const locator = page.locator('#input');
expect(await locator.inputValue()).toBe('input value');
expect(await page.inputValue('#inner').catch(e => e.message)).toContain('Node is not an HTMLInputElement or HTMLTextAreaElement');
const handle2 = page.locator('#inner');
expect(await handle2.inputValue().catch(e => e.message)).toContain('Node is not an HTMLInputElement or HTMLTextAreaElement');
const locator2 = page.locator('#inner');
expect(await locator2.inputValue().catch(e => e.message)).toContain('Node is not an HTMLInputElement or HTMLTextAreaElement');
});
it('innerHTML should work', async ({ page, server }) => {
await page.goto(`${server.PREFIX}/dom.html`);
const handle = page.locator('#outer');
expect(await handle.innerHTML()).toBe('<div id="inner">Text,\nmore text</div>');
const locator = page.locator('#outer');
expect(await locator.innerHTML()).toBe('<div id="inner">Text,\nmore text</div>');
expect(await page.innerHTML('#outer')).toBe('<div id="inner">Text,\nmore text</div>');
});
it('innerText should work', async ({ page, server }) => {
await page.goto(`${server.PREFIX}/dom.html`);
const handle = page.locator('#inner');
expect(await handle.innerText()).toBe('Text, more text');
const locator = page.locator('#inner');
expect(await locator.innerText()).toBe('Text, more text');
expect(await page.innerText('#inner')).toBe('Text, more text');
});
@ -73,15 +73,15 @@ it('innerText should throw', async ({ page, server }) => {
await page.setContent(`<svg>text</svg>`);
const error1 = await page.innerText('svg').catch(e => e);
expect(error1.message).toContain('Not an HTMLElement');
const handle = page.locator('svg');
const error2 = await handle.innerText().catch(e => e);
const locator = page.locator('svg');
const error2 = await locator.innerText().catch(e => e);
expect(error2.message).toContain('Not an HTMLElement');
});
it('textContent should work', async ({ page, server }) => {
await page.goto(`${server.PREFIX}/dom.html`);
const handle = page.locator('#inner');
expect(await handle.textContent()).toBe('Text,\nmore text');
const locator = page.locator('#inner');
expect(await locator.textContent()).toBe('Text,\nmore text');
expect(await page.textContent('#inner')).toBe('Text,\nmore text');
});
@ -196,3 +196,13 @@ it('isChecked should work', async ({page}) => {
const error = await page.isChecked('div').catch(e => e);
expect(error.message).toContain('Not a checkbox or radio button');
});
it('addTextContents should work', async ({page}) => {
await page.setContent(`<div>A</div><div>B</div><div>C</div>`);
expect(await page.locator('div').allTextContents()).toEqual(['A', 'B', 'C']);
});
it('addInnerTexts should work', async ({page}) => {
await page.setContent(`<div>A</div><div>B</div><div>C</div>`);
expect(await page.locator('div').allInnerTexts()).toEqual(['A', 'B', 'C']);
});

10
types/types.d.ts vendored
View File

@ -7047,6 +7047,16 @@ export interface Locator {
elementHandle(options?: {
timeout?: number;
}): Promise<null|ElementHandle<SVGElement | HTMLElement>>;
/**
* Returns an array of `node.innerText` values for all matching nodes.
*/
allInnerTexts(): Promise<Array<string>>;
/**
* Returns an array of `node.textContent` values for all matching nodes.
*/
allTextContents(): Promise<Array<string>>;
/**
* This method returns the bounding box of the element, or `null` if the element is not visible. The bounding box is
* calculated relative to the main frame viewport - which is usually the same as the browser window.