AWS Device FarmのデスクトップブラウザテストでMicrosoft Edgeがサポートされました

2021.10.05

いわさです。

先日のアップデートでAWS Device Farmのデスクトップブラウザテストで、Microsoft Edgeがサポートされました。

サポートされたのは、新(Chromium版)のMicrosoft Edgeです。
旧Edgeは引き続きサポート対象外となっています。

これで、Device Farmでは、以下の4つのブラウザがサポートされることになりました。(すべてWindows)

  • Google Chrome
  • Mozilla Firefox
  • Microsoft Internet Explorer
  • Microsoft Edge (Chromium)

早速 Microsoft Edgeで試してみたのですが、WebDriver標準のDeviceCapabilitiesがそのままだと使えなかったので記事に対応方法なども残しておきます。

ブラウザ確認方法

今回は、簡易的にユーザーエージェントで判断します。
API Gateway + Lambdaでユーザーエージェントを判定するAPIを用意しておきました。

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'body': event['headers']['user-agent']
    }

Device Farm実行後にキャプチャ動画をダウンロード出来ますのでそこでOSやブラウザの動く部分を目視することも可能です。

AWS Device Farmから実行

前回、Device Farmからデスクトップブラウザテストを実行しました。
コードやテストプロジェクトはそのまま使うことが出来ます。

こちらのテストコードの以下のハイライトした部分でブラウザ(実行環境)を指定しています。
Selenium WebDriver標準で用意されているDesiredCapabilitiesを使用しています。
Edge以外はこれでそのまま動作します。

import pytest, boto3
from selenium.webdriver import Remote
from selenium.webdriver import DesiredCapabilities

class TestClass:
    def setup_method(self, method):
        session = boto3.Session(profile_name="hoge")
        devicefarm_client = session.client("devicefarm", region_name="us-west-2")
        testgrid_url_response = devicefarm_client.create_test_grid_url(
            projectArn="arn:aws:devicefarm:us-west-2:123456789023:testgrid-project:9e6b35de-1a24-4ae0-a007-d4cc63de9278",
            expiresInSeconds=300)
        self.driver = Remote(testgrid_url_response["url"], DesiredCapabilities.FIREFOX)

    # later, make sure to end your WebDriver session:
    def teardown_method(self, method):
        self.driver.quit()

    def test_title(self):
        self.driver.get('https://classmethod.jp/')
        self.driver.save_screenshot('capture.png')

DesiredCapabilities.FIREFOX

DesiredCapabilities.CHROME

DesiredCapabilities.INTERNETEXPLORER

DesiredCapabilities.SAFARI

サポートされていないSafariも試してみました。
WebDriverでエラーが発生していますね。

iwasa.takahito@hoge devicefarm-selenium-pytest-sample % pytest
============================================= test session starts =============================================
platform darwin -- Python 3.9.4, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: /Users/iwasa.takahito/src/devicefarm-selenium-pytest-sample
collected 1 item                                                                                              

test_hoge.py E                                                                                          [100%]

=================================================== ERRORS ====================================================
___________________________________ ERROR at setup of TestClass.test_title ____________________________________

self = <test_hoge.TestClass object at 0x10fced970>
method = <bound method TestClass.test_title of <test_hoge.TestClass object at 0x10fced970>>

    def setup_method(self, method):
        session = boto3.Session(profile_name="hoge")
        devicefarm_client = session.client("devicefarm", region_name="us-west-2")
        testgrid_url_response = devicefarm_client.create_test_grid_url(
            projectArn="arn:aws:devicefarm:us-west-2:123456789012:testgrid-project:9e6b35de-1a24-4ae0-a007-d4cc63de9278",
            expiresInSeconds=300)
>       self.driver = Remote(testgrid_url_response["url"], DesiredCapabilities.SAFARI)

test_hoge.py:12: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../.pyenv/versions/3.9.4/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py:157: in __init__
    self.start_session(capabilities, browser_profile)
../../.pyenv/versions/3.9.4/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py:252: in start_session
    response = self.execute(Command.NEW_SESSION, parameters)
../../.pyenv/versions/3.9.4/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py:321: in execute
    self.error_handler.check_response(response)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x114357e80>
response = {'status': 400, 'value': '{"value":{"error":"invalid argument","message":"4 validation errors detected: Value \'safari...\'desiredCapabilities.platformName\' failed to satisfy constraint: Member must satisfy value set: [windows, any]"}}\n'}

