feat(inputValue): allow on labels, retarget (#10666)
This commit is contained in:
parent
15b92e3f62
commit
2ac9c08d0c
|
|
@ -199,10 +199,10 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||
|
||||
async inputValue(): Promise<string> {
|
||||
return throwRetargetableDOMError(await this.evaluateInUtility(([injected, node]) => {
|
||||
if (node.nodeType !== Node.ELEMENT_NODE || (node.nodeName !== 'INPUT' && node.nodeName !== 'TEXTAREA' && node.nodeName !== 'SELECT'))
|
||||
const element = injected.retarget(node, 'follow-label');
|
||||
if (!element || (element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA' && element.nodeName !== 'SELECT'))
|
||||
throw injected.createStacklessError('Node is not an <input>, <textarea> or <select> element');
|
||||
const element = node as unknown as (HTMLInputElement | HTMLTextAreaElement);
|
||||
return { value: element.value };
|
||||
return { value: (element as HTMLInputElement | HTMLTextAreaElement).value };
|
||||
}, undefined)).value;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1117,8 +1117,9 @@ export class Frame extends SdkObject {
|
|||
}
|
||||
|
||||
async inputValue(metadata: CallMetadata, selector: string, options: types.TimeoutOptions & types.StrictOptions = {}): Promise<string> {
|
||||
return this._scheduleRerunnableTask(metadata, selector, (progress, element) => {
|
||||
if (element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA' && element.nodeName !== 'SELECT')
|
||||
return this._scheduleRerunnableTask(metadata, selector, (progress, node) => {
|
||||
const element = progress.injectedScript.retarget(node, 'follow-label');
|
||||
if (!element || (element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA' && element.nodeName !== 'SELECT'))
|
||||
throw progress.injectedScript.createStacklessError('Node is not an <input>, <textarea> or <select> element');
|
||||
return (element as any).value;
|
||||
}, undefined, options);
|
||||
|
|
|
|||
|
|
@ -954,6 +954,7 @@ export class InjectedScript {
|
|||
} else if (expression === 'to.have.url') {
|
||||
received = document.location.href;
|
||||
} else if (expression === 'to.have.value') {
|
||||
element = this.retarget(element, 'follow-label')!;
|
||||
if (element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA' && element.nodeName !== 'SELECT')
|
||||
throw this.createStacklessError('Not an input element');
|
||||
received = (element as any).value;
|
||||
|
|
|
|||
|
|
@ -58,6 +58,13 @@ it('inputValue should work', async ({ page, server }) => {
|
|||
expect(await handle2.inputValue().catch(e => e.message)).toContain('Node is not an <input>, <textarea> or <select> element');
|
||||
});
|
||||
|
||||
it('inputValue should work on label', async ({ page, server }) => {
|
||||
await page.setContent(`<label><input type=text></input></label>`);
|
||||
await page.fill('input', 'foo');
|
||||
const handle = await page.$('label');
|
||||
expect(await handle.inputValue()).toBe('foo');
|
||||
});
|
||||
|
||||
it('innerHTML should work', async ({ page, server }) => {
|
||||
await page.goto(`${server.PREFIX}/dom.html`);
|
||||
const handle = await page.$('#outer');
|
||||
|
|
|
|||
|
|
@ -58,6 +58,12 @@ it('inputValue should work', async ({ page, server }) => {
|
|||
expect(await locator2.inputValue().catch(e => e.message)).toContain('Node is not an <input>, <textarea> or <select> element');
|
||||
});
|
||||
|
||||
it('inputValue should work on label', async ({ page, server }) => {
|
||||
await page.setContent(`<label><input type=text></input></label>`);
|
||||
await page.fill('input', 'foo');
|
||||
expect(await page.locator('label').inputValue()).toBe('foo');
|
||||
});
|
||||
|
||||
it('innerHTML should work', async ({ page, server }) => {
|
||||
await page.goto(`${server.PREFIX}/dom.html`);
|
||||
const locator = page.locator('#outer');
|
||||
|
|
|
|||
|
|
@ -341,9 +341,15 @@ test('should support toHaveValue', async ({ runInlineTest }) => {
|
|||
await locator.fill('Text content');
|
||||
await expect(locator).toHaveValue('Text content');
|
||||
});
|
||||
|
||||
test('pass on label', async ({ page }) => {
|
||||
await page.setContent('<label><input></input></label>');
|
||||
await page.locator('label input').fill('Text content');
|
||||
await expect(page.locator('label')).toHaveValue('Text content');
|
||||
});
|
||||
`,
|
||||
}, { workers: 1 });
|
||||
expect(result.passed).toBe(1);
|
||||
expect(result.passed).toBe(2);
|
||||
expect(result.exitCode).toBe(0);
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue