Bỏ qua, đến nội dung

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 xác định phần tử UI mà một command tác động lên, ví dụ đích của tapOn, assertVisible, copyTextFrom hoặc scrollUntilVisible. Astra Scout dùng accessibility tree của device để tìm phần tử, nên flow tương tác với app giống như người dùng thật.

Trang này liệt kê các trường selector mà Astra Scout hỗ trợ trên Android và iOS. Cú pháp giống hệt flow YAML của Maestro.

Hỗ trợ trong một bảng ​

SelectorAndroidiOSGhi chú
textCóCóBiểu thức chính quy, khớp toàn bộ chuỗi.
idCóCóBiểu thức chính quy.
indexCóCóĐánh số từ 0.
pointCóCóTọa độ, dùng cho tapOn và các command tương tự.
above, below, leftOf, rightOfCóCóVị trí so với một phần tử mốc.
childOf, containsChild, containsDescendantsCóCóQuan hệ trong cây phân cấp.
enabled, selected, focusedCóCóTrạng thái boolean.
checkedCóKhôngBị bỏ qua trên iOS kèm warning.
width, height, toleranceCóCóKích thước theo pixel do accessibility tree báo cáo.
traitsKhôngKhôngĐược parse nhưng không bao giờ dùng để khớp. Xem Không hỗ trợ.
cssKhôngKhôngChỉ dành cho web; Astra Scout không chạy flow web.

Khi flow dùng một trường selector mà nền tảng hiện tại không hỗ trợ, trường đó bị bỏ qua và log của run hiện warning như "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ể khớp một phần tử khác với dự kiến của bạn.

Core selectors ​

Biểu thức chính quy

