検索バーの「キャンセル」ボタンをタップして、検索フィールドを閉じようとしています。
テストケースでは、キャンセルボタンが見つかりません。 Xcode 7.0.1では正常に動作していました
ボタンが表示されるのを待つ述語を追加しました。 「キャンセル」ボタンをタップするとテストケースが失敗する
let button = app.buttons[“Cancel”]
let existsPredicate = NSPredicate(format: "exists == 1")
expectationForPredicate(existsPredicate, evaluatedWithObject: button, handler: nil)
waitForExpectationsWithTimeout(5, handler: nil)
button.tap() // Failing here
ログ:
t = 7.21s Tap SearchField
t = 7.21s Wait for app to idle
t = 7.29s Find the SearchField
t = 7.29s Snapshot accessibility hierarchy for com.test.mail
t = 7.49s Find: Descendants matching type SearchField
t = 7.49s Find: Element at index 0
t = 7.49s Wait for app to idle
t = 7.55s Synthesize event
t = 7.84s Wait for app to idle
t = 8.97s Type '[email protected]' into
t = 8.97s Wait for app to idle
t = 9.03s Find the "Search" SearchField
t = 9.03s Snapshot accessibility hierarchy for com.test.mail
t = 9.35s Find: Descendants matching type SearchField
t = 9.35s Find: Element at index 0
t = 9.36s Wait for app to idle
t = 9.42s Synthesize event
t = 10.37s Wait for app to idle
t = 10.44s Check predicate `exists == 1` against object `"Cancel" Button`
t = 10.44s Snapshot accessibility hierarchy for com.test.mail
t = 10.58s Find: Descendants matching type Button
t = 10.58s Find: Elements matching predicate '"Cancel" IN identifiers'
t = 10.58s Tap "Cancel" Button
t = 10.58s Wait for app to idle
t = 10.64s Find the "Cancel" Button
t = 10.64s Snapshot accessibility hierarchy for com.test.mail
t = 10.78s Find: Descendants matching type Button
t = 10.78s Find: Elements matching predicate '"Cancel" IN identifiers'
t = 10.79s Wait for app to idle
t = 11.08s Synthesize event
t = 11.13s Scroll element to visible
t = 11.14s Assertion Failure: UI Testing Failure - Failed to scroll to visible (by AX action) Button 0x7f7fcaebde40: traits: 8589934593, {{353.0, 26.0}, {53.0, 30.0}}, label: 'Cancel', error: Error -25204 performing AXAction 2003
ここで、[キャンセル]ボタンはfalse
プロパティに対してhittable
を返すため、タップできません。
ドキュメントにtap()
が表示されている場合は、
/*!
* Sends a tap event to a hittable point computed for the element.
*/
- (void)tap;
XCode 7.1では問題が発生しているようです。自分自身(およびuも;))がこれらの問題からブロックされないようにするために、XCUIElement
に拡張機能を作成しました。以下はあなたを助けることができます。
/*Sends a tap event to a hittable/unhittable element.*/
extension XCUIElement {
func forceTapElement() {
if self.hittable {
self.tap()
}
else {
let coordinate: XCUICoordinate = self.coordinateWithNormalizedOffset(CGVectorMake(0.0, 0.0))
coordinate.tap()
}
}
}
今、あなたはとして呼び出すことができます
button.forceTapElement()
更新-Swift 3の場合は以下を使用します:
extension XCUIElement {
func forceTapElement() {
if self.isHittable {
self.tap()
}
else {
let coordinate: XCUICoordinate = self.coordinate(withNormalizedOffset: CGVector(dx:0.0, dy:0.0))
coordinate.tap()
}
}
}
私にとって、根本的な原因は、タップしたいオブジェクトが
どちらの場合も、isAccessibilityElement
プロパティはその後false
でした。 true
に戻すと修正されました。
この質問は、Googleクエリで用語"表示にスクロールできませんでした(AXアクションによる)ボタン"にランクされています。質問の年齢を考えると、受け入れられた答えが示唆するように、これはもはやXCUITestフレームワークの問題ではないと思う傾向がありました。
この問題はXCElement
が存在するが、ソフトウェアキーボードの後ろに隠れていることが原因であることがわかりました。エラーは、タップ可能なようにビューに存在するビューをスクロールできないため、フレームワークによって発行されます。私の場合、問題のボタンはソフトウェアキーボードの後ろにありましたsometimes。
IOSシミュレータのソフトウェアキーボードは、場合によって(たとえば、マシン上)オフに切り替えられ、他の場合(たとえば、CI上)でオンに切り替えられる場合があります。私の場合、1台のマシンでソフトウェアキーボードをオフにし、デフォルトでは他のマシンでオンにしました。
ボタンをタップする前にキーボードを明示的に閉じた場所をタップすると、すべての環境で問題が解決しました。
現在のレスポンダーにresignFirstResponderを取得するアクションを追加しました。テキストビューの背後にあるビューは、最初のレスポンダーを強制的に辞任させるため、最後のテキスト領域のすぐ下のどこかをタップします。
/// The keyboard may be up, dismiss it by tapping just below the password field
let pointBelowPassword = passwordSecureTextField.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 1))
pointBelowPassword.press(forDuration: 0.1)
私の場合、ボタンを覆うUI要素がプログラムで追加されていました。
AppCenterシミュレーターを使用してテストを実行している場合は、ローカルシミュレーターと同じデバイスバージョンでテストを実行していることを確認する必要があります。このため、3日間の仕事を失いました。
Sandyの回避策はしばらくの間は助けに見えましたが、それ以上のことはありませんでした。次に、次のように変更しました。
func waitAndForceTap(timeout: UInt32 = 5000) {
XCTAssert(waitForElement(timeout: timeout))
coordinate(withNormalizedOffset: CGVector(dx:0.5, dy:0.5)).tap()
}
主なポイントは、問題はisHittableチェックが例外をスローすることであるため、このチェックをまったく行わず、要素が見つかった後、座標をまっすぐに移動することです。