Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Populating ReactJS HTML Form via Javascript

I'm working on an app in which I'm able to run my own Javascript inside browser context after opening a 3rd party website. As a sample website which is build on reactjs and has a login form, you can refer to this link.

I'm trying to fill the username and password in the form which is generated by reactjs. However, I'm not able to completely achieve it.

The closest codebase by which I'm able to set value into the username/password field and inside reactjs is:

function setNativeValue(element, value) {
    element.focus();
    element.click();
    element.value = value;
    element.defaultValue = value;
    let tracker = element._valueTracker;
    if (tracker) {
        tracker.setValue(lastValue);
    }
    let inputEvent = new Event("input", { target: element, bubbles: true });
    inputEvent.simulated = true;
    element.dispatchEvent(inputEvent);
}

document.getElementsByClassName("sc-qamJO")[0].click(); // login top button
setTimeout(function () {
    setNativeValue(document.getElementsByClassName("sc-AxheI")[1], "username"); // username
    setNativeValue(document.getElementsByClassName("sc-AxheI")[2], "password"); // password

    setTimeout(function () {
        document.getElementsByClassName("sc-fzpans")[3].click(); // login button
    }, 1000);
}, 1000);

Problem: However, I'm not able to automatically submit the reactjs form. It throws an error This field is required* error, even though I have done everything correctly based on my understanding and google search suggestions. I'm not able to satisfy the field validators.

I have tried lot and lot of ways to automatically submit the form. Some of them are:

  1. Following all the methods provided on this stackoverflow question
  2. Getting the reactjs instance then trying to setState. In this case, .setState is not a function error comes
  3. This github issue comments is what I'm currently following to solve my problem
  4. I have also tried sequence of events like mouseenter mousedown ... keydown keypress keyup and others, similar to what this person is doing

Can you please tell, what should I do, in order to satisfy the reactjs validators available in the login form, so that the form gets automatically submitted on website using javascript or jQuery.

Note - The sample website does not contains jQuery, so a pure Javascript code will also work in terms of understanding.

I'm using Chromium as a browser.

like image 483
Sunil Kumar Avatar asked Jun 23 '20 17:06

Sunil Kumar


1 Answers

Based on the setState example I could submit the login form with this:

const openLoginModal = () => document.getElementsByClassName('sc-qamJO')[0].click()
const submitLoginForm = () => document.getElementsByClassName('sc-fzpans')[3].click()

const getCompFiber = fiber => {
    let parentFiber = fiber.return

    while (parentFiber && typeof parentFiber.type === 'string') {
        parentFiber = parentFiber.return
    }

    return parentFiber
}

const getLoginForm = () => {
    const dom = document.getElementsByClassName('sc-AxheI')[1]
    const key = Object.keys(dom).find(key => key.startsWith('__reactInternalInstance$'))
    const domFiber = dom[key]

    if (domFiber == null) return null

    let compFiber = getCompFiber(domFiber)

    while (compFiber) {
        compFiber = getCompFiber(compFiber);

        if (compFiber && compFiber.stateNode && compFiber.stateNode.props && compFiber.stateNode.props.loginForm) {
            return compFiber
        }
    }
}

const login = (username, password) => {
    openLoginModal()

    setTimeout(() => {
        const loginForm = getLoginForm()

        loginForm.stateNode.props.loginForm.password = {
            value: password,
            error: false,
            errorMessage: 'This field is required',
            type: 'password'
        }

        loginForm.stateNode.props.loginForm.username = {
            value: username,
            error: false,
            errorMessage: 'This field is required'
        }

        submitLoginForm()
    }, 1000)
}

login('myUser', 'myPassword')

The login failed with a 500 error (which is weird), but I checked and that's the same error code when trying to login manually with an invalid username/password, so I guess it should work with proper credentials.

like image 69
Carlos Jiménez Avatar answered Nov 11 '22 12:11

Carlos Jiménez