Re: Content script (Mv3) - JQuery selector not working in code but works in console log

355 views
Skip to first unread message
Message has been deleted

wOxxOm

unread,
Sep 24, 2021, 3:00:03 AM9/24/21
to Chromium Extensions, Lawrence
  1. The content script runs between `DOMContentLoaded` and `load` events by default so this element must be dynamically added by the page afterwards, which is typical for a modern page. You need to wait for the element to appear either by using MutationObserver or re-check periodically using setInterval or setTimeout.
  2. CSS selectors cannot start with a number, whereas HTML id attribute can, so the first digit `2` of the id is encoded using its ASCII code, which is 32 (hexadecimal). The space afterwards is used only to separate the code from the next digit and is not a part of the final result.

On Friday, September 24, 2021 at 3:01:02 AM UTC+3 Lawrence wrote:
populateField(inputId, inputValue) {
   // other code here but I console.log and logic gets to the below command
   // I also wrapped in try catch and no error logged
   $(inputId).val(inputValue);
}

populateField("#\\32 63val-field_1\\.3\\.7--input", "test");

When I call the populateField() within the content script it's not updating the value of the input field, however, if I try the code below in the Chrome console, it works fine and assigns the value in the input field.

$( "#\\32 63val-field_1\\.3\\.7--input"  ).val("test");

The HTML has the input field ID as "263val-field_1.3.7--input".

Please note that other JQuery commands work within the content script.

I have of course JQuery loaded in manifest.json using the "content_scripts". Also, I am trying to test this on a page where the content script is loaded (based on "matches").

1. Any ideas why it might not be working or what am I missing?

2. Can someone explain what the "\\3" part means (got the whole query selector from copy JS path with Chrome)?

Thank you for the help.


Message has been deleted
Message has been deleted

wOxxOm

unread,
Sep 26, 2021, 1:54:18 AM9/26/21
to Chromium Extensions, Lawrence, wOxxOm
> If these input fields are dynamically created, shouldn't the content script have access to them when I can see the input fields on the page?

No, the content script runs just once and it happens before the element is created by the page.

I'm assuming you clicked the reload icon on chrome://extensions page and reloaded the web page tab after making changes so here's a few more ideas.
  1. To use MutationObserver you need to observe some parent node e.g. document.body, look for examples.
  2. The iframe may have a different URL so your "matches" in "content_scripts" won't apply.
  3. The iframe may have no URL so you also need to add "match_about_blank": true to the content script declaration.
  4. The reason the code works in console may be that the site is using its own jQuery. Try this:

    document.querySelector('div.ember-view.form_field.requester.agent.requester_id > div.zd-searchmenu.zd-searchmenu-root > input').focus();
    document.execCommand('insertText', false, 'new text');
    document.querySelector('[id^=ember] > div.LRbr > button').dispatchEvent(new MouseEvent('click', {bubbles: true}));
On Sunday, September 26, 2021 at 3:18:53 AM UTC+3 Lawrence wrote:
I tried the setInterval() and setTimeout() and don't work in the content script, but work in chrome console. I cannot get MutationObserver to work because it needs a node, and guess what?, it's not finding the node of one of the input fields that I'm trying to populate.

I'm trying to populate Zendesk input fields on a new ticket. I thought maybe it's using frames, so I specified "all_frames": true under "content_scripts" in manifest.json. No difference.

It's strange because in the content script I have the below and they work. The first fills in an email address fine, and the second clicks the "take it" link.

$("div.ember-view.form_field.requester.agent.requester_id > div.zd-searchmenu.zd-searchmenu-root > input").val("exa...@example.com");
$("[id^=ember] > div.LRbr > button").click();

But the input fields aren't being populated (probably because they are not found / undefined), yet the same code works in the chrome console.

If these input fields are dynamically created, shouldn't the content script have access to them when I can see the input fields on the page?

Any ideas on how to fix this?

Thank you.

