Selectors
Xác định phần tử UI bằng selector cơ bản, quan hệ và trạng thái trên Android và iOS.
Selector cho Astra Scout biết command cần tác động lên phần tử nào trên màn hình, ví dụ phần tử để tapOn, assertVisible, copyTextFrom hoặc scrollUntilVisible.
Để tìm phần tử, Astra Scout đọc accessibility tree của device. Đó là danh sách các phần tử mà hệ điều hành mô tả cho công cụ hỗ trợ như VoiceOver, kèm chữ, ID và vị trí của từng phần tử. Vì vậy selector khớp với những gì người dùng thấy hoặc những gì developer đã gắn nhãn trong app.
Astra Scout hỗ trợ các trường selector sau trên Android và iOS. Bạn viết selector trong flow YAML.
Hỗ trợ trong một bảng
| Selector | Android | iOS | Ghi chú |
|---|---|---|---|
text | Có | Có | Khớp theo regex, phải khớp toàn bộ chuỗi. |
id | Có | Có | Khớp theo regex. |
index | Có | Có | Đánh số từ 0. |
point | Có | Có | Tọa độ, dùng cho tapOn và các command tương tự. |
above, below, leftOf, rightOf | Có | Có | Vị trí so với một phần tử mốc. |
childOf, containsChild, containsDescendants | Có | Có | Quan hệ trong cây phân cấp. |
enabled, selected, focused | Có | Có | Trạng thái boolean. |
checked | Có | Không | Bị bỏ qua trên iOS kèm warning. |
width, height, tolerance | Có | Có | Kích thước theo pixel do accessibility tree báo cáo. |
traits | Không | Không | Bị bỏ qua. Xem Không hỗ trợ. |
css | Không | Không | Chỉ dành cho web. Astra Scout không chạy flow web. |
Nếu flow dùng một trường mà nền tảng hiện tại không hỗ trợ, Astra Scout bỏ qua trường đó và ghi warning vào log của run, ví dụ "checked" is not supported on ios. Step vẫn chạy với các trường còn lại, nên có thể chọn nhầm phần tử.
Core selectors
Regex
text và id được hiểu là regex (biểu thức chính quy): một mẫu mô tả chuỗi chữ, ví dụ .* là "bất kỳ ký tự nào, bất kỳ số lần nào". Dùng regex để khớp chữ thay đổi, như Welcome back, .*. Nếu chữ cần tìm có ký tự đặc biệt như $, [ hoặc (, đặt dấu gạch chéo ngược (\) trước nó, ví dụ \$99.
Đặc thù theo nền tảng
- Flutter: dùng text hiển thị hoặc Semantics Label cho
text, Semantics Identifier choid. Astra Scout không hỗ trợKeycủa Flutter. - Android Compose: thêm
Modifier.semantics { testTagsAsResourceId = true }để test tag dùng được nhưid.
text
Selector text tìm phần tử theo chữ hiển thị trên màn hình. Trên Android, chữ này gồm cả contentDescription; trên iOS gồm cả accessibilityLabel (nhãn mô tả mà developer gắn cho phần tử).
- Luôn là regex: mọi
textđều được hiểu là regex và phải khớp toàn bộ chữ của phần tử. - Viết tắt: bỏ key
textvà truyền thẳng chuỗi cho các command nhưtapOnhoặcassertVisible.
- tapOn: Login # Viết tắt (khớp đúng chữ "Login")
- tapOn:
text: ".*Continue.*" # Regex, khớp phần tử có chữ chứa "Continue"
- assertVisible: Submit # Viết tắt để kiểm tra hiển thịid
Selector id nhắm tới mã định danh mà developer gắn cho một view. Nên dùng cho nội dung thay đổi, icon không có chữ, và app đa ngôn ngữ (chữ hiển thị đổi theo ngôn ngữ).
- Android: là resource ID.
- iOS: là
accessibilityIdentifier.
- tapOn:
id: login_button
- assertVisible:
id: header_iconindex
Khi nhiều phần tử khớp cùng tiêu chí (ví dụ ba nút Add to Cart trên một màn hình), index chọn một trong số đó. Index đánh số từ 0.
# Chạm vào phần tử thứ ba có ID "buy_button"
- tapOn:
id: buy_button
index: 2point
Selector point nhắm tới một tọa độ trên màn hình. Dùng cho phần tử không có trong accessibility tree, hoặc để chạm một vùng cụ thể của view lớn.
- Vị trí tương đối: phần trăm, ví dụ
"50%, 50%"cho tâm màn hình. - Tọa độ tuyệt đối: pixel chính xác, ví dụ
"100, 200".
- tapOn:
point: "50%, 50%" # Chạm vào tâm màn hình
- tapOn:
point: "100, 250" # Chạm cách mép trái 100 pixel, cách mép trên 250Relational selectors
Relational selector tìm một view theo vị trí hoặc quan hệ với view khác. Dùng khi nhiều phần tử có tên giống nhau (như nhiều nút "Buy"), hoặc phần tử không có text hay id ổn định nhưng luôn nằm gần một phần tử mốc đã biết.
| Selector | Mô tả |
|---|---|
above | Khớp view nằm phía trên phần tử mốc theo chiều dọc. |
below | Khớp view nằm phía dưới phần tử mốc theo chiều dọc. |
leftOf | Khớp view nằm bên trái phần tử mốc. |
rightOf | Khớp view nằm bên phải phần tử mốc. |
containsChild | Khớp phần tử cha có một phần tử con trực tiếp khớp tiêu chí đã cho. |
childOf | Khớp phần tử là con trực tiếp của phần tử cha đã cho. |
containsDescendants | Khớp view chứa tất cả các phần tử con, cháu đã cho, ở mọi độ sâu. |
Mẹo sử dụng
- Kết hợp nhiều trường: các selector vị trí (
above,below,leftOf,rightOf) so sánh theo tọa độ trên màn hình.leftOfchỉ có nghĩa là "nằm bên trái", không nhất thiết sát cạnh hay thẳng hàng với phần tử mốc. Kết hợp vớiid,text,enabled... để chọn chính xác hơn:tapOn: { id: "icon", rightOf: "Settings", enabled: true }. - Chọn mốc ổn định: dùng phần tử ít thay đổi nhất làm mốc, thường là chữ cố định hoặc ID duy nhất.
Alignment selectors
above và below khớp các view nằm phía trên hoặc phía dưới một phần tử tham chiếu:
# Chạm vào view nằm dưới nhãn "Email"
- tapOn:
below: Email
# Chạm vào view nằm trên tiêu đề "Checkout"
- tapOn:
above: CheckoutleftOf và rightOf khớp các view nằm cạnh nhau, ví dụ icon bên cạnh nhãn:
# Chạm vào view bên phải một ô nhập liệu
- tapOn:
rightOf:
id: input_text
# Chạm vào view bên trái một cụm từ cụ thể
- tapOn:
leftOf: I agree to the termsBạn có thể lồng above hoặc below để kiểm tra thứ tự theo chiều dọc:
- assertVisible:
text: Top Thing
above:
text: Middle Thing
above:
text: Bottom ThingQuan hệ cha - con
Các selector này dựa vào quan hệ cha - con trong accessibility tree, không dựa vào vị trí trên màn hình.
containsChild (chỉ con trực tiếp)
Khớp phần tử cha có một phần tử con trực tiếp khớp selector đã cho.
# Chạm vào container chứa trực tiếp text "Order 12345"
- tapOn:
containsChild:
text: Order 12345childOf (chỉ cha trực tiếp)
Khớp phần tử là con trực tiếp của một phần tử cha cụ thể. Hữu ích khi cùng một phần tử con xuất hiện trong nhiều container.
# Chạm vào nút Delete bên trong Basket
- tapOn:
text: Delete
childOf:
id: basket_containercontainsDescendants
Khớp view chứa tất cả các phần tử con, cháu đã chỉ định ở mọi độ sâu, không chỉ con trực tiếp. Dùng cho card, hàng danh sách và các nhóm có nhiều phần tử lồng bên trong.
# Tìm một mục trong danh sách chứa cả tên sản phẩm và giá
- assertVisible:
id: list_item
containsDescendants:
- text: Wireless Headphones
- text: $99.99State selectors
State selector lọc phần tử theo trạng thái hiện tại. Dùng để kiểm tra phần tử đã sẵn sàng, thao tác trước đã làm nó đổi trạng thái, hoặc chọn một phần tử trong nhiều phần tử giống nhau (ví dụ tab đang được chọn). Giá trị luôn là true hoặc false.
| Selector | Android | iOS | Mô tả |
|---|---|---|---|
enabled | Có | Có | Phần tử bấm được, hay đang bị làm mờ. |
selected | Có | Có | Phần tử đang được chọn (tab, segmented control). |
focused | Có | Có | Phần tử đang nhận bàn phím. |
checked | Có | Không | Trạng thái bật/tắt của checkbox, radio button và switch. |
Mẹo sử dụng
State selector hoạt động tốt nhất khi kết hợp với core selector, ví dụ tapOn: { text: "Next", enabled: true }.
# Kiểm tra nút đăng nhập ban đầu đang bị vô hiệu hóa
- assertVisible:
id: login_button
enabled: false
# Chạm vào nút khi nó đã active
- tapOn:
id: login_button
enabled: true
# Xác nhận ô tìm kiếm đang có focus
- assertVisible:
id: search_input
focused: true
# Chỉ tìm tab Profile nếu nó đang được chọn
- tapOn:
text: Profile
selected: trueTrên Android, checked hoạt động với checkbox, radio button và switch:
- assertVisible:
id: remember_me_checkbox
checked: trueLưu ý
checked không hỗ trợ trên iOS. Trường này bị bỏ qua kèm warning, nên step khớp dù đang bật hay tắt. Trên iOS, kiểm tra chữ hoặc giá trị hiển thị của phần tử.
Dimension matchers
Dimension selector khớp phần tử theo kích thước trên màn hình, tính bằng pixel.
| Selector | Mô tả |
|---|---|
width | Khớp phần tử có chiều rộng cụ thể theo pixel. |
height | Khớp phần tử có chiều cao cụ thể theo pixel. |
tolerance | Cho phép chênh lệch nhỏ do render hoặc làm tròn khi khớp kích thước. |
Mẹo sử dụng
Kích thước pixel cố định dễ sai khi flow chạy trên device có độ phân giải khác nhau. Kết hợp width, height với selector khác và đặt tolerance đủ rộng.
width và height khớp theo kích thước (pixel) mà accessibility tree báo về:
# Chạm vào nút rộng đúng 200px
- tapOn:
id: action_button
width: 200
# Kiểm tra header hồ sơ cao 350px
- assertVisible:
id: profile_header
height: 350tolerance cho phép sai lệch một chút, vì nút 100px có thể báo 99px hoặc 101px tùy tỷ lệ scale của màn hình. Với tolerance: 5, phần tử có kích thước lệch không quá 5 pixel so với giá trị bạn ghi đều khớp.
# Khớp icon vuông 48px, chừa 2px sai lệch
- assertVisible:
id: settings_icon
width: 48
height: 48
tolerance: 2Không hỗ trợ
Hai trường selector sau không dùng được trong Astra Scout:
traits(text,long-text,square): Astra Scout bỏ qua trường này, nên step chạy như thể không có nó. Dùngtext,id,width/heightkèmtolerance, hoặc relational selector.css: chỉ dành cho web. Astra Scout chạy flow Android và iOS.
Danh sách command nhận selector nằm ở tham chiếu command.
