Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Full page screenshot #312

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

100000001
Copy link

I have replaced the Selenium screenshot taker with aShot, as Selenium does not seem to be able to take a full page screenshot.

@fhoeben
Copy link
Owner

fhoeben commented Mar 4, 2020

With this PR will all screenshots always be full page (i.e. not just the viewport, what is visible, but the whole page)?
I do not believe that is what we should do. In general screenshots should capture what is on the screen, since that is what an end user would see and methods like 'is visible' also check what is on screen.

I do believe however that it would be a great feature to be able to take full page screenshots. But I would put that behind a separate method of BrowserTest. Just like one can check whether an element is visible, or visible somewhere on the page.

Additionally there could be a configuration option to switch the default screenshots, e.g. the ones taken on exceptions, between full page and viewport.

@100000001
Copy link
Author

All screenshots would be full page, yes.

I considered adding a 'takeFullPageScreenshot' method, but a comment in the Selenium screenshot code (TakeScreenshot.class) said:

For WebDriver extending TakesScreenshot, this makes a best effort
depending on the browser to return the following in order of preference:

  • Entire page
  • Current window
  • Visible portion of the current frame
  • The screenshot of the entire display containing the browser

So I thought this is already what Selenium is trying to do, but failing to do (at least for me in current Chrome) and this change sort of fixes this.

I can move the new code to takeFullPageScreenshot and update the pull request, which will keep things backward compatible.

Another option might be to add an optional parameter to determine the screenshot size/type which then defaults to the current behaviour.
With an additional change this parameter could default to a global config value.

@fhoeben
Copy link
Owner

fhoeben commented Mar 4, 2020

I think a new method fullPageScreenshot would be best (I dropped 'take' since I expect the wiki to usually have 'show' in first column so the wiki content becomes something like: '|show|full page screenshot|order_page|'

…parate method.

Also updated documentation and script test example.
@100000001
Copy link
Author

fullPageScreenshot is now a separate method in BrowserTest and in SeleniumHelper, the method is also added to the BrowserTests wiki.

I also updated a screenshot in the HsacExamples.SlimTests.BrowserTests.ScriptTest wiki to be full page. The test seems to be a bit fickle though, probably due to all the external scripts and content being loaded on the tested web pages.

@fhoeben
Copy link
Owner

fhoeben commented Mar 5, 2020

Yes those tests are a pain. PRs with more reliable, and instructive examples are welcome...

Copy link
Owner

@fhoeben fhoeben left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How big is the extra library added (I try to not let the size of standalone.zip get too much bigger)?

* @param basename filename (below screenshot base directory).
* @return location of screenshot.
*/
public String takeScreenshot(String basename) {
return takeScreenshotWith(
basename,
name ->
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
name ->
name -> this::createScreenshot

name ->
getSeleniumHelper()
.fullPageScreenshot(
getScreenshotBasename(name)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the extra getScreenshotBasename required here and not above?

Furthermore it seems a bit odd that both the basename is supplied to takeScreenshotWith, and all it does is pass it to the function. Seems easier if the caller would just place it inside the lambda (and then pass Supplier instead of function)

* @param maker function for taking the screenshot, should return the screenshot location.
* @return location of screenshot.
*/
private String takeScreenshotWith(String baseName, Function<String, String> maker) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make protected, so people can override in subclasses, should they want to

String result = null;
byte[] png = null;

switch (type) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this not just be two methods instead of switch on type (or at least make each branch just call a method)

@fhoeben
Copy link
Owner

fhoeben commented Mar 28, 2020

I did the cleanup I requested and pushed to a branch

When I tried to run the code I repeatedly got an exception:

java.lang.RuntimeException: org.openqa.selenium.JavascriptException: javascript error: Cannot read property 'scrollHeight' of null
(Session info: chrome=80.0.3987.149)
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: 'runner-72989761-project-17353740-concurrent-0', ip: '172.17.0.3', os.name: 'Linux', os.arch: 'amd64', os.version: '4.19.78-coreos', java.version: '1.8.0_242'
Driver info: org.openqa.selenium.remote.RemoteWebDriver
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 80.0.3987.149, chrome: {chromedriverVersion: 80.0.3987.106 (f68069574609..., userDataDir: /tmp/.com.google.Chrome.bGmdto}, goog:chromeOptions: {debuggerAddress: localhost:37881}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: LINUX, platformName: LINUX, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: ignore, webdriver.remote.sessionid: 4b289f0c92c2d703edab6193ba1...}
Session ID: 4b289f0c92c2d703edab6193ba154e51
at ru.yandex.qatools.ashot.util.InnerScript.execute(InnerScript.java:32)
at ru.yandex.qatools.ashot.shooting.ViewportPastingDecorator.getFullHeight(ViewportPastingDecorator.java:67)
at ru.yandex.qatools.ashot.shooting.ViewportPastingDecorator.getScreenshot(ViewportPastingDecorator.java:41)
at ru.yandex.qatools.ashot.shooting.ViewportPastingDecorator.getScreenshot(ViewportPastingDecorator.java:35)
at ru.yandex.qatools.ashot.AShot.takeScreenshot(AShot.java:145)
at nl.hsac.fitnesse.fixture.util.selenium.SeleniumHelper.fullPageScreenshot(SeleniumHelper.java:1077)
at nl.hsac.fitnesse.fixture.slim.web.BrowserTest.createFullPageScreenshot(BrowserTest.java:2077)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants