New issue
Advanced search Search tips

Issue 832138 link

Starred by 7 users

Issue metadata

Status: Verified
Owner:
Closed: Apr 2018
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: ----
Type: ----


Previous locations:
chromedriver:2373


Sign in to add a comment

Headless Chrome: getScreenshotAs() hangs after manage().window().setPosition()

Reported by phlons...@gmail.com, Apr 9 2018

Issue description

Issue Description:
When using headless Chrome and manage().window().setPosition() is called the following getScreenshotAs() hangs forever.

setPosition() might not make sense for headless Chrome
but if the user reuses a script which previously
was run with visible Chrome the script should not hang.
A proper behavior would be at least to return a
proper error message or do nothing if it does not 
have any effect for headless Chrome.

Used chromedriver version: 2.37.543627 (63642262d9fb93fb4ab52398be4286d844092a5e)


Steps to reproduce:
Execute the following Java JUnit 4 test.
It hangs in the getScreenshotAs() call.

```
@Test
public void testScreenshotOfMovedWindowDoesNotHangOrCrash() {
  // given
  DesiredCapabilities caps = DesiredCapabilities.chrome();
  ChromeOptions options = new ChromeOptions();
  options.addArguments("--headless");
  caps.setCapability(ChromeOptions.CAPABILITY, options);
  System.setProperty("webdriver.chrome.driver", ....);
  System.setProperty("webdriver.chrome.logfile", ....);
  System.setProperty("webdriver.chrome.verboseLogging", "true");
  RemoteWebDriver driver = new ChromeDriver(caps);

  driver.navigate().to("https://tools.ietf.org/html/rfc2616");
  driver.manage().window().setPosition(new Point(800, 100));

  // when
  byte[] screenshotBytes = driver.getScreenshotAs(OutputType.BYTES); // HANGS in headless Chrome

  // then
  assertNotNull(screenshotBytes);
  assertTrue("screenshot is not empty", screenshotBytes.length > 0);
}
```

 
chromedriver3.log
20.6 KB View Download
Your code is hanging on calling driver.manage().window().setPosition(new Point(800, 100));

Try to run the following code and see if it works on your side:
Screenshot is attached.

public class  Issue2373 
{

  private static RemoteWebDriver driver;

  @BeforeClass
  public static void setup()
  {
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--headless");
    options.addArguments("--no-sandbox");
    DesiredCapabilities caps = DesiredCapabilities.chrome();
    caps.setCapability(ChromeOptions.CAPABILITY, options);
    String driverPath = "/<path>/chromedriver";
    System.setProperty("webdriver.chrome.driver", driverPath);
    System.setProperty("webdriver.chrome.logfile", "/<path>/ Issue2373 .log");
    System.setProperty("webdriver.chrome.verboseLogging", "true");
    driver = new ChromeDriver(caps);
    driver.manage().window().maximize();
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
  }

  @Test
  public static void testScreenshotOfMovedWindowDoesNotHangOrCrash() throws InterruptedException {
    // given
    try
    {
      driver.navigate().to("https://tools.ietf.org/html/rfc2616");
      //driver.manage().window().setPosition(new Point(800, 100));

      TakesScreenshot ts = (TakesScreenshot) driver;
      File source = ts.getScreenshotAs(OutputType.FILE);
      String dest = "/<path>/Issue2373_screenshot.png";
      File destination = new File(dest);
      FileUtils.copyFile( source, destination );
      // when
      Thread.sleep(2000);
      System.out.println("screenshot at " + System.currentTimeMillis());
      byte[] screenshotBytes = driver.getScreenshotAs(OutputType.BYTES);
      // then
      assertNotNull(screenshotBytes);
      driver.quit();
    }
    catch (IOException e)
    {
      System.out.println("!!! Exception: "  + e.getMessage()  + "\n");
    }
  }
}


Issue2373_screenshot.png
61.3 KB View Download
Labels: Needs-Feedback

Comment 3 by phlons...@gmail.com, Apr 10 2018

The script above works fine because the line
driver.manage().window().setPosition(new Point(800, 100));
is commented out. I did get a screenshot like you posted.

But when I uncomment the setPosition() line the script hangs in the line
File source = ts.getScreenshotAs(OutputType.FILE);

It definitely does not hang during the setPosition() call.

I attach a chromedriver log of your test  Issue2373  above with the setPosition() call uncommented.

btw: I'm on
Microsoft Windows [Version 10.0.16299.309]
and Chrome 65.0.3325.181 (official build).

The callstack of the hang (started unit test in the Eclipse debugger and the pressed pause during the hang):

