google chrome - Unable to get the shadowRootPushed CDP event - Stack Overflow

admin2025-04-26  4

I'm trying to get CDP to send the DOM.shadowRootPushed event (experimental), but it never works.

I launched Chrome with the flag --remote-debugging-port=2222, connected to it, and sent DOM.enable to enable the DOM domain handler.

import WebSocket from 'ws';

async function connectToChrome() {
    const response = await fetch('http://localhost:2222/json');
    const endpoints = await response.json();

    let debuggerUrl = '';
    for (const i in endpoints) {
      if (endpoints[i].title === 'Simple html') {
        debuggerUrl = endpoints[i].webSocketDebuggerUrl;
      }
    }

    console.log('debuggerUrl', debuggerUrl);

    const ws = new WebSocket(debuggerUrl);

    ws.on('open', () => {
        console.log('Connected to Chrome');
        
        ws.send(JSON.stringify({
            id: 1,
            method: 'DOM.enable'
        }));
    });

    ws.on('message', (data) => {
        const message = JSON.parse(data);
        if (true) {
            console.log('Message received:', message);
        }
    });

    ws.on('error', (error) => {
        console.error('WebSocket error:', error);
    });
}

connectToChrome();

I have a simple HTML page that calls attachShadow when a button is clicked-

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simple html</title>
    <script>
        function test() {
            const dummy = document.getElementById('dummy');
            let shadowRoot = dummy.attachShadow({ mode: 'open' });
            const paragraph = document.createElement('p');
            paragraph.textContent = 'This content is encapsulated.';
            shadowRoot.appendChild(paragraph);
        }
    </script>
</head>

<body>
    <div id="dummy">
        <button onclick="test()">Click me</button>
    </div>
</body>

</html>

A few other details:

  1. When I enable 'Protocol monitor' in Devtools, I see the DOM.shadowRootPushed event, so it looks like the HTML is fine.
  2. Even on a Chrome browser with no flags, the event still shows up in Protocol Monitor, so I'm guessing there are no special Chrome flags that are needed for this event.
  3. When I reload my HTML page, I get the DOM.documentUpdated event, which means that the DOM domain handler must be running.

I'm wondering if there's some other CDP command that needs to be sent to make this work, but I'm unable to find any info on this.

I'm trying to get CDP to send the DOM.shadowRootPushed event (experimental), but it never works.

I launched Chrome with the flag --remote-debugging-port=2222, connected to it, and sent DOM.enable to enable the DOM domain handler.

import WebSocket from 'ws';

async function connectToChrome() {
    const response = await fetch('http://localhost:2222/json');
    const endpoints = await response.json();

    let debuggerUrl = '';
    for (const i in endpoints) {
      if (endpoints[i].title === 'Simple html') {
        debuggerUrl = endpoints[i].webSocketDebuggerUrl;
      }
    }

    console.log('debuggerUrl', debuggerUrl);

    const ws = new WebSocket(debuggerUrl);

    ws.on('open', () => {
        console.log('Connected to Chrome');
        
        ws.send(JSON.stringify({
            id: 1,
            method: 'DOM.enable'
        }));
    });

    ws.on('message', (data) => {
        const message = JSON.parse(data);
        if (true) {
            console.log('Message received:', message);
        }
    });

    ws.on('error', (error) => {
        console.error('WebSocket error:', error);
    });
}

connectToChrome();

I have a simple HTML page that calls attachShadow when a button is clicked-

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simple html</title>
    <script>
        function test() {
            const dummy = document.getElementById('dummy');
            let shadowRoot = dummy.attachShadow({ mode: 'open' });
            const paragraph = document.createElement('p');
            paragraph.textContent = 'This content is encapsulated.';
            shadowRoot.appendChild(paragraph);
        }
    </script>
</head>

<body>
    <div id="dummy">
        <button onclick="test()">Click me</button>
    </div>
</body>

</html>

A few other details:

  1. When I enable 'Protocol monitor' in Devtools, I see the DOM.shadowRootPushed event, so it looks like the HTML is fine.
  2. Even on a Chrome browser with no flags, the event still shows up in Protocol Monitor, so I'm guessing there are no special Chrome flags that are needed for this event.
  3. When I reload my HTML page, I get the DOM.documentUpdated event, which means that the DOM domain handler must be running.

I'm wondering if there's some other CDP command that needs to be sent to make this work, but I'm unable to find any info on this.

Share Improve this question asked Jan 15 at 3:59 SS221SS221 213 bronze badges 2
  • Judging by the source code, the event is sent only when a debugger is already attached at the time, so try mimicking devtools by attaching explicitly first (probably using Target), then [re]loading the page. – woxxom Commented Jan 15 at 4:09
  • @woxxom Thanks for the info. Calling Target.attachToTarget didn't help. Also tried sending DOM.enable over this new session to see if something changes. I now get DOM.documentUpdated over this session when I reload the page, but I still don't get DOM.shadowRootPushed. – SS221 Commented Jan 15 at 4:32
Add a comment  | 

1 Answer 1

Reset to default 0

Finally got it working, just need this 1 command-

    ws.send(JSON.stringify({
      id: 1,
      method: 'DOM.getDocument',
      params: { depth: -1, pierce: true }
    }));

Even DOM.enable isn't needed.

The documentation for DOM.getDocument says -

Returns the root DOM node (and optionally the subtree) to the caller. Implicitly enables the DOM domain events for the current target.

I was assuming that DOM.enable was the explicit way of enabling DOM domain events, and so I kept calling it, but it looks like DOM.getDocument is special. Not sure if this is a bug or not.

转载请注明原文地址:http://anycun.com/QandA/1745600227a91011.html