Lỗi kiểm tra giao diện người dùng - Cả phần tử và bất kỳ hậu duệ nào đều không tập trung bàn phím vào safeTextField


138

Đây là trường hợp của tôi:

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

Lỗi kiểm tra giao diện người dùng - Cả yếu tố và bất kỳ hậu duệ nào đều không tập trung vào bàn phím. Thành phần:

Chuyện gì thế? Điều này là làm việc tốt cho bình thường textFields, nhưng vấn đề chỉ phát sinh với secureTextFields. Bất kỳ cách giải quyết?



và phần kỳ lạ là nếu tôi cố gắng như thế này nó hoạt động XCUIApplication () webViews.secureTextFields [ "Mật khẩu"] tap () XCUIApplication () webViews.secureTextFields [ "Mật khẩu"] typeText ( "Chào mừng")....
aurilio

Đó có thể là trường hợp bạn đã đặt định danh khả năng truy cập nhưng bạn chưa đặt isAccessibilityEuity = true
soumil

Tôi đã thêm một câu trả lời cho một câu hỏi tương tự ở đây: stackoverflow.com/a/59637897/2585413 . Vấn đề của tôi là tôi đã tồn tại các UIWindows khác với các giá trị .windowLevel xấu
nteissler

Câu trả lời:


264

Vấn đề này gây cho tôi một thế giới đau khổ, nhưng tôi đã tìm ra một giải pháp thích hợp. Trong Trình mô phỏng, đảm bảo 'Phần cứng -> Bàn phím -> Kết nối bàn phím phần cứng' đã tắt.


4
Điều này đã khắc phục vấn đề. Nhưng đó là cách giải quyết rất kém vì chúng tôi không thể tự động áp dụng nó cho CI.
Stanislav Pankevich

25
Nếu bạn chạy thử nghiệm trên CI (Jenkins, v.v.) Bạn có thể đặt các tham số sau trong tập lệnh trước khi chạy thử nghiệm. "mặc định viết com.apple.iphonesimulator ConnectHardwarePal 0"
charlyatwork

7
Điều này không giải quyết vấn đề cho tôi. Tôi có thể thấy rõ textfield lấy nét, với bàn phím lên, nhưng khuôn khổ thử nghiệm không bao giờ có thể nhập văn bản bằng cách sử dụng typeText: Phương pháp
Michael

2
Làm việc cho tôi trên Xcode 11, nhưng bỏ chọn Bàn phím phần cứng Connect có thể không đủ. Ngoài ra, người ta còn đảm bảo rằng bàn phím phần mềm thực sự được hiển thị (tôi thực sự đã gặp tình huống không có bàn phím phần cứng nào được kết nối và không có bàn phím phần mềm nào được hiển thị, ngay cả khi textField có tiêu điểm và con trỏ nhấp nháy).
Reinhard Männer

1
Tôi cũng gặp vấn đề này trên Xcode 11. Sửa lỗi cục bộ, nhưng làm thế nào điều này có thể được đặt trong CI?
jherg

26

Gần đây, chúng tôi tìm thấy một hack để làm cho giải pháp từ câu trả lời được chấp nhận liên tục. Để tắt cài đặt Trình mô phỏng: 'Phần cứng -> Bàn phím -> Kết nối bàn phím phần cứng' từ dòng lệnh người ta nên viết:

defaults write com.apple.iphonesimulator ConnectHardwareKeyboard 0

Nó sẽ không ảnh hưởng đến một trình giả lập đang chạy - bạn cần khởi động lại trình giả lập hoặc bắt đầu một trình giả lập mới để làm cho cài đặt đó có hiệu lực.


Điều này đã không thay đổi một cái gì đó.
Netshark1000

@ Netshark1000 có thể được thay đổi với phiên bản Xcode mới hơn, tôi sẽ kiểm tra nó.
AlexDenisov

1
cực kỳ hữu ích, tôi cần ngược lại nơi bàn phím luôn được bật, nhưng vâng, đây là lời cảm ơn tuyệt vời. Tôi đã kết thúc với defaults write com.apple.iphonesimulator ConnectHardwareKeyboard -bool true, nhưng đó là cùng một khái niệm.
Laser Hawk

2
Tôi đã tạo một kịch bản về các giai đoạn xây dựng để làm điều đó. Nhưng tôi cần tiêu diệt tất cả các trình giả lập, vì vậy tôi đã làm điều đó:killall "Simulator"; defaults write com.apple.iphonesimulator ConnectHardwareKeyboard 0;
Bán hàng Wagner

Điều này dường như không còn hoạt động nữa, chìa khóa đã thay đổi ?? @AlexDenisov
Simon McLoughlin

