assertthat / selenium-shutterbug

Java library to create customized full page/frame/elements screenshots using Selenium WebDriver and Java AWT, screenshots and images comparison and many more cool stuff
MIT License
158 stars 45 forks source link

Element screenshot when `iframe` is active appears to switch to main window #82

Closed roboaks closed 4 years ago

roboaks commented 4 years ago

Here's the scenario. We are calling the new shootElement method passing a WebElement that corresponds to a scrollable div i n the main window. Support for this usage is now built into our AFT framework and it works fine except if...

  1. The AFT clicks a button (or does something) that causes an iframe-based popup to be displayed
  2. Does a Selenium switch to that iframe
  3. Calls shootElement using the usual parameters

What seems to happen is that ShutterBug uses Selenium to switch back to the main window to execute shootElement. Then when the AFT proceeds, it fails because the popup iframe is no longer active. Is it indeed possible that ShutterBug uses Selenium to switch back to the main window?

What I tried next was to change the ShutterBug config on the fly (our framework supports that) so that shootFrame is called, supplying the iframe WebElement and using the VIEWPORT strategy (since we don't need to scroll the popup). This generates:

__EXCEPTION__:org.openqa.selenium.JavascriptException: javascript error: Cannot read property 'scrollIntoView' of null
  (Session info: chrome=84.0.4147.135)
Build info: version: 'unknown', revision: 'unknown', time: 'unknown'
System info: host: 'GitHub', ip: '172.30.1.67', os.name: 'Windows Server 2016', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_241'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 84.0.4147.135, chrome: {chromedriverVersion: 84.0.4147.30 (48b3e868b4cc0..., userDataDir: C:\Users\ITSUser\AppData\Lo...}, goog:chromeOptions: {debuggerAddress: localhost:51855}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: WINDOWS, platformName: WINDOWS, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:virtualAuthenticators: true}
Session ID: e1f1da63824ad197ee5bd5b7b405da0c
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [rt.jar:1.8.0_241]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) [rt.jar:1.8.0_241]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) [rt.jar:1.8.0_241]
    at java.lang.reflect.Constructor.newInstance(Unknown Source) [rt.jar:1.8.0_241]
    at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187) [SeleniumFixture-all.jar]
    at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122) [SeleniumFixture-all.jar]
    at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49) [SeleniumFixture-all.jar]
    at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158) [SeleniumFixture-all.jar]
    at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83) [SeleniumFixture-all.jar]
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552) [SeleniumFixture-all.jar]
    at org.openqa.selenium.remote.RemoteWebDriver.executeScript(RemoteWebDriver.java:489) [SeleniumFixture-all.jar]
    at com.assertthat.selenium_shutterbug.utils.web.Browser.executeJsScript(Browser.java:668) [SeleniumFixture-all.jar]
    at com.assertthat.selenium_shutterbug.utils.web.Browser.scrollToElement(Browser.java:644) [SeleniumFixture-all.jar]
    at com.assertthat.selenium_shutterbug.core.Shutterbug.shootFrame(Shutterbug.java:337) [SeleniumFixture-all.jar]
    at com.assertthat.selenium_shutterbug.core.Shutterbug.shootFrame(Shutterbug.java:301) [SeleniumFixture-all.jar]
    at com.its.itap.fixtures.selenium.helpers.Screenshot._saveScreenshot(Screenshot.java:479) [SeleniumFixture-all.jar]
    at com.its.itap.fixtures.selenium.helpers.Screenshot.saveScreenshot(Screenshot.java:607) [SeleniumFixture-all.jar]
...

I suspect that ShutterBug doesn't like the VIEWPORT strategy for a frame. Since the frame popup is small and will always be in view, I suppose I could just use the ShutterBug shootPage method.

Thoughts?

glibas commented 4 years ago

Hi @roboaks

Thank you for reporting.

Thanks, Glib

roboaks commented 4 years ago

Thank you so much for the swift response Glib!

We will test things out today and let you know if we have any issues.

roboaks commented 4 years ago

This fix worked perfectly. Furthermore, we took the simplest approach to shooting the popup, which is to simply take a viewport screenshot of the main window (which includes the popup); it worked perfectly.

Thanks again Glib :-)

glibas commented 4 years ago

Hi Rob, Great news! Thanks for feedback!