devtools
Version:
A Chrome DevTools protocol binding that maps WebDriver commands into Chrome DevTools commands using Puppeteer
50 lines (49 loc) • 2.1 kB
JavaScript
import path from 'node:path';
import { UNICODE_CHARACTERS } from '@wdio/utils';
import { getStaleElementError } from '../utils.js';
/**
* The Element Send Keys command scrolls into view the form control element and then sends
* the provided keys to the element. In case the element is not keyboard-interactable,
* an element not interactable error is returned. The key input state used for input
* may be cleared mid-way through "typing" by sending the null key, which is U+E000 (NULL)
*
* @alias browser.elementSendKeys
* @see https://w3c.github.io/webdriver/#dfn-element-send-keys
* @param {string} elementId the id of an element returned in a previous call to Find Element(s)
* @param {string} text string to send as keystrokes to the element
*/
export default async function elementSendKeys({ elementId, text }) {
const elementHandle = await this.elementStore.get(elementId);
if (!elementHandle) {
throw getStaleElementError(elementId);
}
await elementHandle.focus();
const page = this.getPageHandle();
const propertyHandles = {
tagName: await elementHandle.getProperty('tagName'),
type: await elementHandle.getProperty('type')
};
const tagName = await propertyHandles.tagName?.jsonValue();
const type = await propertyHandles.type?.jsonValue();
let typeInput = [text];
for (const [key, value] of Object.entries(UNICODE_CHARACTERS)) {
typeInput = typeInput.reduce((input, val) => [
...input,
...val.split(value).flatMap((value, index, array) => array.length - 1 !== index // check for the last item
? [value, key]
: value)
], []);
}
if (tagName === 'INPUT' && type === 'file') {
const paths = (text || '').split('\n').map(p => path.resolve(p));
await elementHandle.uploadFile(...paths);
}
else {
for (const input of typeInput) {
UNICODE_CHARACTERS[input]
? await page.keyboard.press(input)
: await page.keyboard.type(input);
}
}
return null;
}