grid 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.1
1
+ 0.4.2
@@ -0,0 +1,27 @@
1
+ require 'grid'
2
+ require 'bacon'
3
+
4
+ describe 'A simple specification' do
5
+
6
+ before do
7
+ options = {}
8
+ options[:controller_uri] = "druby://10.0.1.3:11235"
9
+ options[:browser_type] = 'webdriver'
10
+ options[:browser] = 'chrome'
11
+ options[:loglevel] = Logger::DEBUG
12
+ @grid = Grid.new(options)
13
+ @grid.setup
14
+ end
15
+
16
+ after do
17
+ @grid.teardown
18
+ end
19
+
20
+ it "should do a search on Google" do
21
+ @grid.iterate do |browser|
22
+ browser.goto "altentee.com"
23
+ browser.title.should =~ /Automation Company/
24
+ end
25
+ end
26
+
27
+ end
@@ -1,16 +1,16 @@
1
- require '../lib/grid'
1
+ require 'grid'
2
2
  require 'watir-webdriver-performance' # only if using webdriver_performance
3
3
 
4
4
  ##
5
5
  # Set some parameters before we begin
6
- params={}
7
- params[:controller_uri] = "druby://ec2-50-16-63-81.compute-1.amazonaws.com:11235"
8
- params[:browser] = "chrome"
9
- params[:quantity] = 5
6
+ options={}
7
+ options[:controller_uri] = "druby://ec2-50-16-63-81.compute-1.amazonaws.com:11235"
8
+ options[:browser] = "chrome"
9
+ options[:quantity] = 5
10
10
 
11
11
  ##
12
12
  # Let's instantiate a grid object
13
- grid = Grid.new(params)
13
+ grid = Grid.new(options)
14
14
 
15
15
  ##
16
16
  # How big is my grid?
@@ -44,7 +44,7 @@ grid.teardown
44
44
  ##
45
45
  # There's also a iterate_with_index method if you want to keep track
46
46
  # of individual browsers for further reporting and analysis
47
- grid = Grid.new(params)
47
+ grid = Grid.new(options)
48
48
  grid.setup
49
49
 
50
50
  grid.iterate_with_index do |browser, index|
@@ -0,0 +1,14 @@
1
+ require 'grid'
2
+
3
+ params={}
4
+ params[:controller_uri] = 'druby://10.0.1.3:11235'
5
+ params[:browser] = 'firefox'
6
+
7
+ Grid.control(params) do |driver, index|
8
+ driver.navigate.to 'http://google.com'
9
+ element = driver.find_element(:name, 'q')
10
+ element.send_keys 'gridinit'
11
+ element.submit
12
+ puts driver.title
13
+ driver.quit
14
+ end
@@ -0,0 +1,36 @@
1
+ require 'grid'
2
+ require 'test/unit'
3
+ require 'grid/extensions/capybara'
4
+
5
+ #require 'capybara'
6
+ #require 'capybara/dsl'
7
+ #require 'selenium-webdriver'
8
+
9
+ #module Capybara
10
+ #module Grid
11
+ #autoload :Node, 'lib/grid/extensions/capybara/node.rb'
12
+ #autoload :Driver, 'lib/grid/extensions/capybara/driver.rb'
13
+ #end
14
+ #end
15
+
16
+ Capybara.register_driver :grid do |app|
17
+ options = {}
18
+ options[:controller_uri] = 'druby://10.0.1.3:11235'
19
+ options[:loglevel] = Logger::DEBUG
20
+ Capybara::Grid::Driver.new(app, options)
21
+ end
22
+
23
+ class HelloWorldTest < Test::Unit::TestCase
24
+ include Capybara
25
+
26
+ Capybara.app_host = 'http://www.google.com'
27
+ Capybara.default_driver = :grid
28
+ Capybara.run_server = false
29
+
30
+ def test_google
31
+ visit '/'
32
+ fill_in 'q', :with => 'gridinit'
33
+ assert page.has_content?('results')
34
+ end
35
+
36
+ end
@@ -6,12 +6,12 @@ require 'grid'
6
6
 
7
7
  Given /^(\d+) users open "([^"]*)"$/ do |quantity, browser|
8
8
  params={}
9
- params[:controller_uri] = "druby://ec2-184-73-37-176.compute-1.amazonaws.com:11235"
9
+ params[:controller_uri] = "druby://ec2-50-17-154-31.compute-1.amazonaws.com:11235"
10
10
  params[:browser] = browser # type of webdriver browser to spawn
11
11
  params[:quantity] = quantity.to_i # max number of browsers to use
12
12
  params[:rampup] = 10 # seconds
13
13
  @grid = Grid.new(params)
14
- @grid.setup
14
+ @grid.setup
15
15
  end
16
16
 
