mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
feat(inputValue): implement inputValue for select elements (#7951)
This commit is contained in:
parent
7c3a037b86
commit
731f9453c5
@ -516,7 +516,7 @@ Returns the `element.innerText`.
|
|||||||
## async method: ElementHandle.inputValue
|
## async method: ElementHandle.inputValue
|
||||||
- returns: <[string]>
|
- returns: <[string]>
|
||||||
|
|
||||||
Returns `input.value` for `<input>` or `<textarea>` element. Throws for non-input elements.
|
Returns `input.value` for `<input>` or `<textarea>` or `<select>` element. Throws for non-input elements.
|
||||||
|
|
||||||
### option: ElementHandle.inputValue.timeout = %%-input-timeout-%%
|
### option: ElementHandle.inputValue.timeout = %%-input-timeout-%%
|
||||||
|
|
||||||
|
@ -855,7 +855,7 @@ Returns `element.innerText`.
|
|||||||
## async method: Frame.inputValue
|
## async method: Frame.inputValue
|
||||||
- returns: <[string]>
|
- returns: <[string]>
|
||||||
|
|
||||||
Returns `input.value` for the selected `<input>` or `<textarea>` element. Throws for non-input elements.
|
Returns `input.value` for the selected `<input>` or `<textarea>` or `<select>` element. Throws for non-input elements.
|
||||||
|
|
||||||
### param: Frame.inputValue.selector = %%-input-selector-%%
|
### param: Frame.inputValue.selector = %%-input-selector-%%
|
||||||
|
|
||||||
|
@ -520,7 +520,7 @@ Returns the `element.innerText`.
|
|||||||
## async method: Locator.inputValue
|
## async method: Locator.inputValue
|
||||||
- returns: <[string]>
|
- returns: <[string]>
|
||||||
|
|
||||||
Returns `input.value` for `<input>` or `<textarea>` element. Throws for non-input elements.
|
Returns `input.value` for `<input>` or `<textarea>` or `<select>` element. Throws for non-input elements.
|
||||||
|
|
||||||
### option: Locator.inputValue.timeout = %%-input-timeout-%%
|
### option: Locator.inputValue.timeout = %%-input-timeout-%%
|
||||||
|
|
||||||
|
@ -1961,7 +1961,7 @@ Returns `element.innerText`.
|
|||||||
## async method: Page.inputValue
|
## async method: Page.inputValue
|
||||||
- returns: <[string]>
|
- returns: <[string]>
|
||||||
|
|
||||||
Returns `input.value` for the selected `<input>` or `<textarea>` element. Throws for non-input elements.
|
Returns `input.value` for the selected `<input>` or `<textarea>` or `<select>` element. Throws for non-input elements.
|
||||||
|
|
||||||
### param: Page.inputValue.selector = %%-input-selector-%%
|
### param: Page.inputValue.selector = %%-input-selector-%%
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ export type FatalDOMError =
|
|||||||
'error:notfillablenumberinput' |
|
'error:notfillablenumberinput' |
|
||||||
'error:notvaliddate' |
|
'error:notvaliddate' |
|
||||||
'error:notinput' |
|
'error:notinput' |
|
||||||
'error:notinputvalue' |
|
'error:hasnovalue' |
|
||||||
'error:notselect' |
|
'error:notselect' |
|
||||||
'error:notcheckbox' |
|
'error:notcheckbox' |
|
||||||
'error:notmultiplefileinput';
|
'error:notmultiplefileinput';
|
||||||
|
@ -181,8 +181,8 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||||||
|
|
||||||
async inputValue(): Promise<string> {
|
async inputValue(): Promise<string> {
|
||||||
return throwFatalDOMError(await this.evaluateInUtility(([injeced, node]) => {
|
return throwFatalDOMError(await this.evaluateInUtility(([injeced, node]) => {
|
||||||
if (node.nodeType !== Node.ELEMENT_NODE || (node.nodeName !== 'INPUT' && node.nodeName !== 'TEXTAREA'))
|
if (node.nodeType !== Node.ELEMENT_NODE || (node.nodeName !== 'INPUT' && node.nodeName !== 'TEXTAREA' && node.nodeName !== 'SELECT'))
|
||||||
return 'error:notinputvalue';
|
return 'error:hasnovalue';
|
||||||
const element = node as unknown as (HTMLInputElement | HTMLTextAreaElement);
|
const element = node as unknown as (HTMLInputElement | HTMLTextAreaElement);
|
||||||
return { value: element.value };
|
return { value: element.value };
|
||||||
}, undefined)).value;
|
}, undefined)).value;
|
||||||
@ -883,8 +883,8 @@ export function throwFatalDOMError<T>(result: T | FatalDOMError): T {
|
|||||||
throw new Error(`Malformed value`);
|
throw new Error(`Malformed value`);
|
||||||
if (result === 'error:notinput')
|
if (result === 'error:notinput')
|
||||||
throw new Error('Node is not an HTMLInputElement');
|
throw new Error('Node is not an HTMLInputElement');
|
||||||
if (result === 'error:notinputvalue')
|
if (result === 'error:hasnovalue')
|
||||||
throw new Error('Node is not an HTMLInputElement or HTMLTextAreaElement');
|
throw new Error('Node is not an HTMLInputElement or HTMLTextAreaElement or HTMLSelectElement');
|
||||||
if (result === 'error:notselect')
|
if (result === 'error:notselect')
|
||||||
throw new Error('Element is not a <select> element.');
|
throw new Error('Element is not a <select> element.');
|
||||||
if (result === 'error:notcheckbox')
|
if (result === 'error:notcheckbox')
|
||||||
@ -1039,8 +1039,8 @@ export function inputValueTask(selector: SelectorInfo): SchedulableTask<string>
|
|||||||
if (!element)
|
if (!element)
|
||||||
return continuePolling;
|
return continuePolling;
|
||||||
progress.log(` selector resolved to ${injected.previewNode(element)}`);
|
progress.log(` selector resolved to ${injected.previewNode(element)}`);
|
||||||
if (element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA')
|
if (element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA' && element.nodeName !== 'SELECT')
|
||||||
return 'error:notinputvalue';
|
return 'error:hasnovalue';
|
||||||
return (element as any).value;
|
return (element as any).value;
|
||||||
});
|
});
|
||||||
}, { parsed: selector.parsed, strict: selector.strict, });
|
}, { parsed: selector.parsed, strict: selector.strict, });
|
||||||
|
@ -2,3 +2,4 @@
|
|||||||
more text</div></div><input id="check" type=checkbox checked foo="bar"">
|
more text</div></div><input id="check" type=checkbox checked foo="bar"">
|
||||||
<input id="input"></input>
|
<input id="input"></input>
|
||||||
<textarea id="textarea"></textarea>
|
<textarea id="textarea"></textarea>
|
||||||
|
<select id="select"><option></option><option value="foo"></option></select>
|
||||||
|
@ -42,6 +42,9 @@ it('getAttribute should work', async ({ page, server }) => {
|
|||||||
it('inputValue should work', async ({ page, server }) => {
|
it('inputValue should work', async ({ page, server }) => {
|
||||||
await page.goto(`${server.PREFIX}/dom.html`);
|
await page.goto(`${server.PREFIX}/dom.html`);
|
||||||
|
|
||||||
|
await page.selectOption('#select', 'foo');
|
||||||
|
expect(await page.inputValue('#select')).toBe('foo');
|
||||||
|
|
||||||
await page.fill('#textarea', 'text value');
|
await page.fill('#textarea', 'text value');
|
||||||
expect(await page.inputValue('#textarea')).toBe('text value');
|
expect(await page.inputValue('#textarea')).toBe('text value');
|
||||||
|
|
||||||
@ -50,9 +53,9 @@ it('inputValue should work', async ({ page, server }) => {
|
|||||||
const handle = await page.$('#input');
|
const handle = await page.$('#input');
|
||||||
expect(await handle.inputValue()).toBe('input value');
|
expect(await handle.inputValue()).toBe('input value');
|
||||||
|
|
||||||
expect(await page.inputValue('#inner').catch(e => e.message)).toContain('Node is not an HTMLInputElement or HTMLTextAreaElement');
|
expect(await page.inputValue('#inner').catch(e => e.message)).toContain('Node is not an HTMLInputElement or HTMLTextAreaElement or HTMLSelectElement');
|
||||||
const handle2 = await page.$('#inner');
|
const handle2 = await page.$('#inner');
|
||||||
expect(await handle2.inputValue().catch(e => e.message)).toContain('Node is not an HTMLInputElement or HTMLTextAreaElement');
|
expect(await handle2.inputValue().catch(e => e.message)).toContain('Node is not an HTMLInputElement or HTMLTextAreaElement or HTMLSelectElement');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('innerHTML should work', async ({ page, server }) => {
|
it('innerHTML should work', async ({ page, server }) => {
|
||||||
|
@ -42,6 +42,9 @@ it('getAttribute should work', async ({ page, server }) => {
|
|||||||
it('inputValue should work', async ({ page, server }) => {
|
it('inputValue should work', async ({ page, server }) => {
|
||||||
await page.goto(`${server.PREFIX}/dom.html`);
|
await page.goto(`${server.PREFIX}/dom.html`);
|
||||||
|
|
||||||
|
await page.selectOption('#select', 'foo');
|
||||||
|
expect(await page.inputValue('#select')).toBe('foo');
|
||||||
|
|
||||||
await page.fill('#textarea', 'text value');
|
await page.fill('#textarea', 'text value');
|
||||||
expect(await page.inputValue('#textarea')).toBe('text value');
|
expect(await page.inputValue('#textarea')).toBe('text value');
|
||||||
|
|
||||||
@ -50,9 +53,9 @@ it('inputValue should work', async ({ page, server }) => {
|
|||||||
const locator = page.locator('#input');
|
const locator = page.locator('#input');
|
||||||
expect(await locator.inputValue()).toBe('input value');
|
expect(await locator.inputValue()).toBe('input value');
|
||||||
|
|
||||||
expect(await page.inputValue('#inner').catch(e => e.message)).toContain('Node is not an HTMLInputElement or HTMLTextAreaElement');
|
expect(await page.inputValue('#inner').catch(e => e.message)).toContain('Node is not an HTMLInputElement or HTMLTextAreaElement or HTMLSelectElement');
|
||||||
const locator2 = page.locator('#inner');
|
const locator2 = page.locator('#inner');
|
||||||
expect(await locator2.inputValue().catch(e => e.message)).toContain('Node is not an HTMLInputElement or HTMLTextAreaElement');
|
expect(await locator2.inputValue().catch(e => e.message)).toContain('Node is not an HTMLInputElement or HTMLTextAreaElement or HTMLSelectElement');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('innerHTML should work', async ({ page, server }) => {
|
it('innerHTML should work', async ({ page, server }) => {
|
||||||
|
8
types/types.d.ts
vendored
8
types/types.d.ts
vendored
@ -1890,7 +1890,7 @@ export interface Page {
|
|||||||
}): Promise<string>;
|
}): Promise<string>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns `input.value` for the selected `<input>` or `<textarea>` element. Throws for non-input elements.
|
* Returns `input.value` for the selected `<input>` or `<textarea>` or `<select>` element. Throws for non-input elements.
|
||||||
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be used. See [working with selectors](https://playwright.dev/docs/selectors) for more details.
|
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be used. See [working with selectors](https://playwright.dev/docs/selectors) for more details.
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
@ -4141,7 +4141,7 @@ export interface Frame {
|
|||||||
}): Promise<string>;
|
}): Promise<string>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns `input.value` for the selected `<input>` or `<textarea>` element. Throws for non-input elements.
|
* Returns `input.value` for the selected `<input>` or `<textarea>` or `<select>` element. Throws for non-input elements.
|
||||||
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be used. See [working with selectors](https://playwright.dev/docs/selectors) for more details.
|
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be used. See [working with selectors](https://playwright.dev/docs/selectors) for more details.
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
@ -6461,7 +6461,7 @@ export interface ElementHandle<T=Node> extends JSHandle<T> {
|
|||||||
innerText(): Promise<string>;
|
innerText(): Promise<string>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns `input.value` for `<input>` or `<textarea>` element. Throws for non-input elements.
|
* Returns `input.value` for `<input>` or `<textarea>` or `<select>` element. Throws for non-input elements.
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
inputValue(options?: {
|
inputValue(options?: {
|
||||||
@ -7543,7 +7543,7 @@ export interface Locator {
|
|||||||
}): Promise<string>;
|
}): Promise<string>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns `input.value` for `<input>` or `<textarea>` element. Throws for non-input elements.
|
* Returns `input.value` for `<input>` or `<textarea>` or `<select>` element. Throws for non-input elements.
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
inputValue(options?: {
|
inputValue(options?: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user