sauce_whisk 0.0.8 → 0.0.9

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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZWVmNTYxMjQxNzdjYTRmMWQwNjIxNTFhZjQwYjM1M2IxZWMzNzkzYQ==
4
+ NTgwOTc5ZTkyZmNiZjU3ZmMwZmI3MDBiZTc2M2ZlZTU1ZGU2NzQ5Yw==
5
5
  data.tar.gz: !binary |-
6
- ZDVlOTFhNWEwYzM2OWI4MTM2Y2I5YTJhZmYyMTRmNDdhZDljMTIwOQ==
6
+ NzBiNDA1MmFkNTEzNjJhYzE1NTc1ZDhiMDBjZGI3YzM4NDNhYTdkMg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- ZTdlMzRiMTk1ZTljM2Q3ODhmMGNiZDcwMzE2ZDAwZTkyYTE4Y2ZkYTdmMzdh
10
- YTBiNWMzOWIxNzA3NWJmMTk5OWQzMDhlNzJkMGI4NTU5NmRjYzM0Yzc3ODY3
11
- ODMxMTc4MjdiMWYyMjM0Mzc2NDEzYjUxYjcyODZjZmUxNWFjMDQ=
9
+ ZGQ4ODNiZDQ5YTA5ZDI4ZGFlZTk1Y2MxYTRhOWJlNTA3YzM2NDhhNTJjMzg5
10
+ ODhiYzA1NGI5NTVlZGM5Y2I3ZjY5NTJiOTM2NTExYmI5NDVlOTdhNmVmNGY0
11
+ ODJjMjZmYjgwZWFkMzQyMTk1YTBlOTZlMjBmOWUzNDc2YTUxYTI=
12
12
  data.tar.gz: !binary |-
13
- Y2ZmZmM3ZWFlODljZDI0NGI1YTU1NjhkNmQxNmZhMDI2YmMxZmFiOWZjOGJh
14
- YjQ4M2Y5OGQ2MzE5NjJmOTQxNmFhYTRhMjU1ZGE1NDAyZTkzYWYzNDIzMTNk
15
- MDI4OGYwNGUxYjRjZTU3YmQyMjhlNmU3YjJiMTY3ODA0ZDYxOTg=
13
+ YWJlYWVhZjc3NzBkMjBiMzk4ZDdjYjAzZWY0MjNhYmM2Yjc2MzEwZDMxMTc5
14
+ NjQzMWEyYWJjZmFmYzBjY2YyNTZmODVhNjgzMjgyY2Y5ZTI1MmNkZGEyM2U1
15
+ YzI1YzhiMGQ1OTVjNTc5OWM2YzYyNTQwNDk1OTQwZGE3MmMxMjc=
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ rdoc
15
15
  spec/reports
16
16
  test/tmp
17
17
  test/version_tmp
18
+ .idea
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile CHANGED
@@ -2,8 +2,8 @@ source 'https://rubygems.org'
2
2
 
3
3
  gem "pry"
4
4
 
5
- #group :test do
6
- # gem 'psych', "2.0.0", :path => "./vendor/psych"
7
- #end
5
+ group :test do
6
+ gem 'psych', "2.0.0", :path => "./vendor/psych"
7
+ end
8
8
 
9
9
  gemspec
data/README.md CHANGED
@@ -88,6 +88,35 @@ There are three types of asset for Sauce Labs jobs: screenshots, video and logs.
88
88
  video = job.video # A single Asset, holding the video
89
89
  ```
90
90
 
91
+ ### Accounts
92
+
93
+ At the moment, it is only possible to query existing accounts using the API gem.
94
+
95
+ #### Retrieving a specific account
96
+ ```ruby
97
+ my_account = SauceWhisk::Accounts.fetch "account_name" # Returns a SauceWhisk::Account object, with its concurrency limit
98
+ my_account = SauceWhisk::Accounts.fetch("account_name", false) # Returns a SauceWhisk::Account object, does not fetch its concurrency limit
99
+ ```
100
+
101
+ `SauceWhisk::Account` objects don't do anything other then store data about the relevant account:
102
+
103
+ ```ruby
104
+ my_account.username # Sauce Labs Username
105
+ my_account.access_key # Sauce Labs Access Key (For automated test authentication... Not your password)
106
+ my_account.minutes # Total number of minutes available
107
+ my_account.total_concurrency # Number of concurrent jobs allowed
108
+ my_account.mac_concurrency # Number of concurrent Mac hosted jobs allowed (includes iPad, iPhone, Mac)
109
+ ```
110
+
111
+ #### Retrieving the concurrency limits for an account
112
+
113
+ If you exceed your concurrency limits, your tests will be queued waiting for a free VM. This may cause erroneous failures in your test cases, and no-one wants that.
114
+ ```ruby
115
+ concurrencies = SauceWhisk::Accounts.concurrency_for "account_name" # Hash containing both concurrency limits
116
+ mac_concurrency = SauceWhisk::Accounts.concurrency_for "account_name", :mac # Fixnum of just the Mac limit
117
+ total_concurrency = SauceWhisk::Accounts.concurrency_for "account_name", :total # Fixnum of the upper concurrency limit
118
+ ```
119
+
91
120
  ### Tunnels
92
121
 
93
122
  Tunnels give information about currently running [Sauce Connect](https://saucelabs.com/docs/connect) tunnels for a given user.
@@ -118,6 +147,57 @@ tunnel.stop # Stops the Tunnel
118
147
  SauceWhisk::Tunnels.stop tunnel_id # Stops the tunnel with the given id
119
148
  ```