17
17
  Given /^navigate to the portal$/ do
@@ -0,0 +1,26 @@
1
+ require 'grid'
2
+
3
+ describe 'A simple specification' do
4
+
5
+ before(:all) do
6
+ options = {}
7
+ options[:controller_uri] = "druby://10.0.1.3:11235"
8
+ options[:browser_type] = 'webdriver'
9
+ options[:browser] = 'chrome'
10
+ options[:loglevel] = Logger::DEBUG
11
+ @grid = Grid.new(options)
12
+ @grid.setup
13
+ end
14
+
15
+ after(:all) do
16
+ @grid.teardown
17
+ end
18
+
19
+ it "should do a search on Google" do
20
+ @grid.iterate do |browser|
21
+ browser.goto "altentee.com"
22
+ browser.title.should =~ /Automation Company/
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,25 @@
1
+ require 'grid'
2
+ require 'test/unit'
3
+
4
+ class SimpleTest < Test::Unit::TestCase
5
+ def setup
6
+ options = {}
7
+ options[:controller_uri] = "druby://10.0.1.3:11235"
8
+ options[:browser_type] = 'webdriver'
9
+ options[:browser] = 'chrome'
10
+ options[:loglevel] = Logger::DEBUG
11
+ @grid = Grid.new(options)
12
+ @grid.setup
13
+ end
14
+
15
+ def teardown
16
+ @grid.teardown
17
+ end
18
+
19
+ def test_google
20
+ @grid.iterate do |browser|
21
+ browser.goto "altentee.com"
22
+ assert_match /Automation Company/, browser.title
23
+ end
24
+ end
25
+ end
data/grid.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{grid}
8
- s.version = "0.4.1"
8
+ s.version = "0.4.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Tim Koopmans"]
12
- s.date = %q{2011-04-20}
12
+ s.date = %q{2011-04-26}
13
13
  s.default_executable = %q{grid}
14
14
  s.description = %q{Gridinit command line utilities to help you use the Gridinit API}
15
15
  s.email = %q{tim.koops@gmail.com}
@@ -28,12 +28,21 @@ Gem::Specification.new do |s|
28
28
  "Rakefile",
29
29
  "VERSION",
30
30
  "bin/grid",
31
+ "examples/bacon/bacon.rb",
31
32
  "examples/basic/basic.rb",
33
+ "examples/basic/selenium/selenium.rb",
34
+ "examples/capybara/testunit/example_test.rb",
32
35
  "examples/cucumber/example.feature",
33
36
  "examples/cucumber/step_definitions/.DS_Store",
34
37
  "examples/cucumber/step_definitions/example_steps.rb",
38
+ "examples/rspec/basic_spec.rb",
39
+ "examples/testunit/basic_test.rb",
35
40
  "grid.gemspec",
36
41
  "lib/grid.rb",
42
+ "lib/grid/extensions/capybara.rb",
43
+ "lib/grid/extensions/capybara/driver.rb",
44
+ "lib/grid/extensions/capybara/node.rb",
45
+ "lib/grid/grid.rb",
37
46
  "spec/grid_spec.rb",
38
47
  "spec/spec_helper.rb"
39
48
  ]
@@ -43,8 +52,13 @@ Gem::Specification.new do |s|
43
52
  s.rubygems_version = %q{1.4.2}
44
53
  s.summary = %q{Gridinit command line utilities}
45
54
  s.test_files = [
55
+ "examples/bacon/bacon.rb",
46
56
  "examples/basic/basic.rb",
57
+ "examples/basic/selenium/selenium.rb",
58
+ "examples/capybara/testunit/example_test.rb",
47
59
  "examples/cucumber/step_definitions/example_steps.rb",
60
+ "examples/rspec/basic_spec.rb",
61
+ "examples/testunit/basic_test.rb",
48
62
  "spec/grid_spec.rb",
49
63
  "spec/spec_helper.rb"
50
64
  ]
