teaspoon 1.1.4 → 1.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/README.md +14 -12
- data/app/controllers/teaspoon/suite_controller.rb +13 -4
- data/lib/generators/teaspoon/install/templates/env_comments.rb.tt +3 -1
- data/lib/teaspoon/driver.rb +1 -0
- data/lib/teaspoon/driver/browserstack.rb +114 -0
- data/lib/teaspoon/driver/phantomjs.rb +1 -2
- data/lib/teaspoon/engine.rb +6 -3
- data/lib/teaspoon/formatter/junit.rb +2 -1
- data/lib/teaspoon/registry.rb +1 -1
- data/lib/teaspoon/version.rb +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b1fe7da8e50927f48254e402db1b3cdb677e6ca0
|
4
|
+
data.tar.gz: d4fdb5d2b377e7bbb58be0ecbe73bd26c4bdc951
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db2aeba73939e1ce0cc4e0155c28cd245962f2fb04d949290eaa134e45dd3e64e46883d0ef542e4cc667a896f453fb994ff833983e11f343de8c47d14ae47b70
|
7
|
+
data.tar.gz: bce476ec63fb6b634411237329c3d6bb7ce4711895b0fe96ccfc6ce700b7fc213aaf41474420bfcb78af569362715f7f9b4409ac38924e834d9721f8335461cc
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,18 @@
|
|
2
2
|
|
3
3
|
#### Bug Fixes
|
4
4
|
|
5
|
+
### 1.1.5
|
6
|
+
|
7
|
+
#### Enhancements
|
8
|
+
|
9
|
+
* Adds support for Rails 5
|
10
|
+
|
11
|
+
#### Bug Fixes
|
12
|
+
|
13
|
+
* Fixes an ActionView version related issue.
|
14
|
+
* Changes before_filter to before_action where possible (Rails 3 vs. Rails 5)
|
15
|
+
|
16
|
+
|
5
17
|
### 1.1.4
|
6
18
|
|
7
19
|
#### Bug Fixes
|
@@ -13,6 +25,10 @@
|
|
13
25
|
|
14
26
|
This was an erroneous release, of the rails_5 branch. oops.
|
15
27
|
|
28
|
+
#### Bug Fixes
|
29
|
+
|
30
|
+
* Fix for version check of ActionView, to expand the version checking for security/bug fix releases.
|
31
|
+
|
16
32
|
|
17
33
|
### 1.1.2
|
18
34
|
|
data/README.md
CHANGED
@@ -11,7 +11,7 @@ Teaspoon
|
|
11
11
|
<img src="https://raw.github.com/modeset/teaspoon/master/screenshots/logo_big.png" alt="Logo by Morgan Keys" align="right" />
|
12
12
|
<sup>Logo by [Morgan Keys](http://www.morganrkeys.com/)</sup>
|
13
13
|
|
14
|
-
Teaspoon is a Javascript test runner built for Rails. It can run tests in the browser and headless using PhantomJS, Selenium WebDriver, or Capybara Webkit.
|
14
|
+
Teaspoon is a Javascript test runner built for Rails. It can run tests in the browser and headless using PhantomJS, Selenium WebDriver, or Capybara Webkit. It can also run your tests on selenium-webgrid providers such as [BrowserStack](https://www.browserstack.com).
|
15
15
|
|
16
16
|
Feedback, ideas and pull requests are always welcome, or you can hit us up on Twitter @modeset_.
|
17
17
|
|
@@ -24,15 +24,6 @@ Teaspoon takes advantage of the Rails asset pipeline, and ships with support for
|
|
24
24
|
If you'd like to use Teaspoon with [Guard](https://github.com/guard/guard), check out the [guard-teaspoon](https://github.com/modeset/guard-teaspoon) project. Or, if you want to use the [Spring](https://github.com/rails/spring) preloader, try the unofficial [spring-commands-teaspoon](https://github.com/alejandrobabio/spring-commands-teaspoon).
|
25
25
|
|
26
26
|
|
27
|
-
## Developer Note
|
28
|
-
|
29
|
-
We've added experimental Rails 5 support. If you're looking to use Teaspoon with Rails 5, please try out the rails_5 branch.
|
30
|
-
|
31
|
-
```
|
32
|
-
gem "teaspoon-mocha", github: "modeset/teaspoon", branch: "rails_5"
|
33
|
-
```
|
34
|
-
|
35
|
-
|
36
27
|
## Screenshots
|
37
28
|
|
38
29
|
### Running in the console
|
@@ -57,7 +48,7 @@ gem "teaspoon-mocha", github: "modeset/teaspoon", branch: "rails_5"
|
|
57
48
|
8. [Test Frameworks](#test-frameworks)
|
58
49
|
9. [Support Libraries](#support-libraries)
|
59
50
|
10. [CI Support](#ci-support)
|
60
|
-
|
51
|
+
11. [With BrowserStack](#with-browserstack)
|
61
52
|
|
62
53
|
## Installation
|
63
54
|
|
@@ -133,7 +124,7 @@ bundle exec teaspoon --help
|
|
133
124
|
|
134
125
|
Depending on which framework you use this can differ, and there's an expectation that you have a certain level of familiarity with your chosen test framework.
|
135
126
|
|
136
|
-
Teaspoon supports [Jasmine](http://
|
127
|
+
Teaspoon supports [Jasmine](http://jasmine.github.io/2.0/introduction.html), [Mocha](https://github.com/mochajs/mocha) and [QUnit](http://qunitjs.com). And since it's possible to use the asset pipeline, feel free to use the `= require` directive throughout your specs and spec helpers.
|
137
128
|
|
138
129
|
Here's a basic spec written in Javascript using Jasmine:
|
139
130
|
|
@@ -445,6 +436,17 @@ If you want to generate reports that CI can use you can install Istanbul for cov
|
|
445
436
|
We encourage you to experiment and let us know. Feel free to create a wiki article about what you did to get it working on your CI setup.
|
446
437
|
|
447
438
|
|
439
|
+
## With [BrowserStack](https://www.browserstack.com)
|
440
|
+
|
441
|
+
Running your javascript tests on the BrowserStack infrastructure is easy with the included `browserstack` driver.
|
442
|
+
|
443
|
+
In `teaspoon_env.rb` configure your driver to `config.driver = :browserstack`. You must add the browsers you'd like to test on as an array of hashes with key `capabilities` in `config.driver_options`. More details about the driver configurations are available on the [Using BrowserStack WebDriver](https://github.com/modeset/teaspoon/wiki/Using-BrowserStack-WebDriver) wiki article.
|
444
|
+
|
445
|
+
By default you can run 10 tests in parallel by default, and the number of tests running in parallel can be specified using the `max_parallel` driver option.
|
446
|
+
|
447
|
+
Now you can run Teaspoon locally and can see your tests running on the [BrowserStack Automate Dashboard](https://browserstack.com/automate).
|
448
|
+
|
449
|
+
|
448
450
|
## Alternative Projects
|
449
451
|
|
450
452
|
- [Konacha](https://github.com/jfirebaugh/konacha)
|
@@ -1,6 +1,10 @@
|
|
1
1
|
class Teaspoon::SuiteController < ActionController::Base
|
2
|
-
|
3
|
-
|
2
|
+
def self.before(*args)
|
3
|
+
respond_to?(:before_action) ? before_action(*args) : before_filter(*args)
|
4
|
+
end
|
5
|
+
|
6
|
+
before :check_env
|
7
|
+
before :prepend_fixture_paths
|
4
8
|
|
5
9
|
layout false
|
6
10
|
|
@@ -14,8 +18,8 @@ class Teaspoon::SuiteController < ActionController::Base
|
|
14
18
|
|
15
19
|
def hook
|
16
20
|
hooks = Teaspoon::Suite.new(params).hooks[params[:hook].to_s]
|
17
|
-
hooks.each { |hook| hook.call(params[:args]) }
|
18
|
-
|
21
|
+
hooks.each { |hook| hook.call(hook_params(params[:args])) }
|
22
|
+
head(:success)
|
19
23
|
end
|
20
24
|
|
21
25
|
def fixtures
|
@@ -33,4 +37,9 @@ class Teaspoon::SuiteController < ActionController::Base
|
|
33
37
|
prepend_view_path Teaspoon.configuration.root.join(path)
|
34
38
|
end
|
35
39
|
end
|
40
|
+
|
41
|
+
def hook_params(params)
|
42
|
+
return params.permit!.to_h if params.respond_to?(:permit!)
|
43
|
+
params
|
44
|
+
end
|
36
45
|
end
|
@@ -91,11 +91,12 @@ Teaspoon.configure do |config|
|
|
91
91
|
# Rake:
|
92
92
|
# teaspoon DRIVER=phantomjs SERVER_PORT=31337 FAIL_FAST=true FORMATTERS=junit suite=my_suite
|
93
93
|
|
94
|
-
# Specify which headless driver to use. Supports PhantomJS and
|
94
|
+
# Specify which headless driver to use. Supports PhantomJS, Selenium Webdriver and BrowserStack Webdriver.
|
95
95
|
#
|
96
96
|
# Available: <%= Teaspoon::Driver.available.keys.map{|f| ":#{f}"}.join(", ") %>
|
97
97
|
# PhantomJS: https://github.com/modeset/teaspoon/wiki/Using-PhantomJS
|
98
98
|
# Selenium Webdriver: https://github.com/modeset/teaspoon/wiki/Using-Selenium-WebDriver
|
99
|
+
# BrowserStack Webdriver: https://github.com/modeset/teaspoon/wiki/Using-BrowserStack-WebDriver
|
99
100
|
# Capybara Webkit: https://github.com/modeset/teaspoon/wiki/Using-Capybara-Webkit
|
100
101
|
#config.driver = :<%= Teaspoon::Driver.default %>
|
101
102
|
|
@@ -103,6 +104,7 @@ Teaspoon.configure do |config|
|
|
103
104
|
#
|
104
105
|
# PhantomJS: https://github.com/modeset/teaspoon/wiki/Using-PhantomJS
|
105
106
|
# Selenium Webdriver: https://github.com/modeset/teaspoon/wiki/Using-Selenium-WebDriver
|
107
|
+
# BrowserStack Webdriver: https://github.com/modeset/teaspoon/wiki/Using-BrowserStack-WebDriver
|
106
108
|
# Capybara Webkit: https://github.com/modeset/teaspoon/wiki/Using-Capybara-Webkit
|
107
109
|
#config.driver_options = nil
|
108
110
|
|
data/lib/teaspoon/driver.rb
CHANGED
@@ -12,4 +12,5 @@ end
|
|
12
12
|
|
13
13
|
Teaspoon::Driver.register(:phantomjs, "Teaspoon::Driver::Phantomjs", "teaspoon/driver/phantomjs", default: true)
|
14
14
|
Teaspoon::Driver.register(:selenium, "Teaspoon::Driver::Selenium", "teaspoon/driver/selenium")
|
15
|
+
Teaspoon::Driver.register(:browserstack, "Teaspoon::Driver::BrowserStack", "teaspoon/driver/browserstack")
|
15
16
|
Teaspoon::Driver.register(:capybara_webkit, "Teaspoon::Driver::CapybaraWebkit", "teaspoon/driver/capybara_webkit")
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# :nocov:
|
2
|
+
begin
|
3
|
+
require "selenium-webdriver"
|
4
|
+
rescue LoadError
|
5
|
+
Teaspoon.abort("Could not find Selenium Webdriver. Install the selenium-webdriver gem.")
|
6
|
+
end
|
7
|
+
# :nocov:
|
8
|
+
|
9
|
+
require "teaspoon/driver/base"
|
10
|
+
|
11
|
+
# The driver creates individual thread for each test.
|
12
|
+
# This limit is here to disallow too many threads
|
13
|
+
# Override via max_parallel key in options.
|
14
|
+
MAX_PARALLEL = 10
|
15
|
+
|
16
|
+
# Need to have BrowserStackLocal binary (https://www.browserstack.com/local-testing#command-line)
|
17
|
+
# running in the background to use this driver.
|
18
|
+
module Teaspoon
|
19
|
+
module Driver
|
20
|
+
class BrowserStack < Base
|
21
|
+
def initialize(options = nil)
|
22
|
+
options ||= {}
|
23
|
+
case options
|
24
|
+
when Hash then @options = options.symbolize_keys
|
25
|
+
when String then @options = JSON.parse(options).symbolize_keys
|
26
|
+
else raise Teaspoon::DriverOptionsError.new(types: "hash or json string")
|
27
|
+
end
|
28
|
+
|
29
|
+
unless @options[:capabilities] && @options[:capabilities].is_a?(Array)
|
30
|
+
raise Teaspoon::DriverOptionsError.new(types: "capabilities array." \
|
31
|
+
"Options must have a key 'capabilities' of type array")
|
32
|
+
end
|
33
|
+
@options[:capabilities].each(&:symbolize_keys!)
|
34
|
+
rescue JSON::ParserError
|
35
|
+
raise Teaspoon::DriverOptionsError.new(types: "hash or json string")
|
36
|
+
end
|
37
|
+
|
38
|
+
def run_specs(runner, url)
|
39
|
+
parallelize do
|
40
|
+
driver = Thread.current[:driver]
|
41
|
+
driver.navigate.to(url)
|
42
|
+
::Selenium::WebDriver::Wait.new(driver_options).until do
|
43
|
+
done = driver.execute_script("return window.Teaspoon && window.Teaspoon.finished")
|
44
|
+
driver.execute_script("return window.Teaspoon && window.Teaspoon.getMessages() || []").each do |line|
|
45
|
+
runner.process("#{line}\n")
|
46
|
+
end
|
47
|
+
done
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
protected
|
53
|
+
|
54
|
+
def parallelize
|
55
|
+
threads = []
|
56
|
+
left_capabilities = capabilities
|
57
|
+
until left_capabilities.empty?
|
58
|
+
left_capabilities.pop(max_parallel).each do |desired_capability|
|
59
|
+
desired_capability[:"browserstack.local"] = true
|
60
|
+
desired_capability[:project] = driver_options[:project] if driver_options[:project]
|
61
|
+
desired_capability[:build] = driver_options[:build] if driver_options[:build]
|
62
|
+
threads << Thread.new do
|
63
|
+
driver = ::Selenium::WebDriver.for(:remote, url: hub_url, desired_capabilities: desired_capability)
|
64
|
+
Thread.current[:driver] = driver
|
65
|
+
capability = driver.capabilities
|
66
|
+
|
67
|
+
Thread.current[:name] = "Session on #{capability[:platform].to_s.strip}," \
|
68
|
+
"#{capability[:browser_name].to_s.strip} #{capability[:version].to_s.strip}"
|
69
|
+
|
70
|
+
yield
|
71
|
+
Thread.current[:driver].quit
|
72
|
+
STDOUT.print("#{Thread.current[:name]} Completed\n") unless Teaspoon.configuration.suppress_log
|
73
|
+
end
|
74
|
+
end
|
75
|
+
threads.each(&:join)
|
76
|
+
threads = []
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def capabilities
|
81
|
+
driver_options[:capabilities]
|
82
|
+
end
|
83
|
+
|
84
|
+
def hub_url
|
85
|
+
"https://#{username}:#{access_key}@hub.browserstack.com/wd/hub"
|
86
|
+
end
|
87
|
+
|
88
|
+
def username
|
89
|
+
driver_options[:username] || ENV["BROWSERSTACK_USERNAME"]
|
90
|
+
end
|
91
|
+
|
92
|
+
def access_key
|
93
|
+
driver_options[:access_key] || ENV["BROWSERSTACK_ACCESS_KEY"]
|
94
|
+
end
|
95
|
+
|
96
|
+
def max_parallel
|
97
|
+
parallel = MAX_PARALLEL
|
98
|
+
begin
|
99
|
+
parallel = driver_options[:max_parallel].to_i if driver_options[:max_parallel].to_i > 0
|
100
|
+
rescue
|
101
|
+
end
|
102
|
+
parallel
|
103
|
+
end
|
104
|
+
|
105
|
+
def driver_options
|
106
|
+
@driver_options ||= HashWithIndifferentAccess.new(
|
107
|
+
timeout: Teaspoon.configuration.driver_timeout.to_i,
|
108
|
+
interval: 0.01,
|
109
|
+
message: "Timed out"
|
110
|
+
).merge(@options)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -54,8 +54,7 @@ module Teaspoon
|
|
54
54
|
|
55
55
|
def executable
|
56
56
|
return @executable if @executable
|
57
|
-
@executable = which("phantomjs")
|
58
|
-
@executable = ::Phantomjs.path if @executable.blank? && defined?(::Phantomjs)
|
57
|
+
@executable = defined?(::Phantomjs) ? ::Phantomjs.path : which("phantomjs")
|
59
58
|
return @executable unless @executable.blank?
|
60
59
|
raise Teaspoon::MissingDependencyError.new("Unable to locate phantomjs. Install it or use the phantomjs gem.")
|
61
60
|
end
|
data/lib/teaspoon/engine.rb
CHANGED
@@ -51,6 +51,9 @@ module Teaspoon
|
|
51
51
|
|
52
52
|
def self.inject_instrumentation
|
53
53
|
Sprockets::Environment.send(:include, Teaspoon::SprocketsInstrumentation)
|
54
|
+
Sprockets::CachedEnvironment.send(:include, Teaspoon::SprocketsInstrumentation)
|
55
|
+
rescue NameError
|
56
|
+
# Handle cached environment in Sprockets 2.x
|
54
57
|
Sprockets::Index.send(:include, Teaspoon::SprocketsInstrumentation)
|
55
58
|
end
|
56
59
|
|
@@ -80,7 +83,7 @@ module Teaspoon
|
|
80
83
|
private
|
81
84
|
|
82
85
|
def self.using_phantomjs?
|
83
|
-
Teaspoon::Driver.
|
86
|
+
Teaspoon::Driver.matches?(Teaspoon.configuration.driver, :phantomjs)
|
84
87
|
end
|
85
88
|
|
86
89
|
def self.render_exceptions_with_javascript
|
@@ -98,12 +101,12 @@ end
|
|
98
101
|
|
99
102
|
begin
|
100
103
|
require 'action_view'
|
101
|
-
if ActionView::VERSION::STRING
|
104
|
+
if ActionView::VERSION::STRING >= '4.2.5'
|
102
105
|
require 'action_view/helpers/asset_tag_helper'
|
103
106
|
module ActionView::Helpers::AssetTagHelper
|
104
107
|
def javascript_include_tag(*sources)
|
105
108
|
options = sources.extract_options!.stringify_keys
|
106
|
-
path_options = options.extract!('protocol', 'extname').symbolize_keys
|
109
|
+
path_options = options.extract!('protocol', 'extname', 'host').symbolize_keys
|
107
110
|
path_options[:debug] = options['allow_non_precompiled']
|
108
111
|
sources.uniq.map { |source|
|
109
112
|
tag_options = {
|
@@ -9,7 +9,8 @@ module Teaspoon
|
|
9
9
|
def log_runner(result)
|
10
10
|
log_line(%{<?xml version="1.0" encoding="UTF-8"?>})
|
11
11
|
log_line(%{<testsuites name="Teaspoon">})
|
12
|
-
|
12
|
+
start_time = Time.parse(result.start).iso8601
|
13
|
+
log_line(%{<testsuite name="#{escape(@suite_name)}" tests="#{@total_count}" timestamp="#{start_time}">})
|
13
14
|
end
|
14
15
|
|
15
16
|
def log_suite(result)
|
data/lib/teaspoon/registry.rb
CHANGED
data/lib/teaspoon/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: teaspoon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jejacks0n
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2016-
|
14
|
+
date: 2016-03-25 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: railties
|
@@ -22,7 +22,7 @@ dependencies:
|
|
22
22
|
version: 3.2.5
|
23
23
|
- - "<"
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version: '
|
25
|
+
version: '6'
|
26
26
|
type: :runtime
|
27
27
|
prerelease: false
|
28
28
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: 3.2.5
|
33
33
|
- - "<"
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: '
|
35
|
+
version: '6'
|
36
36
|
description: Run Javascript tests using Jasmine, Mocha or QUnit in the browser or
|
37
37
|
headless using PhantomJS, Selenium Webdriver, or Capybara Webkit
|
38
38
|
email:
|
@@ -95,6 +95,7 @@ files:
|
|
95
95
|
- lib/teaspoon/deprecated.rb
|
96
96
|
- lib/teaspoon/driver.rb
|
97
97
|
- lib/teaspoon/driver/base.rb
|
98
|
+
- lib/teaspoon/driver/browserstack.rb
|
98
99
|
- lib/teaspoon/driver/capybara_webkit.rb
|
99
100
|
- lib/teaspoon/driver/phantomjs.rb
|
100
101
|
- lib/teaspoon/driver/phantomjs/runner.js
|
@@ -149,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
150
|
version: '0'
|
150
151
|
requirements: []
|
151
152
|
rubyforge_project:
|
152
|
-
rubygems_version: 2.
|
153
|
+
rubygems_version: 2.5.1
|
153
154
|
signing_key:
|
154
155
|
specification_version: 4
|
155
156
|
summary: 'Teaspoon: A Javascript test runner built on top of Rails'
|