120
149
 
150
+ ### Generic Sauce Labs Information
151
+
152
+ The Sauce class returns non-user-specific info about available platforms, the number of jobs run, and the status of Sauce Labs' infrastructure.
153
+
154
+ These can be used without authentication.
155
+
156
+ #### Fetch All Available Platforms
157
+
158
+ You can obtain an Array of all available webdriver platforms using `SauceWhisk::Sauce.platforms`:
159
+
160
+ ```ruby
161
+ platforms = SauceWhisk::Sauce.platforms # Fetch all platforms or return cached values
162
+ platforms = SauceWhisk::Sauce.platforms(true) # Force a fetch of all platforms
163
+
164
+ platforms.first # => A Hash of platform details:
165
+
166
+ {
167
+ "long_name"=>"Firefox", # Full name of the platform's browser
168
+ "api_name"=>"firefox", # desired_capabilities name of the platform
169
+ "long_version"=>"20.0.1.", # Full version number for the platform's browser
170
+ "preferred_version"=>"", # Preferred version of the platform's browser (If none is requested)
171
+ "automation_backend"=>"webdriver", # Whether this is a Webdriver or Selenium-rc driven platform
172
+ "os"=>"Linux", # desired_capabilities name of the Platform's Operating System
173
+ "short_version"=>"20" # desired_capabilities name of the Platform's Browsers's version
174
+ }
175
+ ```
176
+
177
+ The most important values for a platform are the **os**, **api_name**, **short_version** fields. These are the values to use for desired_capabilites *os*, *browser* and *browser_version* respectively.
178
+
179
+ The gem does not support retrieval of selenium-rc platforms at the current time
180
+
181
+ #### Count
182
+
183
+ ```ruby
184
+ all_tests = SauceWhisk::Sauce.total_job_count # The total number of jobs ever run with Sauce Labs' help
185
+ ```
186
+
187
+ #### Service Status
188
+
189
+ ```ruby
190
+ status = SauceWhisk::Sauce.service_status # Check the status of Sauce Labs' service
191
+
192
+ status.inspect # =>
193
+
194
+ {
195
+ :wait_time=>0.39880952380952384, # Delay between requesting a job and it starting
196
+ :service_operational=>true, # Operational Status -- Boolean
197
+ :status_message=>"Basic service status checks passed." # More info when erros occuring
198
+ }
199
+ ```
200
+
121
201
  ### Logger
122
202
 
123
203
  You can set a custom logger object, passing anything that responds to puts:
@@ -130,7 +210,7 @@ SauceWhisk.logger defaults to STDOUT.
130
210
 
131
211
  ## Contributing
132
212
 
