Selenium 4 へのアップグレード

まだ Selenium 3 を使用していますか?このガイドは、最新リリースへのアップグレードに役立ちます!

Selenium 4 へのアップグレードは、公式にサポートされている言語 (Ruby、JavaScript、C#、Python、Java) のいずれかを使用している場合は、簡単なプロセスになるはずです。いくつかの問題が発生する可能性がありますが、このガイドはそれらを解決するのに役立ちます。プロジェクトの依存関係をアップグレードする手順と、バージョンアップグレードがもたらす主要な非推奨と変更について説明します。

Selenium 4 にアップグレードするために従う手順は次のとおりです。

  • テストコードの準備
  • 依存関係のアップグレード
  • 潜在的なエラーと非推奨メッセージ

注: Selenium 3.x バージョンの開発中に、W3C WebDriver 標準のサポートが実装されました。この新しいプロトコルとレガシー JSON Wire Protocol の両方がサポートされていました。バージョン 3.11 前後で、Selenium コードは W3C レベル 1 仕様に準拠するようになりました。Selenium 3 の最新バージョンで W3C 準拠コードは、Selenium 4 で期待どおりに動作します。

テストコードの準備

Selenium 4 では、レガシープロトコルのサポートが削除され、デフォルトで内部的に W3C WebDriver 標準が使用されます。ほとんどの場合、この実装はエンドユーザーに影響を与えません。主な例外は、CapabilitiesActions クラスです。

Capabilities

テストケイパビリティが W3C 準拠するように構造化されていない場合、セッションが開始されない可能性があります。W3C WebDriver 標準ケイパビリティのリストを以下に示します。

  • browserName
  • browserVersion (version を置き換え)
  • platformName (platform を置き換え)
  • acceptInsecureCerts
  • pageLoadStrategy
  • proxy
  • timeouts
  • unhandledPromptBehavior

標準ケイパビリティの最新リストは、W3C WebDriver で確認できます。

上記のリストに含まれていないケイパビリティは、ベンダープレフィックスを含める必要があります。これは、ブラウザ固有のケイパビリティとクラウドベンダー固有のケイパビリティの両方に適用されます。たとえば、クラウドベンダーがテストに build および name ケイパビリティを使用している場合、それらを cloud:options ブロックでラップする必要があります (適切なプレフィックスについては、クラウドベンダーに確認してください)。

変更前

コードの移動

DesiredCapabilities caps = DesiredCapabilities.firefox();
caps.setCapability("platform", "Windows 10");
caps.setCapability("version", "92");
caps.setCapability("build", myTestBuild);
caps.setCapability("name", myTestName);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), caps);
caps = {};
caps['browserName'] = 'Firefox';
caps['platform'] = 'Windows 10';
caps['version'] = '92';
caps['build'] = myTestBuild;
caps['name'] = myTestName;
DesiredCapabilities caps = new DesiredCapabilities();
caps.SetCapability("browserName", "firefox");
caps.SetCapability("platform", "Windows 10");
caps.SetCapability("version", "92");
caps.SetCapability("build", myTestBuild);
caps.SetCapability("name", myTestName);
var driver = new RemoteWebDriver(new Uri(CloudURL), caps);
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
caps = {}
caps['browserName'] = 'firefox'
caps['platform'] = 'Windows 10'
caps['version'] = '92'
caps['build'] = my_test_build
caps['name'] = my_test_name
driver = webdriver.Remote(cloud_url, desired_capabilities=caps)

変更後

コードの移動

FirefoxOptions browserOptions = new FirefoxOptions();
browserOptions.setPlatformName("Windows 10");
browserOptions.setBrowserVersion("92");
Map<String, Object> cloudOptions = new HashMap<>();
cloudOptions.put("build", myTestBuild);
cloudOptions.put("name", myTestName);
browserOptions.setCapability("cloud:options", cloudOptions);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), browserOptions);
capabilities = {
  browserName: 'firefox',
  browserVersion: '92',
  platformName: 'Windows 10',
  'cloud:options': {
     build: myTestBuild,
     name: myTestName,
  }
}
var browserOptions = new FirefoxOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "92";
var cloudOptions = new Dictionary<string, object>();
cloudOptions.Add("build", myTestBuild);
cloudOptions.Add("name", myTestName);
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
var driver = new RemoteWebDriver(new Uri(CloudURL), browserOptions);
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
from selenium.webdriver.firefox.options import Options as FirefoxOptions
options = FirefoxOptions()
options.browser_version = '92'
options.platform_name = 'Windows 10'
cloud_options = {}
cloud_options['build'] = my_test_build
cloud_options['name'] = my_test_name
options.set_capability('cloud:options', cloud_options)
driver = webdriver.Remote(cloud_url, options=options)

