3 Replies Latest reply on Feb 21, 2014 6:57 AM by Aslak Knutsen

    How to distribute unified recorder for the first alpha release?

    Stefan Miklosovic Novice



      this one sums up what was written on ML + other info. I just write it here all one more time and more precisely. Sorry for being too verbose.


      We are trying to release this https://github.com/smiklosovic/arquillian-unified-recorder


      How does it work


      As I write this, project is organized in the following manner:


      • arquillian-recorder - this one represents core API which all other extensions depend on (directly or in-directly).
        • -api
        • -build
        • -spi
      • arquillian-recorder-screenshooter - it is Arquillian extension but it _does not_ do anything on its own. It consists of:
        • -api
        • -impl
        • -spi
      • arquillian-recorder-video - it is Arquillian extension but it _does not_ do anything on its own. It consists of:
        • -api
        • -impl
        • -spi
      • arquillian-recorder-reporter - reporting extension, it consists of:
        • -api
          • arquillian-recorder-api
          • arquillian-recorder-reporter-spi
        • -impl (1)
          • Depends on:
            • arquillian-recorder-reporter-api
            • arquillian-recorder-reporter-spi
        • -spi
          • Depends on:
            • arquillian-recorder-spi


      So, reporter extension is standalone extension which does not depend on anything but core API. Interaction with this extension from outside is purly on event level. All extensions depends on arquillian-recorder-api/spi.


      • implementations
        • arquillian-browser-screenshooter - this one took WebDriver approach when taking screenshots. I do not know details, it was implemented by Juraj Huska, however it uses Graphene interceptors so you can take screenshot on every webdriver interaction (meaning on every webdriver's method call) + by default on default Arquillian lifecycle, Before, After ... there is some basic strategy you can override via SPI in order to say when (in which situation) should be screenshot automatically taken.
          • Depends on
            • arquillian-drone-webdriver
            • graphene-webdriver
            • arquillian-recorder-screenshooter-impl (1)
        • arquillian-desktop-screenshooter - likely will be dropped
          • It takes screenshots of whole desktop by native way. It just uses some native java stuff to take screenshot of desktop. We are not sure if this one has some usecase and we are willing and about to drop it.
        • arquillian-droidium-screenshooter - takes screenshots of mobile devices. Screenshot is taken in Droidium via native ddmlib artifact (bridge between Android and Java).
          • Depends on droidium-api
        • arquillian-desktop-video-recorder
          • Records your desktop as-is.



      Why are there arquillian-recorder-screenshooter and arquillian-recorder-video?


      These "sub-extensions" are proper Arquillian extensions as you know them but they are kind of "dummy". They do not take any screens nor record videos on their own. They are there for setting up all necessary infrastructure which is needed for every implementation of screenshooters and video recorders. There is default strategy for taking screens and videos and so on. The point of having these subextensions on which every concrete implementation is built is that you do not repeat yourself. You would have to implement this all over and over again in every implementation so the point is that you just use core implementation and you basically code only concrete Screenshooter.


      Let's see an example of Droidium Screenshooter:


      Because of dependency on arquillian-recoreder-screenshooter-impl, this whole extension only consists of 3-5 classes.


      The implementation is really only about this: arquillian-unified-recorder/implementations/arquillian-droidium-screenshooter/src/main/java/org/arquillian/extension/rec…

      It implements Screenshooter which is produced and that's it.


      This principle hold basically for every other implementation. The idea is still the same. You put everything which is common into "arquillian-recorder-screenshooter-impl" and in your concrete screenshooter implementation extension, you just provide implementation of Screenshooter interface. The same principle holds for video extensions.


      Why it is done such way?


      • Because there can be a lot of concrete implementations of Screenshooters as you can see right now. When some other guy comes and says, hey, I want to do some screenshots which will be taken by XYZ, I do not care at all since I know that he just builds his own screenshooter on top of that core arquillian-recorder-screenshooter-impl.
      • Other example. It is possible that there could be extension which records videos of Android devices. In 4.4 you can record it from command line. When I do not do this in a way as I did, I would have to modify core video recorder, but right now, I just take arquillian-recorder-video-impl and implement just Recorder interface in my concrete Android recorder extension and I am done.
      • Another point relates to configuration. When you have multiple configurations of Screenshooters, they can be configured differently. Every implementation could have its own as it is the case of Browser screenshooter - there is some configuration stuff related to interceptor things (takeScreenOnEveryAction). This property does not make sense in desktop nor Droidium screenshooter. Various configurations leads to standalone extensions. I think it is not good idea to bundle every implementation to "screenshooters" dependency.
      • Simplicitly of usage:
        • This is the main clash between me and Karel. I am for having simple extensions which do their job. Precisely and just for what I need. I personaly see Arquillian as a platform where I can construct my own testing experience. "I've got to test mobile native application and I need take screenshots of that and I will deploy some ear to EAP and maybe some reports would be handy" - nothing easier - put two containers on classpath, drone, _droidium screenshooter_ and reporter and you are done. I love how I can build my own "testing experience" like some LEGO. That is the whole point of extensions right?. On the other hand, I do realize that having it in such way leads to kind of confusion and you have to know "what is available" in order to put it together and that nothing is "turned on" (like reports) by default. I do not know what Arquillian prefers but I see the modularity and the extensionality as very strong advantage and I just prefer this way.


      Karel's opinion is that all screenshooters (possiblity with video recorders) should be bundled all together and that reporter should be kind of turned on by default.


      When reporter is going to be turned on by default, where should be that artifact located? As a dependency of what? Graphene? Drone? Droidium? In every one of these? In addition, I do not like that you "force" tester to use something other then core Arquillian. He knows best what he wants. Or not?




      When you want to reduce number of artifacts and hide it behind some depchain, options are like these:


      1) Drop desktop screenshooter and drop Droidium screenshooter as well. By dropping native Droidium screenshooter, you can take screens only when you test by WebDriver. Not sure I am for this. However, when we drop it, we would have just one "Browser" screenshooter and for that matter, that implementation could be moved to "arquillian-recorder-screenshooter-impl" so you would have -3 implementations + Browser impl would be moved to core -screenshooter-impl and the argument for having custom extensions is from this point obsolete. However I am curious what happens when somebody wants his custom screenshooter / recorder.


      2) Another option is to merge all three (or two when desktop impl is dropped) into one implementation but that leads to implementation problems:

      • Configuration properties for Browser screenshooter are not the same as for Droidium screenshooter
      • There would be a need how to "switch" between them. E.g. when I do screens on pure Droidium without WebDriver I need to choose the right implementation of Screenshooter which is Droidium-specific.
        • It can be done by some property like "screenshooterType" - browser|droidium but I just do not like it. Extension should do one thing for one use case and do it right.
        • I do not like this idea that everything should be bundled together. It makes application logic just harder to follow and harder to maintain.


      Reporting and doing screens turned on by default?


      Karel thinks that reporting and taking screenshots makes testing experience better - you have it turned on by default. I am not sure if I am for this - meaning that screenshooter or reporter should be e.g. part of Droidium. I am not for this idea. This point relates to another problem that when you put some extension on CP and even you do not want to use it, since observes are already registered and they are doing their job, you would end up with a need to check for every @Observes whether this extension is not "turned off" in configuration so that observer would be skipped in the code. I guess it is really bad idea to have it such way.


      For that reason, I am for the possibility of having tester who opt-in when he wants some functionality and not other way, that he needs to opt-out (possibly having performance overhead when some extension is on cp and registered into Arquillian but in effect it does not do anything).


      Putting all artifacts into one dependecy and having developer putting this into his project on his own will _could_ do its job however bundling everything together (all implementations) and switching between them in runtime is, in my humble opinion, not a good idea.

        • 1. Re: How to distribute unified recorder for the first alpha release?
          Karel Piwko Master

          Hi Stefan,


          based on on-site discussion, I'm adding my feedback:


          • arquillian-recorder-reporter should be made a part of arquillian-recorder itself. Probability that somebody will be willing to use recorder without nice reports is very close to zero. This will also simplify dependencies to be added to project - reducing to single dependency
          • arquillian-recorder-screenshoter-impl and arquillian-recorder-video-impl should rather be renamed to -core, -base, -common or something like that to reflect fact they are supposed to be extended by "real" implementation
          • implementations directory should be discarded
            • arquillian-browser-screenshoter should be made a part of Arquillian Graphene
            • arquillian-droidium-screenshoter should be made a part of Arquillian Droidium
            • arquillian-desktop-video-recorder should be made a standalone project, as it is not that much useful at this moment and kept it beta/labs...we need to make it grab only browser or something like that
            • arquillian-desktop-screenshoter can be removed, there is no real use case that cannot be handled by browser/droidium screenshoter
            • the idea is to keep reporting facilities close to extension that profits from it. Allow to share lifecycle with extension where it belongs to. Also, reporting can make a part of documentation - so user will easily spot it when using Graphene/Droidium. So, reporting submodule is defined in BOM but not a part of depchain. If we discover users are using reporting in 70%+, we can make it default in depchain as well.
          • naming - can we figure something out - deneuralyzer anybody ? twitter might help?


          So, usage will be quite straightforward. If user want to enable logging for Graphene, he just adds one artifact from Graphene BOM and he'll get reports. If this is a part of guides/doc, it should be pretty easy to identify whether this should be a default behavior.


          Post Alpha1 steps:

          • allow multiple screenshooters on CP
          • think of better naming for Exporter - Publisher or something
          • provide on-the-fly updating exporter - something that is able to report as test goes, not after all tests
          • think of better hiding of JAX-RS dependency - as this might collide with test classpath, it might be good idea to shade it or somehow load via modular classloader


          Otherwise, I have to say that this extension represents impressive amount of work and I can't wait for having reporting/logging facilities in every extension/container/core in Arquillian!



          • 2. Re: How to distribute unified recorder for the first alpha release?
            Stefan Miklosovic Novice

            Updated dependency model:


            • arquillian-recorder
              • -api / -build / -spi
                • contains arquillian-recorder-reporter
            • arquillian-recorder-screenshooter-base
              • -api / -impl / -spi
              • Depends on arquillian-recorder
            • arquillian-recorder-video-base
              • -api / -impl / -spi
              • Depends on arquillian-recorder
            • arquillian-recorder-reporter
            • -api / -impl / -spi
              • is contained in arquillian-recorder


            Every custom implementation will depend on screenshooter-base / video-base. These -base projects build on top of arquillian-recorder which in turn contains reporter so implementing of screenshooter will automatically get reporter on CP.


            • implementations
              • arquillian-browser-screenshooter
                • moved to Graphene project, released but not on CP by default while testing
              • arquillian-droidium-screenshooter
                • moved to Droidium project, released but not on CP by default while testing
              • arquillian-desktop-video-recorder - standalone repo
                • Records your desktop as-is.
              • arquillian-desktop-screenshooter - will be dropped