133
- 1. Fork it
213
+ 1. Fork the [sauce-labs version](https://github.com/sauce-labs/sauce_whisk) of this repository
134
214
  2. Create your feature branch (`git checkout -b my-new-feature`)
135
215
  3. Commit your changes (`git commit -am 'Add some feature'`)
136
216
  4. Push to the branch (`git push origin my-new-feature`)
@@ -3,7 +3,7 @@ module SauceWhisk
3
3
  extend SauceWhisk::RestRequestBuilder
4
4
 
5
5
  def self.fetch(user_id = ENV["SAUCE_USERNAME"], get_concurrency = true)
6
- user_parameters = JSON.parse get "users/#{user_id}"
6
+ user_parameters = JSON.parse (get "users/#{user_id}"), :symbolize_names => true
7
7
  concurrencies = get_concurrency ? concurrency_for(user_id) : {}
8
8
 
9
9
  account_parameters = user_parameters.merge concurrencies
@@ -28,6 +28,22 @@ module SauceWhisk
28
28
  RestClient::Request.execute({:method => :delete, :url => resource_to_delete}.merge auth_details)
29
29
  end
30
30
 
31
+ def post(resource_parameters)
32
+ url = fully_qualified_resource
33
+ length = resource_parameters.length
34
+ headers = {"Content-Length" => length}
35
+ req_params = {
36
+ :method => :post,
37
+ :url => url,
38
+ :payload => resource_parameters,
39
+ :content_type => "application/json",
40
+ :headers => headers
41
+ }
42
+
43
+ RestClient::Request.execute(req_params.merge auth_details)
44
+
45
+ end
46
+
31
47
  def auth_details
32
48
  {:user => SauceWhisk.username, :password => SauceWhisk.password}
33
49
  end
@@ -23,6 +23,11 @@ module SauceWhisk
23
23
  return tunnels
24
24
  end
25
25
 
26
+ def self.open(opts)
27
+ #opts[:tunnel_identifier] = opts.delete :tunnel_id
28
+ new_tunnel_parameters = JSON.parse post opts.to_json
29
+ end
30
+
26
31
  def self.stop tunnel_id
27
32
  delete tunnel_id
28
33
  end
@@ -1,3 +1,3 @@
1
1
  module SauceWhisk
2
- VERSION = "0.0.8"
2
+ VERSION = "0.0.9"
3
3
  end
@@ -136,43 +136,7 @@ http_interactions:
136
136
  - '36'
137
137
  body:
138
138
  encoding: US-ASCII
139
- string: &1 !ruby/string
140
- str: '["5da3256813fd409ba7927004b499a5cf"]'
141
- net_http_res: !ruby/object:Net::HTTPOK
142
- http_version: '1.0'
143
- code: '200'
144
- message: OK
145
- header:
146
- server:
147
- - nginx/0.7.62
148
- date:
149
- - Tue, 11 Jun 2013 06:49:07 GMT
150
- content-type:
151
- - application/json
152
- connection:
153
- - keep-alive
154
- pragma:
155
- - no-cache
156
- cache-control:
157
- - no-cache
158
- x-frame-options:
159
- - DENY
160
- set-cookie:
161
- - csrf_token=90135ac06149df70abf84010839f0d84; expires="Tue, 11-Jun-2013
162
- 07:06:13 GMT"; Max-Age=600; Path=/
163
- - metrics=74fb9ada210b5a86c395fa69c78b7ece36c584aab137e19870e94bcdb0a2e17bbd96f144;
164
- Path=/
165
- content-length:
166
- - '36'
167
- body: *1
168
- read: true
169
- __read_body_previously_called: true
170
- args:
171
- :method: :get
172
- :url: https://saucelabs.com/rest/v1/dylanatsauce/tunnels
173
- :user: dylanatsauce
174
- :password: 8f5210dd-f0cf-477f-b720-9f721a9679a4
175
- code: 200
139
+ string: '["5da3256813fd409ba7927004b499a5cf"]'
176
140
  http_version:
177
141
  recorded_at: Tue, 11 Jun 2013 06:56:16 GMT
178
142
  - request:
@@ -226,4 +190,54 @@ http_interactions:
226
190
  ["64703"], "ScriptName": "sauce_connect", "Ports": ["80"]}}'
227
191
  http_version:
228
192
  recorded_at: Tue, 11 Jun 2013 07:10:26 GMT
193
+ - request:
194
+ method: post
195
+ uri: https://<SAUCE_USERNAME>:<SAUCE_ACCESS_KEY>@saucelabs.com/rest/v1/<SAUCE_USERNAME>/tunnels
196
+ body:
197
+ encoding: UTF-8
198
+ string: '{"tunnel_identifier":"KarlMarx"}'
199
+ headers:
200
+ Accept:
201
+ - '*/*; q=0.5, application/xml'
202
+ Accept-Encoding:
203
+ - gzip, deflate
204
+ Content-Length:
205
+ - '85'
206
+ User-Agent:
207
+ - Ruby
208
+ response:
209
+ status:
210
+ code: 200
211
+ message: OK
212
+ headers:
213
+ Server:
214
+ - nginx/0.7.62
215
+ Date:
216
+ - Tue, 30 Jul 2013 08:38:22 GMT
217
+ Content-Type:
218
+ - application/json
219
+ Connection:
220
+ - keep-alive
221
+ Pragma:
222
+ - no-cache
223
+ Cache-Control:
224
+ - no-cache
225
+ X-Frame-Options:
226
+ - DENY
227
+ Set-Cookie:
228
+ - csrf_token=3c66b97477a4dedd1255faf05ce90d66; expires="Tue, 30-Jul-2013 08:56:35
229
+ GMT"; Max-Age=600; Path=/
230
+ - metrics=034bd00d05345d3992282b0f28e816878971ff1a86e9ab91ce174a2e89dcab18527fa539;
231
+ Path=/
232
+ Content-Length:
233
+ - '352'
234
+ body:
235
+ encoding: US-ASCII
236
+ string: '{"status": "new", "direct_domains": null, "shutdown_time": null, "ssh_port":
237
+ 9123, "user_shutdown": null, "use_caching_proxy": false, "creation_time":
238
+ 1375173995, "domain_names": null, "shared_tunnel": null, "tunnel_identifier":
239
+ "KarlMarx", "host": null, "owner": "<SAUCE_USERNAME>", "use_kgp": true, "id":
240
+ "4824d6b282e04d1184daff5401a52e1e", "metadata": null}'
241
+ http_version:
242
+ recorded_at: Tue, 30 Jul 2013 08:46:35 GMT
229
243
  recorded_with: VCR 2.5.0
