Friday, February 10, 2012

JavaScript parseInt does not work as expected when parameter starts with 0

There is standard way to parse Strings into Numbers in JavaScript by using parseInt function. But sometimes it works unexpected, and for example, returns 0 when you expect 8. If that is the case, then most probably problem is that when parameter starts with 0 (like '08') parseInt treats it as octal number and changes radix to 8.
This is annoying and can take some time to discover. Luckily, it is easy to fix by specifying radix directly as second parameter. For example like:

parseInt('08', 10)




Wednesday, February 8, 2012

Copy method in Groovy

If you need to copy method reference between objects at runtime, it is super easy in Groovy. Just add & in front of method name and this it. For example:

new Expando(id:it.id, user:it.user, mymethod:it.&othermethod, ...)

For some reason this is not very wide known feature (was not for me), and I unsuccessfully tried to use metaClass and other complicated things before finding this.

Friday, February 3, 2012

Freezing table header with JQuery

When you have long table on page, with a lot of numbers, and you scroll down and header is not visible anymore, it is often difficult to track what number is which column. One nice solution to this problem is to lock and freeze table header when scrolling page.
Unfortunately there is no ready out of the box solution with JQuery for this problem. Fortunately, it is easy to implement with few methods. There are examples how to do it, but for some reason they didn't worked well in my situation (no support for resize and horizontal scroll), so I have adjusted them for my situation.

For example, you have your table named tabs.

First, you have to create invisible table that will hold frozen header.

<table cellpadding='0' cellspacing='0' id="header-fixed"  style="position: fixed; top: 0px; display:none;"></table>

Then just add this Javascript:

     <script type="text/javascript">
       var tableOffset;
       var header;
       var fixedHeader;

       function resize() {
         var totalwidth = $('#tabs').css('width');
         fixedHeader.css('width', totalwidth);
         var widths = [];
         $('#tabs thead th').each(function() {
           widths.push($(this).width());
         });
         var i=0;
         $('#header-fixed th').each(function() {
           this.width = widths[i];
           i++;
         });
       }
       function resizeAndShow() {
         var offset = $(this).scrollTop();
         if (offset >= tableOffset && fixedHeader.is(":hidden")) {
           fixedHeader.show();
           resize();
         } else if (offset < tableOffset) {
           fixedHeader.hide();
         }
         fixedHeader.css('left', $('#tabs').position().left - $(this).scrollLeft());
       };
        $(document).ready(function() {
          tableOffset = $("#tabs").offset().top;
          header = $("#tabs > thead").clone();
          fixedHeader = $("#header-fixed").append(header);

          $(window).bind("scroll", resizeAndShow);
          $(window).resize(resize);
        });
     </script>

This is it.

Thursday, January 5, 2012

Getting text of selected option in Geb

Geb has very nice function to get value of selected option, but I was not able to find method to get it's text. Fortunately, it is still possible using ugly Selenium API and can be nicely hidden behind Page Object. For example, this is what I have in my Page Object:

myField {$("#my") }
myFieldValue {  new Select($("#my").getElement(0)).getFirstSelectedOption().getText() }

And this is how it looks in Spec:

when:
myField.value('B')

then:
myFieldValue == 'B'




Friday, December 30, 2011

Check element existance in Geb

In Geb, if you need to check if some element does exists on page or not the best looking way to do it is method isPresent(), so it can be called like:

!notNeededLink.present
otherLink.present

Of course if you plan to check non-existing elements like this they need to be defined as not required and with wait - false. For example:

notNeededLink(to: SomePage, required:false, wait: false) {$('a', text:'Some')}

Tuesday, December 20, 2011

Too many idle database connections with Tomcat

I recently had problem when there were too many open database connections in Tomcat. Everything was right, but number is far more then is defined in Tomcat resources.
After some investigation, I have found that problem was that datasources were defined in wrong place - conf/context.xml, and when they are defined there, they are picked for every Web application that is defined in this Tomcat instance (including management and utility), therefore you will have all your connections multiplied by number of applications you have.
Fortunately, it is easy to fix by defining resources under conf/Catalina/localhost/ROOT.xml (ROOT if application is defined under root, otherwise, name of your application), in which case, resources will be provided only for specified application.

Tuesday, December 6, 2011

Passing upstream parameters to downstream builds in Jenkins

Jenkins has cool Pipeline plugin, which helps to create build pipelines, that for example, can organize and visualize deployment process. Plugin is very cool and looks great, but lacks few basic features, like passing generated parameters or variables from upstream builds to downstream.
For example, I wanted to pass SVN revision number into downstream builds.
Fortunately it is easy to do it with little hacking. Here is what I did.
  1. Add Groovy plugin.
  2. Add new build step Execute system Groovy script, now it is possible to hook into Jenkins internals.
  3. Then just add Groovy script there:
import hudson.model.*
def thr = Thread.currentThread()
def build = thr?.executable
build.addAction(new ParametersAction(new StringParameterValue('SVN_UPSTREAM', build.getEnvVars()['SVN_REVISION'])))


What this script does it just creates new parameter and adds SVN_REVISION from environment variables there. And pipeline can pass parameters with this mechanism to downstream builds (all of them).
Easy!