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 +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
|