2010-11-05 42 views
14

Chúng tôi đang sử dụng Selenium với API Java và một số tiện ích mở rộng người dùng Javascript. Chúng tôi sử dụng rất nhiều cuộc gọi AJAX trong ứng dụng của mình. Rất nhiều thử nghiệm của chúng tôi thất bại ngẫu nhiên vì đôi khi các cuộc gọi AJAX kết thúc chậm hơn các lần khác để trang không được tải đầy đủ. Chúng tôi khắc phục điều đó bằng cách đợi các phần tử cụ thể hoặc Thread.sleep. Tôi đã cố gắng tìm một cách để thay vào đó chỉ cần chờ cho lưu lượng truy cập mạng để kết thúc. Vì vậy mà chúng ta có thể làm điều này:Selenium - Đợi lưu lượng truy cập mạng

selenium.click("some JS button"); 
selenium.waitForNetwork(); 
assertTrue(something); 

Bằng cách đó chúng ta có thể thoát khỏi sợi giấc ngủ và có bài kiểm tra qua nhanh hơn khi máy chủ đáp ứng nhanh hơn và không có quá nhiều thử nghiệm thất bại do các vấn đề thời gian.

Tôi chưa thể tìm cách để thực hiện điều này khi tìm kiếm trên Google. Có ai có bất kỳ ý tưởng làm thế nào chúng ta có thể thực hiện điều này? (Tốt hơn là thông qua Javascript hoặc API Java nhưng tất cả các đề xuất đều được chào đón).

Lưu ý: các biến thể khác của "waitFor" không phải là những gì tôi đang tìm kiếm. Chúng tôi đã sử dụng chúng trong các lần nhấp và những thứ khác. Tôi đang tìm kiếm thứ gì đó chờ đợi cho GIAO THÔNG MẠNG. Cảm ơn tất cả các phản hồi, tôi sẽ thử một vài gợi ý, nhưng tôi vẫn mở cho các ý tưởng khác.

Cảm ơn.

Trả lời

2

Cập nhật: Tôi sử dụng phương pháp tương tự (wrapRequest) theo cùng cách với Selenium2 và nó vẫn hoạt động. Sự khác biệt duy nhất là tôi không sử dụng tiện ích mở rộng người dùng. Tôi chỉ cần thực hiện javascript để truy vấn mã được nạp bởi JSP.

Đây là những gì chúng tôi đã kết thúc. (Lưu ý, có nhiều cách dễ dàng hơn để nhận được nếu cuộc gọi Ajax đang chạy nếu bạn luôn sử dụng một khung duy nhất như JQuery. Chúng tôi phải jimmy-rig thêm một chút nữa vì chúng tôi có một vài trang sử dụng JQuery và một nhóm sử dụng GWT)

Tôi đã tạo tệp Javascript mà mọi trang chỉ tải nếu bạn đang thử nghiệm. (Tôi đã làm điều này bằng cách bao gồm một đoạn trong mẫu JSP của chúng tôi: nếu tham số chuỗi truy vấn thử nghiệm được chuyển thành đúng, đặt cookie. Nếu cookie đó được đặt, bao gồm tệp javascript) Tệp javascript này về cơ bản bao bọc đối tượng XMLHttpRequest để giữ số lượng tất cả các yêu cầu gửi:

function wrapRequest(xmlRequest) { 
    var oldSend = xmlRequest.prototype.send; 
    xmlRequest.prototype.send = function() { 
     var oldOnReady = this.onreadystatechange; 
     oldOnReady = function() { 
      oldOnReady.apply(this, arguments); 
      // if call is complete, decrement counter. 
     } 
     // increment counter 
     if(oldSend.apply) 
      oldSend.apply(this, arguments); 
     else if (oldOnReady.handleEvent) { //Firefox sometimes will need this 
      oldOnReady.handleEvent.apply(this, arguments); 
     } 
    } 
} 

Có nhiều hơn một chút so với nếu async == sai, nhưng điều đó phải dễ dàng tìm ra.

Sau đó, tôi đã thêm một chức năng để các selen sử dụng extensions.js mà chỉ đơn giản trông như thế này:

Selenium.prototype.getIsNetworkReady = function() { 
    if(this.browserbot.topWindow.isNetworkReady) { //sometimes this method is called before the page has loaded the isNetworkReady function 
     return this.browserbot.topWindow.isNetworkReady(); 
    } 
    return false; 
} 

Ngoài ra, hãy chú ý kiểm tra trên topWindow: đây là bởi vì bạn sẽ có được các vấn đề khi một khung nội tuyến được chọn.

Ngoài ra, bạn sẽ phải gọi phương thức wrapRequest trên đối tượng XMLHttpRequest của mọi iFrame được tải. Tôi làm điều đó ngay bây giờ bằng cách sử dụng: document.addEventListener("DOMNodeInserted", onElementAdded, true); và sau đó trong onElementAdded tôi chỉ lấy khung nội tuyến khi nó được nạp và vượt qua trong đối tượng XMLHttpRequest. nhưng điều đó không hoạt động trong IE vì vậy tôi đang tìm kiếm một giải pháp thay thế. Nếu bất cứ ai biết cách tốt hơn để làm điều đó vì vậy nó hoạt động trong cả IE và FF tôi rất thích nghe nó.

