The output html of testng’s reporter has the columns “Test method” and “Instance” that document each test run.

Test method” can be customized by defining public String getTestName() method in the class providing the test method.

Instance” can be customized by defining public String toString() method in the class providing the test method.

In this posting I document extending Selenium server with a custom javascript method, getAllRadios(), to return all radio button elements in a page. It’s based on the getAllButtons() that is stock in Selenium.

I will demonstrate two ways to add this custom method. The first strategy is to add the custom method to the native javascript files that ship with Selenium server. This is not the recommended way to extend Selenium but it is an almost guaranteed way to be sure the server picks up my new method and that frees me to focus on getting my client syntax right for calling the new method using the client’s doCommand() method.

Method 1 – selenium-browserbot.js + selenium-api.js

Unpack the server jar into a temporary directory to get access to the selenium-browserbot.js and selenium-api.js files.

[20:54 20090906 crashing@server /selenium-server-1.0.1/temp]
$ jar xf ../selenium-server.jar

The new custom method is added to core/scripts/selenium-browserbot.js. It is a slightly modified version of getAllButtons() which is defined in the same file.

BrowserBot.prototype.getAllRadios = function() {
var elements = this.getDocument().getElementsByTagName('input');
var result = [];
for (var i = 0; i < elements.length; i++) {
if (elements[i].type == 'radio') {
result.push(elements[i].id);
}
}
return result;
};

and then the new method is exposed to the Selenium API in core/scripts/selenium-api.js, again modeling after getAllButtons() in selenium-api.js.

Selenium.prototype.getAllRadios = function() {
return this.browserbot.getAllButtons();
};

Now rebundle the updated javascript into a new server jar, replacing the original.

[21:01 20090906 crashing@server /selenium-server-1.0.1/temp]
$ jar cmf META-INF/MANIFEST.MF ../selenium-server.jar .

Method 2 – user-extension.js

The better way to extend Selenium is to add methods to the user-extensions.js file. This avoids screwing around with the native server jar. I initiall had some trouble getting this working, hence the Method 1 approach, but after a bit of futzing I finally got this to work.

Selenium.prototype.getAllRadios = function() {
var elements = this.browserbot.getDocument().getElementsByTagName('input');
var result = [];
for (var i = 0; i < elements.length; i++) {
if (elements[i].type == 'radio') {
result.push(elements[i].id);
}
}
return result;
};

This is basically the same method used in selenium-browserbot.js. The important changed bits are (1) the method is attached to the Selenium object instead of the BrowserBot (Selenium.prototype rather than BrowserBot.prototype) and (2) calling getDocument() on the browserbot instance.

I start the Selenium server with the -userExtensions option pointing to the user-extensions.js file.

java -jar \
/selenium-server-1.0.1/selenium-server.jar \
-userExtensions /user-extensions.js

Client Coding

For either of the above methods of extending the Selenium server, I call this new method in my client code with the doCommand().

/** incomplete code **/

proc = new HttpCommandProcessor(seleniumServerHost,
seleniumServerPort, brower, seleniumServerStartUrl);
selenium = new DefaultSelenium(proc);

selenium.open(url);

// radio buttons returned as comma-delimited strings
String allRadios = proc.doCommand("getAllRadios", null);

// alternatively, get radio buttons as a String array
String[] radios = proc.getStringArray("getAllRadios", null);
for (String radio : radios) {
System.out.println(radio);
}

To call custom doCommand()’s, it’s necessary to instantiate with DefaultSelenium(proc) to inject the HttpCommandProcessor into the DefaultSelenium object.

Related:

Select the ids of radio buttons in a page using selenium
User-Extensions

Google has made its search input box bigger and its font size larger. Excuse me, they S-U-P-E-R-sized! it. It’s not a mistake, indeed Google actually seems proud of it.

Fortunately, Safari and Firefox empowers mere-mortal users to fix this eyesore with a custom stylesheet. Simply add the following to your userContent.css and restart the web browser. Additional general information on userContent.css, and all the spiffy things you can do with it, is available from the links below.


/* Google input text box */
.lst {
font-size:13px ! important;
}
/* Google search type-ahead drop down */
.gac_m td {
font-size:13px ! important;
line-height:120% ! important;
}
/* Google Search/I'm Feeling Lucky buttons */
.lsb {
font-size:11px ! important;
height:auto ! important;
}
/* Google Search/I'm Feeling Lucky buttons in type-ahead drop down*/
.gac_sb {
font-size:11px ! important;
height:auto ! important;
}

