feat(selectAll): allow selecting all in the inputs and in the plain dom (#1783)
This commit is contained in:
parent
b2c65db37e
commit
da683b2752
46
docs/api.md
46
docs/api.md
|
|
@ -1424,7 +1424,13 @@ The `format` options are:
|
||||||
|
|
||||||
Focuses the element, and then uses [`keyboard.down`](#keyboarddownkey) and [`keyboard.up`](#keyboardupkey).
|
Focuses the element, and then uses [`keyboard.down`](#keyboarddownkey) and [`keyboard.up`](#keyboardupkey).
|
||||||
|
|
||||||
`key` can specify the intended [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to generate the text for. A superset of the `key` values can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values). Note that only those present on a typical full computer keyboard are supported. Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
|
`key` can specify the intended [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to generate the text for. A superset of the `key` values can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values). Examples of the keys are:
|
||||||
|
|
||||||
|
`F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`, `Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrayRight`, `ArrowUp`, etc.
|
||||||
|
|
||||||
|
Following modification shortcuts are also suported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
|
||||||
|
|
||||||
|
Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
|
||||||
|
|
||||||
If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different respective texts.
|
If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different respective texts.
|
||||||
|
|
||||||
|
|
@ -2242,7 +2248,13 @@ If the name is empty, returns the id attribute instead.
|
||||||
- `timeout` <[number]> Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [browserContext.setDefaultTimeout(timeout)](#browsercontextsetdefaulttimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods.
|
- `timeout` <[number]> Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [browserContext.setDefaultTimeout(timeout)](#browsercontextsetdefaulttimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods.
|
||||||
- returns: <[Promise]>
|
- returns: <[Promise]>
|
||||||
|
|
||||||
`key` can specify the intended [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to generate the text for. A superset of the `key` values can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values). Note that only those present on a typical full computer keyboard are supported. Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
|
`key` can specify the intended [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to generate the text for. A superset of the `key` values can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values). Examples of the keys are:
|
||||||
|
|
||||||
|
`F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`, `Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrayRight`, `ArrowUp`, etc.
|
||||||
|
|
||||||
|
Following modification shortcuts are also suported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
|
||||||
|
|
||||||
|
Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
|
||||||
|
|
||||||
If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different respective texts.
|
If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different respective texts.
|
||||||
|
|
||||||
|
|
@ -2517,6 +2529,7 @@ ElementHandle instances can be used as an argument in [`page.$eval()`](#pageeval
|
||||||
- [elementHandle.screenshot([options])](#elementhandlescreenshotoptions)
|
- [elementHandle.screenshot([options])](#elementhandlescreenshotoptions)
|
||||||
- [elementHandle.scrollIntoViewIfNeeded()](#elementhandlescrollintoviewifneeded)
|
- [elementHandle.scrollIntoViewIfNeeded()](#elementhandlescrollintoviewifneeded)
|
||||||
- [elementHandle.selectOption(values[, options])](#elementhandleselectoptionvalues-options)
|
- [elementHandle.selectOption(values[, options])](#elementhandleselectoptionvalues-options)
|
||||||
|
- [elementHandle.selectText()](#elementhandleselecttext)
|
||||||
- [elementHandle.setInputFiles(files[, options])](#elementhandlesetinputfilesfiles-options)
|
- [elementHandle.setInputFiles(files[, options])](#elementhandlesetinputfilesfiles-options)
|
||||||
- [elementHandle.textContent()](#elementhandletextcontent)
|
- [elementHandle.textContent()](#elementhandletextcontent)
|
||||||
- [elementHandle.toString()](#elementhandletostring)
|
- [elementHandle.toString()](#elementhandletostring)
|
||||||
|
|
@ -2736,7 +2749,13 @@ If the element is detached from DOM, the method throws an error.
|
||||||
|
|
||||||
Focuses the element, and then uses [`keyboard.down`](#keyboarddownkey) and [`keyboard.up`](#keyboardupkey).
|
Focuses the element, and then uses [`keyboard.down`](#keyboarddownkey) and [`keyboard.up`](#keyboardupkey).
|
||||||
|
|
||||||
`key` can specify the intended [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to generate the text for. A superset of the `key` values can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values). Note that only those present on a typical full computer keyboard are supported. Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
|
`key` can specify the intended [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to generate the text for. A superset of the `key` values can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values). Examples of the keys are:
|
||||||
|
|
||||||
|
`F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`, `Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrayRight`, `ArrowUp`, etc.
|
||||||
|
|
||||||
|
Following modification shortcuts are also suported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
|
||||||
|
|
||||||
|
Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
|
||||||
|
|
||||||
If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different respective texts.
|
If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different respective texts.
|
||||||
|
|
||||||
|
|
@ -2793,6 +2812,11 @@ handle.selectOption('red', 'green', 'blue');
|
||||||
handle.selectOption({ value: 'blue' }, { index: 2 }, 'red');
|
handle.selectOption({ value: 'blue' }, { index: 2 }, 'red');
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### elementHandle.selectText()
|
||||||
|
- returns: <[Promise]> Promise which resolves when the element is successfully selected.
|
||||||
|
|
||||||
|
This method focuses the element and selects all its text content.
|
||||||
|
|
||||||
#### elementHandle.setInputFiles(files[, options])
|
#### elementHandle.setInputFiles(files[, options])
|
||||||
- `files` <[string]|[Array]<[string]>|[Object]|[Array]<[Object]>>
|
- `files` <[string]|[Array]<[string]>|[Object]|[Array]<[Object]>>
|
||||||
- `name` <[string]> [File] name **required**
|
- `name` <[string]> [File] name **required**
|
||||||
|
|
@ -3125,7 +3149,13 @@ await page.keyboard.press('Shift+A');
|
||||||
|
|
||||||
Dispatches a `keydown` event.
|
Dispatches a `keydown` event.
|
||||||
|
|
||||||
`key` can specify the intended [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to generate the text for. A superset of the `key` values can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values). Note that only those present on a typical full computer keyboard are supported. Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
|
`key` can specify the intended [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to generate the text for. A superset of the `key` values can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values). Examples of the keys are:
|
||||||
|
|
||||||
|
`F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`, `Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrayRight`, `ArrowUp`, etc.
|
||||||
|
|
||||||
|
Following modification shortcuts are also suported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
|
||||||
|
|
||||||
|
Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
|
||||||
|
|
||||||
If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different respective texts.
|
If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different respective texts.
|
||||||
|
|
||||||
|
|
@ -3153,7 +3183,13 @@ page.keyboard.insertText('嗨');
|
||||||
- `delay` <[number]> Time to wait between `keydown` and `keyup` in milliseconds. Defaults to 0.
|
- `delay` <[number]> Time to wait between `keydown` and `keyup` in milliseconds. Defaults to 0.
|
||||||
- returns: <[Promise]>
|
- returns: <[Promise]>
|
||||||
|
|
||||||
`key` can specify the intended [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to generate the text for. A superset of the `key` values can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values). Note that only those present on a typical full computer keyboard are supported. Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
|
`key` can specify the intended [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) value or a single character to generate the text for. A superset of the `key` values can be found [here](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values). Examples of the keys are:
|
||||||
|
|
||||||
|
`F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`, `Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrayRight`, `ArrowUp`, etc.
|
||||||
|
|
||||||
|
Following modification shortcuts are also suported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
|
||||||
|
|
||||||
|
Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
|
||||||
|
|
||||||
If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different respective texts.
|
If `key` is a single character, it is case-sensitive, so the values `a` and `A` will generate different respective texts.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -290,6 +290,12 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||||
}, deadline, options, true);
|
}, deadline, options, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async selectText(): Promise<void> {
|
||||||
|
const error = await this._evaluateInUtility(({ injected, node }) => injected.selectText(node), {});
|
||||||
|
if (typeof error === 'string')
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
|
|
||||||
async setInputFiles(files: string | types.FilePayload | string[] | types.FilePayload[], options?: types.NavigatingActionWaitOptions) {
|
async setInputFiles(files: string | types.FilePayload | string[] | types.FilePayload[], options?: types.NavigatingActionWaitOptions) {
|
||||||
const deadline = this._page._timeoutSettings.computeDeadline(options);
|
const deadline = this._page._timeoutSettings.computeDeadline(options);
|
||||||
const multiple = await this._evaluateInUtility(({ node }) => {
|
const multiple = await this._evaluateInUtility(({ node }) => {
|
||||||
|
|
|
||||||
|
|
@ -183,33 +183,46 @@ class Injected {
|
||||||
element.dispatchEvent(new Event('change', { 'bubbles': true }));
|
element.dispatchEvent(new Event('change', { 'bubbles': true }));
|
||||||
return false; // We have already changed the value, no need to input it.
|
return false; // We have already changed the value, no need to input it.
|
||||||
}
|
}
|
||||||
|
} else if (element.nodeName.toLowerCase() === 'textarea') {
|
||||||
|
const textarea = element as HTMLTextAreaElement;
|
||||||
|
if (textarea.disabled)
|
||||||
|
return 'Cannot fill a disabled textarea.';
|
||||||
|
if (textarea.readOnly)
|
||||||
|
return 'Cannot fill a readonly textarea.';
|
||||||
|
} else if (!element.isContentEditable) {
|
||||||
|
return 'Element is not an <input>, <textarea> or [contenteditable] element.';
|
||||||
|
}
|
||||||
|
return this.selectText(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
selectText(node: Node) {
|
||||||
|
if (node.nodeType !== Node.ELEMENT_NODE)
|
||||||
|
return 'Node is not of type HTMLElement';
|
||||||
|
const element = node as HTMLElement;
|
||||||
|
if (!this.isVisible(element))
|
||||||
|
return 'Element is not visible';
|
||||||
|
if (element.nodeName.toLowerCase() === 'input') {
|
||||||
|
const input = element as HTMLInputElement;
|
||||||
input.select();
|
input.select();
|
||||||
input.focus();
|
input.focus();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (element.nodeName.toLowerCase() === 'textarea') {
|
if (element.nodeName.toLowerCase() === 'textarea') {
|
||||||
const textarea = element as HTMLTextAreaElement;
|
const textarea = element as HTMLTextAreaElement;
|
||||||
if (textarea.disabled)
|
|
||||||
return 'Cannot fill a disabled textarea.';
|
|
||||||
if (textarea.readOnly)
|
|
||||||
return 'Cannot fill a readonly textarea.';
|
|
||||||
textarea.selectionStart = 0;
|
textarea.selectionStart = 0;
|
||||||
textarea.selectionEnd = textarea.value.length;
|
textarea.selectionEnd = textarea.value.length;
|
||||||
textarea.focus();
|
textarea.focus();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (element.isContentEditable) {
|
const range = element.ownerDocument!.createRange();
|
||||||
const range = element.ownerDocument!.createRange();
|
range.selectNodeContents(element);
|
||||||
range.selectNodeContents(element);
|
const selection = element.ownerDocument!.defaultView!.getSelection();
|
||||||
const selection = element.ownerDocument!.defaultView!.getSelection();
|
if (!selection)
|
||||||
if (!selection)
|
return 'Element belongs to invisible iframe.';
|
||||||
return 'Element belongs to invisible iframe.';
|
selection.removeAllRanges();
|
||||||
selection.removeAllRanges();
|
selection.addRange(range);
|
||||||
selection.addRange(range);
|
element.focus();
|
||||||
element.focus();
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return 'Element is not an <input>, <textarea> or [contenteditable] element.';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isCheckboxChecked(node: Node) {
|
isCheckboxChecked(node: Node) {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
<textarea spellcheck="false"></textarea>
|
<textarea spellcheck="false"></textarea>
|
||||||
<input></input>
|
<input></input>
|
||||||
<div contenteditable="true"></div>
|
<div contenteditable="true"></div>
|
||||||
|
<div class="plain">Plain div</div>
|
||||||
<script src='mouse-helper.js'></script>
|
<script src='mouse-helper.js'></script>
|
||||||
<script>
|
<script>
|
||||||
window.result = '';
|
window.result = '';
|
||||||
|
|
|
||||||
|
|
@ -327,6 +327,30 @@ describe('ElementHandle.fill', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('ElementHandle.selectText', function() {
|
||||||
|
it.fail(FFOX)('should select textarea', async({page, server}) => {
|
||||||
|
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||||
|
const textarea = await page.$('textarea');
|
||||||
|
await textarea.evaluate(textarea => textarea.value = 'some value');
|
||||||
|
await textarea.selectText();
|
||||||
|
expect(await page.evaluate(() => window.getSelection().toString())).toBe('some value');
|
||||||
|
});
|
||||||
|
it.fail(FFOX)('should select input', async({page, server}) => {
|
||||||
|
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||||
|
const input = await page.$('input');
|
||||||
|
await input.evaluate(input => input.value = 'some value');
|
||||||
|
await input.selectText();
|
||||||
|
expect(await page.evaluate(() => window.getSelection().toString())).toBe('some value');
|
||||||
|
});
|
||||||
|
it('should select plain div', async({page, server}) => {
|
||||||
|
await page.goto(server.PREFIX + '/input/textarea.html');
|
||||||
|
const div = await page.$('div.plain');
|
||||||
|
await div.selectText();
|
||||||
|
expect(await page.evaluate(() => window.getSelection().toString())).toBe('Plain div');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('ElementHandle convenience API', function() {
|
describe('ElementHandle convenience API', function() {
|
||||||
it('getAttribute should work', async({page, server}) => {
|
it('getAttribute should work', async({page, server}) => {
|
||||||
await page.goto(`${server.PREFIX}/dom.html`);
|
await page.goto(`${server.PREFIX}/dom.html`);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue