Monday, September 24, 2012

Extend Selenium::Remote::Driver to support applicationName capability

Why would you need applicationName support incorporated into your automated testing framework? Well if for no other reason of having more granularity when defining the environment in which your automated web application tests will execute in. It is my opinion that we have to be in full control (to the largest extent possible) of the test environment. And this type of control begins when we are defining the environment.

The module that we will be making changes to is Driver.pm (available from CPAN). It is an implementation of the driver that Selenium provides (in Perl) to the Selenium stand alone server (which is required to use the Perl language bindings to Selenium).

NOTE: I recommend the use your Perl package manager to download and install Selenium::Remote::Driver plus its dependencies and familiarizing yourself with it before going through the below changes.

So how do you add this support to the already great Perl language bindings to the Selenium driver? Below is how I did it:

Changes to Driver.pm to support applicationName capability:

1. Add application_name property to the new method (see code below)
2. Add applicationName (see code below) to new_session %args hash

Basically in order to support applicationName property you need to update the new and new_session methods respectively as outlined below: (note code is a fragment used for reference). The code below is found around line 173 of the Driver.pm module; the newly inserted line is number 12, depicted by >>>> <<<< in both.
1:  sub new {  
2:    my ( $class, %args ) = @_;  
3:    my $ress = new Selenium::Remote::Commands;  
4:    
5:    # Set the defaults if user doesn't send any  
6:    my $self = {  
7:      remote_server_addr => delete $args{remote_server_addr} || 'localhost',  
8:      browser_name    => delete $args{browser_name}    || 'firefox',  
9:      platform      => delete $args{platform}      || 'ANY',  
10:      port        => delete $args{port}        || '4444',  
11:      version      => delete $args{version}      || '',  
12:   >>>>> application_name  => delete $args{application_name}  || undef, <<<<<<  
13:      session_id     => undef,  
14:      remote_conn    => undef,  
15:      commands      => $ress,  
16:      auto_close     => 1, # by default we will close remote session on DESTROY  
17:      pid        => $$,  
18:    };  

1:  sub new_session {  
2:    my ($self, $extra_capabilities) = @_;  
3:    $extra_capabilities ||= {};  
4:    my $args = {  
5:      'desiredCapabilities' => {  
6:        'browserName'    => $self->{browser_name},  
7:        'platform'     => $self->{platform},  
8:        'javascriptEnabled' => $self->{javascript},  
9:        'version'      => $self->{version},  
10:        'acceptSslCerts'  => $self->{accept_ssl_certs},  
11:        'proxy'       => $self->{proxy},  
12:    >>>>>> 'applicationName'  => $self->{application_name},  <<<<<<  
13:        %$extra_capabilities,  
14:      },  
15:    };  
After the above modifications you can, in your test scripts, add the applicationName property to your desired capabilities hash. Below is an example:
1:    my %desired_capabilities = ( remote_server_addr => $grid_server,  
2:                   browser_name => $browser,  
3:                   platform => $os_platform,  
4:                   port => $port,  
5:                   application_name => $app_name,  
6:                   proxy => {  
7:                     proxyType => 'system'  
8:                   });  
9:    
10:    my $driver = Selenium::Remote::Driver->new(%desired_capabilities);  
Benefits of running with the above:
You can now define specifically which Browser, OS, Platform to run your test against. For example lets say you want to run a test against Firefox on Windows 7 x64; with the current implementation there is no way to force the grid to select a speficic platform.

With this change you can define an environment (application) when the node is being registered with the hub:
 java -jar selenium-server-standalone-2.25.0.jar -role node -hub http://localhost:4445/wd/hub -browser browserName=firefox,maxInstances=3,platform=VISTA,applicationName=WIN7x64FFX -port 5556  

The above command registers a node with the Firefox application running on the node using the specified applicationName=WIN7x64FFX. When test scripts request this specific environment (via the applicationName property) they will be sent to this node for test execution.

If you do not feel like doing all this yourself then feel free to download the file Driver.pm from my fork on github of the Selenium Perl bindings by clicking the following link: https://github.com/freddyvega/Selenium-Remote-Driver/blob/support-application-name-capability/lib/Selenium/Remote/Driver.pm

3 comments:

  1. Hey, nice site you have here! Keep up the excellent work!


    Creative web systems is a Miami

    ReplyDelete
  2. is it possible to add useragent also this way?

    ReplyDelete
  3. This has already been done. Checkout the project on GitHub for info here:
    https://github.com/detro/ghostdriver/issues/134

    ReplyDelete

Creative Commons License
VGP-Miami Web and Mobile Automation Blog by Alfred Vega is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.