Using script recorders
With Playwright and Puppeteer, writing scripts by hand is not the only option. Since browser automation first became possible, there have always been tools trying to simplify script creation. Such instruments normally aim to help users with little or no scripting skills use automation tools, while also saving more expert users time when creating brand new scripts.
Recorders can be used to quickly generate code for a scenario, saving time users would otherwise have to spend inspecting the various pages to find valid selectors. When creating multiple scripts, this adds up to a noticeable amount of time saved.
Extensions vs libraries
In the world of headless automation, most open-source recorders are available in one of two formats:
-
As extensions to be installed and run from your browser, e.g. Headless Recorder
-
As libraries which launch a new browser session, e.g. QAWolf
Both types will record different input events and generate the corresponding code line-by-line.
Using recorders effectively
Regardless of the approach you choose, you will want to inspect the output scripts to make sure they are doing what you need them to in the fastest and most reliable way possible. In the interest of efficiency, it is recommended that you choose a recorder that outputs scripts that do not require too much tweaking.
That being said, you should always double-check the newly created scripts and tweak it when necessary, especially keeping an eye out for:
- Selectors, which should be in line with common best practices.
- Waits, which should ensure the right element is present and/or ready for interaction at the right time; also, make sure you get rid of unnecessary waits.
- Any sort of needless duplication.
An example of recorded Puppeteer script:
const puppeteer = require('puppeteer')
;(async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
const navigationPromise = page.waitForNavigation()
await page.goto('https://danube-web.shop/')
await page.setViewport({ width: 1792, height: 934 })
await navigationPromise
await navigationPromise
await page.waitForSelector('body > #app > .topbar > input')
await page.click('body > #app > .topbar > input')
await page.waitForSelector('body > #app #button-search')
await page.click('body > #app #button-search')
await page.waitForSelector(
'.shop-content > ul > .preview:nth-child(1) > .preview-details > .preview-price'
)
await page.click(
'.shop-content > ul > .preview:nth-child(1) > .preview-details > .preview-price'
)
await page.waitForSelector(
'#app-content > .main-container > .detail > .detail-wrapper > .call-to-action'
)
await page.click(
'#app-content > .main-container > .detail > .detail-wrapper > .call-to-action'
)
await browser.close()
})()
We can modify this script to improve readability and efficiency:
- The duplicated
await navigationPromise
on line 14 serves no purpose and can be deleted. - The
page.waitForSelector
on line 16 is not needed as we already are waiting on the navigationPromise. - The
page.waitForSelector
on line 19 can be skipped as the element is present on the same page as the previous one. - All the selectors used can be refactored.
const puppeteer = require('puppeteer')
;(async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
const navigationPromise = page.waitForNavigation()
await page.goto('https://danube-web.shop/')
await page.setViewport({ width: 1792, height: 934 })
await navigationPromise
await page.click('input')
await page.click('#button-search')
await page.waitForSelector('.preview:nth-child(1)')
await page.click('.preview:nth-child(1)')
await page.waitForSelector('.call-to-action')
await page.click('.call-to-action')
await browser.close()
})()
Like all scripts, recorded scripts need to be maintained in order to remain useful over time.
Takeaways
- Recorders are a powerful tool to speed up script creation.
- Recorded scripts should always be inspected and possibly tweaked to ensure correctness and efficiency.
- Script maintenance is still required after scripts have been recorded.
Further reading
- Headless Recorder and QAWolf’s GitHub repositories.
- Playwright CLI also enables script recording.