15

Tôi đã viết một phần mở rộng nhỏ (Swift) hoạt động hoàn hảo cho tôi. Đây là mã:

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))
        }
    }
}

Ý tưởng chính là tiếp tục khai thác một yếu tố (trường văn bản) trước khi bàn phím được trình bày.


Điều này không làm việc cho tôi ngay bây giờ. Tôi đang có Xcode 7.2 (7C68), bạn có phiên bản nào? Giải pháp này mà chúng tôi tìm thấy cho CI hoạt động cho chúng tôi: stackoverflow.com/a/34812979/598057 .
Stanislav Pankevich

Để xác nhận nó một lần nữa: người trợ giúp này làm việc cho bạn cho trường văn bản mật khẩu an toàn không chỉ là trường văn bản thông thường?
Stanislav Pankevich

Có, nó hoạt động cho cả hai loại trường văn bản: thường xuyên và an toàn.
berezhnyi oleksandr

1
Vấn đề với câu trả lời này là nó sử dụng độ trễ mã hóa cứng. Thay vào đó, hãy sử dụng mô hình chờ đợi cho kỳ vọng với phần tử bàn phím.
dùng1122069

11

Stanislav có ý tưởng đúng.

Trong môi trường nhóm, bạn cần một cái gì đó sẽ tự động hoạt động. Tôi đã đưa ra một sửa chữa ở đây trên blog của tôi.

Về cơ bản bạn chỉ cần dán:

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

Cảm ơn đã chia sẻ giải pháp của bạn. Thật không may, nó không làm việc cho tôi ngay bây giờ. Tôi đang có Xcode 7.2 (7C68), bạn thì sao? Xem giải pháp khác mà chúng tôi đã tìm thấy cho CI: stackoverflow.com/questions/32184837/ cấp .
Stanislav Pankevich

8

Một nguyên nhân khác của lỗi này là nếu có chế độ xem chính của trường văn bản mà bạn đang cố nhập văn bản được đặt làm thành phần trợ năng ( view.isAccessibilityElement = true). Trong trường hợp này, XCTest không thể có một điều khiển trên khung nhìn phụ để nhập văn bản và trả về lỗi.

Lỗi kiểm tra giao diện người dùng - Cả yếu tố và bất kỳ hậu duệ nào đều không tập trung vào bàn phím.

Không phải là không có phần tử nào có tiêu điểm (vì bạn thường có thể thấy bàn phím lên và nhấp nháy con trỏ trong UITextField), chỉ là không có phần tử nào nó có thể đạt được có tiêu điểm. Tôi gặp phải vấn đề này khi cố gắng nhập văn bản trong UISearchBar. Bản thân thanh tìm kiếm không phải là trường văn bản, khi đặt nó làm thành phần trợ năng, quyền truy cập vào UITextField nằm bên dưới đã bị chặn. Để giải quyết vấn đề này, searchBar.accessibilityIdentifier = "My Identifier"đã được đặt trên UISearchBartuy nhiên cái isAccessibilityElementkhông được đặt thành true. Sau đó, kiểm tra mã của mẫu:

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

Làm


6

Nó xảy ra với tôi nhiều lần. Bạn phải tắt Phần cứng bàn phím và Bố cục giống như OSX trong Trình mô phỏng của bạn

Phần cứng / Bàn phím (vô hiệu hóa tất cả)

Sau đó, phần mềm bàn phím sẽ không loại bỏ và các bài kiểm tra của bạn có thể nhập văn bản

Vô hiệu hóa phần cứng


5

Sử dụng chế độ ngủ giữa khởi chạy ứng dụng và nhập dữ liệu vào các trường văn bản như thế này:

sleep(2)

Trong trường hợp của tôi, tôi luôn bị lỗi này và chỉ có giải pháp này mới giúp tôi thoát ra.


1
Vấn đề là nếu bạn có một số lượng lớn các Thử nghiệm giao diện người dùng thực hiện một cái gì đó giống như đăng nhập ban đầu, thì điều này sẽ thêm một chi phí rất lớn vào quá trình thử nghiệm CI của bạn.
delta2flat

4

Điều này có thể giúp: Tôi chỉ cần thêm một hành động "chạm" trước lỗi; đó là tất cả :)

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

2
Điều này chắc chắn không hoạt động cho trường văn bản mật khẩu an toàn.
Stanislav Pankevich

Điều này làm việc cho trường văn bản mật khẩu an toàn của tôi tốt. Giải pháp tốt.
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

