Monday, June 17, 2013

Selenium: Dealing with HTML loading modal panel

While playing back a test for a java rich faces application, the test was failing in the middle, debugging and playing back step by step, the test was passing with no issues. Looking more into the steps, there was a step that is causing ajax call, and after it there is a button click step, the one that was failing was the next one after the button click. When I checked the screen, there was a loading panel displayed during the ajax call, freezing all the screen, so I figured out that when this loading panel is displayed, selenium was able to find the button and click on it, but it is not actually clicked on the UI of the application, which cause that next step after to fail.

To resolve this, first I tried to look for something to make sure the button is clickable, I found something but for Java, and doesn’t exist for .NET

wait.until(elementToBeClickable(By.partialLinkText("SomeID")));

My test was on IE, and when I tried it with java, I had problems creating the selenium session with the selenium IE server.

Then I thought of something else, to identify any element change in the page that tells that the ajax call is done, then I can use this before the button click, to make sure it is clickable. I looked into the html page before, during and after the ajax call and compared. Before the call and when the loading panel was not visible, I found  hidden div with ID ajaxLoadingModalPanelContainer, it looked like below

<div id="ajaxLoadingModalPanelContainer" class="rich-modalpanel " style="position: absolute; z-index: 100; background-color: inherit; display: none;">

when the loading panel was visible, there was a div in the body like below (same as above, but the display style is gone)

<div id="ajaxLoadingModalPanelContainer" class="rich-modalpanel " style="position: absolute; z-index: 100; background-color: inherit;">

After the ajax call, the loading panel disappears and it changes back to have “display:none”

<div id="ajaxLoadingModalPanelContainer" class="rich-modalpanel " style="position: absolute; z-index: 100; background-color: inherit; display: none;">

I then created a function to wait for the ajaxLoadingModalPanelContainer div to be displayed, then to wait until it is hidden again like below

public void WaitForModalPanel()
{
string element_xpath = ".//*[@id='ajaxLoadingModalPanelContainer' and not(contains(@style,'display: none'))]";
WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 2, 0));
wait.Until(ExpectedConditions.ElementIsVisible(By.XPath(element_xpath)));
element_xpath = ".//*[@id='ajaxLoadingModalPanelContainer' and contains(@style,'DISPLAY: none')]";
wait.Until(ExpectedConditions.ElementExists(By.XPath(element_xpath)));
}


Calling the above function before the button click, the button click was also clicked on the UI and the test was passing successfully

Sunday, June 16, 2013

Selenium: unable to locate element using style attribute with internet explorer

While developing a selenium test and running it on IE,  I was trying to locate an element on the page with xpath, selenium couldn’t find the element, I was getting exception: “NoSuchElementException: Unable to find element with xpath == ……”

I thought at the beginning that there is something wrong with my xpath string, and I kept looking into this for a while. I have installed FirePath plugin for Firefox to verify my xpath, and my xpath was working find, xpath could locate element

Finally I spotted something on selenium documentation under section “IE and Style Attributes” that says that if you are trying to locate an element with the style attribute, it might not work in internet explorer as IE interpret the style parameters in upper case differently that other browsers, so locating with style and lowercase will success in Firefox, Chrome, etc… but will fail in IE

2013-06-16_11-23-10

looking back to my xpath, my element xpath was ".//*[@id='ajaxLoadingModalPanelContainer' and contains(@style,'display: none')]"

Changing it to ".//*[@id='ajaxLoadingModalPanelContainer' and contains(@style,DISPLAY: none')]" my test was able to find the element successfully

Wednesday, June 12, 2013

C#: Inserting duplicates into sorted List

I wanted to have a sorted list, with the ability to have items duplicate, built in sorted collections doesn’t allow duplicate values, so I used a List, and for effeciancy, I maintained the items sorted in it while insertion, instead of calling the sort method with each insertion
To insert in the list sorted, I used the binary search method, to find the first item less then or equal to the inserted item

Suppose we have a sorted list “list”, and we want to insert item i keeping it sorted


    List<int> list= new List<int>();

    int index = list.BinarySearch(i);
    if (index < 0)
       list.Insert(~index, i);
    else
       list.Insert(index, i);

Another way of having sorted list with duplicates is to use a normal sorted list and a custom comparer

    public class DuplicateKeyComparer<TKey>:IComparer<TKey> where TKey : IComparable
    {
        public int Compare(TKey x, TKey y)
        {
            int result = x.CompareTo(y);

            if (result == 0)
                return 1;   // Handle equality as being greater
            return result;
        }
    }



Only draw back of this method is that we can't find elements or remove, we can only iterate over them, as using the above comparer would always return 1 and won't match any elements.