chrome extension to record and play window events

Summary

I am looking for a Chrome extension that will give me JavaScript commands called something like “ListenForWindowEvent()” and “PlayWindowEvent()”, which I can use to record raw window mouse and keyboard events, and replay them later. I don’t want an extension that provides its own UI for recording and replaying sequences of events. I just want to be able to access (detect and play) such events from my own JavaScript code.

Details

Using JavaScript (with or without JQuery), I can track events (mousemove, mouseup, mousedown, click, keyup, keydown) almost anywhere on a page, and I can “replay” these events, mostly, by triggering the appropriate events (e.g., “click”) on the appropriate elements.

However, my understanding is that there are certain events that I can’t quite detect or simulate, which all seem to have to do with “system level” components on a web page such as select (drop-down) menus, text input boxes, and scroll bars.

For instance, I don’t believe with just JavaScript that I can detect that the user dragged a scroll bar from position A to position B. I can listen for the scroll event after the fact, but can’t detect the lower-level mouse events that caused the scroll. And even if I had these events, I couldn’t replay them by causing the same click/drag events on the scroll bar. (I can only set the scroll value of the element.) Similarly, I can detect when a select menu changes value, but I don’t have access to the mouse events that popped the menu open and then selected a particular item. For text input boxes, I believe I can see the individual key up and key down events, but I can’t replay them into the box — again I can only set the value of the text input element as a whole.

Assuming all of that is more or less correct, what I want is a Chrome extension that would give me access to those low-level events (both monitoring them and replaying them) via JavaScript. I see that there are plenty of extensions that allow recording and replaying of these low-level events on the browser window. But these all seem to come with their own record/replay GUI. I don’t want to use someone else’s GUI. I just want to be able to record and replay these low-level window events myself via a simple extension that gives me JavaScript commands like “ListenForWindowEvent()” and “PlayWindowEvent()”.

I know that Puppeteer is Google’s way of playing low-level events to a window. But if possible I’d like to avoid having to use a heavy solution like that (and I don’t even know if Puppeteer can be used to record the events in the first place?). I imagine I can start with the source code of one of the standard record/replay automation extensions and make my own simpler extension. But I wanted to know if such an extension already exists. My Google searches only found the full-GUI ones.

Chrome Extension: Event pages – are they re-run in full or only the portion related to registered events?

I’m transitioning from a background to an event page, see https://developer.chrome.com/extensions/event_pages#transition

The docs say:

Register to receive any events your extension is interested in each
time the event page is loaded. The event page will be loaded once for
each new version of your extension. After that it will only be loaded
to deliver events you have registered for
. This generally means that
your event listeners should be added at the top level scope of the
event page, otherwise they may not be available when the event page
reloads.

My question is regarding to the bold part: Is the event page re-run in full after a re-activating event, or just the portion relative the handling of given event, for example the click on the browser action button.

For example, I’d like the event page to wake up when the user pushes the browser action button.

chrome.browserAction.onClicked.addListener(function(){
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
      chrome.tabs.sendMessage(tabs[0].id, {action: "user_clicked_browser_action_button"}, function(response) {
      });
      ga_push_event("browser_action", "browser_action_clicked");
    });
  });

I’m using Google Analytics and have this snippet at the bottom of my event page:

(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-xxxxxx-x', 'auto');

Since this snippet is at the end of the page, and not called by the event listener block above, will it be processed every time any listening event is triggered, or do I instead have to make sure that every event listener calls the Analytics part explicitly?

Another thing I wondered, perhaps I missed it in the docs: Are we supposed to have one event page per extension or one per event?

How to find the origin of a browser event

My web application started firing off a ton of events while idle and I’ve been trying to hunt down who has been firing them.

I received a Chrome performance profile from a client and discovered that the events are being fired from the root of execution. This makes me believe that the events are coming from the user. But the odd thing is, is that the events are being fired so quickly that it’s impossible for a user to perform them.

I also doubt that these are being executed through the script or a timer because then the stack trace would be prepended with a timer fired or another function.

So now I’m at square one where I have reasons to doubt that a script is firing them and I have reasons to doubt that a user is firing them.

I’m going to reach out to my client and monitorEvents(https://developers.google.com/web/tools/chrome-devtools/console/events) on the element and then check to see if the event being fired isTrusted (https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted). If it is Trusted, then I have no idea what could be happening external to Chrome that’s causing so many events. And if it isn’t Trusted then I have no idea how to track the code that’s firing so many events.

Zoomed in profile execution stack

Zoomed out profile execution stack

Can a Chrome extension detect when the browser has finished starting up?

I have a Chrome extension that tracks tab usage and listens for tab-related events like onActivated, onUpdated, etc. It uses an event page instead of a persistent background page to add the event listeners.

The extension works fine while in the normal course of using the browser, but when Chrome is first launched, the extension gets tons of tab events while all the tabs are reloaded (if the user had lots of tabs open and the session is restored). This causes a lot of unnecessary processing when the browser launches, which I’d like to postpone until Chrome has settled down. But I’m not sure how to detect that change in state using an event page that normally has to re-add the event listeners every time it’s loaded.

I’ve tried something like the following to delay adding the tab event listeners until shortly after the last window has been created:

var gStartingUp = false;

chrome.runtime.onStartup.addListener(() => {
    var timer = null;

    gStartingUp = true;

    chrome.windows.onCreated.addListener(window => {
        clearTimeout(timer);
        timer = setTimeout(() => {
            gStartingUp = false;
            addListeners();
        }, 750);
    });
);

if (!gStartingUp) {
    addListeners();
}

In normal usage, gStartingUp would default to false and the listeners would get added. But when the browser fires the onStartup event, the handler isn’t called fast enough to prevent the addListeners() call from happening, so the listeners are added during startup as well. I suppose I could add a timeout before calling addListeners(), but that would delay adding them during normal usage.

Is there a way for an extension to reliably detect that Chrome has finished its startup processing?