JIRA

Time Zones in JIRA

JIRA allows every user to specify his own timezone through user profile since version 4.4.

JIRA Time zones

JIRA Time zones

If you look at the above diagram at any time we have to consider 3 different time zone. Theoretically users computer/browser’s time zone may also be different than user’s time zone defined in profile page. In that case JIRA will inform user about this mismatch and request user to fix. If he does not any REStFul API that accepts time zone as milliseconds since 1970 convention will fail. As a best practice web service APIs should accept time related information in textual format. But this also has formatting problems and makes using API a little more difficult but it is better than processing wrong information.

When an action is performed by a user, timestamp is converted to JIRA’s own timezone setting and recorded in the database. Later when needed this timezone is also converted to requesting user’s (possibly a different user than who performed the action) timezone. This cause everyone to see different time for the same event. This is the same for work log entries. Lets see with an example. Following two screenshots are for the same work log entry.
In the first one we see how it is displayed for a user with time zone “(GMT+02:00) Istanbul”:

In the second one we see how it is displayed for a user with time zone “(GMT-11:00) Midway”:

As you can see they see the same work log entry as if it is performed on different days. For the perspective of the user actually it is performed on different days. But the question is, “On which day we should place this work log entry for a timesheet?”
Since timesheets are mostly used for cost or billing calculations the day on which a work is performed is very important. For example some companies may be paying more for works performed on weekends. If a user did not performed the issue on the weekend it should not be reported as performed on weekend just because of time zone of the user requesting the timesheet report is different from time zone of work log author.

In Worklog PRO Timesheet for JIRA we display this work log on the same day work log author reported. Not with the time zone of the user requesting the timesheet or not with the time zone of the server. This is also compliant with how timesheets are reported by another popular JIRA Timesheet tool. But these two plugins are radically different in terms of how work logs are stored in JIRA.
Lets start with the easy one, Worklog PRO Timesheet. It just stores work logs with JIRA’s own convention so its work logs are compliant with JIRA. Later if you decide to uninstall the plugin all work logs will be as if they are entered from JIRA’s own work log entry dialog.
Other timesheet solution stores work log entries normalized with JIRA Server’s time zone. As a result if you look at the same work log with this tools own “work log panel” you will see different date and times than it is displayed by JIRA’s own “work log panel”. Recommended solution is to disable JIRA’s own work log panel. But later if you decide to uninstall the plugin, you will need to re-enable it and it will continue to show incorrect dates forever.

VN:F [1.9.22_1171]
Rating: 9.0/10 (4 votes cast)

Using Selenium Chrome Driver on Mac OS X

Update (26/06/2015)
Previously I have written a function which waits until a specific element is available on the page, doWhenAvailable. I have find out Selenium has already a similar feature build-in. Its element search functions could wait until an element is available on the page. It can be activated in @BeforeClass method:

driver. manage( .timeouts( ). implicitlyWait(TIMEOUT_TIME,  TimeUnit.SECONDS) ;
//doWhenAvailable(driver, By.id( “view_profile”), WebElement::click); 
driver.findElement(By.id(“view_profile”)).click() ;

 

It took several attempts for me able to use Chrome Driver by using the instructions from its website and I have decided to publish a step by step tutorial.

Selenium allows you to run your tests using several different browsers Chrome, Firefox, InternetExplorer and HTMLUnit. HTMLUnit is not a real browser it is just a browser simulator written in Java, it can execute JavaScript too. Some settings you have to use for each one is different but for all of them you have to start by adding main Selenium dependency to you project. This is the common part.

Creating Maven Project

I have created a new maven project using following pom.xml but you can just add selenium dependency to your own pom.xml if you want. Here is the pom.xml file I have used for my test project:

 

<!--?xml version="1.0" encoding="UTF-8"?-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelversion>4.0.0</modelversion>
    <groupid>com.deniz.jira</groupid>
    <artifactid>JIRASeleniumTests</artifactid>
    <version>1.0</version>
    <name>JIRASeleniumTests</name>
    <dependencies>
        <!-- This is only required dependency. -->
        <dependency>
            <groupid>org.seleniumhq.selenium</groupid>
            <artifactid>selenium-java</artifactid>
            <version>2.46.0</version>
        </dependency>
        <!-- Selenium does not enforce any unit testing framework and
        it does not have any unit testing features, like asserts so
        we are using JUnit for this. But this is optional and
        you do not need to use any unit testing library if you want. -->
        <dependency>
            <groupid>junit</groupid>
            <artifactid>junit</artifactid>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupid>org.hamcrest</groupid>
            <artifactid>hamcrest-all</artifactid>
            <version>1.3</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <!-- Using Java 8's Lambda expressions makes code simple.
        Because you will be using a lot of handler to asynchronous methods.
        But this is not required. -->
        <plugins>
            <plugin>
                <groupid>org.apache.maven.plugins</groupid>
                <artifactid>maven-compiler-plugin</artifactid>
                <version>3.3</version>
                <configuration>
                    <source>1.8
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

WebDriver Specific Initialization

For newcomers it is best to stick with Firefox. It is easier to setup. After installing Firefox browser to you system just create a new FirefoxDriver and start running your project. There are no extra step required.

For Chrome in addition to Chrome Browser you have to install Chrome Driver too. You can download Chrome Driver from Chromium web site and put it in a suitable place in your system. Location is not important because we will be providing location of it through a system property to our test execution.

In my case I have put chromedriver executable to Applications folder. So for my JUnit test I have use following setting:

System.setProperty("webdriver.chrome.driver" ,  "/Applications/chromedriver");

Writing Actual Test Codes

We have to initialize our WebDriver instance, since I am using JUnit I have done it in @BeforeClass so it is automatically run before my test cases. You can also do this before every test case using @BeforeTest but it will be a lot slower because you will most probably do extra initialization than shown below. For example logging-in to web site.

@BeforeClass
public static void init() {
    driver = new ChromeDriver(); //init chrome driver
    //driver = new FirefoxDriver(); //uncomment to use Firefox
    driver.get("http://localhost:8080”); //url of website we like to test
    driver.manage().window().setSize(new Dimension(1600, 900)); //resize browser window
    //login to web site
}

You will most probably want browser to automatically closed after your tests are completed. Add driver.quit() to your JUnit teardown method. If you do not each execution will left a new browser window open.

@AfterClass
public static void teardown() {
    driver.quit();
}

Nowadays nearly all web applications will be loaded asynchronously. That mean when page is loaded the element you like to test will not be on the page, it will be generated by a JavaScript code. This makes writing test a little more difficult, you have to wait until related element is created by JavaScript code. I have writing a small helper function and reused it in my test code. It waits until given element (Specified using By) is available on the page and execute the given code block (Consumer) when the element is available:

public   static   void   doWhenAvailable( WebDriver driver ,  By by ,  Consumer consumer )   { 
     ( new   WebDriverWait (driver,  TIMEOUT_TIME ) ).until( ( WebDriver drv )   -&gt;  driver.findElement( by )  !=  null ) ; 
    consumer.accept( driver.findElement( by ) ) ; 
 }

 

Using this method with Java 8 is very readable. For example below code waits until an element with id=“view_profile” is available on the page and when it is available just clicks on it.

doWhenAvailable(driver, By.id("view_profile"), WebElement::click);

Following code performs more complex operation when requested element is available. It wails until <select id=“ts_month_picker_selector” …..> select element is available on the page and select option element which has a value of “Jan”:

doWhenAvailable(driver, By.id("ts_month_picker_selector"), (element) -&gt; {
    Select select = new Select(element);
    select.selectByValue(String.valueOf(“Jan"));
});

You will mostly need to perform other asynchronous operations inside the callback and this will result into callback hell. I am still looking a way to promise style of chaining asynchronous operations.

Tips and Tricks

  • Give every HTML element a unique id field. This will allow you to specify elements easily in your test code.
  • Create a reusable small test library specific to your application. For example you should encapsulate logging-in to test system in a method and reuse that method from every test case.
  • Try to avoid time based waits with Thread.sleep() or any other sleep as much as possible. Because they will increate time to run your tests. But you will probably need this for some AJAX based code. In my case I need it for dynamically filled comboboxes which fills its content as you type. Otherwise you may get StaleElementReferenceException because your driver will be using a previous instance of the same visual element not the one on the page. Instead of sleep you may allow StaleElementReferenceException to occur and re-fetch the element automatically. You can check details from here.
  • At the end of the test if test fails take a screenshot automatically. I will explain it in another post. 
VN:F [1.9.22_1171]
Rating: 7.7/10 (3 votes cast)

Preview Issue Description in JIRA

In start a work day by loggin in JIRA. At the end of the day I usually have 10+ tabs are open in the browser just for JIRA. Most of the times I only look description of the issue, I do not need issue to stay in the browser.
I have developed a free JIRA plugin to solve this problem. Everywhere inside (navigations, dashboard, inside other issues etc.) JIRA, if you hover mouse on an issue link, it displays description of the issue in a popover window. Preview contains all the formatting of JIRA, including images, tables, source code highlights etc. It is lighweight and fast way to browse issues.
You can download the plugin from Atlassian Marketplace.

JIRA Issue Description Preview

JIRA Issue Description Preview

VN:F [1.9.22_1171]
Rating: 9.5/10 (2 votes cast)

Installing JIRA on Amazon EC2 Ubuntu Small Instance

I have recently purchased a jira starter license for myself and decided to host it on my Amazon EC2 Ubuntu server. Memory of a small instance is only 1.7Gbytes and I am planning to run JIRA, Confluence, Stash, Mysql, VPN Server on that machine. I am planning to give each tomcat instance a 512MB memory. It may be possible to install JIRA and Confluence on the same Tomcat installation but this is not recommended by Atlasian.

  • Install Java

    #sudo add-apt-repository ppa:webupd8team/java
    #sudo apt-get update && sudo apt-get install oracle-jdk7-installer
     

  • Install mysql

     sudo apt-get install mysql

  • Connect to mysql with root account and password you have created during mysql installation

    mysql -u root -p

  • Create a database for JIRA  called jira

    mysql> create database jira character set utf8 collate utf8_bin 

  • Create a user named jira and grant access to jira database from anywhere

    grant all on jira.* to 'jira'@'localhost' identified by 'your_jira_user_password'  

  • Download JIRA

    wget http://www.atlassian.com/software/jira/downloads/binary/atlassian-jira-5.2.10.tar.gz 

  • Unzip JIRA installation

    tar -zxvf atlassian-jira-5.2.10.tar.gz

        This will extract JIRA to atlassian-jira-5.2.10-standalone folder.

  • Download Mysql JDBC driver, unzip it and copy it to atlassian-jira-5.2.10-standalone/lib folder.

    sudo apt-get install unzip
    unzip mysql-connector-java-5.1.24.zip
    cp mysql-connector-java-5.1.24/mysql-connector-java-5.1.24-bin.jar ~/atlassian-jira-5.2.10-standalone/lib/

  • Adjust memory settings of JIRA installation by editing the bin/setenv.sh file as follows. We have reduce this values a little bit.

    JVM_MINIMUM_MEMORY="128m"
    JVM_MAXIMUM_MEMORY="512m" 

  • Before we run JIRA we need to create and configure a JIRA_HOME folder.

    mkdir -p ~/atlasian/jira

    Change atlassian-jira-5.2.10-standalone/atlassian-jira/WEB-INF/classes/jira-application.properties file as follows

    jira.home = /home/users/ubuntu/attlasian/jira

  •  Start the JIRA installation using

    ./start-jira.sh

  •  Enter http://your_elestic_ip_address:8080 into browser and enter values you have adjusted above.

     

    NewImage

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)