2016-03-08 112 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