UI 테스트 실패-요소 나 하위 요소 모두 secureTextField에 키보드 포커스가 없습니다.


139

이것은 나의 경우이다 :

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

UI 테스트 실패-요소 나 자손 모두 키보드 포커스를 가지고 있지 않습니다. 요소:

뭐가 잘못 되었 니? 이것은 정상 작동 textFields하지만 문제는 오직 발생합니다 secureTextFields. 해결 방법이 있습니까?



이상한 부분은 내가 이것을 시도하면 작동합니다. XCUIApplication (). webViews.secureTextFields [ "Password"]. tap () XCUIApplication (). webViews.secureTextFields [ "Password"]. typeText ( "Welcome")
aurilio

접근성 식별자를 설정했지만 isAccessibilityElement = true
soumil을

비슷한 질문에 대한 답변을 여기에 추가했습니다 : stackoverflow.com/a/59637897/2585413 . 내 문제는 내가 나쁜 .windowLevel 값으로 존재 다른 UIWindows을 한 것으로이었다
nteissler

답변:


264

이 문제로 인해 많은 고통을 겪었지만 적절한 해결책을 찾았습니다. 시뮬레이터에서 '하드웨어-> 키보드-> 하드웨어 키보드 연결'이 꺼져 있는지 확인하십시오.


4
문제가 해결되었습니다. 그러나 CI에 자동으로 적용 할 수 없으므로 해결 방법이 매우 좋지 않습니다.
Stanislav Pankevich

25
CI (Jenkins 등)에서 테스트를 실행하는 경우 테스트를 실행하기 전에 스크립트에서 다음 매개 변수를 설정할 수 있습니다. "기본값은 com.apple.iphonesimulator ConnectHardwareKeyboard 0을 작성합니다"
charlyatwork

7
이것은 나에게 문제를 해결하지 못합니다. 키보드가 위로 올라 가면서 텍스트 필드가 포커스를 얻는 것을 명확하게 볼 수 있지만 테스트 프레임 워크는 typeText : method
Michael

2
Xcode 11에서 나를 위해 일했지만 하드웨어 키보드 연결을 선택 취소하는 것만으로는 충분하지 않을 수 있습니다. 추가로 소프트웨어 키보드가 실제로 표시되는지 확인해야합니다 (텍스트 필드에 포커스가 있고 커서가 깜박이더라도 실제로 하드웨어 키보드가 연결되어 있지 않고 소프트웨어 키보드가 표시되지 않은 상황).
Reinhard Männer

1
Xcode 11 에서도이 문제가 발생했습니다. 로컬로 수정하지만 CI에서 어떻게 설정할 수 있습니까?
jherg

26

최근에 우리는 허용 된 답변의 솔루션을 영구적으로 유지하는 해킹을 발견했습니다. 시뮬레이터 설정을 비활성화하려면 명령 줄에서 '하드웨어-> 키보드-> 하드웨어 키보드 연결'을 작성하십시오.

defaults write com.apple.iphonesimulator ConnectHardwareKeyboard 0

실행중인 시뮬레이터에는 영향을 미치지 않습니다. 시뮬레이터를 다시 시작하거나 새 설정을 시작하여 해당 설정이 적용되도록해야합니다.


이것은 변경되지 않았습니다.
netshark1000

최신 버전의 Xcode로 변경 될 수있는 @ netshark1000을 확인하겠습니다.
AlexDenisov

1
매우 도움이되었으므로 키보드가 항상 활성화되어있는 반대가 필요했습니다. 그러나 이것은 대단히 감사합니다. 나는 결국 defaults write com.apple.iphonesimulator ConnectHardwareKeyboard -bool true은 같은 개념으로 끝났습니다 .
레이저 호크

2
빌드 단계에서 스크립트를 작성했습니다. 그러나 나는 내가 한, 그래서 모든 시뮬레이터를 죽일 필요가 :killall "Simulator"; defaults write com.apple.iphonesimulator ConnectHardwareKeyboard 0;
바그너 판매