On Friday, September 24, 2021 at 7:17:14 AM UTC-6 Lawrence wrote:
Hi, thank you for your reply. I agree it's probably created dynamically. The content script is fully loaded. I can visually see the input fields displayed (this is actually for a Zendesk ticket). I manually activate when to populate the input fields via pressing a button from the popup script (which is after I can see the input fields on the form/page). So, I don't think that's it but of course, I'm willing to give MutationObserver a try. Thank you for #2 answer too, that makes sense.
Message has been deleted

wOxxOm

unread,
Sep 27, 2021, 2:16:14 AM9/27/21
to Chromium Extensions, Lawrence, wOxxOm
Can you post a link to the site?

On Monday, September 27, 2021 at 9:09:02 AM UTC+3 Lawrence wrote:
Yes, I'm always reloading the extension and refreshing pages that I'm testing this on. The content script may run once but it waits until it's triggered by my extension popup. I click a button from the extension popup (and send message) to initiate in the content script to try to populate the fields. Yes, I have the correct current tab and I can only get two fields to work so far (the ones already mentioned)

Thanks about the match_about_blank. It is using frames, so I added that to manifest.json, but it didn't make any difference. I'm not sure why you have me try those three statements in the console since the JQuery already works in the content script. 

The focus and insertText I tried in the console and don't work unless I first manually click and put the cursor in the input box. The MouseEvent line/command works but as mentioned, the JQuery works already within the content script.

How does it help to observe from the body element? I have not tried this yet. I did within the content script $("input field query in here").get(0) to try and return the nodes of the input fields I'm interested in and checked if they're an instanceOf Node and all came back false. So these dynamic or input fields are not being seen by the content script which means I cannot populate them?
Message has been deleted

wOxxOm

unread,
Sep 27, 2021, 10:12:20 AM9/27/21
to Chromium Extensions, Lawrence, wOxxOm
>   I'm not sure why you have me try those three statements in the console since the JQuery already works in the content script. 

That example is for the content script. It uses a different approach: it focuses the input, runs execCommand to insert the text, dispatches the change event.

> How does it help to observe from the body element?

There are lots of examples for MutationObserver.

>  So these dynamic or input fields are not being seen by the content script which means I cannot populate them?

If $('......') is an empty array then this selector didn't match anything i.e. there are no such elements in the current document.

Anyway, such issues should be easy to debug. Set a breakpoint in your content script's onMessage in devtools and when it triggers, switch to the elements inspector panel in devtools and see what's there at this exact moment on the content script's timeline.

On Monday, September 27, 2021 at 4:57:50 PM UTC+3 Lawrence wrote:
Sorry, no, this is for Zendesk (ZD) ticketing system for businesses. One needs to have an account. A business can create custom input fields per their needs.

Main site (free trial available):

Support site:

Every time a new ticket is created, ZD changes the value of the HTML ID's. The HTML ID's don't stay the same from new ticket to ticket. I'm having to grab all the labels, checking for the ones I want (e.g. first name, last name, phone, etc.) in order to know the HTML ID of its associated input ID. That's working fine (I'm logging to console log to confirm). So, I'm confused why the content script can access/query the labels, but not find or populate the input fields. I take the code to query and populate input fields from the content script and run it in the console and it works fine.

Example: ZD label ID for a phone field could be "263val-field_1.3.7--label" when a new ticket is created and its corresponding input field would be "263val-field_1.3.7--input". The next time you create a new ticket the phone field ID label number could be anything like "186val-field_1.3.7--label" and its corresponding input field would be "186val-field_1.3.7--input".

Yes, ZD uses its own JQuery too (v2.4+). I'm loading a newer version 3.6+ in the content script.

Thank you for the help.

wOxxOm

unread,
Sep 27, 2021, 10:38:34 AM9/27/21
to Chromium Extensions, wOxxOm, Lawrence
Note that MutationObserver was just an idea assuming the element doesn't actually exist, which you need to verify first. If the element exists then the problem is something else so it might be helpful if you make a recording of devtools element inspector or otherwise show us what happens.
Reply all
Reply to author
Forward
0 new messages