2026年11月9日、ブラウザを自動で操作できるライブラリPlaywrightのPython版、1.65.0が公開されました。10月の1.64.1から、およそ3週間での新しい版です。
今回は、テストの結果に関わる、動きの変更がいくつも入っています。特に、操作できないはずの入力欄に、エラーを出さずに入力したことにしてしまう動きが直りました。
ほかにも、Cookieの扱いが厳密になったり、インストールの方法が増えたりしています。今回は、1.64.1と1.65.0で同じコードを動かしながら、何が変わったのかを見ていきます。
まずはPlaywrightとはどんなものか¶
最初に、Playwrightを知らない方のために、どんなライブラリなのかを簡単に紹介します。Playwrightは、Microsoftが開発している、ブラウザを自動で操作するためのライブラリです。
ボタンを押す、文字を入力する、画面の内容を確かめる、といった操作を、Pythonのコードで書けます。Webアプリの動作を確かめるテストや、決まった手順の作業の自動化によく使われます。
Seleniumとの違い¶
ブラウザを自動で操作するライブラリとしては、Seleniumもよく知られています。2つの違いを、大まかに表にまとめます。
| 項目 | Selenium | Playwright |
|---|---|---|
| 歴史 | 古くからあり、情報が多い | 比較的新しい |
| 待ち方 | 自分で待つ処理を書くことが多い | 操作できる状態になるまで自動で待つ |
| 対応ブラウザ | 各ブラウザのドライバーを使う | Chromium、Firefox、WebKitを専用に用意 |
Seleniumの使い方は、こちらで紹介しています。【関連記事】PythonのSeleniumとは?
ブラウザを使わずにページの情報だけを集めたいなら、Scrapyのようなクローラーの道具もあります。先日のニュースでは、Scrapyの2.20を紹介しました。【関連記事】Scrapy 2.20がリリース
1.65で何が変わったのかを整理しよう¶
続いて、1.65.0の主な変更を表にまとめます。内容は、Playwrightの公式リポジトリにある、Python版の1.65.0のリリースノートにもとづいています。
| 分類 | 主な変更 |
|---|---|
| 動きの変更 | inertな要素への操作は、操作できるようになるまで待つ |
| 動きの変更 | Cookieの扱いが、RFC 6265という決まりに沿うように |
| 動きの変更 | プロキシの認証情報を、Webサイトには送らない |
| 新機能 | locator.normalize()の結果を、Pythonのコードとして文字列にできる |
| インストール | Node.jsを含まないソース配布物も公開 |
| 依存ライブラリ | pyeeが不要に |
リリースノートには、互換性を壊す変更という見出しはありません。ただし、これらは注意が必要な修正として、警告の印付きでまとめられています。
PyPIの記録によると、1.65.0が必要とするPythonは3.10以上です。同梱のブラウザは、Chromium 158.0.8127.18、Firefox 159.0、WebKit 27.2と書かれています。
操作できない入力欄に、入力したことにしなくなった¶
まずは、一番気をつけたい変更から見ていきましょう。HTMLには、inertという属性があります。
inertを付けた要素とその中身は、クリックや入力ができなくなります。たとえば、ダイアログを開いている間に、後ろの画面を操作できなくするときなどに使われます。
1.64.1と1.65.0で試してみた¶
リリースノートによると、1.65.0からは、fill()やclick()などの操作が、要素がinertでなくなるまで待つようになりました。実際に、inertなフォームの中の入力欄に、文字を入れてみます。
from playwright.sync_api import sync_playwright
html = """
<form inert>
<input id="name" placeholder="お名前">
</form>
"""
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.set_content(html)
try:
page.locator("#name").fill("taro", timeout=2000)
print("入力できた:", page.locator("#name").input_value())
except Exception as e:
print(type(e).__name__, str(e).splitlines()[0])
browser.close()
1.64.1と1.65.0を、それぞれ新しい仮想環境に入れ、手元のPython 3.11で実行した結果です。ブラウザは、手元にあらかじめ入っていたChromiumを、両方で同じように使っています。
playwright 1.64.1
入力できた:
playwright 1.65.0
TimeoutError Locator.fill: Timeout 2000ms exceeded.
1.64.1では、エラーにならずに、入力できたと表示されました。ところが、入力欄の値は空のままです。
つまり、入力したことにして先へ進んでいたわけです。1.65.0では、操作できる状態にならないまま2秒たち、TimeoutErrorではっきり教えてくれました。
なぜ大事なのか¶
テストで、入力したはずなのに値が空、というのは、原因を探すのがとても難しい問題です。1.64.1の動きでは、エラーが出るのは、もっと後の、値を確かめる段階になってしまいます。
1.65.0では、問題が起きたその場所で止まります。ただし、これまで通っていたテストが、上げたあとにタイムアウトで失敗するようになる可能性もあります。
Cookieの扱いが厳密になった¶
2つ目は、Cookieの変更です。Cookieとは、Webサイトがブラウザに保存させる小さなデータで、ログインの状態などを覚えておくのに使われます。
リリースノートによると、Cookieがどのページに送られるかの判定が、RFC 6265という、Cookieの決まりを定めた文書に沿うようになりました。
3つのURLで確かめてみた¶
実際に、2つのCookieを保存して、3つのURLでどのCookieが使われるかを確かめました。1つ目は、example.comだけに送るsession、2つ目は、/apiの下だけに送るapi_tokenです。
context = browser.new_context()
context.add_cookies([
{"name": "session", "value": "abc", "url": "https://example.com/"},
{"name": "api_token", "value": "xyz", "domain": "example.com", "path": "/api"},
])
for url in ["https://example.com/", "https://shop.example.com/", "https://example.com/apiv2"]:
names = [c["name"] for c in context.cookies(url)]
print(url, names)
実行した結果を、表にまとめます。
| URL | 1.64.1 | 1.65.0 |
|---|---|---|
| https://example.com/ | session | session |
| https://shop.example.com/ | session | なし |
| https://example.com/apiv2 | api_token、session | session |
1.64.1では、example.comだけのはずのsessionが、shop.example.comでも返されていました。また、/apiの下だけのはずのapi_tokenが、/apiv2でも返されています。
1.65.0では、どちらも決まりどおりに返されなくなりました。Cookieを使ったログインのテストがある場合は、上げたあとに確かめておきましょう。
そのほかの動きの変更¶
リリースノートには、ほかにも注意が必要な変更が書かれています。初心者にも関係しそうなものを紹介します。
| 変更 | 中身 |
|---|---|
| プロキシの認証情報 | launchのproxyに書いた認証情報は、プロキシにだけ送る。サイトの認証にはhttp_credentialsを使う |
| 表示されない文字 | 閉じたdetailsの中の文字など、表示されない文字は、要素の名前に含めない |
| paramsの扱い | APIRequestContextのparamsは、URLにもとからある検索条件に付け足す |
2つ目は、get_by_role()で名前を指定して要素を探すときの結果に関わります。閉じた要素の中の文字を名前の一部として探していたテストは、見つからなくなるかもしれません。
新機能と、インストールの変更¶
最後に、新機能とインストールまわりの変更を見ていきましょう。
locatorをPythonのコードとして書き出す¶
リリースノートによると、locator.normalize()の結果を文字列にすると、Pythonのコードになるようになりました。aria_snapshot()で画面の要素の一覧を取り、get_by_ref()で選んだ要素を、テストのコードに変換する使い方が紹介されています。
手元の1.65.0で、見出しと入力欄とボタンを置いたページで試すと、e4という番号の入力欄がget_by_role("textbox", name="メール")というコードになりました。なお、同じコードを1.64.1で動かしても同じ表示になったので、細かな違いはリリースノートと公式ドキュメントで確かめてください。
Node.jsを含まない配布物¶
リリースノートによると、Node.jsを含まないソース配布物も公開されるようになりました。PyPIを見ると、1.64.1にはなかったソース配布物が、1.65.0には1つ加わっていました。
また、依存関係の一覧からpyeeが消えていました。リリースノートでは、ほかのパッケージとpyeeの版がぶつかることがなくなる、と説明されています。
上げる前にやっておきたいこと¶
ここまでの内容を踏まえて、Playwrightを1.65.0へ上げる前に確かめておきたいことを整理します。
| 順番 | 確認すること |
|---|---|
| 1 | inertな要素を操作しているテストが、タイムアウトしないか |
| 2 | サブドメインや似たパスで、Cookieを前提にしたテストがないか |
| 3 | プロキシの設定で、サイトの認証もしていないか |
| 4 | playwright installで、新しいブラウザを入れ直したか |
上げるときは、pip install --upgrade playwrightのあとに、playwright installも実行します。Playwrightは版ごとに使うブラウザの版が決まっているので、ライブラリとブラウザをそろえて上げるのが基本です。
テストの書き方そのものは、こちらで紹介しています。【関連記事】pytest入門|Pythonでテストを書く基本
私は10年ほどエンジニアとして開発に関わってきましたが、自動テストが全部通っているのに、本番で入力欄が使えないという不具合を出してしまったことがあります。テストの道具が、できないことを、できないと正直に教えてくれるのは、何より大切だと感じています。
まとめ¶
2026年11月9日、PlaywrightのPython版1.65.0が公開されました。inertで操作できない入力欄に、エラーを出さずに入力したことにしてしまう動きが直り、Cookieの扱いもRFC 6265に沿うよう厳密になっています。
どちらも、テストの結果が変わりうる変更です。上げたら、まずテストを一通り流し、失敗したものがあれば、今回の変更に当てはまらないか確かめてみてください。
ここまでお読みいただきありがとうございました。