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 +8 -8
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/Gemfile +3 -3
- data/README.md +81 -1
- data/lib/sauce_whisk/accounts.rb +1 -1
- data/lib/sauce_whisk/rest_request_builder.rb +16 -0
- data/lib/sauce_whisk/tunnels.rb +5 -0
- data/lib/sauce_whisk/version.rb +1 -1
- data/spec/fixtures/vcr_cassettes/tunnels.yml +51 -37
- data/spec/lib/sauce_whisk/accounts_spec.rb +6 -1
- data/spec/lib/sauce_whisk/rest_request_builder_spec.rb +38 -0
- data/spec/lib/sauce_whisk/tunnels_spec.rb +9 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NTgwOTc5ZTkyZmNiZjU3ZmMwZmI3MDBiZTc2M2ZlZTU1ZGU2NzQ5Yw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NzBiNDA1MmFkNTEzNjJhYzE1NTc1ZDhiMDBjZGI3YzM4NDNhYTdkMg==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZGQ4ODNiZDQ5YTA5ZDI4ZGFlZTk1Y2MxYTRhOWJlNTA3YzM2NDhhNTJjMzg5
|
10
|
+
ODhiYzA1NGI5NTVlZGM5Y2I3ZjY5NTJiOTM2NTExYmI5NDVlOTdhNmVmNGY0
|
11
|
+
ODJjMjZmYjgwZWFkMzQyMTk1YTBlOTZlMjBmOWUzNDc2YTUxYTI=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YWJlYWVhZjc3NzBkMjBiMzk4ZDdjYjAzZWY0MjNhYmM2Yjc2MzEwZDMxMTc5
|
14
|
+
NjQzMWEyYWJjZmFmYzBjY2YyNTZmODVhNjgzMjgyY2Y5ZTI1MmNkZGEyM2U1
|
15
|
+
YzI1YzhiMGQ1OTVjNTc5OWM2YzYyNTQwNDk1OTQwZGE3MmMxMjc=
|
data/.gitignore
CHANGED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
CHANGED
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
|
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`)
|
data/lib/sauce_whisk/accounts.rb
CHANGED
@@ -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
|
data/lib/sauce_whisk/tunnels.rb
CHANGED
data/lib/sauce_whisk/version.rb
CHANGED
@@ -136,43 +136,7 @@ http_interactions:
|
|
136
136
|
- '36'
|
137
137
|
body:
|
138
138
|
encoding: US-ASCII
|
139
|
-
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
|
-
|
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.
|
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-
|
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
|