watir 6.17.0 → 6.18.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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/.github/actions/enable-safari/action.yml +11 -0
  3. data/.github/actions/install-chrome/action.yml +11 -0
  4. data/.github/workflows/linux.yml +61 -0
  5. data/.github/workflows/mac.yml +55 -0
  6. data/.github/workflows/unit.yml +31 -0
  7. data/.github/workflows/windows.yml +39 -0
  8. data/.rubocop_todo.yml +36 -0
  9. data/CHANGES.md +14 -0
  10. data/LICENSE +2 -2
  11. data/README.md +9 -10
  12. data/Rakefile +1 -1
  13. data/lib/watir.rb +1 -0
  14. data/lib/watir/adjacent.rb +1 -1
  15. data/lib/watir/alert.rb +1 -0
  16. data/lib/watir/attribute_helper.rb +2 -0
  17. data/lib/watir/browser.rb +2 -2
  18. data/lib/watir/cookies.rb +2 -0
  19. data/lib/watir/element_collection.rb +21 -6
  20. data/lib/watir/elements/element.rb +10 -10
  21. data/lib/watir/elements/html_elements.rb +0 -1
  22. data/lib/watir/elements/iframe.rb +2 -1
  23. data/lib/watir/elements/select.rb +20 -5
  24. data/lib/watir/generator/html/generator.rb +1 -1
  25. data/lib/watir/has_window.rb +17 -15
  26. data/lib/watir/js_execution.rb +2 -2
  27. data/lib/watir/js_snippets.rb +2 -2
  28. data/lib/watir/locators.rb +1 -3
  29. data/lib/watir/locators/element/selector_builder.rb +1 -1
  30. data/lib/watir/logger.rb +2 -18
  31. data/lib/watir/radio_set.rb +2 -2
  32. data/lib/watir/user_editable.rb +6 -2
  33. data/lib/watir/version.rb +1 -1
  34. data/lib/watir/wait.rb +2 -0
  35. data/lib/watir/wait/timer.rb +1 -1
  36. data/lib/watir/window.rb +7 -3
  37. data/lib/watir/window_collection.rb +105 -0
  38. data/lib/watirspec.rb +1 -0
  39. data/lib/watirspec/implementation.rb +3 -5
  40. data/lib/watirspec/runner.rb +1 -1
  41. data/lib/watirspec/server.rb +1 -1
  42. data/spec/spec_helper.rb +2 -7
  43. data/spec/unit/match_elements/element_spec.rb +17 -15
  44. data/spec/unit/unit_helper.rb +2 -4
  45. data/spec/watirspec/after_hooks_spec.rb +15 -11
  46. data/spec/watirspec/browser_spec.rb +3 -2
  47. data/spec/watirspec/elements/element_spec.rb +14 -11
  48. data/spec/watirspec/elements/filefield_spec.rb +2 -2
  49. data/spec/watirspec/elements/iframe_spec.rb +5 -7
  50. data/spec/watirspec/elements/link_spec.rb +5 -3
  51. data/spec/watirspec/elements/select_list_spec.rb +156 -37
  52. data/spec/watirspec/html/wait.html +5 -5
  53. data/spec/watirspec/html/window_switching.html +10 -0
  54. data/spec/watirspec/legacy_wait_spec.rb +216 -0
  55. data/spec/watirspec/support/rspec_matchers.rb +10 -7
  56. data/spec/watirspec/wait_spec.rb +257 -301
  57. data/spec/watirspec/window_switching_spec.rb +282 -160
  58. data/spec/watirspec_helper.rb +10 -15
  59. data/support/doctest_helper.rb +0 -2
  60. data/watir.gemspec +2 -2
  61. metadata +25 -13
  62. data/.travis.yml +0 -87
  63. data/appveyor.yml +0 -13
  64. data/spec/watirspec/relaxed_locate_spec.rb +0 -109
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c587621e41c1ab878d2e9ff3cfd6c5166c5df9dc66cd02c0719d492aaba48d1e
4
- data.tar.gz: 509ba43afa0272d7b154eb5885e403578e2bc3956ab93803123b519093e7b430
3
+ metadata.gz: 29eeb6548d5f5f91ee744107d1e3c79f0d2baf8b688c9588752e25b75fa696ef
4
+ data.tar.gz: 27502c2b89585471b25751b5564c08784578585d3c196f132f56b52243645735
5
5
  SHA512:
