例:動的 GWT ツリーの展開アイコンの検索

Google Widget Toolkit (GWT) は、とても人気のある強力なツールキットですが、テストしにくいです。動的ツリー コントロールは、とても一般的に使用されている GWT の UI コントロールです。ツリーを展開するには、展開 アイコン要素を識別する必要があります。

動的 GWT ツリーのサンプルは、http://samples.gwtproject.org/samples/Showcase/Showcase.html#!CwTree にあります。

Silk4J が生成するデフォルトのロケーターは次のようになります。
/BrowserApplication//BrowserWindow//DIV[@id='gwt-debug-cwTree-dynamicTree-root-child0']/DIV/DIV[1]//IMG[@border='0']
次の理由で、このデフォルトのロケーターは、Item 0.0展開 アイコンを識別するロケーターとしては信頼できるものではありません。
  • ロケーターは複雑で、複数の階層から構成されています。AJAX で動的に DOM 構造が少し変わるとロケーターは使えなくなります。
  • ロケーターには、階層のいくつかのコントロールにインデックスが含まれています。インデックス ベースのロケーターは、その出現番号によってコントロールを検索するため、一般にもろく、たとえば、ツリーの 6 番目の展開アイコンを見つけるなど、うまく特定のコントロールを定義できません。このルールの例外は、たとえばグリッドの 6 番目のデータ行など、識別するさまざまなデータ セットを表すためにインデックスが使用される場合です。

多くの場合、より良いロケーターを見つける良い方法は、検索する要素の同列要素を探し出すことです。より良いロケーターの同列要素を見つけると、XPath は、これらの同列要素を識別してロケーターを構成することができます。この場合、ツリー項目 Item 0.0 は、展開 アイコンよりも良いロケーターです。ツリー項目 Item 0.0 のロケーターは、コントロールの @textContents プロパティを使用するため、安定した単純なロケーターです。

デフォルトでは、Silk4J@id プロパティを使用しますが、GWT では @id には ='gwt-uid-<nnn>' のような値 (ここで、<nnn> は同じ要素でも呼出し毎に頻繁に変わります) が含まれるため、たいてい安定したプロパティではありません。

@textContents プロパティを @id の代わりに使用してロケーターを手動で変更できます。

元のロケーター:
/BrowserApplication//BrowserWindow//DIV[@id='gwt-uid-109']
別のロケーター:
/BrowserApplication//BrowserWindow//DIV[@textContents='Item 0.0']

もしくは、@id='gwt-uid-<nnn>' を使用しないように Silk4J を設定できます。この場合、Silk4J は自動的に安定したロケーターを記録します。たとえば、@id プロパティで使用されるテキスト パターンをロケーター属性値除外リストに追加ます。この場合、gwt-uid* を除外リストに追加します。

要素の階層を調べると、Item 0.0 コントロールと 展開 アイコン コントロールは、共通のルートノードとして DomTableRow コントロールを持つことが分かります。

展開 アイコンの安定したロケーターを作成するには、次のロケーターを使って Item 0.0 をまず検索する必要があります。
/BrowserApplication//BrowserWindow//DIV[@textContent='Item 0.0']
そして、要素の階層を 2 レベル上がって DomTableRow 要素まで移動します。これは、XPath では、ロケーターに /../.. を追加して表現します。最後に、DomTableRow から 展開 アイコンを検索します。展開 アイコンは、サブツリー内では唯一の IMG コントロールであるので、容易に検索できます。これは、XPath では、ロケーターに //IMG を追加して表現します。展開 アイコンの最終的な安定したロケーターは次のようになります。
/BrowserApplication//BrowserWindow//DIV[@textContent='Item 0.0']/../..//IMG
XPath の ancestor 軸を使うと、より簡単に 展開 アイコンを指定できます。
/BrowserApplication//BrowserWindow//DIV[@textContent='Item 0.0']/ancestor::tr//IMG