简体   繁体   中英

Recursive loop Selenium Webdriver

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

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, eg run every 1 second, but delay 10 seconds under some condition, you may of course add a Thread.sleep(longer) within the task body.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM