🛠️ Selenium ポータル

HTML+CSS+JS+PHP / 単一ファイル

ブラウザ自動操作の定番ツール Selenium を、現場で使える視点で丸ごと整理。待機・要素探索・並列実行・CI 連携などのベストプラクティスを、言語別コード付きで収録。

このページは 500 エラー対策済(PHP ヘッダーは冒頭のみ送出)。BOM なし UTF-8 で保存してください。

Seleniumとは

Selenium は、実ブラウザ(Chrome, Firefox, Edge, Safari など)をドライバ経由で操作し、UI テストや業務オペレーションの自動化を行うためのオープンソース群(WebDriver プロトコル/クライアント/サーバ)です。人のクリックや入力に近い再現性と、主要言語に対応した SDK が特徴です。

概要

構成要素

  • WebDriver:ブラウザ自動操作の標準プロトコル
  • Client(言語バインディング):Python/Java などの SDK
  • Driver Binary:chromedriver/geckodriver 等(新 Chrome は内蔵)

基本フロー

  1. ドライバ起動(ヘッドレス可)
  2. URL を開く / 要素探索 / 操作
  3. 明示的ウェイトで安定化
  4. アサーション / スクショ保存 / 終了

よくある落とし穴

  • 暗黙的ウェイトだけに依存しフレークが増える
  • 不安定な XPath で brittle なテストに
  • 定位できない Shadow DOM / iframe の扱い漏れ

基本

セットアップから要素探索・ウェイト・スクショまで、最小限のパターン。

Python(推奨の最小構成)

# pip install selenium webdriver-manager
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

opt = Options()
opt.add_argument('--headless=new')  # 画面不要なら
with webdriver.Chrome(options=opt) as driver:
    driver.get('https://example.com')
    # 明示的ウェイト:id="login" が出るまで最大10秒待つ
    wait = WebDriverWait(driver, 10)
    btn = wait.until(EC.element_to_be_clickable((By.ID, 'login')))
    btn.click()
    # スクショ
    driver.save_screenshot('shot.png')

Java

// Maven: org.seleniumhq.selenium:selenium-java
WebDriver driver = new ChromeDriver(new ChromeOptions().addArguments("--headless=new"));
driver.get("https://example.com");
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement e = wait.until(ExpectedConditions.elementToBeClickable(By.id("login")));
e.click();
driver.quit();

JavaScript (Node)

// npm i selenium-webdriver
const {Builder, By, until} = require('selenium-webdriver');
(async () => {
  const driver = await new Builder().forBrowser('chrome').build();
  try {
    await driver.get('https://example.com');
    const el = await driver.wait(until.elementLocated(By.id('login')), 10000);
    await el.click();
  } finally { await driver.quit(); }
})();

C#

// dotnet add package Selenium.WebDriver
using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Support.UI;
var opt = new ChromeOptions(); opt.AddArgument("--headless=new");
using var driver = new ChromeDriver(opt);
driver.Navigate().GoToUrl("https://example.com");
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(d => d.FindElement(By.Id("login"))).Click();

PHP

facebook/php-webdriver を利用(composer で php-webdriver/webdriver)。

// composer require php-webdriver/webdriver
use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\WebDriverBy;

$opt = new ChromeOptions();
$opt->addArguments(['--headless=new']);
$cap = DesiredCapabilities::chrome();
$cap->setCapability(ChromeOptions::CAPABILITY, $opt);
$driver = RemoteWebDriver::create('http://localhost:9515', $cap); // chromedriver 起動前提
$driver->get('https://example.com');
$driver->findElement(WebDriverBy::id('login'))->click();
$driver->quit();
Chrome 124+ では Chrome for Testing が標準化。従来の個別ドライバ配布から内蔵化の流れ。CI では固定バージョンを使い、再現性を担保しましょう。

基礎

要素探索の優先度

  1. 安定属性(data-testid, data-qa 等)
  2. CSS セレクタ(#id, .class, [name=], :has() は未対応)
  3. XPath(最後の手段。構造に依存しがち)

ウェイト戦略

  • 明示的 Wait(要素出現/クリック可まで)を基本に
  • 暗黙 Wait は短め(0〜2s)で初期化にのみ
  • ポーリング間隔とタイムアウトをユースケース別に調整

iframe / Shadow DOM

# iframe
frame = wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, 'iframe[name="pay"]')))
# Shadow root
host = driver.find_element(By.CSS_SELECTOR, '#shadow-host')
shadow_root = host.shadow_root
btn = shadow_root.find_element(By.CSS_SELECTOR, 'button.primary')

