MeWrite Docs

Playwright: Locator resolved to multiple elements

Playwrightでロケーターが複数の要素にマッチした場合のエラー

概要

Playwrightでロケーターが複数の要素にマッチし、単一の要素を期待するアクションが失敗した場合のエラーです。

エラーメッセージ

Error: locator.click: Error: strict mode violation: locator('button') resolved to 3 elements
Error: locator.fill: Error: strict mode violation: getByRole('textbox') resolved to 2 elements

解決策

1. より具体的なロケーターを使用

1
2
3
4
5
6
7
8
// NG: 複数の要素にマッチ
await page.locator('button').click()

// OK: テキストで絞り込み
await page.getByRole('button', { name: 'Submit' }).click()

// OK: ラベルで特定
await page.getByLabel('Email').fill('test@example.com')

2. getByRole を優先的に使用

1
2
3
4
5
// 推奨: セマンティックなロケーター
await page.getByRole('button', { name: 'Login' }).click()
await page.getByRole('textbox', { name: 'Password' }).fill('secret')
await page.getByRole('link', { name: 'Sign up' }).click()
await page.getByRole('checkbox', { name: 'Remember me' }).check()

3. 親要素で絞り込み

1
2
3
// 特定のセクション内の要素
const loginForm = page.locator('form[data-testid="login-form"]')
await loginForm.getByRole('button', { name: 'Submit' }).click()

4. nth() で順番を指定

1
2
3
4
5
6
7
8
// 複数あるうちの最初の要素
await page.locator('button').first().click()

// 2番目の要素
await page.locator('button').nth(1).click()

// 最後の要素
await page.locator('button').last().click()

5. filter() で絞り込み

1
2
3
4
5
6
7
8
9
// テキストでフィルター
await page.locator('button').filter({ hasText: 'Submit' }).click()

// 子要素でフィルター
await page
  .locator('div.card')
  .filter({ has: page.locator('h2', { hasText: 'Premium' }) })
  .getByRole('button')
  .click()

6. data-testid を使用

1
2
<!-- HTML -->
<button data-testid="submit-button">Submit</button>
1
2
// テスト
await page.getByTestId('submit-button').click()

7. 複数要素を意図的に扱う

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// すべての要素を取得
const buttons = page.locator('button')

// 要素数を確認
await expect(buttons).toHaveCount(3)

// すべての要素に対して操作
const count = await buttons.count()
for (let i = 0; i < count; i++) {
  await buttons.nth(i).click()
}

// すべての要素のテキストを取得
const texts = await buttons.allTextContents()

8. within でスコープを限定

1
2
3
4
5
6
7
8
9
// 特定のコンテナ内で検索
const modal = page.locator('[role="dialog"]')
await modal.getByRole('button', { name: 'Close' }).click()

// フォーム内の要素
const form = page.locator('form')
await form.getByLabel('Username').fill('john')
await form.getByLabel('Password').fill('secret')
await form.getByRole('button', { name: 'Login' }).click()

9. 可視要素のみを対象

1
2
3
4
5
// 表示されている要素のみ
await page.locator('button:visible').click()

// または
await page.locator('button').filter({ visible: true }).click()

10. デバッグ方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// ロケーターがマッチする要素数を確認
const count = await page.locator('button').count()
console.log(`Found ${count} buttons`)

// 各要素の情報を表示
const buttons = page.locator('button')
for (let i = 0; i < await buttons.count(); i++) {
  console.log(await buttons.nth(i).textContent())
}

// Playwrightインスペクターを起動
await page.pause()

Playwright設定

1
2
3
4
5
6
7
// playwright.config.ts
export default defineConfig({
  use: {
    // strict modeを無効化(非推奨)
    // strictModeを無効にするとfirst()が自動適用される
  },
})

関連エラー

関連エラー

Playwright の他のエラー

最終更新: 2025-12-19