6
- metadata.gz: 5215ff9fc1cfce6fa050532583167e6ed16be6f74b0d305b8d186b83361162c711ae9b63689a00882bf60d559783508ea2369ed9e8d5e25b504688eb2914db01
7
- data.tar.gz: 1b0ba276ea5c83f217151c125b0f645aab7011d86d9049ea7850ea83af4fbeeb9bdfa14ca60d7205c55bee3c0d6f817143bd9f979c7dc5adc368af446367ab8a
6
+ metadata.gz: d2a90695c68c0db0493d1fdeac5ab90ab51604a0916b4b6cbf0abeae595c6680f62269da98b9920c7ee7db4448e70c6afe31caa280ae76234bae2fc0b51c2912
7
+ data.tar.gz: 645305ed2b0ae8b5777995c6620055e37850dcefdb3b5a5b609d98b4ce30f8d0cd14155a79fb2032a46862d8c10ad92e9c0112fc7fe68e31dac01b6da44cbbd9
@@ -0,0 +1,11 @@
1
+ name: 'Enable Safari Driver'
2
+ description: 'Set safaridriver to run in automation mode'
3
+ runs:
4
+ using: composite
5
+ steps:
6
+ - run: |
7
+ defaults write com.apple.Safari IncludeDevelopMenu YES
8
+ defaults write com.apple.Safari AllowRemoteAutomation 1
9
+ sudo safaridriver --enable
10
+ safaridriver -p 0 &
11
+ shell: bash
@@ -0,0 +1,11 @@
1
+ name: 'Install Chrome'
2
+ runs:
3
+ using: "composite"
4
+ steps:
5
+ - run: |
6
+ wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
7
+ echo "deb http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee -a /etc/apt/sources.list.d/google-chrome.list
8
+ sudo apt-get update -qqy
9
+ sudo apt-get -qqy install google-chrome-stable
10
+ sudo rm /etc/apt/sources.list.d/google-chrome.list
11
+ shell: bash
@@ -0,0 +1,61 @@
1
+ name: Linux Tests
2
+
3
+ on:
4
+ - push
5
+ - pull_request
6
+
7
+ jobs:
8
+ chrome-test:
9
+ name: Chrome Test
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ task: [ 'chrome' ]
15
+ steps:
16
+ - uses: actions/checkout@v2
17
+ - uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: 2.5
20
+ - run: bundle install
21
+ - uses: ./.github/actions/install-chrome
22
+ - run: Xvfb :99 &
23
+ - run: |
24
+ bundle exec rake spec:${{ matrix.task }}
25
+ env:
26
+ DISPLAY: :99
27
+
28
+ firefox-test:
29
+ name: Firefox Test
30
+ runs-on: ubuntu-latest
31
+ strategy:
32
+ fail-fast: false
33
+ matrix:
34
+ task: [ 'firefox' ]
35
+ steps:
36
+ - uses: actions/checkout@v2
37
+ - uses: ruby/setup-ruby@v1
38
+ with:
39
+ ruby-version: 2.5
40
+ - run: bundle install
41
+ - run: Xvfb :99 &
42
+ - run: |
43
+ bundle exec rake spec:${{ matrix.task }}
44
+ env:
45
+ DISPLAY: :99
46
+
47
+ documentation-test:
48
+ name: Yard Doc Test
49
+ runs-on: ubuntu-latest
50
+ steps:
51
+ - uses: actions/checkout@v2
52
+ - uses: ruby/setup-ruby@v1
53
+ with:
54
+ ruby-version: 2.5
55
+ - run: bundle install
56
+ - uses: ./.github/actions/install-chrome
57
+ - run: Xvfb :99 &
58
+ - run: |
59
+ bundle exec rake yard:doctest
60
+ env:
61
+ DISPLAY: :99
@@ -0,0 +1,55 @@
1
+ name: Mac Tests
2
+
3
+ on:
4
+ - push
5
+ - pull_request
6
+
7
+ jobs:
8
+ chrome-test:
9
+ name: Chrome Test
10
+ runs-on: macos-latest
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ task: [ 'chrome' ]
15
+ steps:
16
+ - uses: actions/checkout@v2
17
+ - uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: 2.5
20
+ - run: bundle install
21
+ - run: |
22
+ bundle exec rake spec:${{ matrix.task }}
23
+
24
+ firefox-test:
25
+ name: Firefox Test
26
+ runs-on: macos-latest
27
+ strategy:
28
+ fail-fast: false
29
+ matrix:
30
+ task: [ 'firefox' ]
31
+ steps:
32
+ - uses: actions/checkout@v2
33
+ - uses: ruby/setup-ruby@v1
34
+ with:
35
+ ruby-version: 2.5
36
+ - run: bundle install
37
+ - run: |
38
+ bundle exec rake spec:${{ matrix.task }}
39
+
40
+ safari-test:
41
+ name: Safari Test
42
+ runs-on: macos-latest
43
+ strategy:
44
+ fail-fast: false
45
+ matrix:
46
+ task: [ 'safari' ]
47
+ steps:
48
+ - uses: actions/checkout@v2
49
+ - uses: ruby/setup-ruby@v1
50
+ with:
51
+ ruby-version: 2.5
52
+ - run: bundle install
53
+ - uses: ./.github/actions/enable-safari
54
+ - run: |
55
+ bundle exec rake spec:${{ matrix.task }}
@@ -0,0 +1,31 @@
1
+ name: Unit Tests
2
+
3
+ on:
4
+ - push
5
+ - pull_request
6
+
7
+ jobs:
8
+ unit-test:
9
+ name: Unit Tests
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ ruby: ['2.5', '2.6', '2.7', '3.0']
15
+ steps:
16
+ - uses: actions/checkout@v2
17
+ - uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: ${{ matrix.ruby }}
20
+ - run: bundle install
21
+ - run: bundle exec rake spec:unit
22
+ linter-test:
23
+ name: Rubocop Tests
24
+ runs-on: ubuntu-latest
25
+ steps:
26
+ - uses: actions/checkout@v2
27
+ - uses: ruby/setup-ruby@v1
28
+ with:
29
+ ruby-version: 2.5
30
+ - run: bundle install
31
+ - run: bundle exec rubocop
@@ -0,0 +1,39 @@
1
+ name: Windows Tests
2
+
3
+ on:
4
+ - push
5
+ - pull_request
6
+
7
+ jobs:
8
+ chrome-test:
9
+ name: Chrome Test
10
+ runs-on: windows-latest
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ task: [ 'chrome' ]
15
+ steps:
16
+ - uses: actions/checkout@v2
17
+ - uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: 2.5
20
+ - run: bundle install
21
+ - run: |
22
+ bundle exec rake spec:${{ matrix.task }}
23
+ firefox-test:
24
+ name: Firefox Test
25
+ runs-on: windows-latest
26
+ strategy:
27
+ fail-fast: false
28
+ matrix:
29
+ task: [ 'firefox' ]
30
+ steps:
31
+ - uses: actions/checkout@v2
32
+ - uses: ruby/setup-ruby@v1
33
+ with:
34
+ ruby-version: 2.5
35
+ - run: bundle install
36
+ - run: |
37
+ bundle exec rake spec:${{ matrix.task }}
38
+
39
+
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,36 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2020-08-27 01:55:04 UTC using RuboCop version 0.89.1.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 116
10
+ Style/Documentation:
11
+ Enabled: false
12
+
13
+ # Offense count: 11
14
+ # Configuration parameters: EnforcedStyle.
15
+ # SupportedStyles: annotated, template, unannotated
16
+ Style/FormatStringToken:
17
+ Exclude:
18
+ - 'lib/watir/browser.rb'
19
+ - 'lib/watir/window.rb'
20
+
21
+ # Offense count: 229
22
+ # Cop supports --auto-correct.
23
+ # Configuration parameters: EnforcedStyle.
24
+ # SupportedStyles: always, always_true, never
25
+ Style/FrozenStringLiteralComment:
26
+ Enabled: false
27
+
28
+ # Remove for Watir 7
29
+ Naming/FileName:
30
+ Exclude:
31
+ - 'lib/watir-webdriver.rb'
32
+
33
+ # Fix in Watir 7
34
+ Metrics/ParameterLists:
35
+ Exclude:
36
+ - 'lib/watir/wait.rb'
data/CHANGES.md CHANGED
@@ -1,3 +1,17 @@
1
+ ### 6.18.0 (2021-02-26)
2
+
3
+ * Implement `WindowCollection` to manage multiple `Window` objects
4
+ * Add support for locating `Window` by `:element`
5
+ * Deprecate locating `Window` by `:index`
6
+ * Deprecate `Select#select_all` in favor of `#select` and an `Array`
7
+ * Implement `Browser#switch_window` (#849)
8
+ * Add support for `Numeric` attribute values to `Waitable`
9
+ * Allow users to specify Selenium 4 in their projects
10
+ * Update stale element handling behavior to match webdriver spec (#905 #909)
11
+ * Implement `Waitable` for `ElementCollection` (#853 #857)
12
+ * Improve performance for nested elements (#843)
13
+ * Less strict version check for `regexp_parser` gem (thanks Pavel Lobashov)
14
+
1
15
  ### 6.17.0 (2020-08-27)
2
16
  * Require Ruby > 2.5
3
17
  * Implement Logger#selenium= to set selenium level from Watir
data/LICENSE CHANGED
@@ -1,8 +1,8 @@
1
1
  (the MIT License)
2
2
 
3
3
  Copyright (c) 2009-2015 Jari Bakken
4
- Copyright (c) 2015-2018 Alex Rodionov, Titus Fortner
5
- Copyright (c) 2018 Justin Ko
4
+ Copyright (c) 2015-2021 Alex Rodionov, Titus Fortner
5
+ Copyright (c) 2018-2021 Justin Ko
6
6
 
7
7
  Permission is hereby granted, free of charge, to any person obtaining
8
8
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -3,10 +3,12 @@
3
3
  Watir Powered By Selenium!
4
4
 
5
5
  [![Gem Version](https://badge.fury.io/rb/watir.svg)](http://badge.fury.io/rb/watir)
6
- [![Travis Status](https://travis-ci.org/watir/watir.svg?branch=master)](https://travis-ci.org/watir/watir)
7
- [![AppVeyor status](https://ci.appveyor.com/api/projects/status/9vbb7pp5p4uyoott/branch/master?svg=true)](https://ci.appveyor.com/project/p0deje/watir)
6
+ [![Unit Tests](https://github.com/titusfortner/watir/workflows/Unit%20Tests/badge.svg)](https://github.com/watir/watir/actions?query=workflow%3A%22Unit+Tests%22)
7
+ [![Mac Tests](https://github.com/titusfortner/watir/workflows/Mac%20Tests/badge.svg)](https://github.com/watir/watir/actions?query=workflow%3A%22Mac+Tests%22)
8
+ [![Windows Tests](https://github.com/titusfortner/watir/workflows/Windows%20Tests/badge.svg)](https://github.com/watir/watir/actions?query=workflow%3A%22Windows+Tests%22)
9
+ [![Linux Tests](https://github.com/titusfortner/watir/workflows/Linux%20Tests/badge.svg)](https://github.com/watir/watir/actions?query=workflow%3A%22Linux+Tests%22)
8
10
  [![Code Climate](https://codeclimate.com/github/watir/watir.svg)](https://codeclimate.com/github/watir/watir)
9
- [![Coverage Status](https://coveralls.io/repos/github/watir/watir/badge.svg?branch=master)](https://coveralls.io/github/watir/watir?branch=master)
11
+ [![Coverage Status](https://coveralls.io/repos/github/watir/watir/badge.svg?branch=main)](https://coveralls.io/github/watir/watir?branch=master)
10
12
 
11
13
  ## Using Watir
12
14
 
@@ -69,11 +71,11 @@ $ bundle exec rake svg:update
69
71
 
70
72
  ## Specs
71
73
 
72
- #### Travis CI
74
+ #### Github Actions
73
75
 
74
- Watir specs are run on [Travis CI](https://travis-ci.org/watir/watir).
76
+ Watir specs are run with [Github Actions](https://github.com/watir/watir/workflows).
75
77
 
76
- Watir code is tested with 2.3, 2.4 and 2.5 versions in multiple browsers and with multiple configurations.
78
+ Watir code is tested on Linux with latest versions of supported browsers and all active Ruby versions.
77
79
 
78
80
  #### Doctests
79
81
 
@@ -95,7 +97,7 @@ to ensure all paths in their code have tests associated with them.
95
97
 
96
98
  Watir is using [Rubocop](https://github.com/rubocop-hq/rubocop) to ensure a consistent style across the
97
99
  code base. It is run with our minimum supported Ruby version (2.3)
98
- We have some [established exceptions](https://github.com/watir/watir/blob/master/.rubocop.yml)
100
+ We have some [established exceptions](https://github.com/watir/watir/blob/main/.rubocop.yml)
99
101
  that might need to be tweaked for new code submissions. This can be addressed in the PR as necessary.
100
102
 
101
103
  #### Statistics
@@ -107,7 +109,4 @@ on wire calls.
107
109
 
108
110
  ## Copyright
109
111
 
110
- Copyright (c) 2009-2015 Jari Bakken
111
- Copyright (c) 2015-2018 Alex Rodionov, Titus Fortner
112
- Copyright (c) 2018 Justin Ko
113
112
  See LICENSE for details
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ Bundler::GemHelper.install_tasks
5
5
 
6
6
  require 'rspec/core/rake_task'
7
7
  RSpec::Core::RakeTask.new(:spec) do |spec|
8
- spec.rspec_opts = %w[--color --require fuubar --format Fuubar]
8
+ spec.rspec_opts = %w[--color --format doc]
9
9
  spec.pattern = 'spec/**/*_spec.rb'
10
10
  spec.exclude_pattern = 'spec/unit/**/*_spec.rb'
11
11
  end
data/lib/watir.rb CHANGED
@@ -6,6 +6,7 @@ require 'watir/legacy_wait'
6
6
  require 'watir/wait'
7
7
  require 'watir/exception'
8
8
  require 'watir/window'
9
+ require 'watir/window_collection'
9
10
  require 'watir/has_window'
10
11
  require 'watir/adjacent'
11
12
  require 'watir/js_execution'
@@ -117,7 +117,7 @@ module Watir
117
117
  el = Watir.element_class_for(opt[:tag_name] || '').new(self, opt)
118
118
  el.is_a?(Input) ? el.to_subtype : el
119
119
  elsif opt[:tag_name]
120
- Object.const_get("#{Watir.element_class_for(opt[:tag_name])}Collection").new(self, opt)
120
+ Watir.const_get("#{Watir.element_class_for(opt[:tag_name])}Collection").new(self, opt)
121
121
  else
122
122
  HTMLElementCollection.new(self, opt)
123
123
  end
data/lib/watir/alert.rb CHANGED
@@ -84,6 +84,7 @@ module Watir
84
84
  false
85
85
  end
86
86
  alias present? exists?
87
+ alias exist? exists?
87
88
 
88
89
  #
89
90
  # @api private
@@ -46,6 +46,8 @@ module Watir
46
46
  # @return [$1] value of $3 property
47
47
  #
48
48
  def attribute(type, method, attr)
49
+ return if method_defined?(method)
50
+
49
51
  typed_attributes[type] << [method, attr]
50
52
  define_attribute(type, method, attr)
51
53
  end
data/lib/watir/browser.rb CHANGED
@@ -213,11 +213,11 @@ module Watir
213
213
  # @param args Arguments will be available in the given script in the 'arguments' pseudo-array
214
214
  #
215
215
 
216
- def execute_script(script, *args)
216
+ def execute_script(script, *args, function_name: nil)
217
217
  args.map! do |e|
218
218
  e.is_a?(Element) ? e.wait_until(&:exists?).wd : e
219
219
  end
220
-
220
+ Watir.logger.info "Executing Script on Browser: #{function_name}" if function_name
221
221
  wrap_elements_in(self, @driver.execute_script(script, *args))
222
222
  end
223
223
 
data/lib/watir/cookies.rb CHANGED
@@ -105,6 +105,8 @@ module Watir
105
105
  IO.write(file, to_a.to_yaml)
106
106
  end
107
107
 
108
+ #
109
+ # TODO: Use :permitted_classes keyword when minimum supported Ruby is 2.6
108
110
  #
109
111
  # Load cookies from file
110
112
  #
@@ -7,17 +7,19 @@ module Watir
7
7
  include Enumerable
8
8
  include Exception
9
9
  include JSSnippets
10
+ include Waitable
10
11
  include Locators::ClassHelpers
11
12
 
12
13
  def initialize(query_scope, selector)
13
14
  @query_scope = query_scope
14
15
  @selector = selector
16
+ @to_a = nil
15
17
 
16
18
  build unless @selector.key?(:element)
17
19
  end
18
20
 
19
21
  #
20
- # Yields each element in collection.
22
+ # Relocates elements then yields each element in resulting collection.
21
23
  #
22
24
  # @example
23
25
  # divs = browser.divs(class: 'kls')
@@ -29,6 +31,7 @@ module Watir
29
31
  #
30
32
 
31
33
  def each(&blk)
34
+ reset!
32
35
  to_a.each(&blk)
33
36
  end
34
37
 
@@ -37,6 +40,9 @@ module Watir
37
40
 
38
41
  alias empty? none?
39
42
 
43
+ alias exist? any?
44
+ alias exists? any?
45
+
40
46
  def build
41
47
  selector_builder.build(@selector.dup)
42
48
  end
@@ -145,14 +151,19 @@ module Watir
145
151
  alias eql? ==
146
152
 
147
153
  #
148
- # Creates a Collection containing elements of two collections.
154
+ # Removes cache of previously located elements in the collection.
149
155
  #
150
156
  # @example
151
157
  # options = browser.select_list(name: "new_user_languages").options
152
- # (options + browser.select_list(id: "new_user_role").options).size
153
- # #=> 8
158
+ # options.reset!
159
+ # options[0]
160
+ # #=> nil
154
161
  #
155
162
 
163
+ def reset!
164
+ @to_a = nil
165
+ end
166
+
156
167
  private
157
168
 
158
169
  def elements
@@ -182,7 +193,11 @@ module Watir
182
193
  end
183
194
 
184
195
  def ensure_context
185
- @query_scope.locate if @query_scope.is_a?(Browser) || @query_scope.located? && @query_scope.stale?
196
+ if @query_scope.is_a?(Browser) || !@query_scope.located? && @query_scope.is_a?(IFrame)
197
+ @query_scope.browser.locate
198
+ elsif @query_scope.located? && @query_scope.stale?
199
+ @query_scope.locate
200
+ end
186
201
  @query_scope.switch_to! if @query_scope.is_a?(IFrame)
187
202
  end
188
203
 
@@ -191,7 +206,7 @@ module Watir
191
206
  end
192
207
 
193
208
  def element_class
194
- Kernel.const_get(self.class.name.sub(/Collection$/, ''))
209
+ Watir.const_get(self.class.name.sub(/Collection$/, ''))
195
210
  end
196
211
 
197
212
  def construct_subtype(element, hash, tag_name)