Thread [Forwarding screenshot on session ea25d7d97c08cf1501df4a99c04d3d87 to remote] (Suspended)	
	SocketInputStream.socketRead0(FileDescriptor, byte[], int, int, int) line: not available [native method]	
	SocketInputStream.socketRead(FileDescriptor, byte[], int, int, int) line: not available	
	SocketInputStream.read(byte[], int, int, int) line: not available	
	SocketInputStream.read(byte[], int, int) line: not available	
	Okio$2.read(Buffer, long) line: 139	
	AsyncTimeout$2.read(Buffer, long) line: 237	
	RealBufferedSource.indexOf(byte, long, long) line: 345	
	RealBufferedSource.readUtf8LineStrict(long) line: 217	
	Http1Codec.readHeaderLine() line: 212	
	Http1Codec.readResponseHeaders(boolean) line: 189	
	CallServerInterceptor.intercept(Interceptor$Chain) line: 88	
	RealInterceptorChain.proceed(Request, StreamAllocation, HttpCodec, RealConnection) line: 147	
	ConnectInterceptor.intercept(Interceptor$Chain) line: 45	
	RealInterceptorChain.proceed(Request, StreamAllocation, HttpCodec, RealConnection) line: 147	
	RealInterceptorChain.proceed(Request) line: 121	
	CacheInterceptor.intercept(Interceptor$Chain) line: 93	
	RealInterceptorChain.proceed(Request, StreamAllocation, HttpCodec, RealConnection) line: 147	
	RealInterceptorChain.proceed(Request) line: 121	
	BridgeInterceptor.intercept(Interceptor$Chain) line: 93	
	RealInterceptorChain.proceed(Request, StreamAllocation, HttpCodec, RealConnection) line: 147	
	RetryAndFollowUpInterceptor.intercept(Interceptor$Chain) line: 125	
	RealInterceptorChain.proceed(Request, StreamAllocation, HttpCodec, RealConnection) line: 147	
	RealInterceptorChain.proceed(Request) line: 121	
	RealCall.getResponseWithInterceptorChain() line: 200	
	RealCall.execute() line: 77	
	OkHttpClient.execute(HttpRequest) line: 101	
	ChromeDriverCommandExecutor(HttpCommandExecutor).execute(Command) line: 155	
	ChromeDriverCommandExecutor(DriverCommandExecutor).execute(Command) line: 83	
	ChromeDriver(RemoteWebDriver).execute(String, Map<String,?>) line: 545	
	ChromeDriver(RemoteWebDriver).execute(String) line: 602	
	ChromeDriver(RemoteWebDriver).getScreenshotAs(OutputType<X>) line: 291	
	 Issue2373 .testScreenshotOfMovedWindowDoesNotHangOrCrash() line: 50	
	NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
	NativeMethodAccessorImpl.invoke(Object, Object[]) line: not available	
	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: not available	
	Method.invoke(Object, Object...) line: not available	
	FrameworkMethod$1.runReflectiveCall() line: 50	
	FrameworkMethod$1(ReflectiveCallable).run() line: 12	
	FrameworkMethod.invokeExplosively(Object, Object...) line: 47	
	InvokeMethod.evaluate() line: 17	
	BlockJUnit4ClassRunner(ParentRunner<T>).runLeaf(Statement, Description, RunNotifier) line: 325	
	BlockJUnit4ClassRunner.runChild(FrameworkMethod, RunNotifier) line: 78	
	BlockJUnit4ClassRunner.runChild(Object, RunNotifier) line: 57	
	ParentRunner$3.run() line: 290	
	ParentRunner$1.schedule(Runnable) line: 71	
	BlockJUnit4ClassRunner(ParentRunner<T>).runChildren(RunNotifier) line: 288	
	ParentRunner<T>.access$000(ParentRunner, RunNotifier) line: 58	
	ParentRunner$2.evaluate() line: 268	
	RunBefores.evaluate() line: 26	
	BlockJUnit4ClassRunner(ParentRunner<T>).run(RunNotifier) line: 363	
	JUnit4TestReference.run(TestExecution) line: 86	
	TestExecution.run(ITestReference[]) line: 38	
	RemoteTestRunner.runTests(String[], String, TestExecution) line: 538	
	RemoteTestRunner.runTests(TestExecution) line: 760	
	RemoteTestRunner.run() line: 460	
	RemoteTestRunner.main(String[]) line: 206	


Issue2373.log
22.4 KB View Download
Labels: -Needs-Feedback
Status: Untriaged (was: Unconfirmed)
Please add the following instruction in setup() right after chromedriver instance is created:

options.addArguments("window-size=1980,960");

i.e.
    ChromeOptions options = new ChromeOptions();
    options.addArguments("window-size=1980,960");

Screenshot is attached.

Issue2373_screenshot.png
134 KB View Download
I mean ChromeOptions was created, not chromedriver instance.


Status: Unconfirmed (was: Untriaged)
Sorry, I was not enough clear in my comments, my bad.
By saying "code is hanging on calling driver.manage().window().setPosition(new Point(800, 100));" I meant your code hangs because of this call.

