これは、このセクションの複数ページの印刷可能なビューです。 印刷するには、ここをクリックしてください.

このページの通常のビューに戻る.

WebDriver

WebDriverはブラウザをネイティブに操作します。詳細については、こちらをご覧ください。

WebDriverは、ユーザーがローカルまたはSeleniumサーバーを使用するリモートマシンで行うように、ブラウザをネイティブに動かし、ブラウザの自動化に関して大きく前進します。

Selenium WebDriverは言語バインディングと個々のブラウザ制御コードの実装の両方を参照します。
これは通常、単に WebDriver と呼ばれます。

Selenium WebDriverは、W3C勧告です。

  • WebDriverはシンプルでより簡潔なプログラミングインターフェイスとして設計されています。

  • WebDriverはコンパクトなオブジェクト指向APIです。

  • ブラウザーを効果的に動かします。

1 - 入門

Seleniumを初めて使用する場合は、すぐに習得するのに役立つリソースがいくつかあります。

Seleniumは市場で主要なブラウザの全てを WebDriver を使うことでサポートしています。 WebDriverとはAPI群とプロトコルです。これらはウェブブラウザの動作をコントロールするための言語中立なインターフェイスを定義しています。 それぞれのブラウザは特定のWebDriverの実装を持っており、これらは driver と呼ばれます。 driverはブラウザに委譲する責務を持つコンポーネントであり、Seleniumとブラウザ間の通信を処理します。

この分離は、ブラウザベンダーに自分たちのブラウザでの実装の責任を持たせるための意図的な努力のひとつです。 Seleniumは可能な場合これらのサードパーティ製のdriverを使いますが、それが現実的でない場合のためにプロジェクトでメンテナンスしているdriverも提供しています。

Seleniumフレームワークはこれら全ての要素をユーザ向けのインターフェイスを通して結びつけます。このインターフェイスは異なるブラウザバックエンドを透過的に使えるようにし、クロスブラウザ・クロスプラットフォームの自動化を可能にします。

Seleniumのセットアップは、他の商用ツールのセットアップとはかなり異なります。 Seleniumコードの記述を開始する前に、次のことを行う必要があります 選択した言語、つまりブラウザーの言語バインディングライブラリをインストールします 使用したい、そのブラウザのドライバ。

以下のリンクをたどって、Selenium WebDriverを起動してください。

ローコード/録音および再生ツールから始めたい場合は、確認してください Selenium IDE

物事がうまくいったら、テストをスケールアップしたい場合は、Selenium Grid.

1.1 - Seleniumライブラリのインストール

お気に入りのプログラミング言語用にSeleniumライブラリを設定します。

最初にあなたの自動化プロジェクトにSeleniumのバインディングをインストールする必要があります。 インストールの方法は選択した言語によって異なります。

言語別の要件

サポートされている最小のJavaバージョンを表示する ここ.

Java用のSeleniumライブラリのインストールは、ビルドツールを使用して行います。

Maven

プロジェクトの ‘pom.xml’ ファイルで依存関係を指定します:

        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>

Gradle

プロジェクトの ‘build.gradle’ ファイル内の依存関係を ’testImplementation’ として指定します:

    testImplementation 'org.seleniumhq.selenium:selenium-java:4.27.0'
    testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.11.3'

各 Selenium バージョンでサポートされている最小 Python バージョンについては、次の場所にあります サポートされている Python バージョン オン PyPi

Seleniumをインストールするには、いくつかの方法があります。

Pip

pip install selenium

ダウンロード

または、ダウンロードすることもできますPyPI ソースアーカイブ (selenium-x.x.x.tar.gz) を使用してインストールします setup.py

python setup.py install

プロジェクトで必要

プロジェクトで使用するには、requirements.txt ファイルに追加します:

selenium==4.27.1

Seleniumの各バージョンでサポートされているすべてのフレームワークのリスト で利用可能ですNuget

Seleniumのインストールにはいくつかのオプションがあります。

パケットマネージャー

Install-Package Selenium.WebDriver

.NET CLI

dotnet add package Selenium.WebDriver

CSProj

プロジェクトの csprojファイルで、ItemGroupPackageReferenceとして依存関係を指定します。:

      <PackageReference Include="Selenium.WebDriver" Version="4.27.0" />

その他の考慮事項

その他、使用上の注意点 Visual Studio Code (vscode) そして C#

上記のセクションに従って、互換性のある .NET SDK をインストールします。 また、C# と NuGet の vscode 拡張機能 (Ctrl-Shift-X) もインストールします。に従ってください指示はこちら C# を使用して “Hello World” コンソール プロジェクトを作成および実行します。 コマンドラインを使用してNUnitスタータープロジェクトを作成することもできます dotnet new NUnit. ファイルを確認してください %appdata%\NuGet\nuget.config一部の開発者がいくつかの問題のために空になると報告したため、適切に構成されています。 もしnuget.configが空であるか、正しく構成されていない場合、Selenium プロジェクトの .NET ビルドは失敗します。 次のセクションをファイルに追加しますnuget.config 空の場合:

<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />   
  </packageSources>
...

詳細については、nuget.config ここをクリック. カスタマイズする必要があるかもしれません nuget.config あなたのニーズを満たすために。

さて、戻ってください vscode、プレス Ctrl-Shift-P、およびタイプ “NuGet Add Package"をクリックし、必要な Selenium パッケージ Selenium.WebDriver. Enter キーを押して、バージョンを選択します。 これで、C# と vscode に関連するドキュメントの例を使用できるようになりました。

特定の Selenium バージョンに対して最低限必要な Ruby のバージョンを確認できます オン rubygems.org

Seleniumは2つの異なる方法でインストールできます。

手動でインストールする

gem install selenium-webdriver

プロジェクトの gemfile に追加

gem 'selenium-devtools', '= 0.131.0'

Seleniumの特定のバージョンに最低限必要なNodeのバージョンは、Node Support Policy 節 オン npmjs

Seleniumは通常、npmを使用してインストールされます。

ローカルにインストールする

npm install selenium-webdriver

プロジェクトに加える

プロジェクトの package.jsonで、要件を dependencies:

        "mocha": "10.8.2"
Kotlin の Java バインディングを使用します。

次のステップ

初めてのSeleniumスクリプトを作成する

1.2 - 最初のSeleniumスクリプトを書く

Seleniumスクリプトを作成するための段階的な説明

Seleniumをインストールし、 すると、Seleniumコードを書く準備が整います。

8つの基本コンポーネント

Seleniumが行うことはすべて、ブラウザコマンドを送信して、何かを実行したり、情報の要求を送信したりすることです。 Seleniumで行うことのほとんどは、次の基本的なコマンドの組み合わせです。

[GitHub で完全な例を表示] へのリンクをクリックして、コンテキスト内のコードを表示します。

1. ドライバーインスタンスでセッションを開始します

セッションの開始の詳細については、次のドキュメントをお読みください driver sessions

        WebDriver driver = new ChromeDriver();
driver = webdriver.Chrome()
        IWebDriver driver = new ChromeDriver();
driver = Selenium::WebDriver.for :chrome
    driver = await new Builder().forBrowser(Browser.CHROME).build();
        driver = ChromeDriver()

2. Take action on browser

こちらの例では、ナビゲート してウェブページに移動しています。

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");
driver.get('https://www.selenium.dev/selenium/web/web-form.html')
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

3. ブラウザに関する情報をリクエストします

ブラウザに関する 情報 として、ウィンドウハンドル、ブラウザのサイズ/位置、クッキー、アラートなど、さまざまな種類のデータをリクエストできます。

        driver.getTitle();
title = driver.title
        var title = driver.Title;
    let title = await driver.getTitle();
        val title = driver.title

4. 待機戦略の確立

コードをブラウザの現在の状態と同期させることは、最大の課題の 1 つです Seleniumを使用して、それをうまく行うことは高度なトピックです。

基本的には、要素を見つける前に、その要素がページ上にあることを確認する必要があります また、要素は、操作を試みる前に対話可能な状態にあります。

暗黙的な待機が最善の解決策になることはめったにありませんが、ここで示すのが最も簡単なので、 プレースホルダーとして使用します。

[待機戦略] についてさらに読む(https://www.selenium.dev/ja/documentation/webdriver/waits/).

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
driver.implicitly_wait(0.5)
        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
driver.manage.timeouts.implicit_wait = 500
    await driver.manage().setTimeouts({implicit: 500});
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

5. 要素を検索するためのコマンドを送信します

ほとんどのSeleniumセッションにおけるコマンドの大部分は要素に関連しており、要素を見つける ことなしにはそれと対話することができません。

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));
text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")
        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

6. 要素に対してアクションを実行する

要素に対して行う アクションはわずかしかありませんが、それらは頻繁に使用されます。

        textBox.sendKeys("Selenium");
        submitButton.click();
text_box.send_keys("Selenium")
submit_button.click()
        textBox.SendKeys("Selenium");
        submitButton.Click();
text_box.send_keys('Selenium')
submit_button.click
    await textBox.sendKeys('Selenium');
    await submitButton.click();
        textBox.sendKeys("Selenium")
        submitButton.click()

7. 要素に関する情報をリクエストします

要素には リクエスト可能な情報 が多く保存されています。

        message.getText();
text = message.text
        var value = message.Text;
    let value = await message.getText();
        val value = message.getText()

8. セッションを終了します

これにより、ドライバー プロセスが終了し、既定ではブラウザーも閉じます。このドライバー インスタンスにこれ以上コマンドを送信することはできません。

セッションの終了 を参照.

Seleniumファイルの実行

mvn exec:java -D"exec.mainClass"="dev.selenium.getting_started.FirstScript" -D"exec.classpathScope"=test
pytest path/to/test_script.py
ruby example_script.rb
node example_script.spec.js

次のステップ

ほとんどのSeleniumユーザーは多くのセッションを実行し、重複を最小限に抑え、コードをより保守しやすくするために整理する必要があります。このコードをユースケースのコンテキストに配置する方法については、以下をお読みください Seleniumの使用

1.3 - Seleniumコードの整理と実行

IDEとテストランナーライブラリを使用したSelenium実行のスケーリング

一握り以上の 1 回限りのスクリプトを実行する場合は、コードを整理して操作できる必要があります。このページでは、Seleniumコードを使用して実際に生産的なことを行う方法についてのアイデアを提供します。

一般的な用途

ほとんどの人はSeleniumを使用してWebアプリケーションの自動テストを実行します。 しかし、Seleniumはブラウザ自動化のあらゆるユースケースをサポートします。

反復タスク

おそらく、Webサイトにログインして何かをダウンロードするか、フォームを送信する必要があります。 Selenium スクリプトを作成して、あらかじめ設定された時間にサービスと共に実行できます。

Webスクレイピング

APIがないサイトからデータを収集したいとお考えですか?セレン これを行うことができますが、Webサイトに精通していることを確認してください。 一部のWebサイトでは許可されておらず、他のWebサイトではSeleniumがブロックされることさえあります。

テスティング

テストのためにSeleniumを実行するには、Seleniumが実行したアクションに対してアサーションを行う必要があります。 したがって、優れたアサーションライブラリが必要です。テストの構造を提供する追加機能 使用する必要があります Test Runner.

IDEs

Seleniumコードの使用方法に関係なく、優れた統合開発環境がなければ、Seleniumコードの作成や実行はあまり効果的ではありません。一般的なオプションを次に示します…

Test Runner

テストにSeleniumを使用していない場合でも、高度なユースケースがある場合は、テストランナーを使用してコードをより適切に整理するのが理にかなっている場合があります。before/after フックを使用して、グループまたは並行して物事を実行できると非常に便利です。

さまざまなテストランナーが利用可能です。

このドキュメントのすべてのコード例は、 テストランナーを使用し、すべてのコードが正しく更新されていることを確認するためにリリースごとに実行されるディレクトリの例。 リンク付きのテストランナーのリストを次に示します。最初の項目は、このリポジトリで使用される項目と このページのすべての例で使用されます。

  • JUnit - JavaベースのSeleniumテストで広く使用されているテストフレームワーク。
  • TestNG - 並列テスト実行やパラメーター化されたテストなどの追加機能を提供します。
  • pytest - そのシンプルさと強力なプラグインのおかげで、多くの人に好まれる選択肢です。
  • unittest - Python の標準ライブラリテストフレームワーク。
  • NUnit - .NET の一般的な単体テスト フレームワーク。
  • MS Test - Microsoft 独自の単体テスト フレームワーク。
  • RSpec - RubyでSeleniumテストを実行するために最も広く使用されているテストライブラリ。
  • Minitest - Ruby標準ライブラリに付属する軽量なテストフレームワークです。
  • Jest - 主にReactのテストフレームワークとして知られていますが、Seleniumのテストにも使用できます。
  • Mocha - Seleniumテストを実行するための最も一般的なJSライブラリ。

装着

これは、で必要とされたものと非常によく似ています Seleniumライブラリのインストール。このコードは、私たちのドキュメント例プロジェクトで使用されているものの例を示しているだけです。

Maven

Gradle

プロジェクトで使用するには、requirements.txt ファイルに追加します:

プロジェクトの ‘csproj’ ファイルで、依存関係を ‘ItemGroup’ の ‘PackageReference’ として指定します:

プロジェクトの gemfile に追加

プロジェクトの ‘package.json’ で、要件を ‘dependencies’ に追加します。:

主張

		String title = driver.getTitle();
		assertEquals("Web form", title);
    title = driver.title
    assert title == "Web form"
            var title = driver.Title;
            Assert.AreEqual("Web form", title);
    title = @driver.title
    expect(title).to eq('Web form')
    let title = await driver.getTitle();
    assert.equal("Web form", title);

セットアップとティアダウン

並べる

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

取り壊す

	@AfterEach
	public void teardown() {
		driver.quit();
	}

並べる

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

取り壊す

def teardown(driver):
    driver.quit()

並べる

  before do
    @driver = Selenium::WebDriver.for :chrome
  end

取り壊す

  config.after { @driver&.quit }
### 並べる
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
### 取り壊す
  after(async () => await driver.quit());

実行

Maven

mvn clean test

Gradle

gradle clean test
pytest path/to/test_script.py

Mocha

mocha runningTests.spec.js

npx

npx mocha runningTests.spec.js

最初のスクリプトのトピックでは、Seleniumスクリプトの各コンポーネントを見ました。こちらが、テストランナーを使用したそのコードの例です。

package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public void teardown() {
		driver.quit();
	}

}
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted
{
    [TestClass]
    public class UsingSeleniumTest
    {

        [TestMethod]
        public void EightComponents()
        {
            IWebDriver driver = new ChromeDriver();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

            var title = driver.Title;
            Assert.AreEqual("Web form", title);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            var textBox = driver.FindElement(By.Name("my-text"));
            var submitButton = driver.FindElement(By.TagName("button"));
            
            textBox.SendKeys("Selenium");
            submitButton.Click();
            
            var message = driver.FindElement(By.Id("message"));
            var value = message.Text;
            Assert.AreEqual("Received!", value);
            
            driver.Quit();
        }
    }
}
# frozen_string_literal: true
require 'spec_helper'
require 'selenium-webdriver'


RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});

次のステップ

学んだことを活かして、Seleniumコードを構築します!

必要な機能が他にも見つかったら、残りの機能をお読みください WebDriver ドキュメント.

2 - ドライバーセッション

セッションの開始と停止は、ブラウザーを開いたり閉じたりするためのものです。

セッションの作成

新しいセッションの作成は、W3C コマンド New session に対応しています。

セッションは、新しいDriverクラスオブジェクトを初期化することによって自動的に作成されます。

各言語では、次のいずれかのクラス (または同等のもの) の引数を使用してセッションを作成することができます。

ローカルドライバー

ローカルドライバーを起動するための主な一意の引数には、ローカルコンピューターで必要なドライバーサービスを起動するための情報が含まれます。

  • Serviceオブジェクトはローカルドライバーにのみ適用され、ブラウザーのドライバーに関する情報を提供します。
    WebDriver driver = new ChromeDriver(chromeOptions);
    driver = webdriver.Chrome(options=options)
            driver = new ChromeDriver(options);
      driver = Selenium::WebDriver.for :chrome, options: options
    let driver = new Builder()
        .forBrowser(Browser.CHROME)
        .setChromeOptions(options)
        .setChromeService(service)
        .build();

リモートドライバー

リモートドライバーを起動するための主な一意の引数には、コードを実行する場所に関する情報を含みます。 詳細は、リモートドライバーをご覧ください。

セッションの終了

セッションの終了に対するW3Cコマンドは、セッションの削除です。

重要: quit メソッドは close メソッドとは異なり、 セッションを終了するには常に quit を使用することをお勧めします。

2.1 - ブラウザーオプション

これらの機能はすべてのブラウザで共有されています。

Selenium 3 では、Capabilitiesは Desired Capabilities クラスを使用してセッションで定義していました。 Selenium 4 以降、ブラウザ オプション クラスを使用する必要があります。 リモート ドライバー セッションの場合、使用するブラウザーを決めるため、ブラウザーオプションインスタンスが必要です。

これらのオプションは、Capabilities の w3c仕様で説明しています。

各ブラウザには、w3c仕様で定義しているものに加えて定義可能な カスタム オプション があります。

browserName

オプションクラスのインスタンスを使用すると、ブラウザ名はデフォルトで設定されます。

	ChromeOptions chromeOptions = new ChromeOptions();
	String name = chromeOptions.getBrowserName();
    options = webdriver.ChromeOptions()
    assert options.capabilities['browserName'] == 'chrome'
      options = Selenium::WebDriver::Options.chrome

browserVersion

この機能はオプションであり、リモート側で使用可能なブラウザのバージョンを設定するために使用されます。最近のSeleniumのバージョンでは、システムにバージョンが見つからない場合、Selenium Manager によって自動的にダウンロードされます。

	ChromeOptions chromeOptions = new ChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
    options = webdriver.ChromeOptions()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
      options.browser_version = 'latest'

pageLoadStrategy

3種類のページ読み込み戦略を利用できます。

ページ読み込み戦略は、次の表で説明しています。

戦略準備完了状態注釈
normalcompleteデフォルトで使用され、すべてのリソースをダウンロードするのを待ちます
eagerinteractiveDOM アクセスの準備は整っていますが、画像などの他のリソースはまだロード中の可能性があります
noneAnyWebDriver をまったくブロックしません

ドキュメントの document.readyState プロパティは、現在のドキュメントの読み込み状態を示します。

URL 経由で新しいページに移動する場合、デフォルトでは、WebDriver は、ドキュメントの準備完了状態が完了するまで、 ナビゲーション メソッド (driver.navigate().get() など) の完了を保留します。 これは必ずしもページの読み込みが完了したことを意味するわけではありません。 特に、Ready State が完了した後に JavaScript を使用してコンテンツを動的に読み込むシングル ページ アプリケーションのようなサイトの場合はそうです。 また、この動作は、要素のクリックまたはフォームの送信の結果であるナビゲーションには適用されないことに注意してください。

自動化にとって重要ではないアセット (画像、css、js など) をダウンロードした結果、ページの読み込みに時間がかかる場合は、 デフォルトのパラメーターである normaleager または none に変更して、セッションの読み込みを高速化できます。 この値はセッション全体に適用されるため、 待機戦略 が不安定さを最小限に抑えるのに十分であることを確認してください。

normal (デフォルト)

WebDriver は load イベント検知するまで待機します。

    ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    options = webdriver.ChromeOptions()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace pageLoadStrategy {
  class pageLoadStrategy {
    public static void Main(string[] args) {
      var chromeOptions = new ChromeOptions();
      chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
      IWebDriver driver = new ChromeDriver(chromeOptions);
      try {
        driver.Navigate().GoToUrl("https://example.com");
      } finally {
        driver.Quit();
      }
    }
  }
}
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}

eager

WebDriver は、DOMContentLoaded イベントを検知するまで待機します。

    ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    options = webdriver.ChromeOptions()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace pageLoadStrategy {
  class pageLoadStrategy {
    public static void Main(string[] args) {
      var chromeOptions = new ChromeOptions();
      chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
      IWebDriver driver = new ChromeDriver(chromeOptions);
      try {
        driver.Navigate().GoToUrl("https://example.com");
      } finally {
        driver.Quit();
      }
    }
  }
}
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}

none

WebDriver は、最初のページがダウンロードされるまで待機します。

    ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    options = webdriver.ChromeOptions()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace pageLoadStrategy {
  class pageLoadStrategy {
    public static void Main(string[] args) {
      var chromeOptions = new ChromeOptions();
      chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
      IWebDriver driver = new ChromeDriver(chromeOptions);
      try {
        driver.Navigate().GoToUrl("https://example.com");
      } finally {
        driver.Quit();
      }
    }
  }
}
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}

platformName

これにより、リモートエンドのオペレーティングシステムが識別され、 platformName を取得するとOS名が返されます。

クラウドベースのプロバイダーでは、 platformName を設定すると、リモートエンドのOSが設定されます。

	ChromeOptions chromeOptions = new ChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
    options = webdriver.ChromeOptions()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'

acceptInsecureCerts

この機能は、セッション中のナビゲーション中に、期限切れ(または)無効な TLS証明書 が使用されているかどうかを確認します。

機能が false に設定されている場合、ナビゲーションでドメイン証明書の問題が発生すると、 insecure certificate error が返されます。 true に設定すると、無効な証明書はブラウザーによって信頼されます。

すべての自己署名証明書は、デフォルトでこの機能によって信頼されます。 一度設定すると、 acceptInsecureCerts Capabilityはセッション全体に影響します。

    ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    options = webdriver.ChromeOptions()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

timeouts

WebDriverの セッション には特定の セッションタイムアウト 間隔が設定されており、 その間、ユーザーはスクリプトの実行またはブラウザーからの情報の取得の動作を制御できます。

各セッションタイムアウトは、以下で説明するように、異なる タイムアウト の組み合わせで構成されます。

Script Timeout:

現在のブラウジングコンテキストで実行中のスクリプトをいつ中断するかを指定します。 新しいセッションがWebDriverによって作成されると、デフォルトのタイムアウト 30,000 が課されます。

	ChromeOptions chromeOptions = new ChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);
    options = webdriver.ChromeOptions()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

Page Load Timeout:

現在のブラウジングコンテキストでWebページをロードする必要がある時間間隔を指定します。 新しいセッションがWebDriverによって作成されると、デフォルトのタイムアウト 300,000 が課されます。 ページの読み込みが指定/デフォルトの時間枠を制限する場合、スクリプトは TimeoutException によって停止されます。

	ChromeOptions chromeOptions = new ChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);
    options = webdriver.ChromeOptions()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

Implicit Wait Timeout

これは、要素を検索するときに暗黙的な要素の検索戦略を待つ時間を指定します。 新しいセッションがWebDriverによって作成されると、デフォルトのタイムアウト 0 が課されます。

	ChromeOptions chromeOptions = new ChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);
    options = webdriver.ChromeOptions()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

unhandledPromptBehavior

現在のセッションの ユーザープロンプトハンドラー の状態を指定します。 デフォルトでは、 dismiss and notify (却下して通知する) 状態 となります。

User Prompt Handler

これは、リモートエンドでユーザープロンプトが表示されたときに実行する必要があるアクションを定義します。 これは、 unhandledPromptBehavior Capabilityによって定義され、次の状態があります。

  • dismiss (却下)
  • accept (受入)
  • dismiss and notify (却下して通知)
  • accept and notify (受け入れて通知)
  • ignore (無視)
	ChromeOptions chromeOptions = new ChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
    options = webdriver.ChromeOptions()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

setWindowRect

リモート エンドがすべての サイズ変更および再配置 コマンド をサポートするかどうかを示します。

   	ChromeOptions chromeOptions = new ChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

strictFileInteractability

この新しいcapabilityは、厳密な相互作用チェックを input type = file 要素に適用する必要があるかどうかを示します。 厳密な相互作用チェックはデフォルトでオフになっているため、隠しファイルのアップロードコントロールで Element Send Keys を使用する場合の動作が変更されます。

    ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
    options = webdriver.ChromeOptions()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

proxy

プロキシサーバーは、クライアントとサーバー間の要求の仲介役として機能します。 簡単に言えば、トラフィックはプロキシサーバーを経由して、要求したアドレスに戻り、戻ってきます。

Seleniumを使用した自動化スクリプト用のプロキシサーバーは、

  • ネットワークトラフィックをキャプチャする
  • ウェブサイトによって行われた模擬バックエンドを呼び出す
  • 複雑なネットワークトポロジーまたは厳格な企業の制限/ポリシーの下で、必要なWebサイトにアクセスします。

企業環境でブラウザがURLへの接続に失敗した場合、環境にアクセスするにはプロキシが必要であることが原因であることが最も可能性が高いです。

Selenium WebDriverは設定をプロキシする方法を提供します。

Move Code

import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class ProxyTest {
  public static void main(String[] args) {
    Proxy proxy = new Proxy();
    proxy.setHttpProxy("<HOST:PORT>");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("proxy", proxy);
    WebDriver driver = new ChromeDriver(options);
    driver.get("https://www.google.com/");
    driver.manage().window().maximize();
    driver.quit();
  }
}
    options = webdriver.ChromeOptions()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

public class ProxyTest{
public static void Main() {
ChromeOptions options = new ChromeOptions();
Proxy proxy = new Proxy();
proxy.Kind = ProxyKind.Manual;
proxy.IsAutoDetect = false;
proxy.SslProxy = "<HOST:PORT>";
options.Proxy = proxy;
options.AddArgument("ignore-certificate-errors");
IWebDriver driver = new ChromeDriver(options);
driver.Navigate().GoToUrl("https://www.selenium.dev/");
}
}
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')
let webdriver = require('selenium-webdriver');
let chrome = require('selenium-webdriver/chrome');
let proxy = require('selenium-webdriver/proxy');
let opts = new chrome.Options();

(async function example() {
opts.setProxy(proxy.manual({http: '<HOST:PORT>'}));
let driver = new webdriver.Builder()
.forBrowser('chrome')
.setChromeOptions(opts)
.build();
try {
await driver.get("https://selenium.dev");
}
finally {
await driver.quit();
}
}());
import org.openqa.selenium.Proxy
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

class proxyTest {
fun main() {

        val proxy = Proxy()
        proxy.setHttpProxy("<HOST:PORT>")
        val options = ChromeOptions()
        options.setCapability("proxy", proxy)
        val driver: WebDriver = ChromeDriver(options)
        driver["https://www.google.com/"]
        driver.manage().window().maximize()
        driver.quit()
    }
}

2.2 - HTTPクライアントの設定

これにより、HTTPライブラリのさまざまなパラメーターを設定できます。

package dev.selenium.drivers;

import dev.selenium.BaseTest;

import org.openqa.selenium.remote.http.ClientConfig;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import java.io.FileInputStream;
import java.net.URL;
import java.nio.file.Path;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.time.Duration;

import org.openqa.selenium.UsernameAndPassword;

import static java.net.http.HttpClient.Version.HTTP_1_1;

public class HttpClientTest extends BaseTest {
    URL gridUrl;

    @BeforeEach
    public void startGrid() {
        gridUrl = startStandaloneGridAdvanced();
    }

    @Test
    public void remoteWebDriverWithClientConfig() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = new ChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
        driver.quit();
    }

    @Test
    public void remoteWebDriverIgnoreSSL() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createIgnoreSSLContext())
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = new ChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
        driver.quit();
    }

    public static SSLContext createSSLContextWithCA(String caCertPath) throws Exception {
        FileInputStream fis = new FileInputStream(caCertPath);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate caCert = (X509Certificate) cf.generateCertificate(fis);
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);
        keyStore.setCertificateEntry("caCert", caCert);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(keyStore);
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);
        return sslContext;
    }

    public static SSLContext createIgnoreSSLContext() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }
        };
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
        return sslContext;
    }
}
import os
import pytest
import sys
from urllib3.util import Retry, Timeout
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType
from selenium.webdriver.remote.client_config import ClientConfig


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_with_client_config(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    retries = Retry(connect=2, read=2, redirect=2)
    timeout = Timeout(connect=300, read=3600)
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 init_args_for_pool_manager={
                                     "init_args_for_pool_manager": {"retries": retries, "timeout": timeout}},
                                 ca_certs=_get_resource_path("tls.crt"),
                                 username="admin", password="myStrongPassword")
    options = webdriver.ChromeOptions()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_ignore_certs(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 timeout=3600,
                                 ignore_certificates=True,
                                 username="admin", password="myStrongPassword")
    options = webdriver.ChromeOptions()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


def _get_resource_path(file_name: str):
    if os.path.abspath("").endswith("tests"):
        path = os.path.abspath(f"resources/{file_name}")
    else:
        path = os.path.abspath(f"tests/resources/{file_name}")
    return path
    client = Selenium::WebDriver::Remote::Http::Default.new(open_timeout: 30, read_timeout: 30)
    expect(client.open_timeout).to eq 30

2.3 - ドライバーサービスクラス

サービスクラスは、ドライバーの起動と停止を管理するためのものです。リモートWebDriverセッションでは使用できません。

サービスクラスを使用すると、ドライバーに関する情報(場所や使用するポートなど)を指定できます。また、コマンドラインに渡される引数を指定することもできます。便利な引数のほとんどは、ログに関連しています。

デフォルトサービスインスタンス

デフォルトサービスインスタンスを使用してドライバーを起動するには:

    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);

Selenium v4.11

    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service

ドライバーの場所

注意: Selenium 4.6以上を使用している場合、ドライバーの場所を設定する必要はありません。Seleniumを更新できない場合や、特別な使用ケースがある場合は、ドライバーの場所を指定する方法は次のとおりです:

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

Selenium v4.11

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

Selenium v4.9

            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

Selenium v4.8

    service.executable_path = driver_path

ドライバーのポート

ドライバーを特定のポートで実行したい場合は、次のように指定できます:

    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

Selenium v4.11

    service = webdriver.ChromeService(port=1234)
            service.Port = 1234;

ログ記録

ログ記録機能はブラウザによって異なります。ほとんどのブラウザでは、ログの場所とレベルを指定できます。各ブラウザのページを確認してください:

2.4 - リモートWebDriver

Seleniumは、リモートコンピュータ上でブラウザを自動化することができます。これには、リモートコンピュータ上で Selenium Grid が実行されている必要があります。コードを実行するコンピュータはクライアントコンピュータと呼ばれ、ブラウザとドライバーがあるコンピュータはリモートコンピュータまたは時々エンドノードと呼ばれます。Seleniumテストをリモートコンピュータに向けるには、Remote WebDriverクラスを使用し、そのマシンのグリッドのポートを含むURLを渡す必要があります。グリッドの設定方法については、グリッドのドキュメントを参照してください。

基本的な例

ドライバーは、コマンドを送信する場所と、リモートコンピュータ上で開始するブラウザを知る必要があります。そのため、アドレスとオプションインスタンスの両方が必要です。

    ChromeOptions options = new ChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    options = webdriver.ChromeOptions()
    driver = webdriver.Remote(command_executor=server, options=options)
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

アップロード

ファイルのアップロード は、リモートWebDriverセッションではより複雑です。アップロードしたいファイルはコードを実行しているコンピュータ上にあることが多いですが、リモートコンピュータ上のドライバーはそのローカルファイルシステム上で指定されたパスを探しています。この解決策として、ローカルファイルディテクターを使用します。これを設定すると、Seleniumはファイルをパッケージ化し、リモートマシンに送信するため、ドライバーはその参照を認識できるようになります。一部のバインディングでは、デフォルトで基本的なローカルファイルディテクターが含まれており、すべてのバインディングでカスタムファイルディテクターを設定できます。

Javaにはデフォルトでローカルファイルディテクターが含まれていないため、アップロードを行う際には必ず追加する必要があります。
    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

Pythonでは、リモートWebDriverインスタンスにデフォルトでローカルファイルディテクターが追加されますが、独自のクラスを作成することも可能です。

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
.NETでは、リモートWebDriverインスタンスにデフォルトでローカルファイルディテクターが追加されますが、独自のクラスを作成することも可能です。
            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
Rubyでは、リモートWebDriverインスタンスにデフォルトでローカルファイルディテクターが追加されますが、独自のラムダを作成することも可能です。
    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

ダウンロード

Chrome、Edge、およびFirefoxでは、それぞれダウンロードディレクトリの場所を設定できます。 ただし、リモートコンピュータでこれを行う場合、その場所はリモートコンピュータのローカルファイルシステム上にあります。Seleniumを使用すると、クライアントコンピュータにこれらのファイルをダウンロードできるように設定することが可能です。

グリッドでのダウンロードを有効化

クライアントに関係なく、ノードまたはスタンドアロンモードでグリッドを起動する際には、次のフラグを追加する必要があります:

--enable-managed-downloads true

クライアントでのダウンロードを有効化

グリッドは、se:downloadsEnabled 機能を使用して、ブラウザの場所を管理する責任を持つかどうかを切り替えます。各バインディングには、これを設定するためのオプションクラスのメソッドがあります。

    ChromeOptions options = new ChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);
    options = webdriver.ChromeOptions()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

ダウンロード可能なファイルの一覧

Seleniumはファイルのダウンロードが完了するのを待たないため、リストは指定されたセッションのディレクトリに現在存在するファイル名の即時スナップショットであることに注意してください。

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();
    files = driver.get_downloadable_files()
            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();
    files = driver.downloadable_files

ファイルをダウンロード

Seleniumは、提供されたファイルの名前をリストの中で探し、指定されたターゲットディレクトリにダウンロードします。

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);
    driver.download_file(downloadable_file, target_directory)
            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);
    driver.download_file(downloadable_file, target_directory)

ダウンロードしたファイルの削除

デフォルトでは、ダウンロードディレクトリは該当するセッションの終了時に削除されますが、セッション中にすべてのファイルを削除することもできます。

    ((HasDownloads) driver).deleteDownloadableFiles();
    driver.delete_downloadable_files()
            ((RemoteWebDriver)driver).DeleteDownloadableFiles();
    driver.delete_downloadable_files

ブラウザ特有の機能

ブラウザ は、そのブラウザにのみ利用可能な特別な機能を実装しています。各Seleniumバインディングは、リモートセッションでそれらの機能を使用するための異なる方法を実装しています。

Javaでは、Augmenterクラスを使用する必要があります。これにより、RemoteWebDriverで使用される機能に一致するすべてのインターフェースの実装を自動的に取り込むことができます。

    driver = new Augmenter().augment(driver);

興味深いことに、RemoteWebDriverBuilderを使用すると、ドライバーが自動的に拡張されるため、デフォルトで全ての機能を取得するのに最適な方法です。

        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(new ChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();
.NETでは、リモートドライバーで指定されたブラウザに対して有効なコマンドを実行するために、カスタムコマンドエグゼキュータを使用します。
            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);
Rubyでは、ミキシンを使用してリモートWebDriverセッションに適用可能なブラウザ特有のメソッドを追加します。これらのメソッドは常にそのまま機能するはずです。

クライアントのリクエストをトレースする

この機能は、Java クライアント バインディング (ベータ版以降) でのみ利用できます。 Remote WebDriver クライアントは Selenium Grid サーバーにリクエストを送信し、 Selenium Grid サーバーはリクエストを WebDriver に渡します。 HTTP リクエストをエンド ツー エンドでトレースするには、サーバー側とクライアント側でトレースを有効にする必要があります。 両端には、視覚化フレームワークを指すトレース エクスポーターのセットアップが必要です。 デフォルトでは、トレースはクライアントとサーバーの両方で有効になっています。 視覚化フレームワークの Jaeger UI と Selenium Grid 4 を設定するには、目的のバージョンの トレースのセットアップ を参照してください。

クライアント側のセットアップについては、以下の手順に従ってください。

必要な依存関係を追加する

トレーシング エクスポーターの外部ライブラリのインストールは、Maven を使って実行できます。 プロジェクト pom.xml に opentelemetry-exporter-jaeger および grpc-netty の依存関係を追加します。

  <dependency>
      <groupId>io.opentelemetry</groupId>
      <artifactId>opentelemetry-exporter-jaeger</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-netty</artifactId>
      <version>1.35.0</version>
    </dependency>

クライアントの実行中に必要なシステムプロパティを追加/渡す

System.setProperty("otel.traces.exporter", "jaeger");
System.setProperty("otel.exporter.jaeger.endpoint", "http://localhost:14250");
System.setProperty("otel.resource.attributes", "service.name=selenium-java-client");

ImmutableCapabilities capabilities = new ImmutableCapabilities("browserName", "chrome");

WebDriver driver = new RemoteWebDriver(new URL("http://www.example.com"), capabilities);

driver.get("http://www.google.com");

driver.quit();

  

ご希望のSeleniumのバージョンに必要な外部依存関係のバージョンの詳細については、 トレースのセットアップ を参照してください。

詳細については、下記URLを参照してください。

3 - 対応ブラウザ

各ブラウザにはカスタム機能とユニークな特徴があります。

3.1 - Chrome固有の機能

これらは、Google Chromeブラウザに特有の機能と機能です。

これらは、Google Chromeブラウザに特有の機能と機能です。 デフォルトでは、Selenium 4はChrome v75以上と互換性があります。Chromeブラウザのバージョンとchromedriverのバージョンは、メジャーバージョンが一致する必要があることに注意してください。

Options

すべてのブラウザに共通する機能は オプション ページに記載されています。

ChromeおよびChromiumに特有の機能は、Googleの Capabilities & ChromeOptionsのページにドキュメントされています。

基本的に定義されたオプションでChromeセッションを開始する場合は、次のようになります:

    ChromeOptions options = new ChromeOptions();
    driver = new ChromeDriver(options);
    options = webdriver.ChromeOptions()
    driver = webdriver.Chrome(options=options)
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

引数

args パラメータは、ブラウザを起動する際に使用するコマンドラインスイッチのリストです。これらの引数を調査するための優れたリソースが2つあります:

一般的に使用されるargsには以下が含まれます:--start-maximized, --headless=new and --user-data-dir=...

オプションに引数を追加:

    options.addArguments("--start-maximized");
    options.add_argument("--start-maximized")
            options.AddArgument("--start-maximized");
      options.args << '--start-maximized'
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

指定したロケーションでブラウザを起動する

binaryパラメーターは、使用するブラウザの別のロケーションのパスを取ります。 このパラメーターを使用すると、chromedriver を使用して、さまざまな Chromium ベースのブラウザを駆動できます。

オプションにブラウザのロケーションを追加します。

    options.setBinary(getChromeLocation());
    options.binary_location = chrome_bin
            options.BinaryLocation = GetChromeLocation();
      options.binary = chrome_location
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

拡張機能を追加する

extensions パラメーターはcrxファイルを受け入れます

The extensions パラメータはcrxファイルを受け入れます。解凍されたディレクトリについては、代わりに load-extension 引数を使用してください。この投稿で述べたように。

オプションに拡張機能を追加します。

    options.addExtensions(extensionFilePath);
    options.add_extension(extension_file_path)
            options.AddExtension(extensionFilePath);
      options.add_extension(extension_file_path)
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

ブラウザを開いたままにする

detach パラメータをtrueに設定すると、ドライバープロセスが終了した後もブラウザを開いたままにできます。

注意: これはすでにJavaのデフォルトの動作です。

    options.add_experimental_option("detach", True)

注意: これはすでに.NETのデフォルトの動作です。

      options.detach = true
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

引数を除外する

Chrome はさまざまな引数を追加します。 これらの引数を追加したくない場合は、それらを excludeSwitches に渡します。 一般的な例は、ポップアップブロッカーをオンに設定することです。

デフォルトの引数の完全なリストは、 Chromium Source Codeから解析できます。

オプションに除外された引数を設定します。

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));
    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])
            options.AddExcludedArgument("disable-popup-blocking");
      options.exclude_switches << 'disable-popup-blocking'
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

サービス

デフォルトのServiceオブジェクトを作成するための例や、ドライバーの場所とポートを設定する方法は、Driver Serviceページにあります。

ログ出力

ドライバーログを取得することは、問題のデバッグに役立ちます。Serviceクラスを使用すると、ログの出力先を指定できます。ユーザーがどこかにログを指示しない限り、ログ出力は無視されます。

ファイル出力

ログ出力を特定のファイルに保存するように変更するには:

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

注意: Javaでは、システムプロパティによってファイル出力を設定することもできます:
プロパティキー: ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY
プロパティ値: ログファイルへのパスを表す文字列

Selenium v4.11

    service = webdriver.ChromeService(log_output=log_path)
            service.LogPath = GetLogLocation();

コンソール出力

ログ出力をコンソールにSTDOUTとして表示するように変更するには:

Selenium v4.10

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

注意: Javaでは、システムプロパティによってコンソール出力を設定することもできます。
プロパティキー: ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY
プロパティ値: DriverService.LOG_STDOUT または DriverService.LOG_STDERR

Selenium v4.11

    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

$stdout$stderr はどちらも有効な値です。

Selenium v4.10

      service.log = $stdout

ログレベル

利用可能なログレベルは6つあります:ALL, DEBUG, INFO, WARNING, SEVERE, そして OFF--verbose--log-level=ALL と同等であり、--silent--log-level=OFFと同等であることに注意してください。このため、この例ではログレベルを一般的に設定しています:

Selenium v4.8

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

注意: Javaでは、システムプロパティによってログレベルを設定することもできます:
プロパティキー: ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY
プロパティ値: ChromiumDriverLogLevel 列挙型の文字列表現

Selenium v4.11

    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

Selenium v4.10

      service.args << '--log-level=DEBUG'

ログファイル機能

ファイルにログを記録する際にのみ利用できる2つの機能があります:

  • ログの追加
  • 読みやすいタイムスタンプ

これらを使用するには、ログパスとログレベルも明示的に指定する必要があります。ログ出力はプロセスではなくドライバーによって管理されるため、若干の違いが見られる場合があります。

Selenium v4.8

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

注意: Javaでは、これらの機能をシステムプロパティによって切り替えることもできます:
プロパティキー: ChromeDriverService.CHROME_DRIVER_APPEND_LOG_PROPERTY およびChromeDriverService.CHROME_DRIVER_READABLE_TIMESTAMP
プロパティ値: "true" または "false"

    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

Selenium v4.8

      service.args << '--append-log'
      service.args << '--readable-timestamp'

ビルドチェックの無効化

ChromedriverとChromeブラウザのバージョンは一致する必要があり、一致しない場合、ドライバーはエラーを返します。ビルドチェックを無効にすると、任意のバージョンのChromeでドライバーを強制的に使用できます。ただし、これはサポートされていない機能であり、バグは調査されません。

Selenium v4.8

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

注意: Javaでは、システムプロパティによってビルドチェックを無効にすることもできます:
プロパティキー: ChromeDriverService.CHROME_DRIVER_DISABLE_BUILD_CHECK
プロパティ値: "true" または "false"

Selenium v4.11

    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)
            service.DisableBuildCheck = true;

Selenium v4.8

      service.args << '--disable-build-check'

特別な機能

一部のブラウザは、それぞれに特有の追加機能を実装しています。

キャスティング

Chrome Castデバイスを操作することができ、タブの共有も含まれます。

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end

ネットワークの状態

さまざまなネットワークの状態をシミュレートできます。

以下の例はローカルWebDriver用です。リモートWebDriverについては、リモートWebDriverページを参照してください。

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);
    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}

ログ

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);
    logs = driver.get_log("browser")
      logs = @driver.logs.get(:browser)

パーミッション

    driver.setPermission("camera", "denied");
    driver.set_permissions('camera', 'denied')
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')

デベロッパー ツール

Chromeデベロッパーツールの使用に関する詳細については、[Chromeデベロッパー ツール] セクションを参照してください。

3.2 - Edge固有の機能

これらは、Microsoft Edgeブラウザに固有のCapabilityです。

Microsoft EdgeはChromiumで実装されており、サポートされている最も古いバージョンはv79です。 Chromeと同様に、edgedriverのメジャー バージョン番号は、Edgeブラウザのメジャーバージョンと一致する必要があります。

Chromeページ にあるすべての機能とオプションは、Edgeでも機能します。

オプション

すべてのブラウザに共通する機能はオプション ページに記載されています。

Chromiumに特有の機能は、GoogleのCapabilities & ChromeOptionsページに文書化されています。

基本的な定義済みオプションを使用して Edgeセッションを開始すると、次のようになります。

  public void basicOptions() {
    EdgeOptions options = new EdgeOptions();
    options = webdriver.EdgeOptions()
    driver = webdriver.Edge(options=options)
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    let options = new edge.Options();
    driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options)
      .build();

引数

args パラメータは、ブラウザを起動する際に使用されるコマンドラインスイッチのリストです。これらの引数を調査するための優れたリソースが2つあります:

一般的に使用される引数には、--start-maximized および --headless=new が含まれます。 and --user-data-dir=...

オプションに引数を追加します。

    options.add_argument("--start-maximized")
            options.AddArgument("--start-maximized");
      options.args << '--start-maximized'
      .setEdgeOptions(options.addArguments('--headless=new'))

指定された場所でブラウザを起動する

binary パラメータは、使用するブラウザの代替位置のパスを指定します。このパラメータを使用すると、chromedriverを利用してさまざまなChromiumベースのブラウザを操作できます。

オプションにブラウザの場所を追加する:

    options.binary_location = edge_bin
            options.BinaryLocation = GetEdgeLocation();
      options.binary = edge_location

拡張機能を追加する

extensions パラメータは、crxファイルを受け入れます。展開されたディレクトリについては、load-extension 引数を使用してください。このことはこの投稿で言及されています。

オプションに拡張機能を追加する:

    options.add_extension(extension_file_path)
            options.AddExtension(extensionFilePath);
      options.add_extension(extension_file_path)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))

ブラウザを開いたままにする

detach パラメータをtrue に設定すると、プロセスが終了した後でもブラウザが開いたままになります。ただし、quit コマンドがドライバーに送信されない限り、ブラウザは開いたままになります。

注意: これはすでにJavaのデフォルトの動作です。

    options.add_experimental_option("detach", True)

注意: これはすでに.NETのデフォルトの動作です。

      options.detach = true
      .setEdgeOptions(options.detachDriver(true))

引数を除外する

MSEdgedriverには、ブラウザを起動するために使用されるいくつかのデフォルト引数があります。それらの引数を追加したくない場合は、excludeSwitchesに渡してください。一般的な例は、ポップアップブロッカーを再度オンにすることです。デフォルト引数の完全なリストはChromium Source Codeから解析できます。

オプションに除外された引数を設定する:

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])
            options.AddExcludedArgument("disable-popup-blocking");
      options.exclude_switches << 'disable-popup-blocking'
      .setEdgeOptions(options.excludeSwitches('enable-automation'))

サービス

デフォルトのサービスオブジェクトを作成するための例や、ドライバの場所とポートを設定する例は、Driver Service ページにあります。

ログ出力

ドライバのログを取得することは、問題をデバッグするのに役立ちます。サービスクラスを使用すると、ログの出力先を指定できます。ユーザーがどこかにログを指示しない限り、ログ出力は無視されます。

ファイル出力

特定のファイルに保存するようにログ出力を変更するには、以下のようにします:

Selenium v4.10

    File logLocation = getTempFile("logsToFile", ".log");

注意: Javaでもシステムプロパティを使用してファイル出力を設定できます:
プロパティキー: EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY
プロパティ値: ログファイルのパスを表す文字列

    service = webdriver.EdgeService(log_output=log_path)
            service.LogPath = GetLogLocation();

コンソール出力

ログ出力をコンソールにSTDOUTとして表示するには:

Selenium v4.10

: Javaでは、システムプロパティを使用してコンソール出力を設定することもできます。
プロパティキー: EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY
プロパティ値:DriverService.LOG_STDOUT または DriverService.LOG_STDERR

Selenium v4.11

    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

$stdout$stderrはどちらも有効な値です。

Selenium v4.10

      service.log = $stdout

ログレベル

利用可能なログレベルは6つあります:ALL, DEBUG, INFO, WARNING, SEVEREおよび OFF--verbose--log-level=ALL と同等であり、--silent--log-level=OFFと同等です。したがって、この例ではログレベルを一般的に設定しています:

Selenium v4.8


    EdgeDriverService service =

注意: Javaでは、システムプロパティを使用してログレベルを設定することもできます:
プロパティキー: EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY
プロパティ値:ChromiumDriverLogLevel 列挙型の文字列表現

    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

Selenium v4.10

      service.args << '--log-level=DEBUG'

ログファイルの機能

ファイルにログを記録する際にのみ利用可能な2つの機能があります:

  • ログの追加
  • 読みやすいタイムスタンプ

これらを使用するには、ログパスとログレベルも明示的に指定する必要があります。ログ出力はプロセスではなくドライバによって管理されるため、若干の違いが見られることがあります。

Selenium v4.8


    EdgeDriverService service =

注意: Javaでは、これらの機能をSystem Propertyによって切り替えることもできます:
プロパティキー:EdgeDriverService.EDGE_DRIVER_APPEND_LOG_PROPERTY および EdgeDriverService.EDGE_DRIVER_READABLE_TIMESTAMP
プロパティ値: "true" または "false"

    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

Selenium v4.8

      service.args << '--append-log'
      service.args << '--readable-timestamp'

ビルドチェックの無効化

Edge ブラウザとmsedgedriverのバージョンは一致する必要があり、一致しない場合はドライバにエラーが表示されます。ビルドチェックを無効にすると、任意のバージョンのEdgeでドライバを強制的に使用できます。 この機能はサポートされていないことに注意してください。バグは調査されません。

Selenium v4.8


    EdgeDriverService service =

: Javaでは、システムプロパティを使用してビルドチェックを無効にすることもできます:
プロパティキー:EdgeDriverService.EDGE_DRIVER_DISABLE_BUILD_CHECK
プロパティ値: "true" または "false"

    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)
            service.DisableBuildCheck = true;

Selenium v4.8

      service.args << '--disable-build-check'

Internet Explorer Compatibility モード

Microsoft Edge は、Internet Explorer ドライバークラスを Microsoft Edgeと組み合わせて使用する “Internet Explorer 互換モード"で動かすことができます。 詳細については、Internet Explorerページを参照してください。

特別な機能

一部のブラウザは、それぞれ特有の追加機能を実装しています。

キャスティング

Edge を使用して Chrome Cast デバイスを操作し、タブを共有することができます。

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception

ネットワーク条件

さまざまなネットワーク条件をシミュレートすることができます。


    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps
    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}

ログ

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);
    logs = driver.get_log("browser")
      logs = @driver.logs.get(:browser)

権限

    driver.set_permissions('camera', 'denied')
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')

DevTools

EdgeでDevToolsを使用する際の詳細については、[Chrome DevTools]セクションを参照してください。

3.3 - Firefox特有の機能

これらは、Mozilla Firefoxブラウザに特有の機能と機能です。

Selenium 4 には Firefox 78 以降が必要です。 常に最新バージョンの geckodriver を使用することをお勧めします。

オプション

全ブラウザに共通のCapabilityについては、オプションページで説明しています。

Firefox に固有のCapabilityは、Mozilla のページの firefoxOptions にあります。

基本的な定義済みのオプションを使用して Firefox セッションを開始すると、以下のようになります。

    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options)
      .build();

さまざまなCapabilityを備えた一般的な使用例をいくつか示します。

引数

args パラメータは、ブラウザの起動時に使用するコマンドラインスイッチのリストです。 一般的に使用される引数には、 -headless"-profile""/path/to/profile" が含まれます。

オプションに引数を追加します。

    options.addArguments("-headless");
    options.add_argument("-headless")
            options.AddArgument("-headless");
      options.args << '-headless'
      .setFirefoxOptions(options.addArguments('--headless'))

指定したロケーションでブラウザを起動する

binary パラメーターは、使用するブラウザーの別のロケーションのパスを取ります。 たとえば、このパラメーターを使用すると、geckodriver を使用して、製品版とFirefox Nightlyの両方がコンピューターに存在する場合、 製品版の代わりに Firefox Nightly を駆動できます 。

オプションにブラウザーのロケーションを追加します。

    options.setBinary(getFirefoxLocation());
    options.binary_location = firefox_bin
            options.BinaryLocation = GetFirefoxLocation();
      options.binary = firefox_location

プロファイル

Firefoxプロファイルを操作するにはいくつかの方法があります。

    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)
var options = new FirefoxOptions();
var profile = new FirefoxProfile();
options.Profile = profile;
var driver = new RemoteWebDriver(options);
  
      profile = Selenium::WebDriver::Firefox::Profile.new
        profile['browser.download.dir'] = '/tmp/webdriver-downloads'
        options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
const { Builder } = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');

const options = new firefox.Options();
let profile = '/path to custom profile';
options.setProfile(profile);
const driver = new Builder()
    .forBrowser('firefox')
    .setFirefoxOptions(options)
    .build();
  
val options = FirefoxOptions()
options.profile = FirefoxProfile()
driver = RemoteWebDriver(options)
  

サービス

すべてのブラウザに共通するサービス設定は、Service pageに記載されています。

ログ出力

ドライバーログを取得することは、さまざまな問題のデバッグに役立ちます。サービスクラスを使用すると、ログの保存先を指定できます。ログ出力は、ユーザーがどこかに指定しない限り無視されます。

ファイル出力

特定のファイルにログ出力を保存するには:

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

: Java では、システムプロパティによってファイル出力を設定することもできます。
プロパティキー:GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY
プロパティ値: ログファイルへのパスを表す文字列

Selenium v4.11

    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

コンソール出力

ログ出力をコンソールに表示するには、以下のようにします:

Selenium v4.10

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

注意: Javaは、システムプロパティを使用してコンソール出力を設定することもできます;
プロパティキー: GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY
プロパティ値: DriverService.LOG_STDOUT または DriverService.LOG_STDERR

Selenium v4.11

    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

ログレベル

利用可能なログレベルは7つあります: fatal, error, warn, info, config, debug, trace。 ロギングが指定されている場合、デフォルトのレベルは infoになります。

-v iは -log debug と同等であり、-vvlog traceと同等です。 したがって、この例は一般的にログレベルを設定するためのものです:

Selenium v4.10

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

注意: Javaは、システムプロパティによってログレベルの設定も可能です:
プロパティキー: GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY
プロパティ値:FirefoxDriverLogLevel列挙型の文字列表現

Selenium v4.11

    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

Selenium v4.10

      service.args += %w[--log debug]

トランケートログ

ドライバーは、大きなバイナリの文字列表現を含む、送信されたすべてのものをログに記録します。そのため、Firefoxではデフォルトで行が切り捨てられます。切り捨てを無効にするには:

Selenium v4.10

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

注意: Javaでは、システムプロパティによってログレベルを設定することもできます。
プロパティキー: GeckoDriverService.GECKO_DRIVER_LOG_NO_TRUNCATE
プロパティ値: "true" または "false"

Selenium v4.11

    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

Selenium v4.10

      service.args << '--log-no-truncate'

プロファイルルート

プロファイルのデフォルトディレクトリは、システムの一時ディレクトリです。そのディレクトリにアクセスできない場合や、特定の場所にプロファイルを作成したい場合は、プロファイルルートディレクトリを変更できます:

Selenium v4.10

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

注意: Javaでは、システムプロパティを使用してログレベルを設定することもできます:
プロパティキー: GeckoDriverService.GECKO_DRIVER_PROFILE_ROOT
プロパティ値: プロファイルルートディレクトリへのパスを表す文字列

    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

Selenium v4.8

      service.args += ['--profile-root', root_directory]

特別な機能

アドオン

Chromeとは異なり、Firefoxの拡張機能はCapabilityの一部として追加されるのではなく、ドライバーの起動後に作成されます。

Chromeとは異なり、Firefoxの拡張機能はこの問題に記載されているように、機能の一部として追加されるのではなく、ドライバーの起動後に作成されます。

T以下の例はローカルWebDriver用です。リモートWebDriverについては、Remote WebDriverページを参照してください。

インストール

Mozilla Add-Onsページ から取得する署名付きxpiファイル

    driver.installExtension(xpiPath);
    driver.install_addon(addon_path_xpi)
            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));
      driver.install_addon(extension_file_path)
    let id = await driver.installAddon(xpiPath);

アンインストール

アドオンをアンインストールするには、そのIDを知る必要があります。 IDはアドオンインストール時の戻り値から取得できます。

    driver.uninstallExtension(id);
    driver.uninstall_addon(id)

Selenium v4.5

            driver.UninstallAddOn(extensionId);
      driver.uninstall_addon(extension_id)
    await driver.uninstallAddon(id);

