Perl Webdriver tutorials with Selenium::Remote::Driver
I've been mulling over doing a series of tutorials for using Perl and Webdriver together along with Selenium::Remote::Driver. So, I'm making this the index page of the tutorials!
Starting up: using webdrivers directly, [using the selenium-standalone-server.jar]
wait_until to handle your asynchronicity
[Finding elements without croaking]
Using Browsermob Proxy: test analytics, status codes, etc!
Drag and drop, ported over as pioneered by Dave Haeffner
Using custom Firefox profiles
Instructing the standalone server to use PhantomJS
Sometimes I write about changes in the new versions of the package:
v0.22 changes
[v0.25 changes]
There are also a number of articles about using Appium, which aims to be as no-surprises as can be when extending S:R:D.
Setting up Appium with the Perl bindings
Using Appium with a new Ionic app
Explicit step-by-step for installing Appium on Yosemite
Feel free to request articles or pitch ideas/articles if you want something not covered here!
We're gearing up for the release of v0.22 of Selenium-Remote-Driver, a set of Perl bindings for the Webdriver project. My primary motivation to get a new release out is to tweak some of the classes to be more easily extended, so that the perl bindings for Appium can be written more cleanly. But, there's also some cleanup for deprecated functions and a few bugfixes included, along with plans for another release in the near future.
Before we get in to the changes, here's a heads up about the new mailing list for the perl bindings: https://groups.google.com/forum/#!forum/selenium-remote-driver :D
A new subroutine get_user_agent will be making it into the API for Driver.pm as a convenience method to, well, get the user agent!
The main changes for Appium were allowing for more dependency injection of classes like ::RemoteConnection and ::ErrorHandler. This lets us tweak things in the Appium module to address discrepancies between Appium and Webdriver. This is also the case for the FINDERS constant defined in the ::Driver class - previously, the constant was privately scoped to Driver.pm, preventing modification from Appium.pm. But Appium has a different list of acceptable finders. So, ea68e0 makes it so the Appium class can declare its own FINDERS constant via the use constant pragma.
Thanks to a few updates to Dist::Zilla::Plugin::TravisYML, our Travis tests are passing again on the master branch instead of just on cpan - there used to be test failures just getting Dist::Zilla to install, even though our own tests were passing. The most recent version of ::TravisYML fixed those issues!
peroumal1 caught a couple deprecated functions that will now be throwing warnings - get_speed, and set_speed are already no-ops and now will be warning appropriately. The same goes for the drag subroutine in ::WebElement, which no longer seems to be in the (not actually official) JSONWireProtocol.
A few bugfixes made it in, including more helpful error messaging when failing to initiate a session on Saucelabs, or when chromedriver is incorrectly configured. There was also a casting issue reported that I still can't reproduce for setting window size where the JSON conversion was using strings instead of integers ("1280" x "1024" vs 1280 x 1024). I still can't reproduce the issue, but I can't imagine the fix to cast the variables into integers causing any other problems, so I'll probably include it anyway.
On the horizon, we've got a rewrite of our recording/mocking functionality on the way, courtesy of peroumal1. Looking over the code in their mock-driver-experiment branch, things seem to be shaping up quite nicely. This is a welcome change because we've been dealing with a complicated process and an explicit dependency on LWP::Protocol::PSGI v0.04 to generate our recordings, effectively preventing anyone else from contributing recordings.
Speaking of release versions, this is the numbering scheme I'm trying to use. The impression I've gotten is that CPAN version numbering is a bit of a grab bag, so perhaps explanation is in order.
A point increase for deliberate releases with new/important functionality - ie, 0.21 to 0.22.
A minor version increase for bugfixes - 0.21 to 0.2101 to 0.2102, etc.
Dev releases to prepare for the next point release go out on the 0.XX50 namespace and increment - so, 0.2150, 0.2151, etc.
Playing with the new Perl bindings for the BrowserMob Proxy
Browsermob Proxy is an open source project that Patrick Lightbody split off from the main Selenium project. It works really well in tandem with Selenium Webdriver, but it was missing Perl bindings. BMP exposes a RESTish interface for interacting with the proxies, so I've strung together a Perl module to take care of it: Browsermob::Proxy. Amongst other things, you can use BMP to throttle net traffic during tests, analyze request/response pairs for things like Omniture and Google Analytics, and even alter the requests on the fly with custom headers. Here's a short run down and some basic get-started scripts for using it!
The bindings are up on CPAN with pretty limited functionality at the moment - definitely not the full BMP API. It can create proxies and HARs, and spit out the HARs back out when requested, but it doesn't do much else besides that as of v0.04. To get up and running with BMP, you'll need to download the binary from the BMP website and then execute the appropriate file in its bin/ folder to start the BMP server.
Here's an example of using Browsermob::Proxy with Selenium::Remote::Driver to capture all of the network traffic during a single request to google:
#! /usr/bin/perl use strict; use warnings; use DDP; use Browsermob::Proxy; use Selenium::Remote::Driver; my $proxy = Browsermob::Proxy->new( server_port => 8080, ); my $driver = Selenium::Remote::Driver->new( browser_name => 'chrome', proxy => $proxy->selenium_proxy ); $driver->get('https://www.google.com'); p $proxy->har;
This is assuming your BMP server is already downloaded and currently running on port 8080. But, that's all we need to create a new proxy for the Chrome browser that Selenium::Remote::Driver is about to make. The $proxy comes with a convenience method selenium_proxy() that returns the appropriate desired capabilities to configure the proxy for use with Chrome. (If you want to use a proxy with Firefox, you'll need to use a custom Firefox profile.)
Once we've instantiated our driver, having told it to use the proxy, all that's left is to create some traffic and spit out the HAR.
If you want to try out the module without having to install Selenium::Remote::Driver, you can just curl some traffic across the proxy:
#! /usr/bin/perl use strict; use warnings; use DDP; use Browsermob::Proxy; my $proxy = Browsermob::Proxy->new( server_port => 8080, ); $proxy->new_har; my $generate_traffic = 'curl -x http://127.0.0.1:' . $proxy->port . ' http://www.google.com > /dev/null 2>&1'; `$generate_traffic`; p $proxy->har;
This creates a proxy in exactly the same fashion and then uses curl to generate the traffic.