sauce 1.0.2 → 2.0.0

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.
Files changed (56) hide show
  1. data/.document +5 -0
  2. data/.gitignore +30 -0
  3. data/Gemfile +16 -0
  4. data/README.markdown +39 -145
  5. data/Rakefile +46 -20
  6. data/bin/sauce +72 -61
  7. data/gemfiles/rails2.gemfile +10 -0
  8. data/gemfiles/rails2.gemfile.lock +77 -0
  9. data/gemfiles/rails3.gemfile +9 -0
  10. data/gemfiles/rails3.gemfile.lock +137 -0
  11. data/lib/generators/sauce/install/install_generator.rb +1 -2
  12. data/lib/sauce.rb +0 -22
  13. data/lib/sauce/capybara.rb +70 -32
  14. data/lib/sauce/capybara/cucumber.rb +121 -0
  15. data/lib/sauce/config.rb +57 -13
  16. data/lib/sauce/connect.rb +22 -11
  17. data/lib/sauce/integrations.rb +27 -69
  18. data/lib/sauce/jasmine.rb +35 -0
  19. data/lib/sauce/jasmine/rake.rb +47 -0
  20. data/lib/sauce/jasmine/runner.rb +4 -0
  21. data/lib/sauce/job.rb +10 -6
  22. data/lib/sauce/raketasks.rb +0 -21
  23. data/lib/sauce/selenium.rb +9 -18
  24. data/lib/sauce/utilities.rb +0 -17
  25. data/sauce.gemspec +8 -60
  26. data/spec/integration/connect_integration_spec.rb +84 -0
  27. data/spec/sauce/capybara/cucumber_spec.rb +156 -0
  28. data/spec/sauce/capybara/spec_helper.rb +42 -0
  29. data/spec/sauce/capybara_spec.rb +121 -0
  30. data/spec/sauce/config_spec.rb +239 -0
  31. data/spec/sauce/jasmine_spec.rb +49 -0
  32. data/spec/sauce/selenium_spec.rb +57 -0
  33. data/spec/spec_helper.rb +4 -0
  34. data/support/Sauce-Connect.jar +0 -0
  35. data/test/test_integrations.rb +202 -0
  36. data/test/test_testcase.rb +13 -0
  37. metadata +170 -171
  38. data/examples/helper.rb +0 -16
  39. data/examples/other_spec.rb +0 -7
  40. data/examples/saucelabs_spec.rb +0 -12
  41. data/examples/test_saucelabs.rb +0 -13
  42. data/examples/test_saucelabs2.rb +0 -9
  43. data/support/sauce_connect +0 -938
  44. data/support/selenium-server.jar +0 -0
  45. data/support/simplejson/LICENSE.txt +0 -19
  46. data/support/simplejson/__init__.py +0 -437
  47. data/support/simplejson/decoder.py +0 -421
  48. data/support/simplejson/encoder.py +0 -501
  49. data/support/simplejson/ordered_dict.py +0 -119
  50. data/support/simplejson/scanner.py +0 -77
  51. data/support/simplejson/tool.py +0 -39
  52. data/test/test_config.rb +0 -112
  53. data/test/test_connect.rb +0 -45
  54. data/test/test_job.rb +0 -13
  55. data/test/test_selenium.rb +0 -50
  56. data/test/test_selenium2.rb +0 -9