署名なしのインストール

未完成または未公開の拡張機能を使用する場合、署名されていない可能性があります。 そのため、“一時的なもの” としてのみインストールできます。 これは、zipファイルまたはディレクトリを渡すことで実行できます。ディレクトリの例を次に示します。

    driver.installExtension(path, true);
    driver.install_addon(addon_path_dir, temporary=True)

Selenium v4.5

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

Selenium v4.5

      driver.install_addon(extension_dir_path, true)
    let id = await driver.installAddon(xpiPath, true);

ページ全体のスクリーンショット

以下の例はローカルWebDriver用です。リモートWebDriverについては、Remote WebDriverページを参照してください。

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);
    driver.save_full_page_screenshot("full_page_screenshot.png")
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

コンテキスト

以下の例はローカルWebDriver用です。リモートWebDriverについては、Remote WebDriverページを参照してください。

    ((HasContext) driver).setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");
    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")
      driver.context = 'content'

3.4 - IE特有の機能

これらは、Microsoft Internet Explorerブラウザに特有の機能と機能です。

As of June 2022, Selenium officially no longer supports standalone Internet Explorer. The Internet Explorer driver still supports running Microsoft Edge in “IE Compatibility Mode.”

Special considerations

The IE Driver is the only driver maintained by the Selenium Project directly. While binaries for both the 32-bit and 64-bit versions of Internet Explorer are available, there are some known limitations with the 64-bit driver. As such it is recommended to use the 32-bit driver.

Additional information about using Internet Explorer can be found on the IE Driver Server page

Options

Starting a Microsoft Edge browser in Internet Explorer Compatibility mode with basic defined options looks like this:

        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options

As of Internet Explorer Driver v4.5.0:

  • If IE is not present on the system (default in Windows 11), you do not need to use the two parameters above. IE Driver will use Edge and will automatically locate it.
  • If IE and Edge are both present on the system, you only need to set attaching to Edge, IE Driver will automatically locate Edge on your system.

So, if IE is not on the system, you only need:

        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
let driver = await new Builder()
.forBrowser('internet explorer')
.setIEOptions(options)
.build();
<p><a href=/documentation/about/contributing/#moving-examples>
<span class="selenium-badge-code" data-bs-toggle="tooltip" data-bs-placement="right"
      title="One or more of these examples need to be implemented in the examples directory; click for details in the contribution guide">Move Code</span></a></p>


val options = InternetExplorerOptions()
val driver = InternetExplorerDriver(options)

Here are a few common use cases with different capabilities:

fileUploadDialogTimeout

環境によっては、ファイルアップロードダイアログを開くときにInternet Explorerがタイムアウトする場合があります。 IEDriverのデフォルトのタイムアウトは1000ミリ秒ですが、fileUploadDialogTimeout capabilityを使用してタイムアウトを増やすことができます。

InternetExplorerOptions options = new InternetExplorerOptions();
options.waitForUploadDialogUpTo(Duration.ofSeconds(2));
WebDriver driver = new RemoteWebDriver(options);
  
from selenium import webdriver

options = webdriver.IeOptions()
options.file_upload_dialog_timeout = 2000
driver = webdriver.Ie(options=options)

driver.get("http://www.google.com")

driver.quit()
  
var options = new InternetExplorerOptions();
options.FileUploadDialogTimeout = TimeSpan.FromMilliseconds(2000);
var driver = new RemoteWebDriver(options);
  
      @options.file_upload_dialog_timeout = 2000
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().fileUploadDialogTimeout(2000);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
val options = InternetExplorerOptions()
options.waitForUploadDialogUpTo(Duration.ofSeconds(2))
val driver = RemoteWebDriver(options)
  

ensureCleanSession

この機能を true に設定すると、手動またはドライバーによって開始されたものを含め、 InternetExplorerの実行中のすべてのインスタンスのキャッシュ、ブラウザー履歴、およびCookieがクリアされます。 デフォルトでは、false に設定されています。

この機能を使用すると、ドライバーがIEブラウザーを起動する前にキャッシュがクリアされるまで待機するため、 ブラウザーの起動中にパフォーマンスが低下します。

このケイパビリティは、ブール値をパラメーターとして受け入れます。

InternetExplorerOptions options = new InternetExplorerOptions();
options.destructivelyEnsureCleanSession();
WebDriver driver = new RemoteWebDriver(options);
  
from selenium import webdriver

options = webdriver.IeOptions()
options.ensure_clean_session = True
driver = webdriver.Ie(options=options)

driver.get("http://www.google.com")

driver.quit()
  
var options = new InternetExplorerOptions();
options.EnsureCleanSession = true;
var driver = new RemoteWebDriver(options);
  
      @options.ensure_clean_session = true
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().ensureCleanSession(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
val options = InternetExplorerOptions()
options.destructivelyEnsureCleanSession()
val driver = RemoteWebDriver(options)
  

ignoreZoomSetting

InternetExplorerドライバーは、ブラウザーのズームレベルが100%であることを想定しています。 それ以外の場合、ドライバーは例外をスローします。 このデフォルトの動作は、 ignoreZoomSettingtrue に設定することで無効にできます。

このケイパビリティは、ブール値をパラメーターとして受け入れます。

InternetExplorerOptions options = new InternetExplorerOptions();
options.ignoreZoomSettings();
WebDriver driver = new RemoteWebDriver(options);
  
from selenium import webdriver

options = webdriver.IeOptions()
options.ignore_zoom_level = True
driver = webdriver.Ie(options=options)

driver.get("http://www.google.com")

driver.quit()
  
var options = new InternetExplorerOptions();
options.IgnoreZoomLevel = true;
var driver = new RemoteWebDriver(options);
  
      @options.ignore_zoom_level = true
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().ignoreZoomSetting(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
val options = InternetExplorerOptions()
options.ignoreZoomSettings()
val driver = RemoteWebDriver(options)
  

ignoreProtectedModeSettings

新しいIEセッションの起動中に 保護モード チェックをスキップするかどうか。

設定されておらず、 保護モード 設定がすべてのゾーンで同じでない場合、 ドライバーによって例外がスローされます。

ケイパビリティを true に設定すると、テストが不安定になったり、応答しなくなったり、 ブラウザがハングしたりする場合があります。 ただし、これはまだ2番目に良い選択であり、最初の選択は 常に 各ゾーンの保護モード設定を手動で実際に設定することです。 ユーザーがこのプロパティを使用している場合、「ベストエフォート」のみがサポートされます。

このケイパビリティは、ブール値をパラメーターとして受け入れます。

InternetExplorerOptions options = new InternetExplorerOptions();
options.introduceFlakinessByIgnoringSecurityDomains();
WebDriver driver = new RemoteWebDriver(options);
  
from selenium import webdriver

options = webdriver.IeOptions()
options.ignore_protected_mode_settings = True
driver = webdriver.Ie(options=options)

driver.get("http://www.google.com")

driver.quit()
  
var options = new InternetExplorerOptions();
options.IntroduceInstabilityByIgnoringProtectedModeSettings = true;
var driver = new RemoteWebDriver(options);
  
      @options.ignore_protected_mode_settings = true
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().introduceFlakinessByIgnoringProtectedModeSettings(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
val options = InternetExplorerOptions()
options.introduceFlakinessByIgnoringSecurityDomains()
val driver = RemoteWebDriver(options)
  

silent

true に設定すると、このケイパビリティはIEDriverServerの診断出力を抑制します。

このケイパビリティは、ブール値をパラメーターとして受け入れます。

InternetExplorerOptions options = new InternetExplorerOptions();
options.setCapability("silent", true);
WebDriver driver = new InternetExplorerDriver(options);
  
from selenium import webdriver

options = webdriver.IeOptions()
options.set_capability("silent", True)
driver = webdriver.Ie(options=options)

driver.get("http://www.google.com")

driver.quit()
  
InternetExplorerOptions options = new InternetExplorerOptions();
options.AddAdditionalInternetExplorerOption("silent", true);
IWebDriver driver = new InternetExplorerDriver(options);
  
      @options.silent = true
const {Builder,By, Capabilities} = require('selenium-webdriver');
let caps = Capabilities.ie();
caps.set('silent', true);

(async function example() {
    let driver = await new Builder()
        .forBrowser('internet explorer')
        .withCapabilities(caps)
        .build();
    try {
        await driver.get('http://www.google.com/ncr');
    }
    finally {
        await driver.quit();
    }
})();
  
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.setCapability("silent", true)
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  

IE Command-Line Options

Internet Explorerには、ブラウザーのトラブルシューティングと構成を可能にするいくつかのコマンドラインオプションが含まれています。

次に、サポートされているいくつかのコマンドラインオプションについて説明します。

  • -private : IEをプライベートブラウジングモードで起動するために使用されます。 これはIE 8以降のバージョンで機能します。

  • -k : Internet Explorerをキオスクモードで起動します。 ブラウザは、アドレスバー、ナビゲーションボタン、またはステータスバーを表示しない最大化されたウィンドウで開きます。

  • -extoff : アドオンなしモードでIEを起動します。 このオプションは、ブラウザーのアドオンに関する問題のトラブルシューティングに特に使用されます。 IE 7以降のバージョンで動作します。

注:コマンドライン引数が機能するためには、 forceCreateProcessApi を順番に有効にする必要があります。

import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

public class ieTest {
    public static void main(String[] args) {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.useCreateProcessApiToLaunchIe();
        options.addCommandSwitches("-k");
        InternetExplorerDriver driver = new InternetExplorerDriver(options);
        try {
            driver.get("https://google.com/ncr");
            Capabilities caps = driver.getCapabilities();
            System.out.println(caps);
        } finally {
            driver.quit();
        }
    }
}
  
from selenium import webdriver

options = webdriver.IeOptions()
options.add_argument('-private')
options.force_create_process_api = True
driver = webdriver.Ie(options=options)

driver.get("http://www.google.com")

driver.quit()
  
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

namespace ieTest {
 class Program {
  static void Main(string[] args) {
   InternetExplorerOptions options = new InternetExplorerOptions();
   options.ForceCreateProcessApi = true;
   options.BrowserCommandLineArguments = "-k";
   IWebDriver driver = new InternetExplorerDriver(options);
   driver.Url = "https://google.com/ncr";
  }
 }
}
  
      @options.add_argument('-k')
const ie = require('selenium-webdriver/ie');
let options = new ie.Options();
options.addBrowserCommandSwitches('-k');
options.addBrowserCommandSwitches('-private');
options.forceCreateProcessApi(true);

driver = await env.builder()
          .setIeOptions(options)
          .build();
  
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.useCreateProcessApiToLaunchIe()
    options.addCommandSwitches("-k")
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps);
    } finally {
        driver.quit()
    }
}
  

forceCreateProcessApi

CreateProcess APIを使用してInternet Explorerを強制的に起動します。 デフォルト値はfalseです。

IE 8以降の場合、このオプションでは “TabProcGrowth” レジストリの値を0に設定する必要があります。

import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

public class ieTest {
    public static void main(String[] args) {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.useCreateProcessApiToLaunchIe();
        InternetExplorerDriver driver = new InternetExplorerDriver(options);
        try {
            driver.get("https://google.com/ncr");
            Capabilities caps = driver.getCapabilities();
            System.out.println(caps);
        } finally {
            driver.quit();
        }
    }
}
  
from selenium import webdriver

options = webdriver.IeOptions()
options.force_create_process_api = True
driver = webdriver.Ie(options=options)

driver.get("http://www.google.com")

driver.quit()
  
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

namespace ieTest {
 class Program {
  static void Main(string[] args) {
   InternetExplorerOptions options = new InternetExplorerOptions();
   options.ForceCreateProcessApi = true;
   IWebDriver driver = new InternetExplorerDriver(options);
   driver.Url = "https://google.com/ncr";
  }
 }
}
  
      @options.force_create_process_api = true
const ie = require('selenium-webdriver/ie');
let options = new ie.Options();
options.forceCreateProcessApi(true);

driver = await env.builder()
          .setIeOptions(options)
          .build();
  
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.useCreateProcessApiToLaunchIe()
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}

  

Service

Service settings common to all browsers are described on the Service page.

Log output

Getting driver logs can be helpful for debugging various issues. The Service class lets you direct where the logs will go. Logging output is ignored unless the user directs it somewhere.

File output

To change the logging output to save to a specific file:

Selenium v4.10

                .withLogFile(getLogLocation())

Note: Java also allows setting file output by System Property:
Property key: InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY
Property value: String representing path to log file

    service = webdriver.IeService(log_output=log_path, log_level='INFO')

Console output

To change the logging output to display in the console as STDOUT:

Selenium v4.10

                .withLogOutput(System.out)

Note: Java also allows setting console output by System Property;
Property key: InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY
Property value: DriverService.LOG_STDOUT or DriverService.LOG_STDERR

Selenium v4.11

    service = webdriver.IeService(log_output=subprocess.STDOUT)

Log Level

There are 6 available log levels: FATAL, ERROR, WARN, INFO, DEBUG, and TRACE If logging output is specified, the default level is FATAL

                .withLogLevel(InternetExplorerDriverLogLevel.WARN)

Note: Java also allows setting log level by System Property:
Property key: InternetExplorerDriverService.IE_DRIVER_LOGLEVEL_PROPERTY
Property value: String representation of InternetExplorerDriverLogLevel.DEBUG.toString() enum

    service = webdriver.IeService(log_output=log_path, log_level='WARN')

Selenium v4.10

      service.args << '-log-level=WARN'

Supporting Files Path

                .withExtractPath(getTempDirectory())
**Note**: Java also allows setting log level by System Property:\ Property key: `InternetExplorerDriverService.IE_DRIVER_EXTRACT_PATH_PROPERTY`\ Property value: String representing path to supporting files directory

Selenium v4.11

    service = webdriver.IeService(service_args=["–extract-path="+temp_dir])

Selenium v4.8

      service.args << "–extract-path=#{root_directory}"

3.5 - Safari特有の機能

これらは、Apple Safariブラウザに特有の機能と機能です。

Unlike Chromium and Firefox drivers, the safaridriver is installed with the Operating System. To enable automation on Safari, run the following command from the terminal:

safaridriver --enable

Options

Capabilities common to all browsers are described on the Options page.

Capabilities unique to Safari can be found at Apple’s page About WebDriver for Safari

Starting a Safari session with basic defined options looks like this:

        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)
            var options = new SafariOptions();
            driver = new SafariDriver(options);
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    let driver = new Builder()
      .forBrowser(Browser.SAFARI)
      .setSafariOptions(options)
      .build();
val options = SafariOptions()
val driver = SafariDriver(options)

Mobile

Those looking to automate Safari on iOS should look to the Appium project.

Service

Service settings common to all browsers are described on the Service page.

Logging

Unlike other browsers, Safari doesn’t let you choose where logs are output, or change levels. The one option available is to turn logs off or on. If logs are toggled on, they can be found at:~/Library/Logs/com.apple.WebDriver/.

Selenium v4.10

                .withLogging(true)

Note: Java also allows setting console output by System Property;
Property key: SafariDriverService.SAFARI_DRIVER_LOGGING
Property value: "true" or "false"

    service = webdriver.SafariService(service_args=["--diagnose"])

Selenium v4.8

      service.args << '--diagnose'

Safari Technology Preview

Apple provides a development version of their browser — Safari Technology Preview To use this version in your code:

        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari

4 - 待機

Perhaps the most common challenge for browser automation is ensuring that the web application is in a state to execute a particular Selenium command as desired. The processes often end up in a race condition where sometimes the browser gets into the right state first (things work as intended) and sometimes the Selenium code executes first (things do not work as intended). This is one of the primary causes of flaky tests.

All navigation commands wait for a specific readyState value based on the page load strategy (the default value to wait for is "complete") before the driver returns control to the code. The readyState only concerns itself with loading assets defined in the HTML, but loaded JavaScript assets often result in changes to the site, and elements that need to be interacted with may not yet be on the page when the code is ready to execute the next Selenium command.

Similarly, in a lot of single page applications, elements get dynamically added to a page or change visibility based on a click. An element must be both present and displayed on the page in order for Selenium to interact with it.

Take this page for example: https://www.selenium.dev/selenium/web/dynamic.html When the “Add a box!” button is clicked, a “div” element that does not exist is created. When the “Reveal a new input” button is clicked, a hidden text field element is displayed. In both cases the transition takes a couple seconds. If the Selenium code is to click one of these buttons and interact with the resulting element, it will do so before that element is ready and fail.

The first solution many people turn to is adding a sleep statement to pause the code execution for a set period of time. Because the code can’t know exactly how long it needs to wait, this can fail when it doesn’t sleep long enough. Alternately, if the value is set too high and a sleep statement is added in every place it is needed, the duration of the session can become prohibitive.

Selenium provides two different mechanisms for synchronization that are better.

Implicit waits

Selenium has a built-in way to automatically wait for elements called an implicit wait. An implicit wait value can be set either with the timeouts capability in the browser options, or with a driver method (as shown below).

This is a global setting that applies to every element location call for the entire session. The default value is 0, which means that if the element is not found, it will immediately return an error. If an implicit wait is set, the driver will wait for the duration of the provided value before returning the error. Note that as soon as the element is located, the driver will return the element reference and the code will continue executing, so a larger implicit wait value won’t necessarily increase the duration of the session.

Warning: Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example, setting an implicit wait of 10 seconds and an explicit wait of 15 seconds could cause a timeout to occur after 20 seconds.

Solving our example with an implicit wait looks like this:

    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
    driver.implicitly_wait(2)
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
    driver.manage.timeouts.implicit_wait = 2
        await driver.manage().setTimeouts({ implicit: 2000 });

Explicit waits

Explicit waits are loops added to the code that poll the application for a specific condition to evaluate as true before it exits the loop and continues to the next command in the code. If the condition is not met before a designated timeout value, the code will give a timeout error. Since there are many ways for the application not to be in the desired state, explicit waits are a great choice to specify the exact condition to wait for in each place it is needed. Another nice feature is that, by default, the Selenium Wait class automatically waits for the designated element to exist.

This example shows the condition being waited for as a lambda. Java also supports Expected Conditions

    Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    wait.until(d -> revealed.isDisplayed());

This example shows the condition being waited for as a lambda. Python also supports Expected Conditions

    wait = WebDriverWait(driver, timeout=2)
    wait.until(lambda d : revealed.is_displayed())
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
            wait.Until(d => revealed.Displayed);
    wait = Selenium::WebDriver::Wait.new
    wait.until { revealed.displayed? }

JavaScript also supports Expected Conditions

        await driver.wait(until.elementIsVisible(revealed), 2000);

Customization

The Wait class can be instantiated with various parameters that will change how the conditions are evaluated.

This can include:

  • Changing how often the code is evaluated (polling interval)
  • Specifying which exceptions should be handled automatically
  • Changing the total timeout length
  • Customizing the timeout message

For instance, if the element not interactable error is retried by default, then we can add an action on a method inside the code getting executed (we just need to make sure that the code returns true when it is successful):

The easiest way to customize Waits in Java is to use the FluentWait class:

    Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });
    errors = [NoSuchElementException, ElementNotInteractableException]
    wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
    wait.until(lambda d : revealed.send_keys("Displayed") or True)
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2))
            {
                PollingInterval = TimeSpan.FromMilliseconds(300),
            };
            wait.IgnoreExceptionTypes(typeof(ElementNotInteractableException));

            wait.Until(d => {
                revealed.SendKeys("Displayed");
                return true;
            });
    errors = [Selenium::WebDriver::Error::NoSuchElementError,
              Selenium::WebDriver::Error::ElementNotInteractableError]
    wait = Selenium::WebDriver::Wait.new(timeout: 2,
                                         interval: 0.3,
                                         ignore: errors)

    wait.until { revealed.send_keys('Displayed') || true }

5 - Web要素

DOM内の要素オブジェクトの識別と操作

ほとんどの人のSeleniumコードの大部分は、Web要素の操作に関連しています。

5.1 - File Upload

Because Selenium cannot interact with the file upload dialog, it provides a way to upload files without opening the dialog. If the element is an input element with type file, you can use the send keys method to send the full path to the file that will be uploaded.

    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click
    await driver.get('https://the-internet.herokuapp.com/upload');
    // Upload snapshot

Move Code

```java import org.openqa.selenium.By import org.openqa.selenium.chrome.ChromeDriver fun main() { val driver = ChromeDriver() driver.get("https://the-internet.herokuapp.com/upload") driver.findElement(By.id("file-upload")).sendKeys("selenium-snapshot.jpg") driver.findElement(By.id("file-submit")).submit() if(driver.pageSource.contains("File Uploaded!")) { println("file uploaded") } else{ println("file not uploaded") } } ```

5.2 - 要素を探す

DOM内の1つ以上の特定の要素を識別する方法

ロケーターは、ページ上の要素を識別する方法です。 これは、検索要素 メソッドに渡される引数です。

検出方法とは別にロケーターを宣言するタイミングと理由など、 ロケーターに関するヒントについては、 推奨されるテストプラクティス を確認してください。

要素選択の方法

WebDriverには標準のロケータが8種類あります。

ロケータ詳細
class nameclass名に値を含む要素を探す (複合クラス名は使えない)
css selectorCSSセレクタが一致する要素を探す
idid属性が一致する要素を探す
namename属性が一致する要素を探す
link texta要素のテキストが一致する要素を探す
partial link texta要素のテキストが部分一致する要素を探す
tag nameタグ名が一致する要素を探す
xpathXPathと一致する要素を探す

Creating Locators

To work on a web element using Selenium, we need to first locate it on the web page. Selenium provides us above mentioned ways, using which we can locate element on the page. To understand and create locator we will use the following HTML snippet.

<html>
<body>
<style>
.information {
  background-color: white;
  color: black;
  padding: 10px;
}
</style>
<h2>Contact Selenium</h2>

<form action="/action_page.php">
  <input type="radio" name="gender" value="m" />Male &nbsp;
  <input type="radio" name="gender" value="f" />Female <br>
  <br>
  <label for="fname">First name:</label><br>
  <input class="information" type="text" id="fname" name="fname" value="Jane"><br><br>
  <label for="lname">Last name:</label><br>
  <input class="information" type="text" id="lname" name="lname" value="Doe"><br><br>
  <label for="newsletter">Newsletter:</label>
  <input type="checkbox" name="newsletter" value="1" /><br><br>
  <input type="submit" value="Submit">
</form> 

<p>To know more about Selenium, visit the official page 
<a href ="www.selenium.dev">Selenium Official Page</a> 
</p>

</body>
</html>

class name

The HTML page web element can have attribute class. We can see an example in the above shown HTML snippet. We can identify these elements using the class name locator available in Selenium.

    WebDriver driver = new ChromeDriver();
	driver.findElement(By.className("information"));
  
    driver = webdriver.Chrome()
	driver.find_element(By.CLASS_NAME, "information")
  
    var driver = new ChromeDriver();
	driver.FindElement(By.ClassName("information"));
  
    driver.find_element(class: 'information')
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.className('information'));
  
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.className("information"))
  

css selector

CSS is the language used to style HTML pages. We can use css selector locator strategy to identify the element on the page. If the element has an id, we create the locator as css = #id. Otherwise the format we follow is css =[attribute=value] . Let us see an example from above HTML snippet. We will create locator for First Name textbox, using css.

    WebDriver driver = new ChromeDriver();
	driver.findElement(By.cssSelector("#fname"));
  
    driver = webdriver.Chrome()
	driver.find_element(By.CSS_SELECTOR, "#fname")
  
    var driver = new ChromeDriver();
	driver.FindElement(By.CssSelector("#fname"));
  
    driver.find_element(css: '#fname')
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.css('#fname'));
  
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.css("#fname"))
  

id

We can use the ID attribute available with element in a web page to locate it. Generally the ID property should be unique for a element on the web page. We will identify the Last Name field using it.

    WebDriver driver = new ChromeDriver();
	driver.findElement(By.id("lname"));
  
    driver = webdriver.Chrome()
	driver.find_element(By.ID, "lname")
  
    var driver = new ChromeDriver();
	driver.FindElement(By.Id("lname"));
  
    driver.find_element(id: 'lname')
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.id('lname'));
  
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.id("lname"))
  

name

We can use the NAME attribute available with element in a web page to locate it. Generally the NAME property should be unique for a element on the web page. We will identify the Newsletter checkbox using it.

    WebDriver driver = new ChromeDriver();
	driver.findElement(By.name("newsletter"));
  
    driver = webdriver.Chrome()
	driver.find_element(By.NAME, "newsletter")
  
    var driver = new ChromeDriver();
	driver.FindElement(By.Name("newsletter"));
  
    driver.find_element(name: 'newsletter')
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.name('newsletter'));
  
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.name("newsletter"))
  

If the element we want to locate is a link, we can use the link text locator to identify it on the web page. The link text is the text displayed of the link. In the HTML snippet shared, we have a link available, lets see how will we locate it.

    WebDriver driver = new ChromeDriver();
	driver.findElement(By.linkText("Selenium Official Page"));
  
    driver = webdriver.Chrome()
	driver.find_element(By.LINK_TEXT, "Selenium Official Page")
  
    var driver = new ChromeDriver();
	driver.FindElement(By.LinkText("Selenium Official Page"));
  
    driver.find_element(link_text: 'Selenium Official Page')
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.linkText('Selenium Official Page'));
  
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.linkText("Selenium Official Page"))
  

If the element we want to locate is a link, we can use the partial link text locator to identify it on the web page. The link text is the text displayed of the link. We can pass partial text as value. In the HTML snippet shared, we have a link available, lets see how will we locate it.

    WebDriver driver = new ChromeDriver();
	driver.findElement(By.partialLinkText("Official Page"));
  
    driver = webdriver.Chrome()
	driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")
  
    var driver = new ChromeDriver();
	driver.FindElement(By.PartialLinkText("Official Page"));
  
    driver.find_element(partial_link_text: 'Official Page')
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.partialLinkText('Official Page'));
  
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.partialLinkText("Official Page"))
  

tag name

We can use the HTML TAG itself as a locator to identify the web element on the page. From the above HTML snippet shared, lets identify the link, using its html tag “a”.

    WebDriver driver = new ChromeDriver();
	driver.findElement(By.tagName("a"));
  
    driver = webdriver.Chrome()
	driver.find_element(By.TAG_NAME, "a")
  
    var driver = new ChromeDriver();
	driver.FindElement(By.TagName("a"));
  
    driver.find_element(tag_name: 'a')
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.tagName('a'));
  
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.tagName("a"))
  

xpath

A HTML document can be considered as a XML document, and then we can use xpath which will be the path traversed to reach the element of interest to locate the element. The XPath could be absolute xpath, which is created from the root of the document. Example - /html/form/input[1]. This will return the male radio button. Or the xpath could be relative. Example- //input[@name=‘fname’]. This will return the first name text box. Let us create locator for female radio button using xpath.

    WebDriver driver = new ChromeDriver();
	driver.findElement(By.xpath("//input[@value='f']"));
  
    driver = webdriver.Chrome()
	driver.find_element(By.XPATH, "//input[@value='f']")
  
    var driver = new ChromeDriver();
	driver.FindElement(By.Xpath("//input[@value='f']"));
  
    driver.find_element(xpath: "//input[@value='f']")
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.xpath('//input[@value='f']'));
  
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.xpath('//input[@value='f']'))
  

Utilizing Locators

The FindElement makes using locators a breeze! For most languages, all you need to do is utilize webdriver.common.by.By, however in others it’s as simple as setting a parameter in the FindElement function

By

Move Code

    import org.openqa.selenium.By;
    WebDriver driver = new ChromeDriver();
	driver.findElement(By.className("information"));
  
    from selenium.webdriver.common.by import By
    driver = webdriver.Chrome()
	driver.find_element(By.CLASS_NAME, "information")
  
    var driver = new ChromeDriver();
	driver.FindElement(By.ClassName("information"));
  
    driver.find_element(class: 'information')
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.className('information'));
  
    import org.openqa.selenium.By
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.className("information"))
  

ByChained

The ByChained class enables you to chain two By locators together. For example, instead of having to locate a parent element, and then a child element of that parent, you can instead combine those two FindElement functions into one.

        By example = new ByChained(By.id("login-form"), By.id("username-field"));
            WebElement username_input = driver.findElement(example);

ByAll

