0

Trying to create a Greasemonkey script to auto-fill some forms, and I want the script to go to another URL after the form is submitted.

// ==UserScript==
// @name     usersaime
// @description fills data form for user and pass 
// @include https://tramites.saime.gob.ve/*
// @version  1.1
// @grant    none
// ==/UserScript==
document.getElementById('LoginForm_username').value = "user";
document.getElementById('LoginForm_password').value = "1234";

setTimeout(function() {
    document.getElementById('login_button').click();
}, 2000);

window.addEventListener('load', function(event) {
    // all resources finished loading
    window.location = 'https://tramites.saime.gob.ve/index/example/example';
});

The window.location is not working at all. I also tried window.location.href and window.location.replace, and a setTimeout function to the window.location. Nothing works.

There are no errors on the console.

Tried:

  • Firefox 59 + Greasemonkey 4.3
  • Chrome 66 + Tampermonkey 4.5

The login page/form is https://tramites.saime.gob.ve/index.php?r=site/login.
And on successful login it goes to https://tramites.saime.gob.ve/index.php?r=tramite/tramite/ -- which I want to redirect.

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
  • You are likely getting an error like *TypeError: null is not an object (evaluating 'document.getElementById('LoginForm_username').value=""')*. This is a duplicate of many others: put your script the bottom of the page. – RobG May 06 '18 at 22:50
  • not the problem ... but, why would you use `window.onload` **and** `window.addEventListener('load'` 6 lines apart in your code? – Jaromanda X May 06 '18 at 22:51
  • Probably a duplicate of [*Javascript Error Null is not an Object*](https://stackoverflow.com/questions/14207922/javascript-error-null-is-not-an-object). – RobG May 06 '18 at 22:51
  • 1
    debugging, step 1: check the *browser* **developer** tools console for errors – Jaromanda X May 06 '18 at 22:52
  • ok, i edited the code, is a greasemonkey script it works for a external site, i cant edit the site code, like i said before, works fine until the click event, but the redirect is not working – alejandro cabrera May 06 '18 at 23:03
  • Something you aren't showing us is the problem. Supply ALL of the following: (1) Errors from the browser console, (2) Userscript metadata header, (3) Greasemonkey version, (4) Browser version. ... There are multiple problems wit the question code so far. (A) timing, (B) need to differentiate pages: pre-validation/post-validation/post-submit/post redirect (if there is a conflict), (C) basic security. **Above all, need an MCVE.** But a link to a public target page is best. – Brock Adams May 06 '18 at 23:16
  • added more info about it, is there any other way to use a redirect with javascript? i have been looking for others userscripts but cant find any with redirect – alejandro cabrera May 06 '18 at 23:37
  • Looks to be timing issues. Since, I'm not (legally) able to register, Two more questions and then I may have enough info to answer. (1) is the login page for you always `https://tramites.saime.gob.ve/index.php?r=site/login`? (2) Without any userscripts running, is the URL immediately after a successful login the same? If no, what is the new URL? If yes, what is different about the page? – Brock Adams May 06 '18 at 23:48
  • 1
    1.- that is always the login page 2.- after a succesful login with or without userscript the next URL is https://tramites.saime.gob.ve/index.php?r=tramite/tramite/ when lands in this URL i want to redirect another one inside the side https://tramites.saime.gob.ve/index.php?r=agilizacion/agilizacion/ but the redirect doesnt work, this is my problem! – alejandro cabrera May 07 '18 at 00:01

1 Answers1

1

Simple, immediate answer:
The reason window.location is not working for you is because:

  1. The window.location call is made inside a window load event handler.
  2. That target page is one of those were the load event fires almost immediately after the DOMContentLoaded event.
  3. By default userscripts trigger at DOMContentLoaded, but in this case, the load event has already fired by the time your script runs.

The real answer:
There are many problems with that question code:

  1. It's not tracking and accounting for the state of the process. The script fires on many (kinds of) pages and must behave differently depending on state.
  2. The page(s) is/are extensively AJAX-driven. The code is not properly accounting for that.
  3. Load event is not particularly useful in this kind of scenario.
  4. The aforementioned, script-firing versus load, race condition.
  5. Hard-coding login credentials in a script like that means that you will get pwned, it's just a question of when and how much damage.

You need to track and differentiate between at least 3 different states, using a combination of the pages' URLs and/or key nodes on the pages and/or state variables that the script stores/passes.

The following userscript illustrates the process, although I can't test it on the site and the recommended authentication framework is omitted for simplicity. :

// ==UserScript==
// @name     _Login and then redirect an AJAX-driven page
// @include  https://tramites.saime.gob.ve/*
// @require  https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_addStyle
// @grant    GM.getValue
// ==/UserScript==
//- The @grant directives are needed to restore the proper sandbox.

//--- Different pages require different actions
if (location.search.includes ("site/login") ) {  // initial login page

    //-- Wait for page to initialize
    waitForKeyElements ("#login_button:visible", loginWhenReady);
}
else if (location.search.includes ("tramite/tramite") ) {  // successful login page
    //-- Just redirect
    location.assign ("https://tramites.saime.gob.ve/index/example/example");
}
else {
    //-- All other pages, no action needed.
}

function loginWhenReady (jNode) {
    //-- Demo purposes only!  Use framework or password manager instead!
    $("#LoginForm_username").val ("user");
    $("#LoginForm_password").val ("1234");

    clickNode (jNode);  //  Login button passed in by WFKE
}
function clickNode (jNode) {
    var clickEvent  = document.createEvent ('MouseEvents');
    clickEvent.initEvent ('click', true, true);
    jNode[0].dispatchEvent (clickEvent);
}


Possible quick and easy solution:

  1. If-and-only-if (IIF) the post login page is always
    https://tramites.saime.gob.ve/index.php?r=tramite/tramite/.
  2. AND IIF that page is used for nothing else that you care about...

Then the following userscript may suffice for your needs:

// ==UserScript==
// @name     _Quick and dirty post login redirect
// @include  https://tramites.saime.gob.ve/index.php?r=tramite/tramite*
// @grant    none
// @run-at   document-start
// ==/UserScript==

location.replace ("https://tramites.saime.gob.ve/index/example/example");
Brock Adams
  • 90,639
  • 22
  • 233
  • 295
  • omg that is better than i expected, so, now if i need to fill another forms in the same site but different page i have to use the else condition right? else (location.search.includes (example2/example2) { }; – alejandro cabrera May 07 '18 at 02:07
  • Yes, that's probably the easiest way, without knowing more details. – Brock Adams May 07 '18 at 02:10