0

I have a test that loads a page and searches for an element. If it is not present, wait a time interval and then go back and search again. If the element is present output the text, and then wait a time interval and repeat the test.

My reason for my selenium script is to continually scrape a webpage from a console that displays amount of current viewers, and console out the variable saved every ~10 minutes. I want to do this recursively since the test will complete once it runs through one time. I want this to run as long as I want it to, and stop it at will. Any help would be greatly appreciated

//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();
    }
user2683183
  • 243
  • 2
  • 7
  • 23
  • 1
    Try using a [Thread](https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html) – 4castle Mar 08 '16 at 22:22

1 Answers1

1

I don't see any recursion here, only scheduled repetition. It would definitely simplify your code if your code became a task managed by a task scheduler, like a ScheduledExecutorService. You could strip all the loops and sleeps from your code.

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);

That will run reliably, at a fixed rate (every second) for as long as you need it to. Just call future.cancel(true) if you need to cancel it.

If you need different levels of delay, e.g. run every 1 second, but delay 10 seconds under some condition, you may of course add a Thread.sleep(longer) within the task body.

Andrew Regan
  • 5,087
  • 6
  • 37
  • 73
  • Before I read this, I tried to use a Timer and a TimerTask, but it appears that when running the script, it never reaches the timertask. Would you still recommend ScheduledExecutorService over a timertask? – user2683183 Mar 10 '16 at 21:11
  • Yes. Timer/TimerTask still works, but it's not ideal nowadays. See: http://stackoverflow.com/a/409993/954442 and http://stackoverflow.com/q/6111645/954442 – Andrew Regan Mar 10 '16 at 22:04