私はXcode 7でのUIテストから始めて、この問題にぶつかりました:
テキストフィールドにテキストを入力してからボタンをクリックする必要があります。残念ながら、このボタンは、テキストフィールドにテキストを入力しているときに表示されたキーボードの後ろに隠れています。 Xcodeはスクロールして表示できるようにしていますが、ビューがスクロールできないため失敗します。
私の現在の解決策はこれです:
let textField = app.textFields["placeholder"]
textField.tap()
textField.typeText("my text")
app.childrenMatchingType(.Window).elementBoundByIndex(0).tap() // hide keyboard
app.buttons["hidden button"].tap()
私のViewControllerがタッチをインターセプトしているので、これを行うことができます:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
view.endEditing(false)
super.touchesBegan(touches, withEvent: event)
}
私のソリューションには本当に満足していませんが、UIテスト中にキーボードを非表示にする方法は他にありますか?
textField.resignFirstResponder()
デリゲートメソッドでFirstResponderを辞任するようにテキストフィールドを設定した場合(self.view.endEditing(true)
またはtextFieldShouldReturn()
を介して)、次に
textField.typeText("\n")
それを行います。
XCUIApplication().toolbars.buttons["Done"].tap()
ジョーのブログ への質問に基づいて、シミュレーターで数回実行した後、キーボードがこのコードの一部を使用して非表示にできないという問題があります。
XCUIApplication().keyboard.buttons["Hide keyboard"]
だから、私はそれを次のように変更しました:(ありがとうJoe)
XCUIApplication().keyboard.buttons["Hide keyboard"]
let firstKey = XCUIApplication().keys.elementBoundByIndex(0)
if firstKey.exists {
app.typeText("\n")
}
ここで私がしようとしているのは、非表示ボタンをタップした後もキーボードがまだ開いているかどうかを検出することです。ボタンが上にある場合は、「\ n」と入力すると、キーボードも閉じます。
シミュレーターがキーボードタイピングのフォーカスを失い、テストが失敗する可能性があるため、これもトリッキーです。しかし、私の経験では、失敗率は私が取った他のアプローチよりも低くなっています。
これがお役に立てば幸いです。
Swift UITesting:
XCUIApplication().keyboards.buttons["Hide keyboard"].tap()
あなたの質問への答えは、テストコードではなくアプリコードにあります。ユーザーが画面上のソフトウェアキーボードを使用してテキストを入力してボタンをタップできない場合は、テストでキーボードを非表示にする(ユーザーがボタンをタップするために必要となる)か、ビューをスクロール可能にする必要があります。 。
Swift 5ヘルパー関数
func dismissKeyboardIfPresent()
{
if app.keyboards.element(boundBy: 0).exists
{
if UIDevice.current.userInterfaceIdiom == .pad
{
app.keyboards.buttons["Hide keyboard"].tap()
}
else
{
app.toolbars.buttons["Done"].tap()
}
}
}
Swift 4.2を使用すると、次のスニペットでこれを実現できます。
let app = XCUIApplication()
if app.keys.element(boundBy: 0).exists {
app.typeText("\n")
}
テストを実行する前に、シミュレータでキーボードがオフになっていることを確認してください。
ハードウェア->キーボード->ハードウェアキーボードの接続。
次に、ペーストボードを使用してテキストを入力します
textField.tap()
UIPasteboard.generalPasteboard().string = "Some text"
textField.doubleTap()
app.menuItems["paste"].tap()
タップしたり続行したりするために表示されている可能性がある複数の要素を検索することをお勧めします。そして、正しいものを選択してください。
class ElementTapHelper {
///Possible elements to search for.
var elements:[XCUIElement] = []
///Possible keyboard element.
var keyboardElement:XCUIElement?
init(elements:[XCUIElement], keyboardElement:XCUIElement? = nil) {
self.elements = elements
self.keyboardElement = keyboardElement
}
func tap() {
let keyboard = XCUIApplication().keyboards.firstMatch
if let key = keyboardElement, keyboard.exists {
let frame = keyboard.frame
if frame != CGRect.zero {
key.forceTap()
return
}
}
for el in elements {
if el.exists && el.isHittable {
el.forceTap()
return
}
}
}
}
extension XCUIElement {
///If the element isn't hittable, try and use coordinate instead.
func forceTap() {
if self.isHittable {
self.tap()
return
}
//if element isn't reporting hittable, grab it's coordinate and tap it.
coordinate(withNormalizedOffset: CGVector(dx:0, dy:0)).tap()
}
}
それは私にはうまくいきます。これは私が通常それを使用する方法です:
let next1 = XCUIApplication().buttons["Next"]
let keyboardNext = XCUIApplication().keyboards.firstMatch.buttons["Next"]
ElementTapHelper(elements: [next1], keyboardElement: keyboardNext).tap()
これの良い点は、タップできる複数の要素を提供でき、最初にキーボード要素を検索することです。
これのもう1つの利点は、実際のデバイスでテストする場合、デフォルトでキーボードが開くことです。では、キーボードボタンを押すだけではどうでしょうか。
このヘルパーは、同じことを行うボタンが複数あり、一部が非表示になっている場合にのみ使用します。