web-dev-qa-db-ja.com

UIテストの失敗-要素も子孫もsecureTextFieldにキーボードフォーカスがない

これは私の場合です:

let passwordSecureTextField = app.secureTextFields["password"]
passwordSecureTextField.tap()
passwordSecureTextField.typeText("wrong_password") //here is an error

UIテストの失敗-要素も子孫もキーボードフォーカスを持っていません。素子:

なにが問題ですか?これは通常のtextFieldsに対してうまく機能していますが、問題はsecureTextFieldsでのみ発生します。回避策はありますか?

この問題は私に苦痛の世界を引き起こしましたが、適切な解決策を見つけることができました。シミュレーターで、「ハードウェア->キーボード->ハードウェアキーボードの接続」がオフになっていることを確認します。

168
Ted Kaminski

最近、受け入れられた回答から解決策を永続化するためのハックが見つかりました。シミュレーター設定を無効にするには:「ハードウェア->キーボード->ハードウェアキーボードの接続」コマンドラインから次のように記述します。

defaults write com.Apple.iphonesimulator ConnectHardwareKeyboard 0

実行中のシミュレーターには影響しません。シミュレーターを再起動するか、新しいシミュレーターを起動して、設定を有効にする必要があります。

14
AlexDenisov

私にぴったりの小さな拡張機能(Swift)を作成しました。コードは次のとおりです。

extension XCTestCase {

    func tapElementAndWaitForKeyboardToAppear(element: XCUIElement) {
        let keyboard = XCUIApplication().keyboards.element
        while (true) {
            element.tap()
            if keyboard.exists {
                break;
            }
            NSRunLoop.currentRunLoop().runUntilDate(NSDate(timeIntervalSinceNow: 0.5))
        }
    }
}

主なアイデアは、キーボードが表示される前に要素(テキストフィールド)をタップし続けることです。

14

スタニスラフには正しい考えがあります。

チーム環境では、自動的に機能するものが必要です。私のブログで here を修正しました。

基本的には貼り付けるだけです:

UIPasteboard.generalPasteboard().string = "Their password"
let passwordSecureTextField = app.secureTextFields["password"]
passwordSecureTextField.pressForDuration(1.1)
app.menuItems["Paste"].tap()
11
RyanPliske

このエラーのもう1つの原因は、アクセシビリティ要素(view.isAccessibilityElement = true)として設定されているテキストを入力しようとしているテキストフィールドの親ビューがある場合です。この場合、XCTestはテキストを入力するためにサブビューのハンドルを取得できず、エラーを返します。

UIテストの失敗-要素も子孫もキーボードフォーカスを持っていません。

UITextFieldでキーボードがアップし、カーソルが点滅していることがよく見られるように、要素がフォーカスされていないということではなく、要素到達できるがフォーカスされていないというだけです。 UISearchBarにテキストを入力しようとしたときにこれに遭遇しました。検索バー自体はテキストフィールドではありません。アクセシビリティ要素として設定すると、基になるUITextFieldへのアクセスがブロックされました。これを解決するため、searchBar.accessibilityIdentifier = "My Identifier"UISearchBarに設定されましたが、isAccessibilityElementtrueに設定されませんでした。この後、次の形式のコードをテストします。

app.otherElements["My Identifier"].tap()
app.otherElements["My Identifier"].typeText("sample text")

作品

6
user3847320

アプリを起動してから、次のようなテキストフィールドにデータを入力するまでにスリープを使用します。

sleep(2)

私の場合、毎回このエラーが発生し続けていましたが、この解決策しか役に立ちませんでした。

5
Kingalione
func pasteTextFieldText(app:XCUIApplication, element:XCUIElement, value:String, clearText:Bool) {
    // Get the password into the pasteboard buffer
    UIPasteboard.generalPasteboard().string = value

    // Bring up the popup menu on the password field
    element.tap()

    if clearText {
        element.buttons["Clear text"].tap()
    }

    element.doubleTap()

    // Tap the Paste button to input the password
    app.menuItems["Paste"].tap()
}
4
Anthony

私と何度も起こりました。シミュレーターでキーボードハードウェアとOSXと同じレイアウトを無効にする必要があります

ハードウェア/キーボード(すべて無効)

その後、キーボードソフトウェアは終了せず、テストでテキストを入力できます

Disable Hardware

4

これはおそらく役立つでしょう。エラーの前に「タップ」アクションを追加するだけです。それで全部です :)

[app.textFields[@"theTitle"] tap];
[app.textFields[@"theTitle"] typeText:@"kk"];
3
Carlos Peralta

キーボードまたはキーボードが接続されていない場合でも、必要に応じてレコードケースを作成できます。ただし、テストを行う前に次のことを行ってください。

テストのプレイ中は、この次のオプション(ハードウェアキーボードを接続)のチェックを外す必要があります。

enter image description here

3
umairhhhs

