SeleniumHQ / selenium-google-code-issue-archive

Archive, please see main selenium repo
https://github.com/seleniumhq/selenium
346 stars 194 forks source link

Android Webdriver takeScreenshot() does not reflect scrolling #1236

Closed lukeis closed 8 years ago

lukeis commented 8 years ago

Originally reported on Google Code with ID 1236

What steps will reproduce the problem?

***Steps 1-4 as per http://code.google.com/p/selenium/wiki/AndroidDriver
1. Launch Android emulator (I am using an Android 2.2 device with the default HVGA
screen)
2. (Install "adb -e install -r android-server-2.0b1.apk" and) Start WebDriver on device.
3. Start forwarding, "adb forward tcp:8080 tcp:8080"
4. Connect to the webdriver:
from selenium import webdriver
driver = webdriver.connect('remote', 'http://127.0.0.1:8080')
***

5. Open a website: driver.get('http://en.wikipedia.org')
6. In the emulator instance, scroll partway down the page. In the attached screengrab
(taken on my desktop) you can see that I've scrolled down about one full screen-height
to the "in the news" section.
7. Take a screenshot: driver.get_screenshot_as_file('screenshot_from_webdriver.png')

What is the expected output? What do you see instead?

I expected the screenshot to match the on-screen display of the page. Instead, the
screenshot seems to alway reflects the *top* of the canvas, cropped to the size of
the display window. Scrolling up or down has no effect on the screenshot produced.

What version of the product are you using? On what operating system?

Selenium/webdriver version 2.0b1 on Ubuntu 10.04. Android SDK Tools, revision 8. SDK
Platform Android 2.2, API 8, revision 2. 

Please provide any additional information below.

Reported by BrendanMcCollam on 2011-01-25 17:42:35


lukeis commented 8 years ago

Reported by jari.bakken on 2011-01-27 04:04:32

lukeis commented 8 years ago
This function just takes a s/s of the viewport, no? I think thats what its supposed
to do. There is some magic that makes the firefox screenshot method work the way it
does. I'm not sure that's doable on android.

Reported by antlong on 2011-02-01 02:56:14

lukeis commented 8 years ago
I've done a little bit of research on this. The Android method, capturePicture() takes
a shot of the entire web page. According to, http://developer.android.com/reference/android/webkit/WebView.html#capturePicture%28%29
"this picture is of the entire document, and is not restricted to the bounds of the
view."

So what seems to be happening is that it's grabbing the whole webpage, but then these
two lines (250 and 251 here: http://code.google.com/p/selenium/source/browse/trunk/android/src/java/org/openqa/selenium/android/app/WebDriverActivity.java
)

currentView.getWidth() - currentView.getVerticalScrollbarWidth(),
currentView.getHeight(), Config.RGB_565);

are cropping the image to be only the size of the view. And, critically, it gets cropped
so all you have is the top of the image.

I apologize that I'm not familiar enough with the Selenium codebase to submit a patch
myself, but if I might offer my suggestions:

1) Try to fix the existing takeScreenshot() method by checking the scroll position,
and then cropping based on that offset. It looks like you can get the X and Y scroll
positions here: http://developer.android.com/reference/android/view/View.html#attr_android:scrollX

2) Add a separate method to save a full-page image. I know Selenium 1.0 had a captureEntirePageScreenshot
method. I've attached a possible modification that seems to work, but I don't know
where else you'd need to make changes (on the client side?) in order to support a new
method.

Reported by BrendanMcCollam on 2011-02-01 18:09:45


lukeis commented 8 years ago

Reported by berrada@google.com on 2011-06-20 22:07:38

lukeis commented 8 years ago
I fixed the bug that the screenshot seems to alway reflects the *top* of the canvas.
You can have a look at the attachment.

Reported by zhoudong831026 on 2011-07-07 06:22:10


lukeis commented 8 years ago
Thanks for the patch, I will take a look.

Reported by berrada@google.com on 2011-07-07 16:05:35

lukeis commented 8 years ago
Hi All,

Thanks for the patched and sorry for the delayed follow up, I have submitted a fix
in r12988.

Reported by berrada@google.com on 2011-07-19 00:03:43

lukeis commented 8 years ago
if "(currentView.getWidth() - currentView.getVerticalScrollbarWidth() + currentView.getScrollX())
> (pic.getWidth() - currentView.getVerticalScrollbarWidth())", it will throw an exception,
so you should retest it.

Reported by zhoudong831026 on 2011-07-19 03:31:57

lukeis commented 8 years ago
I don't see a situation where currentView.getWidth() - currentView.getVerticalScrollbarWidth()
+ currentView.getScrollX() > pic.getWidth()

Reported by berrada@google.com on 2011-07-19 03:36:08

lukeis commented 8 years ago
Hey hey,

I'm still finding strange behavior with Android screenshots getting 'clipped'. I either
get inconsistent images (for the same url) or no image at all and an exception along
the lines of:

'width and height must be > 0 (java.lang.IllegalArgumentException) (Selenium::WebDriver::Error::UnhandledError)'

I'm using selenium-server-standalone-2.6.0.jar across the board and the ruby bindings
for webdriver.

Reported by astromoose on 2011-09-28 15:17:55

lukeis commented 8 years ago
Will take a look, thanks for letting me know. 

Do you have the code to reproduce the issue you are facing?

Reported by berrada@google.com on 2011-09-28 19:04:45

lukeis commented 8 years ago
Morning!

I've got a single hub instance and a single webdriver instance running on my host.
Webdriver was started with the following JSON:

{
"capabilities":
        [
            { "browserName":"android", "maxInstances":1, "platform":"LINUX" }
        ],
"configuration":
        {
                "cleanUpCycle":2000,
        "port":8000,
        "host":"localhost",
                "timeout":30000,
                "proxy":"org.openqa.grid.selenium.proxy.WebDriverRemoteProxy",
                "maxSession":1,
        "hub":"http://hub.local:4444/grid/register",
        "hubport":4444

        }
}

And then the nuts and bolts of my ruby script:
<ruby>
android = Selenium::WebDriver::Remote::Capabilities.android(:takes_screenshot => true,
:platform => 'LINUX')
driver = Selenium::WebDriver.for(
      :remote,
      :url => hub,
      :desired_capabilities => android
)
driver.get "http://www.apple.com/pr/"
driver.save_screenshot("./webdriver-android.png")
driver.quit
</ruby>

Nothing complicated at all :)

An example of the view I can see on the device (Galaxy SII) and the corresponding screenshot
I'm getting are attached.

Reported by astromoose on 2011-09-29 09:07:37


lukeis commented 8 years ago
I can't reproduced the issue that triggers the exception :
'width and height must be > 0 (java.lang.IllegalArgumentException) (Selenium::WebDriver::Error::UnhandledError)'

The screenshot on android return what's curently displayed in the viewport. Somethimes
the canvas needs to redraw, so it may help to add a wait condition to ensure the page
is ready.

I am marking this as working as intended, feel free to reopen if you have a good repro
case that I can use or is you still see issues with the screenshots API on the lastest
APK released.

Thanks,

Reported by berrada@google.com on 2011-11-02 19:06:55

lukeis commented 8 years ago
What most QA engineers need is a full screenshot.
GetScreenShot in other iterations of the webdriver will scroll through the web page
and  screenshot - giving a 'full picture' of what the page looks like.
Hence, I am requesting that the status please be changed and development be undertaken
so GetScreenShot gets the full web page (portrait or landscape).

Thanks

Reported by queenstownswords on 2011-11-23 21:50:57

lukeis commented 8 years ago
If you need the full screenshot you can use scrolling:
driver.executeScript("window.scroll(x,y)");
// Then take the screenshot.

Reported by berrada@google.com on 2011-11-23 22:25:22

lukeis commented 8 years ago

Reported by luke.semerau on 2015-09-17 18:11:55