crabfarm 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|