The original

The transition from Puppeteer to ourselves may be easy, but is it worth it? What are the specific changes at the coding level? What are the new features and functions? This is our main concern in this article

The state of Puppeteer and offender

The two tools have a lot in common, but the two have grown at different paces in the past two years, leapfrog the Puppeteer. This trend has led many to move down the drain, and this article will describe the steps and the new features the change may bring. Although this article is a bit longer, it is easy to grasp.

Why migrate

In our previous tests, we have linked to Cypress, Selenium, Puppeteer and ourselves for the following reasons:

  • PlaywrightUpdates are more active and are less in terms of new featuresPuppeteerMore obvious
  • PlaywrightPerformance benefits in real-world end-to-end (E2E) testing (see details)The article links), test case execution is faster
  • PlaywrightBetter stability
  • PlaywrightinGitHub.Twitter.SlackWait for the neighborhood to get even hotterPuppeteerThe neighborhood is a little quieter

Change list

Here’s a comparison chart, read it for a few minutes, and we’ll talk more about it later

Puppeteer Playwright
puppeteer.launch(...) playwright.chromium.launch(...)
browser.createIncognitoBrowserContext(...) browser.newContext(...)
page.setViewport(...) page.setViewportSize(...)
page.waitForSelector(selector) page.click(selector); page.click(selector)
page.waitForXPath(XPathSelector) page.waitForSelector(XPathSelector)
page.$x(xpath_selector) page.$(xpath_selector)
page.waitForNetworkIdle(...) page.waitForLoadState({ state: 'networkidle' }})
page.waitForFileChooser(...) Removed, handled differently.
page.waitFor(timeout) page.waitForTimeout(timeout)
page.type(selector, text) page.fill(selector, text)
page.cookies([...urls]) browserContext.cookies([urls])
page.deleteCookie(... cookies) browserContext.clearCookies()
page.setCookie(... cookies) browserContext.addCookies(cookies)
page.on('request', ...) Handled through page.route.
elementHandle.uploadFile(...) elementHandle.setInputFiles(...)
Tricky file download. Better support for downloads.

Change the details

Package introduced

In Puppeteer, the first few lines of a script might look something like this:

const puppeteer = require('puppeteer');

(async() = > {const browser = await puppeteer.launch();
    const page = await browser.newPage();
  // ...
Copy the code

Down the drain, it goes like this:

const { chromium } = require('playwright');

(async() = > {const browser = await chromium.launch();
    const page = await browser.newPage();

  // ...
Copy the code

Down the drain, the offender provides out-of-the-box cross-browser support, allowing you to choose which browser you want to run, such as const {webkit} = require(‘ ourselves ‘); , Puppeteer needs to be configured through the launch interface:

const browser = await puppeteer.launch({ product: 'firefox' })
Copy the code

The context browser

A browser context exists in Puppeteer:

const browser = await puppeteer.launch();
const context = await browser.createIncognitoBrowserContext();
const page = await context.newPage();
Copy the code

In ourselves, the context is more important and is used slightly differently:

const browser = await chromium.launch();
const context = await browser.newContext();
const page = await context.newPage();
Copy the code

As with Puppeteer, the default context can be used for basic use and single-page streams:

const browser = await chromium.launch();
const page = await browser.newPage();
Copy the code

wait

The offender’s auto-waiting mechanism means you may not have to wait explicitly as often. However, waiting is one of the trickiest parts of UI automation, and you still need to know the different ways to have scripts explicitly wait for one or more conditions to be satisfied. In this regard, the offender has brought a few changes you might want to watch out for:

  • Page.waitfornavigation and Page.waitForSelector remain, but are not required in many use cases with automatic waiting
  • A new page. WaitForEvent
  • Puppeteerthepage.waitForXPathIt’s integratedpage.waitForSelectorSupports automatic identificationXPathexpression
  • Remove page.waitForFileChooser. See Upload Files, E2E Account Settings for new usage
  • Page.waitfornetworkidle is integrated into Page.waitForLoadState
  • Added page.waitForURL to allow waiting for a URL to complete loading by the page’s main frame
  • Page.waitfor (timeout) becomes Page.waitforTimeout (timeout)

Note that Page.waitForTimeout should not be used in the official production release, and the hard wait is only used for testing

Set the viewport

The page. SetViewport of the Puppeteer becomes page. SetViewportSize in the offender

Typing

Puppeteer’s Page. Type is still available, controlling fine-grained keyboard events, and the offender has added Page. Fill, used to fill and empty forms

Cookies

Cookies are processed at the page level with Puppeteer; With the offender, you can manipulate them at the BrowserContext level

Before:

  1. page.cookies([...urls])
  2. page.deleteCookie(... cookies)
  3. page.setCookie(... cookies)

Now:

  1. browserContext.cookies([urls])
  2. browserContext.clearCookies()
  3. browserContext.addCookies(cookies)

Notice the subtle differences between these methods, and how cookies are passed to them

XPath selectors

With / / or.. The initial XPath selector will be automatically identified, while the Puppeteer has a separate interface

The device emulation

The offender’s device emulation is provided at the browser context level:

const pixel2 = devices['Pixel 2']; const context = await browser.newContext({ ... pixel2, });Copy the code

In addition, you can control permissions, geographic location, and other device parameters.

File download

Trying to download files in headless Puppeteer mode can be tricky, and the offender may be leaner:

const [download] = await Promise.all([
    page.waitForEvent('download'),
    page.click('#orders > ul > li:nth-child(1) > a')])const path = await download.path();
Copy the code

This is a complete example

File upload

The Puppeteer elementHandle. The uploadFile becomes elementHandle setInputFiles

For details, see file upload examples.

Request to intercept

Request interception in Puppeteer is via page.on(‘request’,…) Implementation:

await page.setRequestInterception(true)

page.on('request', (request) => {
    if (request.resourceType() === 'image') request.abort()
    else request.continue()
})
Copy the code

In the ourselves, the page. Route may block the url of the specified pattern:

await page.route('* * / *'.(route) = > {
  return route.request().resourceType() === 'image'
    ? route.abort()
    : route.continue()
})
Copy the code

See the full example

Notable new features

Be sure to be aware of the many new features of ourselves when moving from Puppeteer to ourselves, as they may offer new solutions and possibilities for testing or monitoring setups

New selector engine

The offender provides a more flexible way to reference UI elements, adding the following methods in addition to CSS and XPath:

  • PlaywrightSpecific selectors, for example:nth-match(:text("Buy"), 3)
  • Text selectors, for exampletext=Add to Car
  • Chain selectors, for examplecss=preview >> text=In stock

In addition, you can create your own custom selector engine

For more information about and usage of selectors, see Working with Selectors

Save and reuse state

The offender can easily save the authentication state (cookie and localStorage) for a given session and use it later when the script runs to save authentication time

Locate the API

The Ourselves Locator API encapsulates the logic needed to retrieve a given element, allowing users to easily get the latest DOM element in a script at different points in time

Inspector

The Offender Inspector is a GUI tool that comes in handy when debugging scripts. It allows the consumer to step through the instructions in the script, making it easier to determine the cause of the failure.

Test

The offender has a Test mechanism that can be useful in E2E testing, such as out-of-the-box parallelization, hooks, and so on

Track view

Offender’s Trace Viewer allows you to explore traces recorded using the Playwriter Test or BrowserContext tracing API. Tracing provides the most detailed insight into script execution

Test generator

You can use the ourselves Test Generator to record the interaction in the browser. The output will be a complete script that can be checked and executed