Question

How are Selenium screenshots handled with multiple instances running on Grid? Say I have a Grid Hub driving a Grid Node with 3 Firefox browsers going simultaneously on one Node machine, how do I get 3 distinct screenshots from each of the 3 node threads?

For example, take this code snippet meant for a single threaded test:

RemoteWebDriver driver;
driver = new RemoteWebDriver(new URL("http://127.1/wd/hub"), DesiredCapabilities
    .firefox() );
driver.get( "http://www.google.com/" );
WebDriver augmentedDriver = new Augmenter().augment(driver);
File screenshot = (TakesScreenshot)augmentedDriver.getScreenshotAs(OutputType
    .FILE);
System.out.println( "Page title is: " + driver.getTitle() );
System.out.println( "Screenshot is located at: " + screenshot.getAbsolutePath());
assertTrue( "Page did not contain string.", driver.getSource().contains( 
    "search") );
driver.quit();
Was it helpful?

Solution 2

First and foremost, Selenium/WebDriver/Selenium Grid would not handle multi-threading for you, its your underlying test framework (TestNG/JUnit/Cucumber etc.) would handle it. WebDriver is not thread-safe, If you are running tests in parallel, you would need to make sure your code is thread-safe.

Going back to your question, the code you wrote would overwrite on the same screenshot file. You would need to copy the file somewhere else with a different name. I would suggest you to prefix the screenshot file with a time stamp with millisecond precision and then copy the screenshot file. This way you would have three unique different screenshots for three different browser instances. This worked for me in the past.

File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
String file_name = "screenshot_"+ Add system_time with millisecond precision 
FileUtils.copyFile(scrFile, new File(file_name));

OTHER TIPS

It will work absolutely fine.

The screenshot is actually the image of that specific driver instance and not a genetic desktop image. You will not see multiple browsers in each screenshot

Here is a snippet from my Utiility code which works perfectly fine

  String path = null;
try {
        File source = ((TakesScreenshot)
                driver).getScreenshotAs(OutputType.FILE);
        Calendar currentDate = Calendar.getInstance();
        SimpleDateFormat formatter = new SimpleDateFormat(
                "yyyy/MMM/dd HH:mm:ss");
        String dateN = formatter.format(currentDate.getTime()).replace("/","_");
        String dateNow = dateN.replace(":","_");
        String snapShotDirectory = Files.screenShotDirectory  + dateNow;

        File f = new File(snapShotDirectory);
        if(f.mkdir()){
        path = f.getAbsolutePath() + "/" + source.getName();
        FileUtils.copyFile(source, new File(path)); 
        }
    }
    catch(IOException e) {
        path = "Failed to capture screenshot: " + e.getMessage();
    }

You can try using it.

Capture the screenshots that You would need to copy the file somewhere else with a different name. The following code help to you.

Create the method of any name. I am creating here captureScreenshot method.

 public static void captureScreenshot(String path) throws IOException{
    try{
        File scrFile= ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);

        FileUtils.copyFile(scrFile, new File(path) );
    }
    catch (Exception e){
        System.out.println("Failed to capture screenshot");
   }

}

Then use this method in your method where you want to take the screenshots. Refer the following line of code. Here I am using the system current time in milliseconds for to save the multiple Images with different name.

captureScreenshot("././screenshots/loginerror_" + System.currentTimeMillis()+".jpg");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top