...

E       selenium.common.exceptions.InvalidArgumentException: Message: 4 validation errors detected: Value 'safari' at 'capabilities.alwaysMatch.browserName' failed to satisfy constraint: Member must satisfy value set: [firefox, chrome, internet explorer, MicrosoftEdge]; Value 'mac' at 'capabilities.alwaysMatch.platformName' failed to satisfy constraint: Member must satisfy value set: [windows, any]; Value 'safari' at 'desiredCapabilities.browserName' failed to satisfy constraint: Member must satisfy value set: [firefox, chrome, internet explorer, MicrosoftEdge]; Value 'MAC' at 'desiredCapabilities.platformName' failed to satisfy constraint: Member must satisfy value set: [windows, any]

../../.pyenv/versions/3.9.4/lib/python3.9/site-packages/selenium/webdriver/remote/errorhandler.py:242: InvalidArgumentException
=========================================== short test summary info ===========================================
ERROR test_hoge.py::TestClass::test_title - selenium.common.exceptions.InvalidArgumentException: Message: 4 ...
============================================== 1 error in 1.89s ===============================================

DesiredCapabilities.EDGE

EdgeもDesiredCapabilitieオプションが標準で用意されているので試してみましたが、そのままだとエラーになりました。

iwasa.takahito@hoge devicefarm-selenium-pytest-sample % pytest
============================================= test session starts =============================================
platform darwin -- Python 3.9.4, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: /Users/iwasa.takahito/src/devicefarm-selenium-pytest-sample
collected 1 item                                                                                              

test_hoge.py E                                                                                          [100%]

=================================================== ERRORS ====================================================
___________________________________ ERROR at setup of TestClass.test_title ____________________________________

self = <test_hoge.TestClass object at 0x105309970>
method = <bound method TestClass.test_title of <test_hoge.TestClass object at 0x105309970>>

    def setup_method(self, method):
        session = boto3.Session(profile_name="hoge")
        devicefarm_client = session.client("devicefarm", region_name="us-west-2")
        testgrid_url_response = devicefarm_client.create_test_grid_url(
            projectArn="arn:aws:devicefarm:us-west-2:123456789012:testgrid-project:9e6b35de-1a24-4ae0-a007-d4cc63de9278",
            expiresInSeconds=300)
>       self.driver = Remote(testgrid_url_response["url"], DesiredCapabilities.EDGE)

test_hoge.py:12: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../.pyenv/versions/3.9.4/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py:157: in __init__
    self.start_session(capabilities, browser_profile)
../../.pyenv/versions/3.9.4/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py:252: in start_session
    response = self.execute(Command.NEW_SESSION, parameters)
../../.pyenv/versions/3.9.4/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py:321: in execute
    self.error_handler.check_response(response)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x109997e20>
response = {'status': 400, 'value': '{"value":{"error":"invalid argument","message":"The capability ms:edgeChromium must be set to true"}}\n'}
...

"ms:edgeChromium"を指定する

The capability ms:edgeChromium must be set to true に従って、オプションを指定しましょう。

class TestClass:
    def setup_method(self, method):
        session = boto3.Session(profile_name="hoge")
        devicefarm_client = session.client("devicefarm", region_name="us-west-2")
        testgrid_url_response = devicefarm_client.create_test_grid_url(
            projectArn="arn:aws:devicefarm:us-west-2:123456789012:testgrid-project:9e6b35de-1a24-4ae0-a007-d4cc63de9278",
            expiresInSeconds=300)
        local_desiredcapabilities = DesiredCapabilities.EDGE
        local_desiredcapabilities['ms:edgeChromium'] = 'true'
        self.driver = Remote(testgrid_url_response["url"], local_desiredcapabilities)

Edgeのユーザーエージェントを確認することが出来ました。

さいごに

Microsoft Edgeで動作させる際は、ms:edgeChromiumの指定を忘れないようにしましょう。

AWS Device Farmはアップデートは少なめな感覚ですが、こういうサポート対象が追加されるアップデートは嬉しいです。
Windowsとモバイルデバイスに関しては概ねカバー出来ていますね。

あとは、WebDriverではプラットフォームにmacOSの指定が可能なのですが、もしここまで対応されるとかなり幅広く使えるようになるのではないでしょうか。