[ BartłomiejSemańczyk のコメントを回答として再投稿したため、問題が解決されたため]

この作業を開始するには、シミュレータメニューバーで[シミュレータ]> [内容と設定をリセット]を実行する必要がありました。

2
rogueleaderr

別の答えですが、私たちにとって問題は、ビューがジェスチャー認識機能のある別のビューに近すぎるということでした。ビューが少なくとも20ピクセル離れている必要があることがわかりました(この場合は下の例です)。文字通り15は機能せず、20以上が機能しました。これは奇妙なことですが、動作するUITextViewと動作しないUITextViewがあり、すべてが同じ親と同じ他のポジショニング(およびもちろん変数名)の下にありました。キーボードのオン/オフ、または何も違いはありません。アクセシビリティはフィールドを示しました。コンピューターを再起動しました。クリーンビルドを行いました。新鮮なソースチェックアウト。

0
David J

私にとっての問題はテッドと同じでした。実際、ログインフィールドとハードウェアKBがオンになった後にパスワードフィールドがタップされた場合、ソフトウェアキーボードは2番目のフィールドタップで自動的に閉じます。これはUIテストに固有のものではありません。

AppleScriptをいじくり回した後、ここに私が思いついたものがあります(改善は大歓迎です):

tell application "Simulator" activate tell application "System Events" try tell process "Simulator" tell menu bar 1 tell menu bar item "Hardware" tell menu "Hardware" tell menu item "Keyboard" tell menu "Keyboard" set menuItem to menu item "Connect Hardware Keyboard" tell menu item "Connect Hardware Keyboard" set checkboxStatus to value of attribute "AXMenuItemMarkChar" of menuItem if checkboxStatus is equal to "✓" then click end if end tell end tell end tell end tell end tell end tell end tell on error tell application "System Preferences" activate set securityPane to pane id "com.Apple.preference.security" tell securityPane to reveal anchor "Privacy_Accessibility" display dialog "Xcode needs Universal access to disable hardware keyboard during tests(otherwise tests may fail because of focus issues)" end tell end try end tell end tell

上記のコードを使用してスクリプトファイルを作成し、必要なターゲットに追加します(おそらくUIテストターゲットのみ。開発ターゲットに同様のスクリプトを追加して、開発中にHWキーボードを再度有効にできます)。ビルドフェーズでRun Scriptフェーズを追加し、次のように使用する必要があります:osascript Path/To/Script/script_name.applescript

0
Timur Kuchkarov

テキストフィールドがテキストフィールドとして実装されていないか、別のUI要素にラップされており、簡単にアクセスできない場合があります。回避策は次のとおりです。

//XCUIApplication().scrollViews.otherElements.staticTexts["Email"] the locator for the element
RegistrationScreenStep1of2.emailTextField.tap()
let keys = app.keys
 keys["p"].tap() //type the keys that you need
 
 //If you stored your data somewhere and need to access that string //you can cats your string to an array and then pass the index //number to key[]
 
 let newUserEmail = Array(newPatient.email())
 let password = Array(newPatient.password)
 
 //When you cast your string to an array the elements of the array //are Character so you would need to cast them into string otherwise //Xcode will compain. 
 
 let keys = app.keys
     keys[String(newUserEmail[0])].tap()
     keys[String(newUserEmail[1])].tap()
     keys[String(newUserEmail[2])].tap()
     keys[String(newUserEmail[3])].tap()
     keys[String(newUserEmail[4])].tap()
     keys[String(newUserEmail[5])].tap()       
0
Eugene Berezin

最初の行はクエリ定義で、これはpasswordSecureTextFieldが実際に存在するという意味ではありません。

2行目は動的にクエリを実行し、クエリをUI要素に(再)バインドしようとします。ブレークポイントを配置して、1つの要素のみが検出されることを確認する必要があります。または、単にアサートを使用します:

XCTAssertFalse(passwordSecureTextField.exists);

そうでなければ、tapはキーボードを強制的に表示し、typeTextは正常に機能するはずです。エラーログに詳細が表示されます。

0
JOM

accessibilityIdentifierサブビューを含むカスタムビュー(UIStackViewサブクラス)にUIControl値を設定すると、同じエラーが発生しました。その場合、XCTestは子孫要素のキーボードフォーカスを取得できませんでした。

解決策は、親ビューからaccessibilityIdentifierを削除し、専用プロパティを介してサブビューのaccessibilityIdentifierを設定するだけでした。

0
shadowhorst

私にとってこの問題を解決したのは、1秒のスリープを追加することでした。

let textField = app.textFields["identifier"]
textField.tap()
sleep(1)
textField.typeText(text)

混乱しないでください。自動テスト時間シミュレータがソフトウェアキーボードのみを使用するのに対して、アプリがハードウェアキーボードを接続するテスト時間を記録しているという問題があります。この問題を修正する方法について。録音時間にソフトウェアキーボードを使用するだけです。あなたは魔法を見ることができます。

0
codercat