The ByAll class enables you to utilize two By locators at once, finding elements that mach either of your By locators. For example, instead of having to utilize two FindElement() functions to find the username and password input fields seperately, you can instead find them together in one clean FindElements()

        By example = new ByAll(By.id("password-field"), By.id("username-field"));
            List<WebElement> login_inputs = driver.findElements(example);

相対ロケーター

Selenium 4 introduces Relative Locators (previously called as Friendly Locators). These locators are helpful when it is not easy to construct a locator for the desired element, but easy to describe spatially where the element is in relation to an element that does have an easily constructed locator.

How it works

Selenium uses the JavaScript function getBoundingClientRect() to determine the size and position of elements on the page, and can use this information to locate neighboring elements.
find the relative elements.

Relative locator methods can take as the argument for the point of origin, either a previously located element reference, or another locator. In these examples we’ll be using locators only, but you could swap the locator in the final method with an element object and it will work the same.

Let us consider the below example for understanding the relative locators.

Relative Locators

Available relative locators

Above

If the email text field element is not easily identifiable for some reason, but the password text field element is, we can locate the text field element using the fact that it is an “input” element “above” the password element.

By emailLocator = RelativeLocator.with(By.tagName("input")).above(By.id("password"));
email_locator = locate_with(By.TAG_NAME, "input").above({By.ID: "password"})
var emailLocator = RelativeBy.WithLocator(By.TagName("input")).Above(By.Id("password"));
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
let emailLocator = locateWith(By.tagName('input')).above(By.id('password'));
val emailLocator = RelativeLocator.with(By.tagName("input")).above(By.id("password"))

Below

If the password text field element is not easily identifiable for some reason, but the email text field element is, we can locate the text field element using the fact that it is an “input” element “below” the email element.

By passwordLocator = RelativeLocator.with(By.tagName("input")).below(By.id("email"));
password_locator = locate_with(By.TAG_NAME, "input").below({By.ID: "email"})
var passwordLocator = RelativeBy.WithLocator(By.TagName("input")).Below(By.Id("email"));
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
let passwordLocator = locateWith(By.tagName('input')).below(By.id('email'));
val passwordLocator = RelativeLocator.with(By.tagName("input")).below(By.id("email"))

Left of

If the cancel button is not easily identifiable for some reason, but the submit button element is, we can locate the cancel button element using the fact that it is a “button” element to the “left of” the submit element.

By cancelLocator = RelativeLocator.with(By.tagName("button")).toLeftOf(By.id("submit"));
cancel_locator = locate_with(By.TAG_NAME, "button").to_left_of({By.ID: "submit"})
var cancelLocator = RelativeBy.WithLocator(By.tagName("button")).LeftOf(By.Id("submit"));
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
let cancelLocator = locateWith(By.tagName('button')).toLeftOf(By.id('submit'));
val cancelLocator = RelativeLocator.with(By.tagName("button")).toLeftOf(By.id("submit"))

Right of

If the submit button is not easily identifiable for some reason, but the cancel button element is, we can locate the submit button element using the fact that it is a “button” element “to the right of” the cancel element.

By submitLocator = RelativeLocator.with(By.tagName("button")).toRightOf(By.id("cancel"));
submit_locator = locate_with(By.TAG_NAME, "button").to_right_of({By.ID: "cancel"})
var submitLocator = RelativeBy.WithLocator(By.tagName("button")).RightOf(By.Id("cancel"));
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
let submitLocator = locateWith(By.tagName('button')).toRightOf(By.id('cancel'));
val submitLocator = RelativeLocator.with(By.tagName("button")).toRightOf(By.id("cancel"))

Near

If the relative positioning is not obvious, or it varies based on window size, you can use the near method to identify an element that is at most 50px away from the provided locator. One great use case for this is to work with a form element that doesn’t have an easily constructed locator, but its associated input label element does.

By emailLocator = RelativeLocator.with(By.tagName("input")).near(By.id("lbl-email"));
email_locator = locate_with(By.TAG_NAME, "input").near({By.ID: "lbl-email"})
var emailLocator = RelativeBy.WithLocator(By.tagName("input")).Near(By.Id("lbl-email"));
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
let emailLocator = locateWith(By.tagName('input')).near(By.id('lbl-email'));
val emailLocator = RelativeLocator.with(By.tagName("input")).near(By.id("lbl-email"));

Chaining relative locators

You can also chain locators if needed. Sometimes the element is most easily identified as being both above/below one element and right/left of another.

By submitLocator = RelativeLocator.with(By.tagName("button")).below(By.id("email")).toRightOf(By.id("cancel"));
submit_locator = locate_with(By.TAG_NAME, "button").below({By.ID: "email"}).to_right_of({By.ID: "cancel"})
var submitLocator = RelativeBy.WithLocator(By.tagName("button")).Below(By.Id("email")).RightOf(By.Id("cancel"));
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
let submitLocator = locateWith(By.tagName('button')).below(By.id('email')).toRightOf(By.id('cancel'));
val submitLocator = RelativeLocator.with(By.tagName("button")).below(By.id("email")).toRightOf(By.id("cancel"))

5.3 - Interacting with web elements

A high-level instruction set for manipulating form controls.

There are only 5 basic commands that can be executed on an element:

  • click (applies to any element)
  • send keys (only applies to text fields and content editable elements)
  • clear (only applies to text fields and content editable elements)
  • submit (only applies to form elements)
  • select (see Select List Elements)

Additional validations

These methods are designed to closely emulate a user’s experience, so, unlike the Actions API, it attempts to perform two things before attempting the specified action.

  1. If it determines the element is outside the viewport, it scrolls the element into view, specifically it will align the bottom of the element with the bottom of the viewport.
  2. It ensures the element is interactable before taking the action. This could mean that the scrolling was unsuccessful, or that the element is not otherwise displayed. Determining if an element is displayed on a page was too difficult to define directly in the webdriver specification, so Selenium sends an execute command with a JavaScript atom that checks for things that would keep the element from being displayed. If it determines an element is not in the viewport, not displayed, not keyboard-interactable, or not pointer-interactable, it returns an element not interactable error.

Click

The element click command is executed on the center of the element. If the center of the element is obscured for some reason, Selenium will return an element click intercepted error.

        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

	    // Click on the element 
        WebElement checkInput=driver.findElement(By.name("checkbox_input"));
        checkInput.click();
    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()
            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
    driver.find_element(name: 'color_input').click
    await submitButton.click();
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    // Click the element
    driver.findElement(By.name("color_input")).click();
  
  

Send keys

The element send keys command types the provided keys into an editable element. Typically, this means an element is an input element of a form with a text type or an element with a content-editable attribute. If it is not editable, an invalid element state error is returned.

Here is the list of possible keystrokes that WebDriver Supports.

        // Clear field to empty it from any previous data
        WebElement emailInput=driver.findElement(By.name("email_input"));
        emailInput.clear();
	    //Enter Text
        String email="admin@localhost.dev";
	    emailInput.sendKeys(email);
    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text
            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
      let inputField = await driver.findElement(By.name('no_type'));
  
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

	//Clear field to empty it from any previous data
	driver.findElement(By.name("email_input")).clear()
	
    // Enter text 
    driver.findElement(By.name("email_input")).sendKeys("admin@localhost.dev")
  
  

Clear

The element clear command resets the content of an element. This requires an element to be editable, and resettable. Typically, this means an element is an input element of a form with a text type or an element with acontent-editable attribute. If these conditions are not met, an invalid element state error is returned.

        //Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
    email_input.clear()
            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
    driver.find_element(name: 'email_input').clear
      await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

	//Clear field to empty it from any previous data
	driver.findElement(By.name("email_input")).clear()
	
  
  

Submit

In Selenium 4 this is no longer implemented with a separate endpoint and functions by executing a script. As such, it is recommended not to use this method and to click the applicable form submission button instead.

5.4 - Web要素の検索

提供されたロケーターの値に基づいて要素を検索します。

Seleniumを使用する最も基本的な側面の1つは、操作する要素の参照を取得することです。 Seleniumは、要素を一意に識別するための多数の組み込みロケーター戦略を提供します。 非常に高度なシナリオでロケーターを使用する方法はたくさんあります。 このドキュメントの目的のために、このHTMLスニペットについて考えてみましょう。

<ol id="vegetables">
 <li class="potatoes"> <li class="onions"> <li class="tomatoes"><span>Tomato is a Vegetable</span></ol>
<ul id="fruits">
  <li class="bananas">  <li class="apples">  <li class="tomatoes"><span>Tomato is a Fruit</span></ul>

最初に一致する要素

多くのロケーターは、ページ上の複数の要素と一致します。 単数の find elementメソッドは、指定されたコンテキスト内で最初に見つかった要素への参照を返します。

DOM全体の評価

ドライバーインスタンスで要素の検索メソッドが呼び出されると、提供されたロケーターと一致するDOMの最初の要素への参照が返されます。 この値は保存して、将来の要素アクションに使用できます。 上記のHTMLの例では、クラス名が “tomatoes” の要素が2つあるため、このメソッドは “vegetables” リストの要素を返します。

WebElement vegetable = driver.findElement(By.className("tomatoes"));
  
vegetable = driver.find_element(By.CLASS_NAME, "tomatoes")
  
var vegetable = driver.FindElement(By.ClassName("tomatoes"));
  
      driver.find_element(class: 'tomatoes')
const vegetable = await driver.findElement(By.className('tomatoes'));
  
val vegetable: WebElement = driver.findElement(By.className("tomatoes"))
  

DOMのサブセットの評価

DOM全体で一意のロケーターを見つけるのではなく、検索を別の検索された要素のスコープに絞り込むと便利なことがよくあります。 上記の例では、クラス名が “トマト” の2つの要素があり、2番目の要素の参照を取得するのは少し困難です。

1つの解決策は、目的の要素の祖先であり、不要な要素の祖先ではない一意の属性を持つ要素を見つけて、そのオブジェクトでfind要素を呼び出すことです。

WebElement fruits = driver.findElement(By.id("fruits"));
WebElement fruit = fruits.findElement(By.className("tomatoes"));
  
fruits = driver.find_element(By.ID, "fruits")
fruit = fruits.find_element(By.CLASS_NAME,"tomatoes")
  
IWebElement fruits = driver.FindElement(By.Id("fruits"));
IWebElement fruit = fruits.FindElement(By.ClassName("tomatoes"));
  
      fruits = driver.find_element(id: 'fruits')
      fruit = fruits.find_element(class: 'tomatoes')
const fruits = await driver.findElement(By.id('fruits'));
const fruit = fruits.findElement(By.className('tomatoes'));
  
val fruits = driver.findElement(By.id("fruits"))
val fruit = fruits.findElement(By.className("tomatoes"))
  

Java and C#
WebDriverWebElement 、および ShadowRoot クラスはすべて、 ロールベースのインターフェイス と見なされる SearchContext インターフェイスを実装します。 ロールベースのインターフェイスを使用すると、特定のドライバーの実装が特定の機能をサポートしているかどうかを判断できます。 これらのインターフェースは明確に定義されており、責任の役割を1つだけ持つように努めています。

Evaluating the Shadow DOM

The Shadow DOM is an encapsulated DOM tree hidden inside an element. With the release of v96 in Chromium Browsers, Selenium can now allow you to access this tree with easy-to-use shadow root methods. NOTE: These methods require Selenium 4.0 or greater.

Move Code

WebElement shadowHost = driver.findElement(By.cssSelector("#shadow_host"));
SearchContext shadowRoot = shadowHost.getShadowRoot();
WebElement shadowContent = shadowRoot.findElement(By.cssSelector("#shadow_content"));
shadow_host = driver.find_element(By.CSS_SELECTOR, '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(By.CSS_SELECTOR, '#shadow_content')
var shadowHost = _driver.FindElement(By.CssSelector("#shadow_host"));
var shadowRoot = shadowHost.GetShadowRoot();
var shadowContent = shadowRoot.FindElement(By.CssSelector("#shadow_content"));
shadow_host = @driver.find_element(css: '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(css: '#shadow_content')

最適化されたロケーター

ネストされたルックアップは、ブラウザに2つの別々のコマンドを発行する必要があるため、最も効果的なロケーション戦略ではない可能性があります。

パフォーマンスをわずかに向上させるために、CSSまたはXPathのいずれかを使用して、単一のコマンドでこの要素を見つけることができます。 推奨されるテストプラクティスの章で、ロケーター戦略の提案を参照してください。

この例では、CSSセレクターを使用します。

WebElement fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"));
  
fruit = driver.find_element(By.CSS_SELECTOR,"#fruits .tomatoes")
  
var fruit = driver.FindElement(By.CssSelector("#fruits .tomatoes"));
  
      fruit = driver.find_element(css: '#fruits .tomatoes')
const fruit = await driver.findElement(By.css('#fruits .tomatoes'));
  
val fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"))
  

一致するすべての要素

最初の要素だけでなく、ロケーターに一致するすべての要素への参照を取得する必要があるユースケースがいくつかあります。 複数の要素の検索メソッドは、要素参照のコレクションを返します。 一致するものがない場合は、空のリストが返されます。 この場合、すべてのfruitsとvegetableのリストアイテムへの参照がコレクションに返されます。

List<WebElement> plants = driver.findElements(By.tagName("li"));
  
plants = driver.find_elements(By.TAG_NAME, "li")
  
IReadOnlyList<IWebElement> plants = driver.FindElements(By.TagName("li"));
  
      plants = driver.find_elements(tag_name: 'li')
const plants = await driver.findElements(By.tagName('li'));
  
val plants: List<WebElement> = driver.findElements(By.tagName("li"))
  

要素の取得

多くの場合、要素のコレクションを取得しますが、特定の要素を操作したいので、コレクションを繰り返し処理して、 必要な要素を特定する必要があります。

List<WebElement> elements = driver.findElements(By.tagName("li"));

for (WebElement element : elements) {
    System.out.println("Paragraph text:" + element.getText());
}
  
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Firefox()

    # Navigate to Url
driver.get("https://www.example.com")

    # Get all the elements available with tag name 'p'
elements = driver.find_elements(By.TAG_NAME, 'p')

for e in elements:
    print(e.text)
  
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System.Collections.Generic;

namespace FindElementsExample {
 class FindElementsExample {
  public static void Main(string[] args) {
   IWebDriver driver = new FirefoxDriver();
   try {
    // Navigate to Url
    driver.Navigate().GoToUrl("https://example.com");

    // Get all the elements available with tag name 'p'
    IList < IWebElement > elements = driver.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }

   } finally {
    driver.Quit();
   }
  }
 }
}
  
      elements = driver.find_elements(:tag_name,'p')
         elements.each { |e| puts e.text }
const {Builder, By} = require('selenium-webdriver');
(async function example() {
    let driver = await new Builder().forBrowser('firefox').build();
    try {
        // Navigate to Url
        await driver.get('https://www.example.com');

        // Get all the elements available with tag 'p'
        let elements = await driver.findElements(By.css('p'));
        for(let e of elements) {
            console.log(await e.getText());
        }
    }
    finally {
        await driver.quit();
    }
})();
  
import org.openqa.selenium.By
import org.openqa.selenium.firefox.FirefoxDriver

fun main() {
    val driver = FirefoxDriver()
    try {
        driver.get("https://example.com")
        // Get all the elements available with tag name 'p'
        val elements = driver.findElements(By.tagName("p"))
        for (element in elements) {
            println("Paragraph text:" + element.text)
        }
    } finally {
        driver.quit()
    }
}
  

要素から要素を検索

これは、親要素のコンテキスト内で一致する子のWebElementのリストを見つけるために利用されます。 これを実現するために、親WebElementは’findElements’と連鎖して子要素にアクセスします。

  import org.openqa.selenium.By;
  import org.openqa.selenium.WebDriver;
  import org.openqa.selenium.WebElement;
  import org.openqa.selenium.chrome.ChromeDriver;
  import java.util.List;

  public class findElementsFromElement {
      public static void main(String[] args) {
          WebDriver driver = new ChromeDriver();
          try {
              driver.get("https://example.com");

              // Get element with tag name 'div'
              WebElement element = driver.findElement(By.tagName("div"));

              // Get all the elements available with tag name 'p'
              List<WebElement> elements = element.findElements(By.tagName("p"));
              for (WebElement e : elements) {
                  System.out.println(e.getText());
              }
          } finally {
              driver.quit();
          }
      }
  }
  
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://www.example.com")
##get elements from parent element using TAG_NAME

    # Get element with tag name 'div'
element = driver.find_element(By.TAG_NAME, 'div')

    # Get all the elements available with tag name 'p'
elements = element.find_elements(By.TAG_NAME, 'p')
for e in elements:
    print(e.text)

##get elements from parent element using XPATH
##NOTE: in order to utilize XPATH from current element, you must add "." to beginning of path

    # Get first element of tag 'ul'
element = driver.find_element(By.XPATH, '//ul')

    # get children of tag 'ul' with tag 'li'
elements  = driver.find_elements(By.XPATH, './/li')
for e in elements:
    print(e.text)
  
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace FindElementsFromElement {
 class FindElementsFromElement {
  public static void Main(string[] args) {
   IWebDriver driver = new ChromeDriver();
   try {
    driver.Navigate().GoToUrl("https://example.com");

    // Get element with tag name 'div'
    IWebElement element = driver.FindElement(By.TagName("div"));

    // Get all the elements available with tag name 'p'
    IList < IWebElement > elements = element.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }
   } finally {
    driver.Quit();
   }
  }
 }
}
  
      element = driver.find_element(:tag_name,'div')
         elements = element.find_elements(:tag_name,'p')
         elements.each { |e| puts e.text }
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = new Builder()
          .forBrowser('chrome')
          .build();

      await driver.get('https://www.example.com');

      // Get element with tag name 'div'
      let element = driver.findElement(By.css("div"));

      // Get all the elements available with tag name 'p'
      let elements = await element.findElements(By.css("p"));
      for(let e of elements) {
          console.log(await e.getText());
      }
  })();
  
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://example.com")

          // Get element with tag name 'div'
          val element = driver.findElement(By.tagName("div"))

          // Get all the elements available with tag name 'p'
          val elements = element.findElements(By.tagName("p"))
          for (e in elements) {
              println(e.text)
          }
      } finally {
          driver.quit()
      }
  }
  

アクティブな要素を取得する

これは、現在のブラウジングコンテキストでフォーカスを持っているDOM要素を追跡(または)検索するために使用されます。

  import org.openqa.selenium.*;
  import org.openqa.selenium.chrome.ChromeDriver;

  public class activeElementTest {
    public static void main(String[] args) {
      WebDriver driver = new ChromeDriver();
      try {
        driver.get("http://www.google.com");
        driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement");

        // Get attribute of current active element
        String attr = driver.switchTo().activeElement().getAttribute("title");
        System.out.println(attr);
      } finally {
        driver.quit();
      }
    }
  }
  
  from selenium import webdriver
  from selenium.webdriver.common.by import By

  driver = webdriver.Chrome()
  driver.get("https://www.google.com")
  driver.find_element(By.CSS_SELECTOR, '[name="q"]').send_keys("webElement")

    # Get attribute of current active element
  attr = driver.switch_to.active_element.get_attribute("title")
  print(attr)
  
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;

    namespace ActiveElement {
     class ActiveElement {
      public static void Main(string[] args) {
       IWebDriver driver = new ChromeDriver();
       try {
        // Navigate to Url
        driver.Navigate().GoToUrl("https://www.google.com");
        driver.FindElement(By.CssSelector("[name='q']")).SendKeys("webElement");

        // Get attribute of current active element
        string attr = driver.SwitchTo().ActiveElement().GetAttribute("title");
        System.Console.WriteLine(attr);
       } finally {
        driver.Quit();
       }
      }
     }
    }
  
      driver.find_element(css: '[name="q"]').send_keys('webElement')
        attr = driver.switch_to.active_element.attribute('title')
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = await new Builder().forBrowser('chrome').build();
      await driver.get('https://www.google.com');
      await  driver.findElement(By.css('[name="q"]')).sendKeys("webElement");

      // Get attribute of current active element
      let attr = await driver.switchTo().activeElement().getAttribute("title");
      console.log(`${attr}`)
  })();
  
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://www.google.com")
          driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement")

          // Get attribute of current active element
          val attr = driver.switchTo().activeElement().getAttribute("title")
          print(attr)
      } finally {
          driver.quit()
      }
  }
  

5.5 - Web要素に関する情報

要素について学ぶことができること。

特定の要素についてクエリできる詳細情報がいくつかあります。

表示されているかどうか

This method is used to check if the connected Element is displayed on a webpage. Returns a Boolean value, True if the connected element is displayed in the current browsing context else returns false.

This functionality is mentioned in, but not defined by the w3c specification due to the impossibility of covering all potential conditions. As such, Selenium cannot expect drivers to implement this functionality directly, and now relies on executing a large JavaScript function directly. This function makes many approximations about an element’s nature and relationship in the tree to return a value.

         driver.get("https://www.selenium.dev/selenium/web/inputs.html");

    	// isDisplayed        
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertEquals(isEmailVisible,true);
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);
    displayed_value = driver.find_element(name: 'email_input').displayed?
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
//navigates to url
 driver.get("https://www.selenium.dev/selenium/web/inputs.html")

 //returns true if element is displayed else returns false 
 val flag = driver.findElement(By.name("email_input")).isDisplayed()

要素が有効か

このメソッドは、接続された要素がWebページで有効または無効になっているかどうかを確認するために使います。 ブール値を返し、現在のブラウジングコンテキストで接続されている要素が 有効(enabled) になっている場合は True 、そうでない場合は false を返します。

        //isEnabled
       //returns true if element is enabled else returns false
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertEquals(isEnabledButton,true);
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
            //isEnabled
            //returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);
    enabled_value = driver.find_element(name: 'email_input').enabled?
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
 //navigates to url
 driver.get("https://www.selenium.dev/selenium/web/inputs.html")

 //returns true if element is enabled else returns false 
 val attr = driver.findElement(By.name("button_input")).isEnabled()
 

要素が選択されているかどうか

このメソッドは、参照された要素が選択されているかどうかを判断します。 このメソッドは、チェックボックス、ラジオボタン、入力要素、およびオプション要素で広く使われています。

ブール値を返し、現在のブラウジングコンテキストで参照された要素が 選択されている 場合は True 、そうでない場合は false を返します。

        //isSelected
        //returns true if element is checked else returns false
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertEquals(isSelectedCheck,true); 
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
            //isSelected
            //returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);
    selected_value = driver.find_element(name: 'email_input').selected?
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
//navigates to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//returns true if element is checked else returns false
val attr =  driver.findElement(By.name("checkbox_input")).isSelected()

要素のタグ名を取得

これは、現在のブラウジングコンテキストにフォーカスがある参照された要素の TagName を取得するために使います。

        //TagName
        //returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals(tagNameInp,"input"); 
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
            //TagName
            //returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");
    tag_name = driver.find_element(name: 'email_input').tag_name
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
//navigates to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//returns TagName of the element
val attr =  driver.findElement(By.name("email_input")).getTagName()

要素矩形を取得

参照される要素の寸法と座標を取得するために使います。

取得データのbodyには、次の詳細が含まれます。

  • 要素の左上隅からのx軸の位置
  • 要素の左上隅からのy軸の位置
  • 要素の高さ
  • 要素の幅
        //GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res =  driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(res.getX(),10);
    rect = driver.find_element(By.NAME, "range_input").rect
            //Get Location and Size
            //Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            //Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);
    size = driver.find_element(name: 'email_input').size
    let object = await driver.findElement(By.name('range_input')).getRect();
// Navigate to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

// Returns height, width, x and y coordinates referenced element
val res = driver.findElement(By.name("range_input")).rect

// Rectangle class provides getX,getY, getWidth, getHeight methods
println(res.getX())
  

要素のCSSの値を取得

現在のブラウジングコンテキスト内の要素の指定された計算したスタイル属性の値を取得します。

     // Retrieves the computed style property 'font-size' of field
     String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
     assertEquals(cssValue, "13.3333px");
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
// Navigate to Url
driver.get("https://www.selenium.dev/selenium/web/colorPage.html")

// Retrieves the computed style property 'color' of linktext
val cssValue = driver.findElement(By.id("namedColor")).getCssValue("background-color")

要素テキストを取得

指定された要素のレンダリングされたテキストを取得します。

        //GetText
       // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");
    text = driver.find_element(By.TAG_NAME, "h1").text
            //GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");
    text = driver.find_element(xpath: '//h1').text
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
// Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/linked_image.html")

// retrieves the text of the element
val text = driver.findElement(By.id("justanotherlink")).getText()

Fetching Attributes or Properties

Fetches the run time value associated with a DOM attribute. It returns the data associated with the DOM attribute or property of the element.

        //FetchAttributes
      //identify the email text box
      WebElement emailTxt = driver.findElement(By.name(("email_input")));
     //fetch the value property associated with the textbox
      String valueInfo = emailTxt.getAttribute("value");
      assertEquals(valueInfo,"admin@localhost");
    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
            //FetchAttributes
            //identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            //fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
// Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//fetch the value property associated with the textbox
val attr = driver.findElement(By.name("email_input")).getAttribute("value")

6 - ブラウザのインタラクション

ブラウザーの情報

タイトルの取得

ブラウザーから現在のページタイトルを読むことができます。

      String title = driver.getTitle();
title = driver.title
            String title = driver.Title;
    current_title = driver.title
    let title = await driver.getTitle();
driver.title

現在のURLを取得

ブラウザーのアドレスバーから現在のURLを読むには、次を使用します。

      String url = driver.getCurrentUrl();
url = driver.current_url
            String url = driver.Url;
    current_url = driver.current_url
    let currentUrl = await driver.getCurrentUrl();
driver.currentUrl

6.1 - ブラウザー ナビゲーション

ナビゲート

ブラウザーを起動した後に最初に行うことは、Webサイトを開くことです。これは1行で実現できます。

        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
driver.get("https://www.selenium.dev/selenium/web/index.html")
            //Convenient
            driver.Url = "https://selenium.dev";
            //Longer
            driver.Navigate().GoToUrl("https://selenium.dev");
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
//Convenient
driver.get("https://selenium.dev")

//Longer way
driver.navigate().to("https://selenium.dev")
  

戻る

ブラウザーの戻るボタンを押す。

        //Back
        driver.navigate().back();
            //Back
             driver.Navigate().Back();
    driver.navigate.back
    //Back
    await driver.navigate().back();
driver.navigate().back() 

次へ

ブラウザーの次へボタンを押す。

        //Forward
        driver.navigate().forward();
            //Forward
             driver.Navigate().Forward();
    driver.navigate.forward
    //Forward
    await driver.navigate().forward();
driver.navigate().forward()

更新

現在のページを更新する。

        //Refresh
        driver.navigate().refresh();
            //Refresh
             driver.Navigate().Refresh();
    driver.navigate.refresh
    //Refresh
    await driver.navigate().refresh();
driver.navigate().refresh()

6.2 - JavaScript アラート、プロンプトおよび確認

WebDriverは、JavaScriptが提供する3種類のネイティブポップアップメッセージを操作するためのAPIを提供します。 これらのポップアップはブラウザーによってスタイルが設定され、カスタマイズが制限されています。

アラート

これらの最も単純なものはアラートと呼ばれ、カスタムメッセージと、ほとんどのブラウザーでOKのラベルが付いたアラートを非表示にする単一のボタンを表示します。 ほとんどのブラウザーでは閉じるボタンを押すことで閉じることもできますが、これは常にOKボタンと同じことを行います。 アラートの例を参照してください

WebDriverはポップアップからテキストを取得し、これらのアラートを受け入れるか、または閉じることができます。


        Alert alert = driver.switchTo().alert();
        //Store the alert text in a variable and verify it
        String text = alert.getText();
        assertEquals(text, "Sample Alert");
        //Press the OK button
        alert.accept();
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
//Click the link to activate the alert
driver.FindElement(By.LinkText("See an example alert")).Click();

//Wait for the alert to be displayed and store it in a variable
IAlert alert = wait.Until(ExpectedConditions.AlertIsPresent());

//Store the alert text in a variable
string text = alert.Text;

//Press the OK button
alert.Accept();
  
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
//Click the link to activate the alert
driver.findElement(By.linkText("See an example alert")).click()

//Wait for the alert to be displayed and store it in a variable
val alert = wait.until(ExpectedConditions.alertIsPresent())

