teaspoon 1.1.2 → 1.2.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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +47 -0
- data/MIT.LICENSE +2 -2
- data/README.md +56 -35
- data/app/assets/javascripts/teaspoon/hook.coffee +1 -1
- data/app/assets/javascripts/teaspoon/teaspoon.coffee +13 -1
- data/app/controllers/teaspoon/suite_controller.rb +25 -11
- data/app/views/teaspoon/suite/index.html.erb +1 -1
- data/lib/generators/teaspoon/install/install_generator.rb +34 -34
- data/lib/generators/teaspoon/install/templates/MISSING_FRAMEWORK +1 -1
- data/lib/generators/teaspoon/install/templates/POST_INSTALL +1 -1
- data/lib/generators/teaspoon/install/templates/_boot.html.erb +1 -1
- data/lib/generators/teaspoon/install/templates/env_comments.rb.tt +9 -7
- data/lib/tasks/teaspoon/info.rake +1 -1
- data/lib/teaspoon/command_line.rb +76 -76
- data/lib/teaspoon/configuration.rb +4 -4
- data/lib/teaspoon/console.rb +41 -40
- data/lib/teaspoon/coverage.rb +29 -25
- data/lib/teaspoon/deprecated.rb +1 -1
- data/lib/teaspoon/driver.rb +1 -1
- data/lib/teaspoon/driver/browserstack.rb +111 -0
- data/lib/teaspoon/driver/phantomjs.rb +25 -26
- data/lib/teaspoon/driver/phantomjs/runner.js +31 -3
- data/lib/teaspoon/driver/selenium.rb +13 -9
- data/lib/teaspoon/engine.rb +32 -16
- data/lib/teaspoon/environment.rb +28 -28
- data/lib/teaspoon/exceptions.rb +7 -7
- data/lib/teaspoon/exporter.rb +23 -23
- data/lib/teaspoon/formatter/base.rb +64 -46
- data/lib/teaspoon/formatter/clean.rb +2 -2
- data/lib/teaspoon/formatter/documentation.rb +40 -40
- data/lib/teaspoon/formatter/dot.rb +12 -12
- data/lib/teaspoon/formatter/json.rb +21 -21
- data/lib/teaspoon/formatter/junit.rb +52 -51
- data/lib/teaspoon/formatter/modules/report_module.rb +34 -32
- data/lib/teaspoon/formatter/pride.rb +21 -21
- data/lib/teaspoon/formatter/rspec_html.rb +31 -31
- data/lib/teaspoon/formatter/snowday.rb +6 -5
- data/lib/teaspoon/formatter/swayze_or_oprah.rb +91 -91
- data/lib/teaspoon/formatter/tap.rb +29 -29
- data/lib/teaspoon/formatter/tap_y.rb +57 -57
- data/lib/teaspoon/formatter/teamcity.rb +63 -63
- data/lib/teaspoon/framework/base.rb +1 -1
- data/lib/teaspoon/instrumentation.rb +18 -18
- data/lib/teaspoon/registry.rb +9 -9
- data/lib/teaspoon/registry/has_default.rb +2 -2
- data/lib/teaspoon/runner.rb +37 -37
- data/lib/teaspoon/server.rb +30 -29
- data/lib/teaspoon/suite.rb +68 -57
- data/lib/teaspoon/utility.rb +6 -0
- data/lib/teaspoon/version.rb +1 -1
- metadata +10 -17
- data/lib/teaspoon/driver/capybara_webkit.rb +0 -40
data/lib/teaspoon/runner.rb
CHANGED
@@ -20,50 +20,50 @@ module Teaspoon
|
|
20
20
|
|
21
21
|
private
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
def resolve_formatter(formatter)
|
24
|
+
formatter, output = formatter.to_s.split(">")
|
25
|
+
Teaspoon::Formatter.fetch(formatter).new(@suite_name, output)
|
26
|
+
end
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
def notify_formatters(event, result)
|
29
|
+
@formatters.each { |f| f.send(event, result) if f.respond_to?(event) }
|
30
|
+
send(:"on_#{event}", result) if respond_to?(:"on_#{event}", true)
|
31
|
+
end
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
33
|
+
def result_from_line(line)
|
34
|
+
json = JSON.parse(line)
|
35
|
+
return false unless json && json["_teaspoon"] && json["type"]
|
36
|
+
json["original_json"] = line
|
37
|
+
result_from_json(json)
|
38
|
+
rescue JSON::ParserError
|
39
|
+
false
|
40
|
+
end
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
42
|
+
def result_from_json(json)
|
43
|
+
result = Teaspoon::Result.build_from_json(json)
|
44
|
+
@failure_count += 1 if result.failing?
|
45
|
+
result
|
46
|
+
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
def on_exception(result)
|
49
|
+
raise Teaspoon::RunnerError.new(result.message)
|
50
|
+
end
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
52
|
+
def on_result(result)
|
53
|
+
resolve_coverage(result.coverage)
|
54
|
+
notify_formatters("complete", @failure_count)
|
55
|
+
end
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
def resolve_coverage(data)
|
58
|
+
return unless Teaspoon.configuration.use_coverage
|
59
|
+
raise Teaspoon::IstanbulNotFoundError unless Teaspoon::Instrumentation.executable
|
60
60
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
61
|
+
coverage = Teaspoon::Coverage.new(@suite_name, data)
|
62
|
+
coverage.generate_reports { |msg| notify_formatters("coverage", msg) }
|
63
|
+
coverage.check_thresholds do |msg|
|
64
|
+
notify_formatters("threshold_failure", msg)
|
65
|
+
@failure_count += 1
|
66
|
+
end
|
66
67
|
end
|
67
|
-
end
|
68
68
|
end
|
69
69
|
end
|
data/lib/teaspoon/server.rb
CHANGED
@@ -37,38 +37,39 @@ module Teaspoon
|
|
37
37
|
|
38
38
|
protected
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
def wait_until_started(thread)
|
41
|
+
Timeout.timeout(Teaspoon.configuration.server_timeout.to_i) { thread.join(0.1) until responsive? }
|
42
|
+
rescue Timeout::Error
|
43
|
+
raise Timeout::Error.new("consider increasing the timeout with `config.server_timeout`")
|
44
|
+
end
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
46
|
+
def disable_logging
|
47
|
+
return unless defined?(Thin)
|
48
|
+
if Teaspoon.configuration.suppress_log
|
49
|
+
Thin::Logging.silent = true
|
50
|
+
else
|
51
|
+
Thin::Logging.trace = false
|
52
|
+
end
|
52
53
|
end
|
53
|
-
end
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
55
|
+
def rack_options
|
56
|
+
{
|
57
|
+
app: Rails.application,
|
58
|
+
Host: host,
|
59
|
+
Port: port,
|
60
|
+
environment: "test",
|
61
|
+
AccessLog: [],
|
62
|
+
Logger: Rails.logger,
|
63
|
+
server: Teaspoon.configuration.server,
|
64
|
+
Silent: true
|
65
|
+
}
|
66
|
+
end
|
66
67
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
68
|
+
def find_available_port
|
69
|
+
server = TCPServer.new(host, 0)
|
70
|
+
server.addr[1]
|
71
|
+
ensure
|
72
|
+
server.close if server
|
73
|
+
end
|
73
74
|
end
|
74
75
|
end
|
data/lib/teaspoon/suite.rb
CHANGED
@@ -42,78 +42,89 @@ module Teaspoon
|
|
42
42
|
|
43
43
|
protected
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
def specs
|
46
|
+
files = specs_from_file
|
47
|
+
return files unless files.empty?
|
48
|
+
glob.map { |file| asset_from_file(file) }
|
49
|
+
end
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
|
51
|
+
def asset_tree(sources)
|
52
|
+
sources.flat_map do |source|
|
53
|
+
asset = @env.find_asset(source, accept: "application/javascript", pipeline: :debug)
|
54
|
+
|
55
|
+
if asset && asset.respond_to?(:logical_path)
|
56
|
+
asset_and_dependencies(asset).map { |a| asset_url(a) }
|
57
|
+
else
|
58
|
+
source.blank? ? [] : [source]
|
59
|
+
end
|
60
|
+
end.compact.uniq
|
61
|
+
end
|
54
62
|
|
55
|
-
|
56
|
-
|
57
|
-
|
63
|
+
def asset_url(asset)
|
64
|
+
params = []
|
65
|
+
params << "body=1" if config.expand_assets
|
66
|
+
params << "instrument=1" if instrument_file?(asset.filename)
|
67
|
+
url = asset.logical_path
|
68
|
+
url += "?#{params.join("&")}" if params.any?
|
69
|
+
url
|
70
|
+
end
|
71
|
+
|
72
|
+
def asset_and_dependencies(asset)
|
73
|
+
if config.expand_assets
|
74
|
+
if asset.respond_to?(:to_a)
|
75
|
+
asset.to_a
|
76
|
+
else
|
77
|
+
asset.metadata[:included].map { |uri| @env.load(uri) }
|
78
|
+
end
|
58
79
|
else
|
59
|
-
|
80
|
+
[asset]
|
60
81
|
end
|
61
|
-
end
|
62
|
-
end
|
82
|
+
end
|
63
83
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
url += "?#{params.join("&")}" if params.any?
|
70
|
-
url
|
71
|
-
end
|
84
|
+
def instrument_file?(file)
|
85
|
+
return false unless coverage_requested?
|
86
|
+
return false if matched_spec_file?(file)
|
87
|
+
true
|
88
|
+
end
|
72
89
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
true
|
77
|
-
end
|
90
|
+
def coverage_requested?
|
91
|
+
@options[:coverage] || Teaspoon.configuration.use_coverage
|
92
|
+
end
|
78
93
|
|
79
|
-
|
80
|
-
|
81
|
-
|
94
|
+
def matched_spec_file?(file)
|
95
|
+
glob.include?(file)
|
96
|
+
end
|
82
97
|
|
83
|
-
|
84
|
-
|
85
|
-
|
98
|
+
def asset_from_file(original)
|
99
|
+
filename = original
|
100
|
+
Rails.application.config.assets.paths.each do |path|
|
101
|
+
filename = filename.gsub(%r(^#{Regexp.escape(path.to_s)}[\/|\\]), "")
|
102
|
+
end
|
86
103
|
|
87
|
-
|
88
|
-
|
89
|
-
Rails.application.config.assets.paths.each do |path|
|
90
|
-
filename = filename.gsub(%r(^#{Regexp.escape(path.to_s)}[\/|\\]), "")
|
104
|
+
raise Teaspoon::AssetNotServableError.new(filename: filename) if filename == original
|
105
|
+
normalize_js_extension(filename)
|
91
106
|
end
|
92
107
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
def normalize_js_extension(original_filename)
|
98
|
-
config.js_extensions.inject(original_filename.gsub(".erb", "")) do |filename, extension|
|
99
|
-
filename.gsub(Regexp.new(extension.to_s + "$"), ".js")
|
108
|
+
def normalize_js_extension(original_filename)
|
109
|
+
config.js_extensions.inject(original_filename.gsub(".erb", "")) do |filename, extension|
|
110
|
+
filename.gsub(Regexp.new(extension.to_s + "$"), ".js")
|
111
|
+
end
|
100
112
|
end
|
101
|
-
end
|
102
113
|
|
103
|
-
|
104
|
-
|
105
|
-
|
114
|
+
def glob
|
115
|
+
@glob ||= Dir[config.matcher.present? ? Teaspoon.configuration.root.join(config.matcher) : ""].sort!
|
116
|
+
end
|
106
117
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
118
|
+
def suite_configuration
|
119
|
+
config = Teaspoon.configuration.suite_configs[name]
|
120
|
+
raise Teaspoon::UnknownSuite.new(name: name) unless config.present?
|
121
|
+
config[:instance] ||= Teaspoon::Configuration::Suite.new(name, &config[:block])
|
122
|
+
end
|
112
123
|
|
113
|
-
|
114
|
-
|
115
|
-
|
124
|
+
def specs_from_file
|
125
|
+
Array(@options[:file]).map do |filename|
|
126
|
+
asset_from_file(File.expand_path(Teaspoon.configuration.root.join(filename)))
|
127
|
+
end
|
116
128
|
end
|
117
|
-
end
|
118
129
|
end
|
119
130
|
end
|
data/lib/teaspoon/utility.rb
CHANGED
data/lib/teaspoon/version.rb
CHANGED
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: teaspoon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jejacks0n
|
8
|
+
- mikepack
|
8
9
|
- jayzes
|
9
10
|
- jedschneider
|
10
|
-
- mikepack
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2021-03-16 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: railties
|
@@ -20,9 +20,6 @@ dependencies:
|
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: 3.2.5
|
23
|
-
- - "<"
|
24
|
-
- !ruby/object:Gem::Version
|
25
|
-
version: '5'
|
26
23
|
type: :runtime
|
27
24
|
prerelease: false
|
28
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -30,13 +27,10 @@ dependencies:
|
|
30
27
|
- - ">="
|
31
28
|
- !ruby/object:Gem::Version
|
32
29
|
version: 3.2.5
|
33
|
-
|
34
|
-
|
35
|
-
version: '5'
|
36
|
-
description: Run Javascript tests using Jasmine, Mocha or QUnit in the browser or
|
37
|
-
headless using PhantomJS, Selenium Webdriver, or Capybara Webkit
|
30
|
+
description: Run your Javascript tests using Jasmine, Mocha or QUnit using a variety
|
31
|
+
of platforms.
|
38
32
|
email:
|
39
|
-
-
|
33
|
+
- jejacks0n@gmail.com
|
40
34
|
executables:
|
41
35
|
- teaspoon
|
42
36
|
extensions: []
|
@@ -95,7 +89,7 @@ files:
|
|
95
89
|
- lib/teaspoon/deprecated.rb
|
96
90
|
- lib/teaspoon/driver.rb
|
97
91
|
- lib/teaspoon/driver/base.rb
|
98
|
-
- lib/teaspoon/driver/
|
92
|
+
- lib/teaspoon/driver/browserstack.rb
|
99
93
|
- lib/teaspoon/driver/phantomjs.rb
|
100
94
|
- lib/teaspoon/driver/phantomjs/runner.js
|
101
95
|
- lib/teaspoon/driver/selenium.rb
|
@@ -129,7 +123,7 @@ files:
|
|
129
123
|
- lib/teaspoon/suite.rb
|
130
124
|
- lib/teaspoon/utility.rb
|
131
125
|
- lib/teaspoon/version.rb
|
132
|
-
homepage: https://github.com/
|
126
|
+
homepage: https://github.com/jejacks0n/teaspoon
|
133
127
|
licenses:
|
134
128
|
- MIT
|
135
129
|
metadata: {}
|
@@ -141,15 +135,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
141
135
|
requirements:
|
142
136
|
- - ">="
|
143
137
|
- !ruby/object:Gem::Version
|
144
|
-
version: '
|
138
|
+
version: '2.4'
|
145
139
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
140
|
requirements:
|
147
141
|
- - ">="
|
148
142
|
- !ruby/object:Gem::Version
|
149
143
|
version: '0'
|
150
144
|
requirements: []
|
151
|
-
|
152
|
-
rubygems_version: 2.4.5
|
145
|
+
rubygems_version: 3.0.8
|
153
146
|
signing_key:
|
154
147
|
specification_version: 4
|
155
148
|
summary: 'Teaspoon: A Javascript test runner built on top of Rails'
|
@@ -1,40 +0,0 @@
|
|
1
|
-
# :nocov:
|
2
|
-
begin
|
3
|
-
require "capybara-webkit"
|
4
|
-
rescue LoadError
|
5
|
-
Teaspoon.abort("Could not find Capybara Webkit. Install the capybara-webkit gem.")
|
6
|
-
end
|
7
|
-
# :nocov:
|
8
|
-
|
9
|
-
require "teaspoon/driver/base"
|
10
|
-
|
11
|
-
module Teaspoon
|
12
|
-
module Driver
|
13
|
-
class CapybaraWebkit < Base
|
14
|
-
class TeaspoonNotFinishedError < StandardError; end
|
15
|
-
def initialize(_options = nil)
|
16
|
-
end
|
17
|
-
|
18
|
-
def run_specs(runner, url)
|
19
|
-
session.visit(url)
|
20
|
-
|
21
|
-
timeout = Teaspoon.configuration.driver_timeout.to_i
|
22
|
-
session.document.synchronize(timeout, errors: [TeaspoonNotFinishedError]) do
|
23
|
-
done = session.evaluate_script("window.Teaspoon && window.Teaspoon.finished")
|
24
|
-
(session.evaluate_script("window.Teaspoon && window.Teaspoon.getMessages()") || []).each do |line|
|
25
|
-
runner.process("#{line}\n")
|
26
|
-
end
|
27
|
-
unless done
|
28
|
-
raise TeaspoonNotFinishedError
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def session
|
36
|
-
@session ||= Capybara::Session.new(:webkit)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|