1

JXA を使用して iTunes からアプリをプログラムでダウンロードする必要があります。私は次のことをしました:

var its = SystemEvents.processes.byName('iTunes');
delay(3);
its.windows[0].buttons.byName('Get').click();

要素が選択されていません。ボタン [0...7] をクリックしてみましたが、どれも「取得」ボタンではありません。必要なボタンはドキュメント内にあると思いますが、JXA ドキュメントには、ボタン要素はドキュメントではなくウィンドウの子であると明確に記載されています。正しいボタンをクリックする方法についてのアイデアはありますか?

4

1 に答える 1

0

ボタンなどの「リーフ」UI 要素は、UI 要素の潜在的に複雑な階層の最下部に配置されます。これは特に iTunes の場合に当てはまります。

感覚をつかむために、無料アプリの App Store ページのボタンのオブジェクト指定子の例を次に示しますGet(このページがアクティブであることを既に確認していると仮定します)。

Application("System Events")
  .applicationProcesses.byName("iTunes")
    .windows.byName("iTunes")
      .splitterGroups.at(0)
        .scrollAreas.at(0)
          .uiElements.at(0)
            .groups.at(3)
              .buttons.at(0)

問題は、このオブジェクト指定子がページ間で異なることです。したがって、理想的には、 (ウィンドウのプロパティを介して)すべてのUI 要素にフィルターを適用して、目的のボタンを取得します。entireContents

// Get an array of all UI elements in iTunes window.
uiElems = Application("System Events").applicationProcesses['iTunes']
           .windows[0].entireContents()

// Find all buttons whose description contains 'Get'.
btns = uiElems.filter(function(el) { 
  try {
    return el.role() == 'AXButton' 
           &&
           el.description().match(/\bGet\b/)
  } catch (e) {}
})

// Click on the 1st button found.
btns[0].click()

問題は次のとおりです。最近の私のマシンでは、これには約 20 秒かかります (!)。

.whoseスタイルのフィルターの方が高速だと思いますが、上記のように例外をキャッチする必要があるため、この例ではそれを機能させることができませんでしたが、.whose組み込みの例外ハンドラーをサポートしていないようです。

サブツリー内のボタンが見つかる階層の下位レベルについて仮定する場合は、処理を大幅に高速化できます。

// Get the group UI elements in one of which the 'Get' button is located.
grps = Application("System Events").applicationProcesses['iTunes'].
        windows[0].splitterGroups[0].scrollAreas[0].uiElements[0].groups

// Loop over groups
count = grps.length
for (i = 0; i < count; ++i) {
  // In the group at hand, find all buttons whose description contains 'Get'.
  btns = grps[i].entireContents().filter(function(el) { 
    try {
      return el.role() == 'AXButton' 
             &&
             el.description().match(/\bGet\b/)
    } catch (e) {}
  })
  // Exit loop, if a 'Get' button was found.
  if (btns.length > 0) break  
}

if (btns.length == 0) {
  console.log('ERROR: No "Get" button found.')
} else {  
  // Click on the 1st button found.
  btns[0].click()
}

これは 1 秒未満で実行されます。私のマシンで。


残念ながら、UI の自動化 (GUI スクリプト) は扱いにくいビジネスです。

インタラクティブな調査のために、Xcode に付属しているAccessibility Inspector開発者ツールがありますが、特に調査結果をコードに変換する場合は、それを使用するのは簡単ではありません。

于 2015-10-22T06:33:10.610 に答える