I touched the latest automatic test tool "Playwright for Python"

"Playwright", which was an E2E automatic test tool for JavaScript, ** It was preview-released as "Playwright for Python" for Python **, so I immediately touched it.

Announcing Playwright for Python: Reliable end-to-end testing for the web

What is Playwright?

Playwright is a library that automates Chromium, Firefox, and Webkit with a single API. This allows you to perform fast and reliable cross-browser tests.

Benefits of Playwright

The Official Document states the following four points. Below is my translation.

1. Supports all browsers

--Supports Chromium, Firefox, Webkit (Safari). --Cross-platform testing of Webkit is possible. (Windows, Mac, Linux) --You can test your browser for mobile. --It can be executed in either headless mode or headful mode.

2. Fast and reliable test execution

--The API will wait automatically. ――Automation without timeout is possible. --Parallel execution is possible using Browser Context. --You can use an element selector that is resistant to changes.

3. Achieve powerful automation

-Supports multiple domains, pages, and frames. --Powerful network control is possible. --You can use modern Web functions. (Shadow DOM, geolocation, permissions, etc ...) ――It has a function to cover all scenarios. (From file DL / UL to dark mode)

4. Integration with workflow

--Can be installed in one line. --Supports TypeScript. --Can be integrated with debugging tools. --Python and C # bindings are available. --You can deploy the test to CI. (Official Docker image, provided by GitHub Actions)

Hands-on

From here, I will actually write a test case. I used the HOTEL PLANISPHERE room reservation (plan with special benefits) page for the test target. .. The test case was a normal test, "Access the page to be tested, set each parameter, then move to the reservation confirmation page, and if the amount displayed there is 15,000 yen, pass".

Installation

Install according to the description on the official GitHub. Also, this time we will use pytest as a unit test framework, so Install the pytest plugin.

pip install playwright
python -m playwright install
pip install pytest-playwright

It will not be executed this time, but if you want to execute asynchronous processing, please perform pip install asyncio separately.

First try writing a test with Selenium

Before touching Playwright, I wrote a test case that I want to realize this time with Selenium Webdriver as a reference. It's quite difficult to manage the number of import statements, wait processing for dynamic content, and Webdriver management for each browser.

selenium.py


import time

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select, WebDriverWait
from webdriver_manager.chrome import ChromeDriverManager


class TestPlanisphere:
    def test_reserve_otoku(self):
        driver = webdriver.Chrome(ChromeDriverManager().install())
        wait = WebDriverWait(driver, 10)

        driver.get("https://hotel.testplanisphere.dev/ja/reserve.html?plan-id=0")
        # NOTE: wait.until(EC.presence_of_all_elements_located) <-Doesn't work
        time.sleep(1)  # HACK

        date = driver.find_element_by_id("date")  #Accommodation date
        date.clear()
        date.send_keys("2020/12/24")
        date.send_keys(Keys.TAB)

        term = driver.find_element_by_id("term")  #number of stays
        term.clear()
        term.send_keys("2")

        head_count = driver.find_element_by_id("head-count")  #Number of people
        head_count.clear()
        head_count.send_keys("1")

        sightseeing = driver.find_element_by_id("sightseeing")  #Select "Great Sightseeing Plan"
        if not sightseeing.is_selected():
            sightseeing.click()

        driver.find_element_by_id("username").send_keys("Beri-bo")  #name

        Select(driver.find_element_by_id("contact")).select_by_value("tel")  #"I would like to be contacted by phone"

        driver.find_element_by_id("tel").send_keys("80120828828")  #phone number

        driver.find_element_by_id("submit-button").click()  #Transition to reservation confirmation page
        wait.until(EC.presence_of_all_elements_located)

        driver.save_screenshot("selenium.png ")  #Take screenshot

        assert "15,000" in driver.find_element_by_id("total-bill").text

        driver.quit()

Write a test with Playwright for Python

Then I wrote the same test in Playwright for Python. The methods used this time are summarized on the following pages of the official document. Although it is described only in JavaScript, it can be used almost entirely in Python.

play.py


from playwright.sync_api import Page


class TestPlanisphere:
    def test_reserve_otoku(self, page: Page):
        page.goto("https://hotel.testplanisphere.dev/ja/reserve.html?plan-id=0")
        page.waitForLoadState("networkidle")

        page.fill("#date", "2020/12/24")  #Accommodation date
        page.press("#date", "Tab")

        page.fill("#term", "2")  #number of stays

        page.fill("#head-count", "1")  #Number of people

        page.check("#sightseeing")  #Plan selection

        page.fill("#username", "Beri-bo")  #name

        page.selectOption("#contact", "tel")  #"I would like to be contacted by phone"
        page.fill("#tel", "80120828828")  #phone number

        page.click("#submit-button")  #Transition to reservation confirmation page
        page.waitForLoadState("networkidle")

        page.screenshot(path="playwright.png ")  #Take screenshot

        assert "15,000" in page.innerText("#total-bill")

        page.close()

