2011/06/22

Fighting Crawling Maven Dependency Changes With Git

You know the situation well - everything goes fine, continuous integration does what is used to do and new releases are produced on regular basis.

Then, out of the blue, integration tests fail with Java complaining about two different versions of the same library on classpath. You can be less lucky and use different version than you think, or different implementation of an API, or your JAR/WAR/whatever-package just grows without reason. Lot of bad things can happen when dependecies get out of control.

It does not depend on the source - one of your colleagues changing something without double-check or changes in some already used library. To fight these problems I tried to use Git pre-commit hook you can see below. It is not perfect but it works. It depends on Maven, if you use Ivy, Gradle or something else, you will have to adapt it.

Just put it in you projects' /git/hooks named pre-commit. When dependency changes are detected, they are printed and commit is aborted - you will have to use diff tool on deps.txt (old dependencies) and deps_tmp.txt (new dependencies) and update deps.txt if the dependency change is desired. If the change is unwanted, use mvn dependency:tree to find the source of problems.

It has only one more constraint -- all people using it must use the same version of Maven. Because of changes in dependency resolution in Maven 3,  Maven dependency plug-in produces slightly different list of changes in versions 2 and 3.

#!/bin/sh

mvn dependency:list -DincludeScope=compile | sort | grep jar \
| cut -c 11- | cut -d":" -f 1-4 | uniq >deps_tmp.txt

diff -a -B -b -u deps.txt deps_tmp.txt >deps_diff.txt

lines=`cat deps_diff.txt | wc -l`

if [ $lines -ne 0 ]; then
   echo "Dependency change detected - check 'mvn dependency:tree' and update deps.txt."
   cat deps_diff.txt
   if [ -a deps_diff.txt ]; then rm -f deps_diff.txt; fi
   exit 1
fi

2011/06/06

Moving to Selenium 2 on WebDriver, Part No.5

Sending Mouse Clicks Via Javascript

Sometimes the WebDriver click does not work well,  after all it is still under development and bugs should be expected. For such case the ability to execute JavaScript through JavascriptExecutor comes in handy. Following code can send "click" or "dblclick" when used as eventName to a DOM element addressed by elementRef - JavaScript expression evaluating to a Node.


  public void fireJsEvent(String elementRef, String eventName)
    {

        String script =
        "" +
        " function eventFire(element, eventName)" +
        " {" +
        "  if (element.fireEvent)" +
        "  { element.fireEvent('on' + eventName); }" +
        "  else" +
        "  {" +
        "    var eventObject = document.createEvent('Events');" +    
        // parameters: type, bubbles, cancelable
        "    eventObject.initEvent(eventName, true, false);" +
        "    element.dispatchEvent(eventObject);" +
        "  }" +
        " };";

        String eventCall = String.format( "eventFire(%s, '%s');", elementRef, eventName );
        String exec = script + eventCall;
        js.executeScript(exec);
    }

Possible usage on a web page with dojo:

fireJsEvent("dojo.query('.someColumn:nth-child(1) li:nth-child(2)')[0]", "click");