Java での要素 (単数/複数) を見つけるユーティリティメソッド

Java バインディングで要素を見つけるためのユーティリティメソッド (FindsBy インターフェース) は、内部使用のみを目的としていたため、削除されました。次のコード例で、これをよりよく説明します。

findElement* を使用して単一の要素を見つける

変更前

driver.findElementByClassName("className");
driver.findElementByCssSelector(".className");
driver.findElementById("elementId");
driver.findElementByLinkText("linkText");
driver.findElementByName("elementName");
driver.findElementByPartialLinkText("partialText");
driver.findElementByTagName("elementTagName");
driver.findElementByXPath("xPath");
変更後

driver.findElement(By.className("className"));
driver.findElement(By.cssSelector(".className"));
driver.findElement(By.id("elementId"));
driver.findElement(By.linkText("linkText"));
driver.findElement(By.name("elementName"));
driver.findElement(By.partialLinkText("partialText"));
driver.findElement(By.tagName("elementTagName"));
driver.findElement(By.xpath("xPath"));

findElements* を使用して複数の要素を見つける

変更前

driver.findElementsByClassName("className");
driver.findElementsByCssSelector(".className");
driver.findElementsById("elementId");
driver.findElementsByLinkText("linkText");
driver.findElementsByName("elementName");
driver.findElementsByPartialLinkText("partialText");
driver.findElementsByTagName("elementTagName");
driver.findElementsByXPath("xPath");
変更後

driver.findElements(By.className("className"));
driver.findElements(By.cssSelector(".className"));
driver.findElements(By.id("elementId"));
driver.findElements(By.linkText("linkText"));
driver.findElements(By.name("elementName"));
driver.findElements(By.partialLinkText("partialText"));
driver.findElements(By.tagName("elementTagName"));
driver.findElements(By.xpath("xPath"));

依存関係のアップグレード

Selenium 4 をインストールし、プロジェクトの依存関係をアップグレードするには、以下のサブセクションを確認してください。

Java

Selenium のアップグレードプロセスは、使用しているビルドツールによって異なります。Java で最も一般的な MavenGradle について説明します。必要な最小 Java バージョンは引き続き 8 です。

Maven

変更前

<dependencies>
  <!-- more dependencies ... -->
  <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.141.59</version>
  </dependency>
  <!-- more dependencies ... -->
</dependencies>
変更後

<dependencies>
    <!-- more dependencies ... -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.4.0</version>
    </dependency>
    <!-- more dependencies ... -->
</dependencies>

変更を加えた後、pom.xml ファイルがある同じディレクトリで mvn clean compile を実行できます。

Gradle

変更前

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.141.59'
}
test {
    useJUnitPlatform()
}
変更後

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '4.4.0'
}
test {
    useJUnitPlatform()
}

変更を加えた後、build.gradle ファイルがある同じディレクトリで ./gradlew clean build を実行できます。

すべての Java リリースを確認するには、MVNRepository にアクセスしてください。

C#

C# での Selenium 4 のアップデートを取得する場所は NuGet です。Selenium.WebDriver パッケージの下に、最新バージョンにアップデートする手順があります。Visual Studio 内から、NuGet パッケージマネージャーを介して、次を実行できます。

PM> Install-Package Selenium.WebDriver -Version 4.4.0

Python

Python を使用するための最も重要な変更は、必要な最小バージョンです。Selenium 4 には、最小 Python 3.7 以降が必要です。詳細については、Python Package Index を参照してください。コマンドラインからアップグレードするには、次を実行できます。

pip install selenium==4.4.3

Ruby

Selenium 4 のアップデート詳細は、RubyGems の selenium-webdriver gem で確認できます。最新バージョンをインストールするには、次を実行できます。

gem install selenium-webdriver

Gemfile に追加するには

gem 'selenium-webdriver', '~> 4.4.0'

JavaScript

