cucumber-pro 0.0.2 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/TODO.md +7 -2
- data/cucumber-pro.gemspec +2 -4
- data/features/publish_results.feature +6 -0
- data/features/security.feature +27 -0
- data/features/step_definitions/steps.rb +2 -0
- data/features/support/fake_results_service.rb +1 -2
- data/lib/cucumber/pro.rb +20 -1
- data/lib/cucumber/pro/scm.rb +10 -5
- data/lib/cucumber/pro/version +1 -0
- data/lib/cucumber/pro/web_socket_session.rb +76 -64
- data/tmp/.gitkeep +0 -0
- metadata +11 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c90f1ff93aa0791fcc5726992f81678704506523
|
4
|
+
data.tar.gz: 4db71bb9349a648e404e787a4f808af24764b9c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52b7ef6e162dc95d32a8b48b8e3b2d67c82da83a48da92667b926d8478d9db2588a4d609e71c1f6b8f74fc3cda3de582141ed8d42882df329f0fd4b38ae10065
|
7
|
+
data.tar.gz: 66d5412d15be33487e3a4cd163d70d1f9c2666dfda7074e1fac89dc86113d5d4f8d8bea66c3868b665ab24cb1eda6eb3a4b5dc6bf4fcdfe1834e0e8df249c610
|
data/TODO.md
CHANGED
@@ -1,4 +1,9 @@
|
|
1
1
|
- Scenario for when the token is invalid
|
2
|
-
-
|
3
|
-
-
|
2
|
+
- Scenario for when branch is invalid
|
3
|
+
- Branch has a * in it
|
4
|
+
- Better (more unique) run ID - use a UUID
|
5
|
+
- Log to Cucumber's IO instead of STDOUT by default
|
6
|
+
- Unit tests for Messaging
|
7
|
+
- Handle cases where some messages sent are not ack'd
|
8
|
+
- Handle cases where some messages sent come back with an error
|
4
9
|
|
data/cucumber-pro.gemspec
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
3
|
-
require "cucumber/pro/version"
|
4
3
|
|
5
4
|
Gem::Specification.new do |s|
|
6
5
|
s.name = 'cucumber-pro'
|
7
|
-
s.version =
|
6
|
+
s.version = File.read(File.expand_path("../lib/cucumber/pro/version", __FILE__))
|
8
7
|
s.authors = ["Matt Wynne"]
|
9
8
|
s.description = "Client library for publishing results to the Cucumber Pro service"
|
10
9
|
s.summary = "cucumber-pro-#{s.version}"
|
@@ -14,8 +13,7 @@ Gem::Specification.new do |s|
|
|
14
13
|
s.license = "MIT"
|
15
14
|
s.required_ruby_version = ">= 1.9.3"
|
16
15
|
|
17
|
-
s.add_dependency '
|
18
|
-
s.add_dependency 'faye-websocket'
|
16
|
+
s.add_dependency 'faye-websocket', '~> 0.7'
|
19
17
|
|
20
18
|
s.add_development_dependency 'bundler', '>= 1.3.5'
|
21
19
|
s.add_development_dependency 'rake', '>= 0.9.2'
|
@@ -1,6 +1,11 @@
|
|
1
1
|
@announce
|
2
2
|
Feature: Publish results
|
3
3
|
|
4
|
+
Background:
|
5
|
+
Given I set the environment variables to:
|
6
|
+
| variable | value |
|
7
|
+
| CUCUMBER_PRO_TOKEN | valid-token |
|
8
|
+
|
4
9
|
Scenario: A couple of scenarios
|
5
10
|
Given a git repo
|
6
11
|
And a feature "features/test.feature" with:
|
@@ -22,6 +27,7 @@ Feature: Publish results
|
|
22
27
|
| status | path | location |
|
23
28
|
| passed | features/test.feature | 2 |
|
24
29
|
| failed | features/test.feature | 5 |
|
30
|
+
And the stderr should not contain anything
|
25
31
|
|
26
32
|
Scenario: A scenario outline
|
27
33
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
@announce
|
2
|
+
Feature: Security
|
3
|
+
|
4
|
+
Scenario: Bad access token
|
5
|
+
Given a git repo
|
6
|
+
And a feature "features/test.feature" with:
|
7
|
+
"""
|
8
|
+
Feature:
|
9
|
+
Scenario:
|
10
|
+
Given passing
|
11
|
+
"""
|
12
|
+
When I set the environment variables to:
|
13
|
+
| variable | value |
|
14
|
+
| CUCUMBER_PRO_TOKEN | invalid-token |
|
15
|
+
And I run `cucumber -f Cucumber::Pro -o /dev/null -f pretty`
|
16
|
+
And the stderr should contain "Access denied"
|
17
|
+
|
18
|
+
Scenario: No access token
|
19
|
+
Given a git repo
|
20
|
+
And a feature "features/test.feature" with:
|
21
|
+
"""
|
22
|
+
Feature:
|
23
|
+
Scenario:
|
24
|
+
Given passing
|
25
|
+
"""
|
26
|
+
When I run `cucumber -f Cucumber::Pro -o /dev/null -f pretty`
|
27
|
+
And the stderr should contain "Missing access token"
|
@@ -11,6 +11,8 @@ end
|
|
11
11
|
|
12
12
|
Given(/^a git repo$/) do
|
13
13
|
run_simple "git init"
|
14
|
+
run_simple "git config user.email \"test@test.com\""
|
15
|
+
run_simple "git config user.name \"Test user\""
|
14
16
|
run_simple "git commit --allow-empty -m 'Initial commit'"
|
15
17
|
run_simple "git remote add origin #{repo_url}"
|
16
18
|
run_simple "git config --get remote.origin.url"
|
@@ -3,7 +3,7 @@ require 'json'
|
|
3
3
|
|
4
4
|
module FakeResultsService
|
5
5
|
PORT = 5000
|
6
|
-
VALID_TOKEN = 'valid-
|
6
|
+
VALID_TOKEN = 'valid-token'
|
7
7
|
|
8
8
|
class << self
|
9
9
|
def messages
|
@@ -91,7 +91,6 @@ else
|
|
91
91
|
require 'cucumber/pro'
|
92
92
|
Cucumber::Pro.configure do |c|
|
93
93
|
c.url = 'ws://localhost:#{FakeResultsService::PORT}'
|
94
|
-
c.token = "#{FakeResultsService::VALID_TOKEN}"
|
95
94
|
end
|
96
95
|
END
|
97
96
|
end
|
data/lib/cucumber/pro.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
require 'logger'
|
2
2
|
require 'cucumber/pro/formatter'
|
3
3
|
require 'cucumber/pro/web_socket_session'
|
4
|
+
require 'cucumber/pro/version'
|
4
5
|
|
5
6
|
module Cucumber
|
6
7
|
module Pro
|
7
8
|
|
8
9
|
class << self
|
9
10
|
def new(*)
|
10
|
-
url = config.url + "?token=#{config.token}"
|
11
11
|
session = WebSocketSession.new(url, config.logger)
|
12
12
|
Formatter.new(session)
|
13
13
|
end
|
@@ -21,6 +21,11 @@ module Cucumber
|
|
21
21
|
def config
|
22
22
|
@config ||= Config.new
|
23
23
|
end
|
24
|
+
|
25
|
+
def url
|
26
|
+
token = config.token || raise(Error::MissingToken.new)
|
27
|
+
config.url + "?token=#{token}"
|
28
|
+
end
|
24
29
|
end
|
25
30
|
|
26
31
|
class Config
|
@@ -34,6 +39,20 @@ module Cucumber
|
|
34
39
|
config.token = ENV['CUCUMBER_PRO_TOKEN']
|
35
40
|
end
|
36
41
|
|
42
|
+
module Error
|
43
|
+
AccessDenied = Class.new(StandardError) {
|
44
|
+
def initialize
|
45
|
+
super "Access denied."
|
46
|
+
end
|
47
|
+
}
|
48
|
+
|
49
|
+
MissingToken = Class.new(StandardError) {
|
50
|
+
def initialize
|
51
|
+
super "Missing access token. Please visit https://app.cucumber.pro/api-token for instructions."
|
52
|
+
end
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
37
56
|
end
|
38
57
|
end
|
39
58
|
|
data/lib/cucumber/pro/scm.rb
CHANGED
@@ -3,7 +3,6 @@ module Cucumber
|
|
3
3
|
|
4
4
|
module Scm
|
5
5
|
|
6
|
-
require 'grit'
|
7
6
|
class Repo
|
8
7
|
|
9
8
|
NoGitRepoFound = Class.new(StandardError)
|
@@ -18,19 +17,25 @@ module Cucumber
|
|
18
17
|
end
|
19
18
|
|
20
19
|
def initialize(path)
|
21
|
-
@
|
20
|
+
@path = path
|
22
21
|
end
|
23
22
|
|
24
23
|
def remote
|
25
|
-
|
24
|
+
cmd('git config --get remote.origin.url')
|
26
25
|
end
|
27
26
|
|
28
27
|
def branch
|
29
|
-
|
28
|
+
cmd("git branch --contains #{rev}")
|
30
29
|
end
|
31
30
|
|
32
31
|
def rev
|
33
|
-
|
32
|
+
cmd("git rev-parse HEAD")
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def cmd(cmd)
|
38
|
+
Dir.chdir(@path) { `#{cmd}` }.strip
|
34
39
|
end
|
35
40
|
end
|
36
41
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
0.0.4
|
@@ -4,106 +4,118 @@ require 'eventmachine'
|
|
4
4
|
|
5
5
|
module Cucumber
|
6
6
|
module Pro
|
7
|
-
module Error
|
8
|
-
AccessDenied = Class.new(StandardError) {
|
9
|
-
def initialize
|
10
|
-
super "Access denied."
|
11
|
-
end
|
12
|
-
}
|
13
|
-
end
|
14
|
-
|
15
7
|
class WebSocketSession
|
16
8
|
|
17
|
-
|
18
|
-
class SendMessage
|
19
|
-
def initialize(data)
|
20
|
-
@data = data
|
21
|
-
end
|
22
|
-
|
23
|
-
def send_to(ws)
|
24
|
-
ws.send(@data.to_json)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
class Close
|
29
|
-
def send_to(ws)
|
30
|
-
ws.close
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
9
|
def initialize(url, logger)
|
35
10
|
@url, @logger = url, logger
|
36
11
|
@queue = Queue.new
|
37
|
-
|
12
|
+
@socket = SocketWorker.new(url, logger, self) do
|
13
|
+
queue.pop.call if !queue.empty?
|
14
|
+
end
|
38
15
|
end
|
39
16
|
|
40
17
|
def send(message)
|
41
18
|
logger.debug [:session, :send, message]
|
42
|
-
queue.push
|
19
|
+
queue.push -> { socket.send(message.to_json) }
|
20
|
+
self
|
43
21
|
end
|
44
22
|
|
45
23
|
def close
|
46
24
|
logger.debug [:session, :close]
|
47
|
-
queue.push
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
25
|
+
queue.push -> { socket.close }
|
26
|
+
loop until socket.closed?
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def error(exception)
|
31
|
+
logger.fatal exception
|
32
|
+
$stderr.puts "Cucumber Pro failed to send results: #{exception}"
|
33
|
+
$stderr.puts exception.backtrace.join("\n")
|
34
|
+
self
|
52
35
|
end
|
53
36
|
|
54
37
|
private
|
55
38
|
|
56
|
-
attr_reader :logger, :queue
|
39
|
+
attr_reader :logger, :queue, :socket
|
57
40
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
@ws_error = exception
|
65
|
-
end
|
41
|
+
class SocketWorker
|
42
|
+
|
43
|
+
def initialize(url, logger, error_handler, &next_task)
|
44
|
+
@url, @logger, @error_handler = url, logger, error_handler
|
45
|
+
@next_task = next_task
|
46
|
+
@em = Thread.new { start_client }
|
66
47
|
end
|
67
|
-
end
|
68
48
|
|
69
|
-
|
70
|
-
|
71
|
-
|
49
|
+
def close
|
50
|
+
@ws.close
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def send(data)
|
55
|
+
@ws.send data
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
def closed?
|
60
|
+
!@em.alive?
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
attr_reader :logger, :error_handler, :next_task
|
72
66
|
|
73
|
-
|
67
|
+
def start_client
|
68
|
+
EM.run do
|
69
|
+
logger.debug [:ws, :start]
|
70
|
+
@ws = Faye::WebSocket::Client.new(@url)
|
71
|
+
@ws.on :open, &self.method(:on_open)
|
72
|
+
@ws.on :error, &self.method(:on_error)
|
73
|
+
@ws.on :message, &self.method(:on_message)
|
74
|
+
@ws.on :close, &self.method(:on_close)
|
75
|
+
end
|
76
|
+
self
|
77
|
+
rescue => exception
|
78
|
+
error_handler.error exception
|
79
|
+
end
|
80
|
+
|
81
|
+
def on_open(event)
|
74
82
|
logger.debug [:ws, :open]
|
75
|
-
|
83
|
+
process_tasks
|
84
|
+
self
|
76
85
|
end
|
77
86
|
|
78
|
-
|
87
|
+
def on_error(event)
|
79
88
|
logger.error [:ws, :error]
|
89
|
+
self
|
80
90
|
end
|
81
91
|
|
82
|
-
|
92
|
+
def on_message(event)
|
83
93
|
logger.debug [:ws, :message, event.data]
|
94
|
+
self
|
84
95
|
end
|
85
96
|
|
86
|
-
|
97
|
+
def on_close(event)
|
87
98
|
logger.debug [:ws, :close]
|
88
|
-
|
89
|
-
|
99
|
+
if access_denied?(event)
|
100
|
+
raise Error::AccessDenied.new
|
101
|
+
end
|
102
|
+
@ws = nil
|
90
103
|
EM.stop_event_loop
|
104
|
+
self
|
91
105
|
end
|
92
|
-
self
|
93
|
-
end
|
94
106
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
107
|
+
def process_tasks
|
108
|
+
next_task.call
|
109
|
+
EM.next_tick { process_tasks }
|
110
|
+
self
|
111
|
+
end
|
112
|
+
|
113
|
+
def access_denied?(event)
|
114
|
+
event.code == 1002 &&
|
115
|
+
event.reason == \
|
116
|
+
"Error during WebSocket handshake: Unexpected response code: 401"
|
99
117
|
end
|
100
|
-
end
|
101
118
|
|
102
|
-
def process_next_message(ws)
|
103
|
-
return if queue.empty?
|
104
|
-
message = queue.pop
|
105
|
-
message.send_to(ws)
|
106
|
-
logger.debug [:ws, :send, message]
|
107
119
|
end
|
108
120
|
|
109
121
|
end
|
data/tmp/.gitkeep
ADDED
File without changes
|
metadata
CHANGED
@@ -1,43 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cucumber-pro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Wynne
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: grit
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: faye-websocket
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
|
-
- - "
|
17
|
+
- - "~>"
|
32
18
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
19
|
+
version: '0.7'
|
34
20
|
type: :runtime
|
35
21
|
prerelease: false
|
36
22
|
version_requirements: !ruby/object:Gem::Requirement
|
37
23
|
requirements:
|
38
|
-
- - "
|
24
|
+
- - "~>"
|
39
25
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
26
|
+
version: '0.7'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: bundler
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -163,6 +149,7 @@ files:
|
|
163
149
|
- TODO.md
|
164
150
|
- cucumber-pro.gemspec
|
165
151
|
- features/publish_results.feature
|
152
|
+
- features/security.feature
|
166
153
|
- features/step_definitions/steps.rb
|
167
154
|
- features/support/aruba.rb
|
168
155
|
- features/support/env.rb
|
@@ -171,8 +158,10 @@ files:
|
|
171
158
|
- lib/cucumber/pro.rb
|
172
159
|
- lib/cucumber/pro/formatter.rb
|
173
160
|
- lib/cucumber/pro/scm.rb
|
161
|
+
- lib/cucumber/pro/version
|
174
162
|
- lib/cucumber/pro/version.rb
|
175
163
|
- lib/cucumber/pro/web_socket_session.rb
|
164
|
+
- tmp/.gitkeep
|
176
165
|
homepage: https://cucumber.pro
|
177
166
|
licenses:
|
178
167
|
- MIT
|
@@ -197,9 +186,10 @@ rubyforge_project:
|
|
197
186
|
rubygems_version: 2.0.14
|
198
187
|
signing_key:
|
199
188
|
specification_version: 4
|
200
|
-
summary: cucumber-pro-0.0.
|
189
|
+
summary: cucumber-pro-0.0.4
|
201
190
|
test_files:
|
202
191
|
- features/publish_results.feature
|
192
|
+
- features/security.feature
|
203
193
|
- features/step_definitions/steps.rb
|
204
194
|
- features/support/aruba.rb
|
205
195
|
- features/support/env.rb
|