Playwrightとは?
E2E自動テストの作成を助けてくれるフレームワーク
公式:https://playwright.dev/
githug:https://github.com/microsoft/playwright
TypeScriptやJavaScriptで扱うのが基本っぽい
これ以外でも当記事で扱うPythonの他、Javaや.Netもサポートしている
インストール
参考
環境
Windows10Pro
Python3.8.8
公式の通りにコマンドを打ち込んでいったら動いた (から、公式を見た方が良い)
# pytest(pythonのテストフレームワーク)のプラグインをインストール
pip install pytest-playwright
# 必要なブラウザのインストール
playwright install
これでインストールは完了
操作を記録する
ここではgoogleの検索を実行する操作を記録する
https://www.google.com/
操作を記録するコマンド
Playwright codegen【対象ページのURL】-o【出力ファイルパス】
# 操作の記録をpythonのコードで現在のフォルダ配下に保存する
Playwright codegen https://www.google.com/ -o PlaywrightSample.py
これを実行するとブラウザが起動し、googleのページが表示する
ここまでやって、コマンドプロンプト上の現在のフォルダを確認すると、pythonコードが出来上がっている
こんな感じのソースが出力される
from playwright.sync_api import Playwright, sync_playwright, expect
def run(playwright: Playwright) -> None:
browser = playwright.chromium.launch(headless=False)
context = browser.new_context()
# Open new page
page = context.new_page()
# Go to https://www.google.com/
page.goto("https://www.google.com/")
# Click text=ログインせずに使う
page.frame_locator("iframe[role=\"presentation\"]").locator("text=ログインせずに使う").click()
# Click [aria-label="検索"]
page.locator("[aria-label=\"検索\"]").click()
# Fill [aria-label="検索"]
page.locator("[aria-label=\"検索\"]").fill("今日の天気")
# Click [aria-label="検索"]
page.locator("[aria-label=\"検索\"]").click()
# Press Enter
page.locator("[aria-label=\"検索\"]").press("Enter")
page.wait_for_url("https://www.google.com/search?q=%E4%BB%8A%E6%97%A5%E3%81%AE%E5%A4%A9%E6%B0%97&source=hp&ei=pJoEY-CECavs2roP9IGkqA0&iflsig=AJiK0e8AAAAAYwSotFt-9IhNDjLm4nMhtp0zg_Urj1OT&ved=0ahUKEwjg5oyF0Nz5AhUrtlYBHfQACdUQ4dUDCAk&uact=5&oq=%E4%BB%8A%E6%97%A5%E3%81%AE%E5%A4%A9%E6%B0%97&gs_lcp=Cgdnd3Mtd2l6EAMyDQgAEIAEEMkDEEYQgAIyBQgAEJIDMgUIABCSAzIFCAAQgAQyCAgAELEDEIMBMgUIABCABDIFCAAQgAQyCwgAEIAEELEDELEDMggIABCxAxCDATIFCAAQgAQ6CAgAEI8BEOoCOgYIABAEEAM6DQgAEIAEELEDEIMBEAQ6BwgAEIAEEAQ6CggAEIAEELEDEAQ6EAgAEIAEELEDEIMBEMkDEAQ6FQgAEIAEELEDEIMBEMkDEAQQRhCAAjoSCAAQgAQQsQMQgwEQBBBGEIACOg8IABCABBDJAxAEEEYQgAI6GQgAEIAEELEDEIMBELEDEIMBEMkDEEYQgAI6EQgAEIAEELEDEIMBELEDEIMBOh0IABCABBCxAxCDARCxAxCDARDJAxAEECUQRhCAAjoVCAAQgAQQsQMQgwEQsQMQgwEQBBAlOgkIABCABBAEECU6CAgAEAQQAxAlOgwIABCABBCxAxAEECU6FwgAEIAEELEDEIMBEMkDEAQQJRBGEIACOg8IABCABBCxAxCDARAEECVQ9wpYqz1guewBaAlwAHgAgAH5AYgByRGSAQYxMS43LjKYAQCgAQGwAQo&sclient=gws-wiz")
# ---------------------
context.close()
browser.close()
with sync_playwright() as playwright:
run(playwright)
当たり前だけど、ログイン確認やいくつかのクリックなど、目的の操作とは直接関係のないものが入り込んでいるので、整理する
また、このまま実行してしまうとpage.wait_for_url()のところでタイムアウトエラーになる
根本的な原因がはっきりしないが、今は動かすことを優先し、代替えの処理に差し替える
page.wait_for_selector()を使って、特定のイメージ(今回はgoogleのロゴ)が表示するまで待つようにしてみた
from playwright.sync_api import Playwright, sync_playwright, expect
def run(playwright: Playwright) -> None:
browser = playwright.chromium.launch(headless=False)
context = browser.new_context()
# Open new page
page = context.new_page()
# Go to https://www.google.com/
page.goto("https://www.google.com/")
# Fill [aria-label="検索"]
page.locator("[aria-label=\"検索\"]").fill("今日の天気")
# Press Enter
page.locator("[aria-label=\"検索\"]").press("Enter")
page.wait_for_selector("img[alt=\"Google\"]")
#page.wait_for_url(url="https://www.google.com/search?q=%E4%BB%8A%E6%97%A5%E3%81%AE%E5%A4%A9%E6%B0%97&source=hp&ei=pJoEY-CECavs2roP9IGkqA0&iflsig=AJiK0e8AAAAAYwSotFt-9IhNDjLm4nMhtp0zg_Urj1OT&ved=0ahUKEwjg5oyF0Nz5AhUrtlYBHfQACdUQ4dUDCAk&uact=5&oq=%E4%BB%8A%E6%97%A5%E3%81%AE%E5%A4%A9%E6%B0%97&gs_lcp=Cgdnd3Mtd2l6EAMyDQgAEIAEEMkDEEYQgAIyBQgAEJIDMgUIABCSAzIFCAAQgAQyCAgAELEDEIMBMgUIABCABDIFCAAQgAQyCwgAEIAEELEDELEDMggIABCxAxCDATIFCAAQgAQ6CAgAEI8BEOoCOgYIABAEEAM6DQgAEIAEELEDEIMBEAQ6BwgAEIAEEAQ6CggAEIAEELEDEAQ6EAgAEIAEELEDEIMBEMkDEAQ6FQgAEIAEELEDEIMBEMkDEAQQRhCAAjoSCAAQgAQQsQMQgwEQBBBGEIACOg8IABCABBDJAxAEEEYQgAI6GQgAEIAEELEDEIMBELEDEIMBEMkDEEYQgAI6EQgAEIAEELEDEIMBELEDEIMBOh0IABCABBCxAxCDARCxAxCDARDJAxAEECUQRhCAAjoVCAAQgAQQsQMQgwEQsQMQgwEQBBAlOgkIABCABBAEECU6CAgAEAQQAxAlOgwIABCABBCxAxAEECU6FwgAEIAEELEDEIMBEMkDEAQQJRBGEIACOg8IABCABBCxAxCDARAEECVQ9wpYqz1guewBaAlwAHgAgAH5AYgByRGSAQYxMS43LjKYAQCgAQGwAQo&sclient=gws-wiz",wait_until='networkidle')
# ---------------------
context.close()
browser.close()
with sync_playwright() as playwright:
run(playwright)
コメントが操作単位に入っているので、初見でも触りやすい
構造が地獄なページを触った場合のlocatorがどうなるかも確認してみたいところ
記録した操作を実行する
pyやpytestで出力したソースを実行するだけ
# 単純なpythonコードとして実行する場合
py .\PlaywrightSample.py
# テストとして実行する場合
pytest .\PlaywrightSample.py
感想
出力されたコードが初見でもわかりやすいことに感動した
先にも触れたが、構造が地獄なページだとどうなるのかが興味ある
セレクターは研究が必要かもしれない
page.wait_for_url()のタイムアウトエラーについて調査していたところ、デフォルトタイムアウトの設定が私の環境では効かないことがわかった(使い方が悪かった?)
使い込んでいけば色々こうしてほしい点は出てくるだろうが、seleniumのようにイチからコードを組むことに敷居の高さを感じる人には良いと思う