Compared to Selenium

--Simple module configuration, almost no import statement required --If you import the Page type and combine it with pylance, you can complete the method search on VS Code, which is very convenient. --Cross-browser support (the browser to start can be specified when running pytest) --Each browser is built into the package, so there is no need for webdriver version control. --Excellent standby processing for dynamic content

You can see that Selenium has solved the difficult part by just looking at the script.

Run Playwright tests with pytest

All you have to do now is run the above play.py in pytest. You can specify headless / headful and execution browser as a run-time option. You can also save the boot options in the file pytest.ini. ](Https://github.com/microsoft/playwright-pytest#usage)

#Test run(Headless Chromium is the default)
pytest play.py

#Test run in headful mode
pytest --headful play.py

#Test execution by specifying a browser(chromium, firefox, webkit)
pytest --browser firefox play.py

#Test run in multiple browsers
pytest --browser chromium --browser webkit play.py

Impressions

I think there are two directions for the evolution of automation tools, I think that one is to evolve as a multifunctional test platform that integrates reporting functions and CI functions, and the other is to evolve as a lightweight, high-speed, programmable tool. I felt that Playwright would be a powerful option for the latter.

The backing of a giant called Microsoft (and the origin is Google's Puppeteer ...) is very powerful as OSS, and future enhancements can be expected, so it is better to start from now on the preview release. think.

To be honest, I personally felt that it was much easier and less expensive to learn than Selenium, so I will give priority to Selenium when it can be used!

Recommended Posts

I touched the latest automatic test tool "Playwright for Python"
Created AtCoder test tool for Python
I made a scaffolding tool for the Python web framework Bottle
I touched the data preparation tool Paxata
[Python] I tried substituting the function name for the function name
vprof --I tried using the profiler for Python
I tried python programming for the first time.
[Python] I searched for the longest Pokemon Shiritori
I touched some of the new features of Python 3.8 ①
[Trainer's Recipe] I touched the flame of the Python framework.
What I got into Python for the first time
I tried Python on Mac for the first time.
I tried python on heroku for the first time
A memo that I touched the Datastore with python
I moved the automatic summarization API "summpy" with python3.
I was hooked for 2 minutes with the Python debugger pdb
For the G test 2020 # 2 exam
I touched the Qiita API
I tried programming the chi-square test in Python and Java.
Python template for Codeforces-manual test-
I didn't know how to use the [python] for statement
I just wrote the original material for the python sample code
Miscellaneous notes that I tried using python for the matter
I passed the Python data analysis test, so I summarized the points
I downloaded the python source
A memorandum of understanding for the Python package management tool ez_setup
I tried using the python module Kwant for quantum transport calculation
Python> I made a test code for my own external file
[Python] LINE notification of the latest information using Twitter automatic search
Prepare a distributed load test environment with the Python load test tool Locust
I touched PyAutoIt for a moment
Install Cheminformatics Tool RDKit for Python
AtCoder: Python: Daddy the sample test.
I liked the tweet with python. ..
See python for the first time
I wrote the queue in Python
What is the python underscore (_) for?
I wrote the stack in Python
Command for the current directory Python
I tried to refer to the fun rock-paper-scissors poi for beginners with Python
Experience Part I "Multinational Currencies" in the book "Test Driven Development" in Python
[Python] I examined the exe conversion method for distributing business efficiency tools.
I measured the speed of list comprehension, for and while with python2.7.
Introducing the BOT framework Minette for Python
Python visualization tool for data analysis work
I tried tensorflow for the first time
Write the test in a python docstring
Python environment tool comparison chart for Rubyist
Python Master RTA for the time being
I tried the OSS visualization tool, superset
Launch the Discord Python bot for 24 hours.
I didn't know the basics of Python
MongoDB for the first time in Python
[Python] I personally summarized the basic grammar.
I wrote the code for Gibbs sampling
Pandas of the beginner, by the beginner, for the beginner [Python]
Python: I tried the traveling salesman problem
The Python project template I think of.
A tool for easily entering Python code
I searched for prime numbers in python
[Python beginner] I collected the articles I wrote