selenium-selenese 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +308 -0
- data/examples/script/google.rb +15 -0
- data/lib/nautilus/shell.rb +32 -0
- data/lib/selenium.rb +14 -0
- data/lib/selenium/client/base.rb +140 -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 +131 -0
- data/lib/selenium/client/selenium_helper.rb +36 -0
- data/lib/selenium/command_error.rb +4 -0
- data/lib/selenium/protocol_error.rb +4 -0
- data/lib/selenium/rake/default_tasks.rb +16 -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 +123 -0
- data/lib/selenium/rspec/reporting/selenium_test_report_formatter.rb +87 -0
- data/lib/selenium/rspec/reporting/system_capture.rb +72 -0
- data/lib/selenium/rspec/rspec_extensions.rb +96 -0
- data/lib/selenium/rspec/spec_helper.rb +34 -0
- data/lib/selenium/selenese.rb +24 -0
- data/lib/tcp_socket_extension.rb +32 -0
- data/vendor/selenium-server.jar +0 -0
- metadata +101 -0
@@ -0,0 +1,131 @@
|
|
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
|
+
|
9
|
+
$commands = []
|
10
|
+
|
11
|
+
attr_reader :session_id
|
12
|
+
|
13
|
+
def remote_control_command(verb, args=[])
|
14
|
+
timeout(@default_timeout_in_seconds) do
|
15
|
+
status, response = http_post(http_request_for(verb, args))
|
16
|
+
raise Selenium::CommandError, response unless status == "OK"
|
17
|
+
response[3..-1] # strip "OK," from response
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def string_command(verb, args=[])
|
22
|
+
remote_control_command(verb, args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def string_array_command(verb, args=[])
|
26
|
+
csv = string_command(verb, args)
|
27
|
+
token = ""
|
28
|
+
tokens = []
|
29
|
+
escape = false
|
30
|
+
csv.split(//).each do |letter|
|
31
|
+
if escape
|
32
|
+
token += letter
|
33
|
+
escape = false
|
34
|
+
next
|
35
|
+
end
|
36
|
+
case letter
|
37
|
+
when '\\'
|
38
|
+
escape = true
|
39
|
+
when ','
|
40
|
+
tokens << token
|
41
|
+
token = ""
|
42
|
+
else
|
43
|
+
token += letter
|
44
|
+
end
|
45
|
+
end
|
46
|
+
tokens << token
|
47
|
+
return tokens
|
48
|
+
end
|
49
|
+
|
50
|
+
def number_command(verb, args)
|
51
|
+
string_command verb, args
|
52
|
+
end
|
53
|
+
|
54
|
+
def number_array_command(verb, args)
|
55
|
+
string_array_command verb, args
|
56
|
+
end
|
57
|
+
|
58
|
+
def boolean_command(verb, args=[])
|
59
|
+
parse_boolean_value string_command(verb, args)
|
60
|
+
end
|
61
|
+
|
62
|
+
def boolean_array_command(verb, args)
|
63
|
+
string_array_command(verb, args).collect {|value| parse_boolean_value(value)}
|
64
|
+
end
|
65
|
+
|
66
|
+
protected
|
67
|
+
|
68
|
+
def parse_boolean_value(value)
|
69
|
+
if ("true" == value)
|
70
|
+
return true
|
71
|
+
elsif ("false" == value)
|
72
|
+
return false
|
73
|
+
end
|
74
|
+
raise ProtocolError, "Invalid Selenese boolean value that is neither 'true' nor 'false': got '#{value}'"
|
75
|
+
end
|
76
|
+
|
77
|
+
def http_request_for(verb, args)
|
78
|
+
data = "cmd=#{CGI::escape(verb)}"
|
79
|
+
args.each_with_index do |arg, index|
|
80
|
+
data << "&#{index.succ}=#{CGI::escape(arg.to_s)}"
|
81
|
+
end
|
82
|
+
data << "&sessionId=#{session_id}" unless session_id.nil?
|
83
|
+
data
|
84
|
+
end
|
85
|
+
|
86
|
+
def http_post(data)
|
87
|
+
dummy_data = data
|
88
|
+
start = Time.now
|
89
|
+
called_from = caller.detect{|line| line !~ /(selenium-client|vendor|usr\/lib\/ruby|\(eval\))/i}
|
90
|
+
http = Net::HTTP.new(@host, @port)
|
91
|
+
http.open_timeout = default_timeout_in_seconds
|
92
|
+
http.read_timeout = default_timeout_in_seconds
|
93
|
+
response = http.post('/selenium-server/driver/', data, HTTP_HEADERS)
|
94
|
+
if response.body !~ /^OK/
|
95
|
+
puts "#{start} selenium-client received failure from selenium server:"
|
96
|
+
puts "requested:"
|
97
|
+
puts "\t" + CGI::unescape(data.split('&').join("\n\t"))
|
98
|
+
puts "received:"
|
99
|
+
puts "\t#{response.body.inspect}"
|
100
|
+
puts "\tcalled from #{called_from}"
|
101
|
+
end
|
102
|
+
cmd = []
|
103
|
+
dummy_data = "" if dummy_data.include?("getNewBrowserSession")
|
104
|
+
if dummy_data != ""
|
105
|
+
command = dummy_data.split('&')
|
106
|
+
command.delete_if{|str| str.include?("sessionId")}
|
107
|
+
command.collect{|str|
|
108
|
+
cmd << str.gsub!("cmd=","") if str.include?("cmd=")
|
109
|
+
cmd << CGI::unescape(str.gsub!("1=",""))if str.include?("1=")
|
110
|
+
cmd << CGI::unescape(str.gsub!("2=","")) if str.include?("2=")
|
111
|
+
}
|
112
|
+
$commands << cmd
|
113
|
+
end
|
114
|
+
[ response.body[0..1], response.body ]
|
115
|
+
end
|
116
|
+
|
117
|
+
def selenese_script
|
118
|
+
|
119
|
+
selenese_commands = ""
|
120
|
+
$commands.collect do |command|
|
121
|
+
selenese_commands << "<tr><td>#{command[0]}</td><td>#{command[1]}</td><td>#{command[2]}</td></tr>"
|
122
|
+
end
|
123
|
+
|
124
|
+
script = '<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head profile="http://selenium-ide.openqa.org/profiles/test-case"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><link rel="selenium.base" href="http://www.google.co.in/" /><title>myscript<title></head><body><table cellpadding="1" cellspacing="1" border="1"><thead><tr><td rowspan="1" colspan="3">myscript</td></tr></thead><tbody>'+selenese_commands+'</tbody></table></body></html>'
|
125
|
+
return script
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,36 @@
|
|
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
|
+
puts "Inside Help Open"
|
13
|
+
@selenium.open url
|
14
|
+
end
|
15
|
+
|
16
|
+
# Overrides default type method to actually delegates to @selenium
|
17
|
+
def type(locator, value)
|
18
|
+
puts "Inside Help type"
|
19
|
+
@selenium.type locator, value
|
20
|
+
end
|
21
|
+
|
22
|
+
# Overrides default select method to actually delegates to @selenium
|
23
|
+
def select(input_locator, option_locator)
|
24
|
+
@selenium.select input_locator, option_locator
|
25
|
+
end
|
26
|
+
|
27
|
+
# Delegates to @selenium on method missing
|
28
|
+
def method_missing(method_name, *args)
|
29
|
+
return super unless @selenium.respond_to?(method_name)
|
30
|
+
|
31
|
+
@selenium.send(method_name, *args)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,16 @@
|
|
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.wait_until_up_and_running = true
|
7
|
+
rc.additional_args << "-singleWindow"
|
8
|
+
end
|
9
|
+
|
10
|
+
Selenium::Rake::RemoteControlStopTask.new
|
11
|
+
|
12
|
+
desc "Restart Selenium Remote Control"
|
13
|
+
task :'selenium:rc:restart' do
|
14
|
+
Rake::Task[:'selenium:rc:stop'].execute [] rescue nil
|
15
|
+
Rake::Task[:'selenium:rc:start'].execute []
|
16
|
+
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 :host, :port, :timeout_in_seconds, :background,
|
27
|
+
:wait_until_up_and_running, :additional_args,
|
28
|
+
:log_to
|
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
|
+
@host = "localhost"
|
36
|
+
@port = 4444
|
37
|
+
@timeout_in_seconds = 5
|
38
|
+
project_specific_jar = Dir[JAR_FILE_PATTERN].first
|
39
|
+
@jar_file = project_specific_jar
|
40
|
+
@additional_args = []
|
41
|
+
@background = 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
|
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]}
|
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,123 @@
|
|
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
|
+
|
28
|
+
html = ""
|
29
|
+
if File.exists? @file_path_strategy.file_path_for_html_capture(example)
|
30
|
+
html << toggable_section(dom_id, :id => "snapshot", :url=> snapshot_url, :name => "Dynamic HTML Snapshot")
|
31
|
+
end
|
32
|
+
if File.exists? @file_path_strategy.file_path_for_remote_control_logs(example)
|
33
|
+
html << toggable_section(dom_id, :id => "rc_logs", :url=> remote_control_logs_url, :name => "Remote Control Logs")
|
34
|
+
end
|
35
|
+
if File.exists? @file_path_strategy.file_path_for_page_screenshot(example)
|
36
|
+
html << toggable_image_section(dom_id, :id => "page_screenshot", :name => "Page Screenshot", :url => page_screenshot_url)
|
37
|
+
end
|
38
|
+
if File.exists? @file_path_strategy.file_path_for_system_screenshot(example)
|
39
|
+
html << toggable_image_section(dom_id, :id => "system_screenshot", :name => "System Screenshot", :url => system_screenshot_url)
|
40
|
+
end
|
41
|
+
|
42
|
+
return html
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.append_javascript(global_scripts)
|
46
|
+
global_scripts + <<-EOF
|
47
|
+
function toggleVisilibility(id, description) {
|
48
|
+
var section;
|
49
|
+
var link;
|
50
|
+
|
51
|
+
section = document.getElementById(id);
|
52
|
+
link = document.getElementById(id + "_link");
|
53
|
+
|
54
|
+
if (section.style.display == "block") {
|
55
|
+
section.style.display = "none"
|
56
|
+
link.innerHTML = "Show " + description
|
57
|
+
} else {
|
58
|
+
section.style.display = "block"
|
59
|
+
link.innerHTML = "Hide " + description
|
60
|
+
}
|
61
|
+
}
|
62
|
+
EOF
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.append_css(global_styles)
|
66
|
+
global_styles + <<-EOF
|
67
|
+
|
68
|
+
div.rspec-report textarea {
|
69
|
+
width: 100%;
|
70
|
+
}
|
71
|
+
|
72
|
+
div.rspec-report .dyn-source {
|
73
|
+
background: #FFFFEE none repeat scroll 0%;
|
74
|
+
border:1px dotted black;
|
75
|
+
color: #000000;
|
76
|
+
display: none;
|
77
|
+
margin: 0.5em 2em;
|
78
|
+
padding: 0.5em;
|
79
|
+
}
|
80
|
+
|
81
|
+
EOF
|
82
|
+
end
|
83
|
+
|
84
|
+
def toggable_section(dom_id, options)
|
85
|
+
<<-EOS
|
86
|
+
|
87
|
+
<div>[
|
88
|
+
<a id="#{dom_id}_#{options[:id]}_link"
|
89
|
+
href=\"javascript:toggleVisilibility('#{dom_id}_#{options[:id]}', '#{options[:name]}')\">Show #{options[:name]}</a>
|
90
|
+
]</div>
|
91
|
+
<br/><br/>
|
92
|
+
<div id="#{dom_id}_#{options[:id]}" class="dyn-source">
|
93
|
+
<a href="#{options[:url]}">Full screen</a><br/><br/>
|
94
|
+
<iframe src="#{options[:url]}" width="100%" height="600px" ></iframe>
|
95
|
+
</div>
|
96
|
+
|
97
|
+
EOS
|
98
|
+
end
|
99
|
+
|
100
|
+
def toggable_image_section(dom_id, options)
|
101
|
+
<<-EOS
|
102
|
+
|
103
|
+
<div>[<a id="#{dom_id}_#{options[:id]}_link" href="javascript:toggleVisilibility('#{dom_id}_#{options[:id]}', '#{options[:name]}');">Show #{options[:name]}</a>]</div>
|
104
|
+
<br/>
|
105
|
+
<div id="#{dom_id}_#{options[:id]}" style="display: none">
|
106
|
+
<a href="#{options[:url]}">
|
107
|
+
<img width="80%" src="#{options[:url]}" />
|
108
|
+
</a>
|
109
|
+
</div>
|
110
|
+
<br/>
|
111
|
+
|
112
|
+
EOS
|
113
|
+
end
|
114
|
+
|
115
|
+
def report_header
|
116
|
+
super + "\n<script type=\"text/javascript\">moveProgressBar('100.0');</script>"
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|