sauce_whisk 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
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