selenium-webdriver パッケージは、Node パッケージマネージャーである npmjs にあります。Selenium 4 は こちら にあります。インストールするには、次を実行できます。

npm install selenium-webdriver

または、package.json を更新して npm install を実行します。

{
  "name": "selenium-tests",
  "version": "1.0.0",
  "dependencies": {
    "selenium-webdriver": "^4.4.0"
  }
}

潜在的なエラーと非推奨メッセージ

Selenium 4 にアップグレードした後に発生する可能性のある非推奨メッセージを克服するのに役立つコード例のセットを次に示します。

Java

待機とタイムアウト

Timeout で受信するパラメータは、(long time, TimeUnit unit) を想定していたものから、(Duration duration) を想定するように切り替わりました。

変更前

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(2, TimeUnit.MINUTES);
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
変更後

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().timeouts().scriptTimeout(Duration.ofMinutes(2));
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));

待機も異なるパラメータを想定するようになりました。WebDriverWait は、タイムアウト (秒およびミリ秒) に long の代わりに Duration を想定するようになりました。FluentWaitwithTimeout および pollingEvery ユーティリティメソッドは、(long time, TimeUnit unit) を想定していたものから、(Duration duration) を想定するように切り替わりました。

変更前

new WebDriverWait(driver, 3)
.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(30, TimeUnit.SECONDS)
  .pollingEvery(5, TimeUnit.SECONDS)
  .ignoring(NoSuchElementException.class);
変更後

new WebDriverWait(driver, Duration.ofSeconds(3))
  .until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

  Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(Duration.ofSeconds(30))
  .pollingEvery(Duration.ofSeconds(5))
  .ignoring(NoSuchElementException.class);

ケイパビリティのマージは、呼び出し元のオブジェクトを変更しなくなりました

別のケイパビリティセットを別のセットにマージすることが可能であり、呼び出し元のオブジェクトを変更していました。現在、マージ操作の結果を割り当てる必要があります。

変更前

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options.merge(capabilities);

// As a result, the `options` object was getting modified.
変更後

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options = options.merge(capabilities);

// The result of the `merge` call needs to be assigned to an object.

Firefox レガシー

GeckoDriver が登場する前は、Selenium プロジェクトには Firefox (バージョン <48) を自動化するためのドライバ実装がありました。ただし、この実装は Firefox の最新バージョンでは動作しないため、不要になりました。Selenium 4 にアップグレードする際の重大な問題を回避するために、setLegacy オプションは非推奨として表示されます。古い実装の使用を停止し、GeckoDriver のみに依存することをお勧めします。次のコードは、アップグレード後に setLegacy 行が非推奨になることを示しています。

FirefoxOptions options = new FirefoxOptions();
options.setLegacy(true);

BrowserType

BrowserType インターフェースは長い間存在していましたが、新しい Browser インターフェースに賛成して非推奨になります。

変更前

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", BrowserType.FIREFOX);
変更後

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", Browser.FIREFOX);

C#

AddAdditionalCapability は非推奨

代わりに、AddAdditionalOption が推奨されます。これを示す例を次に示します。

変更前

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalCapability("cloud:options", cloudOptions, true);
変更後

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);

Python

executable_path は非推奨になりました。Service オブジェクトを渡してください

Selenium 4 では、非推奨の警告を防ぐために、Service オブジェクトからドライバの executable_path を設定する必要があります。(または、パスを設定せずに、必要なドライバがシステム PATH 上にあることを確認してください。)

変更前

from selenium import webdriver
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(
    executable_path=CHROMEDRIVER_PATH, 
    options=options
)
変更後

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
options = webdriver.ChromeOptions()
service = ChromeService(executable_path=CHROMEDRIVER_PATH)
driver = webdriver.Chrome(service=service, options=options)

まとめ

Selenium 4 にアップグレードする際に考慮すべき主な変更点について説明しました。テストコードがアップグレードの準備をするときにカバーするさまざまな側面、および新しいバージョンの Selenium を使用するときに発生する可能性のある問題を回避する方法の提案を含みます。最後に、アップグレード後に遭遇する可能性のある一連の問題についても説明し、それらの問題に対する潜在的な修正を共有しました。

これは元々 https://saucelabs.com/resources/articles/how-to-upgrade-to-selenium-4 に投稿されました。