When selenium webdriver js / protractor won’t click the div that you want it to click

Somebody. Please! Sit down and dedicate as much of your life as you can to improving the documentation for protractor (and while you’re at it you can do selenium webdriver js as well).

In the test that I want to write I have a div, and when I click it a menu (another div that was previously hidden from view) is displayed, at which point I move the mouse to an option in the menu and I click said option.

Typical everyday usage, right? Should be relatively easy to achieve with protractor/WebDriver, right?
Wrong, because it isn’t relatively easy to achieve. It is, in fact, life threateningly difficult to achieve this with protractor/WebDriver.

Here is the (hideous, and clearly not optimal) way in which I’ve managed to get this done.

        it('should show a user config window if user name is pressed in the menu', function() {
            var menuButton = element(by.css("fooBar-menu-bar div.options"));

            var userWindow;

            browser.driver.wait(function(){
                return menuButton.click().then(function(){
                    return browser.waitForAngular().then(function(){
                        return browser.wait(function(){
                            return element(by.id("MenuOptionsContainer")).isPresent().then(function(flag){
                                if (flag === true){
                                    var item = element(by.id("MenuOptionUser"));
                                    browser.actions().mouseMove(item).perform();
                                    item.click();
                                    return browser.wait(function() {
                                        return browser.isElementPresent(by.tagName("fooBar-window")).then(function(flag){
                                            if(flag === true){
                                                userWindow = element(by.tagName("fooBar-window"));
                                                expect(userWindow.isPresent()).toBe(true);
                                                return flag;
                                            } else {
                                                return false;
                                            }
                                        });
                                    });
                                }
                                else{
                                    return false;
                                }
                            });
                        });
                    });
                });
            });
        });

If you’ve read this far then you’re probably trying to get this to work, too. Or, even better you may have found a way to make it work that is far less awful than the above.
Either way I hope you’ll leave a comment.

Advertisements

Linux (Bash) – Copying very big things from one server to another across a flaky connection

Sometimes a tester needs to go to great lengths to reproduce a failure or compare behaviour … or just to have the slightest chance of understanding what the hell is going on .
Earlier today I had to copy a very big file (that contained the only known data set capable of reproducing the failure I’m investigating) from one server to another. I work behind a proxy server, and there’s also a second, independent proxy server and a firewall inbetween the two servers in question – as a result my initial attempts with SCP and RSYNC all ended in failure (due to connections being lost/sessions being dropped mid-transfer).

This is the command that got the job done:

nohup scp originalFile.zip user@host:path/destinationFile.zip &

More on the use of nohup and &:
http://www.cyberciti.biz/tips/nohup-execute-commands-after-you-exit-from-a-shell-prompt.html

Python 2.6 – Subclassing unittest.TestCase

“I need to write a lot of system and component integration tests. Many of them will involve hitting the database, getting a result set and transforming it into XML/JSON/something else. I´ll need to create some flat files which contain expected results for these kind of tests. It would help me immensly if I had some utility classes to help me out with the reading/parsing/transforming of said utility functions.”
The above is what I should have thought to myself a few weeks back. Naturally, I didn’t. So I began creating test cases with their own utility functions included. Shortly afterwards this way of doing things revealed itself to be silly, and bad. So I went through several rounds of refactoring, and ended up with some utility classes.
Now I want to subclass unittest.TestCase and include all my utility classes in every test case I write.

First attempt:

Code example will go here if I’m ever able to locate it (I started this post a year ago, got distracted and then forgot about it. The code examples I had prepared at the time are now long gone…)

Resulting error:

method __init__ takes 2 parameters only 1 provided

eh? …
Cue head scratching session.
Followed by a bit of googling. Didn’t quite find what I was looking for, though.
http://www.velocityreviews.com/forums/t737111-subclassing-unittest-testcase.html
http://stackoverflow.com/questions/8964461/subclassing-python-unittest-testcase-calling-the-same-main

http://stackoverflow.com/questions/1323455/python-unit-test-with-base-and-sub-class

This last solution seemed great on paper, but multiple inheritance and calling functions in (one of) the super class(es) proved to be bafflingly complicated. I’m using jython/python 2.6, apparently multiple inheritance has been revamped in python 3.0 (but I’m stuck with 2.6 so I’ll never know).

