在计算机锁定时是否可以通过编程方式截取屏幕截图?

时间:2018-12-19 00:01:02

标签: java selenium selenium-webdriver automated-tests

我正在隔夜(使用Java和WebDriver)运行Selenium测试,并希望在其中一个测试用例失败时拍摄屏幕截图。如果我使用Robot的createScreenCapture()方法,则只有在显示器打开的情况下它才有效;如果我使用Selenium的getScreenshotAs()方法,则它不会捕获任何弹出窗口或窗口顶部的任何内容(并且通常包含问题的原因)。当计算机锁定时,getScreenshotAs()方法可以正常工作,这就是我当前正在使用的方法。如果这很重要,我的机器将运行Windows 7。

我修改了此代码(可在本网站上找到),并且目前正在使用它:

WebDriver driver = new FirefoxDriver();
driver.get("http://www.google.com/");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// Now you can do whatever you need to do with it, for example copy somewhere
FileUtils.copyFile(scrFile, new File("c:\\tmp\\screenshot.png"));

这是我以前使用的方式,但是如果PC被锁定,它只会捕获灰色屏幕,并且任务栏位于底部,但是如果我登录,它会很好地工作并捕获所有内容。问题是我需要整夜锁定计算机,也就是需要运行以下代码的时间:

Robot robot = new Robot();
// Get size of screen
Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
// Capture the screen
BufferedImage screenFullImage = robot.createScreenCapture(screenRect);
// Save the screen to to disk
ImageIO.write(screenFullImage, "jpg", new File(fileName));

我在这里找到了其他一些问类似问题的帖子,但是它们都已经很老了,与我的问题不太匹配,所以我想知道在这些情况下是否有解决方案?


编辑: 当我使用机器人代码时,这些就是结果。我尝试同时使用Chrome作为浏览器(ChromeDriver)和Firefox(FirefoxDriver)。

Chrome浏览器: Screenshot Using Google Chrome

Firefox: enter image description here

如果我自己单独在一个类中运行屏幕截图的机器人版本,则只是一个每5秒捕获一次屏幕的循环(“运行方式”> Java应用程序),即使锁定了计算机,它也可以正常工作,但是当当测试失败时,我让Selenium运行相同的代码(其运行方式> JUnit测试),如果电脑被锁定,它会给出上面的屏幕截图。我什至尝试过让Selenium代码生成一个新线程来抓取屏幕截图,而它却进行了Thread.sleep(),但是一旦电脑被锁定,结果还是一样。

2 个答案:

答案 0 :(得分:2)

  

在个人桌面上,锁定屏幕应该不是使用AWT Robot捕获屏幕的问题。

您可以使用脚本ScreenCapture.java

对其进行测试
  • 将Java文件下载到文件夹中。
  • 在下载文件的文件夹中打开cmd
  • javac ScreenCapture.java
  • java ScreenCapture

您应该看到文件夹中的循环捕获了屏幕截图。锁定屏幕,等待5秒钟,然后解锁屏幕并检查屏幕截图

  

对于通过RDP访问的虚拟机或远程计算机,锁定可能会导致黑色的屏幕截图。

当用户正常访问桌面时(如笔记本电脑或个人计算机,没有RDP),则将用户会话设置为控制台。您可以使用以下命令查看它。

c:\Users\*******\Desktop>query user
USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
>*********              console             1  Active      none   12/18/2018 5:50 PM 

您可以看到用户已连接到会话console。在此模式下,捕获屏幕截图可以完美运行。

但是,如果您使用RDP访问桌面,则会看到以下结果。

c:\Users\*******\Desktop>FOR /L %N IN () DO (query user
timeout 2)

 // When the screen is locked (RDP closed)
 USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
>*********                                  1  Disc            .  8/21/2018 12:25 PM
 // When RDP session is active
 USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
>*********              rdp-tcp#0           1  Active       none  8/21/2018 12:25 PM

您可以看到,当RDP会话断开连接时,没有活动的会话。这将导致空白的屏幕截图

  

解决方案

当RDP关闭时,必须使用以下命令激活console会话。这可以通过设置计划任务来完成。

  1. 使用以下内容创建批处理文件。

    Tscon 1 /dest:console /v
    
  2. 通过打开Run并键入taskschd.msc来打开任务计划程序
  3. Action menu中,单击Create Task
  4. 给任务起个名字
  5. 选中Run whether user is logged in or not复选框
  6. Triggers标签中,单击New按钮
  7. 选择On disconnect from user session,然后单击OK
  8. Actions标签中,单击New按钮
  9. 操作Start a program并指向批处理文件的位置,然后单击OK
  10. 点击OK创建任务

答案 1 :(得分:1)

好的,当使用浏览器锁定PC时,您可以截取屏幕截图-

public static String captureScreen(WebDriver driver, String screenName) throws IOException {
    String dest = null;
    try {
        Screenshot screenshot = new AShot().shootingStrategy(ShootingStrategies.viewportPasting(1000)).takeScreenshot(driver);
        dest = ScreenshotsPath() + "\\" + screenName + ".png";
        ImageIO.write(screenshot.getImage(), "PNG", new File(dest));
    } catch (Exception e) {
        e.printStackTrace(writeException.toFile());
    }
    return dest;
}

我的方法将目标(图像的路径)返回为字符串,因为我在报表中使用了它们。我还使用AShot(),因为我想拍摄整页的屏幕截图。

谢谢