@@ -0,0 +1,155 @@
1
+ class Capybara::Grid::Driver < Capybara::Driver::Base
2
+ DEFAULT_OPTIONS = {
3
+ :resynchronize => false,
4
+ :resynchronization_timeout => 10,
5
+ :browser => :firefox
6
+ }
7
+ SPECIAL_OPTIONS = [:browser, :resynchronize, :resynchronization_timeout]
8
+
9
+ attr_reader :app, :rack_server, :options
10
+
11
+ def browser
12
+ unless @browsers
13
+ @options[:browser] = 'firefox'
14
+ @grid = Grid.new(@options)
15
+ @browsers = []
16
+ @grid.providers.each_with_index do |provider, index|
17
+ @browsers[index] = provider[:object].new_browser :firefox
18
+ end
19
+ at_exit do
20
+ @browsers.each do |browser|
21
+ browser.quit
22
+ end
23
+ end
24
+ end
25
+ @browsers.first
26
+ end
27
+
28
+ def initialize(app, options={})
29
+ @app = app
30
+ @options = DEFAULT_OPTIONS.merge(options)
31
+ @rack_server = Capybara::Server.new(@app)
32
+ @rack_server.boot if Capybara.run_server
33
+ end
34
+
35
+ def visit(path)
36
+ browser.navigate.to(url(path))
37
+ end
38
+
39
+ def source
40
+ browser.page_source
41
+ end
42
+
43
+ def body
44
+ browser.page_source
45
+ end
46
+
47
+ def current_url
48
+ browser.current_url
49
+ end
50
+
51
+ def find(selector)
52
+ browser.find_elements(:xpath, selector).map do |node|
53
+ Capybara::Grid::Node.new(self, node)
54
+ end
55
+ end
56
+
57
+ def wait?; true; end
58
+
59
+ def resynchronize
60
+ if options[:resynchronize]
61
+ load_wait_for_ajax_support
62
+ yield
63
+ Capybara.timeout(options[:resynchronization_timeout], self, "failed to resynchronize, ajax request timed out") do
64
+ evaluate_script("!window.capybaraRequestsOutstanding")
65
+ end
66
+ else
67
+ yield
68
+ end
69
+ end
70
+
71
+ def execute_script(script)
72
+ browser.execute_script script
73
+ end
74
+
75
+ def evaluate_script(script)
76
+ browser.execute_script "return #{script}"
77
+ end
78
+
79
+ def reset!
80
+ # Use instance variable directly so we avoid starting the browser just to reset the session
81
+ if @browser
82
+ begin
83
+ @browser.manage.delete_all_cookies
84
+ rescue Selenium::WebDriver::Error::UnhandledError => e
85
+ # delete_all_cookies fails when we've previously gone
86
+ # to about:blank, so we rescue this error and do nothing
87
+ # instead.
88
+ end
89
+ @browser.navigate.to('about:blank')
90
+ end
91
+ end
92
+
93
+ def within_frame(frame_id)
94
+ old_window = browser.window_handle
95
+ browser.switch_to.frame(frame_id)
96
+ yield
97
+ browser.switch_to.window old_window
98
+ end
99
+
100
+ def find_window( selector )
101
+ original_handle = browser.window_handle
102
+ browser.window_handles.each do |handle|
103
+ browser.switch_to.window handle
104
+ if( selector == browser.execute_script("return window.name") ||
105
+ browser.title.include?(selector) ||
106
+ browser.current_url.include?(selector) ||
107
+ (selector == handle) )
108
+ browser.switch_to.window original_handle
109
+ return handle
110
+ end
111
+ end
112
+ raise Capybara::ElementNotFound, "Could not find a window identified by #{selector}"
113
+ end
114
+
115
+ def within_window(selector, &blk)
116
+ handle = find_window( selector )
117
+ browser.switch_to.window(handle, &blk)
118
+ end
119
+
120
+ private
121
+
122
+ def load_wait_for_ajax_support
123
+ browser.execute_script <<-JS
124
+ window.capybaraRequestsOutstanding = 0;
125
+ (function() { // Overriding XMLHttpRequest
126
+ var oldXHR = window.XMLHttpRequest;
127
+
128
+ function newXHR() {
129
+ var realXHR = new oldXHR();
130
+
131
+ window.capybaraRequestsOutstanding++;
132
+ realXHR.addEventListener("readystatechange", function() {
133
+ if( realXHR.readyState == 4 ) {
134
+ setTimeout( function() {
135
+ window.capybaraRequestsOutstanding--;
136
+ if(window.capybaraRequestsOutstanding < 0) {
137
+ window.capybaraRequestsOutstanding = 0;
138
+ }
139
+ }, 500 );
140
+ }
141
+ }, false);
142
+
143
+ return realXHR;
144
+ }
145
+
146
+ window.XMLHttpRequest = newXHR;
147
+ })();
148
+ JS
149
+ end
150
+
151
+ def url(path)
152
+ rack_server.url(path)
153
+ end
154
+
155
+ end
@@ -0,0 +1,92 @@
1
+ class Capybara::Grid::Node < Capybara::Driver::Node
2
+ def text
3
+ native.text
4
+ end
5
+
6
+ def [](name)
7
+ if name == :value
8
+ value
9
+ else
10
+ native.attribute(name.to_s)
11
+ end
12
+ rescue Selenium::WebDriver::Error::WebDriverError
13
+ nil
14
+ end
15
+
16
+ def value
17
+ if tag_name == "select" and self[:multiple] and not self[:multiple] == "false"
18
+ native.find_elements(:xpath, ".//option").select { |n| n.selected? }.map { |n| n.value || n.text }
19
+ else
20
+ native.value
21
+ end
22
+ end
23
+
24
+ def set(value)
25
+ if tag_name == 'input' and type == 'radio'
26
+ click
27
+ elsif tag_name == 'input' and type == 'checkbox'
28
+ click if value ^ native.attribute('checked').to_s.eql?("true")
29
+ elsif tag_name == 'textarea' or tag_name == 'input'
30
+ resynchronize do
31
+ native.clear
32
+ native.send_keys(value.to_s)
33
+ end
34
+ end
35
+ end
36
+
37
+ def select_option
38
+ resynchronize { native.select }
39
+ end
40
+
41
+ def unselect_option
42
+ if select_node['multiple'] != 'multiple' and select_node['multiple'] != 'true'
43
+ raise Capybara::UnselectNotAllowed, "Cannot unselect option from single select box."
44
+ end
45
+ resynchronize { native.toggle } if selected?
46
+ end
47
+
48
+ def click
49
+ resynchronize { native.click }
50
+ end
51
+
52
+ def drag_to(element)
53
+ resynchronize { native.drag_and_drop_on(element.native) }
54
+ end
55
+
56
+ def tag_name
57
+ native.tag_name
58
+ end
59
+
60
+ def visible?
61
+ displayed = native.displayed?
62
+ displayed and displayed != "false"
63
+ end
64
+
65
+ def selected?
66
+ selected = native.selected?
67
+ selected and selected != "false"
68
+ end
69
+
70
+ alias :checked? :selected?
71
+
72
+ def find(locator)
73
+ native.find_elements(:xpath, locator).map { |n| self.class.new(driver, n) }
74
+ end
75
+
76
+ private
77
+
78
+ def resynchronize
79
+ driver.resynchronize { yield }
80
+ end
81
+
82
+ # a reference to the select node if this is an option node
83
+ def select_node
84
+ find('./ancestor::select').first
85
+ end
86
+
87
+ def type
88
+ self[:type]
89
+ end
90
+
91
+ end
92
+
@@ -0,0 +1,10 @@
1
+ require 'capybara'
2
+ require 'capybara/dsl'
3
+ require 'selenium-webdriver'
4
+
5
+ module Capybara
6
+ module Grid
7
+ autoload :Node, 'grid/extensions/capybara/node'
8
+ autoload :Driver, 'grid/extensions/capybara/driver'
9
+ end
10
+ end
data/lib/grid/grid.rb ADDED
@@ -0,0 +1,283 @@
1
+ #!/usr/bin/env ruby
2
+ # grid.rb
3
+ # Grid Helper
4
+
5
+ require 'ap'
6
+ require 'watirgrid'
7
+ require 'json'
8
+ require 'rest_client'
9
+ require 'highline/import'
10
+
11
+ class Grid
12
+
13
+ def initialize(params = {})
14
+ @log = Logger.new(STDOUT, 'daily')
15
+ @log.level = params[:loglevel] || Logger::INFO
16
+ @exclusive = params[:exclusive]
17
+ @exclusive ? params[:take_all] = true : params[:read_all] = true
18
+ @webdriver_browser_type = params[:browser].to_sym if params[:browser]
19
+ @grid = Watir::Grid.new(params)
20
+ @grid.start(params)
21
+ @providers = @grid.browsers
22
+ @browsers = []
23
+ end
24
+
25
+ def size
26
+ @grid.size
27
+ end
28
+
29
+ def browsers
30
+ @browsers
31
+ end
32
+
33
+ def providers
34
+ @providers
35
+ end
36
+
37
+ def setup
38
+ @grid.browsers.each_with_index do |browser, index|
39
+ sleep 0.15
40
+ @browsers[index] ||= browser[:object].new_browser(@webdriver_browser_type)
41
+ end
42
+ end
43
+
44
+ def teardown
45
+ @browsers.each do |browser|
46
+ browser.close
47
+ end
48
+ @grid.release_tuples if @exclusive
49
+ end
50
+
51
+ def iterate &block
52
+ threads = []
53
+ @browsers.each do |browser|
54
+ threads << Thread.new do
55
+ yield browser
56
+ end
57
+ end
58
+ threads.each {|thread| thread.join}
59
+ end
60
+
61
+ def iterate_with_index &block
62
+ threads = []
63
+ @browsers.each_with_index do |browser, index|
64
+ threads << Thread.new do
65
+ yield browser, index
66
+ end
67
+ end
68
+ threads.each {|thread| thread.join}
69
+ end
70
+
71
+ def self.control(params = {}, &block)
72
+ @exclusive = params[:exclusive]
73
+ @exclusive ? params[:take_all] = true : params[:read_all] = true
74
+ @webdriver_browser_type = params[:browser].to_sym if params[:browser]
75
+ @grid = Watir::Grid.new(params)
76
+ @grid.start(params)
77
+ @browsers = []
78
+ threads = []
79
+ @grid.browsers.each_with_index do |browser, index|
80
+ sleep rampup(params)
81
+ threads << Thread.new(@webdriver_browser_type) do |webdriver_browser_type|
82
+ @browser = browser[:object].new_browser(webdriver_browser_type)
83
+ yield @browser, index
84
+ end
85
+ end
86
+ threads.each {|thread| thread.join}
87
+ @grid.release_tuples if @exclusive
88
+ end
89
+
90
+ private
91
+
92
+ def self.rampup(params = {})
93
+ if params[:rampup]
94
+ params[:rampup] / @grid.size
95
+ else
96
+ 0.5
97
+ end
98
+ end
99
+
100
+ class Helper
101
+ def initialize(params = {})
102
+ @grid_id = params[:grid_id]
103
+ @api = params[:api]
104
+ @uri = params[:uri] || "http://gridin.it/api/v0"
105
+ logfile = STDOUT
106
+ @log = Logger.new(logfile, 'daily')
107
+ @log.level = Logger::DEBUG
108
+ @log.datetime_format = "%Y-%m-%d %H:%M:%S "
109
+ if home
110
+ if File.file? ENV[home]+'/.gridrc'
111
+ @token = open(ENV[home]+'/.gridrc') { |f| f.read }.split(':')[1]
112
+ end
113
+ end
114
+ @token = get_token(params) unless @token
115
+ @log.debug("Current token: #{@token}")
116
+ end
117
+
118
+ def get_password(prompt='Password: ', mask='*')
119
+ ask(prompt) { |q| q.echo = mask }
120
+ end
121
+
122
+ def get_token(params={})
123
+ if params[:token]
124
+ params[:token]
125
+ else
126
+ HighLine.track_eof = false
127
+ @email = params[:email] || ask('Email: ')
128
+ @password = params[:password] || get_password
129
+ response = RestClient.post "#{@uri}/token.json" , {
130
+ :email => @email, :password => @password
131
+ }
132
+ (JSON.parse(response))["token"]
133
+ end
134
+ end
135
+
136
+ def home
137
+ homes = ["HOME", "HOMEPATH"]
138
+ homes.detect {|h| ENV[h] != nil}
139
+ end
140
+
141
+ def token
142
+ @token = get_token
143
+ open(ENV[home]+'/.gridrc', 'w') { |f| f << "TOKEN:#{@token}" } if home and @token
144
+ @log.debug("New token : #{@token}")
145
+ end
146
+
147
+ def list
148
+ @log.debug("Listing grids ...")
149
+ begin
150
+ response = RestClient.get "#{@uri}/grid.json" , {
151
+ :token => @token
152
+ }
153
+ ap JSON.parse(response)
154
+ rescue => e
155
+ @log.error("#{e}")
156
+ end
157
+ end
158
+
159
+ def show
160
+ @grid_id = ask("Grid ID: ") unless @grid_id
161
+ @log.debug("Listing grid ...")
162
+ begin
163
+ response = RestClient.get "#{@uri}/grid/#{@grid_id}.json" , {
164
+ :token => @token
165
+ }
166
+ ap JSON.parse(response)
167
+ rescue => e
168
+ @log.error("#{e}")
169
+ end
170
+ end
171
+
172
+ def create_grid(name, description)
173
+ begin
174
+ @log.debug("Creating grid ...")
175
+ response = RestClient.post "#{@uri}/grid.json" , {
176
+ :token => @token,
177
+ :name => name,
178
+ :description => description
179
+ }
180
+ (JSON.parse(response)).first[1]["id"]
181
+ rescue => e
182
+ @log.error("#{e}")
183
+ end
184
+ end
185
+
186
+ def create_intranode(grid_id, browser_type, location, nodes)
187
+ begin
188
+ @log.debug("Creating intranode ...")
189
+ response = RestClient.post "#{@uri}/grid/#{grid_id.to_s}/intranode.json", {
190
+ :token => @token,
191
+ :browser_type => browser_type,
192
+ :location => location,
193
+ :nodes => nodes
194
+ }
195
+ rescue => e
196
+ @log.error("#{e}")
197
+ end
198
+ end
199
+
200
+ def delete_intranode
201
+ begin
202
+ @log.debug("Deleting intranode ...")
203
+ response = RestClient.delete "#{@uri}/grid/intranode/#{@intranode_id}.json", {
204
+ :token => @token
205
+ }
206
+ rescue => e
207
+ @log.error("#{e}")
208
+ end
209
+ end
210
+
211
+ def create
212
+ name = ask("Grid name: ") { |q| q.default = "Grid" }
213
+ description = ask("Grid description: ") { |q| q.default = "Grid created #{Time.now}" }
214
+ nodes = ask("Number of nodes: ") { |q| q.default = 5 }
215
+ location = ask("Location of nodes: ") { |q| q.default = "us-east" }
216
+ browser_type = ask("Node type: ") { |q| q.default = "webdriver" } unless @api
217
+ @grid_id = create_grid(name, description)
218
+ create_intranode(@grid_id, browser_type, location, nodes)
219
+ show
220
+ end
221
+
222
+ def add
223
+ @grid_id = ask("Grid ID: ") unless @grid_id
224
+ nodes = ask("Number of nodes: ") { |q| q.default = 5 }
225
+ location = ask("Location of nodes: ") { |q| q.default = "us-east" }
226
+ browser_type = ask("Node type: ") { |q| q.default = "webdriver" } unless @api
227
+ create_intranode(@grid_id, browser_type, location, nodes)
228
+ show
229
+ end
230
+
231
+ def delete
232
+ @grid_id = ask("Grid ID: ") unless @grid_id
233
+ @intranode_id= ask("Intranode ID: ") unless @intranode_id
234
+ delete_intranode
235
+ show
236
+ end
237
+
238
+ def start
239
+ @grid_id = ask("Grid ID: ") unless @grid_id
240
+ @log.debug("Starting grid ...")
241
+ begin
242
+ response = RestClient.put "#{@uri}/grid/#{@grid_id.to_s}/start.json", {:token => @token}
243
+ rescue => e
244
+ @log.error("#{e}")
245
+ end
246
+ show
247
+ end
248
+
249
+ def stop
250
+ @grid_id = ask("Grid ID: ") unless @grid_id
251
+ @log.debug("Stopping grid ...")
252
+ begin
253
+ response = RestClient.put "#{@uri}/grid/#{@grid_id.to_s}/stop.json", {:token => @token}
254
+ rescue => e
255
+ @log.error("#{e}")
256
+ end
257
+ show
258
+ end
259
+
260
+ def restart
261
+ @grid_id = ask("Grid ID: ") unless @grid_id
262
+ @log.debug("Restarting grid ...")
263
+ begin
264
+ response = RestClient.put "#{@uri}/grid/#{@grid_id.to_s}/restart.json", {:token => @token}
265
+ rescue => e
266
+ @log.error("#{e}")
267
+ end
268
+ show
269
+ end
270
+
271
+ def status
272
+ @grid_id = ask("Grid ID: ") unless @grid_id
273
+ @log.debug("Updating status of grid ...")
274
+ begin
275
+ response = RestClient.put "#{@uri}/grid/#{@grid_id.to_s}/status.json", {:token => @token}
276
+ rescue => e
277
+ @log.error("#{e}")
278
+ end
279
+ show
280
+ end
281
+
282
+ end
283
+ end
data/lib/grid.rb CHANGED
@@ -1,283 +1 @@
1
- #!/usr/bin/env ruby
2
- # grid.rb
3
- # Grid Helper
4
-
5
- require 'ap'
6
- require 'watirgrid'
7
- require 'json'
8
- require 'rest_client'
9
- require 'highline/import'
10
-
11
- class Grid
12
-
13
- def initialize(params = {})
14
- @log = Logger.new(STDOUT, 'daily')
15
- @log.level = params[:loglevel] || Logger::INFO
16
- @exclusive = params[:exclusive]
17
- @exclusive ? params[:take_all] = true : params[:read_all] = true
18
- @webdriver_browser_type = params[:browser].to_sym if params[:browser]
19
- @grid = Watir::Grid.new(params)
20
- @grid.start(params)
21
- @providers = @grid.browsers
22
- @browsers = []
23
- end
24
-
25
- def size
26
- @grid.size
27
- end
28
-
29
- def browsers
30
- @browsers
31
- end
32
-
33
- def providers
34
- @providers
35
- end
36
-
37
- def setup
38
- @grid.browsers.each_with_index do |browser, index|
39
- sleep 0.15
40
- @browsers[index] ||= browser[:object].new_browser(@webdriver_browser_type)
41
- end
42
- end
43
-
44
- def teardown
45
- @browsers.each do |browser|
46
- browser.close
47
- end
48
- @grid.release_tuples if @exclusive
49
- end
50
-
51
- def iterate &block
52
- threads = []
53
- @browsers.each do |browser|
54
- threads << Thread.new do
55
- yield browser
56
- end
57
- end
58
- threads.each {|thread| thread.join}
59
- end
60
-
61
- def iterate_with_index &block
62
- threads = []
63
- @browsers.each_with_index do |browser, index|
64
- threads << Thread.new do
65
- yield browser, index
66
- end
67
- end
68
- threads.each {|thread| thread.join}
69
- end
70
-
71
- def self.control(params = {}, &block)
72
- @exclusive = params[:exclusive]
73
- @exclusive ? params[:take_all] = true : params[:read_all] = true
74
- @webdriver_browser_type = params[:browser].to_sym if params[:browser]
75
- @grid = Watir::Grid.new(params)
76
- @grid.start(params)
77
- @browsers = []
78
- threads = []
79
- @grid.browsers.each_with_index do |browser, index|
80
- sleep rampup(params)
81
- threads << Thread.new(@webdriver_browser_type) do |webdriver_browser_type|
82
- @browser = browser[:object].new_browser(webdriver_browser_type)
83
- yield @browser, index
84
- end
85
- end
86
- threads.each {|thread| thread.join}
87
- @grid.release_tuples if @exclusive
88
- end
89
-
90
- private
91
-
92
- def self.rampup(params = {})
93
- if params[:rampup]
94
- params[:rampup] / @grid.size
95
- else
96
- 0.5
97
- end
98
- end
99
-
100
- class Helper
101
- def initialize(params = {})
102
- @grid_id = params[:grid_id]
103
- @api = params[:api]
104
- @uri = params[:uri] || "http://gridin.it/api/v0"
105
- logfile = STDOUT
106
- @log = Logger.new(logfile, 'daily')
107
- @log.level = Logger::DEBUG
108
- @log.datetime_format = "%Y-%m-%d %H:%M:%S "
109
- if home
110
- if File.file? ENV[home]+'/.gridrc'
111
- @token = open(ENV[home]+'/.gridrc') { |f| f.read }.split(':')[1]
112
- end
113
- end
114
- @token = get_token(params) unless @token
115
- @log.debug("Current token: #{@token}")
116
- end
117
-
118
- def get_password(prompt='Password: ', mask='*')
119
- ask(prompt) { |q| q.echo = mask }
120
- end
121
-
122
- def get_token(params={})
123
- if params[:token]
124
- params[:token]
125
- else
126
- HighLine.track_eof = false
127
- @email = params[:email] || ask('Email: ')
128
- @password = params[:password] || get_password
129
- response = RestClient.post "#{@uri}/token.json" , {
130
- :email => @email, :password => @password
131
- }
132
- (JSON.parse(response))["token"]
133
- end
134
- end
135
-
136
- def home
137
- homes = ["HOME", "HOMEPATH"]
138
- homes.detect {|h| ENV[h] != nil}
139
- end
140
-
141
- def token
142
- @token = get_token
143
- open(ENV[home]+'/.gridrc', 'w') { |f| f << "TOKEN:#{@token}" } if home and @token
144
- @log.debug("New token : #{@token}")
145
- end
146
-
147
- def list
148
- @log.debug("Listing grids ...")
149
- begin
150
- response = RestClient.get "#{@uri}/grid.json" , {
151
- :token => @token
152
- }
153
- ap JSON.parse(response)
154
- rescue => e
155
- @log.error("#{e}")
156
- end
157
- end
158
-
159
- def show
160
- @grid_id = ask("Grid ID: ") unless @grid_id
161
- @log.debug("Listing grid ...")
162
- begin
163
- response = RestClient.get "#{@uri}/grid/#{@grid_id}.json" , {
164
- :token => @token
165
- }
166
- ap JSON.parse(response)
167
- rescue => e
168
- @log.error("#{e}")
169
- end
170
- end
171
-
172
- def create_grid(name, description)
173
- begin
174
- @log.debug("Creating grid ...")
175
- response = RestClient.post "#{@uri}/grid.json" , {
176
- :token => @token,
177
- :name => name,
178
- :description => description
179
- }
180
- (JSON.parse(response)).first[1]["id"]
181
- rescue => e
182
- @log.error("#{e}")
183
- end
184
- end
185
-
186
- def create_intranode(grid_id, browser_type, location, nodes)
187
- begin
188
- @log.debug("Creating intranode ...")
189
- response = RestClient.post "#{@uri}/grid/#{grid_id.to_s}/intranode.json", {
190
- :token => @token,
191
- :browser_type => browser_type,
192
- :location => location,
193
- :nodes => nodes
194
- }
195
- rescue => e
196
- @log.error("#{e}")
197
- end
198
- end
199
-
200
- def delete_intranode
201
- begin
202
- @log.debug("Deleting intranode ...")
203
- response = RestClient.delete "#{@uri}/grid/intranode/#{@intranode_id}.json", {
204
- :token => @token
205
- }
206
- rescue => e
207
- @log.error("#{e}")
208
- end
209
- end
210
-
211
- def create
212
- name = ask("Grid name: ") { |q| q.default = "Grid" }
213
- description = ask("Grid description: ") { |q| q.default = "Grid created #{Time.now}" }
214
- nodes = ask("Number of nodes: ") { |q| q.default = 5 }
215
- location = ask("Location of nodes: ") { |q| q.default = "us-east" }
216
- browser_type = ask("Node type: ") { |q| q.default = "webdriver" } unless @api
217
- @grid_id = create_grid(name, description)
218
- create_intranode(@grid_id, browser_type, location, nodes)
219
- show
220
- end
221
-
222
- def add
223
- @grid_id = ask("Grid ID: ") unless @grid_id
224
- nodes = ask("Number of nodes: ") { |q| q.default = 5 }
225
- location = ask("Location of nodes: ") { |q| q.default = "us-east" }
226
- browser_type = ask("Node type: ") { |q| q.default = "webdriver" } unless @api
227
- create_intranode(@grid_id, browser_type, location, nodes)
228
- show
229
- end
230
-
231
- def delete
232
- @grid_id = ask("Grid ID: ") unless @grid_id
233
- @intranode_id= ask("Intranode ID: ") unless @intranode_id
234
- delete_intranode
235
- show
236
- end
237
-
238
- def start
239
- @grid_id = ask("Grid ID: ") unless @grid_id
240
- @log.debug("Starting grid ...")
241
- begin
242
- response = RestClient.put "#{@uri}/grid/#{@grid_id.to_s}/start.json", {:token => @token}
243
- rescue => e
244
- @log.error("#{e}")
245
- end
246
- show
247
- end
248
-
249
- def stop
250
- @grid_id = ask("Grid ID: ") unless @grid_id
251
- @log.debug("Stopping grid ...")
252
- begin
253
- response = RestClient.put "#{@uri}/grid/#{@grid_id.to_s}/stop.json", {:token => @token}
254
- rescue => e
255
- @log.error("#{e}")
256
- end
257
- show
258
- end
259
-
260
- def restart
261
- @grid_id = ask("Grid ID: ") unless @grid_id
262
- @log.debug("Restarting grid ...")
263
- begin
264
- response = RestClient.put "#{@uri}/grid/#{@grid_id.to_s}/restart.json", {:token => @token}
265
- rescue => e
266
- @log.error("#{e}")
267
- end
268
- show
269
- end
270
-
271
- def status
272
- @grid_id = ask("Grid ID: ") unless @grid_id
273
- @log.debug("Updating status of grid ...")
274
- begin
275
- response = RestClient.put "#{@uri}/grid/#{@grid_id.to_s}/status.json", {:token => @token}
276
- rescue => e
277
- @log.error("#{e}")
278
- end
279
- show
280
- end
281
-
282
- end
283
- end
1
+ require 'grid/grid'
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grid
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
4
+ hash: 11
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
- - 1
10
- version: 0.4.1
9
+ - 2
10
+ version: 0.4.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tim Koopmans
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-20 00:00:00 +10:00
18
+ date: 2011-04-26 00:00:00 +10:00
19
19
  default_executable: grid
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -253,12 +253,21 @@ files:
253
253
  - Rakefile
