Open Bug 1471262 Opened 6 years ago Updated 1 year ago

WebDriver:TakeScreenshot returns empty string


(Remote Protocol :: Marionette, defect, P3)

59 Branch


(Not tracked)


(Reporter: aclvaz, Unassigned)


(Blocks 1 open bug)


User Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36

Steps to reproduce:

using Selenium in C#:

return ((ITakesScreenshot)_driver).GetScreenshot();

for a WebDriver configured like this:

        private void CreateWebDriver()
            FirefoxProfile customProfile = new FirefoxProfile();
            customProfile.SetPreference("dom.disable_beforeunload", true); // disable want to leave page question.
            customProfile.SetPreference("full-screen-api.approval-required", false); // disable maximize firefox question
            customProfile.SetPreference("network.http.connection-timeout", 25); // connection time-out.
            customProfile.SetPreference("dom.max_chrome_script_run_time", 0);
            customProfile.SetPreference("dom.max_script_run_time", 0);
            // for some pesky sites
            customProfile.SetPreference("", 2);
            customProfile.SetPreference("", Directory.GetCurrentDirectory());
            customProfile.SetPreference("browser.helperApps.neverAsk.saveToDisk", "text/vnd.wap.wml,application/x-trash,httpd/unix-directory,application/vnd.framemaker,application/octet-stream"); // ex:,,,,
            customProfile.SetPreference("media.volume_scale", "0.0");
            customProfile.SetPreference("dom.successive_dialog_time_limit", 1);

            FirefoxOptions fo = new FirefoxOptions();
            fo.Profile = customProfile;
            fo.SetPreference("security.sandbox.content.level", 5);
            fo.AddAdditionalCapability("acceptInsecureCerts", true, true);
            fo.AcceptInsecureCertificates = true;
            fo.Profile.AcceptUntrustedCertificates = true;
            fo.Profile.AssumeUntrustedCertificateIssuer = true;
            fo.Profile.DeleteAfterUse = true;
            fo.UnhandledPromptBehavior = UnhandledPromptBehavior.Dismiss;
            fo.LogLevel = FirefoxDriverLogLevel.Trace;
            fo.SetPreference("webdriver.log.file", "d:\\selenium\\driver.log");
            _driver = new FirefoxDriver(FirefoxDriverService.CreateDefaultService(), fo, TimeSpan.FromSeconds(60));
            _driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(40);

accessing URL (or, or, etc)

gets an empty string.

* GeckoDriver Version: 0.21.0
* Platform: Windows 7 Enterprise Edition 64 bits
* Firefox: 59.0.2 (64-bit)
* Selenium: 3.12.1

Actual results:

got an empty string on Selenium where there should be a base64 encoded string with the web page image:

1530016396134   webdriver::server       DEBUG   -> POST /session/01e446d4-a1f6-47db-8958-bd6a9ffbbc83/window/rect {"width":1024,"height":768}
1530016396141   webdriver::server       DEBUG   <- 200 OK {"value": {"height":768,"width":1024,"x":4,"y":4}}
1530016396142   webdriver::server       DEBUG   -> GET /session/01e446d4-a1f6-47db-8958-bd6a9ffbbc83/window
1530016396147   webdriver::server       DEBUG   <- 200 OK {"value":"4294967297"}
1530016396626   webdriver::server       DEBUG   -> POST /session/01e446d4-a1f6-47db-8958-bd6a9ffbbc83/url {"url":""}
1530016397592   webdriver::server       DEBUG   <- 200 OK {"value": null}
1530016398311   webdriver::server       DEBUG   -> GET /session/01e446d4-a1f6-47db-8958-bd6a9ffbbc83/alert/text
1530016398315   webdriver::server       DEBUG   <- 404 Not Found {"value":{"error":"no such alert","message":"No modal dialog is currently open","stac
1530016399054   webdriver::server       DEBUG   -> GET /session/01e446d4-a1f6-47db-8958-bd6a9ffbbc83/window/handles
1530016399057   webdriver::server       DEBUG   <- 200 OK {"value":["4294967297"]}
1530016399103   webdriver::server       DEBUG   -> GET /session/01e446d4-a1f6-47db-8958-bd6a9ffbbc83/window/handles
1530016399107   webdriver::server       DEBUG   <- 200 OK {"value":["4294967297"]}
1530016399749   webdriver::server       DEBUG   -> POST /session/01e446d4-a1f6-47db-8958-bd6a9ffbbc83/execute/sync {"script":"return (document.readySt
ate == 'complete' && ((window.jQuery === undefined) || == 0))","args":[]}
1530016399759   webdriver::server       DEBUG   <- 200 OK {"value":true}
1530016400485   webdriver::server       DEBUG   -> POST /session/01e446d4-a1f6-47db-8958-bd6a9ffbbc83/elements {"using":"xpath","value":"//meta[@http-
1530016400492   webdriver::server       DEBUG   <- 200 OK {"value":[]}
1530016407499   webdriver::server       DEBUG   -> GET /session/01e446d4-a1f6-47db-8958-bd6a9ffbbc83/url
1530016407502   webdriver::server       DEBUG   <- 200 OK {"value":""}
1530016407542   webdriver::server       DEBUG   -> GET /session/01e446d4-a1f6-47db-8958-bd6a9ffbbc83/url
1530016407545   webdriver::server       DEBUG   <- 200 OK {"value":""}
1530016433263   webdriver::server       DEBUG   -> GET /session/01e446d4-a1f6-47db-8958-bd6a9ffbbc83/screenshot
1530016433275   webdriver::server       DEBUG   <- 200 OK {"value":""}
1530016433275   webdriver::server       DEBUG   -> GET /session/01e446d4-a1f6-47db-8958-bd6a9ffbbc83/url
1530016433278   webdriver::server       DEBUG   <- 200 OK {"value":""}

Expected results:

should have returned a base64 encoded string with the snapshot image
Triaging this issue to testing::geeckodriver as it seems to me the correct component.
Component: Untriaged → geckodriver
Product: Firefox → Testing
This is an issue with Marionette. We will have to look into it at some point. 

Tonecas, if you want to help us investigating please let us know.
Component: geckodriver → Marionette
Ever confirmed: true
Priority: -- → P3
From Andreas via the Github issue:

> That said, the return value from takeScreenshot is an empty string, which we would not expect for I expect there is an issue somewhere dealing with the correct document type, since the document is an XML file.
(In reply to Henrik Skupin (:whimboo) from comment #2)
> This is an issue with Marionette. We will have to look into it at some
> point. 
> Tonecas, if you want to help us investigating please let us know.

Yes I can help if I can. I am not familiarized how to debug Mozilla code from another project (in my case, my own code and Selenium code). I use Visual Studio and i'm using ReSharper to help bind external code to a project, but did not get yet on how to be able to make breakpoints on Geckodriver/Marionette code. if you have any info/help page on this I surely can make a more in depth debug.
I would propose that you read through the following document first:

Once done feel free to contact me or Andreas (ato) in the #ateam channel. We are happy to help further! Also thank you for your interest to help.
I haven’t been able to confirm yet if this is related to the GitHub
issue quoted, as that is specifically about XHTML/XML documents.
This is an HTML document which appears to exhibit the same problem.
Perhaps my initial suspicion was wrong.

In any case, I reproduced this with the Marionette client against

> >>> m.navigate("")
> 1530629481160	Marionette	TRACE	0 -> [0,2,"WebDriver:Navigate",{"url":""}]
> 1530629481170	Marionette	DEBUG	[7] Received DOM event beforeunload for about:blank
> 1530629481473	Marionette	DEBUG	[7] Received DOM event pagehide for about:blank
> 1530629481524	Marionette	DEBUG	[7] Received DOM event DOMContentLoaded for
> 1530629481784	Marionette	DEBUG	[7] Received DOM event pageshow for
> 1530629481802	Marionette	TRACE	0 <- [1,2,null,{"value":null}]
> >>> m.screenshot()
> 1530629487629	Marionette	TRACE	0 -> [0,3,"WebDriver:TakeScreenshot",{"highlights":null,"full":true,"hash":false,"id":null,"scroll":true}]
> u''
> >>> 1530629487636	Marionette	TRACE	0 <- [1,3,null,{"value":""}]
Blocks: webdriver
Summary: Take a screenshot returns empty value on GeckoDriver/Marionette → WebDriver:TakeScreenshot returns empty string
Also happening on
Quoting Sule Tamas over on

(In reply to Sule Tamas from comment #2)
> The bug can be reproduced with the following code on a local html file:
> <!DOCTYPE html>
> <html>
>     <head>
>         <style>
>             body {
>                 margin: 0
>             }
>         </style>
>     </head>
>     <body></body>
> </html>
I feel that this should be the same underlying issue as I have described on bug 1492357 comment 1.
See Also: → 1492357
I compiled a nightly from source and tracked the issue i mentioned before. I solved my problem and created a workaround.

in /mozilla-unified/testing/marionette/listener.js:
in function takeScreenshot:
if the "full" flag has true value "win.document.documentElement" is passed to the capture.element function. 

in /mozilla-unified/testing/marionette/capture.js
in function capture.element

The necessary dimensions for the rendering are queried by node.getBoundingClientRect() where node is the passed "win.document.documentElement". Of course the size object returned contains zero height.

I found out this works ok for any element, except for win.document.documentElement if the document has 0 height. and some other websites uses one absolute positioned div in the body, so the body and the documentElement has zero height.

While trying to get a correct solution, i checked the inbuilt screenshot function (right click menu: take screenshot)
in /mozilla-unified/browser/extensions/screenshots/selector/uicontrol.js

following functions are used to determine the correct size when the user selects full screen screenshot:

function getDocumentWidth() {
    return Math.max(
      document.body && document.body.clientWidth,
      document.body && document.body.scrollWidth,
function getDocumentHeight() {
    return Math.max(
      document.body && document.body.clientHeight,
      document.body && document.body.scrollHeight,

So, my suggested solution is:

in /mozilla-unified/testing/marionette/capture.js
in function capture.element

Adding a condition helped me:

capture.element = function(node, highlights = []) {
  let win = node.ownerGlobal;
  let rect = node.getBoundingClientRect();

  if (win.document.documentElement === node) {
        rect.height=Math.max(win.document.body && win.document.body.scrollHeight,win.document.documentElement.scrollHeight);
        rect.width=Math.max(win.document.body && win.document.body.scrollWidth,win.document.documentElement.scrollWidth);

  return capture.canvas(

I'm not familiar with mozilla related codes. Please, check my suggestion.
Sule, thanks a lot for the proposed fix! I know that you aren't familiar with the code, but would you feel confident enough, and have interest to maybe try to fix it yourself when I mentor you through the whole process? I would really like doing that if you are up for it.
Flags: needinfo?(suletom)
Sorry for the late answer, i am working on a full time company project.
I'm still interested in solving this problem. If my other project allows some free time, i will contact on irc.

Merry Christmas,

Flags: needinfo?(suletom)

Thank you very much Sule and Henrik. I also experience this problem at different websites that rely on absolute positioned divs. Best regards, Kees

1547028339137 Marionette TRACE 0 -> [0,4,"WebDriver:ExecuteScript",{"args":[],"newSandbox":false,"script":"return document.readyState","specialPowers":false}]
1547028339139 Marionette TRACE 0 <- [1,4,null,{"value":"complete"}]
1547028339139 webdriver::server DEBUG <- 200 OK {"value":"complete"}
1547028339142 webdriver::server DEBUG -> GET /session/e05d0cee-6db5-4aa2-ae00-7ee75a4a1a0e/screenshot
1547028339143 Marionette TRACE 0 -> [0,5,"WebDriver:TakeScreenshot",{"full":false,"highlights":[],"id":null}]
1547028339145 Marionette TRACE 0 <- [1,5,null,{"value":""}]
1547028339145 webdriver::server DEBUG <- 200 OK {"value":""}

Severity: normal → S3
Product: Testing → Remote Protocol
You need to log in before you can comment on or make changes to this bug.