これは私の場合です:
let passwordSecureTextField = app.secureTextFields["password"]
passwordSecureTextField.tap()
passwordSecureTextField.typeText("wrong_password") //here is an error
UIテストの失敗-要素も子孫もキーボードフォーカスを持っていません。素子:
なにが問題ですか?これは通常のtextFields
に対してうまく機能していますが、問題はsecureTextFields
でのみ発生します。回避策はありますか?
この問題は私に苦痛の世界を引き起こしましたが、適切な解決策を見つけることができました。シミュレーターで、「ハードウェア->キーボード->ハードウェアキーボードの接続」がオフになっていることを確認します。
最近、受け入れられた回答から解決策を永続化するためのハックが見つかりました。シミュレーター設定を無効にするには:「ハードウェア->キーボード->ハードウェアキーボードの接続」コマンドラインから次のように記述します。
defaults write com.Apple.iphonesimulator ConnectHardwareKeyboard 0
実行中のシミュレーターには影響しません。シミュレーターを再起動するか、新しいシミュレーターを起動して、設定を有効にする必要があります。
私にぴったりの小さな拡張機能(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))
}
}
}
主なアイデアは、キーボードが表示される前に要素(テキストフィールド)をタップし続けることです。
スタニスラフには正しい考えがあります。
チーム環境では、自動的に機能するものが必要です。私のブログで here を修正しました。
基本的には貼り付けるだけです:
UIPasteboard.generalPasteboard().string = "Their password"
let passwordSecureTextField = app.secureTextFields["password"]
passwordSecureTextField.pressForDuration(1.1)
app.menuItems["Paste"].tap()
このエラーのもう1つの原因は、アクセシビリティ要素(view.isAccessibilityElement = true
)として設定されているテキストを入力しようとしているテキストフィールドの親ビューがある場合です。この場合、XCTestはテキストを入力するためにサブビューのハンドルを取得できず、エラーを返します。
UIテストの失敗-要素も子孫もキーボードフォーカスを持っていません。
UITextFieldでキーボードがアップし、カーソルが点滅していることがよく見られるように、要素がフォーカスされていないということではなく、要素到達できるがフォーカスされていないというだけです。 UISearchBarにテキストを入力しようとしたときにこれに遭遇しました。検索バー自体はテキストフィールドではありません。アクセシビリティ要素として設定すると、基になるUITextFieldへのアクセスがブロックされました。これを解決するため、searchBar.accessibilityIdentifier = "My Identifier"
がUISearchBar
に設定されましたが、isAccessibilityElement
はtrue
に設定されませんでした。この後、次の形式のコードをテストします。
app.otherElements["My Identifier"].tap()
app.otherElements["My Identifier"].typeText("sample text")
作品
アプリを起動してから、次のようなテキストフィールドにデータを入力するまでにスリープを使用します。
sleep(2)
私の場合、毎回このエラーが発生し続けていましたが、この解決策しか役に立ちませんでした。
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()
}
これはおそらく役立つでしょう。エラーの前に「タップ」アクションを追加するだけです。それで全部です :)
[app.textFields[@"theTitle"] tap];
[app.textFields[@"theTitle"] typeText:@"kk"];
[ BartłomiejSemańczyk のコメントを回答として再投稿したため、問題が解決されたため]
この作業を開始するには、シミュレータメニューバーで[シミュレータ]> [内容と設定をリセット]を実行する必要がありました。
別の答えですが、私たちにとって問題は、ビューがジェスチャー認識機能のある別のビューに近すぎるということでした。ビューが少なくとも20ピクセル離れている必要があることがわかりました(この場合は下の例です)。文字通り15は機能せず、20以上が機能しました。これは奇妙なことですが、動作するUITextViewと動作しないUITextViewがあり、すべてが同じ親と同じ他のポジショニング(およびもちろん変数名)の下にありました。キーボードのオン/オフ、または何も違いはありません。アクセシビリティはフィールドを示しました。コンピューターを再起動しました。クリーンビルドを行いました。新鮮なソースチェックアウト。
私にとっての問題はテッドと同じでした。実際、ログインフィールドとハードウェア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
テキストフィールドがテキストフィールドとして実装されていないか、別の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()
最初の行はクエリ定義で、これはpasswordSecureTextField
が実際に存在するという意味ではありません。
2行目は動的にクエリを実行し、クエリをUI要素に(再)バインドしようとします。ブレークポイントを配置して、1つの要素のみが検出されることを確認する必要があります。または、単にアサートを使用します:
XCTAssertFalse(passwordSecureTextField.exists);
そうでなければ、tap
はキーボードを強制的に表示し、typeText
は正常に機能するはずです。エラーログに詳細が表示されます。
accessibilityIdentifier
サブビューを含むカスタムビュー(UIStackView
サブクラス)にUIControl
値を設定すると、同じエラーが発生しました。その場合、XCTestは子孫要素のキーボードフォーカスを取得できませんでした。
解決策は、親ビューからaccessibilityIdentifier
を削除し、専用プロパティを介してサブビューのaccessibilityIdentifier
を設定するだけでした。
私にとってこの問題を解決したのは、1秒のスリープを追加することでした。
let textField = app.textFields["identifier"]
textField.tap()
sleep(1)
textField.typeText(text)
混乱しないでください。自動テスト時間シミュレータがソフトウェアキーボードのみを使用するのに対して、アプリがハードウェアキーボードを接続するテスト時間を記録しているという問題があります。この問題を修正する方法について。録音時間にソフトウェアキーボードを使用するだけです。あなたは魔法を見ることができます。