Dù sao, đó là ý chính của việc triển khai. Hy vọng điều này sẽ giúp mọi người trong tương lai.

0

Vâng, làm một cái gì đó như thế này (giả):

int i = 0; 
while (element is not yet present) { 
    i++; 
    if (i>TRESHOLD) { 
    throw an exception 
    } 
    Thread.sleep(200); 
} 
//go on 

Bạn propably muốn nhét nó vào một hàm.

4

Có vài loại waitFor có sẵn trong Selenium. Trong trường hợp thử nghiệm của bạn nếu bạn biết rằng một văn bản cụ thể sẽ xuất hiện khi tải trang, bạn có thể sử dụng waitForText. Nếu có các phần tử DOM khác nhau nhận được dân cư (thông qua Ajax/pageload), bạn có thể thêm tuần tự waitForText.

1

Chúng tôi đã có mã phía máy khách để thay đổi con trỏ chuột trong khi yêu cầu AJAX (sử dụng a4j:status với các thuộc tính onstartonstop). Do đó, chúng tôi chỉ có thể đợiĐối với giá trị của biểu thức JavaScript

window.document.body.style.cursor 

Tuy nhiên, tôi thấy rằng điều này không hoạt động đáng tin cậy, tức là đôi khi quá trình kiểm tra diễn ra quá sớm. Tôi không chắc chắn về nguyên nhân, nhưng nghi ngờ rằng việc cập nhật DOM không nhất thiết phải được thực hiện đầy đủ khi yêu cầu onstop.

Để giảm sự chậm trễ không cần thiết, bạn có thể tự thực hiện bỏ phiếu và thăm dò ý kiến ​​thường xuyên hơn selen.

4

Sau khi thử tất cả các biến được mô tả trên trang này, chúng tôi đã kết thúc với chiến lược này:

Tiêm một javascript đặc biệt mà về cơ bản sẽ ghi đè tất cả các phương pháp khuôn khổ có liên quan của bạn và giữ một truy cập của số lượng yêu cầu chưa hoàn thành, được tăng lên khi bắt đầu và giảm dần khi hoàn thành. Do tính chất không đồng bộ của javascript, nó là không phải đủ để giữ biến boolean, bạn có khả năng kết thúc với các điều kiện chủng tộc trong logic của riêng bạn.

Nếu bạn đang sử dụng hiệu ứng hình ảnh, có thể bạn cũng muốn thực hiện điều này cho hiệu ứng hình ảnh; morphing/fading và các hình ảnh khác sẽ có cùng một vấn đề.

Vì vậy, về cơ bản chúng tôi thực hiện "nhấp chuột" thông thường và sau đó luôn đợi bộ đếm này tiếp cận lại 0 lần nữa, sử dụng javascript giống như những gợi ý khác được đề xuất ở đây. Sau khi chúng tôi có được điều này tại chỗ, chúng tôi đã giảm các vấn đề tạm thời về không. Hãy nhớ rằng selen không quay trở lại từ "click" cho đến khi tất cả các sự kiện onclick đồng bộ được xử lý, vì vậy bạn phải đảm bảo rằng các bộ đếm này tăng lên như một hệ quả trực tiếp của onclick.

Để có hướng dẫn về cách ghi đè các phương pháp khuôn khổ bạn cần tham khảo tài liệu khung của bạn; chúng tôi sử dụng addMethods trong nguyên mẫu. Có thể ghi đè điều này trong một javascript đặc biệt chỉ được thêm vào trang khi chạy thử nghiệm.

+0

Chúng tôi làm điều tương tự cho khung AJAX được xây dựng trong nhà của chúng tôi, gọi hàm IsTheCountZeroYet() trong WaitForCondition(). Tôi hiểu bạn có thể làm điều đó với jQuery dễ dàng. Các khung công tác khác, cũng có thể. –

+0

Điều thú vị là các bộ đếm ajax trong prototype.js là lỗi, chúng không luôn quay trở lại 0.Và các hiệu ứng hình ảnh không có loại truy cập nào được nêu ra. Vì vậy, chúng tôi đã phải cuộn của riêng mình. – krosenvold

1

Điều này có thể không phù hợp với bạn, nhưng vì những vấn đề tương tự chúng tôi đã chuyển đến Selenium 2 (aka WebDriver). Chúng tôi sử dụng PageFactory với AjaxElementLocatorFactory

Để thực hiện một sự chuyển đổi dễ dàng hơn, có một Selenium Emulation và kế hoạch là hoàn toàn hợp nhất Selenium 1 và WebDriver đó là mục tiêu chính của Selenium 2.

Các vấn đề liên quan