//Store the alert text in a variable
val text = alert.getText()

//Press the OK button
alert.accept()
  

確認

確認ダイアログボックスはアラートに似ていますが、ユーザーがメッセージをキャンセルすることも選択できる点が異なります。 サンプルを確認してください

この例は、アラートを保存する別の方法も示しています。


        alert = driver.switchTo().alert();
        //Store the alert text in a variable and verify it
        text = alert.getText();
        assertEquals(text, "Are you sure?");
        //Press the Cancel button
        alert.dismiss();
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
//Click the link to activate the alert
driver.FindElement(By.LinkText("See a sample confirm")).Click();

//Wait for the alert to be displayed
wait.Until(ExpectedConditions.AlertIsPresent());

//Store the alert in a variable
IAlert alert = driver.SwitchTo().Alert();

//Store the alert in a variable for reuse
string text = alert.Text;

//Press the Cancel button
alert.Dismiss();
  
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
//Click the link to activate the alert
driver.findElement(By.linkText("See a sample confirm")).click()

//Wait for the alert to be displayed
wait.until(ExpectedConditions.alertIsPresent())

//Store the alert in a variable
val alert = driver.switchTo().alert()

//Store the alert in a variable for reuse
val text = alert.text

//Press the Cancel button
alert.dismiss()
  

プロンプト

プロンプトは確認ボックスに似ていますが、テキスト入力も含まれている点が異なります。 フォーム要素の操作と同様に、WebDriverの送信キーを使用して応答を入力できます。 これにより、プレースホルダーテキストが完全に置き換えられます。 キャンセルボタンを押してもテキストは送信されません。 サンプルプロンプトを参照してください


        alert = driver.switchTo().alert();
        //Store the alert text in a variable and verify it
        text = alert.getText();
        assertEquals(text, "What is your name?");
        //Type your message
        alert.sendKeys("Selenium");
        //Press the OK button
        alert.accept();
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
//Click the link to activate the alert
driver.FindElement(By.LinkText("See a sample prompt")).Click();

//Wait for the alert to be displayed and store it in a variable
IAlert alert = wait.Until(ExpectedConditions.AlertIsPresent());

//Type your message
alert.SendKeys("Selenium");

//Press the OK button
alert.Accept();
  
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();
//Click the link to activate the alert
driver.findElement(By.linkText("See a sample prompt")).click()

//Wait for the alert to be displayed and store it in a variable
val alert = wait.until(ExpectedConditions.alertIsPresent())

//Type your message
alert.sendKeys("Selenium")

//Press the OK button
alert.accept()
  

6.3 - クッキーの使用

Cookieは、Webサイトから送信され、コンピューターに保存される小さなデータです。 Cookieは、主にユーザーを認識し、保存されている情報を読み込むために使用されます。

WebDriver APIは、組み込みメソッドでCookieと対話するメソッドを提供します。

クッキーの追加

現在のブラウジングコンテキストにCookieを追加するために使用されます。 Cookieの追加では、一連の定義済みのシリアル化可能なJSONオブジェクトのみを受け入れます。 受け入れられたJSONキー値のリストへのリンクはこちらにあります。

まず、Cookieが有効になるドメインにいる必要があります。 サイトとの対話を開始する前にCookieを事前設定しようとしていて、ホームページが大きい場合/代替の読み込みに時間がかかる場合は、サイトで小さいページを見つけることです。(通常、たとえば http://example.com/some404page のような、404ページは小さいです。)

	      driver.get("https://www.selenium.dev/selenium/web/blank.html");
	      // Add cookie into current browser context
	      driver.manage().addCookie(new Cookie("key", "value"));
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://www.example.com'
  
  # Adds the cookie into current browser context
  driver.manage.add_cookie(name: "key", value: "value")
ensure
  driver.quit
end
  
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")

        // Adds the cookie into current browser context
        driver.manage().addCookie(Cookie("key", "value"))
    } finally {
        driver.quit()
    }
}  
  

命名されたクッキーの取得

関連付けられているすべてのCookieの中で、Cookie名と一致するシリアル化されたCookieデータを返します。

	        driver.get("https://www.selenium.dev/selenium/web/blank.html");
	        // Add cookie into current browser context
	        driver.manage().addCookie(new Cookie("foo", "bar"));
	        // Get cookie details with named cookie 'foo'
	        Cookie cookie = driver.manage().getCookieNamed("foo");
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://www.example.com'
  driver.manage.add_cookie(name: "foo", value: "bar")

  # Get cookie details with named cookie 'foo'
  puts driver.manage.cookie_named('foo')
ensure
  driver.quit
end
  
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("foo", "bar"))

        // Get cookie details with named cookie 'foo'
        val cookie = driver.manage().getCookieNamed("foo")
        println(cookie)
    } finally {
        driver.quit()
    }
}  
  

全てのクッキーの取得

現在のブラウジングコンテキストの ‘成功したシリアル化されたCookieデータ’ を返します。 ブラウザが使用できなくなった場合、エラーが返されます。

	        driver.get("https://www.selenium.dev/selenium/web/blank.html");
	        // Add cookies into current browser context
	        driver.manage().addCookie(new Cookie("test1", "cookie1"));
	        driver.manage().addCookie(new Cookie("test2", "cookie2"));
	        // Get cookies
	        Set<Cookie> cookies = driver.manage().getCookies();
	         for (Cookie cookie : cookies) {
	            if (cookie.getName().equals("test1")) {
	                Assertions.assertEquals(cookie.getValue(), "cookie1");
	            }

	            if (cookie.getName().equals("test2")) {
	                Assertions.assertEquals(cookie.getValue(), "cookie2");
	            }
	         }
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://www.example.com'
  driver.manage.add_cookie(name: "test1", value: "cookie1")
  driver.manage.add_cookie(name: "test2", value: "cookie2")

  # Get all available cookies
  puts driver.manage.all_cookies
ensure
  driver.quit
end
  

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        driver.manage().addCookie(Cookie("test2", "cookie2"))

        // Get All available cookies
        val cookies = driver.manage().cookies
        println(cookies)
    } finally {
        driver.quit()
    }
}  
  

クッキーの削除

指定されたCookie名と一致するCookieデータを削除します。

	        driver.get("https://www.selenium.dev/selenium/web/blank.html");
	        driver.manage().addCookie(new Cookie("test1", "cookie1"));
	        // delete cookie named
	        driver.manage().deleteCookieNamed("test1");
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://www.example.com'
  driver.manage.add_cookie(name: "test1", value: "cookie1")
  driver.manage.add_cookie(name: "test2", value: "cookie2")

  # delete a cookie with name 'test1'
  driver.manage.delete_cookie('test1')
ensure
  driver.quit
end
  
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        val cookie1 = Cookie("test2", "cookie2")
        driver.manage().addCookie(cookie1)

        // delete a cookie with name 'test1'
        driver.manage().deleteCookieNamed("test1")

        // delete cookie by passing cookie object of current browsing context.
        driver.manage().deleteCookie(cookie1)
    } finally {
        driver.quit()
    }
}  
  

全てのクッキーの削除

現在のブラウジングコンテキストの全てのCookieを削除します。

	        driver.get("https://www.selenium.dev/selenium/web/blank.html");
	        // Add cookies into current browser context
	        driver.manage().addCookie(new Cookie("test1", "cookie1"));
	        driver.manage().addCookie(new Cookie("test2", "cookie2"));
	        // Delete All cookies
	        driver.manage().deleteAllCookies();
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://www.example.com'
  driver.manage.add_cookie(name: "test1", value: "cookie1")
  driver.manage.add_cookie(name: "test2", value: "cookie2")

  # deletes all cookies
  driver.manage.delete_all_cookies
ensure
  driver.quit
end
  
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        driver.manage().addCookie(Cookie("test2", "cookie2"))

        // deletes all cookies
        driver.manage().deleteAllCookies()
    } finally {
        driver.quit()
    }
}  
  

SameSite Cookie属性

これにより、ユーザーは、サードパーティのサイトによって開始されたリクエストとともに Cookieを送信するかどうかをブラウザに指示できます。 CSRF(クロスサイトリクエストフォージェリ)攻撃を防ぐために導入されました。

SameSite Cookie属性は、2つのパラメーターを命令として受け入れます。

Strict:

SameSite属性が Strict に設定されている場合、CookieはサードパーティのWebサイトによって 開始されたリクエストとともに送信されません。

Lax:

CookieのSameSite属性を Lax に設定すると、CookieはサードパーティのWebサイトによって 開始されたGETリクエストとともに送信されます。

Note: As of now this feature is landed in chrome(80+version), Firefox(79+version) and works with Selenium 4 and later versions.

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;

public class cookieTest {
  public static void main(String[] args) {
    WebDriver driver = new ChromeDriver();
    try {
      driver.get("http://www.example.com");
      Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
      Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();
      driver.manage().addCookie(cookie);
      driver.manage().addCookie(cookie1);
      System.out.println(cookie.getSameSite());
      System.out.println(cookie1.getSameSite());
    } finally {
      driver.quit();
    }
  }
}
  
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SameSiteCookie {
  class SameSiteCookie {
    static void Main(string[] args) {
      IWebDriver driver = new ChromeDriver();
      try {
        driver.Navigate().GoToUrl("http://www.example.com");

        var cookie1Dictionary = new System.Collections.Generic.Dictionary<string, object>() {
          { "name", "test1" }, { "value", "cookie1" }, { "sameSite", "Strict" } };
        var cookie1 = Cookie.FromDictionary(cookie1Dictionary);

        var cookie2Dictionary = new System.Collections.Generic.Dictionary<string, object>() {
          { "name", "test2" }, { "value", "cookie2" }, { "sameSite", "Lax" } };
        var cookie2 = Cookie.FromDictionary(cookie2Dictionary);

        driver.Manage().Cookies.AddCookie(cookie1);
        driver.Manage().Cookies.AddCookie(cookie2);

        System.Console.WriteLine(cookie1.SameSite);
        System.Console.WriteLine(cookie2.SameSite);
      } finally {
        driver.Quit();
      }
    }
  }
}
  
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://www.example.com'
  # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
  driver.manage.add_cookie(name: "foo", value: "bar", same_site: "Strict")
  driver.manage.add_cookie(name: "foo1", value: "bar", same_site: "Lax")
  puts driver.manage.cookie_named('foo')
  puts driver.manage.cookie_named('foo1')
ensure
  driver.quit
end
  
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("http://www.example.com")
        val cookie = Cookie.Builder("key", "value").sameSite("Strict").build()
        val cookie1 = Cookie.Builder("key", "value").sameSite("Lax").build()
        driver.manage().addCookie(cookie)
        driver.manage().addCookie(cookie1)
        println(cookie.getSameSite())
        println(cookie1.getSameSite())
    } finally {
        driver.quit()
    }
} 
  

6.4 - IFrame と Frame の操作

Frameは、同じドメイン上の複数のドキュメントからサイトレイアウトを構築する非推奨の手段となりました。 HTML5以前のWebアプリを使用している場合を除き、frameを使用することはほとんどありません。 iFrameは、まったく異なるドメインからのドキュメントの挿入を許可し、今でも一般的に使用されています。

FrameまたはiFrameを使用する必要がある場合、Webdriverを使用して同じ方法で作業できます。 iFrame内のボタンがある場合を考えてみましょう。ブラウザー開発ツールを使用して要素を検査すると、次のように表示される場合があります。

<div id="modal">
  <iframe id="buttonframe" name="myframe"  src="https://seleniumhq.github.io">
   <button>Click here</button>
 </iframe>
</div>

iFrameがなければ、次のようなボタンを使用してボタンをクリックします。

//This won't work
driver.findElement(By.tagName("button")).click();
  
    # This Wont work
driver.find_element(By.TAG_NAME, 'button').click()
  
//This won't work
driver.FindElement(By.TagName("button")).Click();
  
    # This won't work
driver.find_element(:tag_name,'button').click
  
// This won't work
await driver.findElement(By.css('button')).click();
  
//This won't work
driver.findElement(By.tagName("button")).click()
  

ただし、iFrameの外側にボタンがない場合は、代わりにno such elementエラーが発生する可能性があります。 これは、Seleniumがトップレベルのドキュメントの要素のみを認識するために発生します。 ボタンを操作するには、ウィンドウを切り替える方法と同様に、最初にFrameに切り替える必要があります。 WebDriverは、Frameに切り替える3つの方法を提供します。

WebElementを使う

WebElementを使用した切り替えは、最も柔軟なオプションです。好みのセレクタを使用してFrameを見つけ、それに切り替えることができます。

         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE= driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
    # Store iframe web element
iframe = driver.find_element(By.CSS_SELECTOR, "#modal > iframe")

    # switch to selected iframe
driver.switch_to.frame(iframe)

    # Now click on button
driver.find_element(By.TAG_NAME, 'button').click()
  
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
    # Store iframe web element
iframe = driver.find_element(:css,'#modal > iframe')

    # Switch to the frame
driver.switch_to.frame iframe

    # Now, Click on the button
driver.find_element(:tag_name,'button').click
  
// Store the web element
const iframe = driver.findElement(By.css('#modal > iframe'));

// Switch to the frame
await driver.switchTo().frame(iframe);

// Now we can click the button
await driver.findElement(By.css('button')).click();
  
//Store the web element
val iframe = driver.findElement(By.cssSelector("#modal>iframe"))

//Switch to the frame
driver.switchTo().frame(iframe)

//Now we can click the button
driver.findElement(By.tagName("button")).click()
  

nameまたはIDを使う

FrameまたはiFrameにidまたはname属性がある場合、代わりにこれを使うことができます。 名前またはIDがページ上で一意でない場合、最初に見つかったものに切り替えます。

         //switch To IFrame using name or id
         driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email=driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
    # Switch frame by id
driver.switch_to.frame('buttonframe')

    # Now, Click on the button
driver.find_element(By.TAG_NAME, 'button').click()
  
            //switch To IFrame using name or id
            driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
// Using the ID
await driver.switchTo().frame('buttonframe');

// Or using the name instead
await driver.switchTo().frame('myframe');

// Now we can click the button
await driver.findElement(By.css('button')).click();
  
//Using the ID
driver.switchTo().frame("buttonframe")

//Or using the name instead
driver.switchTo().frame("myframe")

//Now we can click the button
driver.findElement(By.tagName("button")).click()
  

インデックスを使う

JavaScriptの window.frames を使用して照会できるように、Frameのインデックスを使用することもできます。

         //switch To IFrame using index
         driver.switchTo().frame(0);
    # Switch to the second frame
driver.switch_to.frame(1)
  
            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
    # switching to second iframe based on index
iframe = driver.find_elements(By.TAG_NAME,'iframe')[1]

    # switch to selected iframe
driver.switch_to.frame(iframe)
  
// Switches to the second frame
await driver.switchTo().frame(1);
  
// Switches to the second frame
driver.switchTo().frame(1)
  

Frameを終了する

iFrameまたはFrameセットを終了するには、次のようにデフォルトのコンテンツに切り替えます。

         //leave frame
         driver.switchTo().defaultContent();
    # switch back to default content
driver.switch_to.default_content()
  
            //leave frame
            driver.SwitchTo().DefaultContent();
    # Return to the top level
driver.switch_to.default_content
  
// Return to the top level
await driver.switchTo().defaultContent();
  
// Return to the top level
driver.switchTo().defaultContent()
  

6.5 - Print Page

Printing a webpage is a common task, whether for sharing information or maintaining archives. Selenium simplifies this process through its PrintOptions, PrintsPage, and browsingContext classes, which provide a flexible and intuitive interface for automating the printing of web pages. These classes enable you to configure printing preferences, such as page layout, margins, and scaling, ensuring that the output meets your specific requirements.

Configuring

Orientation

Using the getOrientation() and setOrientation() methods, you can get/set the page orientation — either PORTRAIT or LANDSCAPE.

    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
        }
def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

Range

Using the getPageRanges() and setPageRanges() methods, you can get/set the range of pages to print — e.g. “2-4”.

    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
        }   
def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

Size

Using the getPaperSize() and setPaperSize() methods, you can get/set the paper size to print — e.g. “A0”, “A6”, “Legal”, “Tabloid”, etc.

    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
        }
def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0``
    assert print_options.scale == 0.5

Margins

Using the getPageMargin() and setPageMargin() methods, you can set the margin sizes of the page you wish to print — i.e. top, bottom, left, and right margins.

    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
        }
def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

Scale

Using getScale() and setScale() methods, you can get/set the scale of the page you wish to print — e.g. 1.0 is 100% or default, 0.25 is 25%, etc.

    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
        }
def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

Background

Using getBackground() and setBackground() methods, you can get/set whether background colors and images appear — boolean true or false.

    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
        }
def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

ShrinkToFit

Using getShrinkToFit() and setShrinkToFit() methods, you can get/set whether the page will shrink-to-fit content on the page — boolean true or false.

    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
        }
def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True

Printing

Once you’ve configured your PrintOptions, you’re ready to print the page. To do this, you can invoke the print function, which generates a PDF representation of the web page. The resulting PDF can be saved to your local storage for further use or distribution. Using PrintsPage(), the print command will return the PDF data in base64-encoded format, which can be decoded and written to a file in your desired location, and using BrowsingContext() will return a String.

There may currently be multiple implementations depending on your language of choice. For example, with Java you have the ability to print using either BrowingContext() or PrintsPage(). Both take PrintOptions() objects as a parameter.

Note: BrowsingContext() is part of Selenium’s BiDi implementation. To enable BiDi see Enabling Bidi

PrintsPage()

    public void PrintWithPrintsPageTest() 
    {
        driver.get("https://www.selenium.dev/");
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }

BrowsingContext()

    public void PrintWithBrowsingContextTest() 
    {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();
        String printPage = browsingContext.print(printOptions);
        Assertions.assertTrue(printPage.length() > 0);
    }
        public void PrintWithPrintsPageTest() 
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
        }

print_page()

def test_prints_page(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    pdf = driver.print_page(print_options)
    assert len(pdf) > 0

6.6 - ウィンドウとタブの操作

ウィンドウとタブ

ウィンドウハンドルの取得

WebDriverは、ウィンドウとタブを区別しません。 サイトが新しいタブまたはウィンドウを開く場合、Seleniumはウィンドウハンドルを使って連動します。 各ウィンドウには一意の識別子があり、これは単一のセッションで持続します。 次のコードを使用して、現在のウィンドウのウィンドウハンドルを取得できます。

        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
driver.current_window_handle
            // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
driver.window_handle
await driver.getWindowHandle();
driver.windowHandle

ウィンドウまたはタブの切り替え

新しいウィンドウで開くリンクをクリックすると、新しいウィンドウまたはタブが画面にフォーカスされますが、WebDriverはオペレーティングシステムがアクティブと見なすウィンドウを認識しません。 新しいウィンドウで作業するには、それに切り替える必要があります。 開いているタブまたはウィンドウが2つしかなく、どちらのウィンドウから開始するかがわかっている場合、削除のプロセスによって、WebDriverが表示できる両方のウィンドウまたはタブをループし、元のウィンドウまたはタブに切り替えることができます。

ただし、Selenium 4には、新しいタブ(または)新しいウィンドウを作成して自動的に切り替える新しいAPI NewWindow が用意されています。

        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

    # Start the driver
with webdriver.Firefox() as driver:
    # Open URL
    driver.get("https://seleniumhq.github.io")

    # Setup wait for later
    wait = WebDriverWait(driver, 10)

    # Store the ID of the original window
    original_window = driver.current_window_handle

    # Check we don't have other windows open already
    assert len(driver.window_handles) == 1

    # Click the link which opens in a new window
    driver.find_element(By.LINK_TEXT, "new window").click()

    # Wait for the new window or tab
    wait.until(EC.number_of_windows_to_be(2))

    # Loop through until we find a new window handle
    for window_handle in driver.window_handles:
        if window_handle != original_window:
            driver.switch_to.window(window_handle)
            break

    # Wait for the new tab to finish loading content
    wait.until(EC.title_is("SeleniumHQ Browser Automation"))
  
            //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
    #Store the ID of the original window
original_window = driver.window_handle

    #Check we don't have other windows open already
assert(driver.window_handles.length == 1, 'Expected one window')

    #Click the link which opens in a new window
driver.find_element(link: 'new window').click

    #Wait for the new window or tab
wait.until { driver.window_handles.length == 2 }

    #Loop through until we find a new window handle
driver.window_handles.each do |handle|
    if handle != original_window
        driver.switch_to.window handle
        break
    end
end

    #Wait for the new tab to finish loading content
wait.until { driver.title == 'Selenium documentation'}
  
//Store the ID of the original window
const originalWindow = await driver.getWindowHandle();

//Check we don't have other windows open already
assert((await driver.getAllWindowHandles()).length === 1);

//Click the link which opens in a new window
await driver.findElement(By.linkText('new window')).click();

//Wait for the new window or tab
await driver.wait(
    async () => (await driver.getAllWindowHandles()).length === 2,
    10000
  );

//Loop through until we find a new window handle
const windows = await driver.getAllWindowHandles();
windows.forEach(async handle => {
  if (handle !== originalWindow) {
    await driver.switchTo().window(handle);
  }
});

//Wait for the new tab to finish loading content
await driver.wait(until.titleIs('Selenium documentation'), 10000);
  
//Store the ID of the original window
val originalWindow = driver.getWindowHandle()

//Check we don't have other windows open already
assert(driver.getWindowHandles().size() === 1)

//Click the link which opens in a new window
driver.findElement(By.linkText("new window")).click()

//Wait for the new window or tab
wait.until(numberOfWindowsToBe(2))

//Loop through until we find a new window handle
for (windowHandle in driver.getWindowHandles()) {
    if (!originalWindow.contentEquals(windowHandle)) {
        driver.switchTo().window(windowHandle)
        break
    }
}

//Wait for the new tab to finish loading content
wait.until(titleIs("Selenium documentation"))

  

ウィンドウまたはタブを閉じる

ウィンドウまたはタブでの作業が終了し、 かつ ブラウザーで最後に開いたウィンドウまたはタブではない場合、それを閉じて、以前使用していたウィンドウに切り替える必要があります。 前のセクションのコードサンプルに従ったと仮定すると、変数に前のウィンドウハンドルが格納されます。 これをまとめると以下のようになります。

        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
    #Close the tab or window
driver.close()

    #Switch back to the old tab or window
driver.switch_to.window(original_window)
  
            //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
    #Close the tab or window
driver.close

    #Switch back to the old tab or window
driver.switch_to.window original_window
  
//Close the tab or window
await driver.close();

//Switch back to the old tab or window
await driver.switchTo().window(originalWindow);
  
//Close the tab or window
driver.close()

//Switch back to the old tab or window
driver.switchTo().window(originalWindow)

  

ウィンドウを閉じた後に別のウィンドウハンドルに切り替えるのを忘れると、現在閉じられているページでWebDriverが実行されたままになり、 No Such Window Exception が発行されます。実行を継続するには、有効なウィンドウハンドルに切り替える必要があります。

新しいウィンドウ(または)新しいタブを作成して切り替える

新しいウィンドウ(または)タブを作成し、画面上の新しいウィンドウまたはタブにフォーカスします。 新しいウィンドウ(または)タブを使用するように切り替える必要はありません。 新しいウィンドウ以外に3つ以上のウィンドウ(または)タブを開いている場合、WebDriverが表示できる両方のウィンドウまたはタブをループして、元のものではないものに切り替えることができます。

注意: この機能は、Selenium 4以降のバージョンで機能します。

        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
    # Opens a new tab and switches to new tab
driver.switch_to.new_window('tab')

    # Opens a new window and switches to new window
driver.switch_to.new_window('window')
  
            //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);

Opens a new tab and switches to new tab

    driver.switch_to.new_window(:tab)

Opens a new window and switches to new window

    driver.switch_to.new_window(:window)
Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
Opens a new window and switches to new window:
    await driver.switchTo().newWindow('window');
// Opens a new tab and switches to new tab
driver.switchTo().newWindow(WindowType.TAB)

// Opens a new window and switches to new window
driver.switchTo().newWindow(WindowType.WINDOW)
  

セッションの終了時にブラウザーを終了する

ブラウザーセッションを終了したら、closeではなく、quitを呼び出す必要があります。

        //quitting driver
        driver.quit(); //close all windows
driver.quit()
            //quitting driver
              driver.Quit(); //close all windows
driver.quit
await driver.quit();
driver.quit()
  • Quitは、
    • そのWebDriverセッションに関連付けられているすべてのウィンドウとタブを閉じます
    • ブラウザーのプロセス
    • バックグラウンドのドライバーのプロセス
    • ブラウザーが使用されなくなったことをSelenium Gridに通知して、別のセッションで使用できるようにします(Selenium Gridを使用している場合)

quitの呼び出しに失敗すると、余分なバックグラウンドプロセスとポートがマシン上で実行されたままになり、後で問題が発生する可能性があります。

一部のテストフレームワークでは、テストの終了時にフックできるメソッドとアノテーションを提供しています。

/**
 * Example using JUnit
 * https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
 */
@AfterAll
public static void tearDown() {
    driver.quit();
}
  
    # unittest teardown
    # https://docs.python.org/3/library/unittest.html?highlight=teardown#unittest.TestCase.tearDown
def tearDown(self):
    self.driver.quit()
  
/*
    Example using Visual Studio's UnitTesting
    https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.aspx
*/
[TestCleanup]
public void TearDown()
{
    driver.Quit();
}
  
    # UnitTest Teardown
    # https://www.rubydoc.info/github/test-unit/test-unit/Test/Unit/TestCase
def teardown
    @driver.quit
end
  
/**
 * Example using Mocha
 * https://mochajs.org/#hooks
 */
after('Tear down', async function () {
  await driver.quit();
});
  
/**
 * Example using JUnit
 * https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
 */
@AfterAll
fun tearDown() {
    driver.quit()
}
  

テストコンテキストでWebDriverを実行していない場合は、ほとんどの言語で提供されている try / finally の使用を検討して、例外がWebDriverセッションをクリーンアップするようにします。

try {
    //WebDriver code here...
} finally {
    driver.quit();
}
  
try:
    #WebDriver code here...
finally:
    driver.quit()
  
try {
    //WebDriver code here...
} finally {
    driver.Quit();
}
  
begin
    #WebDriver code here...
ensure
    driver.quit
end
  
try {
    //WebDriver code here...
} finally {
    await driver.quit();
}
  
try {
    //WebDriver code here...
} finally {
    driver.quit()
}
  

PythonのWebDriverは、pythonコンテキストマネージャーをサポートするようになりました。 withキーワードを使用すると、実行終了時にドライバーを自動的に終了できます。

with webdriver.Firefox() as driver:
  # WebDriver code here...

# WebDriver will automatically quit after indentation

ウィンドウマネジメント

画面解像度はWebアプリケーションのレンダリング方法に影響を与える可能性があるため、WebDriverはブラウザーウィンドウを移動およびサイズ変更するメカニズムを提供します。

ウィンドウサイズの取得

ブラウザーウィンドウのサイズをピクセル単位で取得します。

//Access each dimension individually
int width = driver.manage().window().getSize().getWidth();
int height = driver.manage().window().getSize().getHeight();

//Or store the dimensions and query them later
Dimension size = driver.manage().window().getSize();
int width1 = size.getWidth();
int height1 = size.getHeight();
  
    # Access each dimension individually
width = driver.get_window_size().get("width")
height = driver.get_window_size().get("height")

    # Or store the dimensions and query them later
size = driver.get_window_size()
width1 = size.get("width")
height1 = size.get("height")
  
//Access each dimension individually
int width = driver.Manage().Window.Size.Width;
int height = driver.Manage().Window.Size.Height;

//Or store the dimensions and query them later
System.Drawing.Size size = driver.Manage().Window.Size;
int width1 = size.Width;
int height1 = size.Height;
  
    # Access each dimension individually
width = driver.manage.window.size.width
height = driver.manage.window.size.height

    # Or store the dimensions and query them later
size = driver.manage.window.size
width1 = size.width
height1 = size.height
  
Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();
(or) store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;
//Access each dimension individually
val width = driver.manage().window().size.width
val height = driver.manage().window().size.height

//Or store the dimensions and query them later
val size = driver.manage().window().size
val width1 = size.width
val height1 = size.height
  

ウィンドウサイズの設定

ウィンドウを復元し、ウィンドウサイズを設定します。

driver.manage().window().setSize(new Dimension(1024, 768));
driver.set_window_size(1024, 768)
driver.Manage().Window.Size = new Size(1024, 768);
driver.manage.window.resize_to(1024,768)
await driver.manage().window().setRect({ width: 1024, height: 768 });
driver.manage().window().size = Dimension(1024, 768)

ウィンドウの位置を取得

ブラウザーウィンドウの左上の座標を取得します。

// Access each dimension individually
int x = driver.manage().window().getPosition().getX();
int y = driver.manage().window().getPosition().getY();

// Or store the dimensions and query them later
Point position = driver.manage().window().getPosition();
int x1 = position.getX();
int y1 = position.getY();
  
    # Access each dimension individually
x = driver.get_window_position().get('x')
y = driver.get_window_position().get('y')

    # Or store the dimensions and query them later
position = driver.get_window_position()
x1 = position.get('x')
y1 = position.get('y')
  
//Access each dimension individually
int x = driver.Manage().Window.Position.X;
int y = driver.Manage().Window.Position.Y;

//Or store the dimensions and query them later
Point position = driver.Manage().Window.Position;
int x1 = position.X;
int y1 = position.Y;
  
    #Access each dimension individually
x = driver.manage.window.position.x
y = driver.manage.window.position.y

    # Or store the dimensions and query them later
rect  = driver.manage.window.rect
x1 = rect.x
y1 = rect.y
  
Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();
(or) store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;
// Access each dimension individually
val x = driver.manage().window().position.x
val y = driver.manage().window().position.y

// Or store the dimensions and query them later
val position = driver.manage().window().position
val x1 = position.x
val y1 = position.y

  
## ウィンドウの位置設定

選択した位置にウィンドウを移動します。

// Move the window to the top left of the primary monitor
driver.manage().window().setPosition(new Point(0, 0));
  
    # Move the window to the top left of the primary monitor
driver.set_window_position(0, 0)
  
// Move the window to the top left of the primary monitor
driver.Manage().Window.Position = new Point(0, 0);
  
driver.manage.window.move_to(0,0)
  
// Move the window to the top left of the primary monitor
await driver.manage().window().setRect({ x: 0, y: 0 });
  
// Move the window to the top left of the primary monitor
driver.manage().window().position = Point(0,0)
    

ウィンドウの最大化

ウィンドウを拡大します。ほとんどのオペレーティングシステムでは、オペレーティングシステムのメニューとツールバーをブロックすることなく、ウィンドウが画面いっぱいに表示されます。

driver.manage().window().maximize();
driver.maximize_window()
driver.Manage().Window.Maximize();
driver.manage.window.maximize
await driver.manage().window().maximize();
driver.manage().window().maximize()

ウィンドウを最小化

現在のブラウジングコンテキストのウィンドウを最小化します。 このコマンドの正確な動作は、個々のウィンドウマネージャーに固有のものです。

ウィンドウを最小化すると、通常、システムトレイのウィンドウが非表示になります。

注:この機能は、Selenium 4以降のバージョンで機能します。

driver.manage().window().minimize();
driver.minimize_window()
driver.Manage().Window.Minimize();
driver.manage.window.minimize
await driver.manage().window().minimize();
driver.manage().window().minimize()

全画面ウィンドウ

ほとんどのブラウザーでF11を押すのと同じように、画面全体に表示されます。

driver.manage().window().fullscreen();
driver.fullscreen_window()
driver.Manage().Window.FullScreen();
driver.manage.window.full_screen
await driver.manage().window().fullscreen();
driver.manage().window().fullscreen()

スクリーンショットの取得

現在のブラウジング コンテキストのスクリーンショットをキャプチャするために使います。
WebDriver エンドポイントの スクリーンショット は、 Base64 形式でエンコードされたスクリーンショットを返します。

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.*;
import org.openqa.selenium.*;

public class SeleniumTakeScreenshot {
    public static void main(String args[]) throws IOException {
        WebDriver driver = new ChromeDriver();
        driver.get("http://www.example.com");
        File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(scrFile, new File("./image.png"));
        driver.quit();
    }
}
  
from selenium import webdriver

driver = webdriver.Chrome()

    # Navigate to url
driver.get("http://www.example.com")

    # Returns and base64 encoded string into image
driver.save_screenshot('./image.png')

driver.quit()
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using OpenQA.Selenium.Support.UI;

  var driver = new ChromeDriver();
  driver.Navigate().GoToUrl("http://www.example.com");
  Screenshot screenshot = (driver as ITakesScreenshot).GetScreenshot();
  screenshot.SaveAsFile("screenshot.png", ScreenshotImageFormat.Png); // Format values are Bmp, Gif, Jpeg, Png, Tiff
  
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://example.com/'

    # Takes and Stores the screenshot in specified path
  driver.save_screenshot('./image.png')

end
  
    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
import com.oracle.tools.packager.IOUtils.copyFile
import org.openqa.selenium.*
import org.openqa.selenium.chrome.ChromeDriver
import java.io.File

fun main(){
    val driver =  ChromeDriver()
    driver.get("https://www.example.com")
    val scrFile = (driver as TakesScreenshot).getScreenshotAs<File>(OutputType.FILE)
    copyFile(scrFile, File("./image.png"))
    driver.quit()
}
  

要素のスクリーンショットの取得

現在のブラウジング コンテキストの要素のスクリーンショットをキャプチャするために使います。 WebDriver エンドポイントの スクリーンショット は、 Base64 形式でエンコードされたスクリーンショットを返します。

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.File;
import java.io.IOException;

public class SeleniumelementTakeScreenshot {
  public static void main(String args[]) throws IOException {
    WebDriver driver = new ChromeDriver();
    driver.get("https://www.example.com");
    WebElement element = driver.findElement(By.cssSelector("h1"));
    File scrFile = element.getScreenshotAs(OutputType.FILE);
    FileUtils.copyFile(scrFile, new File("./image.png"));
    driver.quit();
  }
}
 
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

    # Navigate to url
driver.get("http://www.example.com")

ele = driver.find_element(By.CSS_SELECTOR, 'h1')

    # Returns and base64 encoded string into image
ele.screenshot('./image.png')

driver.quit()
  
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;
    using OpenQA.Selenium.Support.UI;

    // Webdriver
    var driver = new ChromeDriver();
    driver.Navigate().GoToUrl("http://www.example.com");

    // Fetch element using FindElement
    var webElement = driver.FindElement(By.CssSelector("h1"));

    // Screenshot for the element
    var elementScreenshot = (webElement as ITakesScreenshot).GetScreenshot();
    elementScreenshot.SaveAsFile("screenshot_of_element.png");
  
    # Works with Selenium4-alpha7 Ruby bindings and above
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://example.com/'
  ele = driver.find_element(:css, 'h1')

    # Takes and Stores the element screenshot in specified path
  ele.save_screenshot('./image.jpg')
end
  
    let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
  
import org.apache.commons.io.FileUtils
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.*
import java.io.File

fun main() {
    val driver = ChromeDriver()
    driver.get("https://www.example.com")
    val element = driver.findElement(By.cssSelector("h1"))
    val scrFile: File = element.getScreenshotAs(OutputType.FILE)
    FileUtils.copyFile(scrFile, File("./image.png"))
    driver.quit()
}
  

スクリプトの実行

選択したフレームまたはウィンドウの現在のコンテキストで、JavaScript コードスニペットを実行します。

    //Creating the JavascriptExecutor interface object by Type casting
      JavascriptExecutor js = (JavascriptExecutor)driver;
    //Button Element
      WebElement button =driver.findElement(By.name("btnLogin"));
    //Executing JavaScript to click on element
      js.executeScript("arguments[0].click();", button);
    //Get return value from script
      String text = (String) js.executeScript("return arguments[0].innerText", button);
    //Executing JavaScript directly
      js.executeScript("console.log('hello world')");
  
    # Stores the header element
header = driver.find_element(By.CSS_SELECTOR, "h1")

    # Executing JavaScript to capture innerText of header element
driver.execute_script('return arguments[0].innerText', header)
  
    //creating Chromedriver instance
	IWebDriver driver = new ChromeDriver();
	//Creating the JavascriptExecutor interface object by Type casting
	IJavaScriptExecutor js = (IJavaScriptExecutor) driver;
	//Button Element
	IWebElement button = driver.FindElement(By.Name("btnLogin"));
	//Executing JavaScript to click on element
	js.ExecuteScript("arguments[0].click();", button);
	//Get return value from script
	String text = (String)js.ExecuteScript("return arguments[0].innerText", button);
	//Executing JavaScript directly
	js.ExecuteScript("console.log('hello world')");
  
    # Stores the header element
header = driver.find_element(css: 'h1')

    # Get return value from script
result = driver.execute_script("return arguments[0].innerText", header)

    # Executing JavaScript directly
driver.execute_script("alert('hello world')")
  
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
// Stores the header element
val header = driver.findElement(By.cssSelector("h1"))

// Get return value from script
val result = driver.executeScript("return arguments[0].innerText", header)

// Executing JavaScript directly
driver.executeScript("alert('hello world')")
  

ページの印刷

ブラウザ内の現在のページを印刷します。

Note: Chromium ブラウザがヘッドレスモードである必要があります。

    import org.openqa.selenium.print.PrintOptions;

    driver.get("https://www.selenium.dev");
    printer = (PrintsPage) driver;

    PrintOptions printOptions = new PrintOptions();
    printOptions.setPageRanges("1-2");

    Pdf pdf = printer.print(printOptions);
    String content = pdf.getContent();
  
    from selenium.webdriver.common.print_page_options import PrintOptions

    print_options = PrintOptions()
    print_options.page_ranges = ['1-2']

    driver.get("printPage.html")

    base64code = driver.print_page(print_options)
  
    // code sample not available please raise a PR
  
    driver.navigate_to 'https://www.selenium.dev'

    base64encodedContent = driver.print_page(orientation: 'landscape')
  
    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
    driver.get("https://www.selenium.dev")
    val printer = driver as PrintsPage

    val printOptions = PrintOptions()
    printOptions.setPageRanges("1-2")
    
    val pdf: Pdf = printer.print(printOptions)
    val content = pdf.content
  

6.7 - Virtual Authenticator

A representation of the Web Authenticator model.

Page being translated from English to Japanese. Do you speak Japanese? Help us to translate it by sending us pull requests!

Web applications can enable a public key-based authentication mechanism known as Web Authentication to authenticate users in a passwordless manner. Web Authentication defines APIs that allows a user to create a public-key credential and register it with an authenticator. An authenticator can be a hardware device or a software entity that stores user’s public-key credentials and retrieves them on request.

As the name suggests, Virtual Authenticator emulates such authenticators for testing.

Virtual Authenticator Options

A Virtual Authenticatior has a set of properties. These properties are mapped as VirtualAuthenticatorOptions in the Selenium bindings.

    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False
    options.setHasUserVerification(true);
    options.setIsUserConsenting(true);
    options.setTransport(Transport['USB']);
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    assert(Object.keys(options).length === 6);

Add Virtual Authenticator

It creates a new virtual authenticator with the provided properties.

    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);

Remove Virtual Authenticator

Removes the previously added virtual authenticator.

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

Create Resident Credential

Creates a resident (stateful) credential with the given required credential parameters.

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);
            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);
    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

Create Non-Resident Credential

Creates a resident (stateless) credential with the given required credential parameters.

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);
    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)
    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

Add Credential

Registers the credential with the authenticator.

    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);
    driver.add_credential(credential)
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

Get Credential

Returns the list of credentials owned by the authenticator.

    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
    credential_list = driver.get_credentials()
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();

Remove Credential

Removes a credential from the authenticator based on the passed credential id.

            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    driver.remove_credential(credential.id)

Remove All Credentials

Removes all the credentials from the authenticator.

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();
    driver.remove_all_credentials()
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

Set User Verified

Sets whether the authenticator will simulate success or fail on user verification.

    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.setIsUserVerified(true);

7 - アクション API

仮想化されたデバイス入力アクションを Web ブラウザーに提供するための低レベルのインターフェイス。

In addition to the high-level element interactions, the Actions API provides granular control over exactly what designated input devices can do. Selenium provides an interface for 3 kinds of input sources: a key input for keyboard devices, a pointer input for a mouse, pen or touch devices, and wheel inputs for scroll wheel devices (introduced in Selenium 4.2). Selenium allows you to construct individual action commands assigned to specific inputs and chain them together and call the associated perform method to execute them all at once.

Action Builder

In the move from the legacy JSON Wire Protocol to the new W3C WebDriver Protocol, the low level building blocks of actions became especially detailed. It is extremely powerful, but each input device has a number of ways to use it and if you need to manage more than one device, you are responsible for ensuring proper synchronization between them.

Thankfully, you likely do not need to learn how to use the low level commands directly, since almost everything you might want to do has been given a convenience method that combines the lower level commands for you. These are all documented in keyboard, mouse, pen, and wheel pages.

Pause

Pointer movements and Wheel scrolling allow the user to set a duration for the action, but sometimes you just need to wait a beat between actions for things to work correctly.

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()

Selenium v4.2

            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();

Selenium v4.2

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform
    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()
        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 

Release All Actions

An important thing to note is that the driver remembers the state of all the input items throughout a session. Even if you create a new instance of an actions class, the depressed keys and the location of the pointer will be in whatever state a previously performed action left them.

There is a special method to release all currently depressed keys and pointer buttons. This method is implemented differently in each of the languages because it does not get executed with the perform method.

        ((RemoteWebDriver) driver).resetInputState();
    ActionBuilder(driver).clear_actions()
            ((WebDriver)driver).ResetInputState();
    driver.action.release_actions
    await driver.actions().clear()
        (driver as RemoteWebDriver).resetInputState()

7.1 - Keyboard actions

A representation of any key input device for interacting with a web page.

There are only 2 actions that can be accomplished with a keyboard: pressing down on a key, and releasing a pressed key. In addition to supporting ASCII characters, each keyboard key has a representation that can be pressed or released in designated sequences.

Keys

In addition to the keys represented by regular unicode, unicode values have been assigned to other keyboard keys for use with Selenium. Each language has its own way to reference these keys; the full list can be found here.

Use the [Java Keys enum](https://github.com/SeleniumHQ/selenium/blob/selenium-4.2.0/java/src/org/openqa/selenium/Keys.java#L28)
Use the [Python Keys class](https://github.com/SeleniumHQ/selenium/blob/selenium-4.2.0/py/selenium/webdriver/common/keys.py#L23)
Use the [.NET static Keys class](https://github.com/SeleniumHQ/selenium/blob/selenium-4.2.0/dotnet/src/webdriver/Keys.cs#L28)
Use the [Ruby KEYS constant](https://github.com/SeleniumHQ/selenium/blob/selenium-4.2.0/rb/lib/selenium/webdriver/common/keys.rb#L28)
Use the [JavaScript KEYS constant](https://github.com/SeleniumHQ/selenium/blob/selenium-4.2.0/javascript/node/selenium-webdriver/lib/input.js#L44)
Use the [Java Keys enum](https://github.com/SeleniumHQ/selenium/blob/selenium-4.2.0/java/src/org/openqa/selenium/Keys.java#L28)

Key down

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();
    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();
    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform
    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()
        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

Key up

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();
    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()
            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();
    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform
    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()
        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

Send keys

This is a convenience method in the Actions API that combines keyDown and keyUp commands in one action. Executing this command differs slightly from using the element method, but primarily this gets used when needing to type multiple characters in the middle of other actions.

Active Element

        new Actions(driver)
                .sendKeys("abc")
                .perform();
    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

            new Actions(driver)
                .SendKeys("abc")
    driver.action
          .send_keys('abc')
          .perform
    await driver.actions()
      .sendKeys('abc')
      .perform()
        Actions(driver)
                .sendKeys("abc")
                .perform()

Designated Element

        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();
    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

Selenium v4.5.0

    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()
        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

Copy and Paste

Here’s an example of using all of the above methods to conduct a copy / paste action. Note that the key to use for this operation will be different depending on if it is a Mac OS or not. This code will end up with the text: SeleniumSelenium!

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform
    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()
        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

7.2 - Mouse actions

A representation of any pointer device for interacting with a web page.

There are only 3 actions that can be accomplished with a mouse: pressing down on a button, releasing a pressed button, and moving the mouse. Selenium provides convenience methods that combine these actions in the most common ways.

Click and hold

This method combines moving the mouse to the center of an element with pressing the left mouse button. This is useful for focusing a specific element:

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform
    let clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.move({origin: clickable}).press().perform();
        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

Click and release

This method combines moving to the center of an element with pressing and releasing the left mouse button. This is otherwise known as “clicking”:

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();
    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform
    let click = driver.findElement(By.id("click"));
    const actions = driver.actions({async: true});
    await actions.move({origin: click}).click().perform();
        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

Alternate Button Clicks

There are a total of 5 defined buttons for a Mouse:

  • 0 — Left Button (the default)
  • 1 — Middle Button (currently unsupported)
  • 2 — Right Button
  • 3 — X1 (Back) Button
  • 4 — X2 (Forward) Button

Context Click

This method combines moving to the center of an element with pressing and releasing the right mouse button (button 2). This is otherwise known as “right-clicking”:

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.contextClick(clickable).perform();
        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

Back Click

There is no convenience method for this, it is just pressing and releasing mouse button 3

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

Selenium v4.2

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

Selenium v4.2

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

Selenium v4.2

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

Selenium v4.5.0

    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()
        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

Forward Click

There is no convenience method for this, it is just pressing and releasing mouse button 4

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

Selenium v4.2

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

Selenium v4.2

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

Selenium v4.2

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

Selenium v4.5.0

    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()
        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

Double click

This method combines moving to the center of an element with pressing and releasing the left mouse button twice.

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.doubleClick(clickable).perform();
        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

Move to element

This method moves the mouse to the in-view center point of the element. This is otherwise known as “hovering.” Note that the element must be in the viewport or else the command will error.

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();
    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform
    const hoverable = driver.findElement(By.id("hover"));
    const actions = driver.actions({async: true});
    await actions.move({origin: hoverable}).perform();
        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

Move by offset

These methods first move the mouse to the designated origin and then by the number of pixels in the provided offset. Note that the position of the mouse must be in the viewport or else the command will error.

Offset from Element

This method moves the mouse to the in-view center point of the element, then moves by the provided offset.

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();
    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();
      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();
        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

Offset from Viewport

This method moves the mouse from the upper left corner of the current viewport by the provided offset.

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
      driver.action
            .move_to_location(8, 12)
            .perform
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();
        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

Offset from Current Pointer Location

This method moves the mouse from its current position by the offset provided by the user. If the mouse has not previously been moved, the position will be in the upper left corner of the viewport. Note that the pointer position does not change when the page is scrolled.

Note that the first argument X specifies to move right when positive, while the second argument Y specifies to move down when positive. So moveByOffset(30, -10) moves right 30 and up 10 from the current mouse position.

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();
    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();
      driver.action
            .move_by(13, 15)
            .perform
    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()
        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

Drag and Drop on Element

This method firstly performs a click-and-hold on the source element, moves to the location of the target element and then releases the mouse.

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();
    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();
        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

Drag and Drop by Offset

This method firstly performs a click-and-hold on the source element, moves to the given offset and then releases the mouse.

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();
    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();
        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

7.3 - Pen actions

A representation of a pen stylus kind of pointer input for interacting with a web page.

Chromium Only

A Pen is a type of pointer input that has most of the same behavior as a mouse, but can also have event properties unique to a stylus. Additionally, while a mouse has 5 buttons, a pen has 3 equivalent button states:

  • 0 — Touch Contact (the default; equivalent to a left click)
  • 2 — Barrel Button (equivalent to a right click)
  • 5 — Eraser Button (currently unsupported by drivers)

Using a Pen

Selenium v4.2

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();

Selenium v4.2

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()
            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

Selenium v4.2

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform
        val pointerArea = driver.findElement(By.id("pointerArea"))
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()

Adding Pointer Event Attributes

Selenium v4.2

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));
    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()
            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform
        val pointerArea = driver.findElement(By.id("pointerArea"))
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))

7.4 - Scroll wheel actions

A representation of a scroll wheel input device for interacting with a web page.

Selenium v4.2

Chromium Only

There are 5 scenarios for scrolling on a page.

Scroll to element

This is the most common scenario. Unlike traditional click and send keys methods, the actions class does not automatically scroll the target element into view, so this method will need to be used if elements are not already inside the viewport.

This method takes a web element as the sole argument.

Regardless of whether the element is above or below the current viewscreen, the viewport will be scrolled so the bottom of the element is at the bottom of the screen.

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()
            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();
    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform
    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

Scroll by given amount

This is the second most common scenario for scrolling. Pass in an delta x and a delta y value for how much to scroll in the right and down directions. Negative values represent left and up, respectively.

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();
    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()
            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();
    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform
    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()
        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

Scroll from an element by a given amount

This scenario is effectively a combination of the above two methods.

To execute this use the “Scroll From” method, which takes 3 arguments. The first represents the origination point, which we designate as the element, and the second two are the delta x and delta y values.

If the element is out of the viewport, it will be scrolled to the bottom of the screen, then the page will be scrolled by the provided delta x and delta y values.

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()
        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

Scroll from an element with an offset

This scenario is used when you need to scroll only a portion of the screen, and it is outside the viewport. Or is inside the viewport and the portion of the screen that must be scrolled is a known offset away from a specific element.

This uses the “Scroll From” method again, and in addition to specifying the element, an offset is specified to indicate the origin point of the scroll. The offset is calculated from the center of the provided element.

If the element is out of the viewport, it first will be scrolled to the bottom of the screen, then the origin of the scroll will be determined by adding the offset to the coordinates of the center of the element, and finally the page will be scrolled by the provided delta x and delta y values.

Note that if the offset from the center of the element falls outside of the viewport, it will result in an exception.

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();
    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()
        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

Scroll from a offset of origin (element) by given amount

The final scenario is used when you need to scroll only a portion of the screen, and it is already inside the viewport.

This uses the “Scroll From” method again, but the viewport is designated instead of an element. An offset is specified from the upper left corner of the current viewport. After the origin point is determined, the page will be scrolled by the provided delta x and delta y values.

Note that if the offset from the upper left corner of the viewport falls outside of the screen, it will result in an exception.

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();
    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()
        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

8 - 双方向機能

BiDirectional means that communication is happening in two directions simultaneously. The traditional WebDriver model involves strict request/response commands which only allows for communication to happen in one direction at any given time. In most cases this is what you want; it ensures that the browser is doing the expected things in the right order, but there are a number of interesting things that can be done with asynchronous interactions.

This functionality is currently available in a limited fashion with the [Chrome DevTools Protocol] (CDP), but to address some of its drawbacks, the Selenium team, along with the major browser vendors, have worked to create the new WebDriver BiDi Protocol. This specification aims to create a stable, cross-browser API that leverages bidirectional communication for enhanced browser automation and testing functionality, including streaming events from the user agent to the controlling software via WebSockets. Users will be able to listen for and record or manipulate events as they happen during the course of a Selenium session.

Enabling BiDi in Selenium

In order to use WebDriver BiDi, setting the capability in the browser options will enable the required functionality:

options.setCapability("webSocketUrl", true);
options.enable_bidi = True
UseWebSocketUrl = true,
options.web_socket_url = true
Options().enableBidi();
options.setCapability("webSocketUrl", true);

This enables the WebSocket connection for bidirectional communication, unlocking the full potential of the WebDriver BiDi protocol.

Note that Selenium is updating its entire implementation from WebDriver Classic to WebDriver BiDi (while maintaining backwards compatibility as much as possible), but this section of documentation focuses on the new functionality that bidirectional communication allows. The low-level BiDi domains will be accessible in the code to the end user, but the goal is to provide high-level APIs that are straightforward methods of real-world use cases. As such, the low-level components will not be documented, and this section will focus only on the user-friendly features that we encourage users to take advantage of.

If there is additional functionality you’d like to see, please raise a feature request.

8.1 - WebDriver BiDi Logging Features

These features are related to logging. Because “logging” can refer to so many different things, these methods are made available via a “script” namespace.

Remember that to use WebDriver BiDi, you must enable it in Options. For more details, see Enabling BiDi

Console Message Handlers

Record or take actions on console.log events.

Add Handler

    driver.script.add_console_message_handler(log_entries.append)
    driver.script.add_console_message_handler { |log| log_entries << log }

Remove Handler

You need to store the ID returned when adding the handler to delete it.

    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)
    id = driver.script.add_console_message_handler { |log| log_entries << log }
    driver.script.remove_console_message_handler(id)

JavaScript Exception Handlers

Record or take actions on JavaScript exception events.

Add Handler

    driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.add_javascript_error_handler { |error| log_entries << error }

Remove Handler

You need to store the ID returned when adding the handler to delete it.

    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)
    id = driver.script.add_javascript_error_handler { |error| log_entries << error }
    driver.script.remove_javascript_error_handler(id)

8.2 - WebDriver BiDi Network Features

These features are related to networking, and are made available via a “network” namespace.

The implementation of these features is being tracked here: #13993

Remember that to use WebDriver BiDi, you must enable it in Options. For more details, see Enabling BiDi

Authentication Handlers

Request Handlers

Response Handlers

8.3 - WebDriver BiDi Script Features

These features are related to scripts, and are made available via a “script” namespace.

The implementation of these features is being tracked here: #13992

Remember that to use WebDriver BiDi, you must enable it in Options. For more details, see Enabling BiDi

Script Pinning

Execute Script

DOM Mutation Handlers

8.4 - Chrome DevTools Protocol

Examples of working with Chrome DevTools Protocol in Selenium. CDP support is temporary until WebDriver BiDi has been implemented.

Page being translated from English to Japanese. Do you speak Japanese? Help us to translate it by sending us pull requests!

Many browsers provide “DevTools” – a set of tools that are integrated with the browser that developers can use to debug web apps and explore the performance of their pages. Google Chrome’s DevTools make use of a protocol called the Chrome DevTools Protocol (or “CDP” for short). As the name suggests, this is not designed for testing, nor to have a stable API, so functionality is highly dependent on the version of the browser.

Selenium is working to implement a standards-based, cross-browser, stable alternative to CDP called [WebDriver BiDi]. Until the support for this new protocol has finished, Selenium plans to provide access to CDP features where applicable.

Using Chrome DevTools Protocol with Selenium

Chrome and Edge have a method to send basic CDP commands. This does not work for features that require bidirectional communication, and you need to know what domains to enable when and the exact names and types of domains/methods/parameters.

    Map<String, Object> cookie = new HashMap<>();
    cookie.put("name", "cheese");
    cookie.put("value", "gouda");
    cookie.put("domain", "www.selenium.dev");
    cookie.put("secure", true);
    ((HasCdp) driver).executeCdpCommand("Network.setCookie", cookie);
    cookie = {'name': 'cheese',
              'value': 'gouda',
              'domain': 'www.selenium.dev',
              'secure': True}

    driver.execute_cdp_cmd('Network.setCookie', cookie)
            var cookie = new Dictionary<string, object>
            {
                { "name", "cheese" },
                { "value", "gouda" },
                { "domain", "www.selenium.dev" },
                { "secure", true }
            };
            ((ChromeDriver)driver).ExecuteCdpCommand("Network.setCookie", cookie);
    driver.execute_cdp('Network.setCookie',
                       name: 'cheese',
                       value: 'gouda',
                       domain: 'www.selenium.dev',
                       secure: true)

To make working with CDP easier, and to provide access to the more advanced features, Selenium bindings automatically generate classes and methods for the most common domains. CDP methods and implementations can change from version to version, though, so you want to keep the version of Chrome and the version of DevTools matching. Selenium supports the 3 most recent versions of Chrome at any given time, and tries to time releases to ensure that access to the latest versions are available.

This limitation provides additional challenges for several bindings, where dynamically generated CDP support requires users to regularly update their code to reference the proper version of CDP. In some cases an idealized implementation has been created that should work for any version of CDP without the user needing to change their code, but that is not always available.

Examples of how to use CDP in your Selenium tests can be found on the following pages, but we want to call out a couple commonly cited examples that are of limited practical value.

  • Geo Location — almost all sites use the IP address to determine physical location, so setting an emulated geolocation rarely has the desired effect.
  • Overriding Device Metrics — Chrome provides a great API for setting Mobile Emulation in the Options classes, which is generally superior to attempting to do this with CDP.

