Search code examples
javamultithreadingseleniumio

Selenium actions multithreading


I would like to open multiple Selenium WebDrivers and process them in different threads. The question is how do Selenium Action class share keyboard/ mouse resources?

public class InterruptInput implements Runnable {

    public static void main(String[] args) {
        // two instances of action will run simultaneously
        new Thread(new InterruptInput()).start();
        new Thread(new InterruptInput()).start();
    }

    @Override
    public void run() {
        // not sure if the same can be replicated using ChromeDriver
        WebDriver driver = new FirefoxDriver();
        Actions act1 = new Actions(driver);
        act1.moveToElement(searchBar)
                .click()
                .sendKeys("G")
                .pause(1000)
                .sendKeys("O")
                .pause(1000)
                .sendKeys("O")
                .pause(1000)
                .sendKeys("G")
                .pause(1000)
                .sendKeys("L")
                .pause(1000)
                .sendKeys("E")
                .pause(1000)
                .perform();
    }
}

The observed result is:

  1. Two browsers will open. Each will type GOOGLE to the search bar in 7 seconds. There are no interference.
  2. If I manually click somewhere on the same page, and move the search bar out of focus, the input will be interrupted.
  3. If I manually open a new tab in one of the browsers, or switch to other apps in the operating system, GOOGLE will finish typing in the background.

How is this achieved? Does this mean I can open as many instances of WebDriver, and not worry about clogging up I/O. How is this different from Java's Robot class, which actively takes over keyboard and mouse control? For the reference, I am using Windows 10. Not sure if this is platform dependent.

The fundamental purpose being, I am writing a simple app that allows the user (me) to scrape some websites, while obviously allowing the user to do other work on the computer.


Solution

  • When you use Actions class you do not use real input devices. The only thing you share is what you have in your code - a WebDriver object that is new for each of your threads so that there is no interference.

    So by performing a "mouse move" you send a command to webdriver that sends the event to a browser that it would receive if you would use the real mouse or keyboard. The real mouse pointer would not move.