@@ -1,119 +0,0 @@
1
- """Drop-in replacement for collections.OrderedDict by Raymond Hettinger
2
-
3
- http://code.activestate.com/recipes/576693/
4
-
5
- """
6
- from UserDict import DictMixin
7
-
8
- # Modified from original to support Python 2.4, see
9
- # http://code.google.com/p/simplejson/issues/detail?id=53
10
- try:
11
- all
12
- except NameError:
13
- def all(seq):
14
- for elem in seq:
15
- if not elem:
16
- return False
17
- return True
18
-
19
- class OrderedDict(dict, DictMixin):
20
-
21
- def __init__(self, *args, **kwds):
22
- if len(args) > 1:
23
- raise TypeError('expected at most 1 arguments, got %d' % len(args))
24
- try:
25
- self.__end
26
- except AttributeError:
27
- self.clear()
28
- self.update(*args, **kwds)
29
-
30
- def clear(self):
31
- self.__end = end = []
32
- end += [None, end, end] # sentinel node for doubly linked list
33
- self.__map = {} # key --> [key, prev, next]
34
- dict.clear(self)
35
-
36
- def __setitem__(self, key, value):
37
- if key not in self:
38
- end = self.__end
39
- curr = end[1]
40
- curr[2] = end[1] = self.__map[key] = [key, curr, end]
41
- dict.__setitem__(self, key, value)
42
-
43
- def __delitem__(self, key):
44
- dict.__delitem__(self, key)
45
- key, prev, next = self.__map.pop(key)
46
- prev[2] = next
47
- next[1] = prev
48
-
49
- def __iter__(self):
50
- end = self.__end
51
- curr = end[2]
52
- while curr is not end:
53
- yield curr[0]
54
- curr = curr[2]
55
-
56
- def __reversed__(self):
57
- end = self.__end
58
- curr = end[1]
59
- while curr is not end:
60
- yield curr[0]
61
- curr = curr[1]
62
-
63
- def popitem(self, last=True):
64
- if not self:
65
- raise KeyError('dictionary is empty')
66
- # Modified from original to support Python 2.4, see
67
- # http://code.google.com/p/simplejson/issues/detail?id=53
68
- if last:
69
- key = reversed(self).next()
70
- else:
71
- key = iter(self).next()
72
- value = self.pop(key)
73
- return key, value
74
-
75
- def __reduce__(self):
76
- items = [[k, self[k]] for k in self]
77
- tmp = self.__map, self.__end
78
- del self.__map, self.__end
79
- inst_dict = vars(self).copy()
80
- self.__map, self.__end = tmp
81
- if inst_dict:
82
- return (self.__class__, (items,), inst_dict)
83
- return self.__class__, (items,)
84
-
85
- def keys(self):
86
- return list(self)
87
-
88
- setdefault = DictMixin.setdefault
89
- update = DictMixin.update
90
- pop = DictMixin.pop
91
- values = DictMixin.values
92
- items = DictMixin.items
93
- iterkeys = DictMixin.iterkeys
94
- itervalues = DictMixin.itervalues
95
- iteritems = DictMixin.iteritems
96
-
97
- def __repr__(self):
98
- if not self:
99
- return '%s()' % (self.__class__.__name__,)
100
- return '%s(%r)' % (self.__class__.__name__, self.items())
101
-
102
- def copy(self):
103
- return self.__class__(self)
104
-
105
- @classmethod
106
- def fromkeys(cls, iterable, value=None):
107
- d = cls()
108
- for key in iterable:
109
- d[key] = value
110
- return d
111
-
112
- def __eq__(self, other):
113
- if isinstance(other, OrderedDict):
114
- return len(self)==len(other) and \
115
- all(p==q for p, q in zip(self.items(), other.items()))
116
- return dict.__eq__(self, other)
117
-
118
- def __ne__(self, other):
119
- return not self == other
@@ -1,77 +0,0 @@
1
- """JSON token scanner
2
- """
3
- import re
4
- def _import_c_make_scanner():
5
- try:
6
- from simplejson._speedups import make_scanner
7
- return make_scanner
8
- except ImportError:
9
- return None
10
- c_make_scanner = _import_c_make_scanner()
11
-
12
- __all__ = ['make_scanner']
13
-
14
- NUMBER_RE = re.compile(
15
- r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?',
16
- (re.VERBOSE | re.MULTILINE | re.DOTALL))
17
-
18
- def py_make_scanner(context):
19
- parse_object = context.parse_object
20
- parse_array = context.parse_array
21
- parse_string = context.parse_string
22
- match_number = NUMBER_RE.match
23
- encoding = context.encoding
24
- strict = context.strict
25
- parse_float = context.parse_float
26
- parse_int = context.parse_int
27
- parse_constant = context.parse_constant
28
- object_hook = context.object_hook
29
- object_pairs_hook = context.object_pairs_hook
30
- memo = context.memo
31
-
32
- def _scan_once(string, idx):
33
- try:
34
- nextchar = string[idx]
35
- except IndexError:
36
- raise StopIteration
37
-
38
- if nextchar == '"':
39
- return parse_string(string, idx + 1, encoding, strict)
40
- elif nextchar == '{':
41
- return parse_object((string, idx + 1), encoding, strict,
42
- _scan_once, object_hook, object_pairs_hook, memo)
43
- elif nextchar == '[':
44
- return parse_array((string, idx + 1), _scan_once)
45
- elif nextchar == 'n' and string[idx:idx + 4] == 'null':
46
- return None, idx + 4
47
- elif nextchar == 't' and string[idx:idx + 4] == 'true':
48
- return True, idx + 4
49
- elif nextchar == 'f' and string[idx:idx + 5] == 'false':
50
- return False, idx + 5
51
-
52
- m = match_number(string, idx)
53
- if m is not None:
54
- integer, frac, exp = m.groups()
55
- if frac or exp:
56
- res = parse_float(integer + (frac or '') + (exp or ''))
57
- else:
58
- res = parse_int(integer)
59
- return res, m.end()
60
- elif nextchar == 'N' and string[idx:idx + 3] == 'NaN':
61
- return parse_constant('NaN'), idx + 3
62
- elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity':
63
- return parse_constant('Infinity'), idx + 8
64
- elif nextchar == '-' and string[idx:idx + 9] == '-Infinity':
65
- return parse_constant('-Infinity'), idx + 9
66
- else:
67
- raise StopIteration
68
-
69
- def scan_once(string, idx):
70
- try:
71
- return _scan_once(string, idx)
72
- finally:
73
- memo.clear()
74
-
75
- return scan_once
76
-
77
- make_scanner = c_make_scanner or py_make_scanner
@@ -1,39 +0,0 @@
1
- r"""Command-line tool to validate and pretty-print JSON
2
-
3
- Usage::
4
-
5
- $ echo '{"json":"obj"}' | python -m simplejson.tool
6
- {
7
- "json": "obj"
8
- }
9
- $ echo '{ 1.2:3.4}' | python -m simplejson.tool
10
- Expecting property name: line 1 column 2 (char 2)
11
-
12
- """
13
- import sys
14
- import simplejson as json
15
-
16
- def main():
17
- if len(sys.argv) == 1:
18
- infile = sys.stdin
19
- outfile = sys.stdout
20
- elif len(sys.argv) == 2:
21
- infile = open(sys.argv[1], 'rb')
22
- outfile = sys.stdout
23
- elif len(sys.argv) == 3:
24
- infile = open(sys.argv[1], 'rb')
25
- outfile = open(sys.argv[2], 'wb')
26
- else:
27
- raise SystemExit(sys.argv[0] + " [infile [outfile]]")
28
- try:
29
- obj = json.load(infile,
30
- object_pairs_hook=json.OrderedDict,
31
- use_decimal=True)
32
- except ValueError, e:
33
- raise SystemExit(e)
34
- json.dump(obj, outfile, sort_keys=True, indent=' ', use_decimal=True)
35
- outfile.write('\n')
36
-
37
-
38
- if __name__ == '__main__':
39
- main()
data/test/test_config.rb DELETED
@@ -1,112 +0,0 @@
1
- require File.expand_path("../helper", __FILE__)
2
-
3
- class TestConfig < Test::Unit::TestCase
4
- def test_generates_reasonable_browser_string_from_envrionment
5
- preserved_env = {}
6
- Sauce::Config::ENVIRONMENT_VARIABLES.each do |key|
7
- preserved_env[key] = ENV[key] if ENV[key]
8
- end
9
- begin
10
-
11
- ENV['SAUCE_USERNAME'] = "test_user"
12
- ENV['SAUCE_ACCESS_KEY'] = "test_access"
13
- ENV['SAUCE_OS'] = "Linux"
14
- ENV['SAUCE_BROWSER'] = "firefox"
15
- ENV['SAUCE_BROWSER_VERSION'] = "3."
16
-
17
- config = Sauce::Config.new
18
- assert_equal "{\"name\":\"Unnamed Ruby job\",\"access-key\":\"test_access\",\"os\":\"Linux\",\"username\":\"test_user\",\"browser-version\":\"3.\",\"browser\":\"firefox\"}", config.to_browser_string
19
- ensure
20
- Sauce::Config::ENVIRONMENT_VARIABLES.each do |key|
21
- ENV[key] = preserved_env[key]
22
- end
23
- end
24
- end
25
-
26
- def test_generates_browser_string_from_parameters
27
- config = Sauce::Config.new(:username => "test_user", :access_key => "test_access",
28
- :os => "Linux", :browser => "firefox", :browser_version => "3.")
29
- assert_equal "{\"name\":\"Unnamed Ruby job\",\"access-key\":\"test_access\",\"os\":\"Linux\",\"username\":\"test_user\",\"browser-version\":\"3.\",\"browser\":\"firefox\"}", config.to_browser_string
30
- end
31
-
32
- def test_generates_optional_parameters
33
- # dashes need to work for backward compatibility
34
- config = Sauce::Config.new(:username => "test_user", :access_key => "test_access",
35
- :os => "Linux", :browser => "firefox", :browser_version => "3.",
36
- :"user-extensions-url" => "testing")
37
- assert_equal "{\"name\":\"Unnamed Ruby job\",\"access-key\":\"test_access\",\"user-extensions-url\":\"testing\",\"os\":\"Linux\",\"username\":\"test_user\",\"browser-version\":\"3.\",\"browser\":\"firefox\"}", config.to_browser_string
38
-
39
- # underscores are more natural
40
- config = Sauce::Config.new(:username => "test_user", :access_key => "test_access",
41
- :os => "Linux", :browser => "firefox", :browser_version => "3.",
42
- :user_extensions_url => "testing")
43
- assert_equal "{\"name\":\"Unnamed Ruby job\",\"access-key\":\"test_access\",\"user-extensions-url\":\"testing\",\"os\":\"Linux\",\"username\":\"test_user\",\"browser-version\":\"3.\",\"browser\":\"firefox\"}", config.to_browser_string
44
- end
45
-
46
- def test_convenience_accessors
47
- config = Sauce::Config.new
48
- assert_equal "ondemand.saucelabs.com", config.host
49
- end
50
-
51
- def test_gracefully_degrades_browsers_field
52
- Sauce.config {|c|}
53
- config = Sauce::Config.new
54
- config.os = "A"
55
- config.browser = "B"
56
- config.browser_version = "C"
57
-
58
- assert_equal [["A", "B", "C"]], config.browsers
59
- end
60
-
61
- def test_default_to_first_item_in_browsers
62
- Sauce.config {|c| c.browsers = [["OS_FOO", "BROWSER_FOO", "VERSION_FOO"]] }
63
- config = Sauce::Config.new
64
- assert_equal "OS_FOO", config.os
65
- assert_equal "BROWSER_FOO", config.browser
66
- assert_equal "VERSION_FOO", config.browser_version
67
- end
68
-
69
- def test_boolean_flags
70
- config = Sauce::Config.new
71
- config.foo = true
72
- assert config.foo?
73
- end
74
-
75
- def test_sauce_config_default_os
76
- Sauce.config {|c| c.os = "TEST_OS" }
77
- begin
78
- config = Sauce::Config.new
79
- assert_equal "TEST_OS", config.os
80
- ensure
81
- Sauce.config {|c|}
82
- end
83
- end
84
-
85
- def test_can_call_sauce_config_twice
86
- Sauce.config {|c| c.os = "A"}
87
- assert_equal "A", Sauce::Config.new.os
88
- Sauce.config {|c|}
89
- assert_not_equal "A", Sauce::Config.new.os
90
- end
91
-
92
- def test_override
93
- Sauce.config {|c| c.browsers = [["OS_FOO", "BROWSER_FOO", "VERSION_FOO"]] }
94
- config = Sauce::Config.new(:os => "OS_BAR", :browser => "BROWSER_BAR", :browser_version => "VERSION_BAR")
95
- assert_equal "OS_BAR", config.os
96
- assert_equal "BROWSER_BAR", config.browser
97
- assert_equal "VERSION_BAR", config.browser_version
98
- end
99
-
100
- def test_clears_config
101
- Sauce.config {|c|}
102
- assert_equal [["Windows 2003", "firefox", "3.6."]], Sauce::Config.new.browsers
103
- end
104
-
105
- def test_platforms
106
- config = Sauce::Config.new(:os => "Windows 2003")
107
- assert_equal "WINDOWS", config.to_desired_capabilities[:platform]
108
-
109
- config = Sauce::Config.new(:os => "Windows 2008")
110
- assert_equal "VISTA", config.to_desired_capabilities[:platform]
111
- end
112
- end
data/test/test_connect.rb DELETED
@@ -1,45 +0,0 @@
1
- require File.expand_path("../helper", __FILE__)
2
-
3
- class TestConnect < Test::Unit::TestCase
4
- def test_running_when_ready
5
- connect = Sauce::Connect.new(:host => "saucelabs.com", :port => 80)
6
- assert_equal "uninitialized", connect.status
7
- connect.wait_until_ready
8
- assert_equal "running", connect.status
9
- connect.disconnect
10
- end
11
-
12
- def test_error_flag
13
- connect = Sauce::Connect.new(:host => "saucelabs.com", :port => 80, :username => 'fail')
14
- start = Time.now
15
- while Time.now-start < 20 && !connect.error
16
- sleep 1
17
- end
18
-
19
- assert connect.error
20
- connect.disconnect
21
- end
22
-
23
- def test_fails_fast_with_no_username
24
- Sauce.config {|c| c.username = nil; c.access_key = nil}
25
- username = ENV['SAUCE_USERNAME']
26
- access_key = ENV['SAUCE_ACCESS_KEY']
27
-
28
- begin
29
- ENV['SAUCE_USERNAME'] = nil
30
- assert_raises ArgumentError do
31
- connect = Sauce::Connect.new(:host => "saucelabs.com", :port => 80)
32
- end
33
-
34
- ENV['SAUCE_USERNAME'] = username
35
- ENV['SAUCE_ACCESS_KEY'] = nil
36
- assert_raises ArgumentError do
37
- connect = Sauce::Connect.new(:host => "saucelabs.com", :port => 80)
38
- end
39
- ensure
40
- ENV['SAUCE_USERNAME'] = username
41
- ENV['SAUCE_ACCESS_KEY'] = access_key
42
- Sauce.config {|c|}
43
- end
44
- end
45
- end
data/test/test_job.rb DELETED
@@ -1,13 +0,0 @@
1
- require File.expand_path("../helper", __FILE__)
2
-
3
- class TestJob < Test::Unit::TestCase
4
- def test_running_a_job_creates_a_reasonable_job_object
5
- selenium = Sauce::Selenium.new(:name => "test_running_a_job_creates_a_job_object")
6
- selenium.start
7
- session_id = selenium.session_id
8
- selenium.stop
9
-
10
- job = Sauce::Job.find(session_id)
11
- assert_equal "test_running_a_job_creates_a_job_object", job.name
12
- end
13
- end
@@ -1,50 +0,0 @@
1
- require File.expand_path("../helper", __FILE__)
2
-
3
- class TestSelenium < Test::Unit::TestCase
4
- def test_successful_connection_from_environment
5
- selenium = Sauce::Selenium.new(:job_name => "Sauce gem test suite: test_selenium.rb",
6
- :browser_url => "http://www.google.com/")
7
- selenium.start
8
- selenium.open "/"
9
- selenium.stop
10
- end
11
-
12
- def test_passed
13
- selenium = Sauce::Selenium.new(:job_name => "This test should be marked as passed",
14
- :browser_url => "http://www.google.com/")
15
- selenium.start
16
- job_id = selenium.session_id
17
- begin
18
- selenium.passed!
19
- ensure
20
- selenium.stop
21
- end
22
-
23
- job = Sauce::Job.find(job_id)
24
- while job.status == "in progress"
25
- sleep 0.5
26
- job.refresh!
27
- end
28
-
29
- assert job.passed, job
30
- end
31
-
32
- def test_failed
33
- selenium = Sauce::Selenium.new(:job_name => "This test should be marked as failed",
34
- :browser_url => "http://www.google.com/")
35
- selenium.start
36
- job_id = selenium.session_id
37
- begin
38
- selenium.failed!
39
- ensure
40
- selenium.stop
41
- end
42
-
43
- job = Sauce::Job.find(job_id)
44
- while job.status == "in progress"
45
- sleep 0.5
46
- job.refresh!
47
- end
48
- assert !job.passed, job
49
- end
50
- end