Setting React element values directly from Selenium

I love Selenium, but there are a few things that it still handles poorly. Interacting with non-standard web native inputs is one of those items, for example color pickers, date inputs.

You can usually get around these by simply setting the value using the executeScript method. But this doesn’t work so easily if you are testing against React. This function will directly set an input’s value and trigger the React change event so state updates are made.

This is in TypeScript, but translates pretty easily to JavaScript.

export async function setReactElementValue(driver: WebDriver, element: WebElement, value: string): Promise<void> {
  await driver.executeScript(`const valueSetter = Object.getOwnPropertyDescriptor(arguments[0], 'value').set;
const prototype = Object.getPrototypeOf(arguments[0]);
const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set;
if (valueSetter && valueSetter !== prototypeValueSetter) {
    prototypeValueSetter.call(arguments[0], '${value}');
} else {
    valueSetter.call(arguments[0], '${value}');
}
arguments[0].dispatchEvent(new Event('input', { bubbles: true }));`,
    element,
  );
}

Hopefully this saves someone time!

Leave a comment

Your email address will not be published. Required fields are marked *