howitzer 2.5.0 → 2.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1044884bf6fe39dc63128f59f930a0d75ae80297a946d34d2464f47a30fe17fe
4
- data.tar.gz: b5501960e801914414fc6569996a9cc219e601ea78dfea1dac28c7db9d582ac7
3
+ metadata.gz: 3b59a8a3bed744aeb4c97b117d141bbec762d24d398b97fe6ddfa4f955838360
4
+ data.tar.gz: 20b21155002eb01cb5e680b610b57f1d64d6b68ede1a683e32b74165d5d3c00e
5
5
  SHA512:
6
- metadata.gz: 450f74b4dec7185673b2faa9138c8afb4b9568be8680f38718728105ad5893a5e1abfb1d908e759a021fcd3af13093e67775537b3a109219b065b00c30a7f293
7
- data.tar.gz: 0bc01379c520937ec1bd004fffcc44b9c558ff9c1c5eea1a292067d65f5d1661f9f5aaf806c5b0183d34e46c2591fc3bd9b71a0cc8288fc7e12b56d9946478d0
6
+ metadata.gz: 16a09f131e9b6f9ec714e654f1ee6796a8ffd4779f75fd3d8c13e7b42ad6267abbd9f1e258e5ae8552f6cf59d1a3aa4914345734bcd4738e305e5e62561da2b1
7
+ data.tar.gz: 4bad2e4917e4e19bb0eae5da2c699af26e70adbc558c52b21da9f12781d0c714f23e0d7ea02c8bbf6dc03df44402b488bd87ead92adbeb2d93a06be43e334d69
data/CHANGELOG.md CHANGED
@@ -4,6 +4,20 @@
4
4
 
5
5
  ### Bug-fixes
6
6
 
