crabfarm 0.6.1 → 0.6.2
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 +4 -4
- data/assets/live-tools/tools.js +0 -1
- data/lib/crabfarm/adapters/browser/abstract_webdriver.rb +13 -28
- data/lib/crabfarm/adapters/browser/base.rb +43 -0
- data/lib/crabfarm/adapters/browser/chrome.rb +5 -1
- data/lib/crabfarm/adapters/browser/firefox.rb +4 -0
- data/lib/crabfarm/adapters/browser/noop.rb +3 -10
- data/lib/crabfarm/adapters/browser/phantom_js.rb +8 -8
- data/lib/crabfarm/adapters/driver_wrapper/pincers.rb +6 -0
- data/lib/crabfarm/cli.rb +1 -7
- data/lib/crabfarm/context.rb +17 -21
- data/lib/crabfarm/driver_pool.rb +3 -2
- data/lib/crabfarm/errors.rb +2 -0
- data/lib/crabfarm/http_client.rb +1 -1
- data/lib/crabfarm/live/context.rb +32 -2
- data/lib/crabfarm/live/controller.rb +19 -16
- data/lib/crabfarm/live/interactable.rb +5 -14
- data/lib/crabfarm/live/manager.rb +85 -95
- data/lib/crabfarm/live/navigator_runner.rb +43 -40
- data/lib/crabfarm/live/navigator_runner_direct.rb +1 -2
- data/lib/crabfarm/live/navigator_runner_rspec.rb +34 -55
- data/lib/crabfarm/live/reducer_runner.rb +43 -22
- data/lib/crabfarm/live/reducer_runner_direct.rb +1 -2
- data/lib/crabfarm/live/reducer_runner_rspec.rb +0 -5
- data/lib/crabfarm/live/viewer.rb +92 -0
- data/lib/crabfarm/live/watcher.rb +6 -1
- data/lib/crabfarm/modes/live.rb +1 -1
- data/lib/crabfarm/modes/recorder/snapshot.rb +9 -25
- data/lib/crabfarm/support/webdriver_factory.rb +1 -1
- data/lib/crabfarm/templates/Gemfile.erb +1 -1
- data/lib/crabfarm/utils/rspec_runner.rb +54 -22
- data/lib/crabfarm/version.rb +1 -1
- metadata +4 -2
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'crabfarm/utils/webdriver'
|
2
|
-
|
3
1
|
module Crabfarm
|
4
2
|
module Live
|
5
3
|
module Interactable
|
@@ -29,19 +27,12 @@ module Crabfarm
|
|
29
27
|
|
30
28
|
end
|
31
29
|
|
32
|
-
|
33
|
-
|
34
|
-
def highlight(_elements)
|
30
|
+
def examine(_tools=true)
|
35
31
|
if Crabfarm.live?
|
36
|
-
if
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
if _elements.is_a? String
|
41
|
-
_elements = Crabfarm.live.primary_driver.find_elements(css: _elements)
|
42
|
-
end
|
43
|
-
|
44
|
-
Utils::Webdriver.set_style _elements, "border: 3px solid yellow;"
|
32
|
+
Crabfarm.live.show_primary_contents if self.is_a? BaseNavigator
|
33
|
+
Crabfarm.live.show_content raw_document if self.is_a? BaseReducer
|
34
|
+
Crabfarm.live.show_selector_gadget if _tools
|
35
|
+
raise LiveInterrupted.new
|
45
36
|
end
|
46
37
|
end
|
47
38
|
|
@@ -1,49 +1,37 @@
|
|
1
1
|
require 'timeout'
|
2
|
-
require 'crabfarm/
|
3
|
-
require 'crabfarm/utils/webdriver'
|
2
|
+
require 'crabfarm/live/viewer'
|
4
3
|
require 'crabfarm/support/webdriver_factory'
|
5
4
|
require 'crabfarm/crabtrap_runner'
|
6
5
|
|
7
6
|
module Crabfarm
|
8
7
|
module Live
|
9
8
|
class Manager
|
9
|
+
extend Forwardable
|
10
10
|
|
11
|
-
|
11
|
+
attr_reader :primary_driver, :browser_adapter, :proxy_port
|
12
12
|
|
13
|
-
|
14
|
-
@port = Utils::PortDiscovery.find_available_port
|
15
|
-
@driver_name = Crabfarm.config.recorder_driver
|
16
|
-
end
|
13
|
+
def_delegators :@viewer, :show_message, :show_selector_gadget
|
17
14
|
|
18
|
-
def
|
19
|
-
|
15
|
+
def initialize
|
16
|
+
reserve_port
|
20
17
|
end
|
21
18
|
|
22
19
|
def start
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
restart_crabtrap
|
21
|
+
load_browser_adapter
|
22
|
+
load_primary_driver_and_viewer
|
23
|
+
@viewer.welcome
|
26
24
|
end
|
27
25
|
|
28
26
|
def stop
|
29
|
-
stop_crabtrap
|
30
27
|
release_primary_driver
|
28
|
+
release_viewer_driver
|
29
|
+
stop_crabtrap
|
31
30
|
end
|
32
31
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
def reset_driver_status
|
38
|
-
if Crabfarm.config.live_full_reload
|
39
|
-
# recreate driver if configured to do so
|
40
|
-
release_primary_driver
|
41
|
-
load_primary_driver
|
42
|
-
else
|
43
|
-
primary_driver.manage.delete_all_cookies
|
44
|
-
end
|
45
|
-
|
46
|
-
primary_driver.get('https://www.crabtrap.io/instructions.html')
|
32
|
+
def reset
|
33
|
+
reset_primary_driver
|
34
|
+
@viewer.reset
|
47
35
|
end
|
48
36
|
|
49
37
|
def block_requests
|
@@ -51,12 +39,25 @@ module Crabfarm
|
|
51
39
|
stop_crabtrap
|
52
40
|
return yield
|
53
41
|
ensure
|
54
|
-
|
42
|
+
restart_crabtrap nil
|
55
43
|
end
|
56
44
|
end
|
57
45
|
|
58
|
-
def
|
46
|
+
def show_file(_path)
|
47
|
+
block_requests { @viewer.show_file(_path) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def show_content(_content)
|
51
|
+
block_requests { @viewer.show_content(_content) }
|
52
|
+
end
|
53
|
+
|
54
|
+
def show_primary_contents
|
55
|
+
unless @viewer_driver.nil?
|
56
|
+
@viewer.show_content(primary_driver.to_html)
|
57
|
+
end
|
58
|
+
end
|
59
59
|
|
60
|
+
def restart_crabtrap(_memento=nil)
|
60
61
|
options = if _memento
|
61
62
|
path = Utils::Resolve.memento_path _memento
|
62
63
|
raise ConfigurationError.new "No memento found at #{path}" unless File.exists? path
|
@@ -65,103 +66,92 @@ module Crabfarm
|
|
65
66
|
{ mode: :pass }
|
66
67
|
end
|
67
68
|
|
68
|
-
options.merge!({
|
69
|
-
port: @port,
|
70
|
-
virtual: File.expand_path('./assets/live-tools', Crabfarm.root)
|
71
|
-
})
|
72
|
-
|
73
69
|
stop_crabtrap
|
74
|
-
|
75
|
-
@crabtrap.start
|
76
|
-
|
70
|
+
start_crabtrap options
|
77
71
|
end
|
78
72
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
else nil end
|
73
|
+
private
|
74
|
+
|
75
|
+
def reserve_port
|
76
|
+
@proxy_port = Utils::PortDiscovery.find_available_port
|
84
77
|
end
|
85
78
|
|
86
|
-
def
|
87
|
-
|
88
|
-
|
89
|
-
Utils::Webdriver.inject_style primary_driver, 'https://www.crabtrap.io/tools.css'
|
90
|
-
Utils::Webdriver.inject_script primary_driver, 'https://www.crabtrap.io/selectorgadget_combined.js'
|
91
|
-
Utils::Webdriver.inject_script primary_driver, 'https://www.crabtrap.io/tools.js'
|
92
|
-
Timeout::timeout(INJECTION_TM) { wait_for_injection }
|
93
|
-
end
|
79
|
+
def load_browser_adapter
|
80
|
+
@browser_adapter = Strategies.load(:browser, config.browser).new crabtrap_address
|
81
|
+
@browser_adapter.prepare_driver_services
|
94
82
|
end
|
95
83
|
|
96
|
-
def
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
_content,
|
104
|
-
_content_type.to_s
|
105
|
-
);
|
84
|
+
def load_primary_driver_and_viewer
|
85
|
+
@primary_driver = browser_adapter.build_driver :default_driver
|
86
|
+
|
87
|
+
# IDEA: improve this to allow different viewer modes
|
88
|
+
unless browser_adapter.headless?
|
89
|
+
primary_webdriver = browser_adapter.extract_webdriver @primary_driver
|
90
|
+
@viewer = Viewer.new primary_webdriver unless primary_webdriver.nil?
|
106
91
|
end
|
107
|
-
end
|
108
92
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
'window.crabfarm.showSelectorGadget();'
|
113
|
-
)
|
93
|
+
if @viewer.nil?
|
94
|
+
@viewer_driver = build_support_driver
|
95
|
+
@viewer = Viewer.new @viewer_driver
|
114
96
|
end
|
115
97
|
end
|
116
98
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
99
|
+
def build_support_driver
|
100
|
+
case config.recorder_driver
|
101
|
+
when :firefox
|
102
|
+
Crabfarm::Support::WebdriverFactory.build_firefox_driver driver_config
|
103
|
+
when :chrome
|
104
|
+
Crabfarm::Support::WebdriverFactory.build_chrome_driver driver_config
|
105
|
+
else return nil end
|
121
106
|
end
|
122
107
|
|
123
|
-
def
|
124
|
-
|
125
|
-
_driver.quit rescue nil
|
126
|
-
end
|
108
|
+
def reset_primary_driver
|
109
|
+
@browser_adapter.reset_driver @primary_driver
|
127
110
|
end
|
128
111
|
|
129
|
-
|
112
|
+
def start_crabtrap(_options)
|
113
|
+
_options = _options.merge({
|
114
|
+
port: @proxy_port,
|
115
|
+
virtual: File.expand_path('./assets/live-tools', Crabfarm.root)
|
116
|
+
})
|
130
117
|
|
131
|
-
|
132
|
-
@
|
118
|
+
@crabtrap = CrabtrapRunner.new config.crabtrap_config.merge(_options)
|
119
|
+
@crabtrap.start
|
120
|
+
end
|
121
|
+
|
122
|
+
def stop_crabtrap
|
123
|
+
unless @crabtrap.nil?
|
124
|
+
@crabtrap.kill
|
125
|
+
@crabtrap = nil
|
126
|
+
else nil end
|
133
127
|
end
|
134
128
|
|
135
129
|
def release_primary_driver
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
end
|
130
|
+
@browser_adapter.release_driver @primary_driver
|
131
|
+
@browser_adapter.cleanup_driver_services
|
132
|
+
@primary_driver = nil
|
140
133
|
end
|
141
134
|
|
142
|
-
def
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
else return nil end
|
135
|
+
def release_viewer_driver
|
136
|
+
unless @viewer_driver.nil?
|
137
|
+
@viewer_driver.quit rescue nil
|
138
|
+
@viewer_driver = nil
|
139
|
+
@viewer = nil
|
140
|
+
end
|
149
141
|
end
|
150
142
|
|
151
143
|
def driver_config
|
152
144
|
{
|
153
|
-
proxy:
|
145
|
+
proxy: crabtrap_address
|
154
146
|
}
|
155
147
|
end
|
156
148
|
|
157
|
-
def
|
158
|
-
|
149
|
+
def crabtrap_address
|
150
|
+
"127.0.0.1:#{@proxy_port}"
|
159
151
|
end
|
160
152
|
|
161
|
-
def
|
162
|
-
|
163
|
-
sleep 1.0
|
164
|
-
end
|
153
|
+
def config
|
154
|
+
Crabfarm.config
|
165
155
|
end
|
166
156
|
|
167
157
|
end
|
@@ -6,16 +6,6 @@ module Crabfarm
|
|
6
6
|
module Live
|
7
7
|
class NavigatorRunner
|
8
8
|
|
9
|
-
class Dsl
|
10
|
-
extend Forwardable
|
11
|
-
|
12
|
-
def initialize(_runner)
|
13
|
-
@runner = _runner
|
14
|
-
end
|
15
|
-
|
16
|
-
def_delegators :@runner, :use_memento, :use_params, :clear_params, :use_rspec, :navigate_to
|
17
|
-
end
|
18
|
-
|
19
9
|
def initialize(_manager, _target)
|
20
10
|
@manager = _manager
|
21
11
|
@target = _target
|
@@ -27,10 +17,6 @@ module Crabfarm
|
|
27
17
|
@dsl ||= Dsl.new self
|
28
18
|
end
|
29
19
|
|
30
|
-
def memento
|
31
|
-
if @memento.nil? then memento_for(@target) else @memento end
|
32
|
-
end
|
33
|
-
|
34
20
|
def use_memento(_memento)
|
35
21
|
@memento = _memento
|
36
22
|
@rspec = false
|
@@ -50,15 +36,6 @@ module Crabfarm
|
|
50
36
|
@rspec = true
|
51
37
|
end
|
52
38
|
|
53
|
-
def navigate_to(_navigator, _params={})
|
54
|
-
# TODO.
|
55
|
-
end
|
56
|
-
|
57
|
-
def prepare(_memento) # decorator
|
58
|
-
@manager.set_memento _memento
|
59
|
-
Context.new @manager
|
60
|
-
end
|
61
|
-
|
62
39
|
def execute
|
63
40
|
strategy = if @rspec
|
64
41
|
NavigatorRunnerRSpec.new @manager, @target
|
@@ -66,31 +43,57 @@ module Crabfarm
|
|
66
43
|
NavigatorRunnerDirect.new @manager, memento, @target, @params
|
67
44
|
end
|
68
45
|
|
69
|
-
|
70
|
-
|
71
|
-
|
46
|
+
begin
|
47
|
+
Factories::Context.with_decorator navigator_decorator do
|
48
|
+
strategy.execute
|
49
|
+
end
|
72
50
|
|
73
|
-
|
51
|
+
@manager.show_primary_contents
|
52
|
+
strategy.show_results
|
53
|
+
rescue Crabfarm::LiveInterrupted
|
54
|
+
Utils::Console.info "Execution interrupted"
|
55
|
+
end
|
74
56
|
end
|
75
57
|
|
76
58
|
private
|
77
59
|
|
60
|
+
def memento
|
61
|
+
if @memento.nil? then memento_for(@target) else @memento end
|
62
|
+
end
|
63
|
+
|
78
64
|
def memento_for(_class)
|
79
|
-
Utils::Naming.route_from_constant(_class.to_s).join
|
65
|
+
Utils::Naming.route_from_constant(_class.to_s).join File::SEPARATOR
|
66
|
+
end
|
67
|
+
|
68
|
+
def navigator_decorator
|
69
|
+
@decorator ||= InterceptContextDecorator.new @manager
|
80
70
|
end
|
81
71
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
72
|
+
class InterceptContextDecorator
|
73
|
+
|
74
|
+
def initialize(_manager)
|
75
|
+
@manager = _manager
|
76
|
+
end
|
77
|
+
|
78
|
+
def prepare(_memento)
|
79
|
+
@manager.restart_crabtrap _memento
|
80
|
+
inject_managed_context
|
81
|
+
end
|
82
|
+
|
83
|
+
def inject_managed_context
|
84
|
+
Context.new @manager
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
class Dsl
|
90
|
+
extend Forwardable
|
91
|
+
|
92
|
+
def initialize(_runner)
|
93
|
+
@runner = _runner
|
94
|
+
end
|
95
|
+
|
96
|
+
def_delegators :@runner, :use_memento, :use_params, :clear_params, :use_rspec, :navigate_to
|
94
97
|
end
|
95
98
|
|
96
99
|
end
|
@@ -5,25 +5,23 @@ module Crabfarm
|
|
5
5
|
module Live
|
6
6
|
class NavigatorRunnerRSpec
|
7
7
|
|
8
|
+
attr_reader :example
|
9
|
+
|
8
10
|
def initialize(_manager, _target)
|
9
11
|
@manager = _manager
|
10
12
|
@target = _target
|
11
13
|
end
|
12
14
|
|
13
15
|
def execute
|
14
|
-
@
|
15
|
-
|
16
|
-
end
|
16
|
+
@example = Utils::RSpecRunner.run_single_spec_for spec_for(@target), :live
|
17
|
+
bubble_standard_errors
|
17
18
|
end
|
18
19
|
|
19
20
|
def show_results
|
20
|
-
|
21
|
-
if @examples.count == 0
|
21
|
+
if example.nil?
|
22
22
|
show_empty_warning
|
23
|
-
elsif @examples.count == 1
|
24
|
-
show_example_output @examples.first
|
25
23
|
else
|
26
|
-
|
24
|
+
show_example_output
|
27
25
|
end
|
28
26
|
end
|
29
27
|
|
@@ -37,75 +35,56 @@ module Crabfarm
|
|
37
35
|
end
|
38
36
|
|
39
37
|
def show_empty_warning
|
40
|
-
@manager.
|
38
|
+
@manager.show_message(
|
41
39
|
:warning,
|
42
|
-
|
43
|
-
|
40
|
+
"No examples were found!",
|
41
|
+
"You will need to write at least one spec for #{@target.to_s}"
|
44
42
|
)
|
45
43
|
|
46
|
-
|
44
|
+
console.warning 'No examples were found!'
|
47
45
|
end
|
48
46
|
|
49
|
-
def
|
50
|
-
|
51
|
-
|
52
|
-
errored = (error > 0)
|
53
|
-
|
54
|
-
if error > 0
|
55
|
-
@manager.show_dialog(
|
47
|
+
def show_example_output
|
48
|
+
if example.exception
|
49
|
+
@manager.show_message(
|
56
50
|
:error,
|
57
51
|
'FAILED',
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
Utils::Console.error "#{total} examples, #{error} failures"
|
62
|
-
else
|
63
|
-
@manager.show_dialog(
|
64
|
-
:success,
|
65
|
-
'SUCCESS',
|
66
|
-
"All #{total} tests passed!"
|
67
|
-
)
|
68
|
-
|
69
|
-
Utils::Console.result "#{total} examples, 0 failures"
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def show_example_output(_example)
|
74
|
-
|
75
|
-
handle_standard_errors _example
|
76
|
-
|
77
|
-
if _example.exception
|
78
|
-
@manager.show_dialog(
|
79
|
-
:error,
|
80
|
-
'FAILED',
|
81
|
-
_example.exception.to_s,
|
82
|
-
_example.metadata[:result].to_json,
|
52
|
+
example.exception.to_s,
|
53
|
+
example.metadata[:result].to_json,
|
83
54
|
:json
|
84
55
|
)
|
85
56
|
|
86
|
-
|
87
|
-
|
88
|
-
|
57
|
+
console.error "Example \"#{example.full_description}\" failed (line: #{example.metadata[:line_number]})"
|
58
|
+
console.error example.exception.to_s
|
59
|
+
console.json_result example.metadata[:result]
|
89
60
|
else
|
90
|
-
@manager.
|
61
|
+
@manager.show_message(
|
91
62
|
:success,
|
92
63
|
'SUCCESS',
|
93
|
-
"\"#{
|
94
|
-
|
64
|
+
"\"#{example.full_description}\"",
|
65
|
+
example.metadata[:result].to_json,
|
95
66
|
:json
|
96
67
|
)
|
97
68
|
|
98
|
-
|
99
|
-
|
69
|
+
console.result "Example \"#{example.full_description}\" passed (line: #{example.metadata[:line_number]})"
|
70
|
+
console.json_result example.metadata[:result]
|
100
71
|
end
|
101
72
|
end
|
102
73
|
|
103
|
-
def
|
104
|
-
if
|
105
|
-
raise
|
74
|
+
def bubble_standard_errors
|
75
|
+
if example and example.exception and not example.exception.is_a? expectation_error
|
76
|
+
raise example.exception
|
106
77
|
end
|
107
78
|
end
|
108
79
|
|
80
|
+
def expectation_error
|
81
|
+
::RSpec::Expectations::ExpectationNotMetError
|
82
|
+
end
|
83
|
+
|
84
|
+
def console
|
85
|
+
Utils::Console
|
86
|
+
end
|
87
|
+
|
109
88
|
end
|
110
89
|
end
|
111
90
|
end
|