browser_shooter 0.3.3 → 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +61 -10
- data/examples/config0.yml +2 -2
- data/examples/config1.yml +2 -2
- data/examples/config2.yml +6 -6
- data/examples/config3_debug.yml +23 -0
- data/examples/extension0.rb +13 -0
- data/lib/browser_shooter/commander.rb +20 -117
- data/lib/browser_shooter/commands/base.rb +17 -0
- data/lib/browser_shooter/commands/basics.rb +30 -0
- data/lib/browser_shooter/commands/debug.rb +22 -0
- data/lib/browser_shooter/commands/screenshots.rb +38 -0
- data/lib/browser_shooter/configurator.rb +14 -5
- data/lib/browser_shooter/utils.rb +7 -0
- data/lib/browser_shooter/version.rb +1 -1
- data/lib/browser_shooter.rb +5 -0
- data/test/base_test.rb +1 -1
- data/test/commander_test.rb +25 -126
- data/test/commands/basics_test.rb +49 -0
- data/test/commands/screenshots_test.rb +64 -0
- data/test/configurator_test.rb +18 -5
- data/test/fixtures/config.yml +3 -0
- data/test/fixtures/config_simple.yml +0 -1
- metadata +23 -12
data/README.md
CHANGED
@@ -38,18 +38,21 @@ Create a YAML file like this:
|
|
38
38
|
|
39
39
|
# myconfig.yml
|
40
40
|
output_path: "/tmp/shoots"
|
41
|
+
extensions:
|
42
|
+
- ~/browser_shooter/my_extension_1.rb
|
43
|
+
- ~/browser_shooter/my_extension_2.rb
|
41
44
|
|
42
45
|
tests:
|
43
46
|
google: |
|
44
47
|
navigate.to "http://www.google.de"
|
45
|
-
shot before
|
48
|
+
shot "before"
|
46
49
|
type "input[name='q']", "beautiful houses"
|
47
50
|
click "input[name='btnG']"
|
48
51
|
pause 3
|
49
52
|
click "a.kls"
|
50
53
|
pause 3
|
51
|
-
shot after
|
52
|
-
shot_system final_shot
|
54
|
+
shot "after"
|
55
|
+
shot_system "final_shot"
|
53
56
|
|
54
57
|
miniclip: |
|
55
58
|
navigate.to "http://www.miniclip.com/games/de/"
|
@@ -86,17 +89,65 @@ Look in the [examples folder](https://github.com/fguillen/BrowserShooter/tree/ma
|
|
86
89
|
|
87
90
|
##### Tests section
|
88
91
|
|
89
|
-
|
92
|
+
###### WebDriver commands
|
90
93
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
94
|
+
You can use any command from the [WebDriver API](http://selenium.googlecode.com/svn/trunk/docs/api/rb/index.html).
|
95
|
+
|
96
|
+
Any command you can call from a `driver` instance like:
|
97
|
+
|
98
|
+
driver.navigate.to "http://google.com"
|
99
|
+
|
100
|
+
You can use in the _test section_ just removing the `driver` word:
|
101
|
+
|
102
|
+
navigate.to "http://google.com"
|
103
|
+
|
104
|
+
###### Extended Commands
|
105
|
+
|
106
|
+
Also you can use this list of _extended commands_:
|
107
|
+
|
108
|
+
* **shot** receives an optional param with the 'sufix' of the page screenshot png
|
109
|
+
* **shot_system** equal to 'shot' but uses the "VirtualBox" system command "VBoxManage" to make an screenshot of the OS screen.
|
110
|
+
* **pause** uses a Ruby 'sleep' command to pause
|
111
|
+
* **click** receives a 'css_selector' as a param, find the element and click on it
|
112
|
+
* **type** receives two params: 'css_selector' ana a 'message', find the element and type the message on it
|
113
|
+
* **wait_for_element** receives two params: 'css_selector', and a 'timeout' in seconds
|
114
|
+
* **try** receives an string wich is Ruby code, you have access here to variables like `driver`, `browser` and `output_path`.
|
115
|
+
* **debug** receives no argument. When the test arrives to this command a Ruby console will be open and you will be able to write Ruby commands on the air. Until you write `exit`.
|
97
116
|
|
98
117
|
You can define as much tests as you want. Every test is composed by a list of **one line** commands.
|
99
118
|
|
119
|
+
###### Custom Extended Commands
|
120
|
+
|
121
|
+
If you need to add new commands to the _test section_ you can implement your own ones.
|
122
|
+
|
123
|
+
Write a file like this:
|
124
|
+
|
125
|
+
# my_extension.rb
|
126
|
+
module MyExtension
|
127
|
+
def log( arg1, arg2 )
|
128
|
+
puts "This is the log extension method"
|
129
|
+
puts "arg1: #{arg1}"
|
130
|
+
puts "arg2: #{arg2}"
|
131
|
+
puts "driver: #{driver}"
|
132
|
+
puts "browser: #{browser}"
|
133
|
+
puts "output_path: #{output_path}"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
BrowserShooter::Commands::Base.plug( MyExtension )
|
137
|
+
|
138
|
+
Declare this extension file in the _extensions section_:
|
139
|
+
|
140
|
+
# config.yml
|
141
|
+
extensions:
|
142
|
+
- path/to/my_extension.rb
|
143
|
+
|
144
|
+
Then you will be able to use this new command into the _test section_ like this:
|
145
|
+
|
146
|
+
log "myarg1", "myarg2"
|
147
|
+
|
148
|
+
You can check the [custom extensions](https://github.com/fguillen/BrowserShooter/tree/master/lib/browser_shooter/commands) that are already integrated in BrowserShooter.
|
149
|
+
|
150
|
+
|
100
151
|
##### Browsers section
|
101
152
|
|
102
153
|
All the available browsers with the **selenium server url** and the **selenium browser type**.
|
data/examples/config0.yml
CHANGED
data/examples/config1.yml
CHANGED
@@ -3,13 +3,13 @@ output_path: "~/browser_shoots"
|
|
3
3
|
tests:
|
4
4
|
google: |
|
5
5
|
navigate.to "http://www.google.de"
|
6
|
-
shot before
|
6
|
+
shot "before"
|
7
7
|
type "input[name='q']", "beautiful houses"
|
8
8
|
click "input[name='btnG']"
|
9
9
|
pause 3
|
10
10
|
click "a.kls"
|
11
11
|
pause 3
|
12
|
-
shot after
|
12
|
+
shot "after"
|
13
13
|
|
14
14
|
miniclip: |
|
15
15
|
navigate.to "http://www.miniclip.com/games/de/"
|
data/examples/config2.yml
CHANGED
@@ -3,27 +3,27 @@ output_path: "~/browser_shooter"
|
|
3
3
|
tests:
|
4
4
|
lightbox: |
|
5
5
|
navigate.to "http://192.168.70.70/test/browser_shooter/lightbox_bareplayer.html"
|
6
|
-
shot 01_first
|
6
|
+
shot "01_first"
|
7
7
|
pause 5
|
8
8
|
switch_to.alert.accept
|
9
9
|
click "a"
|
10
10
|
pause 5
|
11
|
-
shot 02_video
|
11
|
+
shot "02_video"
|
12
12
|
switch_to.frame "_sp_wiframe"
|
13
13
|
execute_script "$f().play()"
|
14
14
|
pause 3
|
15
|
-
shot 03_video_start
|
15
|
+
shot "03_video_start"
|
16
16
|
wait_for_element "span.enabled", 40
|
17
|
-
shot 04_green_button
|
17
|
+
shot "04_green_button"
|
18
18
|
click "span.enabled"
|
19
19
|
pause 8
|
20
20
|
switch_to.alert.accept
|
21
|
-
shot 05_spinner
|
21
|
+
shot "05_spinner"
|
22
22
|
switch_to.default_content
|
23
23
|
click "#sp_close_x"
|
24
24
|
switch_to.alert.accept
|
25
25
|
pause 4
|
26
|
-
shot 06_hidden
|
26
|
+
shot "06_hidden"
|
27
27
|
|
28
28
|
browsers:
|
29
29
|
osx-chrome:
|
@@ -0,0 +1,23 @@
|
|
1
|
+
output_path: "~/browser_shoots"
|
2
|
+
extensions:
|
3
|
+
- "./examples/extension0.rb"
|
4
|
+
|
5
|
+
tests:
|
6
|
+
debug: |
|
7
|
+
log "argument1", "argument2"
|
8
|
+
try "puts driver.to_s"
|
9
|
+
debug
|
10
|
+
try "puts 'ending'"
|
11
|
+
|
12
|
+
browsers:
|
13
|
+
ios-chrome:
|
14
|
+
url: "http://127.0.0.1:4444/wd/hub"
|
15
|
+
type: "chrome"
|
16
|
+
vm: "My VM"
|
17
|
+
|
18
|
+
suites:
|
19
|
+
suite1:
|
20
|
+
tests:
|
21
|
+
- debug
|
22
|
+
browsers:
|
23
|
+
- ios-chrome
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Extension0
|
2
|
+
|
3
|
+
def log( arg1, arg2 )
|
4
|
+
puts "This is the log extension method"
|
5
|
+
puts "arg1: #{arg1}"
|
6
|
+
puts "arg2: #{arg2}"
|
7
|
+
puts "driver: #{driver}"
|
8
|
+
puts "browser: #{browser}"
|
9
|
+
puts "output_path: #{output_path}"
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
BrowserShooter::Commands::Base.plug( Extension0 )
|
@@ -1,14 +1,20 @@
|
|
1
1
|
module BrowserShooter::Commander
|
2
2
|
|
3
3
|
def self.script( commands, driver, browser, output_path )
|
4
|
+
|
5
|
+
command_executor =
|
6
|
+
BrowserShooter::Commands::Base.new(
|
7
|
+
driver,
|
8
|
+
browser,
|
9
|
+
output_path
|
10
|
+
)
|
11
|
+
|
4
12
|
test_result =
|
5
13
|
commands.map do |command|
|
6
14
|
command_result =
|
7
15
|
BrowserShooter::Commander.wrapper_execute(
|
8
|
-
|
9
|
-
|
10
|
-
browser,
|
11
|
-
output_path
|
16
|
+
command_executor,
|
17
|
+
command.strip
|
12
18
|
)
|
13
19
|
|
14
20
|
BrowserShooter::Logger.command_result( command_result )
|
@@ -21,63 +27,7 @@ module BrowserShooter::Commander
|
|
21
27
|
test_result
|
22
28
|
end
|
23
29
|
|
24
|
-
def self.
|
25
|
-
BrowserShooter::Logger.log "command: #{command}"
|
26
|
-
|
27
|
-
if( command.split[0].strip == "shot" )
|
28
|
-
sufix = command.split[1] ? command.split[1].strip : nil
|
29
|
-
|
30
|
-
BrowserShooter::Commander.shot(
|
31
|
-
driver,
|
32
|
-
output_path,
|
33
|
-
sufix
|
34
|
-
)
|
35
|
-
|
36
|
-
elsif( command.split[0].strip == "shot_system" )
|
37
|
-
sufix = command.split[1] ? command.split[1].strip : nil
|
38
|
-
|
39
|
-
BrowserShooter::Commander.shot_system(
|
40
|
-
driver,
|
41
|
-
browser,
|
42
|
-
output_path,
|
43
|
-
sufix
|
44
|
-
)
|
45
|
-
|
46
|
-
elsif( command.split[0].strip == "pause" )
|
47
|
-
BrowserShooter::Commander.pause( command.split[1].strip.to_i )
|
48
|
-
|
49
|
-
elsif( command.split[0].strip == "wait_for_element" )
|
50
|
-
params = command.match /wait_for_element "(.*)"\s?,\s?(\d*)/
|
51
|
-
|
52
|
-
BrowserShooter::Commander.wait_for_element(
|
53
|
-
driver,
|
54
|
-
params[1],
|
55
|
-
params[2].to_i
|
56
|
-
)
|
57
|
-
|
58
|
-
elsif( command.split[0].strip == "type" )
|
59
|
-
params = command.match /type "(.*)"\s?,\s?"(.*)"/
|
60
|
-
|
61
|
-
BrowserShooter::Commander.type(
|
62
|
-
driver,
|
63
|
-
params[1],
|
64
|
-
params[2]
|
65
|
-
)
|
66
|
-
|
67
|
-
elsif( command.split[0].strip == "click" )
|
68
|
-
params = command.match /click "(.*)"/
|
69
|
-
BrowserShooter::Commander.click(
|
70
|
-
driver,
|
71
|
-
params[1]
|
72
|
-
)
|
73
|
-
|
74
|
-
else
|
75
|
-
eval "driver.#{command}"
|
76
|
-
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def self.wrapper_execute( command, driver, browser, output_path )
|
30
|
+
def self.wrapper_execute( command_executor, command )
|
81
31
|
result = {
|
82
32
|
:time => Time.now.to_i,
|
83
33
|
:command => command
|
@@ -86,10 +36,8 @@ module BrowserShooter::Commander
|
|
86
36
|
begin
|
87
37
|
message =
|
88
38
|
BrowserShooter::Commander.execute(
|
89
|
-
|
90
|
-
|
91
|
-
browser,
|
92
|
-
output_path
|
39
|
+
command_executor,
|
40
|
+
command
|
93
41
|
)
|
94
42
|
|
95
43
|
|
@@ -114,60 +62,15 @@ module BrowserShooter::Commander
|
|
114
62
|
return result
|
115
63
|
end
|
116
64
|
|
117
|
-
def self.
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
BrowserShooter::Logger.log "shooting in '#{shot_path}'"
|
122
|
-
|
123
|
-
FileUtils.mkdir_p( File.dirname( shot_path ) )
|
124
|
-
driver.save_screenshot( shot_path )
|
125
|
-
|
126
|
-
return shot_path
|
127
|
-
end
|
128
|
-
|
129
|
-
def self.shot_system( driver, browser, output_path, sufix = nil )
|
130
|
-
sufix = timestamp unless sufix
|
131
|
-
shot_path = "#{output_path}/shots/#{sufix}.png"
|
132
|
-
|
133
|
-
BrowserShooter::Logger.log "shooting system in '#{shot_path}'"
|
134
|
-
|
135
|
-
FileUtils.mkdir_p( File.dirname( shot_path ) )
|
136
|
-
|
137
|
-
command = "VBoxManage controlvm '#{browser.vm}' screenshotpng '#{shot_path}'"
|
138
|
-
success = Kernel.system( command )
|
139
|
-
|
140
|
-
if( !success )
|
141
|
-
raise SystemCallError, "Shoot system command [#{command}] returns error: '#{$?}'"
|
142
|
-
end
|
143
|
-
|
144
|
-
return shot_path
|
145
|
-
end
|
146
|
-
|
147
|
-
def self.wait_for_element( driver, css_selector, timeout )
|
148
|
-
wait = Selenium::WebDriver::Wait.new( :timeout => timeout )
|
65
|
+
def self.execute( command_executor, command )
|
66
|
+
BrowserShooter::Logger.log "command: #{command}"
|
67
|
+
command_name = command.split( /[\s\(]/ )[0].strip
|
149
68
|
|
150
|
-
|
151
|
-
|
69
|
+
if( command_executor.respond_to?( command_name.to_sym ) )
|
70
|
+
eval "command_executor.#{command}"
|
71
|
+
else
|
72
|
+
eval "command_executor.driver.#{command}"
|
152
73
|
end
|
153
74
|
end
|
154
75
|
|
155
|
-
def self.click( driver, css_selector )
|
156
|
-
driver.find_element( "css", css_selector ).click
|
157
|
-
end
|
158
|
-
|
159
|
-
def self.type( driver, css_selector, text )
|
160
|
-
driver.find_element( "css", css_selector ).send_keys( text )
|
161
|
-
end
|
162
|
-
|
163
|
-
def self.pause( seconds )
|
164
|
-
BrowserShooter::Logger.log "pausing #{seconds} seconds"
|
165
|
-
Kernel.sleep seconds
|
166
|
-
|
167
|
-
return "#{seconds} seconds later..."
|
168
|
-
end
|
169
|
-
|
170
|
-
def self.timestamp
|
171
|
-
Time.now.to_i
|
172
|
-
end
|
173
76
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module BrowserShooter
|
2
|
+
module Commands
|
3
|
+
class Base
|
4
|
+
attr_reader :driver, :browser, :output_path
|
5
|
+
|
6
|
+
def initialize( driver, browser, output_path )
|
7
|
+
@driver = driver
|
8
|
+
@browser = browser
|
9
|
+
@output_path = output_path
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.plug( _module )
|
13
|
+
include( _module )
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module BrowserShooter
|
2
|
+
module Commands
|
3
|
+
module Basic
|
4
|
+
def wait_for_element( css_selector, timeout )
|
5
|
+
wait = Selenium::WebDriver::Wait.new( :timeout => timeout )
|
6
|
+
|
7
|
+
wait.until do
|
8
|
+
driver.find_element( "css", css_selector )
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def click( css_selector )
|
13
|
+
driver.find_element( "css", css_selector ).click
|
14
|
+
end
|
15
|
+
|
16
|
+
def type( css_selector, text )
|
17
|
+
driver.find_element( "css", css_selector ).send_keys( text )
|
18
|
+
end
|
19
|
+
|
20
|
+
def pause( seconds )
|
21
|
+
BrowserShooter::Logger.log "pausing #{seconds} seconds"
|
22
|
+
Kernel.sleep seconds
|
23
|
+
|
24
|
+
return "#{seconds} seconds later..."
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
BrowserShooter::Commands::Base.plug( BrowserShooter::Commands::Basic )
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module BrowserShooter
|
2
|
+
module Commands
|
3
|
+
module Debug
|
4
|
+
def try( ruby_code )
|
5
|
+
eval ruby_code
|
6
|
+
end
|
7
|
+
|
8
|
+
def debug
|
9
|
+
while( true )
|
10
|
+
print "BrowserShooter > "
|
11
|
+
line = STDIN.gets.chomp
|
12
|
+
|
13
|
+
break if line == "exit"
|
14
|
+
|
15
|
+
eval line
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
BrowserShooter::Commands::Base.plug( BrowserShooter::Commands::Debug )
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module BrowserShooter
|
2
|
+
module Commands
|
3
|
+
module Screenshots
|
4
|
+
|
5
|
+
def shot( sufix = nil )
|
6
|
+
sufix = BrowserShooter::Utils.timestamp unless sufix
|
7
|
+
shot_path = "#{output_path}/shots/#{sufix}.png"
|
8
|
+
|
9
|
+
BrowserShooter::Logger.log "shooting in '#{shot_path}'"
|
10
|
+
|
11
|
+
FileUtils.mkdir_p( File.dirname( shot_path ) )
|
12
|
+
driver.save_screenshot( shot_path )
|
13
|
+
|
14
|
+
return shot_path
|
15
|
+
end
|
16
|
+
|
17
|
+
def shot_system( sufix = nil )
|
18
|
+
sufix = BrowserShooter::Utils.timestamp unless sufix
|
19
|
+
shot_path = "#{output_path}/shots/#{sufix}.png"
|
20
|
+
|
21
|
+
BrowserShooter::Logger.log "shooting system in '#{shot_path}'"
|
22
|
+
|
23
|
+
FileUtils.mkdir_p( File.dirname( shot_path ) )
|
24
|
+
|
25
|
+
command = "VBoxManage controlvm '#{browser.vm}' screenshotpng '#{shot_path}'"
|
26
|
+
success = Kernel.system( command )
|
27
|
+
|
28
|
+
if( !success )
|
29
|
+
raise SystemCallError, "Shoot system command [#{command}] returns error: '#{$?}'"
|
30
|
+
end
|
31
|
+
|
32
|
+
return shot_path
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
BrowserShooter::Commands::Base.plug( BrowserShooter::Commands::Screenshots )
|
@@ -4,8 +4,10 @@ module BrowserShooter
|
|
4
4
|
|
5
5
|
def initialize( opts )
|
6
6
|
@config = BrowserShooter::Configurator.load_config( opts[:config_file] )
|
7
|
-
models
|
7
|
+
models = BrowserShooter::Configurator.build_models( @config )
|
8
8
|
@suites = BrowserShooter::Configurator.filter_suites( models, opts )
|
9
|
+
|
10
|
+
BrowserShooter::Configurator.load_extensions( @config["extensions"] ) if @config["extensions"]
|
9
11
|
end
|
10
12
|
|
11
13
|
def [](value)
|
@@ -77,24 +79,31 @@ module BrowserShooter
|
|
77
79
|
|
78
80
|
def self.load_config( config_file_path )
|
79
81
|
config = {
|
80
|
-
"output_path" => "~/browser_shooter"
|
81
|
-
"logs_format" => "csv"
|
82
|
+
"output_path" => "~/browser_shooter"
|
82
83
|
}
|
83
84
|
|
84
85
|
config.merge! YAML.load_file( config_file_path )
|
85
86
|
|
86
|
-
config["output_path"] =
|
87
|
+
config["output_path"] = setup_output_path( config["output_path"] )
|
87
88
|
|
88
89
|
config
|
89
90
|
end
|
90
91
|
|
91
|
-
def self.
|
92
|
+
def self.setup_output_path( output_path )
|
92
93
|
output_path = File.expand_path( "#{output_path}/#{timestamp}" )
|
93
94
|
BrowserShooter::Logger.log( "output_path: #{output_path}" )
|
94
95
|
|
95
96
|
output_path
|
96
97
|
end
|
97
98
|
|
99
|
+
def self.load_extensions( extensions_paths )
|
100
|
+
extensions_paths.each do |extension_path|
|
101
|
+
extension_path = File.expand_path( extension_path )
|
102
|
+
BrowserShooter::Logger.log( "Loading extension: #{extension_path}" )
|
103
|
+
Kernel.require( extension_path )
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
98
107
|
def self.timestamp
|
99
108
|
Time.now.strftime("%Y%m%d%H%M%S")
|
100
109
|
end
|
data/lib/browser_shooter.rb
CHANGED
@@ -4,6 +4,7 @@ require "yaml"
|
|
4
4
|
require "json"
|
5
5
|
|
6
6
|
require_relative "./browser_shooter/base"
|
7
|
+
require_relative "./browser_shooter/utils"
|
7
8
|
require_relative "./browser_shooter/models/suite"
|
8
9
|
require_relative "./browser_shooter/models/test"
|
9
10
|
require_relative "./browser_shooter/models/browser"
|
@@ -13,5 +14,9 @@ require_relative "./browser_shooter/logger"
|
|
13
14
|
require_relative "./browser_shooter/commander"
|
14
15
|
require_relative "./browser_shooter/log_exporter"
|
15
16
|
require_relative "./browser_shooter/argv_parser"
|
17
|
+
require_relative "./browser_shooter/commands/base"
|
18
|
+
require_relative "./browser_shooter/commands/basics"
|
19
|
+
require_relative "./browser_shooter/commands/screenshots"
|
20
|
+
require_relative "./browser_shooter/commands/debug"
|
16
21
|
|
17
22
|
|
data/test/base_test.rb
CHANGED
data/test/commander_test.rb
CHANGED
@@ -7,8 +7,10 @@ class CommanderTest < Test::Unit::TestCase
|
|
7
7
|
" command2 "
|
8
8
|
]
|
9
9
|
|
10
|
-
BrowserShooter::
|
11
|
-
|
10
|
+
BrowserShooter::Commands::Base.expects( :new ).with( "driver", "browser", "output_path" ).returns( "command_executor" )
|
11
|
+
|
12
|
+
BrowserShooter::Commander.expects( :wrapper_execute ).with( "command_executor", "command1" ).returns( "result1" )
|
13
|
+
BrowserShooter::Commander.expects( :wrapper_execute ).with( "command_executor", "command2" ).returns( "result2" )
|
12
14
|
BrowserShooter::Logger.expects( :command_result ).twice
|
13
15
|
BrowserShooter::Logger.expects( :test_result )
|
14
16
|
|
@@ -18,8 +20,8 @@ class CommanderTest < Test::Unit::TestCase
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def test_wrapper_execute
|
21
|
-
BrowserShooter::Commander.expects( :execute ).with( "
|
22
|
-
result = BrowserShooter::Commander.wrapper_execute( "
|
23
|
+
BrowserShooter::Commander.expects( :execute ).with( "command_executor", "command" ).returns( "message" )
|
24
|
+
result = BrowserShooter::Commander.wrapper_execute( "command_executor", "command" )
|
23
25
|
|
24
26
|
assert_equal( "command", result[:command] )
|
25
27
|
assert_equal( false, result[:time].nil? )
|
@@ -28,8 +30,8 @@ class CommanderTest < Test::Unit::TestCase
|
|
28
30
|
end
|
29
31
|
|
30
32
|
def test_wrapper_execute_when_error
|
31
|
-
BrowserShooter::Commander.expects( :execute ).with( "
|
32
|
-
result = BrowserShooter::Commander.wrapper_execute( "
|
33
|
+
BrowserShooter::Commander.expects( :execute ).with( "command_executor", "command" ).raises( Exception.new( "error" ) )
|
34
|
+
result = BrowserShooter::Commander.wrapper_execute( "command_executor", "command" )
|
33
35
|
|
34
36
|
assert_equal( "command", result[:command] )
|
35
37
|
assert_equal( false, result[:time].nil? )
|
@@ -37,135 +39,32 @@ class CommanderTest < Test::Unit::TestCase
|
|
37
39
|
assert_equal( "error", result[:message] )
|
38
40
|
end
|
39
41
|
|
40
|
-
def
|
41
|
-
|
42
|
-
BrowserShooter::Commander.execute( "shot sufix", "driver", "browser", "shoot-path" )
|
43
|
-
end
|
44
|
-
|
45
|
-
def test_execute_when_shot_without_sufix
|
46
|
-
BrowserShooter::Commander.expects( :shot ).with( "driver", "shoot-path", nil )
|
47
|
-
BrowserShooter::Commander.execute( "shot", "driver", "browser", "shoot-path" )
|
48
|
-
end
|
49
|
-
|
50
|
-
def test_execute_when_shot_system_with_sufix
|
51
|
-
BrowserShooter::Commander.expects( :shot_system ).with( "driver", "browser", "shoot-path", "sufix" )
|
52
|
-
BrowserShooter::Commander.execute( "shot_system sufix", "driver", "browser", "shoot-path" )
|
53
|
-
end
|
54
|
-
|
55
|
-
def test_execute_when_shot_system_without_sufix
|
56
|
-
BrowserShooter::Commander.expects( :shot_system ).with( "driver", "browser", "shoot-path", nil )
|
57
|
-
BrowserShooter::Commander.execute( "shot_system", "driver", "browser", "shoot-path" )
|
58
|
-
end
|
59
|
-
|
60
|
-
def test_execute_when_pause
|
61
|
-
BrowserShooter::Commander.expects( :pause ).with( 10 )
|
62
|
-
BrowserShooter::Commander.execute( "pause 10", "driver", "browser", "shoot-path" )
|
63
|
-
end
|
64
|
-
|
65
|
-
def test_execute_when_wait_for_element
|
66
|
-
BrowserShooter::Commander.expects( :wait_for_element ).with( "driver", "css_selector", 10 )
|
67
|
-
BrowserShooter::Commander.execute( "wait_for_element \"css_selector\", 10", "driver", "browser", nil )
|
68
|
-
end
|
69
|
-
|
70
|
-
def test_execute_when_click
|
71
|
-
BrowserShooter::Commander.expects( :click ).with( "driver", "css_selector" )
|
72
|
-
BrowserShooter::Commander.execute( "click \"css_selector\"", "driver", "browser", nil )
|
73
|
-
end
|
74
|
-
|
75
|
-
def test_execute_when_type
|
76
|
-
BrowserShooter::Commander.expects( :type ).with( "driver", "css_selector", "message a b" )
|
77
|
-
BrowserShooter::Commander.execute( "type \"css_selector\", \"message a b\"", "driver", "browser", nil )
|
78
|
-
end
|
79
|
-
|
80
|
-
def test_shot_with_sufix
|
81
|
-
driver = mock()
|
82
|
-
|
83
|
-
FileUtils.expects( :mkdir_p ).with( "output_path/shots" )
|
84
|
-
driver.expects( :save_screenshot ).with( "output_path/shots/sufix.png" )
|
85
|
-
|
86
|
-
BrowserShooter::Commander.shot( driver, "output_path", "sufix" )
|
87
|
-
end
|
88
|
-
|
89
|
-
def test_shot_without_sufix
|
90
|
-
BrowserShooter::Commander.stubs( :timestamp ).returns( "timestamp" )
|
91
|
-
|
92
|
-
driver = mock()
|
93
|
-
|
94
|
-
FileUtils.expects( :mkdir_p ).with( "output_path/shots" )
|
95
|
-
driver.expects( :save_screenshot ).with( "output_path/shots/timestamp.png" )
|
96
|
-
|
97
|
-
BrowserShooter::Commander.shot( driver, "output_path", nil )
|
98
|
-
end
|
99
|
-
|
100
|
-
def test_shot_system_with_sufix
|
101
|
-
browser = mock()
|
102
|
-
command = "VBoxManage controlvm 'VMName' screenshotpng 'output_path/shots/sufix.png'"
|
103
|
-
|
104
|
-
browser.stubs( :vm ).returns( "VMName" )
|
105
|
-
FileUtils.expects( :mkdir_p ).with( "output_path/shots" )
|
106
|
-
Kernel.expects( :system ).with( command ).returns( true )
|
107
|
-
|
108
|
-
BrowserShooter::Commander.shot_system( "driver", browser, "output_path", "sufix" )
|
109
|
-
end
|
110
|
-
|
111
|
-
def test_shot_system_without_sufix
|
112
|
-
browser = mock()
|
113
|
-
command = "VBoxManage controlvm 'VMName' screenshotpng 'output_path/shots/timestamp.png'"
|
42
|
+
def test_execute_in_command_executor
|
43
|
+
command_executor = mock()
|
114
44
|
|
115
|
-
|
116
|
-
|
117
|
-
FileUtils.expects( :mkdir_p ).with( "output_path/shots" )
|
118
|
-
Kernel.expects( :system ).with( command ).returns( true )
|
45
|
+
command_executor.expects( :respond_to? ).with( :command_name ).returns( true )
|
46
|
+
command_executor.expects( :command_name ).with( "arg1", "arg2" )
|
119
47
|
|
120
|
-
BrowserShooter::Commander.
|
48
|
+
BrowserShooter::Commander.execute( command_executor, "command_name 'arg1', 'arg2'" )
|
121
49
|
end
|
122
50
|
|
123
|
-
def
|
124
|
-
|
125
|
-
command = "VBoxManage controlvm 'VMName' screenshotpng 'output_path/shots/sufix.png'"
|
51
|
+
def test_execute_in_command_executor_command_with_params
|
52
|
+
command_executor = mock()
|
126
53
|
|
127
|
-
|
128
|
-
|
129
|
-
Kernel.expects( :system ).with( command ).returns( false )
|
54
|
+
command_executor.expects( :respond_to? ).with( :command_name ).returns( true )
|
55
|
+
command_executor.expects( :command_name ).with( "arg1", "arg2" )
|
130
56
|
|
131
|
-
|
132
|
-
BrowserShooter::Commander.shot_system( "driver", browser, "output_path", "sufix" )
|
133
|
-
end
|
57
|
+
BrowserShooter::Commander.execute( command_executor, "command_name('arg1', 'arg2')" )
|
134
58
|
end
|
135
59
|
|
136
|
-
def
|
137
|
-
|
138
|
-
driver
|
60
|
+
def test_execute_in_driver
|
61
|
+
command_executor = mock()
|
62
|
+
driver = mock()
|
139
63
|
|
140
|
-
|
141
|
-
|
142
|
-
driver.expects( :
|
143
|
-
|
144
|
-
BrowserShooter::Commander.wait_for_element( driver, "css_selector", 10 )
|
145
|
-
end
|
146
|
-
|
147
|
-
def test_click
|
148
|
-
driver = mock()
|
149
|
-
element = mock()
|
150
|
-
|
151
|
-
driver.expects( :find_element ).with( "css", "css_selector" ).returns( element )
|
152
|
-
element.expects( :click )
|
153
|
-
|
154
|
-
BrowserShooter::Commander.click( driver, "css_selector" )
|
155
|
-
end
|
156
|
-
|
157
|
-
def test_type
|
158
|
-
driver = mock()
|
159
|
-
element = mock()
|
160
|
-
|
161
|
-
driver.expects( :find_element ).with( "css", "css_selector" ).returns( element )
|
162
|
-
element.expects( :send_keys ).with( "message" )
|
163
|
-
|
164
|
-
BrowserShooter::Commander.type( driver, "css_selector", "message" )
|
165
|
-
end
|
64
|
+
command_executor.expects( :respond_to? ).with( :command_name ).returns( false )
|
65
|
+
command_executor.expects( :driver ).returns( driver )
|
66
|
+
driver.expects( :command_name ).with( "arg1", "arg2" )
|
166
67
|
|
167
|
-
|
168
|
-
Kernel.expects( :sleep ).with( 1 )
|
169
|
-
BrowserShooter::Commander.pause( 1 )
|
68
|
+
BrowserShooter::Commander.execute( command_executor, "command_name 'arg1', 'arg2'" )
|
170
69
|
end
|
171
70
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative "../test_helper"
|
2
|
+
|
3
|
+
class BasicsTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@driver = mock()
|
6
|
+
@browser = mock()
|
7
|
+
@output_path = "output_path"
|
8
|
+
|
9
|
+
@command_executor =
|
10
|
+
BrowserShooter::Commands::Base.new(
|
11
|
+
@driver,
|
12
|
+
@browser,
|
13
|
+
@output_path
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_wait_for_element
|
18
|
+
wait = mock()
|
19
|
+
|
20
|
+
Selenium::WebDriver::Wait.expects( :new ).with( :timeout => 10 ).returns( wait )
|
21
|
+
wait.expects( :until ).yields
|
22
|
+
@driver.expects( :find_element ).with( "css", "css_selector" )
|
23
|
+
|
24
|
+
@command_executor.wait_for_element( "css_selector", 10 )
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_click
|
28
|
+
element = mock()
|
29
|
+
|
30
|
+
@driver.expects( :find_element ).with( "css", "css_selector" ).returns( element )
|
31
|
+
element.expects( :click )
|
32
|
+
|
33
|
+
@command_executor.click( "css_selector" )
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_type
|
37
|
+
element = mock()
|
38
|
+
|
39
|
+
@driver.expects( :find_element ).with( "css", "css_selector" ).returns( element )
|
40
|
+
element.expects( :send_keys ).with( "message" )
|
41
|
+
|
42
|
+
@command_executor.type( "css_selector", "message" )
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_pause
|
46
|
+
Kernel.expects( :sleep ).with( 1 )
|
47
|
+
@command_executor.pause( 1 )
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require_relative "../test_helper"
|
2
|
+
|
3
|
+
class ScreenshotsTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@driver = mock()
|
6
|
+
@browser = mock()
|
7
|
+
@output_path = "output_path"
|
8
|
+
|
9
|
+
@command_executor =
|
10
|
+
BrowserShooter::Commands::Base.new(
|
11
|
+
@driver,
|
12
|
+
@browser,
|
13
|
+
@output_path
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_shot_with_sufix
|
18
|
+
FileUtils.expects( :mkdir_p ).with( "output_path/shots" )
|
19
|
+
@driver.expects( :save_screenshot ).with( "output_path/shots/sufix.png" )
|
20
|
+
|
21
|
+
@command_executor.shot( "sufix" )
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_shot_without_sufix
|
25
|
+
BrowserShooter::Utils.stubs( :timestamp ).returns( "timestamp" )
|
26
|
+
FileUtils.expects( :mkdir_p ).with( "output_path/shots" )
|
27
|
+
@driver.expects( :save_screenshot ).with( "output_path/shots/timestamp.png" )
|
28
|
+
|
29
|
+
@command_executor.shot
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_shot_system_with_sufix
|
33
|
+
shell_command = "VBoxManage controlvm 'VMName' screenshotpng 'output_path/shots/sufix.png'"
|
34
|
+
|
35
|
+
@browser.stubs( :vm ).returns( "VMName" )
|
36
|
+
FileUtils.expects( :mkdir_p ).with( "output_path/shots" )
|
37
|
+
Kernel.expects( :system ).with( shell_command ).returns( true )
|
38
|
+
|
39
|
+
@command_executor.shot_system( "sufix" )
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_shot_system_without_sufix
|
43
|
+
shell_command = "VBoxManage controlvm 'VMName' screenshotpng 'output_path/shots/timestamp.png'"
|
44
|
+
|
45
|
+
BrowserShooter::Utils.stubs( :timestamp ).returns( "timestamp" )
|
46
|
+
@browser.stubs( :vm ).returns( "VMName" )
|
47
|
+
FileUtils.expects( :mkdir_p ).with( "output_path/shots" )
|
48
|
+
Kernel.expects( :system ).with( shell_command ).returns( true )
|
49
|
+
|
50
|
+
@command_executor.shot_system
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_shot_system_with_error
|
54
|
+
shell_command = "VBoxManage controlvm 'VMName' screenshotpng 'output_path/shots/sufix.png'"
|
55
|
+
|
56
|
+
@browser.stubs( :vm ).returns( "VMName" )
|
57
|
+
FileUtils.expects( :mkdir_p ).with( "output_path/shots" )
|
58
|
+
Kernel.expects( :system ).with( shell_command ).returns( false )
|
59
|
+
|
60
|
+
assert_raise( SystemCallError ) do
|
61
|
+
@command_executor.shot_system( "sufix" )
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/test/configurator_test.rb
CHANGED
@@ -2,21 +2,28 @@ require_relative "test_helper"
|
|
2
2
|
|
3
3
|
class ConfiguratorTest < Test::Unit::TestCase
|
4
4
|
def test_initialize
|
5
|
-
opts
|
6
|
-
|
5
|
+
opts = {
|
6
|
+
:config_file => "config_file",
|
7
|
+
}
|
8
|
+
|
9
|
+
config = {
|
10
|
+
"key1" => "value1",
|
11
|
+
"extensions" => [ "extension1.rb", "extension2.rb" ]
|
12
|
+
}
|
7
13
|
|
8
14
|
BrowserShooter::Configurator.expects( :load_config ).with( "config_file" ).returns( config )
|
9
15
|
BrowserShooter::Configurator.expects( :build_models ).with( config ).returns( "models" )
|
10
16
|
BrowserShooter::Configurator.expects( :filter_suites ).with( "models", opts ).returns( "suites" )
|
17
|
+
BrowserShooter::Configurator.expects( :load_extensions ).with( ["extension1.rb", "extension2.rb"] )
|
11
18
|
|
12
19
|
configurator = BrowserShooter::Configurator.new( opts )
|
13
20
|
|
14
|
-
assert_equal( "value1", configurator[
|
21
|
+
assert_equal( "value1", configurator["key1"] )
|
15
22
|
assert_equal( "suites", configurator.suites )
|
16
23
|
end
|
17
24
|
|
18
25
|
def test_build_models
|
19
|
-
BrowserShooter::Configurator.stubs( :
|
26
|
+
BrowserShooter::Configurator.stubs( :setup_output_path )
|
20
27
|
config = BrowserShooter::Configurator.load_config( "#{FIXTURES}/config.yml" )
|
21
28
|
models = BrowserShooter::Configurator.build_models( config )
|
22
29
|
|
@@ -40,7 +47,7 @@ class ConfiguratorTest < Test::Unit::TestCase
|
|
40
47
|
end
|
41
48
|
|
42
49
|
def test_filter_suites
|
43
|
-
BrowserShooter::Configurator.stubs( :
|
50
|
+
BrowserShooter::Configurator.stubs( :setup_output_path )
|
44
51
|
config = BrowserShooter::Configurator.load_config( "#{FIXTURES}/config.yml" )
|
45
52
|
models = BrowserShooter::Configurator.build_models( config )
|
46
53
|
|
@@ -80,4 +87,10 @@ class ConfiguratorTest < Test::Unit::TestCase
|
|
80
87
|
assert_equal( "script-one", config["scripts"]["script-one"] )
|
81
88
|
assert_equal( "browser-one", config["browsers"]["browser-one"] )
|
82
89
|
end
|
90
|
+
|
91
|
+
def test_load_extensions
|
92
|
+
Kernel.expects( :require ).with( File.expand_path( "extension1.rb" ) )
|
93
|
+
Kernel.expects( :require ).with( File.expand_path( "extension2.rb" ) )
|
94
|
+
BrowserShooter::Configurator.load_extensions( ["extension1.rb", "extension2.rb"] )
|
95
|
+
end
|
83
96
|
end
|
data/test/fixtures/config.yml
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: browser_shooter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-03-
|
12
|
+
date: 2012-03-27 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
16
|
-
requirement: &
|
16
|
+
requirement: &70207374341860 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 1.0.0.rc.6
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70207374341860
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &70207374341360 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - =
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 0.9.2.2
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70207374341360
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: mocha
|
38
|
-
requirement: &
|
38
|
+
requirement: &70207374340980 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70207374340980
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: selenium-webdriver
|
49
|
-
requirement: &
|
49
|
+
requirement: &70207374340520 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70207374340520
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: mixlib-cli
|
60
|
-
requirement: &
|
60
|
+
requirement: &70207374340100 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,7 +65,7 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70207374340100
|
69
69
|
description: Selenium RC wraper to create browser screenshots
|
70
70
|
email:
|
71
71
|
- fguillen.mail@gmail.com
|
@@ -85,20 +85,29 @@ files:
|
|
85
85
|
- examples/config0.yml
|
86
86
|
- examples/config1.yml
|
87
87
|
- examples/config2.yml
|
88
|
+
- examples/config3_debug.yml
|
89
|
+
- examples/extension0.rb
|
88
90
|
- lib/browser_shooter.rb
|
89
91
|
- lib/browser_shooter/argv_parser.rb
|
90
92
|
- lib/browser_shooter/base.rb
|
91
93
|
- lib/browser_shooter/commander.rb
|
94
|
+
- lib/browser_shooter/commands/base.rb
|
95
|
+
- lib/browser_shooter/commands/basics.rb
|
96
|
+
- lib/browser_shooter/commands/debug.rb
|
97
|
+
- lib/browser_shooter/commands/screenshots.rb
|
92
98
|
- lib/browser_shooter/configurator.rb
|
93
99
|
- lib/browser_shooter/log_exporter.rb
|
94
100
|
- lib/browser_shooter/logger.rb
|
95
101
|
- lib/browser_shooter/models/browser.rb
|
96
102
|
- lib/browser_shooter/models/suite.rb
|
97
103
|
- lib/browser_shooter/models/test.rb
|
104
|
+
- lib/browser_shooter/utils.rb
|
98
105
|
- lib/browser_shooter/version.rb
|
99
106
|
- test/argv_parser_test.rb
|
100
107
|
- test/base_test.rb
|
101
108
|
- test/commander_test.rb
|
109
|
+
- test/commands/basics_test.rb
|
110
|
+
- test/commands/screenshots_test.rb
|
102
111
|
- test/configurator_test.rb
|
103
112
|
- test/fixtures/config.yml
|
104
113
|
- test/fixtures/config_simple.yml
|
@@ -138,6 +147,8 @@ test_files:
|
|
138
147
|
- test/argv_parser_test.rb
|
139
148
|
- test/base_test.rb
|
140
149
|
- test/commander_test.rb
|
150
|
+
- test/commands/basics_test.rb
|
151
|
+
- test/commands/screenshots_test.rb
|
141
152
|
- test/configurator_test.rb
|
142
153
|
- test/fixtures/config.yml
|
143
154
|
- test/fixtures/config_simple.yml
|