warnold-selenium-client 1.2.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +338 -0
- data/examples/rspec/google_spec.rb +41 -0
- data/examples/script/google.rb +25 -0
- data/examples/testunit/google_test.rb +39 -0
- data/lib/nautilus/shell.rb +34 -0
- data/lib/selenium.rb +14 -0
- data/lib/selenium/client.rb +27 -0
- data/lib/selenium/client/base.rb +118 -0
- data/lib/selenium/client/driver.rb +11 -0
- data/lib/selenium/client/extensions.rb +118 -0
- data/lib/selenium/client/idiomatic.rb +488 -0
- data/lib/selenium/client/javascript_expression_builder.rb +116 -0
- data/lib/selenium/client/javascript_frameworks/jquery.rb +13 -0
- data/lib/selenium/client/javascript_frameworks/prototype.rb +13 -0
- data/lib/selenium/client/legacy_driver.rb +1711 -0
- data/lib/selenium/client/protocol.rb +104 -0
- data/lib/selenium/client/selenium_helper.rb +34 -0
- data/lib/selenium/command_error.rb +4 -0
- data/lib/selenium/protocol_error.rb +4 -0
- data/lib/selenium/rake/default_tasks.rb +17 -0
- data/lib/selenium/rake/remote_control_start_task.rb +71 -0
- data/lib/selenium/rake/remote_control_stop_task.rb +44 -0
- data/lib/selenium/rake/tasks.rb +6 -0
- data/lib/selenium/remote_control/remote_control.rb +35 -0
- data/lib/selenium/rspec/reporting/file_path_strategy.rb +78 -0
- data/lib/selenium/rspec/reporting/html_report.rb +155 -0
- data/lib/selenium/rspec/reporting/selenium_test_report_formatter.rb +88 -0
- data/lib/selenium/rspec/reporting/system_capture.rb +72 -0
- data/lib/selenium/rspec/rspec_extensions.rb +104 -0
- data/lib/selenium/rspec/spec_helper.rb +34 -0
- data/lib/tcp_socket_extension.rb +32 -0
- data/test/all_unit_tests.rb +3 -0
- metadata +102 -0
@@ -0,0 +1,104 @@
|
|
1
|
+
module Selenium
|
2
|
+
module Client
|
3
|
+
|
4
|
+
HTTP_HEADERS = { 'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8' }
|
5
|
+
|
6
|
+
# Module in charge of handling Selenium over-the-wire HTTP protocol
|
7
|
+
module Protocol
|
8
|
+
attr_reader :session_id
|
9
|
+
|
10
|
+
def remote_control_command(verb, args=[])
|
11
|
+
timeout(@default_timeout_in_seconds) do
|
12
|
+
status, response = http_post(http_request_for(verb, args))
|
13
|
+
raise Selenium::CommandError, response unless status == "OK"
|
14
|
+
response[3..-1] # strip "OK," from response
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def string_command(verb, args=[])
|
19
|
+
remote_control_command(verb, args)
|
20
|
+
end
|
21
|
+
|
22
|
+
def string_array_command(verb, args=[])
|
23
|
+
csv = string_command(verb, args)
|
24
|
+
token = ""
|
25
|
+
tokens = []
|
26
|
+
escape = false
|
27
|
+
csv.split(//).each do |letter|
|
28
|
+
if escape
|
29
|
+
token += letter
|
30
|
+
escape = false
|
31
|
+
next
|
32
|
+
end
|
33
|
+
case letter
|
34
|
+
when '\\'
|
35
|
+
escape = true
|
36
|
+
when ','
|
37
|
+
tokens << token
|
38
|
+
token = ""
|
39
|
+
else
|
40
|
+
token += letter
|
41
|
+
end
|
42
|
+
end
|
43
|
+
tokens << token
|
44
|
+
return tokens
|
45
|
+
end
|
46
|
+
|
47
|
+
def number_command(verb, args)
|
48
|
+
string_command verb, args
|
49
|
+
end
|
50
|
+
|
51
|
+
def number_array_command(verb, args)
|
52
|
+
string_array_command verb, args
|
53
|
+
end
|
54
|
+
|
55
|
+
def boolean_command(verb, args=[])
|
56
|
+
parse_boolean_value string_command(verb, args)
|
57
|
+
end
|
58
|
+
|
59
|
+
def boolean_array_command(verb, args)
|
60
|
+
string_array_command(verb, args).collect {|value| parse_boolean_value(value)}
|
61
|
+
end
|
62
|
+
|
63
|
+
protected
|
64
|
+
|
65
|
+
def parse_boolean_value(value)
|
66
|
+
if ("true" == value)
|
67
|
+
return true
|
68
|
+
elsif ("false" == value)
|
69
|
+
return false
|
70
|
+
end
|
71
|
+
raise ProtocolError, "Invalid Selenese boolean value that is neither 'true' nor 'false': got '#{value}'"
|
72
|
+
end
|
73
|
+
|
74
|
+
def http_request_for(verb, args)
|
75
|
+
data = "cmd=#{CGI::escape(verb)}"
|
76
|
+
args.each_with_index do |arg, index|
|
77
|
+
data << "&#{index.succ}=#{CGI::escape(arg.to_s)}"
|
78
|
+
end
|
79
|
+
data << "&sessionId=#{session_id}" unless session_id.nil?
|
80
|
+
data
|
81
|
+
end
|
82
|
+
|
83
|
+
def http_post(data)
|
84
|
+
start = Time.now
|
85
|
+
called_from = caller.detect{|line| line !~ /(selenium-client|vendor|usr\/lib\/ruby|\(eval\))/i}
|
86
|
+
http = Net::HTTP.new(@host, @port)
|
87
|
+
http.open_timeout = default_timeout_in_seconds
|
88
|
+
http.read_timeout = default_timeout_in_seconds
|
89
|
+
response = http.post('/selenium-server/driver/', data, HTTP_HEADERS)
|
90
|
+
if response.body !~ /^OK/
|
91
|
+
puts "#{start} selenium-client received failure from selenium server:"
|
92
|
+
puts "requested:"
|
93
|
+
puts "\t" + CGI::unescape(data.split('&').join("\n\t"))
|
94
|
+
puts "received:"
|
95
|
+
puts "\t#{response.body.inspect}"
|
96
|
+
puts "\tcalled from #{called_from}"
|
97
|
+
end
|
98
|
+
[ response.body[0..1], response.body ]
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Defines a mixin module that you can use to write Selenium tests
|
2
|
+
# without typing "@selenium." in front of every command. Every
|
3
|
+
# call to a missing method will be automatically sent to the @selenium
|
4
|
+
# object.
|
5
|
+
module Selenium
|
6
|
+
module Client
|
7
|
+
|
8
|
+
module SeleniumHelper
|
9
|
+
|
10
|
+
# Overrides default open method to actually delegates to @selenium
|
11
|
+
def open(url)
|
12
|
+
@selenium.open url
|
13
|
+
end
|
14
|
+
|
15
|
+
# Overrides default type method to actually delegates to @selenium
|
16
|
+
def type(locator, value)
|
17
|
+
@selenium.type locator, value
|
18
|
+
end
|
19
|
+
|
20
|
+
# Overrides default select method to actually delegates to @selenium
|
21
|
+
def select(input_locator, option_locator)
|
22
|
+
@selenium.select input_locator, option_locator
|
23
|
+
end
|
24
|
+
|
25
|
+
# Delegates to @selenium on method missing
|
26
|
+
def method_missing(method_name, *args)
|
27
|
+
return super unless @selenium.respond_to?(method_name)
|
28
|
+
|
29
|
+
@selenium.send(method_name, *args)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'selenium/rake/tasks'
|
2
|
+
|
3
|
+
Selenium::Rake::RemoteControlStartTask.new do |rc|
|
4
|
+
rc.timeout_in_seconds = 3 * 60
|
5
|
+
rc.background = true
|
6
|
+
rc.nohup = false
|
7
|
+
rc.wait_until_up_and_running = true
|
8
|
+
rc.additional_args << "-singleWindow"
|
9
|
+
end
|
10
|
+
|
11
|
+
Selenium::Rake::RemoteControlStopTask.new
|
12
|
+
|
13
|
+
desc "Restart Selenium Remote Control"
|
14
|
+
task :'selenium:rc:restart' do
|
15
|
+
Rake::Task[:'selenium:rc:stop'].execute [] rescue nil
|
16
|
+
Rake::Task[:'selenium:rc:start'].execute []
|
17
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Selenium
|
2
|
+
module Rake
|
3
|
+
|
4
|
+
# Rake tasks to start a Remote Control server.
|
5
|
+
#
|
6
|
+
# require 'selenium/rake/tasks'
|
7
|
+
#
|
8
|
+
# Selenium::Rake::RemoteControlStartTask.new do |rc|
|
9
|
+
# rc.port = 4444
|
10
|
+
# rc.timeout_in_seconds = 3 * 60
|
11
|
+
# rc.background = true
|
12
|
+
# rc.wait_until_up_and_running = true
|
13
|
+
# rc.jar_file = "/path/to/where/selenium-rc-standalone-jar-is-installed"
|
14
|
+
# rc.additional_args << "-singleWindow"
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# If you do not explicitly specify the path to selenium remote control jar
|
18
|
+
# it will be "auto-discovered" in `vendor` directory using the following
|
19
|
+
# path : `vendor/selenium-remote-control/selenium-server*-standalone.jar`
|
20
|
+
#
|
21
|
+
# To leverage the latest selenium-client capabilities, you may need to download
|
22
|
+
# a recent nightly build of a standalone packaging of Selenium Remote
|
23
|
+
# Control. You will find the nightly build at
|
24
|
+
# http://nexus.openqa.org/content/repositories/snapshots/org/seleniumhq/selenium/server/selenium-server/
|
25
|
+
class RemoteControlStartTask
|
26
|
+
attr_accessor :port, :timeout_in_seconds, :background,
|
27
|
+
:wait_until_up_and_running, :additional_args,
|
28
|
+
:log_to, :nohup
|
29
|
+
attr_reader :jar_file
|
30
|
+
|
31
|
+
JAR_FILE_PATTERN = "vendor/selenium-remote-control/selenium-server-*.jar"
|
32
|
+
|
33
|
+
def initialize(name = :'selenium:rc:start')
|
34
|
+
@name = name
|
35
|
+
@port = 4444
|
36
|
+
@timeout_in_seconds = 5
|
37
|
+
project_specific_jar = Dir[JAR_FILE_PATTERN].first
|
38
|
+
@jar_file = project_specific_jar
|
39
|
+
@additional_args = []
|
40
|
+
@background = false
|
41
|
+
@nohup = false
|
42
|
+
@wait_until_up_and_running = false
|
43
|
+
yield self if block_given?
|
44
|
+
define
|
45
|
+
end
|
46
|
+
|
47
|
+
def jar_file=(new_jar_file)
|
48
|
+
@jar_file = File.expand_path(new_jar_file)
|
49
|
+
end
|
50
|
+
|
51
|
+
def define
|
52
|
+
desc "Launch Selenium Remote Control"
|
53
|
+
task @name do
|
54
|
+
puts "Starting Selenium Remote Control at 0.0.0.0:#{@port}..."
|
55
|
+
raise "Could not find jar file '#{@jar_file}'. Expected it under #{JAR_FILE_PATTERN}" unless @jar_file && File.exists?(@jar_file)
|
56
|
+
remote_control = Selenium::RemoteControl::RemoteControl.new("0.0.0.0", @port, :timeout => @timeout_in_seconds)
|
57
|
+
remote_control.jar_file = @jar_file
|
58
|
+
remote_control.additional_args = @additional_args
|
59
|
+
remote_control.log_to = @log_to
|
60
|
+
remote_control.start :background => @background, :nohup => @nohup
|
61
|
+
if @background && @wait_until_up_and_running
|
62
|
+
puts "Waiting for Remote Control to be up and running..."
|
63
|
+
TCPSocket.wait_for_service :host => @host, :port => @port
|
64
|
+
end
|
65
|
+
puts "Selenium Remote Control at 0.0.0.0:#{@port} ready"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Selenium
|
2
|
+
module Rake
|
3
|
+
|
4
|
+
# Rake task to stop a Selenium Remote Control Server
|
5
|
+
#
|
6
|
+
# Selenium::Rake::RemoteControlStopTask.new do |rc|
|
7
|
+
# rc.host = "localhost"
|
8
|
+
# rc.port = 4444
|
9
|
+
# rc.timeout_in_seconds = 3 * 60
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
class RemoteControlStopTask
|
13
|
+
attr_accessor :host, :port, :timeout_in_seconds, :wait_until_stopped,
|
14
|
+
:shutdown_command
|
15
|
+
|
16
|
+
def initialize(name = :'selenium:rc:stop')
|
17
|
+
@host = "localhost"
|
18
|
+
@name = name
|
19
|
+
@port = 4444
|
20
|
+
@timeout_in_seconds = nil
|
21
|
+
@shutdown_command = nil
|
22
|
+
@wait_until_stopped = true
|
23
|
+
yield self if block_given?
|
24
|
+
define
|
25
|
+
end
|
26
|
+
|
27
|
+
def define
|
28
|
+
desc "Stop Selenium Remote Control running"
|
29
|
+
task @name do
|
30
|
+
puts "Stopping Selenium Remote Control running at #{host}:#{port}..."
|
31
|
+
remote_control = Selenium::RemoteControl::RemoteControl.new(
|
32
|
+
host, port, :timeout => timeout_in_seconds,
|
33
|
+
:shutdown_command => shutdown_command)
|
34
|
+
remote_control.stop
|
35
|
+
if @wait_until_stopped
|
36
|
+
TCPSocket.wait_for_service_termination :host => host, :port => port
|
37
|
+
end
|
38
|
+
puts "Stopped Selenium Remote Control running at #{host}:#{port}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../nautilus/shell')
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../tcp_socket_extension')
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + '/../remote_control/remote_control')
|
5
|
+
require File.expand_path(File.dirname(__FILE__) + '/remote_control_start_task')
|
6
|
+
require File.expand_path(File.dirname(__FILE__) + '/remote_control_stop_task')
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Selenium
|
2
|
+
module RemoteControl
|
3
|
+
|
4
|
+
class RemoteControl
|
5
|
+
attr_reader :host, :port, :timeout_in_seconds, :firefox_profile, :shutdown_command
|
6
|
+
attr_accessor :additional_args, :jar_file, :log_to
|
7
|
+
|
8
|
+
def initialize(host, port, options={})
|
9
|
+
@host, @port = host, port
|
10
|
+
@timeout_in_seconds = options[:timeout] || (2 * 60)
|
11
|
+
@shutdown_command = options[:shutdown_command] || "shutDownSeleniumServer"
|
12
|
+
@firefox_profile = options[:firefox_profile]
|
13
|
+
@additional_args = options[:additional_args] || []
|
14
|
+
@shell = Nautilus::Shell.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def start(options = {})
|
18
|
+
command = "java -jar \"#{jar_file}\""
|
19
|
+
command << " -port #{@port}"
|
20
|
+
command << " -timeout #{@timeout_in_seconds}"
|
21
|
+
command << " -firefoxProfileTemplate '#{@firefox_profile}'" if @firefox_profile
|
22
|
+
command << " #{additional_args.join(' ')}" unless additional_args.empty?
|
23
|
+
command << " > #{log_to}" if log_to
|
24
|
+
|
25
|
+
@shell.run command, {:background => options[:background], :nohup => options[:nohup]}
|
26
|
+
end
|
27
|
+
|
28
|
+
def stop
|
29
|
+
Net::HTTP.get(@host, "/selenium-server/driver/?cmd=#{shutdown_command}", @port)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Selenium
|
2
|
+
module RSpec
|
3
|
+
module Reporting
|
4
|
+
|
5
|
+
class FilePathStrategy
|
6
|
+
attr_reader :final_report_file_path
|
7
|
+
|
8
|
+
REPORT_DEFAULT_FILE_PATH = File.join(Dir::tmpdir, "selenium_test_report", "index.html")
|
9
|
+
|
10
|
+
def initialize(final_report_file_path)
|
11
|
+
@final_report_file_path = final_report_file_path || REPORT_DEFAULT_FILE_PATH
|
12
|
+
@relative_dir = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def base_report_dir
|
16
|
+
@base_report_dir ||= File.dirname(File.expand_path(@final_report_file_path))
|
17
|
+
end
|
18
|
+
|
19
|
+
def relative_dir
|
20
|
+
return @relative_dir if @relative_dir
|
21
|
+
|
22
|
+
file_name_without_extension = File.basename(@final_report_file_path).sub(/\.[^\.]*$/, "")
|
23
|
+
@relative_dir ||= "resources/" + file_name_without_extension
|
24
|
+
end
|
25
|
+
|
26
|
+
def relative_file_path_for_html_capture(example)
|
27
|
+
"#{relative_dir}/example_#{example.reporting_uid}.html"
|
28
|
+
end
|
29
|
+
|
30
|
+
def relative_file_path_for_system_screenshot(example)
|
31
|
+
"#{relative_dir}/example_#{example.reporting_uid}_system_screenshot.png"
|
32
|
+
end
|
33
|
+
|
34
|
+
def relative_file_path_for_page_screenshot(example)
|
35
|
+
"#{relative_dir}/example_#{example.reporting_uid}_page_screenshot.png"
|
36
|
+
end
|
37
|
+
|
38
|
+
def relative_file_path_for_remote_control_logs(example)
|
39
|
+
"#{relative_dir}/example_#{example.reporting_uid}_remote_control.log"
|
40
|
+
end
|
41
|
+
|
42
|
+
def relative_file_path_for_browser_network_traffic(example)
|
43
|
+
"#{relative_dir}/example_#{example.reporting_uid}_browser_network_traffic.log"
|
44
|
+
end
|
45
|
+
|
46
|
+
def file_path_for_html_capture(example)
|
47
|
+
file_path relative_file_path_for_html_capture(example)
|
48
|
+
end
|
49
|
+
|
50
|
+
def file_path_for_system_screenshot(example)
|
51
|
+
file_path relative_file_path_for_system_screenshot(example)
|
52
|
+
end
|
53
|
+
|
54
|
+
def file_path_for_page_screenshot(example)
|
55
|
+
file_path relative_file_path_for_page_screenshot(example)
|
56
|
+
end
|
57
|
+
|
58
|
+
def file_path_for_remote_control_logs(example)
|
59
|
+
file_path relative_file_path_for_remote_control_logs(example)
|
60
|
+
end
|
61
|
+
|
62
|
+
def file_path_for_browser_network_traffic(example)
|
63
|
+
file_path relative_file_path_for_browser_network_traffic(example)
|
64
|
+
end
|
65
|
+
|
66
|
+
def file_path(relative_file_path)
|
67
|
+
the_file_path = base_report_dir + "/" + relative_file_path
|
68
|
+
parent_dir = File.dirname(the_file_path)
|
69
|
+
FileUtils.mkdir_p(parent_dir) unless File.directory?(parent_dir)
|
70
|
+
the_file_path
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
module Selenium
|
2
|
+
module RSpec
|
3
|
+
module Reporting
|
4
|
+
|
5
|
+
class HtmlReport
|
6
|
+
|
7
|
+
PLACEHOLDER = "<<placeholder>>"
|
8
|
+
|
9
|
+
def initialize(file_path_strategy)
|
10
|
+
@file_path_strategy = file_path_strategy
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.inject_placeholder(content)
|
14
|
+
content + Selenium::RSpec::Reporting::HtmlReport::PLACEHOLDER
|
15
|
+
end
|
16
|
+
|
17
|
+
def replace_placeholder_with_system_state_content(result, example)
|
18
|
+
result.gsub! PLACEHOLDER, logs_and_screenshot_sections(example)
|
19
|
+
end
|
20
|
+
|
21
|
+
def logs_and_screenshot_sections(example)
|
22
|
+
dom_id = "example_" + example.reporting_uid
|
23
|
+
system_screenshot_url = @file_path_strategy.relative_file_path_for_system_screenshot(example)
|
24
|
+
page_screenshot_url = @file_path_strategy.relative_file_path_for_page_screenshot(example)
|
25
|
+
snapshot_url = @file_path_strategy.relative_file_path_for_html_capture(example)
|
26
|
+
remote_control_logs_url = @file_path_strategy.relative_file_path_for_remote_control_logs(example)
|
27
|
+
remote_control_logs_path = @file_path_strategy.file_path_for_remote_control_logs(example)
|
28
|
+
|
29
|
+
html = ""
|
30
|
+
if File.exists? @file_path_strategy.file_path_for_html_capture(example)
|
31
|
+
html << toggable_section(dom_id, :id => "snapshot", :url=> snapshot_url, :name => "Dynamic HTML Snapshot")
|
32
|
+
end
|
33
|
+
if File.exists? remote_control_logs_path
|
34
|
+
html << toggable_inline_section(dom_id, :id => "rc_logs", :url => remote_control_logs_url, :path=> remote_control_logs_path, :name => "Remote Control Logs")
|
35
|
+
end
|
36
|
+
if File.exists? @file_path_strategy.file_path_for_page_screenshot(example)
|
37
|
+
html << toggable_image_section(dom_id, :id => "page_screenshot", :name => "Page Screenshot", :url => page_screenshot_url)
|
38
|
+
end
|
39
|
+
if File.exists? @file_path_strategy.file_path_for_system_screenshot(example)
|
40
|
+
html << toggable_image_section(dom_id, :id => "system_screenshot", :name => "System Screenshot", :url => system_screenshot_url)
|
41
|
+
end
|
42
|
+
|
43
|
+
return html
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.append_javascript(global_scripts)
|
47
|
+
global_scripts + <<-EOF
|
48
|
+
function toggleVisilibility(id, description) {
|
49
|
+
var section;
|
50
|
+
var link;
|
51
|
+
|
52
|
+
section = document.getElementById(id);
|
53
|
+
link = document.getElementById(id + "_link");
|
54
|
+
|
55
|
+
if (section.style.display == "block") {
|
56
|
+
section.style.display = "none"
|
57
|
+
link.innerHTML = "Show " + description
|
58
|
+
} else {
|
59
|
+
section.style.display = "block"
|
60
|
+
link.innerHTML = "Hide " + description
|
61
|
+
}
|
62
|
+
}
|
63
|
+
EOF
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.append_css(global_styles)
|
67
|
+
global_styles + <<-EOF
|
68
|
+
|
69
|
+
div.rspec-report textarea {
|
70
|
+
width: 100%;
|
71
|
+
}
|
72
|
+
|
73
|
+
div.rspec-report .dyn-source {
|
74
|
+
background: #FFFFEE none repeat scroll 0%;
|
75
|
+
border:1px dotted black;
|
76
|
+
color: #000000;
|
77
|
+
display: none;
|
78
|
+
margin: 0.5em 2em;
|
79
|
+
padding: 0.5em;
|
80
|
+
}
|
81
|
+
|
82
|
+
EOF
|
83
|
+
end
|
84
|
+
|
85
|
+
def toggable_section(dom_id, options)
|
86
|
+
<<-EOS
|
87
|
+
|
88
|
+
<div>[
|
89
|
+
<a id="#{dom_id}_#{options[:id]}_link"
|
90
|
+
href=\"javascript:toggleVisilibility('#{dom_id}_#{options[:id]}', '#{options[:name]}')\">Show #{options[:name]}</a>
|
91
|
+
]</div>
|
92
|
+
<br/><br/>
|
93
|
+
<div id="#{dom_id}_#{options[:id]}" class="dyn-source">
|
94
|
+
<a href="#{options[:url]}">Full screen</a><br/><br/>
|
95
|
+
<iframe src="#{options[:url]}" width="100%" height="600px" ></iframe>
|
96
|
+
</div>
|
97
|
+
|
98
|
+
EOS
|
99
|
+
end
|
100
|
+
|
101
|
+
def toggable_inline_section(dom_id, options)
|
102
|
+
<<-EOS
|
103
|
+
|
104
|
+
<div>[
|
105
|
+
<a id="#{dom_id}_#{options[:id]}_link"
|
106
|
+
href=\"javascript:toggleVisilibility('#{dom_id}_#{options[:id]}', '#{options[:name]}')\">Show #{options[:name]}</a>
|
107
|
+
]</div>
|
108
|
+
<br/><br/>
|
109
|
+
<div id="#{dom_id}_#{options[:id]}" class="dyn-source">
|
110
|
+
<a href="#{options[:url]}">Full screen</a><br/><br/>
|
111
|
+
<pre>#{File.open(options[:path]).read}</pre>
|
112
|
+
</div>
|
113
|
+
|
114
|
+
EOS
|
115
|
+
end
|
116
|
+
|
117
|
+
def toggable_image_section(dom_id, options)
|
118
|
+
<<-EOS
|
119
|
+
|
120
|
+
<div>[<a id="#{dom_id}_#{options[:id]}_link" href="javascript:toggleVisilibility('#{dom_id}_#{options[:id]}', '#{options[:name]}');">Show #{options[:name]}</a>]</div>
|
121
|
+
<br/>
|
122
|
+
<div id="#{dom_id}_#{options[:id]}" style="display: none">
|
123
|
+
<a href="#{options[:url]}">
|
124
|
+
<img width="80%" src="#{options[:url]}" />
|
125
|
+
</a>
|
126
|
+
</div>
|
127
|
+
<br/>
|
128
|
+
|
129
|
+
EOS
|
130
|
+
end
|
131
|
+
|
132
|
+
def report_header
|
133
|
+
super + "\n<script type=\"text/javascript\">moveProgressBar('100.0');</script>"
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
# Tweaks raised Exceptions to mask noisy (unneeded) parts of the backtrace
|
141
|
+
class SeleniumQuietBacktraceTweaker < Spec::Runner::QuietBacktraceTweaker
|
142
|
+
unless defined?(SELENIUM_IGNORE_PATTERNS)
|
143
|
+
SELENIUM_IGNORE_PATTERNS = [
|
144
|
+
/selenium-client/,
|
145
|
+
/selenium\/client/,
|
146
|
+
]
|
147
|
+
end
|
148
|
+
|
149
|
+
def ignored_patterns
|
150
|
+
super + SELENIUM_IGNORE_PATTERNS
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
end
|