Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programmatically fill reactjs form

I am writing an userscript and I can't manage to fill a form made by reactjs. My code:

document.querySelector("#id-username").value = "[email protected]";
// Attempt to notify framework using input event
document.querySelector("#id-username").dispatchEvent(new Event("input", {data:"[email protected]"}));
// Attempt to notify framework using change event
document.querySelector("#id-username").dispatchEvent(new Event("change"));
// This doesn't help either
document.querySelector("#id-username").dispatchEvent(new Event("blur"));
// Submit the form using button (it's AJAX form)
document.querySelector("fieldset div.wrap button").click();

I entered this code into developper tools console after loading the page. However the form ignores my programatical input:

image description

The form can be found here. The purpose of my work is to automate login to given website. I provided the specific URL, but I expect generic solution to this problem (eg. using some reactjs API) that can be applied to any reactjs form. Other users might need this solution for writing automated tests for their sites.

like image 371
Tomáš Zato - Reinstate Monica Avatar asked Dec 06 '22 15:12

Tomáš Zato - Reinstate Monica


1 Answers

For Chrome version 64, there is a workaround. Otherwise the event is being ignored.

See:https://github.com/facebook/react/issues/10135#issuecomment-314441175

(Full credit to fatfisz in the link)

Code

function setNativeValue(element, value) {
  const valueSetter = Object.getOwnPropertyDescriptor(element, 'value').set;
  const prototype = Object.getPrototypeOf(element);
  const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set;

  if (valueSetter && valueSetter !== prototypeValueSetter) {
    prototypeValueSetter.call(element, value);
  } else {
    valueSetter.call(element, value);
  }
}

Usage

setNativeValue(textarea, 'some text');
// you must dispatch the input event, or the value will not update !!!
textarea.dispatchEvent(new Event('input', { bubbles: true }));
like image 130
bschwagg Avatar answered Dec 08 '22 05:12

bschwagg