howitzer 2.5.0 → 2.6.0

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