11/08/2018, 21:15

Sử dụng XPath với Capybara để lấy và kiểm tra DOM element có chứa chuỗi

Capybara là công cụ lợi hại cho dân lập trình Web với Ruby, thư viện này có đi kèm các hàm selector giúp người dùng dễ dàng tương tác với các phần tử DOM. Thư viện cung cấp 2 kiểu tìm kiếm DOM, thứ nhất là sử dụng CSS Selector và thứ hai là XPath. Hầu hết các trường hợp đơn giản thì chỉ cần sử ...

Capybara là công cụ lợi hại cho dân lập trình Web với Ruby, thư viện này có đi kèm các hàm selector giúp người dùng dễ dàng tương tác với các phần tử DOM.

Thư viện cung cấp 2 kiểu tìm kiếm DOM, thứ nhất là sử dụng CSS Selector và thứ hai là XPath. Hầu hết các trường hợp đơn giản thì chỉ cần sử dụng CSS Selector và một số helper hỗ trợ như within là đủ, nhưng có một số trường hợp cá biệt thì CSS Selector không thể tìm thấy DOM. Hôm nay chúng ta sẽ xem xét một trường hợp, đó là lựa chọn DOM có chứa một chuỗi ở trong một phần tử nằm trong nó, vd lấy tất cả link có từ khoá My Link chẳng hạn:

<a href="#my_link">My Link</a>
<a href="#my_link">Alternative Link</a>

Các bạn có thể thấy là trong trường hợp trên chúng ta không thể áp dụng CSS selector vì attribute href đều giống trong 2 link, nên chúng ta sẽ tiếp cận theo hướng khác.

Để tìm phần tử thì chỉ cần sử dụng hàm find đi kèm theo option :xpath như sau:

find(:xpath, '//Xpath')

Để giải quyết bài trên, cái XPath của chúng ta sẽ như sau:

find(:xpath, '//a[@href="#my_link" and contains(., "My Link")]')

Phân tích XPath ở trên, câu XPath bắt đầu với cú pháp //, cú pháp này có nghĩa là chọn một phần từ bất kì trên document, sau đó chúng ta chọn phần tử chúng ta cần tìm, đó là a, sau đó chúng ta khai báo các điều kiện chúng ta quan tâm của phần tử này thông qua các điều kiện khai báo trong []. Các attribute hiện hành của phần tử được khai báo với từ khoá @ ở trước, vd: @href. Và các điều kiện tiếp nối theo thì phải được liên kết với bằng operator and hoặc or. Điều kiện thứ hai của chúng ta là contains(., "My Link"), nhìn có vẻ khó hiểu nhỉ?. Từ khoá contains nhận vào 2 option, đầu tiên là phần tử mà người dùng muốn kiểm tra, và thứ hai là chuỗi muốn tìm. Ở đây, option đầu là ., có nghĩa là lấy phần từ (node) hiện hành, hay a của chúng ta, rồi bảo Capybara tìm xem có cái phần tử a nào chứa từ khoá My Link hay không.

Vẫn còn nhiều cú pháp khác của XPath mà chúng ta sẽ không thể nào giới thiệu đủ trong bài này, các bạn có thể đọc thêm tại trang W3C XPath tutorial nếu thích.

Câu hỏi cuối cùng là có nhất thiết phải dùng XPath không? Còn cách nào khác không? Câu trả lời là không vì Capybara có cung cấp một số hàm helper rút gọn, như ở trên thì chỉ cần dùng hàm:

find('a[href="#my_link"', text: "My Link"')

Xin tham khảo thêm tại Capybara::Node::Finders.

Xin lưu ý là các hàm kiểm tra sự hiện diện của DOM như hàm has_selector? cũng nhận :xpath, hoặc bạn có thể sử dụng phiên bản explictiy has_xpath?

Hi vọng các bạn học được một mẹo mới hôm nay.

0