0

This is my code.

public static void test1() throws IOException {
    System.setProperty("webdriver.chrome.driver", "data/chromedriver.exe");
    drive = new ChromeDriver();
    drive.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
    try {
        drive.get("http://youtube.com");
    }catch(TimeoutException e) {
        printSS();
    }

}

public static void printSS() throws IOException{
    String path = "logs/ss/";
    File scrFile = ((TakesScreenshot)drive).getScreenshotAs(OutputType.FILE);
    FileUtils.copyFile(scrFile, new File(path + "asdasdas" + ".jpg"));
}

All time when driver.get() throw TimeoutException I want to take a screenshot at browser.

But when throw TimeoutException, getScreenshotAs() from printSS() don't take screenshot because throw another TimeoutException.

Why getScreenshotAs() throw TimeoutException and how to take screenshot at browser

P.S.: Increase pageLoadTimeout time is not the answer I want.

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
KunLun
  • 3,109
  • 3
  • 18
  • 65
  • I found something. After driver.get throw TimeoutException, all methods from drive throw TimeoutException. This is normal? If yes, how can stop page from loading and continue execution? – KunLun Mar 16 '18 at 15:48

2 Answers2

2

While working with Selenium 3.x, ChromeDriver 2.36 and Chrome 65.x you need to mention the relative path of the location (with respect of your project) where you intend to store the screenshot.

I took you code and did a few minor modification as follows :

  • Declared driver as WebDriver instance as static and added @Test annotation.
  • Reduced pageLoadTimeout to 2 seconds to purposefully raise the TimeoutException.
  • Changed the location of String path to a sub-directory wthin the project scope as follows :

    String path = "./ScreenShots/";
    
  • Added a log as :

    System.out.println("Screenshot Taken");
    
  • Here is the code block :

     package captureScreenShot;
    
     import java.io.File;
     import java.io.IOException;
     import java.util.concurrent.TimeUnit;
    
     import org.apache.commons.io.FileUtils;
     import org.openqa.selenium.OutputType;
     import org.openqa.selenium.TakesScreenshot;
     import org.openqa.selenium.TimeoutException;
     import org.openqa.selenium.WebDriver;
     import org.openqa.selenium.chrome.ChromeDriver;
     import org.testng.annotations.Test;
    
     public class q49319748_captureScreenshot 
     {
    
        public static WebDriver drive;
    
        @Test
        public static void test1() throws IOException {
            System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
            drive = new ChromeDriver();
            drive.manage().timeouts().pageLoadTimeout(2, TimeUnit.SECONDS);
            try {
                drive.get("http://youtube.com");
            }catch(TimeoutException e) {
            printSS();
            }
    
        }
    
        public static void printSS() throws IOException{
            String path = "./ScreenShots/";
            File scrFile = ((TakesScreenshot)drive).getScreenshotAs(OutputType.FILE);
            FileUtils.copyFile(scrFile, new File(path + "asdasdas" + ".jpg"));
            System.out.println("Screenshot Taken");
        }
     }
    
  • Console Output :

     [TestNG] Running:
       C:\Users\username\AppData\Local\Temp\testng-eclipse--153679036\testng-customsuite.xml
    
     Starting ChromeDriver 2.36.540470 (e522d04694c7ebea4ba8821272dbef4f9b818c91) on port 42798
     Only local connections are allowed.
     Mar 16, 2018 5:37:59 PM org.openqa.selenium.remote.ProtocolHandshake createSession
     INFO: Detected dialect: OSS
     Screenshot Taken
    PASSED: test1
    
  • Screenshot :

asdasdas


Reference

You can find a detailed discussion in How to take screenshot with Selenium WebDriver

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • This don't help me because I don't have junit. I have a simple java project with a class with name Test which contain this `public class Test { public static WebDriver drive; public static void main(String[] args) throws IOException { test1(); } public static void test1() throws IOException {...} public static void printSS() throws IOException{...} }` – KunLun Mar 16 '18 at 12:52
0

The problem is that while Selenium waits for the page to complete loading it cannot take any other command. This is why it throws TimeoutException also from the exception handler when you try take the screenshot. The only option I see is to take the screenshot not through Selenium, but using other means that take a screenshot of the entire desktop. I've written such a thing in C#, but I'm pretty sure you can either find a way to do it in Java too.

Arnon Axelrod
  • 1,444
  • 2
  • 13
  • 21
  • I can does with Robot library. – KunLun Mar 19 '18 at 10:08
  • What if it's in headless mode? Wouldn't that void a screenshot from the system? Also in .NET standard, how would you get around the issue of being on various platforms? – Dan Oct 03 '22 at 13:33
  • @Dan Good question :) Just thought that maybe `ChromeOptions.PageLoadStartegry = Eager` or `None` may help you avoid the `TimeoutException` and free the browser to take a screenshot sooner, but you'd then need to handle waiting for the entire page to complete loading in other means (e.g. using `ExecuteAsyncScript` to wait for `document.ReadyState` to become `true`). Never tried tweaking `PageLoadStrategy` though, so it's just an educated guess... – Arnon Axelrod Oct 03 '22 at 14:50