2013-01-22 20 views
10

Ngoài việc sử dụng sleep() trong thử nghiệm của mình, tôi tự hỏi liệu có ai biết chiến lược tốt hơn để chờ gửi biểu mẫu (POST) hoàn tất trước không tiếp tục với các xác nhận của tôi. Đây là một phiên bản rất cô đọng của những gì thử nghiệm của tôi trông giống như, sử dụng phpunit với nhau php-webdriver từ Facebook).php-webdriver: chờ phản hồi của trình duyệt sau khi gửi biểu mẫu bằng cách nhấp vào()

function test_form_submission() 
{ 
    // setup 
    $web_driver = new WebDriver(); 
    $session = $web_driver->session(); 
    $session->open('http://example.com/login'); 

    // enter data 
    $session->element('css selector', 'input[name=email]')->value(array('value' => str_split('[email protected]'))); 
    $session->element('css selector', 'input[name=password]')->value(array('value' => str_split('testpassword'))); 

    // click button to submit form 
    $session->element('css selector', 'button[name=submit]')->click(); 

    // How do I wait here until the click() above submits the form 
    // so I can check that we correctly arrives at the destination below 
    // without resorting to sleep()? 

    // Confirm that login was successful because we landed on account page 
    $this->assertSame('http://example.com/account', $session->url()); 

    // teardown 
    $session->close(); 
} 
+1

Vì vậy, khi bạn thực thi mã này ngay bây giờ, url trong dòng thứ hai đến dòng cuối cùng (xác nhận) cho http://example.com/login thay vì http://example.com/account? Có lẽ máy chủ Selenium phải đợi cho đến khi trang được tải trước khi tìm kiếm phần tử. Ngoại lệ cho đó là các yêu cầu không đồng bộ, nhưng yêu cầu của bạn trông khá đồng bộ. Hãy nhớ bạn, tôi đang sử dụng PHPUnit_Selenium để điều khiển Selenium – qrazi

+0

Chính xác. Trong thực tế, tôi có thể chụp ảnh màn hình tại thời điểm đó và thấy rằng tôi vẫn đang ở trên example.com/login, nhưng nếu tôi ngủ trong 1 giây, xác nhận sẽ chuyển và ảnh chụp màn hình hiển thị trang hiện đang được hiển thị. com/tài khoản. Tôi đọc rằng PHPUnit_Selenium không phải là khá lên để chạy Selenium 2 (aka webdriver) vì vậy đó là lý do tại sao tôi đã đi với cách tiếp cận ở trên. –

Trả lời

0

Thay vì click() chúng ta có thể sử dụng clickAndWait(), để chờ cho đến khi trang tiếp theo đã được tải.

+0

Tôi không chắc chắn rằng làm việc với php-webdriver. Tôi nhận được lỗi sau: "Ngoại lệ: clickAndWait không phải là lệnh webdriver hợp lệ". –

1

Bạn có thể sử dụng Implicit Wait and Explicit Wait để chờ một Yếu tố web cụ thể cho đến khi nó xuất hiện trên trang. Khoảng thời gian chờ bạn có thể xác định và điều đó phụ thuộc vào ứng dụng.

Explicit Chờ:

Một chờ đợi rõ ràng là mã bạn xác định để chờ đợi một điều kiện nhất định để xảy ra trước khi tiếp tục trong các mã. Nếu điều kiện đạt được nó sẽ chấm dứt sự chờ đợi và tiến hành các bước tiếp theo.

Code:

WebDriverWait wait = new WebDriverWait(driver,30); 
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(strEdit))); 

Hoặc

WebElement myDynamicElement = (new WebDriverWait(driver, 30)) 
.until(new ExpectedCondition<WebElement>(){ 
@Override 
public WebElement apply(WebDriver d) { 
    return d.findElement(By.id("myDynamicElement")); 
}}); 

này chờ lên đến 30 giây trước khi ném một TimeoutException hoặc nếu nó tìm thấy nguyên tố này sẽ trả lại nó trong 0-30 giây. WebDriverWait theo mặc định gọi ExpectedCondition cứ sau 500 mili giây cho đến khi nó trả về thành công. Trả về thành công là kiểu ExpectedCondition là Boolean trả về true hoặc không trả về giá trị null cho tất cả các kiểu ExpectedCondition khác.