With the aforementioned CSS, the submit buttons will still appear in the type-ahead drop down menu. Add the following style to remove them all together.

/* Turn off Google Search/I’m Feeling Lucky buttons in type-ahead drop down*/
.gac_sb {
display:none;
}

Power to the people.

Related Sites

Customizing Mozilla
Better Ad Blocking for Firefox, Mozilla, Camino, and Safari
Google Chrome Issue 2393: Support user stylesheet

This how I took an existing directory of files on my desktop and put it into a new git repository on a remote server. I found a number of how-tos online but none worked for me – certainly this was because I’m such a newbie with git that I wasn’t sufficiently understanding what I was being told to do. The following works for me; clearly this isn’t the only way or the best way to accomplish the task. This is mostly a note to self.

Create an empty directory on the remote server to hold the repository

[11:44 20090902 crashing@server ~]
$ mkdir -p /var/local/git/repos/CrashTesting

Intialize the empty repository

[11:44 20090902 crashing@server /var/local/git/repos/CrashTesting]
$ git --bare init
Initialized empty Git repository in /var/local/git/repos/CrashTesting/

Now I have the necessary repository components.

[11:44 20090902 crashing@server /var/local/git/repos/CrashTesting]
$ ls
branches config description HEAD hooks info objects refs

On my desktop, in the existing directory of files, init the directory

[11:30 20090902 crashing@desktop ~/Desktop/testws]
$ git init
Initialized empty Git repository in /Users/crashing/Desktop/testws/.git/

This created a .git directory with git control files.

Next, I tell my local desktop repository about the remote repo. The remote repo is given the short name origin.

[11:46 20090902 crashing@desktop ~/Desktop/testws]
$ git remote add origin ssh://server.crashingdaily.com/var/local/git/repos/CrashTesting

Then, I place my local files under version control.

[11:42 20090902 crashing@desktop ~/Desktop/testws]
$ git add .

Now I can commit the local files to the local repository.

[11:45 20090902 crashing@desktop ~/Desktop/testws]
$ git commit -a -m 'initialize repo'
[master (root-commit) 7871087] initialize repo
23 files changed, 500 insertions(+), 0 deletions(-)
create mode 100755 build.properties
create mode 100755 build.xml

Finally, push the master branch to the remote repository named origin.

[11:46 20090902 crashing@desktop ~/Desktop/testws]
$ git push origin master
Counting objects: 44, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (31/31), done.
Writing objects: 100% (44/44), 1.65 MiB, done.
Total 44 (delta 1), reused 0 (delta 0)
To ssh://server.crashingdaily.com/var/local/git/repos/CrashTesting
* [new branch] master -> master

I spent the evening compiling mysql 5.1.37 on Fedora 8. I had no trouble compiling on RHEL4 but on Fedora 8 I ran configure

CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors \
-fno-exceptions -fno-rtti" ./configure \
--enable-assembler \
--with-mysqld-ldflags="-all-static" \
--with-client-ldflags="-all-static"

followed by make and was getting compile errors

/bin/sh ../libtool --preserve-dup-deps --tag=CXX --mode=link gcc -O3 -felide-constructors -fno-exceptions -fno-rtti -fno-implicit-templates -fno-exceptions -fno-rtti -rdynamic -o mysql mysql.o readline.o sql_string.o completion_hash.o ../cmd-line-utils/libedit/libedit.a -lncursesw -all-static -lpthread ../libmysql/libmysqlclient.la -lcrypt -lnsl -lm -lz
libtool: link: gcc -O3 -felide-constructors -fno-exceptions -fno-rtti -fno-implicit-templates -fno-exceptions -fno-rtti -rdynamic -o mysql mysql.o readline.o sql_string.o completion_hash.o -static ../cmd-line-utils/libedit/libedit.a -lncursesw -lpthread ../libmysql/.libs/libmysqlclient.a -lcrypt -lnsl -lm -lz
/usr/bin/ld: cannot find -lncursesw
collect2: ld returned 1 exit status
make[1]: *** [mysql] Error 1
make[1]: Leaving directory `/home/crashingdaily/mysql-5.1.37/client'
make: *** [all] Error 2

This was resolved by installing the static ncurses libs via the ncurses-static package.

$ sudo yum install ncurses-static

That then left me with the compile failure (showing only part of the error)

../cmd-line-utils/libedit/libedit.a(term.o): In function `term_echotc':
term.c:(.text+0×1557): undefined reference to `tputs'
term.c:(.text+0×1580): undefined reference to `tgetstr'
term.c:(.text+0×1676): undefined reference to `tgoto'
term.c:(.text+0×169a): undefined reference to `tputs'
term.c:(.text+0×1761): undefined reference to `tgoto'
term.c:(.text+0×1781): undefined reference to `tputs'

