【python】playwrightでE2E評価環境を作る

# 1.やりたいこと
PlaywrightでWebブラウザの操作を行い、操作結果をpytestで管理できるよう環境構築します。
自動操作対象のWebサイトは、[UI Test Automation Playground][link-1]を利用します。

用語の説明
| フレームワーク | 説明 | 
|:---------:|:-----------|
| [Playwright][link-2]| マイクロソフト社が作っているブラウザを自動で操作する|
| [pytest][link-3]     | Pythonで書いたプログラムをテストする|

# 2.環境
macOSでPlaywrightの環境を構築します。
　・macOS 12.4(monterey)
　・Python 3.7.6
　・pip 22.1
# 3.環境設定
ターミナルを起動させ以下コマンドを実行します。
pip listでplaywrightとpytestがあればインストール成功です。
```ruby:ターミナル
pip install playwright
pip install pytest-playwright
```
rootフォルダの直下に実行ファイルを作成します。
※ 実行ファイルのファイル名は、pytestの仕様上「test_xxx.py」としてください。
> root
> ┣ test_sample.py


# 4.コード
実行ファイルに下記のようなプログラムを書きます。
test_click1(page)は成功ケースでtest_click２(page)は失敗するようなコードを作成しました。
※ 実行ファイルのテスト関数は、pytestの仕様上「def test_xxx（）：」としてください。
```ruby:test_sample.py
from playwright.sync_api import Playwright, sync_playwright
def test_click1(page):
    #対象のURLに遷移する
    page.goto("http://www.uitestingplayground.com/") 
    #テキストと一致した名称の要素を押す
    page.click("text = Click")
    #イベント発生後出現する要素の値がClickであるか確認する。
    assert page.inner_text("xpath = /html/body/section/div/h3") == "Click" 

def test_click2(page):
    #対象のURLに遷移する
    page.goto("http://www.uitestingplayground.com/") 
    #テキストと一致した名称の要素を押す
    page.click("text = Click")
    #イベント発生後出現しない要素を設定する。（test_click2が失敗するようにする）
    assert page.inner_text("xpath = /html/body/section/div/h3") == "Click!" 
```
# 5. 実行
ターミナルを起動後rootフォルダーに移動し、「pytest」を実行します。
```ruby:./root
pytest
```
  <dt>実行結果</dt>
「pytest」を実行することで、test_sample.pyが実行し結果が返されます。
１件成功、１件失敗というメッセージが出力しました。

![スクリーンショット 2022-05-20 13.24.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667601/8675692a-db7d-af37-c090-ff4084a7578e.png)

# 6. 複数のテストファイルの実行
rootフォルダの直下に実行ファイルを複数作成し、「pytest」を実行します。
> root
> ┣ test_sample.py  
> ┣ test_sample2.py
> ┣ test_sample3.py
  <dt>実行結果</dt>
rootフォルダの直下の「test_xxx.py」すべて実行します。

![スクリーンショット 2022-05-18 20.05.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667601/07edf203-3a95-3376-48ac-a8016753d678.png)

# 7. 設定ファイルの活用
playwrightには、pytestのCLIを持っています。このCLIをINIファイルで管理できます。
例えば下記sample1.py、sample2.pyでpage.gotoのURLの値に共通部分があります。
この値をbase_urlとしてINIファイルで管理することができます。
```ruby:test_sample１.py
from playwright.sync_api import Playwright, sync_playwright
def test_click(page):
    page.goto("http://www.uitestingplayground.com/") 
    page.click("text = Click")                                               
```
```ruby:test_sample2.py
from playwright.sync_api import Playwright, sync_playwright
def test_click(page):
    page.goto("http://www.uitestingplayground.com/click") 
    page.click("#badButton")                                              
```

実行ファイルと同階層にpytest.iniを作成します。
> root
> ┣ test_sample1.py  
> ┣ test_sample2.py
> ┣ pytest.ini

pytest.iniに共通値を記載します。
```ruby:pytest.ini
[pytest]
addopts = --base_url http://www.uitestingplayground.com/                                             
```
実行ファイルは、下記のように修正します。
```ruby:test_sample１.py
from playwright.sync_api import Playwright, sync_playwright
def test_click(page):
    page.goto("/") #設定した値を書かなくて良い
    page.click("text = Click")                                               
```
```ruby:test_sample2.py
from playwright.sync_api import Playwright, sync_playwright
def test_click(page):
    page.goto("/click")  #設定した値以降を記載
    page.click("#badButton")                                                
```
  <dt>実行結果</dt>
「pytest」を実行すると、共通部分を省略した実行ファイルが問題なく動作できます。

![スクリーンショット 2022-05-20 11.01.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667601/36c5979f-c2f8-a3dc-e4b8-703ad219ffc5.png)

pytest.iniで管理できるCLIは、[pytest -h]コマンドで確認できます。
```ruby:root
pytest -h
〜〜〜〜〜〜結果〜〜〜〜〜〜
Playwright:
  --browser={chromium,firefox,webkit}　Browser engine which should be used
  --headed              Run tests in headed mode.
  --browser-channel=BROWSER_CHANNEL　　Browser channel to be used.
  --slowmo=SLOWMO       Run tests with slow mo
  --device=DEVICE       Device to be emulated.
  --output=OUTPUT       Directory for artifacts produced by tests, defaults to test-results.
  --tracing={on,off,retain-on-failure} Whether to record a trace for each test.
  --video={on,off,retain-on-failure} Whether to record video for each test.
  --screenshot={on,off,only-on-failure}　Whether to automatically capture a screenshot after each test.
```

# 8. 関連記事
・[【python】playwrightの実行中の操作を録画する方法][link-9-1]
・[【python】playwrightでパラメータテストする方法][link-9-2]
・[【python】playwrightでログイン処理省略する方法][link-9-3]

[link-1]:http://www.uitestingplayground.com/
[link-2]: https://playwright.dev/
[link-3]: https://docs.pytest.org/
[link-9-1]: https://qiita.com/ryuusen999/items/ec3b95f1c2e2aa4f5856
[link-9-2]: https://qiita.com/ryuusen999/items/4e9a1c9a16c6819e3f9c
[link-9-3]: https://qiita.com/ryuusen999/items/59c7416876f9b0d92a72