더 이상 작동하지 않는 것 같습니다. 키가 변경 되었습니까? @AlexDenisov
사이먼 맥 로린

15

나는 나를 위해 완벽하게 작동하는 작은 확장 (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))
        }
    }
}

주요 아이디어는 키보드가 표시되기 전에 요소 (텍스트 필드)를 계속 두드리는 것입니다.


이것은 지금 나를 위해 작동하지 않습니다. Xcode 7.2 (7C68)가 있습니다. 어떤 버전이 있습니까? CI에 대해 찾은이 솔루션은 우리에게 효과적입니다 : stackoverflow.com/a/34812979/598057 .
Stanislav Pankevich

한 번 더 확인하려면 :이 도우미는 일반 텍스트 필드뿐만 아니라 안전한 암호 텍스트 필드 를 위해 작동 합니까?
Stanislav Pankevich

예, 일반 텍스트와 보안 텍스트 필드 모두에서 작동합니다.
berezhnyi oleksandr

1
이 답변의 문제점은 하드 코딩 된 지연을 사용한다는 것입니다. 대신 키보드 요소와 함께 기대 대기 시간 모델을 사용하십시오.
user1122069

11

Stanislav는 올바른 아이디어를 가지고 있습니다.

팀 환경에서는 자동으로 작동하는 것이 필요합니다. 나는했습니다 수정을 마련 여기 내 블로그에.

기본적으로 붙여 넣기 만하면됩니다.

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

솔루션을 공유해 주셔서 감사합니다. 불행히도 그것은 지금 나를 위해 작동하지 않습니다. Xcode 7.2 (7C68)가 있습니까? : 우리가 CI에 대한 발견 다른 솔루션을 참조하십시오 stackoverflow.com/questions/32184837/...을 .
Stanislav Pankevich

8

이 오류의 또 다른 원인은 접근성 요소 ( 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")

공장


6

그것은 여러 번 나와 함께 일어났다. 시뮬레이터에서 키보드 하드웨어 및 OSX와 동일한 레이아웃을 비활성화해야합니다

하드웨어 / 키보드 (모두 비활성화)

그 후 키보드 소프트웨어가 닫히지 않고 테스트에서 텍스트를 입력 할 수 있습니다

하드웨어 비활성화


5

다음과 같이 앱을 시작하고 텍스트 필드에 데이터를 입력 할 때 잠을 자십시오.

sleep(2)

내 경우에는 매번이 오류가 계속 발생 했으며이 솔루션만이 도움이되었습니다.


1
문제는 초기 로그인과 같은 기능을 수행하는 많은 수의 UI 테스트가있는 경우 CI 테스트 실행에 엄청난 오버 헤드가 발생한다는 것입니다.
delta2flat

4

아마도 도움이 될 것입니다. 오류 전에 "탭"동작을 추가하기 만하면됩니다. 그게 다야 :)

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

2
보안 암호 텍스트 필드에는 작동하지 않습니다.
Stanislav Pankevich

이것은 안전한 암호 텍스트 필드에서 잘 작동했습니다. 좋은 해결책입니다.
Travis M.

4
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

그러나 키보드 또는 키보드를 연결하지 않은 상태에서 원하는 경우를 기록하십시오. 그러나 테스트하기 전에 다음을 수행하십시오.

테스트 중에는 다음 옵션 (하드웨어 키보드 연결)을 선택 해제해야합니다.

여기에 이미지 설명을 입력하십시오


4

내 경우에는 Hardware -> Keyboard -> Connect Hardware Keyboard-> 비활성화 이 작동하지 않았습니다.

하지만 내가 따라 갔을 때

1) Hardware -> Keyboard -> Connect Hardware Keyboard-> 사용 및 응용 프로그램 실행
) 2 Hardware -> Keyboard -> Connect Hardware Keyboard-> 사용 안 함 .

그것은 나를 위해 일했다


나를 위해 일한 MAN XCode 의이 측면이 싫어!
bwobbones

3

[ 바트와 이미 세마 첸 키크 다시 게시하기 의 의견을 하면 문제가 해결되었습니다.]

시뮬레이터 메뉴 표시 줄에서 시뮬레이터> 내용 및 설정 재설정을 수행 하여이 작업을 시작해야했습니다.


시뮬레이터를 재설정하면 나에게 도움이되었습니다. 흥미롭게도 동일한 테스트 (탭 texfield와 문자 입력)가 장치에서 제대로 실행되는 동안 시뮬레이터에서만 문제가 발생했습니다.
Christian

1

때때로 텍스트 필드는 텍스트 필드로 구현되지 않거나 다른 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

첫 번째 줄은 단지 쿼리 정의 입니다.passwordSecureTextField 실제로 존재 .

두 번째 줄은 쿼리 를 동적으로 실행하고 쿼리를 UI 요소에 (다시) 바인딩하려고합니다. 여기에 중단 점을두고 하나의 요소 만 발견되는지 확인해야합니다. 또는 단언을 사용하십시오.

XCTAssertFalse(passwordSecureTextField.exists);

그렇지 않으면 괜찮아 보이고 tap키보드를 강제로 보인 다음 typeText작동해야합니다. 오류 로그에 자세한 정보가 표시됩니다.


1
passwordSecureTextField존재합니다. 문제를 해결했지만 메모리를 정리하고 해당 줄을 다시 작성하십시오. 이상하지만 효과가있었습니다.
Bartłomiej Semańczyk

고 쳤어요! 어제 베타 6과 비슷한 문제가 발생했습니다. :)
JOM

베타 6? :-) 정말? 나는 5 :)
Bartłomiej Semańczyk

당신은 코딩에 바빴습니다 :) 베타 6은 tap나를 위해 기록하지 않았으며 , 그것을 알아내는 데 시간이 걸렸습니다. 좋은 디버그 연습!
JOM

아마 당신은 이것에 대한 답을 알고 있습니다 : stackoverflow.com/questions/32219015/… ?
Bartłomiej Semańczyk

0

엉망이 아닙니다. 자동 테스트 시간 시뮬레이터가 소프트웨어 키보드 만 사용하는 동안 앱이 하드웨어 키보드를 연결하는 테스트 시간을 기록했기 때문에 문제가 발생했습니다. 이 문제를 해결하는 방법에 대해. 녹음 시간에 소프트웨어 키보드를 사용하십시오. 당신은 마술을 볼 수 있습니다.


0

나에게 대한 문제는 테드와 동일했다. 실제로 로그인 필드와 하드웨어 KB가 켜진 후 암호 필드가 탭되면 두 번째 필드 탭에서 소프트웨어 키보드가 사라지고 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

서브 accessibilityIdentifier뷰를 포함하는 사용자 정의보기 ( UIStackView서브 클래스) 의 값을 설정할 때 동일한 오류가 발생했습니다 UIControl. 이 경우 XCTest는 하위 요소에 대한 키보드 포커스를 얻을 수 없습니다.

우리의 솔루션은 단순히 accessibilityIdentifier부모 뷰에서 를 제거하고 accessibilityIdentifier전용 속성을 통해 하위 뷰를 설정하는 것이 었습니다 .


0

또 다른 대답이지만 우리에게는 문제는 제스처 인식기가 인식 한 다른보기에 너무 가깝다는 것입니다. 뷰가 최소한 20 픽셀 이상 떨어져 있어야한다는 것을 알았습니다 (아래의 경우). 말 그대로 15 개는 효과가 없었고 20 개 이상은 효과가 없었습니다. 이것은 내가 이상하게 인정할 것이지만, 우리는 일부 UITextViews가 작동하고 일부는 동일하지 않고 모두 동일한 부모와 동일한 다른 위치 (및 변수 이름)에있었습니다. 키보드가 켜져 있거나 꺼져 있거나 아무런 차이가 없습니다. 접근성은 필드를 보여 주었다. 우리는 컴퓨터를 다시 시작했습니다. 깨끗한 빌드를했습니다. 신선한 소스 체크 아웃.


