Giới Thiệu
Khi kiểm thử ứng dụng web, DOM không phải lúc nào cũng đơn giản như nó có vẻ. Đôi khi, phần tử mà bạn nhìn thấy trong DevTools không thể truy cập được từ bài kiểm thử của bạn. Tại sao? Bởi vì nó bị bao bọc bên trong iframes hoặc shadow DOM.
Trong bài viết này, chúng ta sẽ phân tích shadow DOM là gì, tại sao nó quan trọng và cách bạn có thể kiểm thử nó với Cypress.
Shadow DOM là gì?
Shadow DOM là một cây con được đóng gói của DOM sống bên trong một phần tử chứa. Nó được giới thiệu như một phần của chuẩn Web Components và hiện đang được sử dụng rộng rãi trong các thư viện UI hiện đại như Material UI, Ionic, Lit và các thành phần Angular.
Lợi ích chính của Shadow DOM:
- CSS và JS được giới hạn (không bị rò rỉ toàn cầu)
- Các thành phần có thể tái sử dụng
- Cấu trúc được ẩn khỏi DOM “chính”
Hãy tưởng tượng nó như một mini DOM bên trong DOM.
Các loại Shadow DOM
DOM bình thường (baseline)
html
<div id="login">
<input id="username" />
</div>
Cypress:
javascript
cy.get('#username').type('hello')
Shadow DOM (mở)
html
<my-login>
#shadow-root (open)
<input id="username" />
</my-login>
Lựa chọn A: Sử dụng .shadow() trong Cypress
javascript
cy.get('my-login')
.shadow()
.find('#username')
.type('hello')
Lựa chọn B: Kích hoạt toàn cục trong cypress.config.js
javascript
module.exports = {
e2e: {
includeShadowDom: true
}
}
Shadow DOM (đóng)
html
<my-login>
# — - > shadow-root (closed)
<input id="username" />
</my-login>
⚠️ Các shadow root đóng không thể truy cập được với Cypress hoặc các bộ chọn truy vấn thông thường. Chúng được thiết kế để riêng tư. Giải pháp: Bạn cần sử dụng kiểm thử cấp thành phần hoặc dựa vào ứng dụng cung cấp các móc kiểm thử (ví dụ: props hoặc thuộc tính).
Các phần tử được chèn
Đôi khi các phần tử được “dự kiến” vào một shadow DOM thông qua một slot:
html
<my-login>
#shadow-root (open)
<slot name="email"></slot>
</my-login>
<input slot="email" id="email-input" />
Lệnh tùy chỉnh Cypress:
javascript
Cypress.Commands.add('getSlottedElement', (selector) => {
return cy.get(selector).then(($el) => {
return cy.wrap($el[0].assignedNodes()[0])
})
})
Sử dụng:
javascript
cy.getSlottedElement('#email-input').type('hello@qa.com')
Tại sao Shadow DOM quan trọng trong tự động hóa
- Nó xuất hiện khắp nơi trong các SPA hiện đại và Web Components
- Các bài kiểm thử của bạn có thể thất bại với thông báo “không tìm thấy phần tử” nếu bạn không tính đến nó
- Xử lý shadow DOM đúng cách giúp các bài kiểm thử ổn định và bảo vệ tương lai.
Nhớ rằng:
- DOM ≠ không phải lúc nào cũng là các phần tử có thể truy cập
- Ứng dụng web có thể bao gồm: DOM thông thường, iframes, Shadow DOM (mở/đóng)
- Cypress hỗ trợ shadow DOM mở với
.shadow()hoặc thuộc tính cấu hìnhincludeShadowDom - Đối với các phần tử được chèn, bạn có thể cần các trợ giúp tùy chỉnh.
.shadow()không thể nhìn thấy nội dung được chèn trực tiếp, vì nó sống bên ngoài shadow root và chỉ được dự kiến vào đó - Đối với shadow DOM đóng, hợp tác với các nhà phát triển để có các móc kiểm thử.
Nếu bạn mới làm quen với tự động hóa:
Bắt đầu thử nghiệm với Cypress và một ví dụ Web Component đơn giản.
Bạn sẽ nhanh chóng thấy lý do tại sao việc xử lý shadow DOM là một kỹ năng cần thiết.
Thực hành tốt nhất
- Đảm bảo bạn luôn kiểm tra xem một ứng dụng có sử dụng shadow DOM hay không trước khi viết bài kiểm thử.
- Sử dụng các lệnh tùy chỉnh để xử lý các phần tử được chèn vào shadow DOM một cách hiệu quả.
Cạm bẫy phổ biến
- Quên kiểm tra shadow DOM có thể dẫn đến lỗi trong bài kiểm thử của bạn.
- Không sử dụng các phương pháp truy vấn thông thường cho shadow DOM đóng.
Mẹo hiệu suất
- Tối ưu mã của bạn bằng cách chỉ định các phần tử cụ thể mà bạn muốn kiểm tra.
- Sử dụng các lệnh Cypress một cách hợp lý để giảm thiểu thời gian thực hiện bài kiểm thử.
Khắc phục sự cố
- Nếu bạn gặp lỗi “phần tử không tìm thấy”, hãy kiểm tra xem bạn đã truy cập đúng shadow DOM hay chưa.
- Đối với shadow DOM đóng, hãy làm việc với các nhà phát triển để có các móc kiểm thử thích hợp.
Câu hỏi thường gặp (FAQ)
Shadow DOM có thể sử dụng trong những tình huống nào?
Shadow DOM thường được sử dụng trong các ứng dụng web hiện đại và các thư viện UI như Angular, Lit.
Làm thế nào để kiểm thử một ứng dụng sử dụng shadow DOM?
Sử dụng các lệnh Cypress như .shadow() và các lệnh tùy chỉnh để truy cập các phần tử bên trong shadow DOM.
Có cách nào truy cập shadow DOM đóng không?
Không thể truy cập trực tiếp shadow DOM đóng. Bạn cần hợp tác với các nhà phát triển để có các móc kiểm thử.
Kết Luận
Việc hiểu và làm chủ shadow DOM là một kỹ năng quan trọng trong lĩnh vực kiểm thử tự động hóa hiện đại. Hãy bắt đầu thực hành với các ứng dụng sử dụng shadow DOM và tích lũy thêm kinh nghiệm cho mình!