gondola 1.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2011-2012 Agora Games
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.markdown ADDED
File without changes
data/Rakefile ADDED
File without changes
data/bin/gondola ADDED
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Gondola v2
4
+ # FILE: gondola
5
+ # AUTHOR: Matthew Perry
6
+ # DESCRIPTION:
7
+ # Main executable file which will dish out projects in parallel
8
+ # after converting them as needed
9
+
10
+ require 'rubygems'
11
+ require 'yaml'
12
+ require 'cmdparse'
13
+ require 'parallel'
14
+ require 'sauce'
15
+
16
+ lib_dir = File.expand_path( File.join( File.dirname( __FILE__ ), '..', 'lib/' ) )
17
+ $LOAD_PATH.unshift( lib_dir ) unless $LOAD_PATH.include?( lib_dir )
18
+
19
+ require 'converter.rb'
20
+ require 'tester.rb'
21
+
22
+ # Function to configure sauce labs' gem with proper api information
23
+ # as well as populate the configuration for the specific test being run
24
+ def configure( file )
25
+ # Load possible paths for the api information (Sauce already does this to some extent
26
+ # but more paths were required for this gem
27
+ api = {}
28
+ apiPaths = [
29
+ "ondemand.yml",
30
+ File.expand_path( "../ondemand.yml", __FILE__ ),
31
+ File.expand_path( File.join( File.dirname( file ), "ondemand.yml" ) ),
32
+ File.expand_path( File.join( File.dirname( file ), "../ondemand.yml" ) ),
33
+ File.expand_path( File.join( file, "ondemand.yml" ) ),
34
+ File.expand_path( File.join( file, "../ondemand.yml" ) ),
35
+ ]
36
+ apiPaths.each do |path|
37
+ if File.exists?( path )
38
+ api = YAML.load_file( path )
39
+ break
40
+ end
41
+ end
42
+
43
+ # Load possible paths for the configuration information
44
+ conf = {}
45
+ configPaths = [
46
+ "config.yml",
47
+ File.expand_path( "../config.yml", __FILE__ ),
48
+ File.expand_path( File.join( File.dirname( file ), "config.yml" ) ),
49
+ File.expand_path( File.join( File.dirname( file ), "../config.yml" ) ),
50
+ File.expand_path( File.join( file, "config.yml" ) ),
51
+ File.expand_path( File.join( file, "../config.yml" ) ),
52
+ ]
53
+ configPaths.each do |path|
54
+ if File.exists?( path )
55
+ conf.merge! YAML.load_file( path )
56
+ end
57
+ end
58
+
59
+ # Configure Sauce accordingly
60
+ Sauce.config do |config|
61
+ config.username = api["username"]
62
+ config.access_key = api["access_key"]
63
+ config.browser_url = conf["base_url"]
64
+ config.browsers = conf["browsers"]
65
+ config.job_name = conf["project_name"]
66
+ end
67
+ end
68
+
69
+ # Function to run and parallelize the given test on the given browsers
70
+ def run( file, browsers )
71
+ # Initialize a converter object
72
+ converter = Gondola::Converter.new( file )
73
+ # Spawn n threads
74
+ Parallel.map( browsers, :in_threads => browsers.size ) do |browser|
75
+ os,browser,version = browser
76
+ name = converter.name
77
+ if Sauce.get_config.job_name
78
+ name = "#{Sauce.get_config.job_name} - #{name}"
79
+ end
80
+ # Request a new selenium object from Sauce
81
+ selenium = Sauce::Selenium.new({:os => os, :browser => browser, :browser_version => version,
82
+ :job_name => name })
83
+ # Begin test using a tester object
84
+ tester = Gondola::Tester.new( selenium, converter )
85
+ puts "Starting test case \"#{file}\" with: #{os} #{browser} #{version}"
86
+ tester.begin
87
+ puts "#{file} finished - Sauce Job ID: #{tester.job_id}"
88
+ end
89
+ puts
90
+ end
91
+
92
+ # Command parsing stuff
93
+ cmd = CmdParse::CommandParser.new( true, true )
94
+ cmd.program_name = "gondola "
95
+ cmd.add_command( CmdParse::HelpCommand.new )
96
+
97
+ # Run command
98
+ class RunCommand < CmdParse::Command
99
+ def usage
100
+ "Usage: #{commandparser.program_name}run PATH [CONFIG]"
101
+ end
102
+ end
103
+ run = RunCommand.new( 'run', false )
104
+ run.short_desc = "Run an entire test suite or one test case"
105
+ run.set_execution_block do |args|
106
+ if args.length < 1
107
+ puts run.usage
108
+ exit 1
109
+ end
110
+ test = args[0]
111
+ # Can either provide directory or file
112
+ if File.directory?( test )
113
+ puts "Running test suite \"#{test}\""
114
+ configure( test )
115
+ Dir.chdir( test )
116
+ dirlist = Dir.glob( "*.html" )
117
+ dirlist.each do |file|
118
+ run( file, Sauce.get_config.browsers )
119
+ end
120
+ elsif File.exists?( test )
121
+ puts "Running test case \"#{test}\""
122
+ configure( test )
123
+ run( test, Sauce.get_config.browsers )
124
+ else
125
+ puts "Could not find file \"#{test}\""
126
+ end
127
+ end
128
+ cmd.add_command( run )
129
+
130
+ cmd.parse
131
+
132
+ exit( 0 )
@@ -0,0 +1,11 @@
1
+ project_name: "Test Project"
2
+ base_url: "http://www.google.com"
3
+ browsers:
4
+ -
5
+ - "Windows 2003"
6
+ - "firefox"
7
+ - "3.6"
8
+ -
9
+ - "Windows 2003"
10
+ - "iexplore"
11
+ - "8"
@@ -0,0 +1,97 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head profile="http://selenium-ide.openqa.org/profiles/test-case">
5
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6
+ <link rel="selenium.base" href="http://www.google.com/" />
7
+ <title>gondola_agora</title>
8
+ </head>
9
+ <body>
10
+ <table cellpadding="1" cellspacing="1" border="1">
11
+ <thead>
12
+ <tr><td rowspan="1" colspan="3">gondola_agora_fail</td></tr>
13
+ </thead><tbody>
14
+ <tr>
15
+ <td>open</td>
16
+ <td>/</td>
17
+ <td></td>
18
+ </tr>
19
+ <tr>
20
+ <td>type</td>
21
+ <td>q</td>
22
+ <td>agora games</td>
23
+ </tr>
24
+ <tr>
25
+ <td>click</td>
26
+ <td>btnG</td>
27
+ <td></td>
28
+ </tr>
29
+ <tr>
30
+ <td>clickAndWait</td>
31
+ <td>link=Careers</td>
32
+ <td></td>
33
+ </tr>
34
+ <tr>
35
+ <td>verifyTitle</td>
36
+ <td>Agora Games</td>
37
+ <td></td>
38
+ </tr>
39
+ <tr>
40
+ <td>verifyTextPresent</td>
41
+ <td>At Agora</td>
42
+ <td></td>
43
+ </tr>
44
+ <tr>
45
+ <td>assertTextPresent</td>
46
+ <td>Platform Engineer</td>
47
+ <td></td>
48
+ </tr>
49
+ <tr>
50
+ <td>click</td>
51
+ <td>link=Application Engineer</td>
52
+ <td></td>
53
+ </tr>
54
+ <tr>
55
+ <td>assertTextPresent</td>
56
+ <td>Application Engineer</td>
57
+ <td></td>
58
+ </tr>
59
+ <tr>
60
+ <td>click</td>
61
+ <td>link=Producer</td>
62
+ <td></td>
63
+ </tr>
64
+ <tr>
65
+ <td>assertTextPresent</td>
66
+ <td>Producer FAIL</td>
67
+ <td></td>
68
+ </tr>
69
+ <tr>
70
+ <td>clickAndWait</td>
71
+ <td>link=work at Agora.</td>
72
+ <td></td>
73
+ </tr>
74
+ <tr>
75
+ <td>click</td>
76
+ <td>link=Fun at Agora</td>
77
+ <td></td>
78
+ </tr>
79
+ <tr>
80
+ <td>click</td>
81
+ <td>link=Hack-a-thon</td>
82
+ <td></td>
83
+ </tr>
84
+ <tr>
85
+ <td>click</td>
86
+ <td>link=Our Town</td>
87
+ <td></td>
88
+ </tr>
89
+ <tr>
90
+ <td>click</td>
91
+ <td>link=Communication at Agora</td>
92
+ <td></td>
93
+ </tr>
94
+
95
+ </tbody></table>
96
+ </body>
97
+ </html>
@@ -0,0 +1,97 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head profile="http://selenium-ide.openqa.org/profiles/test-case">
5
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6
+ <link rel="selenium.base" href="http://www.google.com/" />
7
+ <title>gondola_agora</title>
8
+ </head>
9
+ <body>
10
+ <table cellpadding="1" cellspacing="1" border="1">
11
+ <thead>
12
+ <tr><td rowspan="1" colspan="3">gondola_agora_pass</td></tr>
13
+ </thead><tbody>
14
+ <tr>
15
+ <td>open</td>
16
+ <td>/</td>
17
+ <td></td>
18
+ </tr>
19
+ <tr>
20
+ <td>type</td>
21
+ <td>q</td>
22
+ <td>agora games</td>
23
+ </tr>
24
+ <tr>
25
+ <td>click</td>
26
+ <td>btnG</td>
27
+ <td></td>
28
+ </tr>
29
+ <tr>
30
+ <td>clickAndWait</td>
31
+ <td>link=Careers</td>
32
+ <td></td>
33
+ </tr>
34
+ <tr>
35
+ <td>verifyTitle</td>
36
+ <td>Agora Games</td>
37
+ <td></td>
38
+ </tr>
39
+ <tr>
40
+ <td>verifyTextPresent</td>
41
+ <td>At Agora</td>
42
+ <td></td>
43
+ </tr>
44
+ <tr>
45
+ <td>assertTextPresent</td>
46
+ <td>Platform Engineer</td>
47
+ <td></td>
48
+ </tr>
49
+ <tr>
50
+ <td>click</td>
51
+ <td>link=Application Engineer</td>
52
+ <td></td>
53
+ </tr>
54
+ <tr>
55
+ <td>assertTextPresent</td>
56
+ <td>Application Engineer</td>
57
+ <td></td>
58
+ </tr>
59
+ <tr>
60
+ <td>click</td>
61
+ <td>link=Producer</td>
62
+ <td></td>
63
+ </tr>
64
+ <tr>
65
+ <td>assertTextPresent</td>
66
+ <td>Producer</td>
67
+ <td></td>
68
+ </tr>
69
+ <tr>
70
+ <td>clickAndWait</td>
71
+ <td>link=work at Agora.</td>
72
+ <td></td>
73
+ </tr>
74
+ <tr>
75
+ <td>click</td>
76
+ <td>link=Fun at Agora</td>
77
+ <td></td>
78
+ </tr>
79
+ <tr>
80
+ <td>click</td>
81
+ <td>link=Hack-a-thon</td>
82
+ <td></td>
83
+ </tr>
84
+ <tr>
85
+ <td>click</td>
86
+ <td>link=Our Town</td>
87
+ <td></td>
88
+ </tr>
89
+ <tr>
90
+ <td>click</td>
91
+ <td>link=Communication at Agora</td>
92
+ <td></td>
93
+ </tr>
94
+
95
+ </tbody></table>
96
+ </body>
97
+ </html>
data/lib/converter.rb ADDED
@@ -0,0 +1,214 @@
1
+ # Gondola v2
2
+ # FILE: converter.rb
3
+ # AUTHOR: Matthew Perry
4
+ # DESCRIPTION:
5
+ # Function definition for turning Selenium HTML into
6
+ # webdriver ruby code
7
+
8
+ module Gondola
9
+ class Converter
10
+ attr_writer :sObject
11
+
12
+ # Constructor that opens an HTML file
13
+ def initialize( filename, sel="@sel" )
14
+ File.open( filename, "r" ) do |f|
15
+ @html = f.read
16
+ end
17
+ @sObject = sel
18
+ ruby()
19
+ end
20
+
21
+ # Function: name
22
+ # Returns the name of this test case
23
+ def name
24
+ unless @name
25
+ @name = /<title>(.*)<\/title>/.match( @html )[1]
26
+ end
27
+ @name
28
+ end
29
+
30
+ # Function: ruby
31
+ # This function parses the selenium
32
+ # HTML file and sends commands to the
33
+ # htmltoruby helper function
34
+ def ruby
35
+ unless @ruby
36
+ @ruby = ""
37
+ # Get body of commands from flattened html
38
+ cmdBody = /<tbody>(.*)<\/tbody>/.match( @html.split("\n").join('') )[1]
39
+
40
+ # Define some patterns for the individual commands
41
+ blockRxp = Regexp.new( /<tr>(.*?)<\/tr>/ )
42
+ cmdRxp = Regexp.new( /<td>(.*?)<\/td>\s*<td>(.*?)<\/td>\s*<td>(.*?)<\/td>/ )
43
+
44
+ # Loop over all commands
45
+ cmdBody.scan( blockRxp ) do |cmdBlock|
46
+ cmdBlock[0].scan( cmdRxp ) do |cmd|
47
+ # Need to make sure arguements are represented
48
+ # correctly
49
+ if cmd[1] =~ /\$\{(.*)\}/
50
+ cmd[1] = $1
51
+ elsif cmd[1] != ""
52
+ cmd[1] = cmd[1].inspect
53
+ end
54
+ if cmd[2] =~ /\$\{(.*)\}/
55
+ cmd[2] = $1
56
+ elsif cmd[2] != ""
57
+ cmd[2] = cmd[2].inspect
58
+ end
59
+ # Append commands to a result string
60
+ args = [ cmd[1], cmd[2] ]
61
+ @ruby << htmltoruby( cmd[0], args )
62
+ @ruby << "\ncmdInc\n"
63
+ end
64
+ end
65
+ end
66
+ @ruby
67
+ end
68
+
69
+ private
70
+ # Function: htmltoruby
71
+ # cmd - the name of the command
72
+ # args - array of arguements to cmd
73
+ # This function turns a command that has been
74
+ # extracted from a selenium HTML file into
75
+ # one that can be used by the ruby-driver for
76
+ # selenium
77
+ def htmltoruby( cmd, args )
78
+ # Select over various command types
79
+ case cmd
80
+ # Assert command
81
+ when /^(assert|verify)(.*)$/ then
82
+ # Check to see if this is a negated assertion
83
+ tester = $1
84
+ string = $2
85
+ if $1 =~ /(.*)Not(.*)$/
86
+ string = $1 + $2
87
+ tester = tester + "Not"
88
+ end
89
+
90
+ # Check the symantics of the command
91
+ if commandIs( string )
92
+ retval = "#{tester} #{@sObject}.is_#{underscore(string)}"
93
+ if args[0] != ""
94
+ retval += "(#{args[0]}"
95
+ end
96
+ if args[1] != ""
97
+ retval += ", #{args[1]}"
98
+ end
99
+ retval += ")"
100
+ else
101
+ var = args[0]
102
+ extra = ''
103
+ if args[1] != ""
104
+ var = args[1]
105
+ extra = "(#{args[0]})"
106
+ end
107
+ retval = "#{tester}Eq #{var}, #{@sObject}.get_#{underscore(string)}" + extra
108
+ end
109
+
110
+ # All commands return arrays that need to be joined
111
+ if string =~ /^All/
112
+ retval += ".join(\",\")"
113
+ end
114
+ return retval
115
+
116
+ # Wait For command
117
+ when /^waitFor(.*)$/ then
118
+ # The expression that is checked against depends on whether
119
+ # or not the command uses the "is" or the "get" symantic
120
+ if commandIs( $1 )
121
+ expression = "#{@sObject}.is_#{underscore($1)}(#{args[0]}"
122
+ if args[1] != ""
123
+ expression += ", #{args[1]}"
124
+ end
125
+ expression += ")"
126
+ else
127
+ expression = "#{args[1]} == #{@sObject}.get_#{underscore($1)}(#{args[1]})"
128
+ end
129
+ # The waitFor commands loop until something is satisfied
130
+ return "assert !60.times{ break if(#{expression} rescue false); sleep 1 }"
131
+
132
+ # AndWait command POSTFIX
133
+ when /^(.*)AndWait$/ then
134
+ # A command with a postfix of AndWait simply adds
135
+ # a second command which waits a certain time
136
+ firstPart = htmltoruby( $1, args )
137
+ secondPart = "\n#{@sObject}.wait_for_page_to_load \"30000\""
138
+ return firstPart + secondPart
139
+
140
+ # store command
141
+ when /^store(.*)$/ then
142
+ string = $1
143
+ # Store by itself doesnt use any selenium functions
144
+ # its the same as a regular assignment
145
+ if $1 == ""
146
+ # Arguements have quotes by default
147
+ # they need to be stripped for LHS assignments
148
+ args[1] = args[1].match( /"(.*)"/ )[1]
149
+ return "#{args[1]} = #{args[0]}"
150
+ end
151
+
152
+ # Otherwise, a store command takes the result of the
153
+ # cmd and stores it somewhere
154
+ var = args[0]
155
+ extra = ""
156
+ if args[1] != ""
157
+ var = args[1]
158
+ extra = "( #{args[0]} )"
159
+ end
160
+ # Arguements have quotes by default
161
+ # they need to be stripped for LHS assignments
162
+ var = var.match( /"(.*)"/ )[1]
163
+ if commandIs( string )
164
+ return "#{var} = #{@sObject}.is_#{underscore(string)}" + extra
165
+ else
166
+ return "#{var} = #{@sObject}.get_#{underscore(string)}" + extra
167
+ end
168
+
169
+ # Pause is directly translated
170
+ when /^pause$/ then
171
+ convert = args[0].to_f * 0.001
172
+ return "sleep #{convert}"
173
+
174
+ # Default case
175
+ else
176
+ # Most commands just need to be converted to
177
+ # underscore_case and have their arguements
178
+ # appeneded
179
+ cmdNew = underscore( cmd )
180
+ add = ""
181
+ if args[1] != ""
182
+ add = ", #{args[1]}"
183
+ end
184
+ return "#{@sObject}.#{cmdNew} #{args[0]}" + add
185
+ end
186
+ end
187
+
188
+ # Function to turn CamelCase into underscore_case
189
+ def underscore( str )
190
+ str.gsub(/(.)([A-Z])/,'\1_\2').downcase
191
+ end
192
+
193
+ # Function to weed out 11 special functions that
194
+ # use an "is" symantic
195
+ def commandIs( str )
196
+ case str
197
+ when /Present$/
198
+ return true
199
+ when /Checked$/
200
+ return true
201
+ when /Editable$/
202
+ return true
203
+ when /Ordered$/
204
+ return true
205
+ when /Selected$/
206
+ return true
207
+ when /Visible$/
208
+ return true
209
+ else
210
+ return false
211
+ end
212
+ end
213
+ end
214
+ end
data/lib/tester.rb ADDED
@@ -0,0 +1,92 @@
1
+ # Gondola v2
2
+ # FILE: tester.rb
3
+ # AUTHOR: Matthew Perry
4
+ # DESCRIPTION:
5
+ # Module which contains all the necessary functions
6
+ # for asserting and verifying various functions without
7
+ # the need for a unit testing framework
8
+
9
+ module Gondola
10
+ class Tester
11
+ attr_reader :cmdNum, :sel, :converter, :job_id
12
+
13
+ class AssertionFailed < StandardError
14
+ end
15
+
16
+ def initialize( sel, converter )
17
+ @sel = sel
18
+ @converter = converter
19
+ @cmdNum = 1
20
+ end
21
+
22
+ def begin
23
+ @sel.start()
24
+ @job_id = @sel.session_id
25
+ begin
26
+ eval( @converter.ruby )
27
+ rescue AssertionFailed
28
+ end
29
+ @sel.stop()
30
+ end
31
+
32
+ def cmdInc
33
+ @cmdNum+=1
34
+ end
35
+
36
+ def assert( expr )
37
+ unless verify( expr )
38
+ raise AssertionFailed
39
+ end
40
+ end
41
+
42
+ def assertNot( expr )
43
+ unless verifyNot( expr )
44
+ raise AssertionFailed
45
+ end
46
+ end
47
+
48
+ def assertEq( eq, expr )
49
+ unless verify( eq, expr )
50
+ raise AssertionFailed
51
+ end
52
+ end
53
+
54
+ def assertNotEq( eq, expr )
55
+ unless verifyNot( eq, expr )
56
+ raise AssertionFailed
57
+ end
58
+ end
59
+
60
+ def verify( expr )
61
+ unless expr
62
+ $stderr.puts "Command #{@cmdNum} returned false, expecting true"
63
+ return false
64
+ end
65
+ return true
66
+ end
67
+
68
+ def verifyNot( expr )
69
+ if expr
70
+ $stderr.puts "Command #{@cmdNum} returned true, expecting false"
71
+ return false
72
+ end
73
+ return true
74
+ end
75
+
76
+ def verifyEq( eq, expr )
77
+ unless eq == expr
78
+ @stderr.puts "Command #{@cmdNum} returned '#{expr}', expecting '#{eq}'"
79
+ return false
80
+ end
81
+ return true
82
+ end
83
+
84
+ def verifyNotEq( eq, expr )
85
+ if eq == expr
86
+ @stderr.puts "Command #{@cmdNum} returned '#{expr}', expecting '#{eq}'"
87
+ return false
88
+ end
89
+ return true
90
+ end
91
+ end
92
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gondola
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ version: "1.0"
9
+ platform: ruby
10
+ authors:
11
+ - Matthew Perry
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+
16
+ date: 2011-03-03 00:00:00 -05:00
17
+ default_executable:
18
+ dependencies:
19
+ - !ruby/object:Gem::Dependency
20
+ name: sauce
21
+ prerelease: false
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ - 17
30
+ - 6
31
+ version: 0.17.6
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ description: " Gondola is Ruby command line utility and as well as a library which helps\n for integrate the Selenium IDE more tightly with Sauce Labs' Ondemand services and\n provide greater ease for those who would like to use both tools but do not have\n enough technical knowledge\n"
35
+ email: mperry@agoragames.com
36
+ executables:
37
+ - gondola
38
+ extensions: []
39
+
40
+ extra_rdoc_files: []
41
+
42
+ files:
43
+ - LICENSE
44
+ - README.markdown
45
+ - Rakefile
46
+ - bin/gondola
47
+ - examples/config.yml
48
+ - examples/gondola_agora_fail.html
49
+ - examples/gondola_agora_pass.html
50
+ - lib/converter.rb
51
+ - lib/tester.rb
52
+ has_rdoc: true
53
+ homepage: https://github.com/perrym5/Gondola_Gem
54
+ licenses: []
55
+
56
+ post_install_message:
57
+ rdoc_options: []
58
+
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ segments:
67
+ - 0
68
+ version: "0"
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ requirements: []
78
+
79
+ rubyforge_project:
80
+ rubygems_version: 1.3.7
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: Ruby command line utility and library for integrating the Selenium IDE more tightly with Sauce Labs' Ondemand services
84
+ test_files: []
85
+