browserstack 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.3@browserstack --create
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in browserstack.gemspec
4
+ gemspec
@@ -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.
@@ -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
@@ -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
@@ -0,0 +1,5 @@
1
+ require "base64"
2
+ require "net/http"
3
+ require "yajl"
4
+ require "browserstack/client"
5
+ require "browserstack/version"
@@ -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,3 @@
1
+ module Browserstack
2
+ VERSION = "0.0.1"
3
+ 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
@@ -0,0 +1,7 @@
1
+ require File.expand_path("../../lib/browserstack", __FILE__)
2
+ require 'webmock/rspec'
3
+ RSpec.configure do |config|
4
+ #config.mock_with :rspec
5
+ end
6
+
7
+ WebMock.disable_net_connect!(:allow_localhost => true)
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==