gondola 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +19 -0
- data/README.markdown +0 -0
- data/Rakefile +0 -0
- data/bin/gondola +132 -0
- data/examples/config.yml +11 -0
- data/examples/gondola_agora_fail.html +97 -0
- data/examples/gondola_agora_pass.html +97 -0
- data/lib/converter.rb +214 -0
- data/lib/tester.rb +92 -0
- metadata +85 -0
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 )
|
data/examples/config.yml
ADDED
@@ -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
|
+
|