4

I am attempting to iron out a bug in a script which automatically logs in to https://account.booking.com/sign-in

function clickButton (){
  const msg = document.querySelector(".bui-form__error");
  const button = document.querySelector(".bui-button");
  if (msg && msg.id !== "loginname-error" ) {
    console.log(msg.textContent);
  } else if (button) {
    button.click();
  } else {
    console.log("Not yet...");
    return;
  }
}

setInterval(clickButton, 200);

Most of the time, this works fine. Despite having the username field filled out automatically by Chrome, it will sometimes display the loginname-error, which we can ignore safely for our purposes--however, this sometimes causes the page to become unresponsive to the script for some reason. Almost anything done on the page by the user will cause the script to continue--pressing F12 to open Dom inspector, clicking literally anywhere on the page, even running a command on the console (as simple as 'a = document.querySelector...') all somehow kick the script into running as it should.

I have attempted to follow previous answers, implemented triggerMouseEvent and run mouseover, mousedown, mouseup, and click. This behaves no differently from simply using click(). As clicking elsewhere on the page can fix it, I have attempted to use such click events on other elements before using them on the button again; this also behaves no differently from simply using click(). The only results I've seen for Tampermonkey script 'works after...' are AJAX issues with page reloading, not user interaction with the window.

Putting console.log("click") following the click event shows that it is reaching the click event just fine. Using triggerMouseEvent, I've logged dispatchEvent as follows:

function triggerMouseEvent (node, eventType) {
    var clickEvent = document.createEvent ('MouseEvents');
    clickEvent.initEvent (eventType, true, true);
    console.log(node.dispatchEvent (clickEvent));
}

Which returns 'true' as expected.

I have attempted to send a keyboard event as below between each click:

function pressf12(){
  var event = new KeyboardEvent("pressF12");
  event.keyCode = 123;
  event.which   = 123;
  event.altKey  = false;
  event.ctrlKey = false;
  event.shiftKey= false;
  event.target  = window;
  window.dispatchEvent(event);
}

This has also not worked. I'm quite out of ideas for what is causing the issue and what can be done to get around it.

This is what is shown on the console after loading the page, if it may be relevant:

[Report Only] Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src saa.booking.com *.bstatic.com bstatic.com google-analytics.com 'self' 'nonce-6B8EKlfK9vqB8Uy'". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.

content_script @ VM1347:61 (anonymous) @ VM1347:71

and

sign-in?op_token=...:38 POST https://account.booking.com/navigation_times?sid=&pid=...&nts=…=3&lang=en-us&ref_action=Signin_Index&aid=...&stype=&route=&ua=&ch=&lt= net::ERR_BLOCKED_BY_CLIENT callback @ sign-in?op_token=...:38 wrapper @ error_catcher:756 setTimeout (async)
win.setTimeout @ error_catcher:666 callback @ sign-in?op_token=...:38 load (async)
nav_timing @ sign-in?op_token=...:38 (anonymous) @ sign-in?op_token=...:38

Here is a screenshot:

No further messages are shown after the user clicks on the page. Even if I increase the interval to 5000, well after the page has loaded and both of these messages have displayed on their own, the clicks from the script do nothing.

The thought occurred to me that this may be caused by Chrome settings, addons or the like, but it occurs both on multiple of my own computers, as well as those of other users. Even were that the case, some workaround would be needed.

It also occurred to me that it may be somehow related to TM's sandbox. Trying @grant none, @grant unsafeWindow, and inserting the script inline as per this answer all have the same problem behavior. Inserting the script inline does give more of the unsafe-inline error in the console.

Worthwelle
  • 1,244
  • 1
  • 16
  • 19
sinaraheneba
  • 781
  • 4
  • 18
  • Maybe [this](https://stackoverflow.com/a/39347807/3168107) provides a clue. – Shikkediel Jun 10 '19 at 12:50
  • I don't believe so; the issue is again not that the element isn't loaded before the script is run (as it runs continuously while on the login page), but that something is causing the events to be ignored or dropped. Any user interaction with the page causes it to continue, but attempting to emulate those same interactions within my script has so far not been successful. I've added additional information from the page's console output to my post, if that might be relevant. – sinaraheneba Jun 10 '19 at 20:35

2 Answers2

0

I tried your script both in Chrome with Tampermonkey and Firefox with Greasemonkey after registering a dummy account. With setInterval delay of 200, they didn't work. You need to increase your setInterval delay to 1000 and it will work.

Albert
  • 195
  • 9
  • 2
    Nope, this changes nothing except making the script a bit slower. – sinaraheneba Jun 10 '19 at 20:26
  • The I'd say it's something on your side. My Chrome is bare, just the tampermonkey extension was added to test this. Firefox has a lot of addons though, still appears to work well. – Albert Jun 12 '19 at 09:39
  • Again, this is not something which occurs every time; the script works fine when it does work. There are no other extensions shared by these machines which would interfere with the pages' behavior; nor would they explain why events sent by TemperMonkey are apparently dropped but commands from console/user actions can successfully send events (which then also cause those from TM to function as intended). It is more likely that you have not replicated the situation which causes the page to behave this way, hence never seeing the unexplained behavior. – sinaraheneba Jun 12 '19 at 09:48
  • If you believe you have replicated it and the script worked as it should, please provide additional information (e.g. screenshots/console log) for comparison; it may be useful. – sinaraheneba Jun 12 '19 at 09:52
0

Have you tried using window.onload?

For example:

window.onload = () => {
  // do stuff...
};

You could also try using addEventListener:

window.addEventListener("load", () => {
  // do stuff...
});

If this doesn't work you could try triggering a click event using:

document.querySelector("<selector>").click();

Good luck.

Malekai
  • 4,765
  • 5
  • 25
  • 60
  • Am already using `.click()` to trigger the event. Again, this shouldn't be an issue of the script running before the page loads, as it runs continuously regardless, and pressing any button or clicking anywhere on the page causes it to continue running. Delaying the script's execution by 5000ms, well after the page has loaded, has the same result. I attempted the above methods anyway, and it behaves exactly the same. – sinaraheneba Jun 11 '19 at 01:18