メインコンテンツへスキップ

セレクター

WebDriver プロトコルは、要素を照会するためのいくつかのセレクターストラテジーを提供します。WebdriverIO は、要素の選択を簡単にするためにそれらを簡略化しています。要素を照会するコマンドは $ および $$ と呼ばれていますが、jQuery や Sizzle セレクターエンジンとは関係がないことに注意してください。

多くの異なるセレクターが利用可能ですが、適切な要素を見つけるための弾力性のある方法を提供するのはごくわずかです。たとえば、次のボタンの場合

<button
id="main"
class="btn btn-large"
name="submission"
role="button"
data-testid="submit"
>
Submit
</button>

次のセレクターを推奨するものと推奨しないものがあります。

セレクター推奨備考
$('button')🚨 絶対に推奨しない最悪 - 汎用的すぎて、コンテキストがない。
$('.btn.btn-large')🚨 絶対に推奨しない良くない。スタイリングに依存している。変更の影響を非常に受けやすい。
$('#main')⚠️ 控えめにまだ良い。しかし、スタイリングや JS イベントリスナーに依存している。
$(() => document.queryElement('button'))⚠️ 控えめに効果的なクエリ、記述が複雑。
$('button[name="submission"]')⚠️ 控えめにHTML セマンティクスを持つ name 属性に依存している。
$('button[data-testid="submit"]')✅ 良い追加の属性が必要で、a11y に接続されていない。
$('aria/Submit') または $('button=Submit')✅ 常に最良。ユーザーがページと対話する方法に似ています。翻訳が更新されたときにテストが失敗しないように、フロントエンドの翻訳ファイルを使用することをお勧めします。

CSS クエリセレクター

特に指定がない場合、WebdriverIO はCSS セレクターパターンを使用して要素を照会します。例:

selectors/example.js
loading...

特定のテキストを含むアンカー要素を取得するには、等号 (=) で始まるテキストを照会します。

例:

selectors/example.html
loading...

この要素は、次のように呼び出すことで照会できます

selectors/example.js
loading...

表示テキストが検索値と部分的に一致するアンカー要素を見つけるには、クエリ文字列の前に *= を使用して照会します(例:*=driver)。

上記の例の要素は、次のように呼び出すことでも照会できます

selectors/example.js
loading...

注: 1 つのセレクターに複数のセレクターストラテジーを混在させることはできません。複数の連結された要素クエリを使用して同じ目標を達成してください。例:

const elem = await $('header h1*=Welcome') // doesn't work!!!
// use instead
const elem = await $('header').$('*=driver')

特定のテキストを持つ要素

同じ手法を要素にも適用できます。さらに、クエリ内で .= または .*= を使用して、大文字と小文字を区別しないマッチングを行うことも可能です。

たとえば、「Welcome to my Page」というテキストを持つレベル 1 の見出しのクエリは次のようになります。

selectors/example.html
loading...

この要素は、次のように呼び出すことで照会できます

selectors/example.js
loading...

または、部分テキストのクエリを使用します。

selectors/example.js
loading...

idclass の名前にも同じように機能します。

selectors/example.html
loading...

この要素は、次のように呼び出すことで照会できます

selectors/example.js
loading...

注: 1 つのセレクターに複数のセレクターストラテジーを混在させることはできません。複数の連結された要素クエリを使用して同じ目標を達成してください。例:

const elem = await $('header h1*=Welcome') // doesn't work!!!
// use instead
const elem = await $('header').$('h1*=Welcome')

タグ名

特定のタグ名を持つ要素を照会するには、<tag> または <tag /> を使用します。

selectors/example.html
loading...

この要素は、次のように呼び出すことで照会できます

selectors/example.js
loading...

名前属性

特定の名前属性を持つ要素を照会するには、通常の CSS3 セレクターを使用するか、セレクターパラメーターとして [name="some-name"] のようなものを渡すことで、JSONWireProtocol から提供される名前ストラテジーを使用できます。

selectors/example.html
loading...
selectors/example.js
loading...

注: このセレクターストラテジーは非推奨であり、JSONWireProtocol プロトコルまたは Appium を使用して実行される古いブラウザーでのみ機能します。

xPath

特定のxPathを介して要素を照会することも可能です。

xPath セレクターの形式は //body/div[6]/div[1]/span[1] のようになります。

selectors/xpath.html
loading...

2 番目の段落は、次のように呼び出すことで照会できます。

selectors/example.js
loading...

xPath を使用して、DOM ツリーを上下にトラバースすることもできます。

selectors/example.js
loading...

