Skip to content

WAAT Ruby JsSniffer

anandbagmar edited this page Nov 5, 2012 · 2 revisions

Approach

This is a generic approach to Web Analytics Test Automation. Regardless of the end-product doing Web Analytics reporting and analysis (example: Omniture, Google Analytics, etc.), you can use this approach to test, in an automated way, if correct name/value properties are being reported by the product / system under test.

This approach works with:

  • any web analytic tool,
  • any test automation framework,
  • a pure-https or http environment,
  • all browsers.

In addition, this approach does NOT need any 3rd party library setup.

To use this plugin, you will need to write a small javascript and execute it in the browser to retrieve the http / https request to the web analytic tool in question. You can either figure out this javascript yourself, or work with your development team to figure out what javascript they need to invoke in the browser to get the URL of interest that is sent as a pure https request over the wire. WAAT then takes this request, and does the tag matching for you.

NOTE: This generation of the JS script is a one-time effort - unless the way the tags are reported changes in the product. Then the test framework can work in a seamless fashion as before to test this is working consistently in an automated fashion.

Refer to the below steps for details around the same.

Define Test data

Provide the test data to be validated for each action in an xml file. See the Sample TestData XML file for reference. This is same as before

Install WAAT-Ruby

WAAT-Ruby gem is available from www.rubygems.org. Add the following line in your Gemfile:

source "http://rubygems.org"
gem 'WAAT', '>= 1.5.0'

Use WAAT-Ruby in your framework

Install the latest version of WAAT from WAAT-Ruby pkg directory.

In your Test project's env.rb, or some such file, add this line:

require 'WAAT'

Test Changes

You can enable / disable WAAT in each test, or better way is to create custom hooks for this purpose.

The below example demonstrates the use of WAAT via custom hooks in a Cucumber-based Test Automation Framework.

Custom hook (using Cucumber project's example)

In your Test framework, create a file /features/support/hook.rb Add the following code in that file:

Before ('@waat') do
  puts "waat before hook"
  initialize_waat(:waat_plugin => "js_sniffer")
 end

After ('@waat') do
  # Nothing required in After hook
end

Feature file changes

In your feature file, for tests that should also be doing Web Analytics testing, add a @waat annotation to them as shown below.

@waat
Scenario: Content is seen on home page - success test
  Given WAAT success test

Validating Web Analytics tags

For each location (you need to test) where test-actions trigger Web Analytics requests, do the following:

test_data_file_name = File.join(File.dirname(__FILE__), "..", "..", "sampleData", "TestData.    
action_name = "WAAT_Success_Test"
JS_FOR_MY_SITE = "window.WAAT_URL=\"\";window.WebTrends.prototype.dcsTag=function(){if(document.cookie.indexOf(\"WTLOPTOUT=\")!=-1){return}var WT=this.WT;var DCS=this.DCS;var DCSext=this.DCSext;var i18n=this.i18n;var P=\"http\"+(window.location.protocol.indexOf('https:')==0?'s':'')+\"://\"+this.domain+(this.dcsid==\"\"?'':'/'+this.dcsid)+\"/dcs.gif?\";if(i18n){WT.dep=\"\"}for(var N in DCS){if(DCS[N]&&(typeof DCS[N]!=\"function\")){P+=this.dcsA(N,DCS[N])}}for(N in WT){if(WT[N]&&(typeof WT[N]!=\"function\")){P+=this.dcsA(\"WT.\"+N,WT[N])}}for(N in DCSext){if(DCSext[N]&&(typeof DCSext[N]!=\"function\")){if(i18n){WT.dep=(WT.dep.length==0)?N:(WT.dep+\";\"+N)}P+=this.dcsA(N,DCSext[N])}}if(i18n&&(WT.dep.length>0)){P+=this.dcsA(\"WT.dep\",WT.dep)}if(P.length>2048&&navigator.userAgent.indexOf('MSIE')>=0){P=P.substring(0,2040)+\"&WT.tu=1\"}this.dcsCreateImage(P);window.WAAT_URL=P;this.WT.ad=\"\"};_tag.dcsCustom=function(){}; _tag.DCS.dcscfg=\"1\"; _tag.dcsCollect();return window.WAAT_URL"

#  Unless specified in hook.rb:
#  initialize_waat(:waat_plugin => "js_sniffer")

# Some test action triggering a Web Analytic request
# Example:

url = "http://essenceoftesting.blogspot.com"
@driver = Selenium::WebDriver.for :firefox
@driver.get url

extracted_url = @driver.execute_script(JS_FOR_MY_SITE);

# Verify Web Analytics Data sent to the Web Analytic tool
params = [:test_data_file_name=> test_data_file_name, 
          :action_name => action_name, 
          :url_patterns => extracted_url]
result = verify_web_analytics_data(params)

# Sample validations
assert (result.status=="FAIL"), "Incorrect Verification Status. Expected: 'FAIL', Actual: #{result.status}"
assert (result.list_of_errors.size==14), "Incorrect number of errors. Expected: '14', Actual: #{result.list_of_errors.size}"
result.list_of_errors.each do |err|
  puts "->\t#{err}"
end

Opportunities for optimization

  • Since the javascript (JS_FOR_MY_SITE) is going to be the same for all tests for a particular site / product, it will be better to move its definition to a common place instead of defining it in each and every test.
  • If all test data is specified in the same XML file, then the input_data_file_name can also be specified once in some common place instead of defining it in each and every test.