Bạn có thể sử dụng lớp ExpectedConditions khi cần cho ứng dụng.

Implicit Chờ:

Một chờ đợi ngầm là để nói WebDriver để thăm dò ý kiến ​​DOM trong một khoảng thời gian nhất định khi cố gắng tìm một phần tử hoặc các yếu tố nếu họ không có sẵn ngay lập tức

Mã số:

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); 

Một điều cần lưu ý là một khi chờ đợi ngầm được thiết lập - nó sẽ vẫn cho đời sống của các đối tượng dụ WebDriver

Để biết thêm thông sử dụng liên kết này http://seleniumhq.org/docs/04_webdriver_advanced.jsp

+6

Tôi đã yêu cầu cụ thể cho một giải pháp PHP sử dụng php-webdriver. –

2

Được rồi, vì vậy tôi biết đây là một câu hỏi rất cũ, nhưng như tôi stumbled khi nó thông qua Google Tôi hy vọng rằng điều này vẫn có thể có ích cho một ai đó (thậm chí có thể OP? :-)).

Sau khi một số bài viết và tin nhắn tìm kiếm và đọc trên Google Code, tôi đã tìm thấy một giải pháp mà tôi cho là khá xấu, nhưng không thực sự là một giải pháp thay thế tốt. Bạn có thể đọc here rằng WebDriver không thể phát hiện khi trang đã tải. Vì vậy, chúng ta phải trở lại chờ đợi. Bây giờ, OP đang sử dụng PHP WebDriver của Facebook, mà không bao gồm các tiện ích chờ đợi AFAIK, nhưng khi sử dụng this maintained clone, bạn sẽ có được một triển khai WebDriverWait.

Bây giờ câu hỏi đặt ra là: chúng ta chờ đợi điều gì? Bạn có thể đợi URL thay đổi, nhưng điều này không phải là cách tiếp cận đáng tin cậy vì trang có thể chưa được tải khi URL đã thay đổi. Tùy chọn tiếp theo: chờ phần tử bạn biết đang ở trên trang được tải để xuất hiện. Điều đó sẽ hiệu quả, nhưng nếu bạn muốn có cách tiếp cận chung hơn thì sao? May mắn thay, tôi đọc một ý tưởng rất hay in the thread Tôi đã đề cập ở trên. Bạn có thể đợi một phần tử trên cả hai trang biến mất và xuất hiện lại, ví dụ như chân trang.

Tôi đã triển khai tính năng này ngay bây giờ và có vẻ như nó hoạt động. Chức năng dưới đây có thể được thông qua $session của bạn và sẽ chỉ trở lại khi trang mới được tải (hoặc ít nhất, chân trang có sẵn một lần nữa).

public static function waitForNextPage($pWDSession) { 
    $aWait = new PHPWebDriver_WebDriverWait($pWDSession); 
    // wait for footer to not be available anymore 
    $aWait->until(
      function($pWDSession) { 
       return (0 === count($pWDSession->elements(PHPWebDriver_WebDriverBy::CSS_SELECTOR, "#footer,#mx-footer"))); 
      } 
     ); 
    // wait for footer to be available again 
    $aWait->until(
      function($pWDSession) { 
       return (0 < count($pWDSession->elements(PHPWebDriver_WebDriverBy::CSS_SELECTOR, "#footer,#mx-footer"))); 
      } 
     ); 
} 

Bạn rõ ràng có thể thay đổi bộ chọn hoặc sử dụng một số phần tử khác, ý tưởng vẫn giữ nguyên.

Tôi hy vọng điều đó sẽ hữu ích! Chúc mừng!

19

php-webdriver từ Facebook đã được viết lại vào tháng 6 năm 2013. Bạn có thể đợi URL dễ dàng như thế này.

// wait for at most 10 seconds until the URL is 'http://example.com/account'. 
// check again 500ms after the previous attempt. 
$driver->wait(10, 500)->until(function ($driver) { 
    return $driver->getCurrentURL() === 'http://example.com/account'; 
}) 
+0

Điều gì xảy ra nếu url được tạo động? ví dụ: site.com/item?id=123&color=black&size=small – Purefan

+1

Khớp URL bằng cụm từ thông dụng. – whhone

+0

Câu trả lời hay nhất ít nhất là để chờ đợi! –