adding html unit spike
This commit is contained in:
parent
7c46a6fed0
commit
0800f79428
41
lib/webrat/ruby_html_unit.rb
Normal file
41
lib/webrat/ruby_html_unit.rb
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
$:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
||||||
|
|
||||||
|
module RubyHtmlUnit
|
||||||
|
Jars = Dir[File.dirname(__FILE__) + '/ruby_html_unit/htmlunit/*.jar']
|
||||||
|
end
|
||||||
|
|
||||||
|
if RUBY_PLATFORM =~ /java/
|
||||||
|
require 'java'
|
||||||
|
RubyHtmlUnit::Jars.each { |jar| require(jar) }
|
||||||
|
|
||||||
|
module HtmlUnit
|
||||||
|
include_package 'com.gargoylesoftware.htmlunit'
|
||||||
|
end
|
||||||
|
JavaString = java.lang.String
|
||||||
|
else
|
||||||
|
raise "RubyHtmlUnit only works on JRuby at the moment."
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
Dir[File.join(File.dirname(__FILE__), "ruby_html_unit", "*.rb")].each do |file|
|
||||||
|
require File.expand_path(file)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# Deal with the test server
|
||||||
|
if `uname`.chomp == "Darwin"
|
||||||
|
TEST_SERVER_PORT = '3001'
|
||||||
|
|
||||||
|
if `ps ax`.match(/^\s*(\d*).*-e test -p #{TEST_SERVER_PORT}/)
|
||||||
|
puts "A test server was found running on port #{TEST_SERVER_PORT} (PID #{$1})"
|
||||||
|
else
|
||||||
|
puts "A test server was not found running (looking for -e test -p #{TEST_SERVER_PORT})"
|
||||||
|
puts "Please start a new test server using the command below:"
|
||||||
|
puts
|
||||||
|
|
||||||
|
command_string = "ruby #{RAILS_ROOT}/script/server -e test -p #{TEST_SERVER_PORT}"
|
||||||
|
|
||||||
|
puts command_string
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
end
|
13
lib/webrat/ruby_html_unit/alert_handler.rb
Normal file
13
lib/webrat/ruby_html_unit/alert_handler.rb
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
module RubyHtmlUnit
|
||||||
|
|
||||||
|
class AlertHandler
|
||||||
|
def handleAlert(html_unit_page, alert_message)
|
||||||
|
alert_messages << alert_message
|
||||||
|
end
|
||||||
|
|
||||||
|
def alert_messages
|
||||||
|
@alert_messages ||= []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
119
lib/webrat/ruby_html_unit/element.rb
Normal file
119
lib/webrat/ruby_html_unit/element.rb
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
module RubyHtmlUnit
|
||||||
|
|
||||||
|
class Element
|
||||||
|
def initialize(element, page)
|
||||||
|
@html_unit_element = element
|
||||||
|
@page = page
|
||||||
|
end
|
||||||
|
|
||||||
|
def elem_type
|
||||||
|
@html_unit_element.node_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def id_attribute
|
||||||
|
@html_unit_element.id_attribute
|
||||||
|
end
|
||||||
|
|
||||||
|
def matches_text?(text)
|
||||||
|
@html_unit_element.as_text =~ text_as_regexp(text)
|
||||||
|
end
|
||||||
|
|
||||||
|
def matches_attribute?(attribute, text)
|
||||||
|
@html_unit_element.get_attribute(attribute) =~ text_as_regexp(text)
|
||||||
|
end
|
||||||
|
|
||||||
|
def ancestors
|
||||||
|
current_element = self
|
||||||
|
[].tap do |ancs|
|
||||||
|
while current_element.parent && current_element.elem_type != 'html'
|
||||||
|
ancs << current_element
|
||||||
|
current_element = current_element.parent
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def label_matches?(label_text)
|
||||||
|
ancestors.each do |anc|
|
||||||
|
return true if anc.elem_type == 'label' && anc.matches_text?(label_text)
|
||||||
|
end
|
||||||
|
|
||||||
|
if id_attribute.blank?
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
label_tag = @page.elements_by_xpath("//label[@for='#{id_attribute}']").first
|
||||||
|
return label_tag if label_tag && label_tag.matches_text?(label_text)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def click
|
||||||
|
@html_unit_element.click
|
||||||
|
end
|
||||||
|
|
||||||
|
def fill_in_with(value)
|
||||||
|
clear
|
||||||
|
type_string(value)
|
||||||
|
end
|
||||||
|
|
||||||
|
def clear
|
||||||
|
case @html_unit_element.getTagName
|
||||||
|
when 'textarea' then @html_unit_element.setText('')
|
||||||
|
when 'input' then @html_unit_element.setValueAttribute('')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def select(option_text)
|
||||||
|
@html_unit_element.getOptions.select { |e| e.asText =~ text_as_regexp(option_text) }.each do |option|
|
||||||
|
option.click
|
||||||
|
#@container.update_page(option.click)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def set(value = true)
|
||||||
|
@html_unit_element.setChecked(value)
|
||||||
|
#value ? @html_unit_element.click : @html_unit_element.setChecked(value)
|
||||||
|
end
|
||||||
|
|
||||||
|
def includes_option?(option_text)
|
||||||
|
!!@html_unit_element.getByXPath("//option").detect {|opt| opt.as_text =~ text_as_regexp(option_text) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
@html_unit_element.as_text
|
||||||
|
end
|
||||||
|
|
||||||
|
def hidden?
|
||||||
|
!!ancestors.detect { |elem| elem.style =~ /display\s*:[\s'"]*none/ }
|
||||||
|
end
|
||||||
|
|
||||||
|
def visible?
|
||||||
|
!hidden?
|
||||||
|
end
|
||||||
|
|
||||||
|
def parent
|
||||||
|
@html_unit_element.respond_to?(:parent_node) ? Element.new(@html_unit_element.parent_node, @page) : nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def class_name
|
||||||
|
@html_unit_element.class_attribute
|
||||||
|
end
|
||||||
|
|
||||||
|
def method_missing(name, *args)
|
||||||
|
return @html_unit_element.send("#{name}_attribute") if @html_unit_element.respond_to?("#{name}_attribute")
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
def type_string(value)
|
||||||
|
last_page = nil
|
||||||
|
JavaString.new(value.to_java_bytes, @html_unit_element.getPage.getPageEncoding).toCharArray.each do |char|
|
||||||
|
last_page = @html_unit_element.type(char)
|
||||||
|
end
|
||||||
|
last_page
|
||||||
|
end
|
||||||
|
|
||||||
|
def text_as_regexp(text)
|
||||||
|
Regexp.new(Regexp.escape(text), true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
BIN
lib/webrat/ruby_html_unit/htmlunit/commons-codec-1.3.jar
Normal file
BIN
lib/webrat/ruby_html_unit/htmlunit/commons-codec-1.3.jar
Normal file
Binary file not shown.
BIN
lib/webrat/ruby_html_unit/htmlunit/commons-collections-3.2.jar
Normal file
BIN
lib/webrat/ruby_html_unit/htmlunit/commons-collections-3.2.jar
Normal file
Binary file not shown.
BIN
lib/webrat/ruby_html_unit/htmlunit/commons-httpclient-3.1.jar
Normal file
BIN
lib/webrat/ruby_html_unit/htmlunit/commons-httpclient-3.1.jar
Normal file
Binary file not shown.
BIN
lib/webrat/ruby_html_unit/htmlunit/commons-io-1.4.jar
Normal file
BIN
lib/webrat/ruby_html_unit/htmlunit/commons-io-1.4.jar
Normal file
Binary file not shown.
BIN
lib/webrat/ruby_html_unit/htmlunit/commons-lang-2.4.jar
Normal file
BIN
lib/webrat/ruby_html_unit/htmlunit/commons-lang-2.4.jar
Normal file
Binary file not shown.
BIN
lib/webrat/ruby_html_unit/htmlunit/commons-logging-1.1.1.jar
Normal file
BIN
lib/webrat/ruby_html_unit/htmlunit/commons-logging-1.1.1.jar
Normal file
Binary file not shown.
BIN
lib/webrat/ruby_html_unit/htmlunit/cssparser-0.9.5.jar
Normal file
BIN
lib/webrat/ruby_html_unit/htmlunit/cssparser-0.9.5.jar
Normal file
Binary file not shown.
BIN
lib/webrat/ruby_html_unit/htmlunit/htmlunit-2.2.jar
Normal file
BIN
lib/webrat/ruby_html_unit/htmlunit/htmlunit-2.2.jar
Normal file
Binary file not shown.
BIN
lib/webrat/ruby_html_unit/htmlunit/htmlunit-core-js-2.2.jar
Normal file
BIN
lib/webrat/ruby_html_unit/htmlunit/htmlunit-core-js-2.2.jar
Normal file
Binary file not shown.
BIN
lib/webrat/ruby_html_unit/htmlunit/nekohtml-1.9.8.jar
Normal file
BIN
lib/webrat/ruby_html_unit/htmlunit/nekohtml-1.9.8.jar
Normal file
Binary file not shown.
BIN
lib/webrat/ruby_html_unit/htmlunit/sac-1.3.jar
Normal file
BIN
lib/webrat/ruby_html_unit/htmlunit/sac-1.3.jar
Normal file
Binary file not shown.
BIN
lib/webrat/ruby_html_unit/htmlunit/xalan-2.7.0.jar
Normal file
BIN
lib/webrat/ruby_html_unit/htmlunit/xalan-2.7.0.jar
Normal file
Binary file not shown.
BIN
lib/webrat/ruby_html_unit/htmlunit/xercesImpl-2.8.1.jar
Normal file
BIN
lib/webrat/ruby_html_unit/htmlunit/xercesImpl-2.8.1.jar
Normal file
Binary file not shown.
BIN
lib/webrat/ruby_html_unit/htmlunit/xml-apis-1.0.b2.jar
Normal file
BIN
lib/webrat/ruby_html_unit/htmlunit/xml-apis-1.0.b2.jar
Normal file
Binary file not shown.
114
lib/webrat/ruby_html_unit/page.rb
Normal file
114
lib/webrat/ruby_html_unit/page.rb
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
module RubyHtmlUnit
|
||||||
|
|
||||||
|
class Page
|
||||||
|
SAVED_PAGE_DIR = File.expand_path('.')
|
||||||
|
|
||||||
|
def initialize(html_unit_page)
|
||||||
|
@html_unit_page = html_unit_page
|
||||||
|
end
|
||||||
|
|
||||||
|
def body
|
||||||
|
@html_unit_page.getWebResponse.getContentAsString || ''
|
||||||
|
end
|
||||||
|
alias_method :html_document, :body
|
||||||
|
|
||||||
|
def find_link(text)
|
||||||
|
matching_links = elements_by_tag_name('a').select{|e| e.matches_text?(text)}
|
||||||
|
|
||||||
|
if matching_links.any?
|
||||||
|
matching_links.sort_by { |l| l.to_s.length }.first
|
||||||
|
else
|
||||||
|
flunk("Could not find link with text #{text.inspect}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_button(text = nil)
|
||||||
|
buttons = []
|
||||||
|
field_type_xpaths = %w( //button //input[@type='submit'] //input[@type='reset'] //input[@type='image'] //input[@type='button'] )
|
||||||
|
field_type_xpaths.each do |xpath_expr|
|
||||||
|
buttons += elements_by_xpath(xpath_expr)
|
||||||
|
end
|
||||||
|
|
||||||
|
return buttons.first if text.nil?
|
||||||
|
|
||||||
|
matching_buttons = buttons.select{|b| b.matches_attribute?('value', text) }
|
||||||
|
|
||||||
|
if matching_buttons.any?
|
||||||
|
matching_buttons.sort_by { |b| b.to_s.length }.first
|
||||||
|
else
|
||||||
|
flunk("Could not find button with text #{text.inspect}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_field(id_or_name_or_label, field_type)
|
||||||
|
field_type_xpaths = case field_type
|
||||||
|
when :text then %w( //input[@type='text'] //input[@type='hidden'] //textarea )
|
||||||
|
when :select then %w( //select )
|
||||||
|
when :radio then %w( //input[@type='radio'] )
|
||||||
|
when :checkbox then %w( //input[@type='checkbox'] )
|
||||||
|
end
|
||||||
|
|
||||||
|
field_type_xpaths.each do |xpath_expr|
|
||||||
|
elements_by_xpath(xpath_expr).each do |possible_field|
|
||||||
|
return possible_field if possible_field.id_attribute == id_or_name_or_label ||
|
||||||
|
possible_field.name == id_or_name_or_label ||
|
||||||
|
possible_field.label_matches?(id_or_name_or_label)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
flunk("Could not find #{field_type_xpaths.inspect}: #{id_or_name_or_label.inspect}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_select_list_with_option(option_text, id_or_name_or_label = nil)
|
||||||
|
if id_or_name_or_label
|
||||||
|
select_tag = find_field(id_or_name_or_label, :select)
|
||||||
|
return select_tag if select_tag && select_tag.includes_option?(option_text)
|
||||||
|
else
|
||||||
|
elements_by_xpath("//select").each do |sel|
|
||||||
|
if sel.includes_option?(option_text)
|
||||||
|
return sel
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def elements_by_tag_name(tag_name)
|
||||||
|
node_list = @html_unit_page.getElementsByTagName(tag_name)
|
||||||
|
list_len = node_list.length
|
||||||
|
|
||||||
|
[].tap do |array|
|
||||||
|
0.upto(list_len-1) { |i| array << Element.new(node_list.item(i), self)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def elements_by_xpath(xpath_expression)
|
||||||
|
@html_unit_page.getByXPath(xpath_expression).to_a.map{ |e| Element.new(e, self) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def save_and_open
|
||||||
|
return unless File.exist?(SAVED_PAGE_DIR)
|
||||||
|
|
||||||
|
filename = "#{SAVED_PAGE_DIR}/webrat-#{Time.now.to_i}.html"
|
||||||
|
|
||||||
|
File.open(filename, "w") do |f|
|
||||||
|
f.write rewrite_css_and_image_references(body)
|
||||||
|
end
|
||||||
|
|
||||||
|
open_in_browser(filename)
|
||||||
|
end
|
||||||
|
|
||||||
|
def rewrite_css_and_image_references(response_html) # :nodoc
|
||||||
|
response_html.gsub(%r<"/(stylesheets|images)>, Session.rewrite_url('"/\1'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def open_in_browser(path) # :nodoc
|
||||||
|
`open #{path}`
|
||||||
|
end
|
||||||
|
|
||||||
|
def flunk(message)
|
||||||
|
raise message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
24
lib/webrat/ruby_html_unit/response.rb
Normal file
24
lib/webrat/ruby_html_unit/response.rb
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
module RubyHtmlUnit
|
||||||
|
|
||||||
|
class Response
|
||||||
|
def initialize(html_unit_response)
|
||||||
|
@html_unit_response = html_unit_response
|
||||||
|
end
|
||||||
|
|
||||||
|
def success?
|
||||||
|
@html_unit_response.status_code / 100 == 2
|
||||||
|
end
|
||||||
|
|
||||||
|
def content_type
|
||||||
|
@html_unit_response.content_type
|
||||||
|
end
|
||||||
|
|
||||||
|
def body
|
||||||
|
@html_unit_response.getContentAsString || ''
|
||||||
|
end
|
||||||
|
alias_method :text, :body
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
26
lib/webrat/ruby_html_unit/rspec_story.rb
Normal file
26
lib/webrat/ruby_html_unit/rspec_story.rb
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
class Spec::Story::Runner::ScenarioRunner
|
||||||
|
def initialize
|
||||||
|
@listeners = []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module RubyHtmlUnit
|
||||||
|
|
||||||
|
class RspecStory
|
||||||
|
include ::Spec::Matchers
|
||||||
|
include ::Spec::Rails::Matchers
|
||||||
|
|
||||||
|
def current_session
|
||||||
|
@current_session ||= Session.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def method_missing(name, *args)
|
||||||
|
if current_session.respond_to?(name)
|
||||||
|
current_session.send(name, *args)
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
127
lib/webrat/ruby_html_unit/session.rb
Normal file
127
lib/webrat/ruby_html_unit/session.rb
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
module RubyHtmlUnit
|
||||||
|
|
||||||
|
class Session
|
||||||
|
attr_accessor :response, :current_page, :alert_handler
|
||||||
|
|
||||||
|
include ActionController::UrlWriter
|
||||||
|
include ActionController::Assertions
|
||||||
|
include Test::Unit::Assertions
|
||||||
|
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def rewrite_url(url)
|
||||||
|
if url =~ %r{^(/.*)} || url =~ %r{^https?://www.example.com(/.*)}
|
||||||
|
append_to_root_url($1)
|
||||||
|
else
|
||||||
|
url
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def append_to_root_url(path)
|
||||||
|
path = "/#{path}" unless path =~ /^\//
|
||||||
|
"http://localhost:#{TEST_SERVER_PORT}#{path}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize()
|
||||||
|
#java.lang.System.getProperties.put("org.apache.commons.logging.simplelog.defaultlog", opts[:log_level] ? opts[:log_level].to_s : "warn")
|
||||||
|
java.lang.System.getProperties.put("org.apache.commons.logging.simplelog.defaultlog", "warn")
|
||||||
|
|
||||||
|
browser = ::HtmlUnit::BrowserVersion::FIREFOX_2
|
||||||
|
@webclient = ::HtmlUnit::WebClient.new(browser)
|
||||||
|
@webclient.setThrowExceptionOnScriptError(false) #unless opts[:javascript_exceptions]
|
||||||
|
@webclient.setThrowExceptionOnFailingStatusCode(false) #unless opts[:status_code_exceptions]
|
||||||
|
@webclient.setCssEnabled(false) #unless opts[:css]
|
||||||
|
@webclient.setUseInsecureSSL(true) #if opts[:secure_ssl]
|
||||||
|
|
||||||
|
@alert_handler = AlertHandler.new
|
||||||
|
|
||||||
|
@webclient.setAlertHandler(@alert_handler)
|
||||||
|
|
||||||
|
@response = nil
|
||||||
|
@current_page = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def visits(url)
|
||||||
|
update_page(@webclient.getPage(Session.rewrite_url(url)))
|
||||||
|
end
|
||||||
|
|
||||||
|
def clicks_link(text)
|
||||||
|
link = @current_page.find_link(text)
|
||||||
|
update_page(link.click)
|
||||||
|
end
|
||||||
|
|
||||||
|
def clicks_button(text = nil)
|
||||||
|
button = @current_page.find_button(text)
|
||||||
|
update_page(button.click)
|
||||||
|
end
|
||||||
|
|
||||||
|
def fills_in(id_or_name_or_label, options = {})
|
||||||
|
field = @current_page.find_field(id_or_name_or_label, :text)
|
||||||
|
update_page(field.fill_in_with(options[:with]))
|
||||||
|
end
|
||||||
|
|
||||||
|
def selects(option_text, options = {})
|
||||||
|
id_or_name_or_label = options[:from]
|
||||||
|
|
||||||
|
select_tag = @current_page.find_select_list_with_option(option_text, id_or_name_or_label)
|
||||||
|
|
||||||
|
flunk("Could not find option #{option_text.inspect}") if select_tag.nil?
|
||||||
|
select_tag.select(option_text)
|
||||||
|
end
|
||||||
|
|
||||||
|
def chooses(label)
|
||||||
|
field = @current_page.find_field(label, :radio)
|
||||||
|
update_page(field.set)
|
||||||
|
end
|
||||||
|
|
||||||
|
def checks(id_or_name_or_label)
|
||||||
|
field = @current_page.find_field(id_or_name_or_label, :checkbox)
|
||||||
|
update_page(field.set(true))
|
||||||
|
end
|
||||||
|
|
||||||
|
def unchecks(id_or_name_or_label)
|
||||||
|
field = @current_page.find_field(id_or_name_or_label, :checkbox)
|
||||||
|
update_page(field.set(false))
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_element(dom_id)
|
||||||
|
@current_page.elements_by_xpath("//*[@id='#{dom_id}']").first
|
||||||
|
end
|
||||||
|
alias_method :get_element_by_id, :get_element
|
||||||
|
|
||||||
|
def wait_for_result(wait_type)
|
||||||
|
# No support for different types of waiting right now
|
||||||
|
sleep(0.5)
|
||||||
|
# if wait_type == :ajax
|
||||||
|
# wait_for_ajax
|
||||||
|
# elsif wait_type == :effects
|
||||||
|
# wait_for_effects
|
||||||
|
# else
|
||||||
|
# wait_for_page_to_load
|
||||||
|
# end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_page(html_unit_page)
|
||||||
|
@current_page = Page.new(html_unit_page)
|
||||||
|
@response = Response.new(html_unit_page.getWebResponse)
|
||||||
|
end
|
||||||
|
|
||||||
|
def save_and_open_page
|
||||||
|
@current_page.save_and_open
|
||||||
|
end
|
||||||
|
|
||||||
|
def respond_to?(method)
|
||||||
|
super || @current_page.respond_to?(method)
|
||||||
|
end
|
||||||
|
|
||||||
|
def method_missing(name, *args)
|
||||||
|
if @current_page.respond_to?(name)
|
||||||
|
@current_page.send(name, *args)
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user