Labels: Needs-Feedback
Please let us know if this bug can be closed.

Comment 9 by phlons...@gmail.com, Apr 11 2018

It seems if the size of the window is set to at least double of the setPosition() coordinates the followup screenshot call does not hang any more.

This example does HANG:
driver.manage().window().setSize(new Dimension(1600, 600));
driver.manage().window().setPosition(new Point(800, 100));
driver.getScreenshotAs(OutputType.FILE); // hangs

This example does NOT hang (1601 > 800*2):
driver.manage().window().setSize(new Dimension(1601, 600));
driver.manage().window().setPosition(new Point(800, 100));
driver.getScreenshotAs(OutputType.FILE); // OK

This example does HANG (size reset after setPosition()):
driver.manage().window().setSize(new Dimension(1601, 600));
driver.manage().window().setPosition(new Point(800, 100));
driver.manage().window().setSize(new Dimension(800, 600));
driver.getScreenshotAs(OutputType.FILE); // hangs

So it seems that there is a workaround if you want to call setPosition().

However, this is still a bug.

My use case here is not that I want to call setPosition() (which may not have any effect anyways).
The easier workaround here would be to just remove setPosition() call.
The case is problematic if a user uses setPosition() by accident if he resuses a script which also runs on a visible browser. Then the screenshot call should not hang.

If setPosition() is not supported in the headless scenario it should return a proper error message or just do nothing if the position does not matter. It is just about a well behaving API.

Regards,
Philip

Status: Untriaged (was: Unconfirmed)
I just run the code again and it fails with calling options.addArguments("window-size=1600,600"); as well.

Thank you for your feedback.

We are investigating the issue.


Here are some consistent cases when this code hangs and when it doesn't:

Hangs:
options.addArguments("window-size=800,600");
options.addArguments("--headless");

Does not hang:
options.addArguments("window-size=800,600");
//options.addArguments("--headless");


Hangs:
options.addArguments("window-size=800,100");
options.addArguments("--headless");

Hangs:
options.addArguments("window-size=800,100");
//options.addArguments("--headless");

Here is consistently hanging case. Windows size is greater then set position:

options.addArguments("window-size=1000,200");
options.addArguments("--headless");
...
driver.manage().window().setPosition(new Point(800, 100));

In normal mode this code doesn't hang.

Same with double than position size. Consistently hangs.

options.addArguments("window-size=1600,200");
options.addArguments("--headless");
...
driver.manage().window().setPosition(new Point(800, 100));

Owner: jzfeng@chromium.org
Status: Assigned (was: Untriaged)
Jianzhou, could you please take a look at this issue. Case described in comment #13 consistently fails.



Owner: eseckler@chromium.org
I have switched to another project.

Hi Eric, could you take a look at this issue?

Thanks!
Labels: -Needs-Feedback
I'll aim to have a look, but am travelling the next week.

It sounds like setting the position might be moving the window off-screen (or something like that) and the screenshot fails subsequently.

FWIW, this sounds like an issue that we should track in chromium under Internals>Headless.
Project: chromium
Moved issue chromedriver:2373 to now be  issue chromium:832138 .
Components: Internals>Headless
Moved issue to chromium under Internals>Headless.
Project Member

Comment 20 by bugdroid1@chromium.org, Apr 27 2018

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/1cbd8e0f4d2f3405e7b57bc6d547c49763b4199d

commit 1cbd8e0f4d2f3405e7b57bc6d547c49763b4199d
Author: Eric Seckler <eseckler@chromium.org>
Date: Fri Apr 27 03:17:34 2018

headless: Adjust browser window size to contain all WebContents

When setting the bounds of a WebContents, we shouldn't also change the
browser window size to the size of the WebContents. This can lead to
the bounds of the WebContents lying outside the browser's window, in
which case screenshots will hang.

Instead, make sure that all WebContents are contained within the browser
window size.

Bug:  832138 
Change-Id: Iaeb8b36b4edceedfdf2fdd1d54c3765587c79ea7
Reviewed-on: https://chromium-review.googlesource.com/1031655
Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
Commit-Queue: Eric Seckler <eseckler@chromium.org>
Cr-Commit-Position: refs/heads/master@{#554285}
[modify] https://crrev.com/1cbd8e0f4d2f3405e7b57bc6d547c49763b4199d/headless/lib/browser/headless_browser_impl_aura.cc
[modify] https://crrev.com/1cbd8e0f4d2f3405e7b57bc6d547c49763b4199d/headless/lib/headless_web_contents_browsertest.cc

Status: Fixed (was: Assigned)
Above patch should address the issue.
Status: Verified (was: Fixed)
I confirm the fix.
Tested with Chromedriver 2.38.554400 and Chrome 68.0.3411.0 in headless mode.


Sign in to add a comment