0

나를 위해이 문제를 해결 한 것은 1 초 수면을 추가하는 것이 었습니다.

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

0

나는이 문제에 부딪 쳤고 @AlexDenisov가 게시 한 솔루션을 가져 와서 실행테스트를 위한 사전 조치에 추가하여 시나리오에서 해결할 수있었습니다 .

여기에 이미지 설명을 입력하십시오


0

I / O에서 키보드를 켜거나 끌 필요가 없습니다. secureTextField에 .typeText를 사용하지 마십시오.

app.keys["p"].tap()
app.keys["a"].tap()
app.keys["s"].tap()
app.keys["s"].tap()

보너스 : 키보드 사운드 클릭 :)


0

마지막으로, 시뮬레이터의 .plist 파일을 편집하고 ConnectHardwareKeyboard 하고 선택한 시뮬레이터 속성을 false로 . 잘 들었습니다. 전역 속성을 편집하지 않고 "DevicePreferences"사전에서 특별히 선택된 시뮬레이터의 속성을 변경합니다.

먼저 다음 내용으로 disable-hardware-keyboard.sh 라는 셸 스크립트를 만듭니다 . "YourProject / xyzUITests / Scripts /"내에 배치 할 수 있습니다.

echo "Script: Set ConnectHardwareKeyboard to false for given Simulator UDID"

if [[ $1 != *-*-*-*-* ]]; then
    echo "Pass device udid as first argument."
    exit 1
else
    DEVICE_ID=$1
fi

DEVICE_PREFERENCES_VALUE='<dict><key>ConnectHardwareKeyboard</key><false/></dict>'
killall Simulator # kill restart the simulator to make the plist changes picked up
defaults write com.apple.iphonesimulator DevicePreferences -dict-add $DEVICE_ID $DEVICE_PREFERENCES_VALUE
open -a Simulator # IMPORTANT

이제 다음 단계에 따라 선택한 시뮬레이터의 udid를 인수로 전달하여 호출하십시오.

  1. Xcode 체계를 편집하십시오 (또는 UI 체계가있는 경우 특정 체계를 테스트하십시오)
  2. 테스트> 사전 조치로 이동하십시오.
  3. "+"기호> "새 실행 스크립트 동작"을 눌러 새 스크립트를 추가하십시오.
  4. 중대한: "빌드 설정 제공"드롭 다운에서 UI 테스트 대상이 아닌 기본 앱 대상을 선택하십시오.
  5. 이제 아래 텍스트 영역에 다음 스크립트를 추가하십시오.

Test> Pre-actions 내부 스크립트 :

#!/bin/sh
# $PROJECT_DIR is path to your source project. This is provided when we select "Provide build settings from" to "AppTarget"
# $TARGET_DEVICE_IDENTIFIER is the UDID of the selected simulator
sh $PROJECT_DIR/xyzUITests/Scripts/disable-hardware-keyboard.sh $TARGET_DEVICE_IDENTIFIER

# In order to see output of above script, append following with it:
#  | tee ~/Desktop/ui-test-scheme-prescript.txt

그것을 테스트 할 시간 :

  1. 시뮬레이터 시작
  2. 하드웨어 키보드 사용
  3. 키보드 상호 작용으로 UI 테스트를 실행하십시오. 시뮬레이터가 다시 시작되고 하드웨어 키보드가 비활성화되어 있는지 확인하십시오 . 그리고 테스트의 키보드 상호 작용이 잘 작동합니다. :)

-1

Securetextfields와 동일한 문제가 있습니다. 내 시뮬레이터의 하드웨어 연결 옵션이 사용되었지만 여전히 문제가 발생했습니다. 마지막으로 이것은 나를 위해 일했습니다 (Swift 3).

 let enterPasswordSecureTextField = app.secureTextFields["Enter Password"]
    enterPasswordSecureTextField.tap()
    enterPasswordSecureTextField.typeText("12345678")

코드와 질문에서 묻는 코드의 차이점은 무엇입니까?
Shivam Pokhriyal
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.