How to succesfully fill an angular input field using AutoHotKey? I can set the value, but get a message implying nothing was input

Viewed 549

I'm trying to automate the login of my CCTV system's webpage in IE11 using AHK. I think the login page utilises Angular 1.2.0.

Here's my script:

wb := ComObjCreate("InternetExplorer.Application")

wb.Visible := True

wb.Navigate("http://192.168.1.6/doc/page/login.asp")

While wb.readyState != 4 || wb.document.readyState != "complete" || wb.busy ; wait for the page to load
   Sleep, 10

Sleep, 100

username_input := wb.document.getElementById("username")
password_input := wb.document.getElementById("password")

username_input.value := "myusername"
password_input.value := "mypassword"

wb.document.querySelector(".login-btn").click()

Return

The username/password visually populate as I expect, but when the script "clicks" the login button, I get an error message implying the username field is blank. If I manually type and delete a single letter and try again, I get the same message for the password field. If I manually type and delete a single letter in that field, then the login button works.

I've never used Angular, so I've no idea what magic goes on behind the scenes when a user types in a field. How can I make it believe there's something in those fields?

Here's the HTML of the login page, if that helps:

<!doctype html>
<html>
<head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" >
    <meta http-equiv="Pragma" content="no-cache" />
    <meta http-equiv="Cache-Control" content="no-cache, must-revalidate" />
    <meta http-equiv="Expires" content="0" />
    <script>
        document.write("<link type='text/css' href='../ui/css/ui.css?version=" + new Date().getTime() + "' rel='stylesheet' />");
    </script>
</head>
<body ng-keypress="docPress($event)" ng-controller="loginController" ng-cloak class="ng-cloak">
<div class="login" id="login">
    <div class="top">
        <div class="logo"></div>
        <div class="language">
            <div class="language-show" ng-click="showLanguageList($event)"><span class="current-language" id="current_language"></span></div>
            <div class="language-list" id="language_list" ng-click="changeLanguage($event)"></div>
        </div>
    </div>
    <table cellspacing="0" cellpadding="0" border="0" class="middle">
        <tr>
            <td class="login-l">&nbsp;</td>
            <td class="login-m">
                <div class="login-part">
                    <div class="line"></div>
                    <div class="login-error">
                        <div class="inputValidTip" ng-show="szErrorTip!=''"><i class='error'></i><label>{{szErrorTip}}</label></div>
                    </div>
                    <div class="login-user">
                        <input type="text" class="login-input" id="username" ng-model="username"maxlength="32" autocomplete="off" placeholder="{{oLan.username}}" />
                        <i class="icon-user"></i>
                    </div>
                    <div class="login-item">
                        <input type="password" class="login-input" id="password" ng-model="password" maxlength="16" placeholder="{{oLan.password}}" />
                        <i class="icon-pass"></i>
                    </div>
                    <div class="login-item">
                        <button type="button" class="btn btn-primary login-btn" ng-click="login()"><label ng-bind="oLan.login"></label></button>
                    </div>
                    <div class="login-item anonymous" ng-show="anonymous">
                        <span ng-bind="oLan.anonymous" ng-click="login('anonymous')"></span>
                    </div>
                </div>
            </td>
            <td class="login-r">&nbsp;</td>
        </tr>
    </table>
    <div class="footer" id="footer"></div>
</div>
<div id="active" class="msg-content-wrap">
    <div class="msg-content">
        <div class="password">
            <span class="desc"><label ng-bind="oLan.username"></label></span>
            <span><label ng-bind="activeUsername"></label></span>
        </div>
        <div class="password">
            <span class="desc"><label ng-bind="oLan.password"></label></span>
            <span><input id="activePassword" type="password" ng-model="activePassword" maxlength="16" onpaste="return false;" /></span>
            <span class="inputValidTip"><i ng-class="{true:'success', false:'error'}[activePasswordStatus]"></i></span>
        </div>
        <div strength class="passwordstrength" lan="oLan" o-password="activePassword" o-username="activeUsername"></div>
        <div class="password">
            <span class="desc"><label ng-bind="oLan.confirm"></label></span>
            <span><input type="password" onpaste="return false;" ng-model="activePasswordConfirm" maxlength="16" /></span>
        </div>
    </div>
</div>
<div id="main_plugin" class="no-window"></div>
</body>
<script id="seajsnode" src="../script/lib/seajs/seajs/sea-2.1.1.min.js"></script>
<script>
    document.write("<script src='../script/lib/seajs/config/sea-config.js?version=" + new Date().getTime() + "' ></scr" + "ipt>");
</script>
</html>

Thanks

1 Answers

Couldn't you focus or click on the elements and then send the data with one of the several send types until you find one that works? Sometimes it helps to send a letter and a backspace then wait to send the data then wait .2 sec and send tabs to next field (or repeat the process:

...
wb.document.getElementById("username").click() ; or .focus()
SendInput, x{bs}
Sleep, 200
SendInput, myusername
Sleep, 200
SendInput, {tab} ; or {tab x} to pw field and skip next line
wb.document.getElementById("password").click()
Sleep, 200
SendInput, mypassword
Sleep, 200
SendInput, {tab}
...

Try it and see . . .

EDIT Per OP success with:

....
username_input := wb.document.getElementById("username")
username_input.focus() 
SendInput, myusername{tab}
SendInput, mypassword{enter}
Related