2016-03-08 81 views
0

我有一個測試,加載一個頁面並搜索一個元素。如果它不存在,請等待一段時間,然後返回並重新搜索。如果元素存在,則輸出文本,然後等待一段時間並重複測試。遞歸循環Selenium Webdriver

我對我的硒腳本的理由是不斷地從顯示當前查看者數量的控制檯上刮取網頁,並控制每個~10分鐘保存的變量。我希望遞歸地執行此操作,因爲一旦運行一次,測試就會完成。我希望這個運行只要我想要它,並隨時停止它。任何幫助將不勝感激

//Search for channel (Change below to a new channel) 
      driver.findElement(By.id("channelName")).clear(); 
      driver.findElement(By.id("channelName")).sendKeys("ch123"); 

//Label - updateViewer 
     updateViewer(); 
//Verify that viewer count is listed 
//Label checkViewer 
     checkViewer(); 
//Once viewer is updated, loop back to updateViewer and below 
     loopInterval(); 
    } 

    @After 
    public void tearDown() throws Exception { 
     driver.quit(); 
     String verificationErrorString = verificationErrors.toString(); 
     if (!"".equals(verificationErrorString)) { 
      fail(verificationErrorString); 
     } 
    } 

    private boolean isElementPresent(By by) { 
     try { 
      driver.findElement(by); 
      return true; 
     } catch (NoSuchElementException e) { 
      return false; 
     } 
    } 

    private void updateViewer() throws InterruptedException { 
     System.out.println("Getting current viewer count"); 
     driver.findElement(By.id("gobutton")).click(); 
     for (int second = 0;; second++) { 
      if (second >= 60) fail("timeout"); 
      try { if (isElementPresent(By.xpath("//table[@id='datatable1']/tbody/tr/td[4]"))) break; } catch (Exception e) {} 
      Thread.sleep(1000); 
     } 
    } 

    private void checkViewer() throws InterruptedException { 
     boolean viewElement = isElementPresent(By.xpath("//table[@id='datatable1']/tbody/tr/td[4]")); 
     if(!viewElement){ 
      System.out.println("no view element, refreshing page"); 
      updateViewer(); 
     } 
     else{ 
      String viewers = driver.findElement(By.xpath("//table[@id='datatable1']/tbody/tr/td[4]")).getText(); 
      System.out.println(viewers); 
      //-- placement to write current timestamp and date + viewers to file -- 

      // -- placement method that calls updateViewer and checkViewer in a loop -- 
     } 
    } 

    private void loopInterval() throws InterruptedException { 
     updateViewer(); 
     checkViewer(); 
    } 
+1

嘗試使用[線程](https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html) – 4castle

回答

1

我沒有看到任何遞歸這裏,只安排重複。如果您的代碼成爲任務調度程序管理的任務(如ScheduledExecutorService),它肯定會簡化您的代碼。你可以去掉你的代碼中的所有循環和睡眠。

ScheduledExecutorService sched = Executors.newScheduledThreadPool(1); // single-threaded OK 

final ScheduledFuture<?> future = sched.scheduleAtFixedRate(new Runnable() { 
    public void run() { 
     if (canDoStuffNow) { 
      doStuffNow(); 
     } 
     else { 
      // Skip, wait another second 
     } 
    } 
}, /* Delay for */ 0, /* Every */ 1, TimeUnit.SECONDS); 

這將可靠地運行,在只要你需要它固定的速率(每秒)。如果您需要取消,請致電future.cancel(true)

如果您需要不同程度的延遲,例如每隔1秒運行一次,但在某些情況下延遲10秒,您當然可以在任務主體內添加Thread.sleep(longer)

+0

在閱讀本文之前,我嘗試過使用Timer和TimerTask,但它看起來在運行腳本時,它永遠不會到達任務時間。你還會推薦一個timertask的ScheduledExecutorService嗎? – user2683183

+0

是的。 Timer/TimerTask仍然有效,但現在並不理想。請參閱:http://stackoverflow.com/a/409993/954442和http://stackoverflow.com/q/6111645/954442 –

+1

這爲我工作謝謝! – user2683183