Skip to content

Instantly share code, notes, and snippets.

@rtyler
Created September 21, 2012 23:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rtyler/3764502 to your computer and use it in GitHub Desktop.
Save rtyler/3764502 to your computer and use it in GitHub Desktop.
hookeddriver.rb
#
# This file contains some slightly modified drivers to help do i18n testing.
#
# In order to do the testing we want, we can't use the AfterStep cucumber since
# we might invoke multiple pages or change the page content entirely within a
# specific step
require 'rubygems'
require 'capybara'
# I have no problem admitting that I don't entirely understand this code, I
# borrowed it from here:
# <http://cheind.blogspot.com/2008/12/method-hooks-in-ruby.html>
module FollowingHook
module ClassMethods
private
# Hook the provided instance methods so that the block
# is executed directly after the specified methods have
# been invoked.
#
def following(*syms, &block)
syms.each do |sym| # For each symbol
str_id = "__#{sym}__hooked__"
unless private_instance_methods.include?(str_id)
alias_method str_id, sym # Backup original
# method
private str_id # Make backup private
define_method sym do |*args| # Replace method
ret = __send__ str_id, *args # Invoke backup
block.call(self, # Invoke hook
:method => sym,
:args => args,
:return => ret
)
ret # Forward return value of method
end
end
end
end
end
# On inclusion, we extend the receiver by
# the defined class-methods. This is an ruby
# idiom for defining class methods within a module.
def FollowingHook.included(base)
base.extend(ClassMethods)
end
end
module HookedSelenium
def i18n_check(driver)
if ENV['CHECK_I18N']
[XPath::HTML.content('translation_missing'),
XPath::HTML.content('translation missing'),
XPath::css('.translation_missing'),
XPath::HTML.content('TRANSLATION_MISSING')].each do |selector|
elems = driver.find(selector)
unless elems.empty?
raise "Missing translation found on #{driver.current_url}"
end
end
end
end
module_function :i18n_check
class Node < Capybara::Selenium::Node
include FollowingHook
following :click, :drag_to, :set, :select_option, :unselect_option, :select_node, :type do |node, args|
::HookedSelenium.i18n_check(node.driver)
end
end
class Driver < Capybara::Selenium::Driver
def find(selector)
browser.find_elements(:xpath, selector).map { |node| Node.new(self, node) }
end
include FollowingHook
following :visit do |driver, args|
::HookedSelenium.i18n_check(driver)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment