Rào cản lớn nhất trong việc thử nghiệm ExtJS với Selenium là ExtJS không hiển thị các phần tử HTML tiêu chuẩn và Selenium IDE sẽ tạo ra các lệnh một cách ngây thơ (và đúng đắn) nhằm vào các phần tử chỉ hoạt động như trang trí - các phần tử thừa giúp ExtJS với toàn bộ màn hình- xem và cảm nhận. Dưới đây là một số mẹo và thủ thuật mà tôi đã thu thập được khi viết thử nghiệm Selenium tự động với ứng dụng ExtJS.
Mẹo chung
Định vị các phần tử
Khi tạo các trường hợp kiểm tra Selenium bằng cách ghi lại các hành động của người dùng với Selenium IDE trên Firefox, Selenium sẽ căn cứ các hành động đã ghi trên id của các phần tử HTML. Tuy nhiên, đối với hầu hết các phần tử có thể nhấp, ExtJS sử dụng các id được tạo như "ext-gen-345" có khả năng thay đổi trong lần truy cập tiếp theo vào cùng một trang, ngay cả khi không có thay đổi mã nào được thực hiện. Sau khi ghi lại các thao tác của người dùng để kiểm tra, cần phải có một nỗ lực thủ công để thực hiện tất cả các thao tác phụ thuộc vào id đã tạo và để thay thế chúng. Có hai loại thay thế có thể được thực hiện:
Thay thế Bộ định vị ID bằng Bộ định vị CSS hoặc XPath
Trình định vị CSS bắt đầu bằng "css =" và trình định vị XPath bắt đầu bằng "//" (tiền tố "xpath =" là tùy chọn). Bộ định vị CSS ít dài dòng hơn và dễ đọc hơn và nên được ưu tiên hơn bộ định vị XPath. Tuy nhiên, có thể có những trường hợp cần sử dụng bộ định vị XPath vì bộ định vị CSS đơn giản là không thể cắt nó.
Thực thi JavaScript
Một số yếu tố yêu cầu nhiều hơn các tương tác chuột / bàn phím đơn giản do kết xuất phức tạp do ExtJS thực hiện. Ví dụ, một Ext.form.CombBox không thực sự là một <select>
phần tử mà là một đầu vào văn bản với danh sách thả xuống tách rời nằm ở đâu đó ở cuối cây tài liệu. Để mô phỏng chính xác lựa chọn ComboBox, trước tiên có thể mô phỏng một lần nhấp vào mũi tên thả xuống và sau đó nhấp vào danh sách xuất hiện. Tuy nhiên, việc định vị các phần tử này thông qua các trình định vị CSS hoặc XPath có thể phức tạp. Một giải pháp thay thế là định vị chính thành phần ComoBox và gọi các phương thức trên đó để mô phỏng lựa chọn:
var combo = Ext.getCmp('genderComboBox'); // returns the ComboBox components
combo.setValue('female'); // set the value
combo.fireEvent('select'); // because setValue() doesn't trigger the event
Trong Selenium, runScript
lệnh có thể được sử dụng để thực hiện thao tác trên ở dạng ngắn gọn hơn:
with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
Đối phó với AJAX và Kết xuất chậm
Selenium có hương vị "* AndWait" cho tất cả các lệnh chờ tải trang khi hành động của người dùng dẫn đến chuyển đổi trang hoặc tải lại. Tuy nhiên, vì các lần tìm nạp AJAX không liên quan đến tải trang thực tế, nên không thể sử dụng các lệnh này để đồng bộ hóa. Giải pháp là sử dụng các manh mối trực quan như sự hiện diện / vắng mặt của chỉ báo tiến trình AJAX hoặc sự xuất hiện của các hàng trong lưới, các thành phần bổ sung, liên kết, v.v. Ví dụ:
Command: waitForElementNotPresent
Target: css=div:contains('Loading...')
Đôi khi một phần tử sẽ chỉ xuất hiện sau một khoảng thời gian nhất định, tùy thuộc vào tốc độ ExtJS hiển thị các thành phần sau khi một hành động của người dùng dẫn đến thay đổi chế độ xem. Thay vì sử dụng độ trễ trọng tài với pause
lệnh, phương pháp lý tưởng là đợi cho đến khi yếu tố quan tâm nằm trong tầm nắm bắt của chúng ta. Ví dụ, để nhấp vào một mục sau khi đợi nó xuất hiện:
Command: waitForElementPresent
Target: css=span:contains('Do the funky thing')
Command: click
Target: css=span:contains('Do the funky thing')
Việc dựa vào các khoảng tạm dừng tùy ý không phải là một ý tưởng hay vì sự khác biệt về thời gian dẫn đến việc chạy các bài kiểm tra trong các trình duyệt khác nhau hoặc trên các máy khác nhau sẽ làm cho các trường hợp kiểm tra không ổn định.
Các mục không thể nhấp
Một số phần tử không thể được kích hoạt bằng click
lệnh. Đó là bởi vì trình xử lý sự kiện thực sự ở trên vùng chứa, theo dõi các sự kiện chuột trên các phần tử con của nó, cuối cùng sẽ bong bóng đến cha mẹ. Điều khiển tab là một ví dụ. Để nhấp vào một tab, bạn phải mô phỏng một mouseDown
sự kiện tại nhãn tab:
Command: mouseDownAt
Target: css=.x-tab-strip-text:contains('Options')
Value: 0,0
Xác thực trường
Các trường biểu mẫu (thành phần Ext.form. *) Có các biểu thức chính quy được liên kết hoặc các loại vtype để xác thực sẽ kích hoạt xác thực với độ trễ nhất định (xem thuộc validationDelay
tính được đặt thành 250ms theo mặc định), sau khi người dùng nhập văn bản hoặc ngay lập tức khi trường bị mất tiêu điểm - hoặc làm mờ (xem thuộc validateOnDelay
tính). Để kích hoạt xác thực trường sau khi phát lệnh loại Selenium để nhập một số văn bản bên trong trường, bạn phải thực hiện một trong các thao tác sau:
Kích hoạt xác thực bị trì hoãn
ExtJS kích hoạt bộ đếm thời gian trễ xác thực khi trường nhận được các sự kiện keyup. Để kích hoạt bộ đếm thời gian này, chỉ cần đưa ra một sự kiện keyup giả (không quan trọng bạn sử dụng phím nào vì ExtJS bỏ qua nó), sau đó là một khoảng dừng ngắn dài hơn validationDelay:
Command: keyUp
Target: someTextArea
Value: x
Command: pause
Target: 500
Kích hoạt xác thực ngay lập tức
Bạn có thể đưa một sự kiện mờ vào trường để kích hoạt xác thực ngay lập tức:
Command: runScript
Target: someComponent.nameTextField.fireEvent("blur")
Kiểm tra kết quả xác thực
Sau khi xác thực, bạn có thể kiểm tra sự hiện diện hay vắng mặt của trường lỗi:
Command: verifyElementNotPresent
Target: //*[@id="nameTextField"]/../*[@class="x-form-invalid-msg" and not(contains(@style, "display: none"))]
Command: verifyElementPresent
Target: //*[@id="nameTextField"]/../*[@class="x-form-invalid-msg" and not(contains(@style, "display: none"))]
Lưu ý rằng việc kiểm tra "display: none" là cần thiết vì một khi trường lỗi được hiển thị và sau đó nó cần được ẩn đi, ExtJS sẽ chỉ ẩn trường lỗi thay vì xóa hoàn toàn trường đó khỏi cây DOM.
Mẹo dành riêng cho từng yếu tố
Nhấp vào một Ext.form.Button
lựa chọn 1
Lệnh: bấm vào Mục tiêu: css = button: chứa ('Lưu')
Chọn nút theo chú thích của nó
Lựa chọn 2
Lệnh: nhấp vào nút Target: css = # save-options
Chọn nút theo id của nó
Chọn giá trị từ Ext.form.ComboBox
Command: runScript
Target: with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
Đầu tiên đặt giá trị và sau đó kích hoạt rõ ràng sự kiện được chọn trong trường hợp có người quan sát.