sauce 1.0.2 → 2.0.0

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.
Files changed (56) hide show
  1. data/.document +5 -0
  2. data/.gitignore +30 -0
  3. data/Gemfile +16 -0
  4. data/README.markdown +39 -145
  5. data/Rakefile +46 -20
  6. data/bin/sauce +72 -61
  7. data/gemfiles/rails2.gemfile +10 -0
  8. data/gemfiles/rails2.gemfile.lock +77 -0
  9. data/gemfiles/rails3.gemfile +9 -0
  10. data/gemfiles/rails3.gemfile.lock +137 -0
  11. data/lib/generators/sauce/install/install_generator.rb +1 -2
  12. data/lib/sauce.rb +0 -22
  13. data/lib/sauce/capybara.rb +70 -32
  14. data/lib/sauce/capybara/cucumber.rb +121 -0
  15. data/lib/sauce/config.rb +57 -13
  16. data/lib/sauce/connect.rb +22 -11
  17. data/lib/sauce/integrations.rb +27 -69
  18. data/lib/sauce/jasmine.rb +35 -0
  19. data/lib/sauce/jasmine/rake.rb +47 -0
  20. data/lib/sauce/jasmine/runner.rb +4 -0
  21. data/lib/sauce/job.rb +10 -6
  22. data/lib/sauce/raketasks.rb +0 -21
  23. data/lib/sauce/selenium.rb +9 -18
  24. data/lib/sauce/utilities.rb +0 -17
  25. data/sauce.gemspec +8 -60
  26. data/spec/integration/connect_integration_spec.rb +84 -0
  27. data/spec/sauce/capybara/cucumber_spec.rb +156 -0
  28. data/spec/sauce/capybara/spec_helper.rb +42 -0
  29. data/spec/sauce/capybara_spec.rb +121 -0
  30. data/spec/sauce/config_spec.rb +239 -0
  31. data/spec/sauce/jasmine_spec.rb +49 -0
  32. data/spec/sauce/selenium_spec.rb +57 -0
  33. data/spec/spec_helper.rb +4 -0
  34. data/support/Sauce-Connect.jar +0 -0
  35. data/test/test_integrations.rb +202 -0
  36. data/test/test_testcase.rb +13 -0
  37. metadata +170 -171
  38. data/examples/helper.rb +0 -16
  39. data/examples/other_spec.rb +0 -7
  40. data/examples/saucelabs_spec.rb +0 -12
  41. data/examples/test_saucelabs.rb +0 -13
  42. data/examples/test_saucelabs2.rb +0 -9
  43. data/support/sauce_connect +0 -938
  44. data/support/selenium-server.jar +0 -0
  45. data/support/simplejson/LICENSE.txt +0 -19
  46. data/support/simplejson/__init__.py +0 -437
  47. data/support/simplejson/decoder.py +0 -421
  48. data/support/simplejson/encoder.py +0 -501
  49. data/support/simplejson/ordered_dict.py +0 -119
  50. data/support/simplejson/scanner.py +0 -77
  51. data/support/simplejson/tool.py +0 -39
  52. data/test/test_config.rb +0 -112
  53. data/test/test_connect.rb +0 -45
  54. data/test/test_job.rb +0 -13
  55. data/test/test_selenium.rb +0 -50
  56. data/test/test_selenium2.rb +0 -9
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,30 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ sauce_connect.log*
23
+ account.yml
24
+ *.gem
25
+ Gemfile.lock
26
+ .idea
27
+ .rvmrc
28
+ ondemand.yml
29
+ *.sqlite3
30
+ schema.rb
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source :gemcutter
2
+
3
+ gem 'rake'
4
+
5
+ gemspec
6
+
7
+ group :test do
8
+ gem 'cucumber'
9
+ gem 'rspec', '~> 2.9'
10
+ gem 'capybara'
11
+ gem 'jasmine'
12
+ end
13
+
14
+ group :development do
15
+ gem 'ruby-debug'
16
+ end
data/README.markdown CHANGED
@@ -1,20 +1,30 @@
1
- Sauce OnDemand is a Selenium testing cloud service, developed by Sauce Labs Inc
2
- (saucelabs.com). This is the Ruby client adapter for Sauce OnDemand.
1
+ # Sauce OnDemand for Ruby
3
2
 