7
+ ## [2.6.0](https://github.com/strongqa/howitzer/compare/v2.5.0...v2.6.0) (2023-01-16)
8
+
9
+
10
+ ### Features
11
+
12
+ * Add Docker support ([#321](https://github.com/strongqa/howitzer/issues/321)) ([d0e7bc9](https://github.com/strongqa/howitzer/commit/d0e7bc953182b13e93b74ab4b609316ece6cf956))
13
+ * Ruby3.2 support ([#327](https://github.com/strongqa/howitzer/issues/327)) ([265acc3](https://github.com/strongqa/howitzer/commit/265acc34fb2eac9b879e097ae938e66c62a6e7f7))
14
+
15
+
16
+ ### Bug Fixes
17
+
18
+ * Handle section options ([#324](https://github.com/strongqa/howitzer/issues/324)) ([b976e5b](https://github.com/strongqa/howitzer/commit/b976e5b83800fa1c0671857daba796dd8a1048f4))
19
+ * Section method typo ([#318](https://github.com/strongqa/howitzer/issues/318)) ([984deeb](https://github.com/strongqa/howitzer/commit/984deebe817d27278b93517b3f0e1338af25128a))
20
+
7
21
  ## [2.5.0](https://github.com/strongqa/howitzer/compare/v2.4.0...v2.5.0) (2022-08-16)
8
22
 
9
23
 
data/bin/howitzer CHANGED
@@ -31,21 +31,21 @@ module HowitzerCli
31
31
  Dir.mkdir(path_to_dir)
32
32
  puts " #{ColorizedString.new('Created').light_green} './#{args.first}' folder"
33
33
  Dir.chdir(path_to_dir)
34
- Howitzer::ConfigGenerator.new(options)
35
- Howitzer::WebGenerator.new(options)
36
- Howitzer::TasksGenerator.new(options)
37
- Howitzer::EmailsGenerator.new(options)
38
- Howitzer::RootGenerator.new(options)
39
- Howitzer::PrerequisitesGenerator.new(options)
34
+ Howitzer::ConfigGenerator.new(options, args)
35
+ Howitzer::WebGenerator.new(options, args)
36
+ Howitzer::TasksGenerator.new(options, args)
37
+ Howitzer::EmailsGenerator.new(options, args)
38
+ Howitzer::RootGenerator.new(options, args)
39
+ Howitzer::PrerequisitesGenerator.new(options, args)
40
40
  if options[:cucumber]
41
- Howitzer::CucumberGenerator.new(options)
41
+ Howitzer::CucumberGenerator.new(options, args)
42
42
  elsif options[:rspec]
43
- Howitzer::RspecGenerator.new(options)
43
+ Howitzer::RspecGenerator.new(options, args)
44
44
  elsif options['turnip']
45
- Howitzer::TurnipGenerator.new(options)
45
+ Howitzer::TurnipGenerator.new(options, args)
46
46
  end
47
47
  puts ColorizedString.new('[WARN] Extra parameters were skipped').yellow if args.size > 1
48
- elsif args.size.zero?
48
+ elsif args.empty?
49
49
  exit_now!(ColorizedString.new('Please specify <PROJECT NAME>').red, 64)
50
50
  end
51
51
  end
@@ -54,8 +54,8 @@ module Howitzer
54
54
  end
55
55
  end
56
56
 
57
- def initialize(_options)
58
- super()
57
+ def initialize
58
+ super
59
59
 
60
60
  manifest.each do |type, list|
61
61
  case type
@@ -72,6 +72,12 @@ module Howitzer
72
72
  []
73
73
  end
74
74
 
75
+ def template_context
76
+ data = options
77
+ data = options.merge(project_name: project_name) unless project_name.nil?
78
+ OpenStruct.new(data) # rubocop:disable Style/OpenStructUse
79
+ end
80
+
75
81
  protected
76
82
 
77
83
  def copy_files(list)
@@ -90,7 +96,7 @@ module Howitzer
90
96
  else
91
97
  write_template(destination_path, source_path)
92
98
  puts_info "#{ColorizedString.new('Added').light_green} template '#{data[:source]}' with " \
93
- "params '#{@options}' to destination '#{data[:destination]}'"
99
+ "params '#{template_context.to_h}' to destination '#{data[:destination]}'"
94
100
  end
95
101
  end
96
102
  end
@@ -118,8 +124,10 @@ module Howitzer
118
124
  end
119
125
 
120
126
  def write_template(dest_path, source_path)
121
- File.write(dest_path, ERB.new(File.read(source_path), trim_mode: '-')
122
- .result(OpenStruct.new(@options).instance_eval { binding })) # rubocop:disable Style/OpenStructUse
127
+ File.write(
128
+ dest_path,
129
+ ERB.new(File.read(source_path), trim_mode: '-').result(template_context.instance_eval { binding })
130
+ )
123
131
  end
124
132
 
125
133
  private
@@ -177,14 +185,16 @@ module Howitzer
177
185
 
178
186
  # Parent class for all generators
179
187
  class BaseGenerator
180
- attr_reader :options
188
+ attr_reader :options, :args, :project_name
181
189
 
182
190
  include Outputable
183
191
  include Copyable
184
192
 
185
- def initialize(options = {})
193
+ def initialize(options = {}, args = [])
186
194
  @options = options.symbolize_keys
187
- super
195
+ @args = args
196
+ @project_name = args.first
197
+ super()
188
198
  end
189
199
  end
190
200
  end
@@ -7,12 +7,16 @@ module Howitzer
7
7
  { files:
8
8
  [
9
9
  { source: '.gitignore', destination: '.gitignore' },
10
+ { source: '.dockerignore', destination: '.dockerignore' },
11
+ { source: 'Dockerfile', destination: 'Dockerfile' },
10
12
  { source: 'Rakefile', destination: 'Rakefile' }
11
13
  ],
12
14
  templates:
13
15
  [
14
16
  { source: '.rubocop.yml.erb', destination: '.rubocop.yml' },
15
- { source: 'Gemfile.erb', destination: 'Gemfile' }
17
+ { source: 'docker-compose.yml.erb', destination: 'docker-compose.yml' },
18
+ { source: 'Gemfile.erb', destination: 'Gemfile' },
19
+ { source: 'README.md.erb', destination: 'README.md' }
16
20
  ] }
17
21
  end
18
22
 
@@ -0,0 +1,34 @@
1
+ FROM ruby:alpine
2
+
3
+ ENV CHROME_BIN=/usr/bin/chromium-browser \
4
+ CHROME_PATH=/usr/lib/chromium/ \
5
+ SEXY_SETTINGS_DELIMITER=";" \
6
+ CHROME_ARGS="window-size=1920x1080, disable-gpu, no-sandbox, disable-dev-shm-usage, disable-software-rasterizer"
7
+
8
+ RUN apk update && apk upgrade --no-cache --available \
9
+ && apk add --no-cache \
10
+ chromium firefox \
11
+ chromium-chromedriver \
12
+ ttf-freefont \
13
+ font-noto-emoji \
14
+ build-base bash \
15
+ curl \
16
+ git \
17
+ less dbus \
18
+ && apk add --no-cache \
19
+ --repository=https://dl-cdn.alpinelinux.org/alpine/edge/testing font-wqy-zenhei \
20
+ && wget https://github.com/mozilla/geckodriver/releases/download/v0.31.0/geckodriver-v0.31.0-linux64.tar.gz \
21
+ && tar -zxf geckodriver-v0.31.0-linux64.tar.gz -C /usr/bin \
22
+ && dbus-daemon --system
23
+
24
+ RUN adduser -D howitzer
25
+ USER howitzer
26
+
27
+ WORKDIR /home/howitzer
28
+
29
+ COPY --chown=howitzer Gemfile Gemfile.lock /home/howitzer/
30
+ RUN bundle config --global && bundle install --jobs=3 --retry=3
31
+
32
+ COPY --chown=howitzer . ./
33
+
34
+ ENTRYPOINT ["sleep", "infinity"]
@@ -0,0 +1,33 @@
1
+ # <%= project_name %>
2
+
3
+ ## Run tests in Docker
4
+
5
+ ### Build an image
6
+
7
+ `docker build -t <%= project_name %> .`
8
+
9
+ ### Run a container
10
+
11
+ `docker run -d --name <%= project_name %>_container <%= project_name %>
12
+
13
+ ### Connect to the container
14
+
15
+ `docker exec -it <%= project_name %>_container /bin/bash`
16
+
17
+ ### Run tests in the container
18
+
19
+ `SEXY_SETTINGS="driver=headless_chrome; headless_chrome_flags=$CHROME_ARGS" bundle exec rake`
20
+
21
+ or
22
+
23
+ `SEXY_SETTINGS="driver=headless_firefox" bundle exec rake`
24
+
25
+ ## Run tests via docker compose
26
+
27
+ ### Initialize build, and run a container in detached mode
28
+
29
+ `docker-compose -f docker-compose.yml up -d`
30
+
31
+ ### Connect to the container
32
+
33
+ `docker compose exec -it <%= project_name %> /bin/bash`
@@ -0,0 +1,9 @@
1
+ version: '1.0'
2
+
3
+ services:
4
+ <%= project_name %>:
5
+ build:
6
+ context: "."
7
+ dockerfile: Dockerfile
8
+ volumes:
9
+ - '.:/home/howitzer/:cached'
@@ -0,0 +1,54 @@
1
+ module Howitzer
2
+ module Utils
3
+ # This module mixes in private utils methods for section and element dsl
4
+ module ArgumentConvertable
5
+ private
6
+
7
+ def convert_arguments(args, options, block_args, block_options)
8
+ conv_args = args.map { |el| el.is_a?(Proc) ? proc_to_selector(el, block_args, block_options) : el }
9
+ args_options = pop_options_from_array(conv_args)
10
+ block_args_options = pop_options_from_array(block_args)
11
+ conv_options = [args_options, options, block_args_options, block_options].map do |el|
12
+ el.transform_keys(&:to_sym)
13
+ end.reduce(&:merge).except(:lambda_args)
14
+ [conv_args, conv_options]
15
+ end
16
+
17
+ def proc_to_selector(proc, block_args, block_options)
18
+ lambda_args = extract_lambda_args(block_args, block_options)
19
+ if lambda_args
20
+ if lambda_args[:keyword_args].present?
21
+ proc.call(*lambda_args[:args], **lambda_args[:keyword_args])
22
+ else
23
+ proc.call(*lambda_args[:args])
24
+ end
25
+ else
26
+ puts "WARNING! Passing lambda arguments with element options is deprecated.\n" \
27
+ "Please use 'lambda_args' method, for example: foo_element(lambda_args(title: 'Example'), wait: 10)"
28
+ proc.call(*block_args.shift(proc.arity))
29
+ end
30
+ end
31
+
32
+ def extract_lambda_args(block_args, block_options)
33
+ (block_args.first.is_a?(Hash) && block_args.first[:lambda_args]) || block_options[:lambda_args]
34
+ end
35
+
36
+ def pop_options_from_array(value)
37
+ if value.last.is_a?(Hash) && !value.last.key?(:lambda_args)
38
+ value.pop
39
+ else
40
+ {}
41
+ end
42
+ end
43
+
44
+ def lambda_args(*args, **keyword_args)
45
+ {
46
+ lambda_args: {
47
+ args: args,
48
+ keyword_args: keyword_args
49
+ }
50
+ }
51
+ end
52
+ end
53
+ end
54
+ end
@@ -8,4 +8,5 @@ module Howitzer
8
8
  end
9
9
  end
10
10
 
11
+ require 'howitzer/utils/argument_convertable'
11
12
  require 'howitzer/utils/string_extensions'
@@ -1,4 +1,4 @@
1
1
  # This module holds howitzer version
2
2
  module Howitzer
3
- VERSION = '2.5.0'.freeze # :nodoc:
3
+ VERSION = '2.6.0'.freeze # :nodoc:
4
4
  end
@@ -3,67 +3,16 @@ module Howitzer
3
3
  module Web
4
4
  # This module combines element dsl methods
5
5
  module ElementDsl
6
- # This module holds element helper methods
7
- module Helpers
8
- private
9
-
10
- def lambda_args(*args, **keyword_args)
11
- {
12
- lambda_args: {
13
- args: args,
14
- keyword_args: keyword_args
15
- }
16
- }
17
- end
18
- end
19
-
20
6
  include CapybaraContextHolder
21
- include Helpers
7
+ include Howitzer::Utils::ArgumentConvertable
22
8
 
23
9
  def self.included(base) # :nodoc:
24
10
  base.extend(ClassMethods)
25
11
  end
26
12
 
27
- def convert_arguments(args, options, block_args, block_options)
28
- conv_args = args.map { |el| el.is_a?(Proc) ? proc_to_selector(el, block_args, block_options) : el }
29
- args_options = pop_options_from_array(conv_args)
30
- block_args_options = pop_options_from_array(block_args)
31
- conv_options = [args_options, options, block_args_options, block_options].map do |el|
32
- el.transform_keys(&:to_sym)
33
- end.reduce(&:merge).except(:lambda_args)
34
- [conv_args, conv_options]
35
- end
36
-
37
- def proc_to_selector(proc, block_args, block_options)
38
- lambda_args = extract_lambda_args(block_args, block_options)
39
- if lambda_args
40
- if lambda_args[:keyword_args].present?
41
- proc.call(*lambda_args[:args], **lambda_args[:keyword_args])
42
- else
43
- proc.call(*lambda_args[:args])
44
- end
45
- else
46
- puts "WARNING! Passing lambda arguments with element options is deprecated.\n" \
47
- "Please use 'lambda_args' method, for example: foo_element(lambda_args(title: 'Example'), wait: 10)"
48
- proc.call(*block_args.shift(proc.arity))
49
- end
50
- end
51
-
52
- def extract_lambda_args(block_args, block_options)
53
- (block_args.first.is_a?(Hash) && block_args.first[:lambda_args]) || block_options[:lambda_args]
54
- end
55
-
56
- def pop_options_from_array(value)
57
- if value.last.is_a?(Hash) && !value.last.key?(:lambda_args)
58
- value.pop
59
- else
60
- {}
61
- end
62
- end
63
-
64
13
  # This module holds element dsl methods
65
14
  module ClassMethods
66
- include Helpers
15
+ include Howitzer::Utils::ArgumentConvertable
67
16
 
68
17
  protected
69
18
 
@@ -172,7 +121,6 @@ module Howitzer
172
121
  else
173
122
  capybara_context.find(*conv_args)
174
123
  end
175
- return nil
176
124
  end
177
125
  private "wait_for_#{name}_element"
178
126
  end
@@ -50,7 +50,7 @@ module Howitzer
50
50
  private
51
51
 
52
52
  def eval_in_out_context(*args, **options, &block)
53
- return nil if args.size.zero?
53
+ return nil if args.empty?
54
54
 
55
55
  name = args.shift
56
56
  return get_outer_instance_variable(name) if name.to_s.start_with?('@')
@@ -4,6 +4,7 @@ module Howitzer
4
4
  # This module combines section dsl methods
5
5
  module SectionDsl
6
6
  include CapybaraContextHolder
7
+ include Howitzer::Utils::ArgumentConvertable
7
8
 
8
9
  def self.included(base) # :nodoc:
9
10
  base.extend(ClassMethods)
@@ -11,6 +12,7 @@ module Howitzer
11
12
 
12
13
  # This module holds section dsl class methods
13
14
  module ClassMethods
15
+ include Howitzer::Utils::ArgumentConvertable
14
16
  # This class is for private usage only
15
17
  class SectionScope
16
18
  attr_accessor :section_class
@@ -61,9 +63,7 @@ module Howitzer
61
63
  # @raise [ArgumentError] when finder arguments were not specified
62
64
 
63
65
  def finder_options
64
- @options if @args.present? # it is ok to have blank options, so we rely here on the argments
65
-
66
- @finder_options ||= (section_class.default_finder_options || {})
66
+ @options.presence || section_class.default_finder_options || {}
67
67
  end
68
68
  end
69
69
 
@@ -135,45 +135,45 @@ module Howitzer
135
135
  private
136
136
 
137
137
  def define_section_method(klass, name, *args, **options)
138
- define_method("#{name}_section") do |**block_options|
139
- kwdargs = options.transform_keys(&:to_sym).merge(block_options.transform_keys(&:to_sym))
140
- if kwdargs.present?
141
- klass.new(self, capybara_context.find(*args, **kwdargs))
138
+ define_method("#{name}_section") do |*block_args, **block_options|
139
+ conv_args, conv_options = convert_arguments(args, options, block_args, block_options)
140
+ if conv_options.present?
141
+ klass.new(self, capybara_context.find(*conv_args, **conv_options))
142
142
  else
143
- klass.new(self, capybara_context.find(*args))
143
+ klass.new(self, capybara_context.find(*conv_args))
144
144
  end
145
145
  end
146
146
  end
147
147
 
148
148
  def define_sections_method(klass, name, *args, **options)
149
- define_method("#{name}_sections") do |**block_options|
150
- kwdargs = options.transform_keys(&:to_sym).merge(block_options.transform_keys(&:to_sym))
151
- if kwdargs.present?
152
- capybara_context.all(*args, **kwdargs).map { |el| klass.new(self, el) }
149
+ define_method("#{name}_sections") do |*block_args, **block_options|
150
+ conv_args, conv_options = convert_arguments(args, options, block_args, block_options)
151
+ if conv_options.present?
152
+ capybara_context.all(*conv_args, **conv_options).map { |el| klass.new(self, el) }
153
153
  else
154
- capybara_context.all(*args).map { |el| klass.new(self, el) }
154
+ capybara_context.all(*conv_args).map { |el| klass.new(self, el) }
155
155
  end
156
156
  end
157
157
  end
158
158
 
159
159
  def define_has_section_method(name, *args, **options)
160
- define_method("has_#{name}_section?") do |**block_options|
161
- kwdargs = options.transform_keys(&:to_sym).merge(block_options.transform_keys(&:to_sym))
162
- if kwdargs.present?
163
- capybara_context.has_selector?(*args, **kwdargs)
160
+ define_method("has_#{name}_section?") do |*block_args, **block_options|
161
+ conv_args, conv_options = convert_arguments(args, options, block_args, block_options)
162
+ if conv_options.present?
163
+ capybara_context.has_selector?(*conv_args, **conv_options)
164
164
  else
165
- capybara_context.has_selector?(*args)
165
+ capybara_context.has_selector?(*conv_args)
166
166
  end
167
167
  end
168
168
  end
169
169
 
170
170
  def define_has_no_section_method(name, *args, **options)
171
- define_method("has_no_#{name}_section?") do |**block_options|
172
- kwdargs = options.transform_keys(&:to_sym).merge(block_options.transform_keys(&:to_sym))
173
- if kwdargs.present?
174
- capybara_context.has_no_selector?(*args, **kwdarg)
171
+ define_method("has_no_#{name}_section?") do |*block_args, **block_options|
172
+ conv_args, conv_options = convert_arguments(args, options, block_args, block_options)
173
+ if conv_options.present?
174
+ capybara_context.has_no_selector?(*conv_args, **conv_options)
175
175
  else
176
- capybara_context.has_no_selector?(*args)
176
+ capybara_context.has_no_selector?(*conv_args)
177
177
  end
178
178
  end
179
179
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: howitzer
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 2.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roman Parashchenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-09 00:00:00.000000000 Z
11
+ date: 2023-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: '5'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '7'
22
+ version: '8'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: '5'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '7'
32
+ version: '8'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: capybara
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -272,8 +272,11 @@ files:
272
272
  - generators/prerequisites/templates/user.rb
273
273
  - generators/prerequisites/templates/users.rb
274
274
  - generators/root/root_generator.rb
275
+ - generators/root/templates/Dockerfile
275
276
  - generators/root/templates/Gemfile.erb
277
+ - generators/root/templates/README.md.erb
276
278
  - generators/root/templates/Rakefile
279
+ - generators/root/templates/docker-compose.yml.erb
277
280
  - generators/rspec/rspec_generator.rb
278
281
  - generators/rspec/templates/example_spec.rb
279
282
  - generators/rspec/templates/rspec.rake
@@ -322,6 +325,7 @@ files:
322
325
  - lib/howitzer/testmail_api.rb
323
326
  - lib/howitzer/testmail_api/client.rb
324
327
  - lib/howitzer/utils.rb
328
+ - lib/howitzer/utils/argument_convertable.rb
325
329
  - lib/howitzer/utils/string_extensions.rb
326
330
  - lib/howitzer/version.rb
327
331
  - lib/howitzer/web.rb
@@ -342,7 +346,7 @@ licenses:
342
346
  metadata:
343
347
  bug_tracker_uri: https://github.com/strongqa/howitzer/issues
344
348
  changelog_uri: https://github.com/strongqa/howitzer/blob/master/CHANGELOG.md
345
- documentation_uri: https://www.rubydoc.info/gems/howitzer/2.5.0
349
+ documentation_uri: https://www.rubydoc.info/gems/howitzer/2.6.0
346
350
  source_code_uri: https://github.com/strongqa/howitzer
347
351
  rubygems_mfa_required: 'false'
348
352
  post_install_message: