crabfarm 0.2.5 → 0.3.0

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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/lib/crabfarm.rb +17 -18
  3. data/lib/crabfarm/adapters/browser/abstract_webdriver.rb +60 -0
  4. data/lib/crabfarm/adapters/browser/chrome.rb +24 -0
  5. data/lib/crabfarm/adapters/browser/firefox.rb +26 -0
  6. data/lib/crabfarm/adapters/browser/noop.rb +25 -0
  7. data/lib/crabfarm/adapters/browser/phantom_js.rb +59 -0
  8. data/lib/crabfarm/adapters/browser/remote_webdriver.rb +31 -0
  9. data/lib/crabfarm/adapters/driver_wrapper/capybara.rb +11 -0
  10. data/lib/crabfarm/adapters/driver_wrapper/surfer.rb +13 -0
  11. data/lib/crabfarm/adapters/{browser → driver_wrapper}/watir.rb +7 -3
  12. data/lib/crabfarm/adapters/parser/nokogiri.rb +17 -15
  13. data/lib/crabfarm/adapters/parser/pdf_reader.rb +14 -12
  14. data/lib/crabfarm/assertion/fields.rb +85 -0
  15. data/lib/crabfarm/base_navigator.rb +78 -0
  16. data/lib/crabfarm/base_reducer.rb +68 -0
  17. data/lib/crabfarm/base_struct.rb +17 -0
  18. data/lib/crabfarm/cli.rb +18 -8
  19. data/lib/crabfarm/configuration.rb +24 -51
  20. data/lib/crabfarm/context.rb +19 -43
  21. data/lib/crabfarm/crabtrap_context.rb +4 -11
  22. data/lib/crabfarm/driver_pool.rb +32 -0
  23. data/lib/crabfarm/dsl/surfer/surf_context.rb +5 -25
  24. data/lib/crabfarm/engines/async_state_manager.rb +1 -1
  25. data/lib/crabfarm/engines/sync_state_manager.rb +1 -1
  26. data/lib/crabfarm/forked_navigator.rb +31 -0
  27. data/lib/crabfarm/modes/console.rb +4 -4
  28. data/lib/crabfarm/modes/generator.rb +24 -11
  29. data/lib/crabfarm/rspec.rb +26 -24
  30. data/lib/crabfarm/strategies.rb +15 -9
  31. data/lib/crabfarm/templates/Crabfile.erb +21 -26
  32. data/lib/crabfarm/templates/Gemfile.erb +6 -0
  33. data/lib/crabfarm/templates/navigator.rb.erb +20 -0
  34. data/lib/crabfarm/templates/{state_spec.rb.erb → navigator_spec.rb.erb} +1 -1
  35. data/lib/crabfarm/templates/{parser.rb.erb → reducer.rb.erb} +4 -4
  36. data/lib/crabfarm/templates/{parser_spec.rb.erb → reducer_spec.rb.erb} +1 -1
  37. data/lib/crabfarm/templates/struct.rb.erb +12 -0
  38. data/lib/crabfarm/transition_service.rb +20 -7
  39. data/lib/crabfarm/version.rb +1 -1
  40. metadata +50 -48
  41. data/lib/crabfarm/adapters/browser/capybara.rb +0 -7
  42. data/lib/crabfarm/adapters/browser/surfer.rb +0 -9
  43. data/lib/crabfarm/adapters/output/hash.rb +0 -11
  44. data/lib/crabfarm/adapters/output/jbuilder.rb +0 -11
  45. data/lib/crabfarm/adapters/output/ostruct.rb +0 -14
  46. data/lib/crabfarm/base_parser.rb +0 -59
  47. data/lib/crabfarm/base_state.rb +0 -112
  48. data/lib/crabfarm/default_driver_factory.rb +0 -86
  49. data/lib/crabfarm/driver_bucket.rb +0 -42
  50. data/lib/crabfarm/driver_bucket_pool.rb +0 -26
  51. data/lib/crabfarm/forked_state.rb +0 -38
  52. data/lib/crabfarm/mocks/noop_driver.rb +0 -6
  53. data/lib/crabfarm/phantom_driver_factory.rb +0 -33
  54. data/lib/crabfarm/templates/state.rb.erb +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ccec565757953537736ab94a2f8a45f9abb12847
4
- data.tar.gz: 927c3fd72e63af76517b0d3e53e43a91261028d9
3
+ metadata.gz: e0b57880b14cf2f7456a2d457e9c3b9531c9ac2b
4
+ data.tar.gz: 61200983d1469d597384640d3d3457547ab486fa
5
5
  SHA512:
6
- metadata.gz: 933c56e98e7f9703756d25a379b45011292f310606886bd1d40b138e36f60a36877efb45cb730bee5208bcd364802d06ce40dcf4ac2064544124e7ac3bf59f07
7
- data.tar.gz: 2f80e480debeb2f8f39a8e44493579205269fb1f198b175b02db597c5bd531d2dfb7342214f49e2ac95eb299d05b39d9446f1bef242318bbc15367f8476f53d0
6
+ metadata.gz: 65659324efa94632a56a2da599f760ec0f79199f307efaf9399580d23344456f076987baba5631c1be7ac37ac063da41b46fd8aaf762c49911eae1439ba74d84
7
+ data.tar.gz: db9ee502e2db56b89ad0ec80dea565537cb20577b6660f27f1c3e3fbd8392da8a8ff1608b7e1c5011b7e30ddd922b2d6367bcff5630ab90fe67bc4aa7a27b766
data/lib/crabfarm.rb CHANGED
@@ -2,24 +2,21 @@ require "logger"
2
2
  require "forwardable"
3
3
  require "net/http"
4
4
  require "active_support/inflector"
5
- require "selenium-webdriver"
6
5
 
7
6
  require "crabfarm/version"
8
7
  require "crabfarm/errors"
9
8
  require "crabfarm/configuration"
10
9
  require "crabfarm/global_state"
11
- require "crabfarm/driver_bucket"
12
- require "crabfarm/driver_bucket_pool"
10
+ require "crabfarm/driver_pool"
13
11
  require "crabfarm/http_client"
14
- require "crabfarm/default_driver_factory"
15
- require "crabfarm/phantom_driver_factory"
16
12
  require "crabfarm/phantom_runner"
17
13
  require "crabfarm/state_store"
18
14
  require "crabfarm/context"
19
15
  require "crabfarm/context_factory"
20
16
  require "crabfarm/transition_service"
21
- require "crabfarm/base_state"
22
- require "crabfarm/base_parser"
17
+ require "crabfarm/base_navigator"
18
+ require "crabfarm/base_reducer"
19
+ require "crabfarm/base_struct"
23
20
  require "crabfarm/strategies"
24
21
 
25
22
  require "crabfarm/utils/port_discovery"
@@ -47,18 +44,20 @@ module Crabfarm
47
44
  end
48
45
 
49
46
  module Strategies
50
- # bundled browser dsl adapters
51
- register :browser_dsl, :surfer, 'Crabfarm::SurferBrowserDsl', 'crabfarm/adapters/browser/surfer'
52
- register :browser_dsl, :watir, 'Crabfarm::WatirBrowserDsl', 'crabfarm/adapters/browser/watir', ['watir-webdriver']
53
- register :browser_dsl, :capybara, 'Crabfarm::CapybaraBrowserDsl', 'crabfarm/adapters/browser/capybara', ['capybara']
47
+ # bundled browser adapters
48
+ register :browser, :phantomjs, 'Crabfarm::Adapters::Browser::PhantomJs', dependencies: ['selenium-webdriver']
49
+ register :browser, :firefox, 'Crabfarm::Adapters::Browser::Firefox', dependencies: ['selenium-webdriver']
50
+ register :browser, :chrome, 'Crabfarm::Adapters::Browser::Chrome', dependencies: ['selenium-webdriver']
51
+ register :browser, :remote, 'Crabfarm::Adapters::Browser::RemoteWebdriver', dependencies: ['selenium-webdriver']
52
+ register :browser, :noop, 'Crabfarm::Adapters::Browser::Noop'
53
+
54
+ # bundled webdriver dsl adapters
55
+ register :webdriver_dsl, :surfer, 'Crabfarm::Adapters::DriverWrapper::Surfer'
56
+ register :webdriver_dsl, :watir, 'Crabfarm::Adapters::DriverWrapper::Watir', dependencies: ['watir-webdriver']
57
+ register :webdriver_dsl, :capybara, 'Crabfarm::Adapters::DriverWrapper::Capybara', dependencies: ['capybara']
54
58
 
55
59
  # bundled parsers dsl adapters
56
- register :parser_engine, :nokogiri, 'Crabfarm::NokogiriAdapter', 'crabfarm/adapters/parser/nokogiri'
57
- register :parser_engine, :pdf_reader, 'Crabfarm::PdfReaderAdapter', 'crabfarm/adapters/parser/pdf_reader', ['pdf-reader']
58
-
59
- # bundled state output builders
60
- register :output_builder, :hash, 'Crabfarm::HashOutputBuilder', 'crabfarm/adapters/output/hash'
61
- register :output_builder, :ostruct, 'Crabfarm::OStructOutputBuilder', 'crabfarm/adapters/output/ostruct'
62
- register :output_builder, :jbuilder, 'Crabfarm::JbuilderOutputBuilder', 'crabfarm/adapters/output/jbuilder', ['jbuilder']
60
+ register :parser, :nokogiri, 'Crabfarm::Adapters::Parser::Nokogiri', dependencies: ['nokogiri']
61
+ register :parser, :pdf_reader, 'Crabfarm::Adapters::Parser::PdfReader', dependencies: ['pdf-reader']
63
62
  end
64
63
  end
@@ -0,0 +1,60 @@
1
+ module Crabfarm
2
+ module Adapters
3
+ module Browser
4
+ class AbstractWebdriver
5
+
6
+ attr_accessor :config
7
+
8
+ def initialize(_proxy=nil)
9
+ @config = load_driver_config
10
+ @config[:proxy] = _proxy
11
+ end
12
+
13
+ def prepare_driver_services
14
+ # Nothing by default
15
+ end
16
+
17
+ def cleanup_driver_services
18
+ # Nothing by default
19
+ end
20
+
21
+ def build_driver(_session_id)
22
+
23
+ # load driver and configure general selenium settings
24
+ driver = build_webdriver_instance
25
+ driver.manage.window.resize_to(config[:window_width], config[:window_height]) rescue nil
26
+
27
+ return wrap_driver driver
28
+ end
29
+
30
+ def release_driver(_driver)
31
+ @driver.quit rescue nil
32
+ end
33
+
34
+ private
35
+
36
+ def wrap_driver _driver
37
+ if config[:dsl].present?
38
+ Strategies.load(:webdriver_dsl, config[:dsl]).wrap _driver
39
+ else _driver end
40
+ end
41
+
42
+ def build_webdriver_instance
43
+ raise NotImplementedError.new
44
+ end
45
+
46
+ def load_driver_config
47
+ {
48
+ capabilities: Crabfarm.config.webdriver_capabilities,
49
+ remote_host: Crabfarm.config.webdriver_remote_host,
50
+ remote_timeout: Crabfarm.config.webdriver_remote_timeout,
51
+ window_width: Crabfarm.config.webdriver_window_width,
52
+ window_height: Crabfarm.config.webdriver_window_height,
53
+ dsl: Crabfarm.config.webdriver_dsl
54
+ }
55
+ end
56
+
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,24 @@
1
+ require "crabfarm/adapters/browser/abstract_webdriver"
2
+
3
+ module Crabfarm
4
+ module Adapters
5
+ module Browser
6
+ class Chrome < AbstractWebdriver
7
+
8
+ private
9
+
10
+ def build_webdriver_instance
11
+ switches = []
12
+
13
+ if config[:proxy].present?
14
+ switches << "--proxy-server=#{config[:proxy]}"
15
+ switches << "--ignore-certificate-errors"
16
+ end
17
+
18
+ Selenium::WebDriver.for :chrome, :switches => switches
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ require "crabfarm/adapters/browser/abstract_webdriver"
2
+
3
+ module Crabfarm
4
+ module Adapters
5
+ module Browser
6
+ class Firefox < AbstractWebdriver
7
+
8
+ private
9
+
10
+ def build_webdriver_instance
11
+ profile = Selenium::WebDriver::Firefox::Profile.new
12
+
13
+ if config.key? :proxy
14
+ profile.proxy = Selenium::WebDriver::Proxy.new({
15
+ :http => config[:proxy],
16
+ :ssl => config[:proxy]
17
+ })
18
+ end
19
+
20
+ Selenium::WebDriver.for :firefox, :profile => profile
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,25 @@
1
+ module Crabfarm
2
+ module Adapters
3
+ module Browser
4
+ class Noop
5
+
6
+ def initialize(_proxy=nil)
7
+ end
8
+
9
+ def prepare_driver_services
10
+ end
11
+
12
+ def cleanup_driver_services
13
+ end
14
+
15
+ def build_driver(_session_id)
16
+ _session_id || :noop
17
+ end
18
+
19
+ def release_driver(_driver)
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,59 @@
1
+ require "crabfarm/adapters/browser/abstract_webdriver"
2
+ require "crabfarm/phantom_runner"
3
+
4
+ module Crabfarm
5
+ module Adapters
6
+ module Browser
7
+ class PhantomJs < AbstractWebdriver
8
+
9
+ def prepare_driver_services
10
+ @phantom = load_and_start_phantom if @phantom.nil?
11
+ end
12
+
13
+ def cleanup_driver_services
14
+ @phantom.stop unless @phantom.nil?
15
+ @phantom = nil
16
+ end
17
+
18
+ private
19
+
20
+ def build_webdriver_instance
21
+ client = Selenium::WebDriver::Remote::Http::Default.new
22
+ client.timeout = config[:remote_timeout]
23
+
24
+ driver = Selenium::WebDriver.for :remote, {
25
+ :url => phantom_url,
26
+ :http_client => client,
27
+ :desired_capabilities => config[:capabilities] || Selenium::WebDriver::Remote::Capabilities.firefox
28
+ }
29
+
30
+ # TODO: not sure if this is necessary...
31
+ # driver.send(:bridge).setWindowSize(config[:window_width], config[:window_height])
32
+
33
+ return driver
34
+ end
35
+
36
+ def load_and_start_phantom
37
+ new_phantom = PhantomRunner.new phantom_config
38
+ new_phantom.start
39
+ return new_phantom
40
+ end
41
+
42
+ def phantom_config
43
+ {
44
+ load_images: Crabfarm.config.phantom_load_images,
45
+ ssl: Crabfarm.config.phantom_ssl,
46
+ bin_path: Crabfarm.config.phantom_bin_path,
47
+ proxy: config[:proxy],
48
+ port: Utils::PortDiscovery.find_available_port
49
+ }
50
+ end
51
+
52
+ def phantom_url
53
+ "http://localhost:#{@phantom.port}"
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,31 @@
1
+ require "crabfarm/adapters/browser/abstract_webdriver"
2
+
3
+ module Crabfarm
4
+ module Adapters
5
+ module Browser
6
+ class RemoteWebdriver < AbstractWebdriver
7
+
8
+ private
9
+
10
+ def build_webdriver_instance
11
+ client = Selenium::WebDriver::Remote::Http::Default.new
12
+ client.timeout = config[:remote_timeout]
13
+
14
+ if config.has_key? :proxy
15
+ client.proxy = Selenium::WebDriver::Proxy.new({
16
+ :http => config[:proxy],
17
+ :ssl => config[:proxy]
18
+ })
19
+ end
20
+
21
+ Selenium::WebDriver.for(:remote, {
22
+ :url => config[:remote_host],
23
+ :http_client => client,
24
+ :desired_capabilities => config[:capabilities] || Selenium::WebDriver::Remote::Capabilities.firefox
25
+ })
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,11 @@
1
+ module Crabfarm
2
+ module Adapters
3
+ module DriverWrapper
4
+ class Capybara
5
+ def self.wrap(_driver)
6
+ raise NotImplementedError.new "Capybara adapter is not available yet"
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ require 'crabfarm/dsl/surfer'
2
+
3
+ module Crabfarm
4
+ module Adapters
5
+ module DriverWrapper
6
+ class Surfer
7
+ def self.wrap(_driver)
8
+ Crabfarm::Dsl::Surfer::SurfContext.new _driver
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -17,9 +17,13 @@ class Watir::ElementCollection
17
17
  end
18
18
 
19
19
  module Crabfarm
20
- class WatirBrowserDsl
21
- def self.wrap(_bucket)
22
- Watir::Browser.new _bucket.original
20
+ module Adapters
21
+ module DriverWrapper
22
+ class Watir
23
+ def self.wrap(_driver)
24
+ ::Watir::Browser.new _driver
25
+ end
26
+ end
23
27
  end
24
28
  end
25
29
  end
@@ -1,21 +1,23 @@
1
- require 'nokogiri'
2
-
3
1
  module Crabfarm
4
- class NokogiriAdapter
5
- def self.format
6
- 'html'
7
- end
2
+ module Adapters
3
+ module Parser
4
+ class Nokogiri
5
+ def self.format
6
+ 'html'
7
+ end
8
8
 
9
- def self.parse(_raw)
10
- Nokogiri::HTML _raw
11
- end
9
+ def self.parse(_raw)
10
+ ::Nokogiri::HTML _raw
11
+ end
12
12
 
13
- def self.preprocess_parsing_target(_target)
14
- if _target.respond_to? :to_html
15
- _target.to_html
16
- else
17
- _target
13
+ def self.preprocess_parsing_target(_target)
14
+ if _target.respond_to? :to_html
15
+ _target.to_html
16
+ else
17
+ _target
18
+ end
19
+ end
18
20
  end
19
21
  end
20
22
  end
21
- end
23
+ end
@@ -1,17 +1,19 @@
1
- require "pdf-reader"
2
-
3
1
  module Crabfarm
4
- class PdfReaderAdapter
5
- def self.format
6
- 'pdf'
7
- end
2
+ module Adapters
3
+ module Parser
4
+ class PdfReader
5
+ def self.format
6
+ 'pdf'
7
+ end
8
8
 
9
- def self.parse(_raw)
10
- PDF::Reader.new StringIO.new _raw
11
- end
9
+ def self.parse(_raw)
10
+ PDF::Reader.new StringIO.new _raw
11
+ end
12
12
 
13
- def self.preprocess_parsing_target(_target)
14
- _target
13
+ def self.preprocess_parsing_target(_target)
14
+ _target
15
+ end
16
+ end
15
17
  end
16
18
  end
17
- end
19
+ end
@@ -0,0 +1,85 @@
1
+ require "active_support/core_ext/object/duplicable"
2
+ require 'crabfarm/assertion/context'
3
+
4
+ module Crabfarm
5
+ module Assertion
6
+ module Fields
7
+ include Context
8
+
9
+ module ClassMethods
10
+
11
+ def has_field(_name, _options={})
12
+ name = _name.to_sym
13
+
14
+ fields << name
15
+ field_defaults[name] = _options.delete :field_default
16
+
17
+ assertion = _options.delete :field_assertion
18
+ if assertion
19
+ define_method("#{name}=") { |v| field_hash[name] = assert(v).send(assertion, _options) }
20
+ elsif not _options[:field_readonly]
21
+ define_method("#{name}=") { |v| field_hash[name] = v }
22
+ end
23
+
24
+ define_method(name) { field_hash[name] }
25
+ end
26
+
27
+ def has_asserted_field(_name, _assertion, _options={})
28
+ has_field(_name, _options.merge(field_assertion: _assertion))
29
+ end
30
+
31
+ def has_array(_name)
32
+ has_field(_name, field_default: [], field_readonly: true)
33
+ end
34
+
35
+ def has_integer(_name, _options={})
36
+ has_asserted_field _name, :is_integer, _options
37
+ end
38
+
39
+ def has_float(_name, _options={})
40
+ has_asserted_field _name, :is_float, _options
41
+ end
42
+
43
+ def has_string(_name, _options={})
44
+ has_asserted_field _name, :is_string, _options
45
+ end
46
+
47
+ def has_word(_name, _options={})
48
+ has_asserted_field _name, :is_word, _options
49
+ end
50
+
51
+ def has_boolean(_name, _options={})
52
+ has_asserted_field _name, :is_boolean, _options
53
+ end
54
+
55
+ def fields
56
+ @fields ||= []
57
+ end
58
+
59
+ def field_defaults
60
+ @field_defaults ||= {}
61
+ end
62
+
63
+ end
64
+
65
+ def self.included(klass)
66
+ klass.extend ClassMethods
67
+ end
68
+
69
+ def reset_fields
70
+ klass = self.class
71
+
72
+ @field_hash = {}
73
+ klass.fields.each do |field|
74
+ value = klass.field_defaults[field]
75
+ @field_hash[field] = value.duplicable? ? value.clone : value
76
+ end
77
+ end
78
+
79
+ def field_hash
80
+ @field_hash
81
+ end
82
+
83
+ end
84
+ end
85
+ end