warnold-selenium-client 1.2.19
Sign up to get free protection for your applications and to get access to all the features.
- 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
|