Extracting Chrome DevTools Network Trace with Playwright

ExecuteAutomation
ExecuteAutomation
Published in
2 min readMay 8, 2021

Playwright

If you have not heard of Playwright before, Playwright is an Open-source FREE to use testing tool which does support most of the popular browsers and platforms. Playwright also supports many different language bindings such as C#, Java, JS, TS and Python. Playwright is actively developed and maintained by Microsoft Team.

Playwright also provides APIs to monitor and modify network traffic, both HTTP and HTTPS. Any requests that page does, including XHRs and fetch requests, can be tracked, modified and handled.

Some of the interesting things we can do with having this API are

  • HTTP Authentication
  • Intercept XHR and understand the response
  • Trace the network
  • Set network speed and understand how page loads
  • Modify the network request made by the page and verify how application behaves

Playwright Tracing

Playwright supports Chromium-specific features including Tracing, service worker support, etc.

In order to enable tracing in our code, here is the line of code to do it

await browser.startTracing(page,{path:`trace.json`,screenshots:true, categories: ['devtools.timeline']});

The above line of code will generate a trace.json as shown below

{"traceEvents":[{"args":{"name":"swapper"},"cat":"__metadata","name":"thread_name","ph":"M","pid":35881,"tid":0,"ts":0},{"args":{"name":"CrBrowserMain"},"cat":"__metadata","name":"thread_name","ph":"M","pid":35881,"tid":515,"ts":0},{"args":{"name":"CrRendererMain"},"cat":"__metadata","name":"thread_name","ph":"M","pid":35903,"tid":515,"ts":0},{"args":{"name":"ThreadPoolForegroundWorker"},"cat":"__metadata","name":"thread_name","ph":"M","pid":35903,"tid":16643,"ts":0},{"args":{"name":"ThreadPoolForegroundWorker"},"cat":"__metadata","name":"thread_name","ph":"M","pid":35903,"tid":18435,"ts":0},{"args":{"name":"ThreadPoolForegroundWorker"},"cat":"__metadata","name":"thread_name","ph":"M","pid":35881,"tid":48387,"ts":0},{"args":{"name":"ThreadPoolForegroundWorker"},"cat":"__metadata","name":"thread_name","ph":"M","pid":35895,"tid":28419,"ts":0},{"args":{"name":"Browser"},"cat":"__metadata","name":"process_name","ph":"M","pid":35881,"tid":0,"ts":0},{"args":{"name":"GPU Process"},"cat":"__metadata","name":"process_name","ph":"M","pid":35895,"tid":0,"ts":0},{"args":{"name":"Renderer"},"cat":"__metadata","name":"process_name","ph":"M","pid":35903,"tid":0,"ts":0},{"args":{"data":{"frame":"208226377A02CECC4CC0F2B8B57E9C81","id":1}},"cat":"devtools.timeline","name":"RequestAnimationFrame","ph":"I","pid":35903,"s":"t","tid":515,"ts":115414610059,"tts":281925},{"args":{"data":{"frame":"208226377A02CECC4CC0F2B8B57E9C81","id":1}},"cat":"devtools.timeline","dur":546,"name":"FireAnimationFrame","ph":"X","pid":35903,"tdur":545,"tid":515,"ts":115414610924,"tts":282293},{"args":{"data":{"columnNumber":27,"frame":"208226377A02CECC4CC0F2B8B57E9C81","functionName":"onRaf","lineNumber":2082,"scriptId":"11","url":""}},"cat":"devtools.timeline","dur":268,"name":"FunctionCall","ph":"X","pid":35903,"tdur":268,"tid":515,"ts":115414611100,"tts":282469},{"args":{"data":{"frame":"208226377A02CECC4CC0F2B8B57E9C81","id":2}},"cat":"devtools.timeline","name":"RequestAnimationFrame","ph":"I","pid":35903,"s":"t","tid":515,"ts":115414611350,"tts":282719},{"args":{"data":{"frame":"208226377A02CECC4CC0F2B8B57E9C81"}},"cat":"devtools.timeline","dur":16,"name":"UpdateLayerTree","ph":"X","pid":35903,"tdur":16,"tid":515,"ts":115414611773,"tts":283142},{"args":{"data":{"frame":"208226377A02CECC4CC0F2B8B57E9C81","id":2}},"cat":"devtools.timeline","dur":227,"name":"FireAnimationFrame","ph":"X","pid":35903,"tdur":226,"tid":515,"ts":115414615816,"tts":283767},{"args":{"data":{"columnNumber":27,"frame":"208226377A02CECC4CC0F2B8B57E9C81","functionName":"onRaf","lineNumber":2082,"scriptId":"11","url":""}},"cat":"devtools.timeline","dur":92,"name":"FunctionCall","ph":"X","pid":35903,"tdur":92,"tid":515,"ts":115414615841,"tts":283792},{"args":{"data":{"frame":"208226377A02CECC4CC0F2B8B57E9C81"}},"cat":"devtools.timeline","dur":12,"name":"UpdateLayerTree","ph":"X","pid":35903,"tdur":12,"tid":515,"ts":115414616059,"tts":284009}}

Once we have the trace information in the trace.json file, we can then perform any operation we are intended to something like extracting its events based on the category and also the one which has screenshot in it

const traceData = traceInfo.traceEvents.filter(x => (    x.cat === ‘disabled-by-default-devtools.screenshot’ &&    x.name === ‘Screenshot’ &&    typeof x.args !== ‘undefined’ &&    typeof x.args.snapshot !== ‘undefined’));

We can also additionally stored the screenshots in our project directory if you are interested

traceData.forEach(function(snap, index) {fs.writeFile(`trace-screenshot-${index}.png`, snap.args.snapshot, 'base64', function(err) {if (err) {    console.log('write error', err);
}
});})

The complete discussion is available in the Udemy course https://www.udemy.com/course/e2e-playwright/

— Karthik KK

Here is the complete video of the above discussion

If you are interested in the Udemy course of Playwright, do leave your details on the comments, I will send you across the discount code for you to avail the course in much cheaper price.

Thanks,

Karthik KK

--

--

ExecuteAutomation
ExecuteAutomation

ExecuteAutomation Ltd is a Software testing and its related information service company founded in 2020. Info available in YouTube and Udemy as video courses .