Selenium::Remote::Driver - mouse_move_to_location

I’ve been trying to figure out how to use move the mouse in Selenium Webdriver. I’m using perl, so I’m using the Perl bindings obviously - Selenium::Remote::Driver has a function called mouse_move_to_location, and the documentation for that is the same as what is provided officially by the Selenium project, and both weren’t very forthcoming with why I couldn’t get it to work.

I’ve been banging my head against the wall for this one and eventually just gave up, but the whole time the answer was staring me in the face. The syntax for the arguments to this function in the documentation is different from any of the others - it accepts a hash, like {element => $element}, not just a WebElement or a Sizzle locator or anything like that. Sheesh. I feel pretty dumb about that, but at least it’s solved now :)

Selenium WebDriver, Perl, and Saucelabs.

Last year, Selenium introduced WebDriver, an automated browser program that runs the browser in the same way that a user would.  Saucelabs offers a way to test multiple browsers on multiple operating systems in parallel, completely automated, by running the Selenium software and selling time on their servers. Perl is fun. Saucelabs doesn’t have documentation for connecting to their OnDemand service using WebDriver and Perl, so I’d like to explain how to do that. 

Using Gordon Child’s Selenium::Remote::Driver, it’s pretty straightforward to use Perl to run tests on Saucelabs using WebDriver. Get Selenium::Remote::Driver if you don’t have it (sudo CPAN install Selenium::Remote::Driver). 

#! /usr/bin/perl
use strict;
use warnings;
use Selenium::Remote::Driver;

my $desc = "perl webdriver bindings and selenium!";

my $login = "loginName";
my $apiKey = "myApiKey";
my $host = "$login:$apiKey\@ondemand.saucelabs.com";

my $driver = new Selenium::Remote::Driver(
'remote_server_addr' => $host,
'port' => "80",
'browser_name' => "firefox",
'version' => "7",
'platform' => "WINDOWS",
'extra_capabilities' => {'name' => $desc},
); $driver->get('http://www.google.com'); print $driver->get_title(); $driver->quit();

Plugin your login name and api key and that should get you up and running. The script opens FF7 on Windows 2003, gets google.com and outputs “Google” as the title of the webpage. 

For anyone using the Selenium RC WWW::Selenium bindings, things are a bit different in Selenium::Remote::Driver - namely, many of the events (clicking, getting information) are done as methods to a new Selenium::Remote::WebElement object, not the selenium driver object. It was a bit of a pain to migrate over, but I think it’s a lot cleaner now. So far, everything I did with WWW::Selenium I’ve been able to duplicate with Selenium::Remote::Driver, and in most cases it’s much simpler and more elegant :)

Using Perl’s CPAN Library Without Root

At my work I ssh into a linux box somewhere in the cloud. Since I’m not Ops, I don’t have root access on the box, but I am consistently running into situations where I need to install modules from CPAN on to the box. Without sudo, I was having a lot of trouble writing code with new functionality and not being able to utilize the CPAN library.

But, luckily, stackoverflow came to my rescue. Or, in particular, Chas Owens did, with the following simple three lines:

wget -O- http://cpanmin.us | perl - -l ~/perl5 App::cpanminus local::lib
eval `perl -I ~/perl5/lib/perl5 -Mlocal::lib`
echo
'eval `perl -I ~/perl5/lib/perl5 -Mlocal::lib`' >> ~/.profile

So, the first line runs a script to install App::cpanminus and local::lib. cpanm is CPAN without all the customization options, so you can just cpanm Module::Name and not worry about a thing. local::lib lets you install to non-root directories. The second line uses local::lib to tell perl where to look for the new modules, and the third line exports it to ones .bash_profile so it’s used each time we log in.

Finally, since the scripts I’m writing actually get run as root, 

use lib("~/perl5/lib/perl5");

I just have to insert that line into my script to tell perl where to look. 

tl;dr - I <3 CPAN & stackoverflow.

OS X Lion doesn’t always play nicely with CPAN :(

So, I am trying to set up the Net::IMAP::Simple::SSL perl module installed on my Macbook running OS X Lion 10.7. BUT ALAS apparently Apple uses a stupid deprecated version of gcc in the bloated 4.5gb Xcode, leading my sudo cpan install Net::IMAP::Simple::SSL command to fail during the installation of the EV module.

The exact error code was

t/11_signal.t …… 1/24 Argument “EV::RUN_ONCE” isn’t numeric in subroutine entry at t/11_signal.t line 48.

So, intrepid explorer that I am, I threw that into Google in hopes of stumbling on to someone else’s solution. Lucky for me, the first result was a mailing list post about my exact problem, and the first response to that post contained a link to a submitted bug at LLVM.org where the final comment contained a tiny patch to one the EV.xs file in the EV module.

I downloaded the tarball of the EV module from CPAN and did the usual:

tar -xvzf EV-4.03
cd EV-4.03
perl Makefile.PL
// says some stuff
make
// says some other stuff
make test
// says some more stuff, then breaks

As expected it was throwing the same error from before. According to the bugfix from the LLVM.org, I needed to change one and a half lines of code in EV.xs so I opened it up in Emacs and M-g g’d to line 426 on a whim. (Probably more reliable would’ve been C-s newCONSTSUB). Around there, I added in the lines

const void* civ_start = const_iv;
for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ— > civ_start; )

which replaced the old for loop above the newCONSTSUB thing. So, problems solved, thanks to the Google, no thanks to the stupid Apple Xcode gcc. Grrr…

Page 1 of 1