hyper-spec 0.1.2 → 0.99.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +3 -0
- data/.travis.yml +26 -0
- data/Gemfile +3 -2
- data/Gemfile.lock +222 -193
- data/README.md +3 -1
- data/Rakefile +6 -0
- data/hyper-spec.gemspec +45 -57
- data/lib/bin/firebug-2.0.19-fx.xpi +0 -0
- data/lib/hyper-spec.rb +57 -38
- data/lib/hyper-spec/component_test_helpers.rb +91 -37
- data/lib/hyper-spec/time_cop.rb +152 -2
- data/lib/hyper-spec/version.rb +1 -1
- data/lib/hyper-spec/wait_for_ajax.rb +23 -8
- data/lib/react/top_level_rails_component.rb +37 -47
- data/lib/selenium/web_driver/firefox/profile.rb +3 -3
- data/lib/sources/lolex.js +733 -0
- metadata +136 -87
- data/.rubocop.yml +0 -107
- data/CODE_OF_CONDUCT.md +0 -49
- data/LICENSE.txt +0 -21
- data/lib/hyper-spec/component_helpers.rb +0 -368
- data/lib/hyper-spec/lolex.rb +0 -66
- data/lib/hyper-spec/rails/engine.rb +0 -8
- data/lib/react/isomorphic_helpers.rb +0 -7
- data/vendor/assets/javascripts/lolex.js +0 -658
- data/vendor/assets/javascripts/time_cop.rb +0 -190
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# HyperSpec
|
2
2
|
|
3
|
+
[![Build Status](https://travis-ci.org/ruby-hyperloop/hyper-spec.svg?branch=master)](https://travis-ci.org/ruby-hyperloop/hyper-spec)
|
4
|
+
|
3
5
|
With HyperSpec you can run *isomorphic* specs for all your Hyperloop code using RSpec. Everything runs as standard RSpec test specs.
|
4
6
|
|
5
7
|
For example if you have a component like this:
|
@@ -47,7 +49,7 @@ end
|
|
47
49
|
|
48
50
|
Hyperloop wants to make the server-client divide as transparent to the developer as practical. Given this, it makes sense that the testing should also be done with as little concern for client versus server.
|
49
51
|
|
50
|
-
HyperSpec allows you to directly use tools like
|
52
|
+
HyperSpec allows you to directly use tools like FactoryBot (or Hyperloop Operations) to setup some test data, then run a spec to make sure that a component correctly displays, or modifies that data. You can use Timecop to manipulate time and keep in sync between the server and client. This makes testing easier and more realistic without writing a lot of redundant code.
|
51
53
|
|
52
54
|
|
53
55
|
## Installation
|
data/Rakefile
CHANGED
data/hyper-spec.gemspec
CHANGED
@@ -6,67 +6,55 @@ require 'hyper-spec/version'
|
|
6
6
|
Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
|
7
7
|
spec.name = 'hyper-spec'
|
8
8
|
spec.version = HyperSpec::VERSION
|
9
|
-
spec.authors = ['
|
10
|
-
spec.email = ['mitch@catprint.com']
|
11
|
-
|
12
|
-
spec.
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
'Active Record Models, Stores, Operations and Policiespec. '\
|
17
|
-
'Test them all from Rspec, regardless if the code runs on the client or server.'
|
18
|
-
spec.homepage = 'https://github.com/ruby-hyperloop/hyper-spec'
|
9
|
+
spec.authors = ['Mitch VanDuyn', 'Adam Creekroad', 'Jan Biedermann']
|
10
|
+
spec.email = ['mitch@catprint.com', 'jan@kursator.com']
|
11
|
+
spec.summary = 'Drive your Hyperloop client and server specs from RSpec and Capybara'
|
12
|
+
spec.description = 'A Hyperloop application consists of isomorphic React Components, '\
|
13
|
+
'Active Record Models, Stores, Operations and Policiespec. '\
|
14
|
+
'Test them all from Rspec, regardless if the code runs on the client or server.'
|
15
|
+
spec.homepage = 'http://ruby-hyperloop.org'
|
19
16
|
spec.license = 'MIT'
|
17
|
+
# spec.metadata = {
|
18
|
+
# "homepage_uri" => 'http://ruby-hyperloop.org',
|
19
|
+
# "source_code_uri" => 'https://github.com/ruby-hyperloop/hyper-component'
|
20
|
+
# }
|
20
21
|
|
21
|
-
|
22
|
-
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
23
|
-
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
24
|
-
|
25
|
-
spec.files =
|
26
|
-
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
22
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(gemfiles|spec)/}) }
|
27
23
|
spec.bindir = 'exe'
|
28
24
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
29
25
|
spec.require_paths = ['lib']
|
30
26
|
|
31
|
-
|
32
|
-
spec.
|
33
|
-
spec.
|
34
|
-
spec.
|
35
|
-
spec.
|
36
|
-
spec.
|
37
|
-
|
38
|
-
|
39
|
-
spec.
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
spec.add_development_dependency 'rspec-expectations'
|
65
|
-
spec.add_development_dependency 'rspec-its'
|
66
|
-
spec.add_development_dependency 'rspec-mocks'
|
67
|
-
spec.add_development_dependency 'rspec-steps'
|
68
|
-
spec.add_development_dependency 'shoulda'
|
69
|
-
spec.add_development_dependency 'shoulda-matchers'
|
70
|
-
spec.add_development_dependency 'spring-commands-rspec'
|
71
|
-
end
|
27
|
+
spec.add_dependency 'capybara'
|
28
|
+
spec.add_dependency 'chromedriver-helper', '1.2.0'
|
29
|
+
spec.add_dependency 'libv8', '~> 6.3.0' # see https://github.com/discourse/mini_racer/issues/92
|
30
|
+
spec.add_dependency 'method_source'
|
31
|
+
spec.add_dependency 'mini_racer', '~> 0.1.15'
|
32
|
+
spec.add_dependency 'opal', '>= 0.11.0', '< 0.12.0'
|
33
|
+
spec.add_dependency 'parser', '>= 2.3.3.1'
|
34
|
+
spec.add_dependency 'pry'
|
35
|
+
spec.add_dependency 'rspec-rails'
|
36
|
+
spec.add_dependency 'selenium-webdriver'
|
37
|
+
spec.add_dependency 'timecop', '~> 0.8.1'
|
38
|
+
spec.add_dependency 'uglifier'
|
39
|
+
spec.add_dependency 'unparser'
|
40
|
+
spec.add_dependency 'webdrivers'
|
41
|
+
|
42
|
+
spec.add_development_dependency 'bundler'
|
43
|
+
spec.add_development_dependency 'hyper-component', HyperSpec::VERSION
|
44
|
+
spec.add_development_dependency 'opal-browser', '~> 0.2.0'
|
45
|
+
spec.add_development_dependency 'opal-rails', '~> 0.9.4'
|
46
|
+
spec.add_development_dependency 'pry-rescue'
|
47
|
+
spec.add_development_dependency 'puma'
|
48
|
+
spec.add_development_dependency 'rails', '>= 4.0.0'
|
49
|
+
spec.add_development_dependency 'rake'
|
50
|
+
spec.add_development_dependency 'react-rails', '>= 2.3.0', '< 2.5.0'
|
51
|
+
spec.add_development_dependency 'rspec-collection_matchers'
|
52
|
+
spec.add_development_dependency 'rspec-expectations'
|
53
|
+
spec.add_development_dependency 'rspec-its'
|
54
|
+
spec.add_development_dependency 'rspec-mocks'
|
55
|
+
spec.add_development_dependency 'rspec-steps', '~> 2.1.1'
|
56
|
+
spec.add_development_dependency 'rubocop', '~> 0.51.0'
|
57
|
+
spec.add_development_dependency 'shoulda'
|
58
|
+
spec.add_development_dependency 'shoulda-matchers'
|
59
|
+
spec.add_development_dependency 'spring-commands-rspec'
|
72
60
|
end
|
Binary file
|
data/lib/hyper-spec.rb
CHANGED
@@ -1,13 +1,10 @@
|
|
1
1
|
require 'capybara/rspec'
|
2
|
-
require 'capybara/poltergeist'
|
3
2
|
require 'opal'
|
4
3
|
require 'selenium-webdriver'
|
5
4
|
|
6
5
|
require 'hyper-spec/component_test_helpers'
|
7
|
-
require 'hyper-spec/rails/engine'
|
8
6
|
require 'hyper-spec/version'
|
9
7
|
require 'hyper-spec/wait_for_ajax'
|
10
|
-
require 'react/isomorphic_helpers'
|
11
8
|
require 'selenium/web_driver/firefox/profile'
|
12
9
|
|
13
10
|
RSpec.configure do |config|
|
@@ -17,14 +14,20 @@ RSpec.configure do |config|
|
|
17
14
|
|
18
15
|
config.mock_with :rspec
|
19
16
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
17
|
+
config.add_setting :debugger_width, default: nil
|
18
|
+
|
19
|
+
config.before(:each) do
|
20
|
+
Hyperloop.class_eval do
|
21
|
+
def self.on_server?
|
22
|
+
true
|
26
23
|
end
|
27
|
-
end
|
24
|
+
end if defined?(Hyperloop)
|
25
|
+
# for compatibility with HyperMesh
|
26
|
+
HyperMesh.class_eval do
|
27
|
+
def self.on_server?
|
28
|
+
true
|
29
|
+
end
|
30
|
+
end if defined?(HyperMesh)
|
28
31
|
end
|
29
32
|
|
30
33
|
config.before(:each, js: true) do
|
@@ -40,49 +43,65 @@ RSpec.configure do |config|
|
|
40
43
|
PusherFake::Channel.reset if defined? PusherFake
|
41
44
|
end
|
42
45
|
end
|
46
|
+
|
43
47
|
end
|
44
48
|
|
45
49
|
# Capybara config
|
46
50
|
RSpec.configure do |_config|
|
47
51
|
Capybara.default_max_wait_time = 10
|
48
52
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
js_errors: false, timeout: 180, inspector: true,
|
61
|
-
phantomjs_options: ['--load-images=no', '--ignore-ssl-errors=yes']
|
62
|
-
}.tap do |hash|
|
63
|
-
unless ENV['SHOW_LOGS']
|
64
|
-
hash[:phantomjs_logger] = StringIO.new
|
65
|
-
hash[:logger] = StringIO.new
|
66
|
-
end
|
67
|
-
end
|
53
|
+
Capybara.register_driver :chrome do |app|
|
54
|
+
options = {}
|
55
|
+
options.merge!(
|
56
|
+
args: %w[auto-open-devtools-for-tabs],
|
57
|
+
prefs: { 'devtools.open_docked' => false, "devtools.currentDockState" => "undocked", devtools: {currentDockState: :undocked} }
|
58
|
+
) unless ENV['NO_DEBUGGER']
|
59
|
+
# this does not seem to work properly. Don't document this feature yet.
|
60
|
+
options['mobileEmulation'] = { 'deviceName' => ENV['DEVICE'].tr('-', ' ') } if ENV['DEVICE']
|
61
|
+
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(chromeOptions: options)
|
62
|
+
Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: capabilities)
|
63
|
+
end
|
68
64
|
|
69
|
-
|
65
|
+
Capybara.register_driver :chrome_headless_docker_travis do |app|
|
66
|
+
options = ::Selenium::WebDriver::Chrome::Options.new
|
67
|
+
options.add_argument('--headless')
|
68
|
+
options.add_argument('--no-sandbox')
|
69
|
+
options.add_argument('--disable-dev-shm-usage')
|
70
|
+
Capybara::Selenium::Driver.new(app, browser: :chrome, :driver_path => "/usr/lib/chromium-browser/chromedriver", options: options)
|
71
|
+
end
|
72
|
+
|
73
|
+
Capybara.register_driver :firefox do |app|
|
74
|
+
Capybara::Selenium::Driver.new(app, browser: :firefox)
|
75
|
+
end
|
76
|
+
|
77
|
+
Capybara.register_driver :firefox_headless do |app|
|
78
|
+
options = Selenium::WebDriver::Firefox::Options.new
|
79
|
+
options.headless!
|
80
|
+
Capybara::Selenium::Driver.new(app, browser: :firefox, options: options)
|
70
81
|
end
|
71
82
|
|
72
83
|
Capybara.register_driver :selenium_with_firebug do |app|
|
73
84
|
profile = Selenium::WebDriver::Firefox::Profile.new
|
74
|
-
|
85
|
+
ENV['FRAME_POSITION'] && profile.frame_position = ENV['FRAME_POSITION']
|
75
86
|
profile.enable_firebug
|
87
|
+
options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
|
88
|
+
Capybara::Selenium::Driver.new(app, browser: :firefox, options: options)
|
89
|
+
end
|
76
90
|
|
77
|
-
|
91
|
+
Capybara.register_driver :safari do |app|
|
92
|
+
Capybara::Selenium::Driver.new(app, browser: :safari)
|
78
93
|
end
|
79
94
|
|
80
95
|
Capybara.javascript_driver =
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
96
|
+
case ENV['DRIVER']
|
97
|
+
when 'beheaded' then :firefox_headless
|
98
|
+
when 'chrome' then :chrome
|
99
|
+
when 'ff' then :selenium_with_firebug
|
100
|
+
when 'firefox' then :firefox
|
101
|
+
when 'headless' then :selenium_chrome_headless
|
102
|
+
when 'safari' then :safari
|
103
|
+
when 'travis' then :chrome_headless_docker_travis
|
104
|
+
else :selenium_chrome_headless
|
87
105
|
end
|
106
|
+
|
88
107
|
end
|
@@ -1,29 +1,31 @@
|
|
1
1
|
# see component_test_helpers_spec.rb for examples
|
2
|
-
|
3
2
|
require 'parser/current'
|
4
3
|
require 'unparser'
|
5
4
|
require 'method_source'
|
6
|
-
require_relative '../../
|
5
|
+
require_relative '../../lib/hyper-spec/time_cop.rb'
|
7
6
|
|
8
7
|
module HyperSpec
|
9
8
|
module ComponentTestHelpers
|
10
9
|
TOP_LEVEL_COMPONENT_PATCH =
|
11
10
|
Opal.compile(File.read(File.expand_path('../../react/top_level_rails_component.rb', __FILE__)))
|
11
|
+
TIME_COP_CLIENT_PATCH =
|
12
|
+
Opal.compile(File.read(File.expand_path('../../hyper-spec/time_cop.rb', __FILE__))) +
|
13
|
+
"\n#{File.read(File.expand_path('../../sources/lolex.js', __FILE__))}"
|
12
14
|
|
13
15
|
class << self
|
14
16
|
attr_accessor :current_example
|
15
17
|
attr_accessor :description_displayed
|
16
18
|
|
17
19
|
def display_example_description
|
18
|
-
"<script type='text/javascript'>console.log(
|
19
|
-
",'color:green; font-weight:bold; font-size: 200%')
|
20
|
+
"<script type='text/javascript'>console.log('%c#{current_example.description}'"\
|
21
|
+
",'color:green; font-weight:bold; font-size: 200%')</script>"
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
25
|
def build_test_url_for(controller)
|
24
26
|
unless controller
|
25
27
|
unless defined?(::ReactTestController)
|
26
|
-
Object.const_set('ReactTestController', Class.new(ActionController::Base))
|
28
|
+
Object.const_set('ReactTestController', Class.new(::ActionController::Base))
|
27
29
|
end
|
28
30
|
|
29
31
|
controller = ::ReactTestController
|
@@ -47,11 +49,14 @@ module HyperSpec
|
|
47
49
|
|
48
50
|
page = '<%= react_component @component_name, @component_params, '\
|
49
51
|
"{ prerender: #{render_on != :client_only} } %>"
|
50
|
-
|
51
|
-
|
52
|
-
|
52
|
+
unless render_on == :server_only
|
53
|
+
page = "<script type='text/javascript'>\n#{TOP_LEVEL_COMPONENT_PATCH}\n</script>\n#{page}"
|
54
|
+
page = "<script type='text/javascript'>\n#{code}\n</script>\n#{page}" if code
|
55
|
+
end
|
53
56
|
|
54
|
-
|
57
|
+
if render_on != :server_only || Lolex.initialized?
|
58
|
+
page = "<script type='text/javascript'>\n#{TIME_COP_CLIENT_PATCH}\n</script>\n#{page}"
|
59
|
+
end
|
55
60
|
|
56
61
|
if (render_on != :server_only && !render_params[:layout]) || javascript
|
57
62
|
page = "<%= javascript_include_tag '#{javascript || 'application'}' %>\n#{page}"
|
@@ -60,22 +65,14 @@ module HyperSpec
|
|
60
65
|
if !render_params[:layout] || style_sheet
|
61
66
|
page = "<%= stylesheet_link_tag '#{style_sheet || 'application'}' %>\n#{page}"
|
62
67
|
end
|
63
|
-
|
64
|
-
if render_on == :server_only # so that test helper wait_for_ajax works
|
65
|
-
page = "<script type='text/javascript'>window.jQuery = {'active': 0}</script>\n#{page}"
|
66
|
-
else
|
67
|
-
page = "<%= javascript_include_tag 'jquery' %>\n"\
|
68
|
-
"<%= javascript_include_tag 'jquery_ujs' %>\n#{page}"
|
69
|
-
end
|
70
|
-
|
71
68
|
page = "<script type='text/javascript'>go = function() "\
|
72
69
|
"{window.hyper_spec_waiting_for_go = false}</script>\n#{page}"
|
73
70
|
|
74
71
|
title = view_context.escape_javascript(ComponentTestHelpers.current_example.description)
|
75
72
|
title = "#{title}...continued." if ComponentTestHelpers.description_displayed
|
76
73
|
|
77
|
-
page = "<script type='text/javascript'>console.log(
|
78
|
-
"'color:green; font-weight:bold; font-size: 200%')
|
74
|
+
page = "<script type='text/javascript'>console.log('%c#{title}',"\
|
75
|
+
"'color:green; font-weight:bold; font-size: 200%')</script>\n#{page}"
|
79
76
|
|
80
77
|
ComponentTestHelpers.description_displayed = true
|
81
78
|
render_params[:inline] = page
|
@@ -112,6 +109,8 @@ module HyperSpec
|
|
112
109
|
str = "#{str}\n#{Unparser.unparse Parser::CurrentRuby.parse(block.source).children.last}"
|
113
110
|
end
|
114
111
|
js = Opal.compile(str).delete("\n").gsub('(Opal);', '(Opal)')
|
112
|
+
# workaround for firefox 58 and geckodriver 0.19.1, because firefox is unable to find .$to_json:
|
113
|
+
# JSON.parse(evaluate_script("(function(){var a=Opal.Array.$new(); a[0]=#{js}; return a.$to_json();})();"), opts).first
|
115
114
|
JSON.parse(evaluate_script("[#{js}].$to_json()"), opts).first
|
116
115
|
end
|
117
116
|
|
@@ -129,25 +128,25 @@ module HyperSpec
|
|
129
128
|
"#{Unparser.unparse Parser::CurrentRuby.parse(block.source).children.first.children.last}"
|
130
129
|
end
|
131
130
|
|
132
|
-
def
|
131
|
+
def evaluate_promise(str = '', opts = {}, &block)
|
133
132
|
insure_mount
|
134
|
-
|
135
|
-
str = add_opal_block(str, block)
|
133
|
+
str = "#{str}\n#{Unparser.unparse Parser::CurrentRuby.parse(block.source).children.last}" if block
|
136
134
|
str = "#{str}.then { |args| args = [args]; `window.hyper_spec_promise_result = args` }"
|
137
|
-
js = Opal.compile(str).
|
138
|
-
page.evaluate_script(
|
135
|
+
js = Opal.compile(str).gsub("\n","").gsub("(Opal);","(Opal)")
|
136
|
+
page.evaluate_script("window.hyper_spec_promise_result = false")
|
139
137
|
page.execute_script(js)
|
140
|
-
|
141
138
|
Timeout.timeout(Capybara.default_max_wait_time) do
|
142
139
|
loop do
|
143
140
|
sleep 0.25
|
144
|
-
break if page.evaluate_script(
|
141
|
+
break if page.evaluate_script("!!window.hyper_spec_promise_result")
|
145
142
|
end
|
146
143
|
end
|
144
|
+
JSON.parse(page.evaluate_script("window.hyper_spec_promise_result.$to_json()"), opts).first
|
145
|
+
end
|
147
146
|
|
148
|
-
|
149
|
-
|
150
|
-
expect(
|
147
|
+
def expect_promise(str = '', opts = {}, &block)
|
148
|
+
insure_mount
|
149
|
+
expect(evaluate_promise(add_opal_block(str, block), opts))
|
151
150
|
end
|
152
151
|
|
153
152
|
def ppr(str)
|
@@ -193,19 +192,32 @@ module HyperSpec
|
|
193
192
|
`eval(s)`
|
194
193
|
end
|
195
194
|
def self.dasherize(s)
|
196
|
-
|
195
|
+
res = %x{
|
196
|
+
s.replace(/[-_\\s]+/g, '-')
|
197
197
|
.replace(/([A-Z\\d]+)([A-Z][a-z])/g, '$1-$2')
|
198
198
|
.replace(/([a-z\\d])([A-Z])/g, '$1-$2')
|
199
|
-
.toLowerCase()
|
199
|
+
.toLowerCase()
|
200
|
+
}
|
201
|
+
res
|
200
202
|
end
|
201
203
|
def self.add_class(class_name, styles={})
|
202
|
-
style = styles.collect { |attr, value| "\#{dasherize(attr)}:\#{value}"}.join("; ")
|
203
|
-
|
204
|
-
|
204
|
+
style = styles.collect { |attr, value| "\#{dasherize(attr)}:\#{value}" }.join("; ")
|
205
|
+
cs = class_name.to_s
|
206
|
+
%x{
|
207
|
+
var style_el = document.createElement("style");
|
208
|
+
var css = "." + cs + " { " + style + " }";
|
209
|
+
style_el.type = "text/css";
|
210
|
+
if (style_el.styleSheet){
|
211
|
+
style_el.styleSheet.cssText = css;
|
212
|
+
} else {
|
213
|
+
style_el.appendChild(document.createTextNode(css));
|
214
|
+
}
|
215
|
+
document.head.appendChild(style_el);
|
216
|
+
}
|
205
217
|
end
|
206
218
|
end
|
207
219
|
class React::Component::HyperTestDummy < React::Component::Base
|
208
|
-
|
220
|
+
def render; end
|
209
221
|
end
|
210
222
|
#{@client_code}
|
211
223
|
#{Unparser.unparse(Parser::CurrentRuby.parse(block.source).children.last) if block}
|
@@ -215,6 +227,19 @@ module HyperSpec
|
|
215
227
|
|
216
228
|
component_name ||= 'React::Component::HyperTestDummy'
|
217
229
|
::Rails.cache.write(test_url, [component_name, params, opts])
|
230
|
+
test_code_key = "hyper_spec_prerender_test_code.js"
|
231
|
+
@@original_server_render_files ||= ::Rails.configuration.react.server_renderer_options[:files]
|
232
|
+
if opts[:render_on] == :both || opts[:render_on] == :server_only
|
233
|
+
unless opts[:code].blank?
|
234
|
+
::Rails.cache.write(test_code_key, opts[:code])
|
235
|
+
::Rails.configuration.react.server_renderer_options[:files] = @@original_server_render_files + [test_code_key]
|
236
|
+
::React::ServerRendering.reset_pool # make sure contexts are reloaded so they dont use code from cache, as the rails filewatcher doesnt look for cache changes
|
237
|
+
else
|
238
|
+
::Rails.cache.delete(test_code_key)
|
239
|
+
::Rails.configuration.react.server_renderer_options[:files] = @@original_server_render_files
|
240
|
+
::React::ServerRendering.reset_pool # make sure contexts are reloaded so they dont use code from cache, as the rails filewatcher doesnt look for cache changes
|
241
|
+
end
|
242
|
+
end
|
218
243
|
visit test_url
|
219
244
|
wait_for_ajax unless opts[:no_wait]
|
220
245
|
page.instance_variable_set('@hyper_spec_mounted', true)
|
@@ -234,7 +259,7 @@ module HyperSpec
|
|
234
259
|
end
|
235
260
|
|
236
261
|
def add_class(class_name, style)
|
237
|
-
@client_code = "#{@client_code}ComponentHelpers.add_class
|
262
|
+
@client_code = "#{@client_code}ComponentHelpers.add_class('#{class_name}', #{style})\n"
|
238
263
|
end
|
239
264
|
|
240
265
|
def open_in_chrome
|
@@ -263,7 +288,28 @@ module HyperSpec
|
|
263
288
|
end
|
264
289
|
end
|
265
290
|
|
291
|
+
def wait_for_size(width, height)
|
292
|
+
start_time = Capybara::Helpers.monotonic_time
|
293
|
+
stable_count_w = 0
|
294
|
+
stable_count_h = 0
|
295
|
+
prev_size = [0, 0]
|
296
|
+
begin
|
297
|
+
sleep 0.05
|
298
|
+
curr_size = Capybara.current_session.current_window.size
|
299
|
+
return if [width, height] == curr_size
|
300
|
+
# some maximum or minimum is reached and size doesnt change anymore
|
301
|
+
stable_count_w += 1 if prev_size[0] == curr_size[0]
|
302
|
+
stable_count_h += 1 if prev_size[1] == curr_size[1]
|
303
|
+
return if stable_count_w > 2 || stable_count_h > 2
|
304
|
+
prev_size = curr_size
|
305
|
+
end while (Capybara::Helpers.monotonic_time - start_time) < Capybara.current_session.config.default_max_wait_time
|
306
|
+
raise Capybara::WindowError, "Window size not stable within #{Capybara.current_session.config.default_max_wait_time} seconds."
|
307
|
+
end
|
308
|
+
|
266
309
|
def size_window(width = nil, height = nil)
|
310
|
+
# return if @window_cannot_be_resized
|
311
|
+
# original_width = evaluate_script('window.innerWidth')
|
312
|
+
# original_height = evaluate_script('window.innerHeight')
|
267
313
|
width, height = [height, width] if width == :portrait
|
268
314
|
width, height = width if width.is_a? Array
|
269
315
|
portrait = true if height == :portrait
|
@@ -283,7 +329,15 @@ module HyperSpec
|
|
283
329
|
|
284
330
|
width, height = [height, width] if portrait
|
285
331
|
|
286
|
-
|
332
|
+
unless RSpec.configuration.debugger_width
|
333
|
+
Capybara.current_session.current_window.resize_to(1000, 500)
|
334
|
+
wait_for_size(1000, 500)
|
335
|
+
inner_width = evaluate_script('window.innerWidth')
|
336
|
+
RSpec.configuration.debugger_width = 1000 - inner_width
|
337
|
+
end
|
338
|
+
Capybara.current_session.current_window
|
339
|
+
.resize_to(width + RSpec.configuration.debugger_width, height)
|
340
|
+
wait_for_size(width + RSpec.configuration.debugger_width, height)
|
287
341
|
end
|
288
342
|
end
|
289
343
|
|