Cue second head scratching session.

I decide to enlist the help of the resident genius on the project and he came up with the following snippet (took him a fair few tries though, which is why I’ve deemed it worthy of being posted here):

from my.testUtilities import DBMock
from my.testUtilities import JSONHelper
import unittest

class MyTest(unittest.TestCase):
    def __init__(self, methodName='runTest'):
        unittest.TestCase.__init__(self, methodName)
        self.DBMock = DBMOCK
        self.JSONHELPER = JSONHELPER

Job done.

Selenium Web Driver Firefox KeyError: self.session_id = response[‘sessionId’]

Had a nice little head-to-head with this issue yesterday.

As with all things Selenium Web Driver: there are many suggested solutions on the pages of the many forums and wikis that discuss the project and it’s hard to determine which, if any, are suitable for the problem at hand.

This solved it for me: 
http://stackoverflow.com/a/17545189/375996

 

When ChromeDriver doesn’t start up on non-english installation of windows xp

What an awful little error message this is:

WebDriverException: 
Message: u'unknown error: chrome failed to start\n  
(Driver info: chromedriver=2.0,platform=Windows NT 5.1 SP3 x86)'

I’ve spent more time than I’d like to admit to trying to figure out the “why” of this message.
This didn’t help much:
https://code.google.com/p/chromedriver/wiki/TroubleshootingAndSupport

Also, there’s a lot of useful info about making sure Selenium can locate ChromeDriver.exe.  All very good, but not what I was looking for.

This sent me in the right direction, but it’s section on overriding the binary_location shows outdated example code (or, at the very least it didn’t work for me in SWD v2.33)
https://code.google.com/p/selenium/wiki/ChromeDriver#Overriding_the_Chrome_binary_location

 The root cause

My installation of windows XP uses Spanish as it’s default language (I’m currently working in Barcelona).

The default install location for google chrome on Windows XP English is:

C:\Documents and Settings\<USERNAME>\Local Settings\
Application Data\Google\Chrome\Application\chrome.exe

on a Spanish installation this translates to:

C:\Documents and Settings\<USERNAME>\Configuración local\
Datos de programa\Google\Chrome\Application

ChromeDriver looks for Chrome in the default location and if it doesn’t find it, it returns the (wonderfully descriptive) error message quoted at the beginning of the post.

The ‘fix’

The following code allows me to launch ChromeDriver successfully (using the python bindings):

import unittest
from selenium import webdriver

class Test_Login(unittest.TestCase):
    def setUp(self):
        chromeOptions = webdriver.ChromeOptions()
        chromeOptions.binary_location = "C:\\Documents and Setting\\myusername\\Configuración local\\Datos de programa\\Google\\Chrome\\Application\\chrome.exe"

        self.driver = webdriver.Chrome(chrome_options=chromeOptions)

So, now that the (bloody) tools are correctly configured I can actually start writing the tests. Hooray!

‘continue’ versus ‘else if’

When looping over an array and taking different actions based on the the contents of each array entry the traditional approach is to use an ‘if’ with an ‘else if’. I think that, in these circumstances, code becomes more readable if we use an ‘if’ with a ‘continue’.

Let’s take a list of things (we’ll do this in javascript)

var fooBar = ["foo","bar"];

and loop over it using ‘continue’

for (var x=0; x&lt;=fooBar.length;x++){
    if (fooBar[x] === "foo"){
        console.log("we have foo");
        continue;
    }
if (fooBar[x] === "bar"){
    console.log("we have bar");
    }
}

and then lets loop over it again, this time using ‘else if’

for (var x=0; x&lt;=fooBar.length;x++){
    if (fooBar[x] === "foo"){
        console.log("we have foo");
    }
    else if (fooBar[x] === "bar"){
        console.log("we have bar");
    }
}

I like the ‘continue’ snippet. It’s just that little bit easier for me to read. That little bit more explicit. The paths through the code are clearer to the naked eye.

js.perf suggests that using “continue” instead of “else if” within a “for” loop introduces a minimal, barely noticeable performance dip:
http://jsperf.com/continue-vs-else/2

I’m a ‘continue’ man from now on.