-
Notifications
You must be signed in to change notification settings - Fork 105
Add Screenshot function to Selection. #111
base: master
Are you sure you want to change the base?
Add Screenshot function to Selection. #111
Conversation
Hi @johanbrandhorst, thanks for contributing. Your PR looks fantastic! If you have time, you could add an integration test here that looks like this. Doing so would give us a test to drive out a fix. It seems like the per-element screenshot API is newer, and isn't implemented for every webdriver yet. The webdriver.io docs seem to suggest this. If you can use a webdriver that supports per-element screenshots, I'm happy to merge this with your current implementation. You can filter out the unsupported webdrivers in your integration test like this. If you need to use a webdriver that doesn't support per-element screenshots, you could fallback to taking a screenshot of the whole page and cropping it to the selected element's rect. Here's an extension to webdriver.io that employs that strategy successfully. |
@sclevine Thanks for the feedback! I'll get on those integration tests. I'd really like to have this functionality with ChromeDriver myself so I'll try and implement the fallback as well. |
Adding the integration test was easy, and after some struggling I managed to get PhantomJS, ChromeDriver and Selenium running. ChromeDriver reports the error I reported before, and while PhantomJS does seem to have implemented the element screenshot endpoint, the screenshot in question is still of the whole page. Selenium (with firefox) returns an extremely unhelpful error:
This is in the debug log:
As for fallback strategies, do you prefer it to "give it a go" and do the fallback as error handling or to have a whitelist/blacklist of browsers in the function? |
5b10af5
to
57eff70
Compare
I've pushed up the integration tests anyway, you can test run them yourself if you have a large setup of drivers. I expect the Travis integration tests will fail because the PhantomJS screenshot is of the whole page. |
As a general rule, Agouti should implement the w3c spec, and bugs and missing functionality should be fixed upstream in the webdrivers. At the
This strategy reduces maintenance costs for Agouti. When bugs are fixed and additional endpoints are implemented upstream, the fallback behavior becomes unnecessary, but no changes are needed in Agouti. That said, browsers should be whitelisted/blacklisted in the integration tests when functionality is broken and we don't have a sane fallback behavior. For instance, I'm fine with per-element PhantomJS screenshots not working due to the whole-page bug you mentioned, as long as the integration test blacklists PhantomJS. |
Okay, so if I'm understanding that correctly, what I should be doing is implement a new method on the Obviously, this means that PhantomJS will still exhibit the wron behaviour because it wouldn't trigger the fallback but it also wouldn't capture only the element in the screenshot. Therefore it should be blacklisted from the Am I understanding that correctly? |
Almost. The |
Cool, can probably do. I'm going to have to implement https://www.w3.org/TR/webdriver/#get-element-rect at the same time, but that appears simple enough. How do you feel about 3rd party dependencies? I'm loathe to introduce one unless it's needed but for cropping an |
With the exception of tests (which depend on Ginkgo) and the Gomega I leave it up to you though -- I'll accept the PR either way. If you do include it, please vendor it using the |
So, I've implemented ChromeDriver doesn't support the element screenshot, and also doesn't support the get element rect endpoint. PhantomJS as mentioned supports the element screenshot endpoint but still draws the entire page. Firefox supports get element rect, but I'm not entirely sure how to translate the I will push the stuff I've written, but I'm not sure how to proceed here. We might just have to close this an blame poor driver support. I could also limit the scope of this PR to just be adding the element screenshot and element rect endpoints to the |
57eff70
to
f02d45c
Compare
I'm hesitant to add the endpoints to If you can make this work with more than one webdriver, I'll merge it to master, and we can blacklist the others in the integration tests. If not, how about we:
I appreciate the work you've put into this, and I hope that we can merge it eventually :) |
f02d45c
to
746f25e
Compare
So I think it might be possible to get this functionality (the cropping technique) working with Firefox, since it does support Given that, I've decided not to pursue this any further. I have made the changes you suggested and squashed the commit history a bit, so we can retarget this PR to a branch in this repo and open a new PR to merge that into master (is that the easiest way?). Thanks for being such a great maintainer! It's always exciting to have such good and prompt feedback on PRs. Lets hope this could be solved with proper driver support down the line 😞 . |
Test failures seems to be due to a difference of encoding in |
Leave this PR open, and I'll take care of moving the branch over when I have time. Github doesn't support changing the source repo for PRs, so I'll just mention the local branch name here and keep it rebased against master, if that works for you. I really appreciate your efforts, and I'm disappointed that we can't merge this (yet). I spend a significant portion of my time reviewing PRs, and I rarely see first-time contributions of this quality 😄 |
Happy to contribute 👍. I've automated the testing of my GopherJS framework courtesy of agouti and I wanted to give back. Good luck with the project! |
Any updates on this feature? |
// cropped copy of the original img. | ||
func Crop(img image.Image, width, height int, anchor image.Point) (image.Image, error) { | ||
maxBounds := maxBounds(anchor, img.Bounds()) | ||
size := computeSize(maxBounds, image.Point{width, height}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the logic, there is no need to create maxBounds / computeSize functions.
just need to use
size := image.Point{width, height}
} | ||
|
||
screenshot, err := selectedElement.GetScreenshot() | ||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than adding a fallback, it could be more explicit if we have two functions, one directly use the screenshot, the other use the fallback. And after detecting the browser version, we directly calls one function or the other.
@shanshanzhu Thanks for picking up on this PR, unfortunately I have not touched it since last year (as you can see). I found at the time that support for this in the web drivers was in the range of lacking to non-existent. If that has changed in the meantime you're welcome to pick this up, but I currently don't have the time to invest in this right now. |
Hello any update for this Feature |
Hey, |
Fixes #104. Adds Screenshot function to Selection and GetScreenshot to the element API.
I had a quick stab at implementing this, and when I tried it in my own tests I'm seeing the following error:
I'm slightly confused as that seems to conform to the API description in https://w3c.github.io/webdriver/webdriver-spec.html#take-element-screenshot. Am I doing something obviously wrong?