Warning: fopen(/tmp/SghXTngBZPli-Rt9zhl.tmp): failed to open stream: Disk quota exceeded in /home/executea/public_html/blog/wp-admin/includes/class-wp-filesystem-ftpext.php on line 139

Warning: unlink(/tmp/SghXTngBZPli-Rt9zhl.tmp): No such file or directory in /home/executea/public_html/blog/wp-admin/includes/class-wp-filesystem-ftpext.php on line 142
Site Loader
Auckland, New Zealand

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},
{"args":{"data":{"frame":"208226377A02CECC4CC0F2B8B57E9C81"}},"cat":"devtools.timeline","dur":17,"name":"UpdateLayerTree","ph":"X","pid":35903,"tdur":15,"tid":515,"ts":115414620118,"tts":286137},

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

Post Author: Karthik kk

Leave a Reply

Your email address will not be published. Required fields are marked *