8.4.1 - Chrome DevTools Logging Features

Logging features using CDP.

Page being translated from English to Japanese. Do you speak Japanese? Help us to translate it by sending us pull requests!

While Selenium 4 provides direct access to the Chrome DevTools Protocol, these methods will eventually be removed when WebDriver BiDi implemented.

Console Logs

    ((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));
    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();
    driver.on_log_event(:console) { |log| logs << log.args.first }

JavaScript Exceptions

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();
    driver.on_log_event(:exception) { |exception| exceptions << exception }

8.4.2 - Chrome DevTools Network Features

Network features using CDP.

Page being translated from English to Japanese. Do you speak Japanese? Help us to translate it by sending us pull requests!

While Selenium 4 provides direct access to the Chrome DevTools Protocol, these methods will eventually be removed when WebDriver BiDi implemented.

Basic authentication

Some applications make use of browser authentication to secure pages. It used to be common to handle them in the URL, but browsers stopped supporting this. With this code you can insert the credentials into the header when necessary

    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);
        credentials = base64.b64encode("admin:admin".encode()).decode()
        auth = {'authorization': 'Basic ' + credentials}
        await connection.session.execute(connection.devtools.network.set_extra_http_headers(Headers(auth)))
            var handler = new NetworkAuthenticationHandler()
            {
                UriMatcher = uri => uri.AbsoluteUri.Contains("herokuapp"),
                Credentials = new PasswordCredentials("admin", "admin")
            };
            var networkInterceptor = driver.Manage().Network;
            networkInterceptor.AddAuthenticationHandler(handler);
            await networkInterceptor.StartMonitoring();
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

Network Interception

Both requests and responses can be recorded or transformed.

Response information

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      HttpResponse res = next.execute(req);
                      contentType.add(res.getHeader("Content-Type"));
                      return res;
                    })) {
            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

Response transformation

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            Route.matching(req -> true)
                .to(
                    () ->
                        req ->
                            new HttpResponse()
                                .setStatus(200)
                                .addHeader("Content-Type", MediaType.HTML_UTF_8.toString())
                                .setContent(Contents.utf8String("Creamy, delicious cheese!"))))) {
            var handler = new NetworkResponseHandler()
            {
                ResponseMatcher = _ => true,
                ResponseTransformer = _ => new HttpResponseData
                {
                    StatusCode = 200,
                    Body = "Creamy, delicious cheese!"
                }
            };
            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.AddResponseHandler(handler);
            await networkInterceptor.StartMonitoring();
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

Request interception

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
            var handler = new NetworkRequestHandler
            {
                RequestMatcher = request => request.Url.Contains("one.js"),
                RequestTransformer = request =>
                {
                    request.Url = request.Url.Replace("one", "two");

                    return request;
                }
            };
            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.AddRequestHandler(handler);
            await networkInterceptor.StartMonitoring();
    driver.intercept do |request, &continue|
      uri = URI(request.url)
      request.url = uri.to_s.gsub('one', 'two') if uri.path&.end_with?('one.js')
      continue.call(request)
    end

Performance Metrics

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());
    async with driver.bidi_connection() as connection:
        await connection.session.execute(connection.devtools.performance.enable())
        metric_list = await connection.session.execute(connection.devtools.performance.get_metrics())
            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V131.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );
    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

Setting Cookies

    devTools.send(
            Network.setCookie(
                    "cheese",
                    "gouda",
                    Optional.empty(),
                    Optional.of("www.selenium.dev"),
                    Optional.empty(),
                    Optional.of(true),
                    Optional.empty(),
                    Optional.empty(),
                    Optional.empty(),
                    Optional.empty(),
                    Optional.empty(),
                    Optional.empty(),
                    Optional.empty(),
                    Optional.empty()));
    async with driver.bidi_connection() as connection:
        execution = connection.devtools.network.set_cookie(
            name="cheese",
            value="gouda",
            domain="www.selenium.dev",
            secure=True
        )
        await connection.session.execute(execution)
            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

Waiting for Downloads

    devTools.send(
            Browser.setDownloadBehavior(
                    Browser.SetDownloadBehaviorBehavior.ALLOWANDNAME,
                    Optional.empty(),
                    Optional.of(""),
                    Optional.of(true)));
    driver.devtools.browser.set_download_behavior(behavior: 'allow',
                                                  download_path: '',
                                                  events_enabled: true)

    driver.devtools.browser.on(:download_progress) do |progress|
      @completed = progress['state'] == 'completed'
    end

8.4.3 - Chrome DevTools Script Features

Script features using CDP.

Page being translated from English to Japanese. Do you speak Japanese? Help us to translate it by sending us pull requests!

While Selenium 4 provides direct access to the Chrome DevTools Protocol, these methods will eventually be removed when WebDriver BiDi implemented.

Script Pinning

    ScriptKey key = ((JavascriptExecutor) driver).pin("return arguments;");
    List<Object> arguments =
        (List<Object>) ((JavascriptExecutor) driver).executeScript(key, 1, true, element);
            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);
    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)

DOM Mutation Handlers

    async with driver.bidi_connection() as session:
        async with Log(driver, session).mutation_events() as event:
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            monitor.DomMutated += (_, e) =>
            {
                var locator = By.CssSelector($"*[data-__webdriver_id='{e.AttributeData.TargetId}']");
                mutations.Add(driver.FindElement(locator));
            };
            await monitor.StartEventMonitoring();
            await monitor.EnableDomMutationMonitoring();
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }

8.5 - BiDirectional API (W3C compliant)

Page being translated from English to Japanese. Do you speak Japanese? Help us to translate it by sending us pull requests!

The following list of APIs will be growing as the WebDriver BiDirectional Protocol grows and browser vendors implement the same. Additionally, Selenium will try to support real-world use cases that internally use a combination of W3C BiDi protocol APIs.

If there is additional functionality you’d like to see, please raise a feature request.

8.5.1 - Browsing Context

Page being translated from English to Japanese. Do you speak Japanese? Help us to translate it by sending us pull requests!

Commands

This section contains the APIs related to browsing context commands.

Open a new window

Creates a new browsing context in a new window.

Selenium v4.8

    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

Selenium v4.8

    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })

Open a new tab

Creates a new browsing context in a new tab.

Selenium v4.8

    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

Selenium v4.8

    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

Use existing window handle

Creates a browsing context for the existing tab/window to run commands.

Selenium v4.8

    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

Selenium v4.8

    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

Open a window with a reference browsing context

A reference browsing context is a top-level browsing context. The API allows to pass the reference browsing context, which is used to create a new window. The implementation is operating system specific.

Selenium v4.8

    void testCreateAWindowWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.WINDOW, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

Selenium v4.8

    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })

Open a tab with a reference browsing context

A reference browsing context is a top-level browsing context. The API allows to pass the reference browsing context, which is used to create a new tab. The implementation is operating system specific.

Selenium v4.8

    void testCreateATabWithAReferenceContext() {
        BrowsingContext
                browsingContext =
                new BrowsingContext(driver, WindowType.TAB, driver.getWindowHandle());
        Assertions.assertNotNull(browsingContext.getId());
    }

Selenium v4.8

    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })

Selenium v4.8

    void testNavigateToAUrl() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);

        NavigationResult info = browsingContext.navigate("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");

        Assertions.assertNotNull(browsingContext.getId());
        Assertions.assertNotNull(info.getNavigationId());
        Assertions.assertTrue(info.getUrl().contains("/bidi/logEntryAdded.html"));
    }

Selenium v4.8

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

Selenium v4.8

    void testNavigateToAUrlWithReadinessState() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);

        NavigationResult info = browsingContext.navigate("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html",
                ReadinessState.COMPLETE);

        Assertions.assertNotNull(browsingContext.getId());
        Assertions.assertNotNull(info.getNavigationId());
        Assertions.assertTrue(info.getUrl().contains("/bidi/logEntryAdded.html"));
    }

Selenium v4.8

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

Get browsing context tree

Provides a tree of all browsing contexts descending from the parent browsing context, including the parent browsing context.

Selenium v4.8

    void testGetTreeWithAChild() {
        String referenceContextId = driver.getWindowHandle();
        BrowsingContext parentWindow = new BrowsingContext(driver, referenceContextId);

        parentWindow.navigate("https://www.selenium.dev/selenium/web/iframes.html", ReadinessState.COMPLETE);

        List<BrowsingContextInfo> contextInfoList = parentWindow.getTree();

        Assertions.assertEquals(1, contextInfoList.size());
        BrowsingContextInfo info = contextInfoList.get(0);
        Assertions.assertEquals(1, info.getChildren().size());
        Assertions.assertEquals(referenceContextId, info.getId());
        Assertions.assertTrue(info.getChildren().get(0).getUrl().contains("formPage.html"));
    }

Selenium v4.8

    const browsingContextId = await driver.getWindowHandle()
    const parentWindow = await BrowsingContext(driver, {
      browsingContextId: browsingContextId,
    })
    await parentWindow.navigate('https://www.selenium.dev/selenium/web/iframes.html', 'complete')

    const contextInfo = await parentWindow.getTree()

Get browsing context tree with depth

Provides a tree of all browsing contexts descending from the parent browsing context, including the parent browsing context upto the depth value passed.

Selenium v4.8

    void testGetTreeWithDepth() {
        String referenceContextId = driver.getWindowHandle();
        BrowsingContext parentWindow = new BrowsingContext(driver, referenceContextId);

        parentWindow.navigate("https://www.selenium.dev/selenium/web/iframes.html", ReadinessState.COMPLETE);

        List<BrowsingContextInfo> contextInfoList = parentWindow.getTree(0);

        Assertions.assertEquals(1, contextInfoList.size());
        BrowsingContextInfo info = contextInfoList.get(0);
        Assertions.assertNull(info.getChildren()); // since depth is 0
        Assertions.assertEquals(referenceContextId, info.getId());
    }

Selenium v4.8

    const browsingContextId = await driver.getWindowHandle()
    const parentWindow = await BrowsingContext(driver, {
      browsingContextId: browsingContextId,
    })
    await parentWindow.navigate('https://www.selenium.dev/selenium/web/iframes.html', 'complete')

    const contextInfo = await parentWindow.getTree(0)

Get All Top level browsing contexts

Selenium v4.8

    void testGetAllTopLevelContexts() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        List<BrowsingContextInfo> contextInfoList = window1.getTopLevelContexts();

        Assertions.assertEquals(2, contextInfoList.size());
    }

Selenium v4.20.0

    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()

Close a tab/window

Selenium v4.8

    void testCloseAWindow() {
        BrowsingContext window1 = new BrowsingContext(driver, WindowType.WINDOW);
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window2.close();

        Assertions.assertThrows(BiDiException.class, window2::getTree);
    }

    @Test
    void testCloseATab() {
        BrowsingContext tab1 = new BrowsingContext(driver, WindowType.TAB);
        BrowsingContext tab2 = new BrowsingContext(driver, WindowType.TAB);

        tab2.close();

        Assertions.assertThrows(BiDiException.class, tab2::getTree);
    }

Selenium v4.8

    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

Activate a browsing context

Selenium v4.14.1

        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

Selenium v4.15

    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await window1.activate()

Reload a browsing context

Selenium v4.13.0

        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);

        browsingContext.navigate("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html", ReadinessState.COMPLETE);

        NavigationResult reloadInfo = browsingContext.reload(ReadinessState.INTERACTIVE);

Selenium v4.15

    await browsingContext.reload(undefined, 'complete')

Handle user prompt

Selenium v4.13.0

        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("prompt-with-default")).click();

        String userText = "Selenium automates browsers";
        browsingContext.handleUserPrompt(true, userText);

Selenium v4.15

    await browsingContext.handleUserPrompt(true, userText)

Capture Screenshot

Selenium v4.13.0

        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

Selenium v4.15

    const response = await browsingContext.captureScreenshot()

Capture Viewport Screenshot

Selenium v4.14.0

        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/coordinates_tests/simple_page.html");

        WebElement element = driver.findElement(By.id("box"));
        Rectangle elementRectangle = element.getRect();

        String screenshot =
                browsingContext.captureBoxScreenshot(
                        elementRectangle.getX(), elementRectangle.getY(), 5, 5);

Selenium v4.15

    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

Capture Element Screenshot

Selenium v4.14.0

        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        WebElement element = driver.findElement(By.id("checky"));

        String screenshot = browsingContext.captureElementScreenshot(((RemoteWebElement) element).getId());

Selenium v4.15

    const response = await browsingContext.captureElementScreenshot(elementId)

Set Viewport

Selenium v4.14.1

        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

Selenium v4.15

    await browsingContext.setViewport(250, 300)

Selenium v4.14.1

        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();

        String printPage = browsingContext.print(printOptions);

Selenium v4.10

    const result = await browsingContext.printPage({
      orientation: 'landscape',
      scale: 1,
      background: true,
      width: 30,
      height: 30,
      top: 1,
      bottom: 1,
      left: 1,
      right: 1,
      shrinkToFit: true,
      pageRanges: ['1-2'],
    })

Selenium v4.16.0

        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        browsingContext.navigate("https://www.selenium.dev/selenium/web/formPage.html", ReadinessState.COMPLETE);

        wait.until(visibilityOfElementLocated(By.id("imageButton"))).submit();
        wait.until(titleIs("We Arrive Here"));

        browsingContext.back();

Selenium v4.17

    await browsingContext.back()

Selenium v4.16.0

    void canNavigateForwardInTheBrowserHistory() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        browsingContext.navigate("https://www.selenium.dev/selenium/web/formPage.html", ReadinessState.COMPLETE);

        wait.until(visibilityOfElementLocated(By.id("imageButton"))).submit();
        wait.until(titleIs("We Arrive Here"));

        browsingContext.back();
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));

        browsingContext.forward();

Selenium v4.17

    await browsingContext.forward()

Traverse history

Selenium v4.16.0

        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        browsingContext.navigate("https://www.selenium.dev/selenium/web/formPage.html", ReadinessState.COMPLETE);

        wait.until(visibilityOfElementLocated(By.id("imageButton"))).submit();
        wait.until(titleIs("We Arrive Here"));

        browsingContext.traverseHistory(-1);

Selenium v4.17

    await browsingContext.traverseHistory(-1)

Events

This section contains the APIs related to browsing context events.

Browsing Context Created Event

Selenium v4.10

    try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
        CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();

        inspector.onBrowsingContextCreated(future::complete);

        String windowHandle = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();

        BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

Selenium v4.9.2

    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

Dom Content loaded Event

Selenium v4.10

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()

Selenium v4.9.2

    const browsingContextInspector = await BrowsingContextInspector(driver)
    let navigationInfo = null
    await browsingContextInspector.onDomContentLoaded((entry) => {
      navigationInfo = entry
    })

    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: await driver.getWindowHandle(),
    })
    await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

Browsing Context Loaded Event

Selenium v4.10

        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextLoaded(future::complete);

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            context.navigate("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html", ReadinessState.COMPLETE);

            NavigationInfo navigationInfo = future.get(5, TimeUnit.SECONDS);

Selenium v4.9.2

    const browsingContextInspector = await BrowsingContextInspector(driver)

    await browsingContextInspector.onBrowsingContextLoaded((entry) => {
      navigationInfo = entry
    })
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: await driver.getWindowHandle(),
    })
    await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

Selenium v4.15

        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onNavigationStarted(future::complete);

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            context.navigate("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html", ReadinessState.COMPLETE);

            NavigationInfo navigationInfo = future.get(5, TimeUnit.SECONDS);

Fragment Navigated Event

Selenium v4.15

        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            context.navigate("https://www.selenium.dev/selenium/web/linked_image.html", ReadinessState.COMPLETE);

            inspector.onFragmentNavigated(future::complete);

            context.navigate("https://www.selenium.dev/selenium/web/linked_image.html#linkToAnchorOnThisPage", ReadinessState.COMPLETE);

            NavigationInfo navigationInfo = future.get(5, TimeUnit.SECONDS);

Selenium v4.15.0

    const browsingContextInspector = await BrowsingContextInspector(driver)

    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: await driver.getWindowHandle(),
    })
    await browsingContext.navigate('https://www.selenium.dev/selenium/web/linked_image.html', 'complete')

    await browsingContextInspector.onFragmentNavigated((entry) => {
      navigationInfo = entry
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/linked_image.html#linkToAnchorOnThisPage', 'complete')

User Prompt Opened Event

Selenium v4.15

        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            context.navigate("https://www.selenium.dev/selenium/web/linked_image.html", ReadinessState.COMPLETE);

            inspector.onFragmentNavigated(future::complete);

            context.navigate("https://www.selenium.dev/selenium/web/linked_image.html#linkToAnchorOnThisPage", ReadinessState.COMPLETE);

            NavigationInfo navigationInfo = future.get(5, TimeUnit.SECONDS);

User Prompt Closed Event

Selenium v4.15

        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptClosed> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptClosed(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("prompt")).click();

            context.handleUserPrompt(true, "selenium");

            UserPromptClosed userPromptClosed = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptClosed.getBrowsingContextId());

Browsing Context Destroyed Event

Selenium v4.18

        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();

            inspector.onBrowsingContextDestroyed(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();

            driver.close();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());

Selenium v4.18.0

    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

8.5.2 - Browsing Context

Page being translated from English to Japanese. Do you speak Japanese? Help us to translate it by sending us pull requests!

This section contains the APIs related to input commands.

Perform Actions

Selenium v4.17

        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());

Selenium v4.17

    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)

Release Actions

Selenium v4.17

        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);

Selenium v4.17

    await input.release(browsingContextId)

8.5.3 - Network

Page being translated from English to Japanese. Do you speak Japanese? Help us to translate it by sending us pull requests!

Commands

This section contains the APIs related to network commands.

Add network intercept

Selenium v4.18

        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));

Selenium v4.18

    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))

Remove network intercept

Selenium v4.18

        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);

Selenium v4.18

    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))

Continue request blocked at authRequired phase with credentials

Selenium v4.18

        try (Network network = new Network(driver)) {
            network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED));
            network.onAuthRequired(
                    responseDetails ->
                            network.continueWithAuth(
                                    responseDetails.getRequest().getRequestId(),
                                    new UsernameAndPassword("admin", "admin")));
            driver.get("https://the-internet.herokuapp.com/basic_auth");

Selenium v4.18

    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })

Continue request blocked at authRequired phase without credentials

Selenium v4.18

        try (Network network = new Network(driver)) {
            network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED));
            network.onAuthRequired(
                    responseDetails ->
                            // Does not handle the alert
                            network.continueWithAuthNoCredentials(responseDetails.getRequest().getRequestId()));
            driver.get("https://the-internet.herokuapp.com/basic_auth");

Selenium v4.18

    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

Cancel request blocked at authRequired phase

Selenium v4.18

        try (Network network = new Network(driver)) {
            network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED));
            network.onAuthRequired(
                    responseDetails ->
                            // Does not handle the alert
                            network.cancelAuth(responseDetails.getRequest().getRequestId()));
            driver.get("https://the-internet.herokuapp.com/basic_auth");

Selenium v4.18

    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

Fail request

Selenium v4.18

        try (Network network = new Network(driver)) {
            network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            network.onBeforeRequestSent(
                    responseDetails -> network.failRequest(responseDetails.getRequest().getRequestId()));
            driver.manage().timeouts().pageLoadTimeout(Duration.of(5, ChronoUnit.SECONDS));

Events

This section contains the APIs related to network events.

Before Request Sent

Selenium v4.15

        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();
            network.onBeforeRequestSent(future::complete);
            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);

Selenium v4.18

    let beforeRequestEvent = null
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

Response Started

Selenium v4.15

        try (Network network = new Network(driver)) {
            CompletableFuture<ResponseDetails> future = new CompletableFuture<>();
            network.onResponseStarted(future::complete);
            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");

            ResponseDetails response = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

Selenium v4.18

    let onResponseStarted = []
    const network = await Network(driver)
    await network.responseStarted(function (event) {
      onResponseStarted.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

Response Completed

Selenium v4.15

        try (Network network = new Network(driver)) {
            CompletableFuture<ResponseDetails> future = new CompletableFuture<>();
            network.onResponseCompleted(future::complete);
            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");

            ResponseDetails response = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

Selenium v4.18

    let onResponseCompleted = []
    const network = await Network(driver)
    await network.responseCompleted(function (event) {
      onResponseCompleted.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

Auth Required

Selenium v4.17

        try (Network network = new Network(driver)) {
            CompletableFuture<ResponseDetails> future = new CompletableFuture<>();
            network.onAuthRequired(future::complete);
            driver.get("https://the-internet.herokuapp.com/basic_auth");

            ResponseDetails response = future.get(5, TimeUnit.SECONDS);

8.5.4 - Script

Page being translated from English to Japanese. Do you speak Japanese? Help us to translate it by sending us pull requests!

Commands

This section contains the APIs related to script commands.

Call function in a browsing context

Selenium v4.15

        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            arguments.add(PrimitiveProtocolValue.numberValue(22));

            Map<Object, LocalValue> value = new HashMap<>();
            value.put("some_property", LocalValue.numberValue(42));
            LocalValue thisParameter = LocalValue.objectValue(value);

            arguments.add(thisParameter);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "function processWithPromise(argument) {\n"
                                    + "  return new Promise((resolve, reject) => {\n"
                                    + "    setTimeout(() => {\n"
                                    + "      resolve(argument + this.some_property);\n"
                                    + "    }, 1000)\n"
                                    + "  })\n"
                                    + "}",
                            true,
                            Optional.of(arguments),
                            Optional.of(thisParameter),
                            Optional.of(ResultOwnership.ROOT));

Selenium v4.9

    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value = new ArgumentValue(LocalValue.createNumberValue(22))
    argumentValues.push(value)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function processWithPromise(argument) {' +
      'return new Promise((resolve, reject) => {' +
      'setTimeout(() => {' +
      'resolve(argument + this.some_property);' +
      '}, 1000)' +
      '})' +
      '}',
      true,
      argumentValues,
      thisParameter,
      ResultOwnership.ROOT)

Call function in a sandbox

Selenium v4.15

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

Selenium v4.9

    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

Call function in a realm

Selenium v4.15

        try (Script script = new Script(tab, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            EvaluateResult result = script.callFunctionInRealm(
                    realmId,
                    "() => { window.foo = 3; }",
                    true,
                    Optional.empty(),
                    Optional.empty(),
                    Optional.empty());

Selenium v4.9

    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

Evaluate script in a browsing context

Selenium v4.15

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

Selenium v4.9

    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

Evaluate script in a sandbox

Selenium v4.15

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());

Selenium v4.9

    const manager = await ScriptManager(id, driver)

    await manager.evaluateFunctionInBrowsingContext(id, 'window.foo = 2', true, null, 'sandbox')

    const resultInSandbox = await manager.evaluateFunctionInBrowsingContext(id, 'window.foo', true, null, 'sandbox')

Evaluate script in a realm

Selenium v4.15

        try (Script script = new Script(tab, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            EvaluateResult result =
                    script.evaluateFunctionInRealm(
                            realmId, "window.foo", true, Optional.empty());

Selenium v4.9

    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.evaluateFunctionInRealm(realmId, 'window.foo = 3', true)

    const result = await manager.evaluateFunctionInRealm(realmId, 'window.foo', true)

Disown handles in a browsing context

Selenium v4.15

            script.disownBrowsingContextScript(

Selenium v4.9

    await manager.disownBrowsingContextScript(id, boxId)

Disown handles in a realm

Selenium v4.15

            script.disownRealmScript(realmId, List.of(boxId));

Selenium v4.9

    await manager.disownRealmScript(realmId, boxId)

Get all realms

Selenium v4.15

        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();

Selenium v4.9

    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()

Get realm by type

Selenium v4.15

        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);

Selenium v4.9

    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)

Get browsing context realms

Selenium v4.15

        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);

Selenium v4.9

    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

Get browsing context realms by type

Selenium v4.15

            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);

Selenium v4.9

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

Preload a script

Selenium v4.15

            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");

Selenium v4.10

    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

Remove a preloaded script

Selenium v4.15

                script.removePreloadScript(id);

Selenium v4.10

    await manager.removePreloadScript(scriptId)

Events

This section contains the APIs related to script events.

Message

Selenium v4.16

        try (Script script = new Script(driver)) {
            CompletableFuture<Message> future = new CompletableFuture<>();
            script.onMessage(future::complete);

            script.callFunctionInBrowsingContext(
                    driver.getWindowHandle(),
                    "(channel) => channel('foo')",
                    false,
                    Optional.of(List.of(LocalValue.channelValue("channel_name"))),
                    Optional.empty(),
                    Optional.empty());

            Message message = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals("channel_name", message.getChannel());
        }

Selenium v4.18

    const manager = await ScriptManager(undefined, driver)

    let message = null

    await manager.onMessage((m) => {
      message = m
    })

    let argumentValues = []
    let value = new ArgumentValue(LocalValue.createChannelValue(new ChannelValue('channel_name')))
    argumentValues.push(value)

    const result = await manager.callFunctionInBrowsingContext(
      await driver.getWindowHandle(),
      '(channel) => channel("foo")',
      false,
      argumentValues,
    )

Realm Created

Selenium v4.16

        try (Script script = new Script(driver)) {
            CompletableFuture<RealmInfo> future = new CompletableFuture<>();
            script.onRealmCreated(future::complete);

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());

            context.navigate("https://www.selenium.dev/selenium/blankPage");
            RealmInfo realmInfo = future.get(5, TimeUnit.SECONDS);
            Assertions.assertNotNull(realmInfo.getRealmId());
            Assertions.assertEquals(RealmType.WINDOW, realmInfo.getRealmType());
        }

Selenium v4.18

    const manager = await ScriptManager(undefined, driver)

    let realmInfo = null

    await manager.onRealmCreated((result) => {
      realmInfo = result
    })

    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/blank', 'complete')

Realm Destroyed

Selenium v4.16

        try (Script script = new Script(driver)) {
            CompletableFuture<RealmInfo> future = new CompletableFuture<>();
            script.onRealmDestroyed(future::complete);

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());

            context.close();
            RealmInfo realmInfo = future.get(5, TimeUnit.SECONDS);
            Assertions.assertNotNull(realmInfo.getRealmId());
            Assertions.assertEquals(RealmType.WINDOW, realmInfo.getRealmType());
        }

Selenium v4.19

    const manager = await ScriptManager(undefined, driver)

    let realmInfo = null

    await manager.onRealmDestroyed((result) => {
      realmInfo = result
    })

    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.close()

8.5.5 - BiDirectional API (W3C compliant)

Page being translated from English to Japanese. Do you speak Japanese? Help us to translate it by sending us pull requests!

This section contains the APIs related to logging.

Console logs

Listen to the console.log events and register callbacks to process the event.

Selenium v4.8

    public void jsErrors() {
        CopyOnWriteArrayList<ConsoleLogEntry> logs = new CopyOnWriteArrayList<>();

        try (LogInspector logInspector = new LogInspector(driver)) {
            logInspector.onConsoleEntry(logs::add);
        }

        driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    await driver.findElement({id: 'consoleLog'}).click()

    assert.equal(logEntry.text, 'Hello, world!')
    assert.equal(logEntry.realm, null)
    assert.equal(logEntry.type, 'console')
    assert.equal(logEntry.level, 'info')
    assert.equal(logEntry.method, 'log')
    assert.equal(logEntry.stackTrace, null)
    assert.equal(logEntry.args.length, 1)

JavaScript exceptions

Listen to the JS Exceptions and register callbacks to process the exception details.

            logInspector.onJavaScriptLog(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
    const inspector = await LogInspector(driver)
    await inspector.onJavascriptException(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    await driver.findElement({id: 'jsException'}).click()

    assert.equal(logEntry.text, 'Error: Not working')
    assert.equal(logEntry.type, 'javascript')
    assert.equal(logEntry.level, 'error')

Listen to JS Logs

Listen to all JS logs at all levels and register callbacks to process the log.

Selenium v4.8

            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());

9 - サポート機能

サポート クラスは、オプションの上位レベル機能を提供します。

The core libraries of Selenium try to be low level and non-opinionated. The Support classes in each language provide opinionated wrappers for common interactions that may be used to simplify some behaviors.

9.1 - Waiting with Expected Conditions

These are classes used to describe what needs to be waited for.

Expected Conditions are used with Explicit Waits. Instead of defining the block of code to be executed with a lambda, an expected conditions method can be created to represent common things that get waited on. Some methods take locators as arguments, others take elements as arguments.

These methods can include conditions such as:

  • element exists
  • element is stale
  • element is visible
  • text is visible
  • title contains specified value
[Expected Conditions Documentation](https://www.selenium.dev/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html)

Add Example

.NET stopped supporting Expected Conditions in Selenium 4 to minimize maintenance hassle and redundancy.
Ruby makes frequent use of blocks, procs and lambdas and does not need Expected Conditions classes

9.2 - Command Listeners

These allow you to execute custom actions in every time specific Selenium commands are sent

9.3 - 色を扱う

テストの一部として何かの色を検証したい場合があります。 問題は、ウェブ上の色の定義が一定ではないことです。 色のHEX表現を色のRGB表現と比較する簡単な方法、または色のRGBA表現を色のHSLA表現と比較する簡単な方法があったらいいのではないでしょうか?

心配しないでください。解決策があります。: Color クラスです!

まず、クラスをインポートする必要があります。

import org.openqa.selenium.support.Color;
  
from selenium.webdriver.support.color import Color
  
// This feature is not implemented - Help us by sending a pr to implement this feature
  
include Selenium::WebDriver::Support
  
// This feature is not implemented - Help us by sending a pr to implement this feature
  
import org.openqa.selenium.support.Color

これで、カラーオブジェクトの作成を開始できます。 すべての色オブジェクトは、色の文字列表現から作成する必要があります。 サポートされている色表現は、以下のとおりです。

private final Color HEX_COLOUR = Color.fromString("#2F7ED8");
private final Color RGB_COLOUR = Color.fromString("rgb(255, 255, 255)");
private final Color RGB_COLOUR = Color.fromString("rgb(40%, 20%, 40%)");
private final Color RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)");
private final Color RGBA_COLOUR = Color.fromString("rgba(40%, 20%, 40%, 0.5)");
private final Color HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)");
private final Color HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)");
  
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
  
// This feature is not implemented - Help us by sending a pr to implement this feature
  
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
  
// This feature is not implemented - Help us by sending a pr to implement this feature
  
private val HEX_COLOUR = Color.fromString("#2F7ED8")
private val RGB_COLOUR = Color.fromString("rgb(255, 255, 255)")
private val RGB_COLOUR_PERCENT = Color.fromString("rgb(40%, 20%, 40%)")
private val RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)")
private val RGBA_COLOUR_PERCENT = Color.fromString("rgba(40%, 20%, 40%, 0.5)")
private val HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)")
private val HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)")
  

Colorクラスは、 http://www.w3.org/TR/css3-color/#html4 で指定されているすべての基本色定義もサポートしています。

private final Color BLACK = Color.fromString("black");
private final Color CHOCOLATE = Color.fromString("chocolate");
private final Color HOTPINK = Color.fromString("hotpink");
  
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
  
// This feature is not implemented - Help us by sending a pr to implement this feature
  
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
  
// This feature is not implemented - Help us by sending a pr to implement this feature
  
private val BLACK = Color.fromString("black")
private val CHOCOLATE = Color.fromString("chocolate")
private val HOTPINK = Color.fromString("hotpink")
  

要素に色が設定されていない場合、ブラウザは “透明” の色の値を返すことがあります。 Colorクラスもこれをサポートしています。

private final Color TRANSPARENT = Color.fromString("transparent");
  
TRANSPARENT = Color.from_string('transparent')
  
// This feature is not implemented - Help us by sending a pr to implement this feature
  
TRANSPARENT = Color.from_string('transparent')
  
// This feature is not implemented - Help us by sending a pr to implement this feature
  
private val TRANSPARENT = Color.fromString("transparent")
  

レスポンスが正しく解析され、有効なColorオブジェクトに変換されることを認識して、要素を安全にクエリしてその色/背景色を取得できるようになりました。

Color loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"));

Color loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"));
  
login_button_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('color'))