254
254
  - VERSION
255
255
  - bin/grid
256
+ - examples/bacon/bacon.rb
256
257
  - examples/basic/basic.rb
258
+ - examples/basic/selenium/selenium.rb
259
+ - examples/capybara/testunit/example_test.rb
257
260
  - examples/cucumber/example.feature
258
261
  - examples/cucumber/step_definitions/.DS_Store
259
262
  - examples/cucumber/step_definitions/example_steps.rb
263
+ - examples/rspec/basic_spec.rb
264
+ - examples/testunit/basic_test.rb
260
265
  - grid.gemspec
261
266
  - lib/grid.rb
267
+ - lib/grid/extensions/capybara.rb
268
+ - lib/grid/extensions/capybara/driver.rb
269
+ - lib/grid/extensions/capybara/node.rb
270
+ - lib/grid/grid.rb
262
271
  - spec/grid_spec.rb
263
272
  - spec/spec_helper.rb
264
273
  has_rdoc: true
@@ -296,7 +305,12 @@ signing_key:
296
305
  specification_version: 3
297
306
  summary: Gridinit command line utilities
298
307
  test_files:
308
+ - examples/bacon/bacon.rb
299
309
  - examples/basic/basic.rb
310
+ - examples/basic/selenium/selenium.rb
311
+ - examples/capybara/testunit/example_test.rb
300
312
  - examples/cucumber/step_definitions/example_steps.rb
313
+ - examples/rspec/basic_spec.rb
314
+ - examples/testunit/basic_test.rb
301
315
  - spec/grid_spec.rb
302
316
  - spec/spec_helper.rb