@@ -10,7 +10,12 @@ describe SauceWhisk::Accounts, :vcr => {:cassette_name => "accounts"} do
10
10
  end
11
11
 
12
12
  it "returns an Account object" do
13
- SauceWhisk::Accounts.fetch(ENV["SAUCE_USERNAME"]).should be_an_instance_of SauceWhisk::Account
13
+ username = ENV["SAUCE_USERNAME"]
14
+ account = SauceWhisk::Accounts.fetch(username)
15
+ account.should be_an_instance_of SauceWhisk::Account
16
+
17
+ account.username.should eq username
18
+ account.access_key.should_not be_nil
14
19
  end
15
20
 
16
21
  it "includes the concurrency by default" do
@@ -69,6 +69,44 @@ describe SauceWhisk::RestRequestBuilder do
69
69
  end
70
70
  end
71
71
 
72
+ begin
73
+ describe "#post", :vcr => {:cassette_name => 'tunnels'} do
74
+ let(:expected_payload) {{:tunnel_identifier => "KarlMarx"}.to_json}
75
+ it "calls the base URL" do
76
+ expected_url = "#{SauceWhisk.base_url}/#{dummy_client.resource}"
77
+ RestClient::Request.should_receive(:execute).with(hash_including({:url => expected_url}))
78
+
79
+ dummy_client.post expected_payload
80
+ end
81
+
82
+ it "uses the correct method" do
83
+ RestClient::Request.should_receive(:execute).with(hash_including({:method => :post}))
84
+ dummy_client.post expected_payload
85
+ end
86
+
87
+ it "includes the correct payload" do
88
+ RestClient::Request.should_receive(:execute).with(hash_including({:payload => expected_payload}))
89
+ dummy_client.post expected_payload
90
+ end
91
+
92
+ it "includes the correct content_type" do
93
+ RestClient::Request.should_receive(:execute).with(hash_including({:content_type => "application/json"}))
94
+ dummy_client.post expected_payload
95
+ end
96
+
97
+ it "includes the correct length" do
98
+ expected_length = expected_payload.length
99
+ RestClient::Request.should_receive(:execute).with(hash_including({:headers => {"Content-Length" => expected_length}}))
100
+ dummy_client.post expected_payload
101
+ end
102
+
103
+ it "includes the authentication parameters" do
104
+ RestClient::Request.should_receive(:execute).with(hash_including(mock_auth))
105
+ dummy_client.post expected_payload
106
+ end
107
+ end
108
+ end
109
+
72
110
  describe "#put", :vcr => {:cassette_name => 'jobs'} do
73
111
  let(:expected_url) {"#{SauceWhisk.base_url}/#{dummy_client.resource}/something"}
74
112
  it "calls the base URL with the put method" do
@@ -51,4 +51,13 @@ describe SauceWhisk::Tunnels, :vcr => {:cassette_name => "tunnels"} do
51
51
  assert_requested :delete, "https://#{auth}@saucelabs.com/rest/v1/dylanatsauce/tunnels/#{tunnel_id}"
52
52
  end
53
53
  end
54
+
55
+ describe "##open" do
56
+ it "calls the correct API method" do
57
+ params = {:tunnel_identifier => "bees", :ssh_port => 9123, :use_caching_proxy => false, :use_kgp => true}
58
+
59
+ SauceWhisk::Tunnels.open params
60
+ assert_requested(:post, "https://#{auth}@saucelabs.com/rest/v1/dylanatsauce/tunnels",:body => params.to_json)
61
+ end
62
+ end
54
63
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sauce_whisk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dylan Lacey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-24 00:00:00.000000000 Z
11
+ date: 2013-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -88,6 +88,7 @@ extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
90
  - .gitignore
91
+ - .rspec
91
92
  - .ruby-gemset
92
93
  - .ruby-version
93
94
  - Gemfile