アクセシビリティ名セレクター

アクセス可能な名前で要素を照会します。アクセス可能な名前とは、要素にフォーカスが当たったときにスクリーンリーダーによってアナウンスされるものです。アクセス可能な名前の値は、視覚的なコンテンツと非表示のテキスト代替の両方になる可能性があります。

情報

このセレクターの詳細については、リリースブログ記事をご覧ください

aria-label で取得

selectors/aria.html
loading...
selectors/example.js
loading...

aria-labelledby で取得

selectors/aria.html
loading...
selectors/example.js
loading...

コンテンツで取得

selectors/aria.html
loading...
selectors/example.js
loading...

タイトルで取得

selectors/aria.html
loading...
selectors/example.js
loading...

alt プロパティで取得

selectors/aria.html
loading...
selectors/example.js
loading...

ARIA - ロール属性

ARIA ロールに基づいて要素を照会するには、セレクターパラメーターとして [role=button] のように要素のロールを直接指定できます。

selectors/aria.html
loading...
selectors/example.js
loading...

ID 属性

ロケーターストラテジー「id」は WebDriver プロトコルではサポートされていません。ID を使用して要素を見つけるには、代わりに CSS または xPath セレクターストラテジーを使用する必要があります。

ただし、一部のドライバー(例:Appium You.i Engine Driver)は、このセレクターを依然としてサポートする場合があります。

現在サポートされている ID のセレクター構文は次のとおりです。

//css locator
const button = await $('#someid')
//xpath locator
const button = await $('//*[@id="someid"]')
//id strategy
// Note: works only in Appium or similar frameworks which supports locator strategy "ID"
const button = await $('id=resource-id/iosname')

JS 関数

JavaScript 関数を使用して、Web ネイティブ API を使用して要素を取得することもできます。もちろん、これは Web コンテキスト(例:browser、またはモバイルの Web コンテキスト)内でのみ可能です。

次の HTML 構造の場合

selectors/js.html
loading...

次のように、#elem の兄弟要素を照会できます

selectors/example.js
loading...

ディープセレクター

警告

WebdriverIO の v9 以降では、この特別なセレクターは必要ありません。WebdriverIO は、シャドウ DOM を自動的に貫通するためです。先頭の >>> を削除して、このセレクターからの移行をお勧めします。

多くのフロントエンドアプリケーションは、シャドウ DOM を持つ要素に大きく依存しています。回避策なしにシャドウ DOM 内の要素を照会することは、技術的には不可能です。shadow$ および shadow$$ は、制限があった回避策でした。ディープセレクターを使用すると、一般的なクエリコマンドを使用して、シャドウ DOM 内のすべての要素を照会できるようになりました。

次の構造を持つアプリケーションがあるとします

Chrome Example

このセレクターを使用すると、別のシャドウ DOM 内にネストされている <button /> 要素を照会できます。例:

selectors/example.js
loading...

モバイルセレクター

ハイブリッドモバイルテストでは、コマンドを実行する前に、自動化サーバーが適切なコンテキストにあることが重要です。ジェスチャーを自動化するには、ドライバーをネイティブコンテキストに設定するのが理想的です。ただし、DOM から要素を選択するには、ドライバーをプラットフォームの Webview コンテキストに設定する必要があります。その場合のみ、上記のメソッドを使用できます。

ネイティブモバイルテストの場合、コンテキスト間の切り替えは必要ありません。モバイル戦略を使用し、基盤となるデバイス自動化技術を直接使用する必要があるためです。これは、テストが要素の検索においてきめ細かい制御を必要とする場合に特に役立ちます。

Android UiAutomator

AndroidのUI Automatorフレームワークは、要素を見つけるための多くの方法を提供します。特にUI Automator APIUiSelectorクラスを使用して要素を特定できます。Appiumでは、Javaコードを文字列としてサーバーに送信し、サーバーがアプリケーションの環境で実行し、要素または要素の集合を返します。

const selector = 'new UiSelector().text("Cancel").className("android.widget.Button")'
const button = await $(`android=${selector}`)
await button.click()

Android DataMatcherとViewMatcher (Espressoのみ)

AndroidのDataMatcher戦略は、Data Matcherによって要素を見つける方法を提供します。

const menuItem = await $({
"name": "hasEntry",
"args": ["title", "ViewTitle"]
})
await menuItem.click()

同様にView Matcherも利用できます。

const menuItem = await $({
"name": "hasEntry",
"args": ["title", "ViewTitle"],
"class": "androidx.test.espresso.matcher.ViewMatchers"
})
await menuItem.click()