応用

ログイン/2FA の扱い

  • テスト用 ID を発行し、本番アカウントとは分離
  • メール/SMS 2FA は テストバイパス を用意
  • SSO(SAML/OIDC)はスタブ環境で検証

ダウンロード

from selenium.webdriver.chrome.options import Options
opt = Options(); opt.add_experimental_option('prefs', {
  'download.default_directory': '/tmp/dl',
  'download.prompt_for_download': False,
  'safebrowsing.enabled': True,
})

ファイルアップロード

driver.find_element(By.CSS_SELECTOR, 'input[type=file]').send_keys('/path/to/file.png')

並列実行

pytest-xdist / JUnit / NUnit の並列オプションでスイート短縮。テストデータの競合を避ける分離設計が鍵。

発展

Page Object Model

class LoginPage:
    def __init__(self, driver):
        self.d = driver
    def open(self):
        self.d.get('https://example.com/login')
        return self
    def login(self, user, pw):
        self.d.find_element(By.ID,'user').send_keys(user)
        self.d.find_element(By.ID,'pw').send_keys(pw)
        self.d.find_element(By.CSS_SELECTOR,'button[type=submit]').click()

CI 連携

  • Docker で selenium/standalone-chrome を利用
  • テスト失敗時のスクショ/har/console log をアーティファクト保存
  • 安定化のためネットワーク/時間に依存するテストを隔離

アクセシビリティ

重要シナリオの ARIA/コントラストを自動検査(axe-core 等)と組み合わせ、セマンティクスを担保。

最新情報

目的

主な目的は UI の正しさを担保 し、リリースの信頼性を上げること。副次的に、定型のブラウザ操作業務を自動化して人手を削減します。

仕事の現場

テスト戦略

  • 単体/結合テストで土台を固め、E2E は 要点のみ に絞る
  • テストデータ/テスト環境は毎回クリーンに
  • フレーク検知 → 自動リトライ+原因切り分け

運用

  • 失敗スクショ・ログを自動収集
  • 失敗解析テンプレ(要素未検出/タイムアウト/ネットワーク)
  • 週次で flakiness レポートを共有

自動化プログラムと比較

Playwright / Puppeteer

  • 高速で API がモダン。テスト記録/トレース が強力(特に Playwright)
  • マルチブラウザは Playwright がカバー、Puppeteer は Chrome 系中心
  • 既存 Selenium 資産が多い環境では Selenium 継続が合理的

HTTP クライアント + パーサ

  • requests + BeautifulSoup 等:速度/安定性は高いが JS 実行 UI は対象外
  • API があるなら まず API 直叩き を検討

RPA ツール

  • UiPath / Power Automate:ノーコードで社内手続きに向く
  • Web UI 中心・コード管理したいなら Selenium/Playwright が適合

知っておくといい

知識

  • DOM/CSS セレクタ/イベント伝播
  • ネットワーク/キャッシュ/同一生成元制約
  • ブラウザ別の差(ポリフィル/レンダリング)

技能

  • 安定 Locators 設計(data-* 属性の導入)
  • Page Object / テストデータ戦略
  • CI/CD 組み込み & 並列化

用語

  • Headless / Explicit Wait / Shadow DOM / Viewport
  • Har / Console log / Trace

ルール

  • テストはユーザ価値の高い シナリオ優先
  • UI 変化に強い Locator を採用(role/name 等)
  • 外部サイト自動化は規約/法令を順守

スクリーンショット+エラーハンドリング

from selenium.common.exceptions import TimeoutException
try:
    driver.get('https://example.com/dashboard')
    wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,'h1.title')))
except TimeoutException:
    driver.save_screenshot('error.png')
    raise

Network 条件の制御(Chrome)

Selenium 4 の CDP 経由でスロットリング。

from selenium.webdriver.common.devtools.v125 import network
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
# 例: 速度制限
with driver.bidi_connection() as cdp:
    cdp.session.execute(network.enable())
    cdp.session.execute(network.emulate_network_conditions(
      offline=False, latency=200, download_throughput=50*1024, upload_throughput=20*1024))

CSV に結果を書き出す

import csv
rows = [(e.text, e.get_attribute('href')) for e in driver.find_elements(By.CSS_SELECTOR,'a.item')]
with open('list.csv','w',newline='',encoding='utf-8') as f:
    writer = csv.writer(f); writer.writerow(['title','url']); writer.writerows(rows)

より具体的に:導入チェックリスト