browserstack 0.0.1
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.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +107 -0
- data/Rakefile +1 -0
- data/browserstack.gemspec +23 -0
- data/lib/browserstack.rb +5 -0
- data/lib/browserstack/client.rb +106 -0
- data/lib/browserstack/version.rb +3 -0
- data/spec/browserstack/client_spec.rb +90 -0
- data/spec/browserstack_spec.rb +10 -0
- data/spec/spec_helper.rb +7 -0
- metadata +149 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use 1.9.3@browserstack --create
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Rahul Nawani
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
# Browserstack
|
2
|
+
|
3
|
+
A ruby gem for working with [BrowserStack](http://browserstack.com) through its [API](https://github.com/browserstack/api).(V2 API only)
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'browserstack'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install browserstack
|
18
|
+
|
19
|
+
## Example of Use
|
20
|
+
|
21
|
+
First, you're probably gonna want to require it:
|
22
|
+
|
23
|
+
``` ruby
|
24
|
+
require 'browserstack'
|
25
|
+
```
|
26
|
+
|
27
|
+
### Creating Client
|
28
|
+
Creates a new client instance.
|
29
|
+
|
30
|
+
* `settings`: A hash of settings that apply to all requests for the new client.
|
31
|
+
* `username`: The username for the BrowserStack account.
|
32
|
+
* `password`: The password for the BrowserStack account.
|
33
|
+
|
34
|
+
``` ruby
|
35
|
+
settings = {username: "foo", password: "foobar"}
|
36
|
+
client = Browserstack::Client.new(settings)
|
37
|
+
```
|
38
|
+
|
39
|
+
###API
|
40
|
+
|
41
|
+
####Getting available browsers
|
42
|
+
Fetches all available browsers.
|
43
|
+
|
44
|
+
``` ruby
|
45
|
+
client.get_browsers #returns a hash
|
46
|
+
```
|
47
|
+
|
48
|
+
or for a specific OS
|
49
|
+
|
50
|
+
``` ruby
|
51
|
+
client.get_browsers("mac")
|
52
|
+
```
|
53
|
+
|
54
|
+
####Getting list of supported OS
|
55
|
+
|
56
|
+
``` ruby
|
57
|
+
client.get_supported_os_list
|
58
|
+
```
|
59
|
+
|
60
|
+
####Creating a worker
|
61
|
+
A worker is simply a new browser instance.
|
62
|
+
|
63
|
+
``` ruby
|
64
|
+
enc_url = URI.escape("http://example.com/?a=\111\\115")
|
65
|
+
settings = {os: "win", browser: "ie7", version: "4.0", url: enc_url}
|
66
|
+
worker_id = client.create_worker(settings)
|
67
|
+
```
|
68
|
+
A worker id is returned after worker gets created.
|
69
|
+
|
70
|
+
* `settings`: A hash of settings for the worker
|
71
|
+
* `os`: Which OS to use for the new worker.
|
72
|
+
* `browser`/`device`: Which browser/device to use in the new worker. Which property to use depends on the OS.
|
73
|
+
* `version`: Which version of the specified browser to use.
|
74
|
+
* `url` : Which URL to navigate to upon creation.
|
75
|
+
* `timeout` (optional): defaults to 300 seconds. Use 0 for "forever" (BrowserStack will kill the worker after 1,800 seconds).
|
76
|
+
|
77
|
+
####Terminating a worker
|
78
|
+
Use this method to terminate an active worker. A hash with indicating how long the worker was alive is returned.
|
79
|
+
|
80
|
+
``` ruby
|
81
|
+
data = client.terminate_worker(worker_id)
|
82
|
+
```
|
83
|
+
|
84
|
+
####Getting worker status
|
85
|
+
Determines whether the worker is in queue, running or terminated.
|
86
|
+
|
87
|
+
``` ruby
|
88
|
+
status = client.worker_status(worker_id)
|
89
|
+
```
|
90
|
+
|
91
|
+
* `status`: A string representing the current status of the worker.
|
92
|
+
* Possible statuses: `"running"`, `"queue"`, `"terminated"`.
|
93
|
+
|
94
|
+
####Getting all workers of a client
|
95
|
+
|
96
|
+
``` ruby
|
97
|
+
workers = client.get_workers
|
98
|
+
```
|
99
|
+
Returns an array of all workers with all their properties
|
100
|
+
|
101
|
+
## Contributing
|
102
|
+
|
103
|
+
1. Fork it
|
104
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
105
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
106
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
107
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'browserstack/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "browserstack"
|
8
|
+
gem.version = Browserstack::VERSION
|
9
|
+
gem.authors = ["Rahul Nawani"]
|
10
|
+
gem.email = ["rahulnwn@gmail.com"]
|
11
|
+
gem.description = %q{Ruby gem for interacting with the Browserstack API}
|
12
|
+
gem.summary = %q{Ruby gem for interacting with the Browserstack API}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
gem.add_development_dependency("rake")
|
20
|
+
gem.add_development_dependency("rspec", "2.11.0")
|
21
|
+
gem.add_development_dependency("webmock", "1.8.11")
|
22
|
+
gem.add_dependency("yajl-ruby", "1.1.0")
|
23
|
+
end
|
data/lib/browserstack.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
module Browserstack
|
2
|
+
HOSTNAME = "api.browserstack.com"
|
3
|
+
class Client
|
4
|
+
attr_reader :browsers, :version
|
5
|
+
|
6
|
+
def initialize(params)
|
7
|
+
params ||= {}
|
8
|
+
|
9
|
+
raise ArgumentError, "Username is required" unless params[:username]
|
10
|
+
raise ArgumentError, "Password is required" unless params[:password]
|
11
|
+
|
12
|
+
@authentication = "Basic " + Base64.encode64("#{params[:username]}:#{params[:password]}").strip
|
13
|
+
|
14
|
+
@version = 2
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_browsers(os = nil)
|
18
|
+
if update_cache?
|
19
|
+
connection = create_new_connection
|
20
|
+
call = Net::HTTP::Get.new("/#{self.version}/browsers")
|
21
|
+
add_authentication(call)
|
22
|
+
res = make_request(connection, call)
|
23
|
+
@latest_update = Time.now
|
24
|
+
parser = Yajl::Parser.new(:symbolize_keys => true)
|
25
|
+
@browsers = parser.parse(res.body)
|
26
|
+
end
|
27
|
+
return_with_os(os)
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_worker(settings)
|
31
|
+
settings ||= {}
|
32
|
+
connection = create_new_connection
|
33
|
+
call = Net::HTTP::Post.new("/#{self.version}/worker")
|
34
|
+
call.set_form_data(settings)
|
35
|
+
add_authentication(call)
|
36
|
+
res = make_request(connection, call)
|
37
|
+
Yajl::Parser.parse(res.body)['id']
|
38
|
+
end
|
39
|
+
|
40
|
+
def terminate_worker(worker_id)
|
41
|
+
connection = create_new_connection
|
42
|
+
call = Net::HTTP::Delete.new("/#{self.version}/worker/#{worker_id}")
|
43
|
+
add_authentication(call)
|
44
|
+
res = make_request(connection, call)
|
45
|
+
parser = Yajl::Parser.new(:symbolize_keys => true)
|
46
|
+
parser.parse(res.body)
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_worker_status(worker_id)
|
50
|
+
connection = create_new_connection
|
51
|
+
call = Net::HTTP::Get.new("/#{self.version}/worker/#{worker_id}")
|
52
|
+
add_authentication(call)
|
53
|
+
res = make_request(connection, call)
|
54
|
+
parser = Yajl::Parser.new(:symbolize_keys => true)
|
55
|
+
parser.parse(res.body)
|
56
|
+
end
|
57
|
+
|
58
|
+
def get_workers
|
59
|
+
connection = create_new_connection
|
60
|
+
call = Net::HTTP::Get.new("/#{self.version}/workers")
|
61
|
+
add_authentication(call)
|
62
|
+
res = make_request(connection, call)
|
63
|
+
parser = Yajl::Parser.new(:symbolize_keys => true)
|
64
|
+
parser.parse(res.body)
|
65
|
+
end
|
66
|
+
|
67
|
+
def get_supported_os_list
|
68
|
+
get_browsers.keys.map { |os| os.to_s }
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
def create_new_connection
|
73
|
+
Net::HTTP.new(HOSTNAME, 80)
|
74
|
+
end
|
75
|
+
|
76
|
+
def add_authentication(call)
|
77
|
+
call["Authorization"] = @authentication
|
78
|
+
end
|
79
|
+
|
80
|
+
def make_request(connection, call)
|
81
|
+
res = connection.request(call)
|
82
|
+
case res.code.to_i
|
83
|
+
when 200
|
84
|
+
res
|
85
|
+
when 401
|
86
|
+
raise "Unauthorized User".inspect
|
87
|
+
when 422
|
88
|
+
raise_validation_error
|
89
|
+
else
|
90
|
+
raise res.body.inspect
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def raise_validation_error
|
95
|
+
raise res.body.inspect
|
96
|
+
end
|
97
|
+
|
98
|
+
def update_cache?
|
99
|
+
@latest_update.nil? || (Time.now - @latest_update > 86400) #cache for one day
|
100
|
+
end
|
101
|
+
|
102
|
+
def return_with_os(os)
|
103
|
+
os ? @browsers[os.to_sym] : @browsers
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Browserstack::Client do
|
4
|
+
before do
|
5
|
+
@params = {username: "foobar", password: "1234"}
|
6
|
+
@client = Browserstack::Client.new(@params)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#initialize" do
|
10
|
+
it "should create a new client object" do
|
11
|
+
@client.should be_an_instance_of(Browserstack::Client)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should raise an error without username params" do
|
15
|
+
@params.delete(:username)
|
16
|
+
expect { Browserstack::Client.new(@params) }.to raise_error("Username is required")
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should raise an error without password params" do
|
20
|
+
@params.delete(:password)
|
21
|
+
expect { Browserstack::Client.new(@params) }.to raise_error("Password is required")
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should set API version as 2" do
|
25
|
+
@client.version.should == 2
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "get_broswers" do
|
31
|
+
before do
|
32
|
+
@browsers = "{\"ios\":[{\"device\":\"iPhone 3GS\",\"version\":\"3.0\"}],\"android\":[{\"device\":\"Samsung Galaxy S\",\"version\":\"2.1\"}],\"mac\":[{\"version\":\"4.0\",\"browser\":\"safari\"}],\"win\":[{\"version\":\"4.0\",\"browser\":\"safari\"}]}"
|
33
|
+
stub_request(:get, "http://#{@params[:username]}:#{@params[:password]}@api.browserstack.com/#{@client.version}/browsers").
|
34
|
+
with(:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
|
35
|
+
to_return(:status => 200, :body => @browsers, :headers => {})
|
36
|
+
parser = Yajl::Parser.new(:symbolize_keys => true)
|
37
|
+
@parsed_data = parser.parse(@browsers)
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when no os argument passed" do
|
41
|
+
it "should return a hash of all os browsers" do
|
42
|
+
browsers = @client.get_browsers
|
43
|
+
browsers.should == @parsed_data
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should update cache depending on last updated" do
|
47
|
+
browsers = @client.get_browsers
|
48
|
+
@client.stub("update_cache?").and_return(true)
|
49
|
+
@browsers = "{\"ios\":[{\"device\":\"iPhone 3GS\",\"version\":\"3.0\"}],\"android\":[{\"device\":\"Samsung Galaxy S\",\"version\":\"2.1\"}],\"mac\":[{\"version\":\"4.0\",\"browser\":\"safari\"}]}"
|
50
|
+
stub_request(:get, "http://#{@params[:username]}:#{@params[:password]}@api.browserstack.com/#{@client.version}/browsers").
|
51
|
+
with(:headers => {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
|
52
|
+
to_return(:status => 200, :body => @browsers, :headers => {})
|
53
|
+
updated_browsers = @client.get_browsers
|
54
|
+
updated_browsers[:win].should be_nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "when os argument passed" do
|
59
|
+
it "should return a hash of browsers of that os" do
|
60
|
+
browsers = @client.get_browsers(:win)
|
61
|
+
browsers.should == @parsed_data[:win]
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should return nil if invalid argument passed" do
|
65
|
+
browsers = @client.get_browsers("windows7")
|
66
|
+
browsers.should be_nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "create_worker" do
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "terminate_worker" do
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "get_worker_status" do
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "get_workers" do
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "get_supported_os_list" do
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Browserstack do
|
4
|
+
describe "create_client" do
|
5
|
+
it "should create a new client object" do
|
6
|
+
@client = Browserstack.create_client(username: "foo", password: "testing")
|
7
|
+
@client.should be_an_instance_of(Browserstack::Client)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: browserstack
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Rahul Nawani
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-10-15 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - '='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 2.11.0
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - '='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.11.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: webmock
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - '='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.8.11
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.8.11
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: yajl-ruby
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - '='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.1.0
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - '='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.1.0
|
78
|
+
description: Ruby gem for interacting with the Browserstack API
|
79
|
+
email:
|
80
|
+
- rahulnwn@gmail.com
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- !binary |-
|
86
|
+
LmdpdGlnbm9yZQ==
|
87
|
+
- !binary |-
|
88
|
+
LnJzcGVj
|
89
|
+
- !binary |-
|
90
|
+
LnJ2bXJj
|
91
|
+
- !binary |-
|
92
|
+
R2VtZmlsZQ==
|
93
|
+
- !binary |-
|
94
|
+
TElDRU5TRS50eHQ=
|
95
|
+
- !binary |-
|
96
|
+
UkVBRE1FLm1k
|
97
|
+
- !binary |-
|
98
|
+
UmFrZWZpbGU=
|
99
|
+
- !binary |-
|
100
|
+
YnJvd3NlcnN0YWNrLmdlbXNwZWM=
|
101
|
+
- !binary |-
|
102
|
+
bGliL2Jyb3dzZXJzdGFjay5yYg==
|
103
|
+
- !binary |-
|
104
|
+
bGliL2Jyb3dzZXJzdGFjay9jbGllbnQucmI=
|
105
|
+
- !binary |-
|
106
|
+
bGliL2Jyb3dzZXJzdGFjay92ZXJzaW9uLnJi
|
107
|
+
- !binary |-
|
108
|
+
c3BlYy9icm93c2Vyc3RhY2svY2xpZW50X3NwZWMucmI=
|
109
|
+
- !binary |-
|
110
|
+
c3BlYy9icm93c2Vyc3RhY2tfc3BlYy5yYg==
|
111
|
+
- !binary |-
|
112
|
+
c3BlYy9zcGVjX2hlbHBlci5yYg==
|
113
|
+
homepage: ''
|
114
|
+
licenses: []
|
115
|
+
post_install_message:
|
116
|
+
rdoc_options: []
|
117
|
+
require_paths:
|
118
|
+
- lib
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
none: false
|
121
|
+
requirements:
|
122
|
+
- - ! '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
segments:
|
126
|
+
- 0
|
127
|
+
hash: 3393997254230974074
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
segments:
|
135
|
+
- 0
|
136
|
+
hash: 3393997254230974074
|
137
|
+
requirements: []
|
138
|
+
rubyforge_project:
|
139
|
+
rubygems_version: 1.8.24
|
140
|
+
signing_key:
|
141
|
+
specification_version: 3
|
142
|
+
summary: Ruby gem for interacting with the Browserstack API
|
143
|
+
test_files:
|
144
|
+
- !binary |-
|
145
|
+
c3BlYy9icm93c2Vyc3RhY2svY2xpZW50X3NwZWMucmI=
|
146
|
+
- !binary |-
|
147
|
+
c3BlYy9icm93c2Vyc3RhY2tfc3BlYy5yYg==
|
148
|
+
- !binary |-
|
149
|
+
c3BlYy9zcGVjX2hlbHBlci5yYg==
|