Skip to content
This repository has been archived by the owner on Dec 24, 2023. It is now read-only.

checkElement only saves a screenshot with part of the element #20

Open
anto-ac opened this issue Jun 10, 2019 · 16 comments
Open

checkElement only saves a screenshot with part of the element #20

anto-ac opened this issue Jun 10, 2019 · 16 comments

Comments

@anto-ac
Copy link

anto-ac commented Jun 10, 2019

Environment (please complete the following information):

  • Node.js version: 8.11.4 (but also tries in 10.15.0)
  • Browser name and version: Firefox 67.0 and Chrome 75.0.3770.80 and previous versions
  • Platform name and version: Debian Jessie (but it's not OS dependent)
  • Framework name and version: wdio 5.10.0
  • Plugin name and version: wdio-image-comparison-service 1.1.0
  • webdriver-image-comparison version: 0.5.0

Config of the automation framework + plugin
See here: https://github.com/anto-ac/checkElement-wdio-image-comparison-service-issue

Describe the bug

When taking a screenshot of an element via checkElement, only part of element is shown in the screenshot.
I think (but I'm not sure) it may happen for elements that are larger than the visible viewport.

See image taken from the library:
https://user-images.githubusercontent.com/30859172/59210996-b7715280-8ba6-11e9-9006-ca2adfa34196.png

To Reproduce
Steps to reproduce the behavior:

Run the test included in this repo:
https://github.com/anto-ac/checkElement-wdio-image-comparison-service-issue

You will need docker and docker-compose to run it.

Expected behavior
The whole element should be captured in the screenshot.

app-content

Log
See here: https://gist.github.com/anto-ac/1877d24fa9e88b5fd2ec5acc7b371626

Additional context

Add any other context about the problem here.

@wswebcreation
Copy link
Owner

@anto-ac

Tnx for filling the issue and providing the extra info. The problem what with you are trying to do is that you can only use checkElement with:

  • elements that are in the view
  • you should use this for small elements, it can't take an element screenshot of the element that you are providing

If you want to take a screenshot of the complete page please use something like this

        t('should compare successful with a baseline', () => {
            browser.url('https://www.treatwell.co.uk/treatment/spray-tanning-and-sunless-tanning/');
            $('.CookieBanner--closePointerZone--989df1').click();
            expect(browser.checkFullPageScreen('treatwell', {
                fullPageScrollTimeout: '1500',
            })).toEqual(0);
        });

I need to update the specs with the requirement that the element needs to be in the view.

@anto-ac
Copy link
Author

anto-ac commented Jun 11, 2019

Thanks! I suspected it was the case. I know I can take a screenshot of the whole document, but I was hoping that I could ignore the header and footer without having to remove or hide them every single time.

Is this an explicit choice or is it a constraint? In other words, would it be possible to add the ability to take a screenshot of an element even if not fully in view? This used to be possible with the old visual regression service for wdio, but I suspect that there was some extra logic that handled the scrolling and collating of multiple screenshots.

@wswebcreation
Copy link
Owner

Hi @anto-ac

Sorry, I didn't see this comment.

In other words, would it be possible to add the ability to take a screenshot of an element even if not fully in view?

Yes, you as a user need to be sure that you are scrolling the element in the view, I currently didn't implement the logic to automatically scroll to the element. That could be something for the future. You might have 1 challenge with that, what if the element is bigger then the view, how would you like to handle that?

@anto-ac
Copy link
Author

anto-ac commented Jun 29, 2019

Bigger than the view in both width and height do you mean?

@wswebcreation
Copy link
Owner

@anto-ac
More in height

@anto-ac
Copy link
Author

anto-ac commented Jun 30, 2019

That is exactly the use case I have in mind: an element that is taller than the viewport.

This is how wdio-screenshot (at the moment not compatible with wdio v5) does it:
https://github.com/zinserjan/wdio-screenshot/blob/master/src/modules/makeElementScreenshot.js

@wswebcreation
Copy link
Owner

Labeled it as a feature, it currently doesn't have this and I must say you're the first who wants to use it. The core has been extracted from my previous module that is already out there for 3 years or something and I never had this question.

@Viacheslav-Romanov
Copy link

IMO the framework should provide the options to capture entire screenshot of the element even it's hidden behind the viewport or throw an error with clear error message that element doesn't fit into the viewport (with suggestions like extend vieport, etc.).

@L0stSoul
Copy link

When upgrading from WDIOv4 + zinserjan/wdio-screenshot we also encounter problems with that.
So adding that feature would be helpful :)

@wswebcreation
Copy link
Owner

Ok,

Been diving into this feature request and it's very complex, the V4-module wdio-screenshot module had a solution for it, there are some downsides to the solution but here are my thoughts:

Re-use solution from wdio-screenshot
It's basically determining the element size, the screensize and then the diff between them, if the element is not in the viewport is will take a screenshot, cut the element out, scroll, take a screenshot, cut the element out and so on

There are some downsides to this solution:

  • you need to be aware of elements that could stick, like a sticky menu and if you explicitly need to hide them, this can be implemented, but is error prone of you don't think about it
  • this will not work for mobile because the screenshot will contain the status and address bar. This makes the calculation very complex and requires a lot of refactoring of the core code which makes it a dangerous feature to implement.

Use the takeElementScreenshot from W3C:
This method can take a screenshot of a complete element without doing all the complex calculations. Really easy to use and not that hard to implement

The downside of this is that it is hardly supported with Appium. I've been running some tests and most of them fail with Appium on different devices / OS versions

There might be more solutions, but I still don't see a lot of usage for this specific feature. I'll keep this on my to-do-list and if people like to work on it I'm happy to support it, but for now it will not have my highest priority

@KITSEPAMMaksymDusheiko
Copy link

takeElementScreenshot from W3C is not a solution -

The Take Element Screenshot command takes a screenshot of the visible region encompassed by the bounding rectangle of an element.
https://w3c.github.io/webdriver/#dfn-take-element-screenshot

@dpoetzsch
Copy link

dpoetzsch commented Oct 5, 2022

We were running into this problem as well because our test suite heavily uses element comparison for visual regression testing. Just taking the whole screen is not an easy option because this make the screens even more fragile.

As we also ran into other problems (mainly #115) we ported wdio-screenshot to wdio v7: https://www.npmjs.com/package/wdio-screenshot-v7. Then, we migrated back to https://www.npmjs.com/package/wdio-visual-regression with custom matchers. This is a working solution until this project stabilizes.

@tanjilahsan
Copy link

Hi @wswebcreation
This would be a very useful feature for me. Especially when I just want to skip a small part of the page.
Could you please let me know if you are still in the process of adding this feature?
Thanks

@wswebcreation
Copy link
Owner

Hi @tanjilahsan

I'm not actively working on this one, any help is appreciated

@tanjilahsan
Copy link

Hi @wswebcreation
I would like to help if I can. Please let me know what is the process to contribute as I am new to this.
Should I just clone and jump start or is there anything I should know before?
Thanks

@mazur-nadia
Copy link

Hi @wswebcreation This would be a very useful feature for me. Especially when I just want to skip a small part of the page. Could you please let me know if you are still in the process of adding this feature? Thanks

For your purpose, you can use checkElement() with hideElements option.
Like this:

checkResult = await browser.checkElement(element, tag,   { hideElements: [elementToSkip] })

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

No branches or pull requests

8 participants