_ruby
Example
First, we'll need to download a copy of Selenium Server and launch it.
java -jar selenium-server-4.8.2.jar standalone
Next, we'll want to create a mechanism to access the Selenium Server logs through the WebDriver Wire Protocol via an HTTP library -- filtering out the logs we don't want and return the most recent one.
# filename: logger.rb
require 'rest-client'
require 'json'
class Logger
def initialize(session_id)
@session_id = session_id
end
def latest
parse(fetch).last
end
private
def fetch
RestClient.post(
"http://127.0.0.1:4444/wd/hub/session/#{@session_id}/log",
{ "type" => "client" }.to_json,
content_type: :json,
accept: :json
)
end
def parse(input)
logs = JSON.parse(input)
messages = []
logs["value"].each do |entry|
msg = entry["message"]
unless msg.include? "session:" or
msg.include? "fetching logs" or
msg.include? "execute script"
messages << msg.scan(/handle(.*)$/)[-1][-1]
end
end
messages
end
end
A couple of things to note.
The session_id
will come from the instance of Selenium that gets created in our test (via Selenium Grid). To see
your sessions, navigate to the instance in your web browser (http://localhost:4444/) and then click Sessions in the
side panel. This session ID maps to a URI endpoint on the Selenium Server that we use to get the logging payload
with an HTTP POST (see fetch
). We are then taking that payload (which comes back as a JSON object in String form)
and parsing it into JSON, iterating through it, grabbing the relevant bits we want (see parse
). When that's all
done, we return the last entry found (see latest
).
And of all the available log types we can access, we're grabbing the client logs (which will give us the real time actions taken in our test).
NOTE: Each time we access the logs, it will clear the cache of logs. So the next time we access them, it will only return new entries.
Now we're ready to wire up our test to use the Selenium Server, access our logger class, and output the latest log entries after each Selenium action.
# filename: log_test.rb
require 'selenium-webdriver'
require 'rspec/expectations'
include RSpec::Matchers
require_relative 'logger'
def setup
@driver = Selenium::WebDriver.for :remote, url: 'http://127.0.0.1:4444/wd/hub'
@logger = Logger.new(@driver.session_id)
end
def teardown
@driver.quit
end
def run
setup
yield
teardown
end
run do
@driver.get 'https://the-internet.herokuapp.com'
puts @logger.latest
@driver.find_elements(css: 'a').last.click
puts @logger.latest
end
When we run this (e.g., ruby log_test.rb
), here's what we should see.
Done: [get: http://the-internet.herokuapp.com]
Done: [click: 23 [[FirefoxDriver: firefox on MAC (2afa5f83-1aba-ad43-b1f3-9b4907ae9471)] -> css selector: a]]
If we couple this with jQuery Growl Notifications (covered in the last tip) then we can really put this information to work.
Let's add some helper methods to add jQuery Growl to the page and display notification messages.
def add_growl_notifications
@driver.execute_script("if (!window.jQuery) {
var jquery = document.createElement('script'); jquery.type = 'text/javascript';
jquery.src = 'https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js';
document.getElementsByTagName('head')[0].appendChild(jquery);
}")
@driver.execute_script("$.getScript('http://the-internet.herokuapp.com/js/vendor/jquery.growl.js')")
@driver.execute_script("$('head').append('<link rel=\"stylesheet\" href=\"http://the-internet.herokuapp.com/css/jquery.growl.css\" type=\"text/css\" />');")
end
def display_growl_message(message)
@driver.execute_script("$.growl({ title: 'Selenium', message: '#{message}' });")
sleep 2
end
Now let's update our test to perform an action and then display it through jQuery Growl notifications.
run do
@driver.get 'http://the-internet.herokuapp.com'
add_growl_notifications
display_growl_message(@logger.latest)
end
When we run this (e.g., ruby log_test.rb
), we should see the latest log action appear in a growl notification within
the browser window.
Expected Behavior
- Load the browser
- Take an action
- Grab the action from the logs
- Display the action
Summary
Hopefully that was a helpful tip on how to get browser-agnostic, real-time logging information.
Happy Testing!