Ghi lại trường hợp bạn muốn, bàn phím hoặc không có bàn phím kèm theo. Nhưng làm như sau trước khi chơi thử.

Tùy chọn sau (kết nối bàn phím phần cứng) nên được bỏ chọn trong khi chơi thử.

nhập mô tả hình ảnh ở đây


4

Trong trường hợp của tôi, điều này Hardware -> Keyboard -> Connect Hardware Keyboard-> Vô hiệu hóa không làm việc cho tôi.

Nhưng khi tôi làm theo

1) Hardware -> Keyboard -> Connect Hardware Keyboard-> Đã bật và chạy ứng dụng
2) Hardware -> Keyboard -> Connect Hardware Keyboard-> Tắt .

Nó làm việc cho tôi


Làm việc cho tôi, MAN Tôi ghét khía cạnh này của XCode!
bwobbones

3

[Đăng lại bình luận của Bartłomiej Semańchot như một câu trả lời vì nó đã giải quyết vấn đề cho tôi]

Tôi cần thực hiện Trình mô phỏng> Đặt lại Nội dung và Cài đặt trong thanh trình đơn giả lập để thực hiện việc này bắt đầu với tôi.


Đặt lại trình giả lập cũng giúp tôi. Điều thú vị là sự cố chỉ xảy ra trong trình giả lập trong khi thử nghiệm tương tự (nhấn texfield theo sau là gõ ký tự) chạy tốt trên thiết bị.
Christian

1

Đôi khi các trường văn bản không được triển khai dưới dạng trường văn bản hoặc chúng được bọc trong một thành phần UI khác và không dễ truy cập. Đây là một công việc xung quanh:

//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

Dòng đầu tiên của bạn chỉ là một định nghĩa truy vấn , điều đó không có nghĩa là nó passwordSecureTextFieldthực sự tồn tại.

Dòng thứ hai của bạn sẽ tự động thực hiện truy vấn và cố gắng (tái) liên kết truy vấn với thành phần UI. Bạn nên đặt một điểm dừng trên đó và xác minh rằng một và chỉ một yếu tố được tìm thấy. Hoặc chỉ sử dụng một xác nhận:

XCTAssertFalse(passwordSecureTextField.exists);

Nếu không thì có vẻ ổn, tapnên buộc bàn phím hiển thị và sau đó typeTextchỉ nên hoạt động. Nhật ký lỗi sẽ cho bạn biết thêm thông tin.


1
passwordSecureTextFieldtồn tại Tôi đã khắc phục sự cố, nhưng làm sạch bộ nhớ và viết lại các dòng đó một lần nữa. Lạ, nhưng nó đã làm việc.
Bartłomiej Semańchot

Thật tốt khi nghe nó đã được sửa! Tôi gặp vấn đề tương tự ngày hôm qua với beta 6 :)
JOM

beta 6? :-) thực sự? Tôi chỉ có 5 :)
Bartłomiej Semańchot

Bạn đã bận mã hóa :) Beta 6 không ghi lại tapcho tôi, đã mất một thời gian để tìm ra nó. Thực hành gỡ lỗi tốt!
JOM

Có lẽ bạn biết câu trả lời cho điều này: stackoverflow.com/questions/32219015/iêu ?
Bartłomiej Semańchot

0

Đừng nhầm lẫn, Có một vấn đề được nêu ra là bạn đang ghi lại thời gian thử nghiệm, ứng dụng của bạn sẽ kết nối bàn phím phần cứng trong khi trình giả lập thời gian thử nghiệm tự động của bạn chỉ sử dụng bàn phím phần mềm. Vì vậy, làm thế nào để khắc phục vấn đề này. Chỉ cần sử dụng bàn phím phần mềm về thời gian ghi âm của bạn. bạn có thể thấy điều kỳ diệu


0

Vấn đề đối với tôi cũng giống như với Ted. Trên thực tế nếu trường mật khẩu được gõ sau khi trường đăng nhập và KB phần cứng được bật, bàn phím phần mềm sẽ tự loại bỏ khi chạm vào trường thứ hai và nó không dành riêng cho kiểm tra giao diện người dùng.

Sau một thời gian loay hoay với AppleScript, đây là những gì tôi nghĩ ra (cải tiến rất đáng hoan nghênh):

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

Tạo một tệp tập lệnh với mã ở trên và thêm nó vào các mục tiêu cần thiết (có thể chỉ kiểm tra giao diện người dùng, bạn có thể muốn thêm tập lệnh tương tự vào các mục tiêu phát triển của mình để bật lại bàn phím CT trong quá trình phát triển). Bạn nên thêm Run Scriptpha trong các giai đoạn xây dựng và sử dụng nó như thế này: osascript Path/To/Script/script_name.applescript


0

Chúng tôi đã gặp lỗi tương tự khi đặt accessibilityIdentifiergiá trị cho chế độ xem tùy chỉnh ( UIStackViewlớp con) có chứaUIControl . Trong trường hợp đó, XCTest không thể lấy nét bàn phím cho các phần tử con cháu.

Giải pháp của chúng tôi chỉ đơn giản là loại bỏ accessibilityIdentifierkhỏi chế độ xem cha mẹ của chúng tôi và đặt accessibilityIdentifiercho các cuộc phỏng vấn thông qua các thuộc tính chuyên dụng.


0

Một câu trả lời khác, nhưng đối với chúng tôi, vấn đề là chế độ xem quá gần với chế độ xem khác mà trình nhận dạng cử chỉ trên đó. Chúng tôi thấy rằng chúng tôi cần chế độ xem cách xa ít nhất 20 pixel (trong trường hợp của chúng tôi dưới đây). Nghĩa đen là 15 không hoạt động và 20 hoặc nhiều hơn đã làm. Điều này thật lạ, tôi thừa nhận, nhưng chúng tôi đã có một số UITextView đang hoạt động và một số không phải và tất cả đều nằm dưới cùng một cha mẹ và định vị khác giống hệt nhau (và tất nhiên là tên biến). Bàn phím bật hoặc tắt hoặc bất cứ điều gì không có sự khác biệt. Khả năng tiếp cận cho thấy các lĩnh vực. Chúng tôi khởi động lại máy tính của chúng tôi. Chúng tôi đã xây dựng sạch sẽ. Kiểm tra nguồn tươi.


0

Điều đã khắc phục vấn đề này đối với tôi là thêm một giấc ngủ 1 giây:

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

0

Tôi đã gặp phải vấn đề này và đã có thể khắc phục nó trong kịch bản của mình bằng cách sử dụng giải pháp được đăng bởi @AlexDenisov và thêm nó vào các hành động trước của tôi để chạy & kiểm tra .

nhập mô tả hình ảnh ở đây


0

Không cần bật / tắt bàn phím trong I / O. Không sử dụng .typeText cho safeTextField, chỉ sử dụng

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

Phần thưởng: Bạn nhận được âm thanh bàn phím :)


0

Cuối cùng, tôi đã viết một tập lệnh chỉnh sửa tệp .plist của Trình mô phỏng và đặt ConnectHardwareKeyboard tính thành false cho trình giả lập được chọn. Bạn đã nghe đúng, nó thay đổi thuộc tính cho trình giả lập được chọn cụ thể trong từ điển "DevicePreferences" thay vì chỉnh sửa thuộc tính toàn cầu.

Đầu tiên, tạo một tập lệnh shell có tên là void-hardware-keyboard.sh với các nội dung sau. Bạn có thể đặt nó trong "YourProject / xyzUITests / Sc 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

Bây giờ hãy làm theo các bước sau để gọi nó bằng cách chuyển udid của trình giả lập được chọn làm đối số:

  1. Chỉnh sửa lược đồ Xcode của bạn (hoặc giao diện người dùng kiểm tra lược đồ cụ thể nếu bạn có)
  2. Chuyển đến: Kiểm tra> Hành động trước
  3. Thêm tập lệnh mới bằng cách nhấn vào biểu tượng "+"> "Hành động tập lệnh chạy mới".
  4. Quan trọng: Bên trong thả xuống "Cung cấp cài đặt bản dựng từ" chọn mục tiêu ứng dụng chính của bạn, không phải mục tiêu kiểm tra giao diện người dùng.
  5. Bây giờ thêm đoạn script sau vào vùng văn bản bên dưới.

Tập lệnh bên trong Kiểm tra> Hành động trước:

#!/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

Thời gian để kiểm tra nó:

  1. Khởi chạy giả lập
  2. Kích hoạt bàn phím phần cứng cho nó
  3. Chạy bất kỳ kiểm tra giao diện người dùng với tương tác bàn phím. Quan sát trình mô phỏng khởi động lại và bàn phím phần cứng bị tắt. Và tương tác bàn phím của bài kiểm tra đang hoạt động tốt. :)

-1

Có cùng một vấn đề với Securetextfields. Tùy chọn phần cứng kết nối trong Trình mô phỏng của tôi là của, nhưng vẫn gặp sự cố. Cuối cùng, điều này làm việc cho tôi (Swift 3):

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

Sự khác biệt giữa mã của bạn và mã được hỏi trong câu hỏi.
Shivam Pokhriyal
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.