Guides · Tooling & Windows gotchas · Published 2026-09-13 · 3 min read

Automating Web Forms From the Console — Why element.value Does Nothing in React, the Native Setter Trick, and How to Fill Quill, CKEditor and Hidden File Inputs

Scripting a publishing dashboard or an admin form from DevTools breaks on modern frameworks. The native value setter that makes React and Vue notice a change, how to push HTML into Quill and CKEditor 5 through their own APIs, and how to feed files to a hidden upload input.

Publishing the same book or product to several platforms means filling the same long form several times. Doing it from the browser console is faster and less error-prone than typing, but the obvious approach, setting input.value and submitting, silently fails on most modern sites: the framework never sees the change, validation says the field is empty, and rich-text editors ignore assignments to their content. These are the techniques that work.

Why input.value = "x" is not enough

React, Vue and similar frameworks track input state through events. Setting .value directly changes the DOM but fires no input event, and React additionally overrides the value property on the element with its own tracker, so even a dispatched event reports "no change". The fix is to call the original setter from the element's prototype, then dispatch the events the framework listens for:

function setValue(el, value) {
  const proto = Object.getPrototypeOf(el);
  const setter = Object.getOwnPropertyDescriptor(proto, 'value').set;
  setter.call(el, value);
  el.dispatchEvent(new Event('input', { bubbles: true }));
  el.dispatchEvent(new Event('change', { bubbles: true }));
}

This works for <input>, <textarea> and <select>. For checkboxes and radio buttons, call .click() instead of setting checked; it fires the right events and respects the framework's handlers.

Rich-text editors

Editors keep their own model and rewrite the DOM from it, so editing innerHTML is undone on the next keystroke or ignored at submit. Use the editor's API.

Editor How to find the instance How to set content
Quill Quill.find(document.querySelector('.ql-container')), or the container's __quill property quill.clipboard.dangerouslyPasteHTML(0, html, 'user') inserts HTML and updates the model
CKEditor 5 document.querySelector('.ck-editor__editable').ckeditorInstance editor.setData(html)
TinyMCE tinymce.activeEditor editor.setContent(html)
ProseMirror or TipTap Usually exposed on the wrapper element or a global by the host app Use the host's API; if none, a synthetic paste event with text/html in a DataTransfer often works

Most editors also mirror content into a hidden <textarea> or <input> for submission; after using the API, check that the hidden field updated, because that is what the server receives.

File inputs

Upload widgets hide the real <input type="file"> and draw a button over it. You cannot set the input's value from script for security reasons, but automation tools that drive the browser can attach files to a file input by reference. The problem is finding the right input among several hidden ones: give each a temporary aria-label from the console, then have the tool locate the input by that label. Uploader libraries such as Plupload create one hidden input per drop zone, and the one whose invisible overlay sits over the "Upload file" button is the product input.

Submitting once and verifying

Press the submit button once, with the network panel open, and then verify from the list page rather than from the form's own success message. Forms on slow dashboards often show no feedback for several seconds, and pressing again creates a duplicate that has to be cleaned up.

Common mistakes

Summary

Use the prototype's native value setter plus input and change events for framework-controlled fields, the editor's own API for rich text, and file attachment by labelled input for uploads. Submit once and check the list page. The same techniques apply whether you are driving the page from DevTools or from a browser automation tool.

Related guides