This was resolved by adding -ltinfo to the client ldflags in the configure options

CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors \
-fno-exceptions -fno-rtti" ./configure \
--enable-assembler \
--with-mysqld-ldflags="-all-static" \
--with-client-ldflags="-all-static -ltinfo"

Now make completed successfully. Lovely.

Today I installed NCBI BLAST on Windows XP SP2 but was unable to run the executables – I was confronted with “the system cannot execute the specified program”.

The fix was to install Microsoft Visual C++ 2005 SP1 Redistributable Package

I recently re-discovered autossh. I’ve been using it to persist mounted sshfs volumes but am only just now realizing it’s the scratch for some of my other itches.

With it I can

autossh -M50000 -t -D1080 -Nf crashingdaily.com

to keep a seemingly persistent SOCKS proxy running.

Or

autossh -M50000 -t crashingdaily.com 'screen -aAdR autossh'

to maintain an interactive session.

The value that I missed earlier is that the connections are maintained (re-established, actually) even if I change networks – which my laptop and I often do.

Jon’s View has a nice posting on using autossh for SOCKS proxying.

And Dread Pirate PJ has a good instruction for combining autossh and screen for persistent interactive sessions.

autossh is available for OS X via Darwin Ports and Fink and for Linux as source code or as binary packages from repositories for most modern Linux distributions.

Hot on the heels of yesterday’s posting about my brief experience with YSlow in a Selenium framework, comes the release of Cesium 0.1, a tool specifically designed for automating YSlow runs.

I don’t care enough about YSlow tests to setup and maintain another test harness just for that purpose, so I don’t think I’ll be trying it myself. For others who get in to this sort of thing, here’s something to get in to.

Adam Goucher has a clever idea to automate YSlow reporting to a Show Slow database with Selenium.

Well, I tried this with my Selenium RC setup, testing one page. In my setup, two beacons are sent by YSlow to the Show Slow database but the urls recorded,

http://localhost:3000/selenium-server/core/Blank.html?start=true
and
chrome://src/content/RemoteRunner.html?sessionId=2d7695881a3881f940ada5bc889a6dee&multiWindow=true&baseUrl=http%3A%2F%2Fintegrate.crashingdaily.com&debugMode=false&driverUrl=http://localhost:3000/selenium-server/driver/

are not the ones for the page under test. Neither report generated from selenium matches the report I get from the standalone browser so it’s not just a matter of the url being misreported to Show Slow.

disappointing.

The at command can be used in CGI scripts to remotely trigger non-recurring jobs on a web server. This is especially useful for long running jobs that clients don’t need to wait on and jobs that need to persist across web daemon restarts.

My initial simple attempts to schedule a job with at in a CGI script executed by an Apache webserver were met with the failure response “This account is currently not available“. That message being the output of /sbin/nologin which is the shell value set for the apache user in /etc/password.

The fix is to set the SHELL environment variable to a proper shell when executing at. Here’s a simple, proof-of-concept CGI script.

#!/usr/bin/perl
use CGI;
my $cgi = new CGI;
print $cgi->header;

system(‘echo “/usr/bin/env > /tmp/apacheenv” | SHELL=/bin/bash at now’);

Calling the CGI script triggers the at scheduling. In this case, the execution of /usr/bin/env is immediate and successful.

$ cat /tmp/apacheenv
SERVER_SIGNATURE=
SHELL=/bin/bash
HTTP_USER_AGENT=Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_7; en-us) AppleWebKit/528.18.1 (KHTML, like Gecko) Version/4.0 Safari/528.17
SERVER_PORT=80

Related:

at man page

Categories

 

November 2009
M T W T F S S
« Sep    
 1
2345678
9101112131415
16171819202122
23242526272829
30  

Latest del.icio.us