0

I was asked to implement a "proof of display" in a web application...

This means that I need to, somehow, get a screenshot of what is or will be displayed (or close) to the client in his browser, to be able to prove that we did give him what he was needed as a "legal" evidence.

Even if I don't agree with this kind of proof (browser have their own way to display HTML, stored screenshot can easily be hack or faked, ...), I wonder if it has already been done somewhere and how to implement this kind of functionality.

Any Idea or experience ?

To make it simpler, we cannot ask user to install anything (plug-ins, applications, ...)
Technologies used : mainly Java, Spring-mvc, Thymeleaf and JQuery

antoine
  • 618
  • 7
  • 16
  • You mean you want to have a proof the client saw something in his browser ? – Denys Séguret Jan 13 '14 at 15:35
  • Why don't you use a browser testing service such as [Browserstack](http://www.browserstack.com)? You can select a number of different browsers and get it to email you back screenshots of what a specified URL rendered as. – ajtrichards Jan 13 '14 at 15:37
  • I believe the OP wants some kind of visual proof of what a specific user is "seeing". – Boaz Jan 13 '14 at 15:39
  • yes : an image or something else that can prove what he saw – antoine Jan 13 '14 at 15:39
  • 2
    Can't you ask him to print screen? – ajtrichards Jan 13 '14 at 15:41
  • 2
    This doesn't make any technical sense as you probably know. Which doesn't mean it doesn't make any legal sense but this is probably very dependent of the accepted legal practice of your country. – Denys Séguret Jan 13 '14 at 15:41
  • Browserstack is a testing tool (that I will have a look to...) but cannot be used in production with real user. About the how "legal" is this : I am not sure if this will be accepted as an evidence too... – antoine Jan 13 '14 at 15:45
  • 1
    http://stackoverflow.com/a/6678156/106261 – NimChimpsky Jan 13 '14 at 16:12
  • @NimChimpsky good advice ! I'll give it a try even if it does only work with html5. I'll give feebacks as soon as possible. – antoine Jan 13 '14 at 20:22

2 Answers2

0

You can use Selenium Webdriver to make screenshots and save it to your local disk. Look in this question about How take screenshot using selenium webdriver with java.

But then again this can only be used as an automated testing tool to manipulate user activities in a system without any user interactions. Our project also use the same technology stack you mentioned and the testing team uses the Selenium webdriver to make the screenshots of certain conditions to make sure the condition works.

It is usually done by selecting and checking the id's and tag element in the html page loaded using Xpath selectors. And it will take screenshot of failure and success conditions in a separate folder configured in the java code they run. Then it creates an Excel document on-the-fly to show the tasks performed and results of those tasks.

Community
  • 1
  • 1
Lucky
  • 16,787
  • 19
  • 117
  • 151
0

OK, here are 2 solutions found :

One server side : capture the HTML flow before sending it to the client's browser using Filter :

    public class ProofDisplayFilter implements Filter {
        @Override
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException {

             HttpServletRequest request = (HttpServletRequest) req;
             HttpServletResponse response = (HttpServletResponse) res;  

             Mywriter writer = ...;
             ProofWriter proofWriter = new ProofWriter(response.getWriter(), writer);

              //doFilter will right in the proofWriter that will copy output flow
              chain.doFilter(request, wrapResponse(response, proofWriter)); 

              //do whatever you need with your copy
              saveHTMLAndStaticContentAsZip(proofWriter);
        }

        private static HttpServletResponse wrapResponse (final HttpServletResponse response, final PrintWriter writer){
                return new HttpServletResponseWrapper(response) {
                    public PrintWriter getWriter() throws IOException {
                        return writer;
                    }
                };
       }
    }

The thing is that you need to modify the HTML flow to get the good reference to js, css and image resources.

One client side : (Thanks @NimChimpsky) use the html2canvas.js API to create a snapshot and send it to your controller as an image :

JS

    html2canvas(document.body, {
                onrendered: function(canvas) {
                    $.post('/myApp/proof',
                            {
                                image : canvas.toDataURL()
                            },
                            function(data) {...});
                }
            });

CONTROLLER

    @RequestMapping(value = "/proof")
    @ResponseBody
    public void proof(@RequestParam(value="image") String imageBase64) throws IOException {
        long now = Calendar.getInstance().getTimeInMillis();
        byte[] bytes = imageBase64.replaceAll("data:image/.+;base64,", "").getBytes();

        File proof = new File("./proof", "display-"+now+".jpeg");

        if(!proof.exists()){
            Files.createParentDirs(proof);
        }
        Files.write(DECODER.decode(bytes), proof);
}

(Or anything else you need to do with this image)

Both solutions have pros and cons :
Server-side :
PROS
- Capture HTML as it is
- possibility to process/compare HTML flow
CONS
- We don't know how it was displayed to the client
- Consume a lot of disk space : ~1Mo/capture (need to save static files too)
- What about part of the page called using AJAX ?

client-side :
PROS
- Precise : set the script in the pages that need it
- Manage rendering of the browser
CONS
- use HTML5 canvas which is not supported in IE until the 9th version.
- Intrusive (in my point of view)

Hoping this can help someonelse.
Thanks for your support!

antoine
  • 618
  • 7
  • 16