Android View Tag (Espressoのみ)

view tag戦略は、要素をtagで検索する便利な方法を提供します。

const elem = await $('-android viewtag:tag_identifier')
await elem.click()

iOS UIAutomation

iOSアプリケーションを自動化する場合、AppleのUI Automationフレームワークを使用して要素を見つけることができます。

このJavaScript APIには、ビューとその上のすべての要素にアクセスするためのメソッドがあります。

const selector = 'UIATarget.localTarget().frontMostApp().mainWindow().buttons()[0]'
const button = await $(`ios=${selector}`)
await button.click()

また、Appium内のiOS UI Automation内で述語検索を使用して、要素の選択をさらに絞り込むこともできます。詳細については、こちらを参照してください。

iOS XCUITest述語文字列とクラスチェーン

iOS 10以上(XCUITestドライバーを使用)では、述語文字列を使用できます。

const selector = `type == 'XCUIElementTypeSwitch' && name CONTAINS 'Allow'`
const switch = await $(`-ios predicate string:${selector}`)
await switch.click()

そして、クラスチェーンも使用できます。

const selector = '**/XCUIElementTypeCell[`name BEGINSWITH "D"`]/**/XCUIElementTypeButton'
const button = await $(`-ios class chain:${selector}`)
await button.click()

アクセシビリティID

accessibility idロケータ戦略は、UI要素の一意の識別子を読み取るように設計されています。これにより、ローカライゼーションやテキストを変更する可能性のあるその他のプロセス中に変更されないという利点があります。さらに、機能的に同じ要素が同じアクセシビリティIDを持つ場合、クロスプラットフォームテストの作成に役立ちます。

  • iOSの場合、これはAppleによってこちらで説明されているaccessibility identifierです。
  • Androidの場合、accessibility idは、こちらで説明されているように、要素のcontent-descriptionにマッピングされます。

両方のプラットフォームで、要素(または複数の要素)をaccessibility idで取得する方法は通常、最良の方法です。また、非推奨のname戦略よりも推奨される方法です。

const elem = await $('~my_accessibility_identifier')
await elem.click()

クラス名

class name戦略は、現在のビュー上のUI要素を表すstringです。

  • iOSの場合、UIAutomationクラスの完全な名前であり、テキストフィールドの場合はUIATextFieldのようにUIA-で始まります。完全なリファレンスは、こちらにあります。
  • Androidの場合、これはUI Automator クラスの完全修飾名であり、テキストフィールドの場合はandroid.widget.EditTextのようになります。完全なリファレンスは、こちらにあります。
  • Youi.tvの場合、これはYoui.tvクラスの完全な名前であり、プッシュボタン要素の場合はCYIPushButtonViewのようにCYI-で始まります。完全なリファレンスは、You.i Engine DriverのGitHubページにあります。
// iOS example
await $('UIATextField').click()
// Android example
await $('android.widget.DatePicker').click()
// Youi.tv example
await $('CYIPushButtonView').click()

チェーンセレクター

クエリでより具体的に指定したい場合は、適切な要素が見つかるまでセレクターをチェーンできます。実際のコマンドの前にelementを呼び出すと、WebdriverIOはその要素からクエリを開始します。

たとえば、次のようなDOM構造がある場合

<div class="row">
<div class="entry">
<label>Product A</label>
<button>Add to cart</button>
<button>More Information</button>
</div>
<div class="entry">
<label>Product B</label>
<button>Add to cart</button>
<button>More Information</button>
</div>
<div class="entry">
<label>Product C</label>
<button>Add to cart</button>
<button>More Information</button>
</div>
</div>

製品Bをカートに追加したい場合、CSSセレクターを使用するだけでは困難です。

セレクターチェーンを使用すると、はるかに簡単になります。目的の要素を段階的に絞り込むだけです。

await $('.row .entry:nth-child(2)').$('button*=Add').click()

Appium Image Selector

-imageロケータ戦略を使用すると、アクセスしたい要素を表す画像ファイルをAppiumに送信できます。

サポートされているファイル形式:jpg,png,gif,bmp,svg

完全なリファレンスはこちらにあります。

const elem = await $('./file/path/of/image/test.jpg')
await elem.click()

注意:Appiumがこのセレクターを使用する方法は、内部的に(アプリ)スクリーンショットを作成し、その(アプリ)スクリーンショット内で要素が見つかるかどうかを検証するために、提供された画像セレクターを使用することです。

Appiumが、取得した(アプリ)スクリーンショットのサイズを、(アプリ)画面のCSSサイズに合わせて変更する可能性があることに注意してください(これは、iPhoneだけでなく、DPRが1より大きいRetinaディスプレイを備えたMacマシンでも発生します)。これにより、提供された画像セレクターが元のスクリーンショットから取得されたものである可能性があるため、一致するものが見つからない結果になることがあります。これは、Appium Serverの設定を更新することで修正できます。設定についてはAppiumドキュメントを、詳細な説明についてはこのコメントを参照してください。

Reactセレクター

WebdriverIOは、コンポーネント名に基づいてReactコンポーネントを選択する方法を提供します。これを行うには、react$react$$の2つのコマンドから選択できます。

これらのコマンドを使用すると、React VirtualDOMからコンポーネントを選択し、単一のWebdriverIO要素または要素の配列(使用する関数に応じて)を返すことができます。

注意:コマンドreact$react$$は機能が似ていますが、react$$は一致するすべてのインスタンスをWebdriverIO要素の配列として返し、react$は最初に見つかったインスタンスを返します。

基本的な例

// index.jsx
import React from 'react'
import ReactDOM from 'react-dom'

function MyComponent() {
return (
<div>
MyComponent
</div>
)
}

function App() {
return (<MyComponent />)
}

ReactDOM.render(<App />, document.querySelector('#root'))

上記のコードでは、アプリケーション内に単純なMyComponentインスタンスがあり、Reactはそれをid="root"を持つHTML要素内でレンダリングしています。

browser.react$コマンドを使用すると、MyComponentのインスタンスを選択できます。

const myCmp = await browser.react$('MyComponent')

これで、WebdriverIO要素がmyCmp変数に格納されたため、要素コマンドを実行できます。

コンポーネントのフィルタリング

WebdriverIOが内部で使用するライブラリでは、コンポーネントのpropsおよび/またはstateで選択をフィルタリングできます。これを行うには、ブラウザコマンドに2番目の引数としてprops、3番目の引数としてstateを渡す必要があります。

// index.jsx
import React from 'react'
import ReactDOM from 'react-dom'

function MyComponent(props) {
return (
<div>
Hello { props.name || 'World' }!
</div>
)
}

function App() {
return (
<div>
<MyComponent name="WebdriverIO" />
<MyComponent />
</div>
)
}

ReactDOM.render(<App />, document.querySelector('#root'))

nameというpropがWebdriverIOであるMyComponentのインスタンスを選択する場合は、次のようにコマンドを実行できます。

const myCmp = await browser.react$('MyComponent', {
props: { name: 'WebdriverIO' }
})

stateで選択をフィルタリングする場合は、browserコマンドは次のようになります。

const myCmp = await browser.react$('MyComponent', {
state: { myState: 'some value' }
})

React.Fragmentの処理

react$コマンドを使用してReact フラグメントを選択すると、WebdriverIOはそのコンポーネントの最初の子供をコンポーネントのノードとして返します。react$$を使用すると、セレクターに一致するフラグメント内のすべてのHTMLノードを含む配列が返されます。

// index.jsx
import React from 'react'
import ReactDOM from 'react-dom'

function MyComponent() {
return (
<React.Fragment>
<div>
MyComponent
</div>
<div>
MyComponent
</div>
</React.Fragment>
)
}

function App() {
return (<MyComponent />)
}

ReactDOM.render(<App />, document.querySelector('#root'))

上記の例の場合、コマンドは次のように動作します。

await browser.react$('MyComponent') // returns the WebdriverIO Element for the first <div />
await browser.react$$('MyComponent') // returns the WebdriverIO Elements for the array [<div />, <div />]

注意:MyComponentの複数のインスタンスがあり、react$$を使用してこれらのフラグメントコンポーネントを選択すると、すべてのノードの1次元配列が返されます。つまり、3つの<MyComponent />インスタンスがある場合、6つのWebdriverIO要素の配列が返されます。

カスタムセレクターストラテジー

アプリが要素を取得するための特定の方法を必要とする場合は、custom$およびcustom$$で使用できるカスタムセレクターストラテジーを自分で定義できます。そのためには、テストの開始時、たとえばbeforeフックで、ストラテジーを一度登録します。

queryElements/customStrategy.js
loading...

次のHTMLスニペットが与えられた場合

queryElements/example.html
loading...

次のように呼び出して使用します。

queryElements/customStrategy.js
loading...

注意:これは、executeコマンドを実行できるWeb環境でのみ機能します。

ようこそ!何かお手伝いできることはありますか?

WebdriverIO AI Copilot