howitzer 1.1.1 → 2.0.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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +32 -0
- data/.travis.yml +1 -4
- data/.yardopts +1 -2
- data/CHANGELOG.md +28 -1
- data/Gemfile +6 -0
- data/LICENSE +1 -1
- data/README.md +55 -85
- data/Rakefile +7 -7
- data/bin/howitzer +56 -31
- data/features/cli_new.feature +162 -79
- data/features/cli_update.feature +114 -21
- data/features/step_definitions/common_steps.rb +29 -9
- data/features/support/env.rb +1 -1
- data/features/support/transformers.rb +2 -2
- data/generators/base_generator.rb +121 -49
- data/generators/config/config_generator.rb +8 -5
- data/generators/config/templates/boot.rb +14 -0
- data/generators/config/templates/capybara.rb +156 -0
- data/generators/config/templates/custom.yml +2 -3
- data/generators/config/templates/default.yml +50 -82
- data/generators/cucumber/cucumber_generator.rb +9 -9
- data/generators/cucumber/templates/common_steps.rb +4 -4
- data/generators/cucumber/templates/cucumber.rake +63 -54
- data/generators/cucumber/templates/env.rb +24 -23
- data/generators/cucumber/templates/transformers.rb +23 -15
- data/generators/emails/emails_generator.rb +4 -2
- data/generators/emails/templates/example_email.rb +4 -4
- data/generators/prerequisites/prerequisites_generator.rb +24 -0
- data/generators/prerequisites/templates/base.rb +22 -0
- data/generators/prerequisites/templates/factory_girl.rb +30 -0
- data/generators/prerequisites/templates/user.rb +7 -0
- data/generators/prerequisites/templates/users.rb +12 -0
- data/generators/root/root_generator.rb +11 -7
- data/generators/root/templates/.rubocop.yml +32 -0
- data/generators/root/templates/Gemfile.erb +27 -0
- data/generators/root/templates/Rakefile +6 -8
- data/generators/rspec/rspec_generator.rb +7 -7
- data/generators/rspec/templates/example_spec.rb +1 -1
- data/generators/rspec/templates/rspec.rake +48 -29
- data/generators/rspec/templates/spec_helper.rb +33 -32
- data/generators/tasks/tasks_generator.rb +4 -2
- data/generators/tasks/templates/common.rake +1 -16
- data/generators/turnip/templates/.rspec +1 -0
- data/generators/turnip/templates/common_steps.rb +25 -0
- data/generators/turnip/templates/example.feature +8 -0
- data/generators/turnip/templates/spec_helper.rb +56 -0
- data/generators/turnip/templates/turnip.rake +61 -0
- data/generators/turnip/templates/turnip_helper.rb +6 -0
- data/generators/turnip/turnip_generator.rb +26 -0
- data/generators/web/templates/example_page.rb +15 -0
- data/generators/web/templates/menu_section.rb +13 -0
- data/generators/web/web_generator.rb +22 -0
- data/howitzer.gemspec +14 -21
- data/lib/howitzer.rb +47 -7
- data/lib/howitzer/cache.rb +70 -0
- data/lib/howitzer/capybara_helpers.rb +194 -0
- data/lib/howitzer/email.rb +96 -104
- data/lib/howitzer/exceptions.rb +10 -6
- data/lib/howitzer/log.rb +120 -0
- data/lib/howitzer/mail_adapters.rb +7 -0
- data/lib/howitzer/mail_adapters/abstract.rb +84 -0
- data/lib/howitzer/mail_adapters/mailgun.rb +115 -0
- data/lib/howitzer/mailgun_api.rb +9 -0
- data/lib/howitzer/mailgun_api/client.rb +79 -0
- data/lib/howitzer/mailgun_api/connector.rb +37 -0
- data/lib/howitzer/mailgun_api/response.rb +28 -0
- data/lib/howitzer/tasks/framework.rake +2 -2
- data/lib/howitzer/utils.rb +7 -1
- data/lib/howitzer/utils/string_extensions.rb +66 -0
- data/lib/howitzer/version.rb +2 -1
- data/lib/howitzer/web.rb +11 -0
- data/lib/howitzer/web/base_section.rb +27 -0
- data/lib/howitzer/web/blank_page.rb +12 -0
- data/lib/howitzer/web/capybara_methods_proxy.rb +29 -0
- data/lib/howitzer/web/element_dsl.rb +109 -0
- data/lib/howitzer/web/iframe_dsl.rb +93 -0
- data/lib/howitzer/web/page.rb +173 -0
- data/lib/howitzer/web/page_dsl.rb +64 -0
- data/lib/howitzer/web/page_validator.rb +118 -0
- data/lib/howitzer/web/section.rb +27 -0
- data/lib/howitzer/web/section_dsl.rb +154 -0
- data/spec/config/custom.yml +10 -1
- data/spec/spec_helper.rb +37 -19
- data/spec/support/generator_helper.rb +12 -11
- data/spec/support/logger_helper.rb +10 -9
- data/spec/support/mailgun_unit_client.rb +52 -44
- data/spec/support/shared_examples/capybara_context_holder.rb +33 -0
- data/spec/support/shared_examples/capybara_methods_proxy.rb +94 -0
- data/spec/support/shared_examples/dynamic_section_methods.rb +35 -0
- data/spec/support/shared_examples/element_dsl.rb +119 -0
- data/spec/unit/generators/base_generator_spec.rb +64 -33
- data/spec/unit/generators/config_generator_spec.rb +11 -7
- data/spec/unit/generators/cucumber_generator_spec.rb +26 -17
- data/spec/unit/generators/emails_generator_spec.rb +10 -6
- data/spec/unit/generators/prerequisites_generator_spec.rb +53 -0
- data/spec/unit/generators/root_generator_spec.rb +50 -13
- data/spec/unit/generators/rspec_generator_spec.rb +9 -9
- data/spec/unit/generators/tasks_generator_spec.rb +6 -6
- data/spec/unit/generators/turnip_generator_spec.rb +52 -0
- data/spec/unit/generators/web_generator_spec.rb +52 -0
- data/spec/unit/lib/cache_spec.rb +85 -0
- data/spec/unit/lib/capybara_helpers_spec.rb +696 -0
- data/spec/unit/lib/email_spec.rb +104 -91
- data/spec/unit/lib/howitzer.rb +31 -0
- data/spec/unit/lib/init_spec.rb +0 -1
- data/spec/unit/lib/log_spec.rb +122 -0
- data/spec/unit/lib/mail_adapters/abstract_spec.rb +62 -0
- data/spec/unit/lib/mail_adapters/mailgun_spec.rb +163 -0
- data/spec/unit/lib/mailgun_api/client_spec.rb +58 -0
- data/spec/unit/lib/mailgun_api/connector_spec.rb +54 -0
- data/spec/unit/lib/mailgun_api/response_spec.rb +28 -0
- data/spec/unit/lib/utils/string_extensions_spec.rb +77 -0
- data/spec/unit/lib/web/base_section_spec.rb +41 -0
- data/spec/unit/lib/web/element_dsl_spec.rb +17 -0
- data/spec/unit/lib/web/iframe_dsl_spec.rb +99 -0
- data/spec/unit/lib/web/page_dsl_spec.rb +52 -0
- data/spec/unit/lib/web/page_spec.rb +304 -0
- data/spec/unit/lib/web/page_validator_spec.rb +218 -0
- data/spec/unit/lib/web/section_dsl_spec.rb +165 -0
- data/spec/unit/lib/web/section_spec.rb +61 -0
- data/spec/unit/version_spec.rb +1 -1
- metadata +116 -203
- data/GETTING_STARTED.md +0 -774
- data/generators/cucumber/templates/cucumber.yml +0 -10
- data/generators/pages/pages_generator.rb +0 -21
- data/generators/pages/templates/example_menu.rb +0 -15
- data/generators/pages/templates/example_page.rb +0 -15
- data/generators/root/templates/Gemfile +0 -7
- data/generators/root/templates/boot.rb +0 -10
- data/lib/howitzer/blank_page.rb +0 -6
- data/lib/howitzer/capybara/dsl_ex.rb +0 -15
- data/lib/howitzer/capybara/settings.rb +0 -343
- data/lib/howitzer/helpers.rb +0 -230
- data/lib/howitzer/init.rb +0 -1
- data/lib/howitzer/mailgun/client.rb +0 -65
- data/lib/howitzer/mailgun/connector.rb +0 -34
- data/lib/howitzer/mailgun/response.rb +0 -28
- data/lib/howitzer/patches/rawler_patched.rb +0 -86
- data/lib/howitzer/settings.rb +0 -27
- data/lib/howitzer/utils/data_generator/data_storage.rb +0 -88
- data/lib/howitzer/utils/data_generator/gen.rb +0 -135
- data/lib/howitzer/utils/locator_store.rb +0 -217
- data/lib/howitzer/utils/log.rb +0 -139
- data/lib/howitzer/utils/page_validator.rb +0 -133
- data/lib/howitzer/vendor/firebug-1.12.1-fx.xpi +0 -0
- data/lib/howitzer/vendor/firepath-0.9.7-fx.xpi +0 -0
- data/lib/howitzer/web_page.rb +0 -253
- data/spec/active_resource.rb +0 -0
- data/spec/config/default.yml +0 -26
- data/spec/support/boot_helper.rb +0 -15
- data/spec/unit/generators/pages_generator_spec.rb +0 -33
- data/spec/unit/lib/capybara/dsl_ex_spec.rb +0 -60
- data/spec/unit/lib/capybara/settings_spec.rb +0 -441
- data/spec/unit/lib/helpers_spec.rb +0 -1129
- data/spec/unit/lib/mailgun/client_spec.rb +0 -36
- data/spec/unit/lib/mailgun/connector_spec.rb +0 -70
- data/spec/unit/lib/mailgun/response_spec.rb +0 -28
- data/spec/unit/lib/settings_spec.rb +0 -17
- data/spec/unit/lib/utils/data_generator/data_storage_spec.rb +0 -80
- data/spec/unit/lib/utils/data_generator/gen_spec.rb +0 -90
- data/spec/unit/lib/utils/locator_store_spec.rb +0 -157
- data/spec/unit/lib/utils/log_spec.rb +0 -107
- data/spec/unit/lib/utils/page_validator_spec.rb +0 -265
- data/spec/unit/lib/web_page_spec.rb +0 -346
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module Howitzer
|
|
2
|
+
module Web
|
|
3
|
+
# This module combines page dsl methods
|
|
4
|
+
module PageDsl
|
|
5
|
+
# This class is for private usage only
|
|
6
|
+
class PageScope
|
|
7
|
+
include RSpec::Matchers
|
|
8
|
+
|
|
9
|
+
def initialize(page_klass, &block)
|
|
10
|
+
self.page_klass = page_klass
|
|
11
|
+
instance_eval(&block)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Makes current page as a subject for Rspec expectations
|
|
15
|
+
# @example
|
|
16
|
+
# HomePage.on { expect(HomePage.given).to have_menu_section } # Bad
|
|
17
|
+
# HomePage.on { is_expected.to have_menu_section } # Good
|
|
18
|
+
|
|
19
|
+
def is_expected # rubocop:disable Style/PredicateName
|
|
20
|
+
expect(page_klass.given)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Proxies all methods to page instance except methods with be_ and have_ prefixes
|
|
24
|
+
|
|
25
|
+
def method_missing(name, *args, &block)
|
|
26
|
+
return super if name =~ /\A(?:be|have)_/
|
|
27
|
+
page_klass.given.send(name, *args, &block)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Makes proxied methods to be evaludated and returned as a proc
|
|
31
|
+
# @see #method_missing
|
|
32
|
+
|
|
33
|
+
def respond_to_missing?(name, include_private = false)
|
|
34
|
+
!(name =~ /\A(?:be|have)_/) || super
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
attr_accessor :page_klass
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.included(base)
|
|
43
|
+
base.extend(ClassMethods)
|
|
44
|
+
end
|
|
45
|
+
# This module holds page dsl class methods
|
|
46
|
+
module ClassMethods
|
|
47
|
+
# Allows to execute page methods in context of the page.
|
|
48
|
+
# @note It additionally checks the page is really displayed
|
|
49
|
+
# on each method call, otherwise it raises error
|
|
50
|
+
# @example
|
|
51
|
+
# LoginPage.open
|
|
52
|
+
# LoginPage.on do
|
|
53
|
+
# fill_form(name: 'John', email: 'jkarpensky@gmail.com')
|
|
54
|
+
# submit_form
|
|
55
|
+
# end
|
|
56
|
+
|
|
57
|
+
def on(&block)
|
|
58
|
+
PageScope.new(self, &block)
|
|
59
|
+
nil
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
require 'howitzer/exceptions'
|
|
2
|
+
|
|
3
|
+
module Howitzer
|
|
4
|
+
module Web
|
|
5
|
+
# This module combines page validation methods
|
|
6
|
+
module PageValidator
|
|
7
|
+
@validations = {}
|
|
8
|
+
|
|
9
|
+
def self.included(base) #:nodoc:
|
|
10
|
+
base.extend(ClassMethods)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @return [Hash] defined validations for all page classes
|
|
14
|
+
|
|
15
|
+
def self.validations
|
|
16
|
+
@validations ||= {}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Returns page list
|
|
20
|
+
# @return [Array]
|
|
21
|
+
|
|
22
|
+
def self.pages
|
|
23
|
+
@pages ||= []
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Checks if any validations are defined for the page
|
|
27
|
+
# @raise [Howitzer::NoValidationError] if no one validation is defined for the page
|
|
28
|
+
|
|
29
|
+
def check_validations_are_defined!
|
|
30
|
+
return if self.class.validations.present?
|
|
31
|
+
|
|
32
|
+
raise Howitzer::NoValidationError, "No any page validation was found for '#{self.class.name}' page"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# This module holds page validation class methods
|
|
36
|
+
module ClassMethods
|
|
37
|
+
# Adds validation to validation list for current page
|
|
38
|
+
# @param name [Symbol, String] a validation type. Possible values [:url, :element_presence, :title]
|
|
39
|
+
# @param value [Symbol, String, Regexp]
|
|
40
|
+
# For :url and :title validation types must be <b>Regexp</b>
|
|
41
|
+
# For :element_presence must be one of element names described for page
|
|
42
|
+
# @param additional_value [Object, nil] any value required to pass for a labmda selector
|
|
43
|
+
# @raise [Howitzer::UnknownValidationError] if unknown validation type
|
|
44
|
+
# @example
|
|
45
|
+
# class ArticleListPage < Howitzer::Web::Page
|
|
46
|
+
# validate :title, /\ADemo web application - Listing Articles\z/
|
|
47
|
+
# end
|
|
48
|
+
# @example
|
|
49
|
+
# class ArticlePage < Howitzer::Web::Page
|
|
50
|
+
# validate :url, %r{\/articles\/\d+\/?\z}
|
|
51
|
+
# end
|
|
52
|
+
# @example
|
|
53
|
+
# class HomePage < Howitzer::Web::Page
|
|
54
|
+
# validate :element_presence, :menu_item, 'Logout'
|
|
55
|
+
# element :menu_item, :xpath, ->(name) { ".//a[.='#{name}']" }
|
|
56
|
+
# end
|
|
57
|
+
|
|
58
|
+
def validate(name, value, additional_value = nil)
|
|
59
|
+
validate_by_type(name, value, additional_value)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Check whether current page is opened or no
|
|
63
|
+
# @return [Boolean]
|
|
64
|
+
# @raise [Howitzer::NoValidationError] if no one validation is defined for the page
|
|
65
|
+
|
|
66
|
+
def opened?
|
|
67
|
+
if validations.present?
|
|
68
|
+
return !validations.any? { |(_, validation)| !validation.call(self) }
|
|
69
|
+
end
|
|
70
|
+
raise Howitzer::NoValidationError, "No any page validation was found for '#{name}' page"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Finds all matched pages which satisfy of defined validations on current page
|
|
74
|
+
# @return [Array] page name list
|
|
75
|
+
|
|
76
|
+
def matched_pages
|
|
77
|
+
PageValidator.pages.select(&:opened?)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# @return [Hash] defined validations for current page class
|
|
81
|
+
|
|
82
|
+
def validations
|
|
83
|
+
PageValidator.validations[name] ||= {}
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
def validate_element(element_name, value = nil)
|
|
89
|
+
validations[:element_presence] =
|
|
90
|
+
->(web_page) { web_page.public_send(*["has_#{element_name}_element?", value].compact) }
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def validate_by_url(pattern)
|
|
94
|
+
validations[:url] =
|
|
95
|
+
-> (web_page) { pattern === web_page.instance.current_url }
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def validate_by_title(pattern)
|
|
99
|
+
validations[:title] =
|
|
100
|
+
-> (web_page) { pattern === web_page.instance.title }
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def validate_by_type(type, value, additional_value)
|
|
104
|
+
case type.to_s.to_sym
|
|
105
|
+
when :url
|
|
106
|
+
validate_by_url(value)
|
|
107
|
+
when :element_presence
|
|
108
|
+
validate_element(value, additional_value)
|
|
109
|
+
when :title
|
|
110
|
+
validate_by_title(value)
|
|
111
|
+
else
|
|
112
|
+
raise Howitzer::UnknownValidationError, "unknown '#{type}' validation type"
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'howitzer/web/base_section'
|
|
2
|
+
|
|
3
|
+
module Howitzer
|
|
4
|
+
module Web
|
|
5
|
+
# This class uses for named sections which possible to reuse in different pages
|
|
6
|
+
class Section < BaseSection
|
|
7
|
+
class << self
|
|
8
|
+
protected
|
|
9
|
+
|
|
10
|
+
# DSL method which specifies section container selector represented by HTML element.
|
|
11
|
+
# Any elements described in sections will start in this HTML element.
|
|
12
|
+
# @param args [Array] original Capybara arguments. For details, see `Capybara::Node::Finders#all.
|
|
13
|
+
# @raise [ArgumentError] if no arguments were passed
|
|
14
|
+
# @example
|
|
15
|
+
# class MenuSection < Howitzer::Web::Section
|
|
16
|
+
# me :xpath, ".//*[@id='panel']"
|
|
17
|
+
# end
|
|
18
|
+
# @!visibility public
|
|
19
|
+
|
|
20
|
+
def me(*args)
|
|
21
|
+
raise ArgumentError, 'Finder arguments are missing' if args.blank?
|
|
22
|
+
@default_finder_args = args
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
module Howitzer
|
|
2
|
+
module Web
|
|
3
|
+
# This module combines section dsl methods
|
|
4
|
+
module SectionDsl
|
|
5
|
+
def self.included(base) #:nodoc:
|
|
6
|
+
base.extend(ClassMethods)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Returns capybara context. For example, capybara session, parent element, etc.
|
|
10
|
+
# @abstract should be defined in parent context
|
|
11
|
+
|
|
12
|
+
def capybara_context
|
|
13
|
+
raise NotImplementedError, "Please define 'capybara_context' method for class holder"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# This module holds section dsl class methods
|
|
17
|
+
module ClassMethods
|
|
18
|
+
# This class is for private usage only
|
|
19
|
+
class SectionScope
|
|
20
|
+
attr_accessor :section_class
|
|
21
|
+
|
|
22
|
+
# Instantiates an anynomous or named section and executes block code in the section scope
|
|
23
|
+
|
|
24
|
+
def initialize(name, *args, &block)
|
|
25
|
+
@args = args
|
|
26
|
+
self.section_class =
|
|
27
|
+
if block
|
|
28
|
+
Class.new(Howitzer::Web::BaseSection)
|
|
29
|
+
else
|
|
30
|
+
"#{name}_section".classify.constantize
|
|
31
|
+
end
|
|
32
|
+
instance_eval(&block) if block_given?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# # Defines an element on the section
|
|
36
|
+
# # @see Howitzer::PageDsl::ClassMethods#element
|
|
37
|
+
|
|
38
|
+
def element(*args)
|
|
39
|
+
section_class.send(:element, *args)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Delegates a section describing to the section class
|
|
43
|
+
|
|
44
|
+
def section(name, *args, &block)
|
|
45
|
+
section_class.send(:section, name, *args, &block)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Returns a selector for the section.
|
|
49
|
+
# @note If anonymous section uses, then inline selector should be specified.
|
|
50
|
+
# Otherwise arguments should be defined with `.me` dsl method in named section
|
|
51
|
+
# @return [Array]
|
|
52
|
+
# @raise [ArgumentError] when finder arguments were not specified
|
|
53
|
+
|
|
54
|
+
def finder_args
|
|
55
|
+
@finder_args ||= begin
|
|
56
|
+
return @args if @args.present?
|
|
57
|
+
section_class.default_finder_args || raise(ArgumentError, 'Missing finder arguments')
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
protected
|
|
63
|
+
|
|
64
|
+
# DSL method which defines named or anonymous section within a page or a section
|
|
65
|
+
# @note This method generates following dynamic methods:
|
|
66
|
+
#
|
|
67
|
+
# <b><em>section_name</em>_section</b> - equals capybara #find(...) method
|
|
68
|
+
#
|
|
69
|
+
# <b><em>section_name</em>_sections</b> - equals capybara #all(...) method
|
|
70
|
+
#
|
|
71
|
+
# <b><em>section_name</em>_sections.first</b> - equals capybara #first(...) method
|
|
72
|
+
#
|
|
73
|
+
# <b>has_<em>section_name</em>_section?</b> - equals capybara #has_selector(...) method
|
|
74
|
+
#
|
|
75
|
+
# <b>has_no_<em>section_name</em>_section?</b> - equals capybara #has_no_selector(...) method
|
|
76
|
+
# @note It is possible to use nested anonymous sections
|
|
77
|
+
# @param name [Symbol, String] an unique section name
|
|
78
|
+
# @param args [Array] original Capybara arguments. For details, see `Capybara::Node::Finders#all.
|
|
79
|
+
# (In most cases should be ommited for named sections because the section selector is specified
|
|
80
|
+
# with `#me` method. But must be specified for anonymous sections)
|
|
81
|
+
# @param block [Proc] this block can contain nested sections and elements
|
|
82
|
+
# @example Named section
|
|
83
|
+
# class MenuSection < Howitzer::Web::Section
|
|
84
|
+
# me :xpath, ".//*[@id='panel']"
|
|
85
|
+
# end
|
|
86
|
+
# class HomePage < Howitzer::Web::Page
|
|
87
|
+
# section :menu
|
|
88
|
+
# end
|
|
89
|
+
# HomePage.on { is_expected.to have_menu_section }
|
|
90
|
+
# @example Anonymous section
|
|
91
|
+
# class HomePage < Howitzer::Web::Page
|
|
92
|
+
# section :info_panel, '#panel' do
|
|
93
|
+
# element :edit_button, '.edit'
|
|
94
|
+
# element :title_field, '.title'
|
|
95
|
+
#
|
|
96
|
+
# def edit_info(title: nil)
|
|
97
|
+
# edit_button_element.click
|
|
98
|
+
# title_field_element.set(title)
|
|
99
|
+
# end
|
|
100
|
+
# end
|
|
101
|
+
# end
|
|
102
|
+
# HomePage.on { info_panel.edit_info(title: 'Test Title') }
|
|
103
|
+
# @example Anonymous nested section
|
|
104
|
+
# class HomePage < Howitzer::Web::Page
|
|
105
|
+
# section :info_panel, '#panel' do
|
|
106
|
+
# element :edit_button, '.edit'
|
|
107
|
+
#
|
|
108
|
+
# section :form, '.form' do
|
|
109
|
+
# element :title_field, '.title'
|
|
110
|
+
# end
|
|
111
|
+
# end
|
|
112
|
+
# end
|
|
113
|
+
# HomePage.on { info_panel_section.edit_info(title: 'Test Title') }
|
|
114
|
+
# @!visibility public
|
|
115
|
+
|
|
116
|
+
def section(name, *args, &block)
|
|
117
|
+
scope = SectionScope.new(name, *args, &block)
|
|
118
|
+
define_section_method(scope.section_class, name, scope.finder_args)
|
|
119
|
+
define_sections_method(scope.section_class, name, scope.finder_args)
|
|
120
|
+
define_has_section_method(name, scope.finder_args)
|
|
121
|
+
define_has_no_section_method(name, scope.finder_args)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
private
|
|
125
|
+
|
|
126
|
+
def define_section_method(klass, name, args)
|
|
127
|
+
define_method("#{name}_section") do
|
|
128
|
+
klass.new(self, capybara_context.find(*args))
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def define_sections_method(klass, name, args)
|
|
133
|
+
define_method("#{name}_sections") do
|
|
134
|
+
capybara_context.all(*args).map { |el| klass.new(self, el) }
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def define_has_section_method(name, args)
|
|
139
|
+
define_method("has_#{name}_section?") do
|
|
140
|
+
capybara_context.has_selector?(*args)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def define_has_no_section_method(name, args)
|
|
145
|
+
define_method("has_no_#{name}_section?") do
|
|
146
|
+
capybara_context.has_no_selector?(*args)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
require 'howitzer/web/base_section'
|
data/spec/config/custom.yml
CHANGED
|
@@ -1 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
log_dir: "spec/log"
|
|
2
|
+
driver: selenium
|
|
3
|
+
mailgun_domain: mailgun@test.domain
|
|
4
|
+
mailgun_idle_timeout: 0.5
|
|
5
|
+
mailgun_sleep_time: 0.05
|
|
6
|
+
page_load_idle_timeout: 0.1
|
|
7
|
+
capybara_wait_time: 5
|
|
8
|
+
cloud_http_idle_timeout: 10
|
|
9
|
+
hide_datetime_from_log: true
|
|
10
|
+
maximized_window: false
|
data/spec/spec_helper.rb
CHANGED
|
@@ -2,23 +2,13 @@ require 'rubygems'
|
|
|
2
2
|
require 'bundler/setup'
|
|
3
3
|
require 'simplecov'
|
|
4
4
|
require 'coveralls'
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
require 'json'
|
|
9
|
-
require 'capybara/dsl'
|
|
10
|
-
require 'active_support'
|
|
11
|
-
require 'active_support/deprecation'
|
|
12
|
-
require 'active_support/deprecation/method_wrappers'
|
|
13
|
-
require 'active_support/core_ext'
|
|
14
|
-
require 'repeater'
|
|
15
|
-
require 'howitzer/exceptions'
|
|
16
|
-
require 'howitzer/utils/log'
|
|
17
|
-
|
|
18
|
-
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
|
5
|
+
Coveralls.wear!
|
|
6
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
|
|
7
|
+
[
|
|
19
8
|
SimpleCov::Formatter::HTMLFormatter,
|
|
20
9
|
Coveralls::SimpleCov::Formatter
|
|
21
|
-
]
|
|
10
|
+
]
|
|
11
|
+
)
|
|
22
12
|
|
|
23
13
|
SimpleCov.start do
|
|
24
14
|
add_filter '/spec/'
|
|
@@ -30,8 +20,36 @@ SimpleCov.start do
|
|
|
30
20
|
add_group 'lib', '/lib'
|
|
31
21
|
end
|
|
32
22
|
|
|
23
|
+
require 'tmpdir'
|
|
24
|
+
require 'ffaker'
|
|
25
|
+
require 'capybara'
|
|
26
|
+
require 'json'
|
|
27
|
+
require 'capybara/dsl'
|
|
28
|
+
require 'active_support'
|
|
29
|
+
require 'active_support/deprecation'
|
|
30
|
+
require 'active_support/deprecation/method_wrappers'
|
|
31
|
+
require 'active_support/core_ext'
|
|
32
|
+
require 'repeater'
|
|
33
|
+
require 'sexy_settings'
|
|
34
|
+
|
|
35
|
+
SexySettings.configure do |config|
|
|
36
|
+
config.path_to_default_settings = File.expand_path(
|
|
37
|
+
'default.yml',
|
|
38
|
+
File.join(__dir__, '..', 'generators', 'config', 'templates')
|
|
39
|
+
)
|
|
40
|
+
config.path_to_custom_settings = File.expand_path(
|
|
41
|
+
'custom.yml',
|
|
42
|
+
File.join(__dir__, 'config')
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
puts SexySettings::Base.instance.as_formatted_text
|
|
47
|
+
|
|
48
|
+
require 'howitzer'
|
|
49
|
+
require 'howitzer/exceptions'
|
|
50
|
+
|
|
33
51
|
def project_path
|
|
34
|
-
File.expand_path(File.join(
|
|
52
|
+
File.expand_path(File.join(__dir__, '..'))
|
|
35
53
|
end
|
|
36
54
|
|
|
37
55
|
def lib_path
|
|
@@ -46,10 +64,10 @@ def log_path
|
|
|
46
64
|
File.join(project_path, 'spec/log')
|
|
47
65
|
end
|
|
48
66
|
|
|
49
|
-
Dir[File.join(
|
|
67
|
+
Dir[File.join(__dir__, 'support', '**', '*.rb')].each { |f| require f }
|
|
50
68
|
|
|
51
69
|
RSpec.configure do |config|
|
|
52
|
-
config.include GeneratorHelper
|
|
70
|
+
config.include Howitzer::GeneratorHelper
|
|
53
71
|
config.disable_monkey_patching = true
|
|
54
72
|
config.around(:each) do |ex|
|
|
55
73
|
$stdout = StringIO.new
|
|
@@ -58,4 +76,4 @@ RSpec.configure do |config|
|
|
|
58
76
|
$stdout = STDOUT
|
|
59
77
|
$stderr = STDERR
|
|
60
78
|
end
|
|
61
|
-
end
|
|
79
|
+
end
|