自動テストチュートリアル

Playwright、Seleniumなどの自動テストツールを学ぼう

HTML構造の理解

HTML構造の理解

HTMLは、Webページの構造を定義するマークアップ言語です。E2Eテストでは、HTML構造を理解することが必須です。

HTMLの基本構造

すべてのHTMLページは以下の構造を持っています:

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <title>ページタイトル</title>
  </head>
  <body>
    <h1>見出し</h1>
    <p>本文</p>
  </body>
</html>

構造の説明

要素 役割
<!DOCTYPE html> HTML5であることを宣言
<html> HTML文書のルート要素
<head> メタ情報(ページタイトル、文字コードなど)
<body> 実際に表示されるコンテンツ

タグの基本

開始タグと終了タグ

<p>これは段落です</p>
│  │              │
│  └─ 内容        └─ 終了タグ
└─ 開始タグ

<br>  <!-- 終了タグがないタグもある -->

よく使うタグ

タグ 用途
<h1> ~ <h6> 見出し <h1>大見出し</h1>
<p> 段落 <p>段落のテキスト</p>
<div> ブロック要素のコンテナ <div>...</div>
<span> インライン要素のコンテナ <span>...</span>
<a> リンク <a href="/page">リンク</a>
<img> 画像 <img src="pic.jpg" alt="説明">
<button> ボタン <button>クリック</button>
<input> 入力欄 <input type="text">
<form> フォーム <form>...</form>

属性(Attributes)

タグに追加情報を付与するものです。

属性の書き方

<input type="text" id="username" class="form-control" placeholder="名前を入力">
       │           │             │                 │
       │           │             │                 └─ プレースホルダー
       │           │             └─ CSSクラス
       │           └─ ID(一意の識別子)
       └─ 入力タイプ

よく使う属性

属性 用途
id 要素の一意なID id="submit-btn"
class CSSクラス(複数可) class="btn btn-primary"
type 要素のタイプ type="submit"
href リンク先URL href="/about"
src 画像やスクリプトのURL src="image.jpg"
value 入力値 value="初期値"
placeholder プレースホルダー placeholder="入力してください"
disabled 無効化 disabled
data-* カスタムデータ data-testid="login-form"
💡 テストで重要な属性
  • id: 要素を一意に識別できる(最も確実)
  • data-testid: テスト専用の識別子
  • type: ボタンや入力欄の種類を判別
  • aria-*: アクセシビリティ属性(セマンティックなテストに有用)

階層構造(入れ子)

HTMLは階層構造でコンテンツを整理します。

<div class="container">                    <!-- 親 -->
  <header>                                  <!-- 子 -->
    <nav>                                   <!-- 孫 -->
      <ul>                                  <!-- ひ孫 -->
        <li><a href="/">ホーム</a></li>    <!-- さらに下の階層 -->
        <li><a href="/about">About</a></li>
      </ul>
    </nav>
  </header>
  <main>                                    <!-- 子 -->
    <article>                               <!-- 孫 -->
      <h1>記事タイトル</h1>
      <p>本文...</p>
    </article>
  </main>
</div>

親子関係

<ul id="menu">              <!-- 親要素 -->
  <li>項目1</li>            <!-- 子要素 -->
  <li>項目2</li>            <!-- 子要素(兄弟) -->
  <li>                      <!-- 子要素 -->
    <ul>                    <!-- 孫要素(ネストされたリスト) -->
      <li>サブ項目1</li>   <!-- ひ孫要素 -->
    </ul>
  </li>
</ul>

フォームの構造

E2Eテストでよく扱うフォームの例:

<form id="registration-form" method="post" action="/register">
  <!-- テキスト入力 -->
  <div class="form-group">
    <label for="email">メールアドレス</label>
    <input type="email" id="email" name="email" required>
  </div>

  <!-- パスワード入力 -->
  <div class="form-group">
    <label for="password">パスワード</label>
    <input type="password" id="password" name="password" required>
  </div>

  <!-- チェックボックス -->
  <div class="form-group">
    <label>
      <input type="checkbox" name="terms" value="agree">
      利用規約に同意する
    </label>
  </div>

  <!-- ラジオボタン -->
  <div class="form-group">
    <label>性別</label>
    <label><input type="radio" name="gender" value="male"> 男性</label>
    <label><input type="radio" name="gender" value="female"> 女性</label>
  </div>

  <!-- セレクトボックス -->
  <div class="form-group">
    <label for="country">国</label>
    <select id="country" name="country">
      <option value="jp">日本</option>
      <option value="us">アメリカ</option>
      <option value="uk">イギリス</option>
    </select>
  </div>

  <!-- 送信ボタン -->
  <button type="submit">登録する</button>
</form>

PlaywrightでHTML構造を扱う

階層を指定して要素を取得

// 親要素の中の子要素を取得
await page.locator('#menu li'); // ID="menu"の中のすべてのli

// 直接の子要素のみ
await page.locator('#menu > li'); // 直接の子のみ

// 特定の親の中の要素
await page.locator('form#registration-form input[type="email"]');

属性でフィルタリング

// 属性で取得
await page.locator('[data-testid="submit-button"]');
await page.locator('button[type="submit"]');
await page.locator('input[name="email"]');

// 複数の属性
await page.locator('input[type="text"][required]');

フォームの操作

test('フォーム送信', async ({ page }) => {
  await page.goto('/register');

  // テキスト入力
  await page.locator('#email').fill('user@example.com');
  await page.locator('#password').fill('password123');

  // チェックボックス
  await page.locator('input[name="terms"]').check();

  // ラジオボタン
  await page.locator('input[name="gender"][value="male"]').check();

  // セレクトボックス
  await page.locator('#country').selectOption('jp');

  // フォーム送信
  await page.locator('button[type="submit"]').click();
});

セマンティックHTML

意味のあるタグを使うことで、構造が分かりやすくなります。

<!-- 良い例(セマンティック) -->
<header>
  <nav>
    <ul>
      <li><a href="/">ホーム</a></li>
    </ul>
  </nav>
</header>
<main>
  <article>
    <h1>記事タイトル</h1>
    <p>本文</p>
  </article>
</main>
<footer>
  <p>&copy; 2024</p>
</footer>

<!-- 悪い例(div だけ) -->
<div class="header">
  <div class="nav">
    <div class="menu-item"><a href="/">ホーム</a></div>
  </div>
</div>
セマンティックタグ 用途
<header> ヘッダー部分
<nav> ナビゲーション
<main> メインコンテンツ
<article> 記事
<section> セクション
<aside> サイドバー
<footer> フッター
🎯 テストでの利点
セマンティックなHTMLは、Playwrightの getByRole() で要素を取得しやすくなります。

コメント

HTMLコメントは、コードの説明に使われます(ブラウザには表示されない)。

<!-- これはコメントです -->
<div class="container">
  <!-- メインコンテンツ開始 -->
  <p>テキスト</p>
  <!-- メインコンテンツ終了 -->
</div>

まとめ

概念 説明
タグ HTMLの要素を定義(<p>, <div> など)
属性 タグに情報を追加(id, class, type など)
階層構造 親子関係で要素を整理
セマンティック 意味のあるタグを使う(<header>, <nav> など)

次のチャプターでは、セレクタの種類と使い方を学びます。