login_button_background_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('background-color'))
  
// This feature is not implemented - Help us by sending a pr to implement this feature
  
login_button_colour = Color.from_string(driver.find_element(id: 'login').css_value('color'))

login_button_background_colour = Color.from_string(driver.find_element(id: 'login').css_value('background-color'))
  
// This feature is not implemented - Help us by sending a pr to implement this feature
  
val loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"))

val loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"))
  

そして、色オブジェクトを直接比較できます。

assert loginButtonBackgroundColour.equals(HOTPINK);
  
assert login_button_background_colour == HOTPINK
  
// This feature is not implemented - Help us by sending a pr to implement this feature
  
assert(login_button_background_colour == HOTPINK)
  
// This feature is not implemented - Help us by sending a pr to implement this feature
  
assert(loginButtonBackgroundColour.equals(HOTPINK))
  

または、色を次の形式のいずれかに変換し、静的に検証することができます。

assert loginButtonBackgroundColour.asHex().equals("#ff69b4");
assert loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)");
assert loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)");
  
assert login_button_background_colour.hex == '#ff69b4'
assert login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)'
assert login_button_background_colour.rgb == 'rgb(255, 105, 180)'
  
// This feature is not implemented - Help us by sending a pr to implement this feature
  
assert(login_button_background_colour.hex == '#ff69b4')
assert(login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)')
assert(login_button_background_colour.rgb == 'rgb(255, 105, 180)')
  
// This feature is not implemented - Help us by sending a pr to implement this feature
  
assert(loginButtonBackgroundColour.asHex().equals("#ff69b4"))
assert(loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)"))
assert(loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)"))
  

色はもはや問題ではありません。

9.4 - 選択要素の操作

選択リストには、他の要素と比較して特別な動作があります。

The Select object will now give you a series of commands that allow you to interact with a <select> element.

If you are using Java or .NET make sure that you’ve properly required the support package in your code. See the full code from GitHub in any of the examples below.

Note that this class only works for HTML elements select and option. It is possible to design drop-downs with JavaScript overlays using div or li, and this class will not work for those.

Types

Select methods may behave differently depending on which type of <select> element is being worked with.

Single select

This is the standard drop-down object where one and only one option may be selected.

<select name="selectomatic">
    <option selected="selected" id="non_multi_option" value="one">One</option>
    <option value="two">Two</option>
    <option value="four">Four</option>
    <option value="still learning how to count, apparently">Still learning how to count, apparently</option>
</select>

Multiple select

This select list allows selecting and deselecting more than one option at a time. This only applies to <select> elements with the multiple attribute.

<select name="multi" id="multi" multiple="multiple">
    <option selected="selected" value="eggs">Eggs</option>
    <option value="ham">Ham</option>
    <option selected="selected" value="sausages">Sausages</option>
    <option value="onion gravy">Onion gravy</option>
</select>

Create class

First locate a <select> element, then use it to initialize a Select object. Note that as of Selenium 4.5, you can’t create a Select object if the <select> element is disabled.

        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);
    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

  it('Select an option', async function () {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)

List options

There are two lists that can be obtained:

All options

Get a list of all options in the <select> element:

        List<WebElement> optionList = select.getOptions();
    option_list = select.options
            IList<IWebElement> optionList = select.Options;
    option_list = select.options
    val optionList = select.getOptions()

Selected options

Get a list of selected options in the <select> element. For a standard select list this will only be a list with one element, for a multiple select list it can contain zero or many elements.

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
    selected_option_list = select.all_selected_options
            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
    selected_option_list = select.selected_options
    val selectedOptionList = select.getAllSelectedOptions()

Select option

The Select class provides three ways to select an option. Note that for multiple select type Select lists, you can repeat these methods for each element you want to select.

Text

Select the option based on its visible text

        select.selectByVisibleText("Four");
    select.select_by_visible_text('Four')
            select.SelectByText("Four");
    select.select_by(:text, 'Four')
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))
    select.selectByVisibleText("Four")

Value

Select the option based on its value attribute

        select.selectByValue("two");
    select.select_by_value('two')
            select.SelectByValue("two");
    select.select_by(:value, 'two')
    assert.equal(true, await fourElement.isSelected())
    select.selectByValue("two")

Index

Select the option based on its position in the list

        select.selectByIndex(3);
    select.select_by_index(3)
            select.SelectByIndex(3);
    select.select_by(:index, 3)
    assert.equal(true, await twoElement.isSelected())
    select.selectByIndex(3)

Disabled options

Selenium v4.5

Options with a disabled attribute may not be selected.

    <select name="single_disabled">
      <option id="sinlge_disabled_1" value="enabled">Enabled</option>
      <option id="sinlge_disabled_2" value="disabled" disabled="disabled">Disabled</option>
    </select>
        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }

De-select option

Only multiple select type select lists can have options de-selected. You can repeat these methods for each element you want to select.

        select.deselectByValue("eggs");
    select.deselect_by_value('eggs')
            select.DeselectByValue("eggs");
    select.deselect_by(:value, 'eggs')
    assert.equal(true, await gravyElement.isSelected())
    select.deselectByValue("eggs")

9.5 - ThreadGuard

このクラスは、Javaバインディングでのみ使用可能です。

ThreadGuardは、ドライバーが、それを作成した同じスレッドからのみ呼び出されることを確認します。 特に並行してテストを実行する場合のスレッドの問題は、不可解でエラーの診断が難しい場合があります。 このラッパーを使用すると、このカテゴリのエラーが防止され、発生時に例外が発生します。

次の例は、スレッドの衝突をシミュレートします。

public class DriverClash {
  //thread main (id 1) created this driver
  private WebDriver protectedDriver = ThreadGuard.protect(new ChromeDriver());

  static {
    System.setProperty("webdriver.chrome.driver", "<Set path to your Chromedriver>");
  }

  //Thread-1 (id 24) is calling the same driver causing the clash to happen
  Runnable r1 = () -> {protectedDriver.get("https://selenium.dev");};
  Thread thr1 = new Thread(r1);

  void runThreads(){
    thr1.start();
  }

  public static void main(String[] args) {
    new DriverClash().runThreads();
  }
}

結果は以下のとおりです。

Exception in thread "Thread-1" org.openqa.selenium.WebDriverException:
Thread safety error; this instance of WebDriver was constructed
on thread main (id 1)and is being accessed by thread Thread-1 (id 24)
This is not permitted and *will* cause undefined behaviour

下記例を参照してください。

  • protectedDriver はメインスレッドで作成されます
  • Java Runnableを使用して新しいプロセスを起動し、新しいスレッドを使用してプロセスを実行します
  • メインスレッドのメモリにprotectedDriverがないため、両方のスレッドが衝突します。
  • ThreadGuard.protectは例外をスローします。

注意:

これは、並列実行時にドライバーを管理するために ThreadLocalを使用する必要性を置き換えるものではありません。

10 - トラブルシューティングの支援

WebDriverの問題を管理する方法。

It is not always obvious the root cause of errors in Selenium.

  1. The most common Selenium-related error is a result of poor synchronization. Read about Waiting Strategies. If you aren’t sure if it is a synchronization strategy you can try temporarily hard coding a large sleep where you see the issue, and you’ll know if adding an explicit wait can help.

  2. Note that many errors that get reported to the project are actually caused by issues in the underlying drivers that Selenium sends the commands to. You can rule out a driver problem by executing the command in multiple browsers.

  3. If you have questions about how to do things, check out the Support options for ways get assistance.

  4. If you think you’ve found a problem with Selenium code, go ahead and file a Bug Report on GitHub.

10.1 - Understanding Common Errors

How to solve various problems in your Selenium code.

InvalidSelectorException

CSS and XPath Selectors are sometimes difficult to get correct.

Likely Cause

The CSS or XPath selector you are trying to use has invalid characters or an invalid query.

Possible Solutions

Run your selector through a validator service:

Or use a browser extension to get a known good value:

NoSuchElementException

The element can not be found at the exact moment you attempted to locate it.

Likely Cause

  • You are looking for the element in the wrong place (perhaps a previous action was unsuccessful).
  • You are looking for the element at the wrong time (the element has not shown up in the DOM, yet)
  • The locator has changed since you wrote the code

Possible Solutions

  • Make sure you are on the page you expect to be on, and that previous actions in your code completed correctly
  • Make sure you are using a proper Waiting Strategy
  • Update the locator with the browser’s devtools console or use a browser extension like:

StaleElementReferenceException

An element goes stale when it was previously located, but can not be currently accessed. Elements do not get relocated automatically; the driver creates a reference ID for the element and has a particular place it expects to find it in the DOM. If it can not find the element in the current DOM, any action using that element will result in this exception.

Likely Cause

This can happen when:

  • You have refreshed the page, or the DOM of the page has dynamically changed.
  • You have navigated to a different page.
  • You have switched to another window or into or out of a frame or iframe.

Possible Solutions

The DOM has changed

When the page is refreshed or items on the page have moved around, there is still an element with the desired locator on the page, it is just no longer accessible by the element object being used, and the element must be relocated before it can be used again. This is often done in one of two ways:

  • Always relocate the element every time you go to use it. The likelihood of the element going stale in the microseconds between locating and using the element is small, though possible. The downside is that this is not the most efficient approach, especially when running on a remote grid.

  • Wrap the Web Element with another object that stores the locator, and caches the located Selenium element. When taking actions with this wrapped object, you can attempt to use the cached object if previously located, and if it is stale, exception can be caught, the element relocated with the stored locator, and the method re-tried. This is more efficient, but it can cause problems if the locator you’re using references a different element (and not the one you want) after the page has changed.

The Context has changed

Element objects are stored for a given context, so if you move to a different context — like a different window or a different frame or iframe — the element reference will still be valid, but will be temporarily inaccessible. In this scenario, it won’t help to relocate the element, because it doesn’t exist in the current context. To fix this, you need to make sure to switch back to the correct context before using the element.

The Page has changed

This scenario is when you haven’t just changed contexts, you have navigated to another page and have destroyed the context in which the element was located. You can’t just relocate it from the current context, and you can’t switch back to an active context where it is valid. If this is the reason for your error, you must both navigate back to the correct location and relocate it.

ElementClickInterceptedException

This exception occurs when Selenium tries to click an element, but the click would instead be received by a different element. Before Selenium will click an element, it checks if the element is visible, unobscured by any other elements, and enabled - if the element is obscured, it will raise this exception.

Likely Cause

UI Elements Overlapping

Elements on the UI are typically placed next to each other, but occasionally elements may overlap. For example, a navbar always staying at the top of your window as you scroll a page. If that navbar happens to be covering an element we are trying to click, Selenium might believe it to be visible and enabled, but when you try to click it will throw this exception. Pop-ups and Modals are also common offenders here.

Animations

Elements with animations have the potential to cause this exception as well - it is recommended to wait for animations to cease before attempting to click an element.

Possible Solutions

Use Explicit Waits

Explicit Waits will likely be your best friend in these instances. A great way is to use ExpectedCondition.ToBeClickable() with WebDriverWait to wait until the right moment.

Scroll the Element into View

In instances where the element is out of view, but Selenium still registers the element as visible (e.g. navbars overlapping a section at the top of your screen), you can use the WebDriver.executeScript() method to execute a javascript function to scroll (e.g. WebDriver.executeScript('window.scrollBy(0,-250)')) or you can utilize the Actions class with Actions.moveToElement(element).

InvalidSessionIdException

Sometimes the session you’re trying to access is different than what’s currently available

Likely Cause

This usually occurs when the session has been deleted (e.g. driver.quit()) or if the session has changed, like when the last tab/browser has closed (e.g. driver.close())

Possible Solutions

Check your script for instances of driver.close() and driver.quit(), and any other possible causes of closed tabs/browsers. It could be that you are locating an element before you should/can.

10.1.1 - Unable to Locate Driver Error

Troubleshooting missing path to driver executable.

Historically, this is the most common error beginning Selenium users get when trying to run code for the first time:

The path to the driver executable must be set by the webdriver.chrome.driver system property; for more information, see https://chromedriver.chromium.org/. The latest version can be downloaded from https://chromedriver.chromium.org/downloads
The executable chromedriver needs to be available in the path.
The file geckodriver does not exist. The driver can be downloaded at https://github.com/mozilla/geckodriver/releases"
Unable to locate the chromedriver executable;

Likely cause

Through WebDriver, Selenium supports all major browsers. In order to drive the requested browser, Selenium needs to send commands to it via an executable driver. This error means the necessary driver could not be found by any of the means Selenium attempts to use.

Possible solutions

There are several ways to ensure Selenium gets the driver it needs.

Use the latest version of Selenium

As of Selenium 4.6, Selenium downloads the correct driver for you. You shouldn’t need to do anything. If you are using the latest version of Selenium and you are getting an error, please turn on logging and file a bug report with that information.

If you want to read more information about how Selenium manages driver downloads for you, you can read about the Selenium Manager.

Use the PATH environment variable

This option first requires manually downloading the driver.

This is a flexible option to change location of drivers without having to update your code, and will work on multiple machines without requiring that each machine put the drivers in the same place.

You can either place the drivers in a directory that is already listed in PATH, or you can place them in a directory and add it to PATH.

To see what directories are already on PATH, open a Terminal and execute:

echo $PATH

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

echo 'export PATH=$PATH:/path/to/driver' >> ~/.bash_profile
source ~/.bash_profile

You can test if it has been added correctly by checking the version of the driver:

chromedriver --version

To see what directories are already on PATH, open a Terminal and execute:

echo $PATH

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

echo 'export PATH=$PATH:/path/to/driver' >> ~/.zshenv
source ~/.zshenv

You can test if it has been added correctly by checking the version of the driver:

chromedriver --version

To see what directories are already on PATH, open a Command Prompt and execute:

echo %PATH%

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

setx PATH "%PATH%;C:\WebDriver\bin"

You can test if it has been added correctly by checking the version of the driver:

chromedriver.exe --version

Specify the location of the driver

If you cannot upgrade to the latest version of Selenium, you do not want Selenium to download drivers for you, and you can’t figure out the environment variables, you can specify the location of the driver in the Service object.

You first need to download the desired driver, then create an instance of the applicable Service class and set the path.

Specifying the location in the code itself has the advantage of not needing to figure out Environment Variables on your system, but has the drawback of making the code less flexible.

Driver management libraries

Before Selenium managed drivers itself, other projects were created to do so for you.

If you can’t use Selenium Manager because you are using an older version of Selenium (please upgrade), or need an advanced feature not yet implemented by Selenium Manager, you might try one of these tools to keep your drivers automatically updated:

Download the driver

ブラウザーサポートするOS維持管理機関ダウンロードイシュートラッカー
Chromium/ChromeWindows/macOS/LinuxGoogleDownloadsIssues
FirefoxWindows/macOS/LinuxMozillaDownloadsIssues
EdgeWindows/macOS/LinuxMicrosoftDownloadsIssues
Internet ExplorerWindowsSelenium ProjectDownloadsIssues
SafarimacOS High Sierra and newerAppleBuilt inIssues

Note: The Opera driver no longer works with the latest functionality of Selenium and is currently officially unsupported.

10.2 - Logging Selenium commands

Getting information about Selenium execution.

Turning on logging is a valuable way to get extra information that might help you determine why you might be having a problem.

Getting a logger

Java logs are typically created per class. You can work with the default logger to work with all loggers. To filter out specific classes, see Filtering

Get the root logger:

        Logger logger = Logger.getLogger("");

Java Logging is not exactly straightforward, and if you are just looking for an easy way to look at the important Selenium logs, take a look at the Selenium Logger project

Python logs are typically created per module. You can match all submodules by referencing the top level module. So to work with all loggers in selenium module, you can do this:

    logger = logging.getLogger('selenium')

.NET logger is managed with a static class, so all access to logging is managed simply by referencing Log from the OpenQA.Selenium.Internal.Logging namespace.

If you want to see as much debugging as possible in all the classes, you can turn on debugging globally in Ruby by setting $DEBUG = true.

For more fine-tuned control, Ruby Selenium created its own Logger class to wrap the default Logger class. This implementation provides some interesting additional features. Obtain the logger directly from the #loggerclass method on the Selenium::WebDriver module:

    logger = Selenium::WebDriver.logger
const logging = require('selenium-webdriver/lib/logging')
logger = logging.getLogger('webdriver')

Logger level

Logger level helps to filter out logs based on their severity.

Java has 7 logger levels: SEVERE, WARNING, INFO, CONFIG, FINE, FINER, and FINEST. The default is INFO.

You have to change both the level of the logger and the level of the handlers on the root logger:

        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

Python has 6 logger levels: CRITICAL, ERROR, WARNING, INFO, DEBUG, and NOTSET. The default is WARNING

To change the level of the logger:

    logger.setLevel(logging.DEBUG)

Things get complicated when you use PyTest, though. By default, PyTest hides logging unless the test fails. You need to set 3 things to get PyTest to display logs on passing tests.

To always output logs with PyTest you need to run with additional arguments. First, -s to prevent PyTest from capturing the console. Second, -p no:logging, which allows you to override the default PyTest logging settings so logs can be displayed regardless of errors.

So you need to set these flags in your IDE, or run PyTest on command line like:

pytest -s -p no:logging

Finally, since you turned off logging in the arguments above, you now need to add configuration to turn it back on:

logging.basicConfig(level=logging.WARN)

.NET has 6 logger levels: Error, Warn, Info, Debug, Trace and None. The default level is Info.

To change the level of the logger:

            Log.SetLevel(LogEventLevel.Trace);

Ruby logger has 5 logger levels: :debug, :info, :warn, :error, :fatal. As of Selenium v4.9.1, The default is :info.

To change the level of the logger:

    logger.level = :debug

JavaScript has 9 logger levels: OFF, SEVERE, WARNING, INFO, DEBUG, FINE, FINER, FINEST, ALL. The default is OFF.

To change the level of the logger:

logger.setLevel(logging.Level.INFO)

Actionable items

Things are logged as warnings if they are something the user needs to take action on. This is often used for deprecations. For various reasons, Selenium project does not follow standard Semantic Versioning practices. Our policy is to mark things as deprecated for 3 releases and then remove them, so deprecations may be logged as warnings.

Java logs actionable content at logger level WARN

Example:

May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
WARNING: this is a warning

Python logs actionable content at logger level — WARNING Details about deprecations are logged at this level.

Example:

WARNING  selenium:test_logging.py:23 this is a warning

.NET logs actionable content at logger level Warn.

Example:

11:04:40.986 WARN LoggingTest: this is a warning

Ruby logs actionable content at logger level — :warn. Details about deprecations are logged at this level.

For example:

2023-05-08 20:53:13 WARN Selenium [:example_id] this is a warning 

Because these items can get annoying, we’ve provided an easy way to turn them off, see filtering section below.

Useful information

This is the default level where Selenium logs things that users should be aware of but do not need to take actions on. This might reference a new method or direct users to more information about something

Java logs useful information at logger level INFO

Example:

May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
INFO: this is useful information

Python logs useful information at logger level — INFO

Example:

INFO     selenium:test_logging.py:22 this is useful information

.NET logs useful information at logger level Info.

Example:

11:04:40.986 INFO LoggingTest: this is useful information

Ruby logs useful information at logger level — :info.

Example:

2023-05-08 20:53:13 INFO Selenium [:example_id] this is useful information 

Logs useful information at level: INFO

Debugging Details

The debug log level is used for information that may be needed for diagnosing issues and troubleshooting problems.

Java logs most debug content at logger level FINE

Example:

May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
FINE: this is detailed debug information

Python logs debugging details at logger level — DEBUG

Example:

DEBUG    selenium:test_logging.py:24 this is detailed debug information

.NET logs most debug content at logger level Debug.

Example:

11:04:40.986 DEBUG LoggingTest: this is detailed debug information

Ruby only provides one level for debugging, so all details are at logger level — :debug.

Example:

2023-05-08 20:53:13 DEBUG Selenium [:example_id] this is detailed debug information 

Logs debugging details at level: FINER and FINEST

Logger output

Logs can be displayed in the console or stored in a file. Different languages have different defaults.

By default all logs are sent to System.err. To direct output to a file, you need to add a handler:

        Handler handler = new FileHandler("selenium.xml");
        logger.addHandler(handler);

By default all logs are sent to sys.stderr. To direct output somewhere else, you need to add a handler with either a StreamHandler or a FileHandler:

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

By default all logs are sent to System.Console.Error output. To direct output somewhere else, you need to add a handler with a FileLogHandler:

            Log.Handlers.Add(new FileLogHandler(filePath));

By default, logs are sent to the console in stdout.
To store the logs in a file:

    logger.output = file_name

JavaScript does not currently support sending output to a file.

To send logs to console output:

logging.installConsoleHandler()

Logger filtering

Java logging is managed on a per class level, so instead of using the root logger (Logger.getLogger("")), set the level you want to use on a per-class basis:

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);
Because logging is managed by module, instead of working with just "selenium", you can specify different levels for different modules:
    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

.NET logging is managed on a per class level, set the level you want to use on a per-class basis:

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

Ruby’s logger allows you to opt in (“allow”) or opt out (“ignore”) of log messages based on their IDs. Everything that Selenium logs includes an ID. You can also turn on or off all deprecation notices by using :deprecations.

These methods accept one or more symbols or an array of symbols:

    logger.ignore(:jwp_caps, :logger_info)

or

    logger.allow(%i[selenium_manager example_id])

10.3 - Selenium4にアップグレードする方法

Selenium 4に興味がありますか? 最新リリースへのアップグレードに役立つこのガイドを確認してください。

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

これが、Selenium4にアップグレードするために実行する手順です。

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

注:Selenium 3.xバージョンの開発中に、W3CWebDriver標準のサポートが実装されました。 この新しいプロトコルと従来のJSONワイヤープロトコルの両方がサポートされました。 バージョン3.11の前後で、SeleniumコードはレベルW3C1仕様に準拠するようになりました。 Selenium 3の最新バージョンのW3C準拠のコードは、Selenium4で期待どおりに機能します。

テストコードの準備

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

Capabilities

テスト機能がW3Cに準拠するように構成されていない場合、セッションが開始されない可能性があります。 W3CWebDriverの標準機能のリストは次のとおりです。

  • browserName
  • browserVersion (version に変更)
  • platformName (platform に変更)
  • acceptInsecureCerts
  • pageLoadStrategy
  • proxy
  • timeouts
  • unhandledPromptBehavior

標準Capabilitiesの最新リストは、 W3C WebDriver にあります。

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

Before

Move Code

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)

After

Move Code

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 * で単一の要素を検索する。

Before

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

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 * で複数の要素を検索する。

Before

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

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"));

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

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

Java

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

Maven

Before

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

<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

Before

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()
}
After

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 cleanbuild を実行できます。

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

C#

C#でSelenium4の更新を取得する場所は NuGet です。 Selenium.WebDriver パッケージの下で、最新バージョンに更新するための手順を入手できます。 Visual Studio内では、NuGetパッケージマネージャーを使用して次の操作を実行できます。

PM> Install-Package Selenium.WebDriver -Version 4.4.0

Python

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

pip install selenium==4.4.3

Ruby

Selenium 4の更新の詳細は、RubyGemsのselenium-webdriverで確認できます。 最新バージョンをインストールするには、次のコマンドを実行できます。

gem install selenium-webdriver

Gemfileには下記のように追加します。

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

JavaScript

selenium-webdriverパッケージは、Nodeパッケージマネージャーのnpmjsにあります。 Selenium4はhereにあります。 これをインストールするには、次のいずれかを実行します。

npm install selenium-webdriver

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

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

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

これは、Selenium4にアップグレードした後に発生する可能性のある非推奨メッセージを克服するのに役立つ一連のコード例です。

Java

待機とタイムアウト

タイムアウトで受信するパラメーターは、期待値 (long time, TimeUnit unit) から期待値 (Duration duration) に替わりました。

Before

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

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) に替わりました。

Before

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);
After

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);

マージCapabilitiesは、もはや呼び出し元のオブジェクトを変更しなくなりました

以前は、別のCapabilitiesセットを別のセットにマージすることが可能であり、呼び出し元のオブジェクトを変更していました。 今は、ここで、マージ操作の結果を割り当てる必要があります。

Before

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.
After

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 インターフェースを優先して非推奨になります。

Before

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

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

C#

AddAdditionalCapability は非推奨になりました

その代わりに、 AddAdditionalOption をお勧めします。 これを示す例を次に示します。

Before

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

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

Python

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

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

Before

from selenium import webdriver
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(
    executable_path=CHROMEDRIVER_PATH, 
    options=options
)
After

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 に投稿されました