Cuộn tùy chỉnh cho phần màn hình
Cuộn tới phần tử trong fragment bằng logic swipe tùy chỉnh khi scrollUntilVisible không hiệu quả.
scrollUntilVisible gốc của Maestro là công cụ mạnh, nhưng nó hoạt động theo một cách cụ thể:
- Kiểm tra phần tử được xác định bởi selector.
- Vuốt lên từ giữa màn hình.
- Quay lại step 1.
Cách này chạy tốt với hầu hết danh sách toàn màn hình, nhưng fail ở các app mà chỉ một phần màn hình cuộn được, như bottom sheet, widget nhỏ cuộn ngang, hoặc UI phân mảnh có nửa trên cố định. Nếu giữa màn hình không cuộn được, lệnh gốc sẽ chỉ chạm lặp đi lặp lại vào một phần tử tĩnh.
Công thức này chỉ cách xây dựng logic cuộn vuốt chính xác ở nơi bạn cần.
Ghi công
Issue này lần đầu được các developer tại Amicara báo cáo. Team của họ đóng vai trò quan trọng trong việc tạo ra giải pháp này để vượt qua khó khăn khi cuộn trong các layout phức tạp, phân mảnh.
Quy trình
Để vượt qua giới hạn vuốt ở giữa, ta tạo lại logic cuộn thủ công bằng một vòng lặp. Thay vì để Maestro quyết định vuốt ở đâu, ta xác định tọa độ màn hình cụ thể để đảm bảo cú vuốt nằm trong container cuộn được.
1. Flow cuộn tái sử dụng
Subflow này (ví dụ scroll_fragment.yaml) nhận TARGET_ID từ flow cha. Nó tiếp tục vuốt trong một vùng giới hạn của màn hình cho đến khi tìm thấy phần tử đích.
# scroll_fragment.yaml
# Cuộn tùy chỉnh cho các vùng màn hình xác định
# Biến môi trường cần có: TARGET_ID (resource id của phần tử cần tìm)
# Bước 1: khởi tạo trạng thái
# Dùng một cờ để theo dõi xem đã tìm thấy đích chưa
- evalScript: ${output.foundElement = 0}
# Bước 2: kiểm tra ngay
# Trước khi bắt đầu di chuyển, xem phần tử đã có ở đó chưa
- runFlow:
when:
visible:
id: "${TARGET_ID}"
commands:
- evalScript: ${output.foundElement = 1}
# Bước 3: vòng lặp có mục tiêu
# Ta tiếp tục vuốt ở vùng phía dưới cho đến khi foundElement thành 1
- repeat:
while:
true: ${output.foundElement == 0}
commands:
# Ta vuốt từ 90% chiều cao màn hình lên 75% chiều cao màn hình.
# Cách này giữ tương tác nằm gọn trong fragment phía dưới.
- swipe:
start: 50%, 90%
end: 50%, 75%
# Kiểm tra lại sau khi di chuyển
# Nếu phần tử hiển thị, ta dừng vòng lặp
- runFlow:
when:
visible:
id: "${TARGET_ID}"
commands:
- evalScript: ${output.foundElement = 1}Cách triển khai này cho bạn toàn quyền kiểm soát cơ chế cuộn. Trong lệnh swipe, dùng phần trăm như 90% và 75% đảm bảo hành vi nhất quán trên các kích thước device khác nhau. Bằng cách nhắm vào phần dưới của màn hình, bạn tránh vô tình tương tác với header tĩnh hoặc vùng hero không cuộn được. Ngoài ra, cờ tìm kiếm (${output.foundElement}) đóng vai trò cầu nối giữa step runFlow, kiểm tra hiển thị, và vòng lặp repeat, điều khiển hành động cuộn.
Mẹo: điều chỉnh theo nhu cầu
Nếu vùng tĩnh trong app của bạn khác, hãy điều chỉnh cấu hình lệnh swipe cho phù hợp.
Mẹo: tránh vuốt vô hạn
Dù không thể hiện trong đoạn cơ bản này, bạn có thể dễ dàng thêm một bộ đếm vào vòng lặp repeat để ném error nếu không tìm thấy phần tử sau 10 hay 20 lần vuốt, tránh để test bị treo vô thời hạn.
2. Triển khai
Để dùng helper này trong flow chính, gọi nó bằng runFlow và truyền TARGET_ID của phần tử cần tìm dưới dạng biến môi trường.
# main_test.yaml
- tapOn: "Open Settings"
# Tìm một thiết lập cụ thể ở cuối fragment cuộn được
- runFlow:
file: ../utils/scroll_fragment.yaml
env:
TARGET_ID: "logout_button"
# Khi subflow kết thúc, phần tử đã chắc chắn hiển thị
- tapOn:
id: "logout_button"Nội dung liên quan
Khám phá các trang tài liệu sau nếu một số khái niệm dùng trong công thức này chưa rõ với bạn:
