0

I'm trying to create a chrome extension to interact with twitch website.

So far, it works most of the time, but randomly I get an error.

Here is the code of the content script:

var observer = new MutationObserver(function(mutations) {
 mutations.forEach(function(mutation) {
   for (var i = 0; i < mutation.addedNodes.length; i++){
    if (mutation.addedNodes[i].nodeType == 1){
        if (mutation.addedNodes[i].hasAttribute("aria-describedby")){
          mutation.addedNodes[i].querySelector("button").click();
        }
    }
   }
 });
});

window.addEventListener('load', function () {
    node = document.querySelector("[data-test-selector='community-points-summary']");
    observer.observe(node, { subtree: true, childList: true });
});

The problem is sometimes "node" is null, which creates an error:

Uncaught TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'.

My assumption is that the page is not fully loaded, then the querySelector fails to get the DOM. But I don't understand why this is happening, as I am in the "load" function, which should be fired only when the page is fully loaded.

It's a bit difficult to debug because it is mostly random. If I refresh the twitch page, then the script works. I feel like if the page is in the cache, I don't really have this issue, but I'm not sure.

Thanks.

whiteShadow
  • 369
  • 4
  • 19
  • yes node can be inserted after load (although I'm not sure that node actually does) – apple apple Sep 17 '20 at 14:51
  • why not add `var observer` inside of the load event listener? – Derek Pollard Sep 17 '20 at 14:52
  • maybe you can put a breakpoint and see the document tree at that point? – apple apple Sep 17 '20 at 14:52
  • @DerekPollard Probably just to keep the code flatter, it's pretty nested already – CertainPerformance Sep 17 '20 at 14:53
  • @CertainPerformance even so, he could make the call a function call instead of adding it directly to the load event, then call the function within the load event – Derek Pollard Sep 17 '20 at 15:01
  • @DerekPollard well he can, but no need to. – apple apple Sep 17 '20 at 15:04
  • @DerekPollard note that content script are run in isolated context, it'd not collide with page variable. – apple apple Sep 17 '20 at 15:05
  • @appleapple how do you put a breakpoint in a content script? – whiteShadow Sep 17 '20 at 15:07
  • @whiteShadow you need to click `>>` on source panel if it's hidden – apple apple Sep 17 '20 at 15:10
  • @whiteShadow or you can log a message from content script and just click that – apple apple Sep 17 '20 at 15:11
  • @appleapple Thanks, I'll try that – whiteShadow Sep 17 '20 at 15:17
  • maybe https://stackoverflow.com/questions/17119385/debugging-content-scripts-for-chrome-extension – apple apple Sep 17 '20 at 15:19
  • The problem is that to be able to debug it, you need to load the page once at least. But usually the error happen the first time I load the page. If I refresh, it usually works. – whiteShadow Sep 17 '20 at 15:22
  • you can keep devtool open, then trigger the behavior. – apple apple Sep 17 '20 at 15:24
  • I'm not sure what you mean. To be able to place a bp I need to have the source open, so I need to open the website first (and this is usually when the error happens). If I open it, place a bp, and refresh the page, it's unlikely the error will be triggered. – whiteShadow Sep 17 '20 at 15:29
  • Ok, I found that you can do a hard refresh with DevTools open. I'll try that. Thanks. But I'm pretty sure of what I will find. I think 'node' is empty sometimes, but I'm just not sure why. – whiteShadow Sep 17 '20 at 15:31
  • I tried but it seems difficult. I feel like it's a timing issue (load event is fired, but not everything is loaded or accessible, so the querySelector fails), but adding the debugger kind of mess up all of that, because everything loads slowly. – whiteShadow Sep 17 '20 at 15:40
  • @whiteShadow you can always wait until that node is added. maybe a setInterval, maybe observe it's parent... – apple apple Sep 17 '20 at 15:41
  • Yes I thought about adding a small waiting time, but I don't find that very clean. This is already the parent of what I'm trying to catch, but the problem is that most div don't have ids so it's difficult to find exactly which one you need to wait for. – whiteShadow Sep 17 '20 at 15:48

0 Answers0