4
- Features
5
- --------
3
+ Sauce OnDemand is a Selenium-based browser testing service offered by [Sauce
4
+ Labs](https://www.saucelabs.com).
6
5
 
7
- * Drop-in replacement for Selenium::Client::Driver that takes care of connecting to Sauce OnDemand
8
- * RSpec, Test::Unit, and Rails integration for tests, including automatic setup of Sauce Connect
9
- * ActiveRecord-like interface for job metadata: Find/create/destroy
10
6
 
11
- Install
12
- -------
7
+ ## Installation
13
8
 
14
- `gem install sauce`
9
+ ```bash
10
+ % gem install sauce
11
+ ```
15
12
 
16
- Rails Integration
17
- -------
13
+
14
+ ## Suggested Toolchain
15
+
16
+
17
+ The Sauce gem has been optimized to work most effectively with
18
+ [Cucumber](https://www.cukes.info) and
19
+ [Capybara](http://jnicklas.github.com/capybara/).
20
+
21
+ You can read more about how to get started with [Cucumber and Capybara on this
22
+ wiki
23
+ page](https://github.com/saucelabs/sauce\_ruby/wiki/Cucumber-and-Capybara).
24
+
25
+
26
+
27
+ ## Legacy Rails Integration
18
28
 
19
29
  You can use either RSpec or Test::Unit with Rails and Sauce OnDemand. To get started, run the generator:
20
30
 
@@ -28,11 +38,11 @@ configuration, which you can tweak inside the `Sauce.config` block if necessary.
28
38
  Here's an example test for RSpec. Drop something like this in spec/selenium/example.rb. (Because of the way RSpec categorizes tests, the "spec/selenium" directory tree is required for the integration to work properly):
29
39
 
30
40
  require "spec_helper"
31
-
41
+
32
42
  describe "my app" do
33
43
  it "should have a home page" do
34
- page.open "/"
35
- page.is_text_present("Welcome Aboard").should be_true
44
+ s.get 'http://localhost:3001/'
45
+ assert s.page_source.include? 'Welcome aboard'
36
46
  end
37
47
  end
38
48
 
@@ -42,14 +52,14 @@ Here's how you run RSpec tests with Sauce OnDemand using rake:
42
52
 
43
53
  ### Example Test::Unit test for Rails
44
54
 
45
- Here's an example test for Test::Unit. Drop something like this in test/selenium/example.rb:
55
+ Here's an example test for Test::Unit. Drop something like this in test/selenium/example\_test.rb:
46
56
 
47
57
  require "test_helper"
48
-
58
+
49
59
  class DemoTest < Sauce::RailsTestCase
50
60
  test "my app", do
51
- page.open "/"
52
- page.is_text_present("Welcome Aboard").should be_true
61
+ s.get 'http://localhost:3001/'
62
+ assert s.page_source.include? 'Welcome aboard'
53
63
  end
54
64
  end
55
65
 
@@ -57,138 +67,22 @@ Here's how you run Test::Unit tests with Sauce OnDemand using rake:
57
67
 
58
68
  `rake test:selenium:sauce`
59
69
 
60
- RSpec integration without Rails
61
- -------------------------------
62
-
63
- First, configure with your account info:
64
-
65
- `sauce config USERNAME ACCESS_KEY`
66
-
67
- And here's an example test. Drop something like this in spec/selenium/example.rb. (Because of the way RSpec categorizes tests, the "spec/selenium" directory tree is required for the integration to work properly):
68
-
69
- #!/usr/bin/env ruby
70
- #
71
- # Sample RSpec test case using the Sauce gem
72
- #
73
- require "rubygems"
74
- require "sauce"
75
-
76
- # This should go in your spec_helper.rb file if you have one
77
- Sauce.config do |config|
78
- config.browser_url = "http://saucelabs.com/"
79
- config.browsers = [
80
- ["Linux", "firefox", "3.6."]
81
- ]
82
-
83
- # uncomment this if your server is not publicly accessible
84
- #config.application_host = "localhost"
85
- #config.application_port = "80"
86
- end
87
-
88
- # If this goes in spec/selenium/foo_spec.rb, you can omit the :type parameter
89
- describe "The Sauce Labs website", :type => :selenium do
90
- it "should have a home page" do
91
- page.open "/"
92
- page.is_text_present("Sauce Labs").should be_true
93
- end
94
-
95
- it "should have a pricing page" do
96
- page.open "/"
97
- page.click "link=Pricing"
98
- page.wait_for_page_to_load 30000
99
- page.is_text_present("Free Trial").should be_true
100
- end
101
- end
102
70
 
103
- Test::Unit integration without Rails
104
- ------------------------------------
105
-
106
- First, configure with your account info:
107
-
108
- `sauce config USERNAME ACCESS_KEY`
109
-
110
- And here's an example test:
111
-
112
- #!/usr/bin/env ruby
113
- #
114
- # Sample Test:Unit test case using the Sauce gem
115
- #
116
- require "test/unit"
117
- require "rubygems"
118
- require "sauce"
119
-
120
- # This should go in your test_helper.rb file if you have one
121
- Sauce.config do |config|
122
- config.browser_url = "http://saucelabs.com/"
123
- config.browsers = [
124
- ["Linux", "firefox", "3.6."]
125
- ]
126
-
127
- # uncomment this if your server is not publicly accessible
128
- #config.application_host = "localhost"
129
- #config.application_port = "80"
130
- end
131
-
132
- class ExampleTest < Sauce::TestCase
133
- def test_sauce
134
- page.open "/"
135
- assert page.title.include?("Sauce Labs")
136
- end
137
- end
138
-
139
- Direct use of the Selenium Client driver
140
- ----------------------------------------
141
-
142
- First, configure with your account info:
143
-
144
- `sauce config USERNAME ACCESS_KEY`
145
-
146
- And here's an example test:
147
-
148
- require 'rubygems'
149
- require 'sauce'
150
- selenium = Sauce::Selenium.new(:browser_url => "http://saucelabs.com",
151
- :browser => "firefox", :browser_version => "3.", :os => "Windows 2003",
152
- :job_name => "My first test!")
153
- selenium.start
154
- selenium.open "/"
155
- selenium.stop
71
+ ### Contributing to the Gem
156
72
 
157
- Note on Patches/Pull Requests
158
- -----------------------------
73
+ * Fork the project.
74
+ * Make your feature addition or bug fix.
75
+ * Please add RSpec tests for your changes, as we don't create a new release of the gem unless all tests are passing.
76
+ * Commit
77
+ * Send a pull request. Bonus points for topic branches.
159
78
 
160
- * Fork the project.
161
- * Make your feature addition or bug fix.
162
- * Add tests for it. This is important so we don't break it in a future version unintentionally.
163
- * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
164
- * Send me a pull request. Bonus points for topic branches.
165
79
 
166
- Testing the Gem
167
- ---------------
80
+ ### Testing the Gem
168
81
 
169
- The tests in test/ need a bit of setup to get running:
82
+ Running the full test suite will require [RVM](http://rvm.beginrescueend.com)
170
83
 
171
- if you're on Ubuntu:
172
-
173
- * sudo aptitude install expect libsqlite3-dev
174
-
175
- For all platforms:
176
-
177
- * Install RVM: bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )
178
- * If you're in a headless environment, set SAUCE_TEST_NO_LOCAL=y in your environment
179
84
  * Set SAUCE_USERNAME and SAUCE_ACCESS_KEY in your environment to valid Sauce OnDemand credentials
180
85
  * bundle install
181
- * rake test
182
-
183
- If you want tests to go a bit faster, globally install the gems with native extensions:
184
-
185
- * rvm use 1.8.7@global
186
- * gem install ffi sqlite3 json
187
- * rvm use 1.9.2@global
188
- * gem install ffi sqlite3 json
189
- * rvm use default
190
-
191
- Copyright
192
- ---------
86
+ * rake spec:unit # Will just run the unit tests
87
+ * rake test # Will run *all* the tests and can be slow
193
88
 
194
- Copyright (c) 2009-2011 Sauce Labs Inc. See LICENSE for details.
data/Rakefile CHANGED
@@ -1,26 +1,53 @@
1
1
  require 'rubygems'
2
- require 'rake'
3
-
2
+ require 'bundler'
4
3
  require 'rake/testtask'
5
- Rake::TestTask.new(:test) do |test|
6
- test.libs << 'lib' << 'test'
7
- test.pattern = 'test/**/test_*.rb'
8
- test.verbose = true
4
+ require 'rspec/core/rake_task'
5
+
6
+ Bundler::GemHelper.install_tasks
7
+
8
+ namespace :spec do
9
+ rspec_options = '--color --format d --fail-fast --order random'
10
+ RSpec::Core::RakeTask.new(:unit) do |s|
11
+ s.pattern = 'spec/sauce/**_spec.rb'
12
+ s.rspec_opts = rspec_options
13
+ end
14
+
15
+ RSpec::Core::RakeTask.new(:integration) do |s|
16
+ s.pattern = 'spec/integration/**_spec.rb'
17
+ s.rspec_opts = rspec_options
18
+ end
19
+ end
20
+
21
+ task :default => :'spec:unit'
22
+
23
+ def ensure_rvm!
24
+ unless File.exists? File.expand_path("~/.rvm/scripts/rvm")
25
+ abort("I don't think you have RVM installed, which means this test will fail")
26
+ end
9
27
  end
10
28
 
11
29
  namespace :test do
12
- Rake::TestTask.new(:api) do |test|
13
- test.libs << 'lib' << 'test'
14
- test.pattern = 'test/api/test_*.rb'
15
- test.verbose = true
30
+ namespace :cucumber do
31
+ desc "Run an integration test with the cucumber-capybara code (slow)"
32
+ task :capybara do |t|
33
+ ensure_rvm!
34
+ sh "(cd examples/cucumber-capybara/ && ./run-test.sh)"
35
+ end
16
36
  end
17
- Rake::TestTask.new(:integrations) do |test|
18
- test.libs << 'lib' << 'test'
19
- test.pattern = 'test/test_integrations.rb'
20
- test.verbose = true
37
+ namespace :rails3 do
38
+ desc "Run an integration test with the rails3-demo code (slow)"
39
+ task :testunit do |t|
40
+ ensure_rvm!
41
+ sh "(cd examples/rails3-demo && ./run-test.sh)"
42
+ end
21
43
  end
22
44
  end
23
45
 
46
+ desc "Run *all* tests, this will be slow!"
47
+ task :test => [:'spec:unit', :'spec:integration',
48
+ :'test:cucumber:capybara', :'test:rails3:testunit']
49
+
50
+
24
51
  Rake::TestTask.new(:examples) do |test|
25
52
  test.libs << 'lib' << 'examples'
26
53
  test.pattern = 'examples/test_*.rb'
@@ -50,13 +77,12 @@ Rake::RDocTask.new do |rdoc|
50
77
  rdoc.rdoc_files.include('lib/**/*.rb')
51
78
  end
52
79
 
53
- task :build do
54
- system "gem build sauce.gemspec"
55
- end
56
-
57
80
  desc 'Release gem to rubygems.org'
58
81
  task :release => :build do
59
- system "gem push `ls *.gem | sort | tail -n 1`"
82
+ gems = Dir["pkg/*.gem"]
83
+ if gems
84
+ system("gem push #{gems[-1]}")
85
+ end
60
86
  end
61
87
 
62
88
  desc 'tag current version'
@@ -80,4 +106,4 @@ task :push do
80
106
  system "git push origin master --tags"
81
107
  end
82
108
 
83
- task :default => [:tag, :release, :push]
109
+ #task :default => [:tag, :release, :push]
data/bin/sauce CHANGED
@@ -10,79 +10,90 @@ require 'highline/import'
10
10
  sauce_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
11
11
  $LOAD_PATH.unshift(sauce_dir) unless $LOAD_PATH.include?(sauce_dir)
12
12
 
13
- # special case for sauce connect
14
- if ARGV.length > 0 && ARGV[0] == 'connect'
15
- require 'sauce/connect'
16
- system ([Sauce::Connect.find_sauce_connect] + ARGV[1..100]).join(" ")
17
- else
18
13
  require 'sauce'
19
14
 
20
- cmd = CmdParse::CommandParser.new(true, true)
21
- cmd.program_name = "sauce "
22
- cmd.program_version = [0, 1, 0]
15
+ cmd = CmdParse::CommandParser.new(true, true)
16
+ cmd.program_name = "sauce "
17
+ cmd.program_version = [0, 1, 0]
23
18
 
24
- cmd.add_command(CmdParse::HelpCommand.new)
19
+ cmd.add_command(CmdParse::HelpCommand.new)
25
20
 
26
- # configure
27
- class ConfigureCommand < CmdParse::Command
28
- def usage
29
- "Usage: #{commandparser.program_name}configure USERNAME ACCESS_KEY"
30
- end
21
+ class ConnectCommand < CmdParse::Command
22
+ def usage
23
+ "Usage: #{commandparser.program_name}connect"
31
24
  end
32
- configure = ConfigureCommand.new('configure', false)
33
- configure.short_desc = "Configure Sauce OnDemand credentials"
34
- configure.set_execution_block do |args|
35
- if args.length < 2
36
- puts configure.usage
37
- exit 1
38
- end
39
- username = args[0]
40
- access_key = args[1]
41
- dir = File.join(File.expand_path("~"), ".sauce")
42
- FileUtils.mkdir(dir) unless File.directory?(dir)
25
+ end
26
+ connect = ConnectCommand.new('connect', false)
27
+ connect.short_desc = 'Connect a Sauce Connect tunnel'
28
+ connect.set_execution_block do |args|
29
+ require 'sauce/connect'
30
+ require 'sauce/config'
31
+ config = Sauce::Config.new
32
+ command = "#{Sauce::Connect.connect_command} #{config.username} #{config.access_key} #{ARGV[1 .. -1]}"
33
+ exec(command)
34
+ end
35
+ cmd.add_command(connect)
43
36
 
44
- out = File.new(File.join(dir, "ondemand.yml"), 'w')
45
- out.write(YAML.dump({"username" => username, "access_key" => access_key}))
46
- out.close()
37
+
38
+ # configure
39
+ class ConfigureCommand < CmdParse::Command
40
+ def usage
41
+ "Usage: #{commandparser.program_name}configure USERNAME ACCESS_KEY"
47
42
  end
48
- cmd.add_command(configure)
43
+ end
44
+ configure = ConfigureCommand.new('configure', false)
45
+ configure.short_desc = "Configure Sauce OnDemand credentials"
46
+ configure.set_execution_block do |args|
47
+ if args.length < 2
48
+ puts configure.usage
49
+ exit 1
50
+ end
51
+ username = args[0]
52
+ access_key = args[1]
53
+ dir = File.join(File.expand_path("~"), ".sauce")
54
+ FileUtils.mkdir(dir) unless File.directory?(dir)
55
+
56
+ out = File.new(File.join(dir, "ondemand.yml"), 'w')
57
+ out.write(YAML.dump({"username" => username, "access_key" => access_key}))
58
+ out.close()
59
+ end
60
+ cmd.add_command(configure)
49
61
 
50
- #create
51
- create = CmdParse::Command.new('create', false)
52
- create.short_desc = "Create a new Sauce OnDemand account"
53
- create.set_execution_block do |args|
54
- puts "Let's create a new account!"
55
- username = ask("Username: ")
56
- password = ask("Password: ") { |q| q.echo = "*" }
57
- email = ask("Email: ")
58
- name = ask("Full name: ")
62
+ #create
63
+ create = CmdParse::Command.new('create', false)
64
+ create.short_desc = "Create a new Sauce OnDemand account"
65
+ create.set_execution_block do |args|
66
+ puts "Let's create a new account!"
67
+ username = ask("Username: ")
68
+ password = ask("Password: ") { |q| q.echo = "*" }
69
+ email = ask("Email: ")
70
+ name = ask("Full name: ")
59
71
 
60
- body = {
61
- :username => username,
62
- :password => password,
63
- :email => email,
64
- :name => name,
65
- :token => "c8eb3e2645005bcbbce7e2c208c6b7a71555d908"
66
- }.to_json
72
+ body = {
73
+ :username => username,
74
+ :password => password,
75
+ :email => email,
76
+ :name => name,
77
+ :token => "c8eb3e2645005bcbbce7e2c208c6b7a71555d908"
78
+ }.to_json
67
79
 
80
+ begin
81
+ result = RestClient.post("http://saucelabs.com/rest/v1/users",
82
+ body, :content_type => :json, :accept => :json)
83
+ rescue => e
68
84
  begin
69
- result = RestClient.post("http://saucelabs.com/rest/v1/users",
70
- body, :content_type => :json, :accept => :json)
71
- rescue => e
72
- begin
73
- puts "ERROR: #{JSON.load(e.response)['errors']}"
74
- rescue
75
- puts "ERROR: #{e.response}"
76
- end
77
- else
78
- result = JSON.load(result)
79
-
80
- puts "Account #{username} created successfully."
81
- puts "Your access key is: #{result['access_key']}"
85
+ puts "ERROR: #{JSON.load(e.response)['errors']}"
86
+ rescue
87
+ puts "ERROR: #{e.response}"
82
88
  end
89
+ else
90
+ result = JSON.load(result)
91
+
92
+ puts "Account #{username} created successfully."
93
+ puts "Your access key is: #{result['access_key']}"
83
94
  end
95
+ end
84
96
 
85
- cmd.add_command(create)
97
+ cmd.add_command(create)
86
98
 
87
- cmd.parse
88
- end
99
+ cmd.parse