text và id dựa trên regex nên xử lý giá trị động khá dễ. Nhớ escape các ký tự đặc biệt như $ hoặc [ bằng dấu gạch chéo ngược (\).

Đặc thù theo nền tảng

  • Flutter: Dùng text hiển thị hoặc Semantics Labels (cho text), hoặc Semantics Identifiers (cho id). Các key nội bộ của Flutter không được hỗ trợ.
  • Android Compose: Dùng Modifier.semantics { testTagsAsResourceId = true } để test tag của bạn tìm được dưới dạng ID.

text ​

Selector text tìm phần tử theo chuỗi hiển thị trên màn hình. Trên Android, chuỗi này gồm cả contentDescription; trên iOS gồm cả accessibilityLabel.

  • Mặc định là regex: mọi text selector đều được coi là biểu thức chính quy.
  • Viết tắt: bạn có thể bỏ key và truyền thẳng một chuỗi cho các command như tapOn hoặc assertVisible.
yaml
- tapOn: Login              # Viết tắt (khớp chính xác "Login")
- tapOn:
    text: ".*Continue.*"    # Regex để khớp một phần
- assertVisible: Submit     # Viết tắt để kiểm tra hiển thị

id ​

Selector id nhắm tới mã định danh kỹ thuật của một view. Nên dùng cho nội dung động, icon không có chữ, và app đa ngôn ngữ nơi text hiển thị đổi theo ngôn ngữ.

  • Android: ánh xạ tới resource ID.
  • iOS: ánh xạ tới accessibilityIdentifier.
yaml
- tapOn:
    id: login_button
- assertVisible:
    id: header_icon

index ​

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.

yaml
# Chạm vào phần tử thứ ba có ID "buy_button"
- tapOn:
    id: buy_button
    index: 2

point ​

Selector point nhắm tới tọa độ màn hình. Dùng cho phần tử không nằm 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".
yaml
- 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 250

Relational selectors ​

Relational selector xác định một view theo quan hệ với view khác. Hữu ích khi các phần tử có tên chung chung (như nhiều nút "Buy") hoặc 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.

SelectorMô tả
aboveKhớp view nằm phía trên phần tử mốc theo chiều dọc.
belowKhớp view nằm phía dưới phần tử mốc theo chiều dọc.
leftOfKhớp view nằm bên trái phần tử mốc.
rightOfKhớp view nằm bên phải phần tử mốc.
containsChildKhớp phần tử cha có một phần tử con trực tiếp khớp tiêu chí đã cho.
childOfKhớp phần tử là con trực tiếp của phần tử cha đã cho.
containsDescendantsKhớ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

  • Selector kết hợp: các selector vị trí (above, below, leftOf, rightOf) so sánh theo vùng hiển thị trên màn hình. leftOf chỉ có nghĩa "bên trái" theo tọa độ, không nhất thiết ngay cạnh hay thẳng hàng với phần tử mốc. Kết hợp với các trường khác (id, text, enabled, v.v.) để chính xác hơn: tapOn: { id: "icon", rightOf: "Settings", enabled: true }.
  • Độ tin cậy của phần tử mốc: dùng phần tử ổn định nhất (thường là text tĩnh hoặc ID duy nhất) làm mốc.

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:

yaml
# 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: Checkout

leftOf và rightOf khớp các view nằm cạnh nhau, ví dụ icon bên cạnh nhãn:

yaml
# 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 terms

Bạn có thể lồng above hoặc below để kiểm tra thứ tự theo chiều dọc:

yaml
- assertVisible:
    text: Top Thing
    above:
      text: Middle Thing
      above:
        text: Bottom Thing

Quan hệ cha - con ​

Các selector này duyệt accessibility tree thay vì 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.

yaml
# Chạm vào container chứa trực tiếp text "Order 12345"
- tapOn:
    containsChild:
      text: Order 12345

childOf (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.

yaml
# Chạm vào nút Delete bên trong Basket
- tapOn:
    text: Delete
    childOf:
      id: basket_container

containsDescendants ​

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 và bố cục nhóm nơi các phần tử liên quan được lồng bên trong.

yaml
# 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.99

State 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, một thao tác trước đó đã cập nhật nó, hoặc tìm một phần tử trong số nhiều phần tử giống hệt nhau (ví dụ tab đang được chọn). Mọi state selector đều nhận giá trị boolean.

SelectorAndroidiOSMô tả
enabledCóCóPhần tử có tương tác được hay bị làm mờ.
selectedCóCóPhần tử có được đánh dấu là đã chọn không (tab, segmented control).
focusedCóCóPhần tử có đang giữ focus nhập bàn phím không.
checkedCóKhôngTrạ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 }.

yaml
# 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: true

Trên Android, checked hoạt động với checkbox, radio button và switch:

yaml
- assertVisible:
    id: remember_me_checkbox
    checked: true

Lưu ý

checked không được hỗ trợ trên iOS. Trường này bị bỏ qua kèm warning, nên step đó khớp bất kể trạng thái bật/tắt. Trên iOS, hãy kiểm tra label hoặc giá trị hiển thị của phần tử thay thế.

Dimension matchers ​

Dimension selector khớp phần tử theo kích thước trên màn hình.

SelectorMô tả
widthKhớp phần tử có chiều rộng cụ thể theo pixel.
heightKhớp phần tử có chiều cao cụ thể theo pixel.
toleranceCho 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

Cẩn thận với giá trị pixel cố định khi chạy flow trên các device có mật độ màn hình khác nhau. Kết hợp width và height với các selector khác, và dùng tolerance cao hơn để flow ổn định giữa các device.

width và height khớp theo kích thước pixel do accessibility tree báo cáo:

yaml
# 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: 350

tolerance đặt một biên độ, vì nút 100px có thể báo 99px hoặc 101px tùy theo tỷ lệ scale. Với tolerance: 5, mọi phần tử nằm trong khoảng cộng trừ 5 pixel so với kích thước đích đều khớp.

yaml
# Khớp icon vuông 48px, chừa 2px sai lệch
- assertVisible:
    id: settings_icon
    width: 48
    height: 48
    tolerance: 2

Không hỗ trợ ​

Các trường selector này của Maestro không có trong Astra Scout:

  • traits (text, long-text, square): trường này được parse nhưng không dùng để khớp, nên step chạy như thể không có nó. Hãy dùng text, id, width/height với tolerance, hoặc relational selector thay thế.
  • css: chỉ dành cho web app. Astra Scout chạy flow Android và iOS.

Các command nhận selector xem ở tham chiếu command.