2

I am trying to set values on an angular page through a chrome extension I create so I can easily complete some repetitive angular forms I have to fill it up many times a day. (Change the angular page's code is not an option, the new values have to be injected or "typed" somehow)

On my tests, I can see the values been updated on the DOM and displaying on the page, however when I press the submit button the bound angular variables have no values.

Bellow is the code inject on the DOM by the extension, It has a little added complexity as it has everything I tried many different things such as to simulate typing using a timer, setting focus, selecting the field using select, etc.

// listen for checkForWord request, call getTags which includes callback to sendResponse
chrome.runtime.onMessage.addListener(
    function (request, sender, sendResponse) {
        if (request.action === "checkForWord") {
            TypeIntoInput("inputFieldPasswordRegister", "Password123!")
            TypeIntoInput("inputFieldConfirm", "Password123!")
            var inputs = document.getElementsByTagName('input');
            for(var i=0; i<inputs.length; i++){
                if(inputs[i].getAttribute('type')=='button'){
                    inputs[i].disabled = false
                }
}

            return true;
        }
    }
);

function TypeIntoInput(inputBox, valueText) {
    var input = document.getElementById(inputBox);
    input.select();
    input.focus();

    input.value="";
    var text = valueText;
    var l=text.length;
    var current = 0;
    var time = 100;


    var write_text = function() {
    input.value+=text[current];
        if(current < l-1) {
            current++;
            setTimeout(function(){write_text()},time);
        } else {
            input.setAttribute('value',input.value);
            var e = document.createEvent('KeyboardEvent');
            e.initKeyEvent('ENTER', true, true, window, false, false, false, false, 13, 0);
            // Dispatch event into document
            document.body.dispatchEvent(e);
        }
    }
    setTimeout(function(){write_text()},time);
}
Icaro
  • 14,585
  • 6
  • 60
  • 75
  • You probably need to trigger angulars change detection. Can you try executing a change event on the input you're setting? (https://stackoverflow.com/questions/34827334/triggering-change-detection-manually-in-angular) Angular really doesn't like it when things external to it try and update it. Usually doesn't work without some extra step of telling angular to pick up said changes – mwilson Aug 04 '19 at 21:18
  • @mwilson I look into that but change the page is not an option – Icaro Aug 04 '19 at 21:39
  • Not sure what you mean by 'change the page' but you're going to have to find a way (either through your Angular App or through your Chrome Extension) to let angular know about your changes. As a test to see if this is the issue, i'd do something simple like creating a `setInterval` function to trigger the change detector every couple of seconds and see if you can get it to pick things up. If this works, then you know what the problem is. – mwilson Aug 04 '19 at 21:43
  • Basically, just import the `ChangeDetectorRef` and run `ChangeDetectorRef.detectChanges` (https://angular.io/api/core/ChangeDetectorRef) – mwilson Aug 04 '19 at 21:44
  • Also, if this is strictly for testing purposes only, why not use the built in Karma setup to do this? e2e is great for this. – mwilson Aug 04 '19 at 21:47
  • @mwilson I cannot change the Angular page, it is a third party page, I want to inject some values to its form from outside simulating typing, I add the delay to try fool angular as if someone is typing – Icaro Aug 04 '19 at 22:18
  • I suggest looking into how angular detects changes within it's model(s). I don't think you're going to have any luck with what you're trying to do. My last comment here is to circle back to the first one. Try and trigger a change event on the input and see if you can tease angular into picking it up. I think you're on a dead path. Zone might be available at the window object. pretty sure you can get the the change detector object with that, but I'm not sure. Knowing the angular team, they probably have some security in place for this sort of thing. – mwilson Aug 04 '19 at 22:21
  • It must have a way where I can send an event the same way Windows does when we press a key. Or inject some javascript that would be similar to the javascript generated by the `ChangeDetectorRef.detectChanges` – Icaro Aug 04 '19 at 22:24
  • You should re-read everything I've said. I've given you 2 different ways to make that happen (although unsure if it will work). Angular is infamous for ignoring ANYTHING that happens outside of the angular context. Again, you're on a dead path. – mwilson Aug 04 '19 at 22:26
  • 1
    It's often sufficient to focus() the element and simply do document.execCommand('insertText', false', 'your text here') – wOxxOm Aug 05 '19 at 04:10
  • @wOxxOm it normally would be, however, the binding on angular is not capturing the change, I am not sure what makes angular update the biding, I try onkeydown, onkeypress, onkeyup events but the variable does not update even with the value on the screen updating – Icaro Aug 05 '19 at 23:51
  • Just in case, are you repeating to me the info you've posted in the question or did you actually try execCommand? – wOxxOm Aug 06 '19 at 03:51
  • @wOxxOm sorry you right I was reading it wrong, it worked fine now :) – Icaro Aug 06 '19 at 21:14

0 Answers0