question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[BUG] initiators missing from Chrome Debug Protocol messages

See original GitHub issue

System:

  • Browser: Chromium
  • OS: Linux 5.10 Ubuntu 20.04.3 LTS (Focal Fossa) (WSL2 on Windows)
  • Memory: 21.72 GB / 24.84 GB
  • Container: Yes

Binaries:

  • Node: 14.17.6 - ~/.nvm/versions/node/v14.17.6/bin/node
  • npm: 8.0.0 - ~/.nvm/versions/node/v14.17.6/bin/npm

Languages:

  • Bash: 5.0.17 - /usr/bin/bash

npmPackages:

  • playwright: ^1.18.0-alpha-nov-18-2021 => 1.18.0-alpha-nov-18-2021

Code Snippet

import express from "express";
import type { Server } from "http";
import { chromium } from "playwright-core";

const options = {
  port: 5051,
};

main();

async function main() {
  const browser = await chromium.launch();

  const context = await browser.newContext();

  const server = await createTestServer();

  // return; // 👈 uncomment this to run the test-server stand-alone

  const page = await context.newPage();

  const session = await context.newCDPSession(page);

  await session.send("Network.enable");

  session.on("Network.requestWillBeSent", payload => {
    console.log(payload);
  });

  await page.goto(`http://localhost:${options.port}/test`, { waitUntil: "load" });

  await new Promise(resolve => setTimeout(resolve, 2000)); // wait for image to load
  
  await page.close()
  await context.close();
  await browser.close();

  await new Promise(resolve => server.close(resolve));
}

const PAGE = `<!DOCTYPE html>
<head>
  <title>Image cookies test page</title>
</head>
<body>
  <h3>Setting a <code>hello_script</code> cookie using a script to set the <code>src</code> property.</h3>
  <img data-src="https://via.placeholder.com/200x100">

  <script>
    window.addEventListener("load", () => {
      document.querySelectorAll("img[data-src]").forEach(img => {
        img.src = img.getAttribute("data-src");
      });
    });
  </script>
</body>
`;

async function createTestServer(): Promise<Server> {
  return new Promise(resolve => {
    const app = express();

    // Serve a test page:

    app.get("/test", (req, res) => {
      res.setHeader("Content-Type", "text/html");

      res.send(PAGE);
    });

    // Launch the server:

    const server = app.listen(options.port, () => resolve(server));
  });
}

Note that the script requires an npm install express for the test-server.

Bug Report

It appears Playwright is doing something that alters the normal behavior/results of CDP Network messages.

I encountered this while monitoring pages that lazy-load images - having <img> tags with no src-attribute is rather common in scripts that lazy-load images, and the test-script provided here is a minimal script demonstrating the problem, which occurs when an <img> tag is on the page at load-time, while the src-property gets initialized by a script at run-time.

If you run the test-script above, the payload of the second Network.requestWillBeSent message (from loading the image) is missing the initiator information:

image

If you uncomment the return statement near the beginning of the script, you can open the page http://localhost:5051/test in a browser, where you can use Protocol Monitor to inspect the same events - here, the result is as expected, with detailed information about the initiator, including a stack-trace:

image

As noted, I’m on Windows WSL2 myself - since I can’t open Playwright’s Chromium fork in headed mode, I created this screenshot using Chrome proper, but I also had a friend open your fork in headed mode, and this works correctly.

So the issue is not caused by some change to your fork, and it’s not caused by running headless either.

Perhaps Playwright is meddling with the run-time environment somehow?

Or perhaps the loading sequence or timing is somehow different when Playwright issues commands from page.goto?

It appears newCDPSession does not in fact create a new session, but might reuse an existing session? If the CDP session I’m getting is not in fact a dedicated session, but a shared reference to Playwright’s internal CDP session, perhaps the issue is that Playwright’s facilities are somehow issuing commands that cause the CDP session to behave differently?

These are all the clues I could think of… I hope this is helpful. 🙂

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
eliassorensencommented, Nov 23, 2021

Okay, I now understand why opening DevTools makes it work.

DevTools sends Debugger.enable to CDP. This, and having the correct async callstack depth makes it work.

Now, I wonder why opening DevTools “fixes” the CDP session we create in Playwright. As far as I understood, those two sessions should not affect each other?

Adding the following fixed the initiator to correctly show the callstack instead of “other”:

await session.send('Debugger.enable');
await session.send("Debugger.setAsyncCallStackDepth", {maxDepth:32});
0reactions
eliassorensencommented, Nov 23, 2021

I have created the following ticket on Chromium’s end: https://bugs.chromium.org/p/chromium/issues/detail?id=1273075

Read more comments on GitHub >

github_iconTop Results From Across the Web

What's New In DevTools (Chrome 80)
Support for let and class redeclarations in the Console, improved WebAssembly debugging, and more.
Read more >
How to retrieve the Initiator of a request when extending ...
You are correct in that the initiator is not exposed through devtools extensions API -- currently, the resource properties that the API ...
Read more >
Network domain - Chrome DevTools Protocol - GitHub Pages
Error message. bundleRequestId: RequestId. Bundle request identifier. Used to match this information to another event. This made be absent in case when the ......
Read more >
Web Workers Panel Missing? - Google Groups
You received this message because you are subscribed to the Google Groups "Google Chrome Developer Tools" group. To unsubscribe from this group and...
Read more >
Using the Chrome Debugger Tools, part 3: The Source Tab
Since Javascript halts execution on an error, though, the code below this line will never be invoked, leaving you to wonder what was...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found