Lấy phần tử khớp cuối cùng
Chọn phần tử cuối cùng trong danh sách bằng index selector và JavaScript.
Trong một flow, nhắm vào một view cụ thể thường đơn giản nhờ index. Ví dụ, nếu muốn nút Add to Basket thứ ba, bạn chỉ cần dùng index: 2:
- tapOn:
text: Add to Basket
index: 2 # Mục thứ 3. Index bắt đầu từ 0Nhưng với danh sách có số mục thay đổi, như giỏ hàng, chuỗi tin nhắn hay thư viện ảnh, bạn không biết trước mục cuối là số mấy. Dùng một subflow dùng lại được để tìm index của mục cuối, rồi chạm vào mục đó.
Quy trình
Astra Scout không có index: last, nên bạn tự tìm index cuối bằng cách thử lần lượt từng index. Logic là một vòng lặp:
- Bắt đầu từ
index: 0. - Kiểm tra phần tử có tồn tại ở index hiện tại không.
- Nếu có, tăng bộ đếm và kiểm tra
indextiếp theo. - Khi một
indexkhông hiện ra (not visible), index ngay trước đó là cái cuối cùng.
1. Flow tìm kiếm tái sử dụng
Tạo một subflow tiện ích (ví dụ utils/find_last_element.yaml) chứa toàn bộ vòng lặp. Subflow này tìm index cuối rồi trả về cho flow chính.
# utils/find_last_element.yaml
# Cách dùng: truyền SELECTOR_TYPE ("id" hoặc "text") và SELECTOR_VALUE
# Kết quả: index được lưu trong ${output.lastElementIndex}
# Bước 1: trước hết cần khởi tạo trạng thái tìm kiếm
- evalScript: ${output.lastElementIndex = -1}
- evalScript: ${output._findLastElement_complete = false}
# Bước 2: kiểm tra loại đầu vào để tránh lỗi
# Ví dụ này chỉ hỗ trợ selector "id" và "text"
- runFlow:
when:
true: ${SELECTOR_TYPE != "id" && SELECTOR_TYPE != "text"}
commands:
- evalScript: |
throw new Error("Invalid SELECTOR_TYPE: " + SELECTOR_TYPE + ". Must be 'id' or 'text'");
# Bước 3: vòng lặp tìm kiếm
# Lặp cho đến khi gặp một index không tồn tại.
- repeat:
while:
true: ${!output._findLastElement_complete}
commands:
# Kiểm tra phần tử có tồn tại ở index hiện tại (selector id)
- runFlow:
when:
true: ${SELECTOR_TYPE == "id"}
commands:
- runFlow:
when:
visible:
id: "${SELECTOR_VALUE}"
index: ${output.lastElementIndex + 1}
commands:
# Tìm thấy phần tử, cập nhật index và tiếp tục
- evalScript: ${output.lastElementIndex = output.lastElementIndex + 1}
- runFlow:
when:
notVisible:
id: "${SELECTOR_VALUE}"
index: ${output.lastElementIndex + 1}
commands:
# Không thấy phần tử. Việc tìm kiếm kết thúc
- evalScript: ${output._findLastElement_complete = true}
# Kiểm tra phần tử có tồn tại ở index hiện tại (selector text)
- runFlow:
when:
true: ${SELECTOR_TYPE == "text"}
commands:
- runFlow:
when:
visible:
text: "${SELECTOR_VALUE}"
index: ${output.lastElementIndex + 1}
commands:
# Tìm thấy phần tử, cập nhật index và tiếp tục
- evalScript: ${output.lastElementIndex = output.lastElementIndex + 1}
- runFlow:
when:
notVisible:
text: "${SELECTOR_VALUE}"
index: ${output.lastElementIndex + 1}
commands:
# Không thấy phần tử. Việc tìm kiếm kết thúc
- evalScript: ${output._findLastElement_complete = true}
# Bước 4: kiểm tra cuối cùng
- runFlow:
when:
true: ${output.lastElementIndex == -1}
commands:
- evalScript: |
throw new Error("No elements found matching: " + SELECTOR_VALUE);Về bản chất, subflow này thử lần lượt từng index cho đến khi hết (tìm tuyến tính), viết bằng YAML của flow. Các điểm chính:
- Nó dùng biến
outputlàm bộ đếm. Giá trị đặt bằngevalScriptđược giữ suốt lúc flow chạy, nên lần lặp sau dùng tiếp được index đã tăng. repeatvới điều kiệnwhiledựa trên một cờ boolean (_findLastElement_complete, ban đầu làfalse) lặp cho đến khi hết danh sách, nên danh sách dài bao nhiêu cũng được.- Nếu vòng lặp kết thúc mà index vẫn là
-1(không tìm thấy phần tử nào), subflow báo một error rõ ràng và dừng, thay vì chạy tiếp với dữ liệu sai.
2. Triển khai
Gọi subflow bằng runFlow, rồi dùng ${output.lastElementIndex} ở command tiếp theo. Bạn cần truyền loại selector (id hoặc text) và giá trị của nó.
# main_test.yaml
# Tìm nút "Remove" cuối cùng trong giỏ hàng và chạm vào nó
- runFlow:
file: ../utils/find_last_element.yaml
env:
SELECTOR_TYPE: "text"
SELECTOR_VALUE: "Remove"
- tapOn:
text: "Remove"
index: ${output.lastElementIndex}Nội dung liên quan
Các trang về những thành phần được dùng ở đây:
- Vòng lặp: các cách lặp trong flow, gồm
whilevà lặp theo số lần. - Tổng quan JavaScript: dùng JavaScript để giữ trạng thái trong flow.
- Cách dùng selector: cách Astra Scout nhận diện và phân biệt các phần tử UI giống nhau.
