prof 0.29.3

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 (51) hide show
  1. checksums.yaml +7 -0
  2. data/LEGAL +13 -0
  3. data/lib/prof/cloud_foundry.rb +145 -0
  4. data/lib/prof/environment/cloud_foundry.rb +150 -0
  5. data/lib/prof/environment/pcf_drinks.rb +156 -0
  6. data/lib/prof/environment_manager.rb +93 -0
  7. data/lib/prof/external_spec/helpers/capybara.rb +58 -0
  8. data/lib/prof/external_spec/helpers/debug.rb +53 -0
  9. data/lib/prof/external_spec/helpers/file_helper.rb +35 -0
  10. data/lib/prof/external_spec/helpers/product_path.rb +23 -0
  11. data/lib/prof/external_spec/shared_examples/deployment.rb +23 -0
  12. data/lib/prof/external_spec/shared_examples/ops_manager_upgrade.rb +32 -0
  13. data/lib/prof/external_spec/shared_examples/service.rb +105 -0
  14. data/lib/prof/external_spec/shared_examples/service_broker.rb +25 -0
  15. data/lib/prof/external_spec/spec_helper.rb +35 -0
  16. data/lib/prof/marketplace_service.rb +20 -0
  17. data/lib/prof/matchers/metadata.rb +180 -0
  18. data/lib/prof/matchers/only_support_ssl_with_cipher_set.rb +102 -0
  19. data/lib/prof/matchers/ssl.rb +67 -0
  20. data/lib/prof/matchers/tile_configuration.rb +47 -0
  21. data/lib/prof/ops_manager/rails_500_error.rb +15 -0
  22. data/lib/prof/ops_manager/web_app_internals/page/checkbox_field.rb +38 -0
  23. data/lib/prof/ops_manager/web_app_internals/page/click_field.rb +40 -0
  24. data/lib/prof/ops_manager/web_app_internals/page/dashboard.rb +100 -0
  25. data/lib/prof/ops_manager/web_app_internals/page/flash_message.rb +53 -0
  26. data/lib/prof/ops_manager/web_app_internals/page/form.rb +130 -0
  27. data/lib/prof/ops_manager/web_app_internals/page/form_error.rb +43 -0
  28. data/lib/prof/ops_manager/web_app_internals/page/form_field.rb +51 -0
  29. data/lib/prof/ops_manager/web_app_internals/page/form_fields.rb +35 -0
  30. data/lib/prof/ops_manager/web_app_internals/page/installation_progress.rb +149 -0
  31. data/lib/prof/ops_manager/web_app_internals/page/login.rb +53 -0
  32. data/lib/prof/ops_manager/web_app_internals/page/modal.rb +85 -0
  33. data/lib/prof/ops_manager/web_app_internals/page/rails_500.rb +41 -0
  34. data/lib/prof/ops_manager/web_app_internals/page/select_field.rb +27 -0
  35. data/lib/prof/ops_manager/web_app_internals/page/tile_settings.rb +105 -0
  36. data/lib/prof/ops_manager/web_app_internals.rb +63 -0
  37. data/lib/prof/ops_manager.rb +141 -0
  38. data/lib/prof/ops_manager_log_fetcher.rb +30 -0
  39. data/lib/prof/product.rb +59 -0
  40. data/lib/prof/pushed_test_app.rb +40 -0
  41. data/lib/prof/service_instance.rb +21 -0
  42. data/lib/prof/ssh_gateway.rb +104 -0
  43. data/lib/prof/ssl/check.rb +79 -0
  44. data/lib/prof/ssl/cipher_set.rb +56 -0
  45. data/lib/prof/ssl/result.rb +27 -0
  46. data/lib/prof/ssl/results.rb +74 -0
  47. data/lib/prof/test_app.rb +19 -0
  48. data/lib/prof/tile.rb +25 -0
  49. data/lib/prof/uaa_client.rb +66 -0
  50. data/lib/prof/version.rb +13 -0
  51. metadata +403 -0
@@ -0,0 +1,47 @@
1
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
2
+ # All rights reserved.
3
+ # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
4
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
5
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
6
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
7
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
8
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
9
+ #
10
+
11
+ require 'rspec/expectations'
12
+
13
+ RSpec::Matchers.define :have_configuration_fields_on do |tile|
14
+ match do |_ops_manager|
15
+ @tile = tile
16
+ (expected_field_names - actual_field_names).empty?
17
+ end
18
+
19
+ chain :including do |*fields|
20
+ @expected_field_names = fields
21
+ end
22
+
23
+ failure_message do |_actual|
24
+ [
25
+ 'expected:',
26
+ "\t#{expected_field_names.inspect}",
27
+ 'to be present in:',
28
+ "\t#{actual_field_names}",
29
+ 'but these were not found',
30
+ "\t#{(expected_field_names - actual_field_names).inspect}"
31
+ ].join("\n")
32
+ end
33
+
34
+ def expected_field_names
35
+ raise 'Please set including' if @expected_field_names.nil?
36
+
37
+ @expected_field_names
38
+ end
39
+
40
+ def actual_config
41
+ @actual_config ||= ops_manager.tile_configuration(@tile)
42
+ end
43
+
44
+ def actual_field_names
45
+ actual_config.map { |_header, fields| fields.keys }.flatten
46
+ end
47
+ end
@@ -0,0 +1,15 @@
1
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
2
+ # All rights reserved.
3
+ # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
4
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
5
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
6
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
7
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
8
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
9
+ #
10
+
11
+ module Prof
12
+ class OpsManager
13
+ class Rails500Error < StandardError; end
14
+ end
15
+ end
@@ -0,0 +1,38 @@
1
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
2
+ # All rights reserved.
3
+ # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
4
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
5
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
6
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
7
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
8
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
9
+ #
10
+
11
+ require 'prof/ops_manager/web_app_internals/page/form_field'
12
+
13
+ module Prof
14
+ class OpsManager
15
+ class WebAppInternals
16
+ module Page
17
+ class CheckboxField < FormField
18
+ def initialize(name:, value:, checked:)
19
+ super(name: name, value: value)
20
+ @checked = checked
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :checked
26
+
27
+ def selector
28
+ super + "[value$='#{value}']"
29
+ end
30
+
31
+ def set_value(field)
32
+ field.set(checked)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,40 @@
1
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
2
+ # All rights reserved.
3
+ # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
4
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
5
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
6
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
7
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
8
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
9
+ #
10
+
11
+ require 'prof/ops_manager/web_app_internals/page/form_field'
12
+
13
+ module Prof
14
+ class OpsManager
15
+ class WebAppInternals
16
+ module Page
17
+ class ClickField < FormField
18
+ def initialize(name:, expected_state: )
19
+ super(name: name, value: nil)
20
+ @expected_state = expected_state
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :expected_state
26
+
27
+ def selector
28
+ super + ":not([type=hidden])"
29
+ end
30
+
31
+ def set_value(field)
32
+ unless field.checked? == expected_state
33
+ field.click
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,100 @@
1
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
2
+ # All rights reserved.
3
+ # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
4
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
5
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
6
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
7
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
8
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
9
+ #
10
+
11
+ require 'prof/ops_manager/web_app_internals/page/installation_progress'
12
+ require 'prof/ops_manager/web_app_internals/page/modal'
13
+ require 'prof/ops_manager/web_app_internals/page/tile_settings'
14
+
15
+ module Prof
16
+ class OpsManager
17
+ class WebAppInternals
18
+ module Page
19
+ class Dashboard
20
+
21
+ class ModalPresent < StandardError; end
22
+
23
+ def initialize(opts = {})
24
+ @page = opts.fetch(:page)
25
+ end
26
+
27
+ def tile(tile)
28
+ begin
29
+ page.find("#show-#{tile.name}-configure-action").click
30
+ rescue Capybara::ElementNotFound
31
+ page.visit(page.current_url)
32
+ page.find("#show-#{tile.name}-configure-action").click
33
+ end
34
+
35
+ TileSettings.new(page: page)
36
+ end
37
+
38
+ def tile_configure(target_tile, configuration)
39
+ tile(target_tile).configure(configuration)
40
+ end
41
+
42
+ def tile_configuration(target_tile)
43
+ tile_setting_page = tile(target_tile)
44
+
45
+ Hash.new.tap do |config|
46
+ tile_setting_page.setting_names.each do |setting_name|
47
+ config[setting_name] = tile_setting_page.settings_for(setting_name)
48
+ end
49
+
50
+ tile_setting_page.return_to_dashboard
51
+ end
52
+ end
53
+
54
+ def apply_setting(target_tile, field_name, field_value)
55
+ tile(target_tile).set_field_value('Resource Config', field_name, field_value).return_to_dashboard
56
+ end
57
+
58
+ def tile_configured?(target_tile)
59
+ page.find("#show-#{target_tile.name}-configure-action")['data-progress'] == '100'
60
+ rescue Capybara::ElementNotFound
61
+ false
62
+ end
63
+
64
+ def tile_uninstall(target_tile)
65
+ page.find("#show-#{target_tile.name}-configure-action ~ #open-delete-#{target_tile.name}-modal").click
66
+ modal.confirm
67
+ rescue Capybara::ElementNotFound
68
+ end
69
+
70
+ def apply_changes
71
+ check_no_modal!
72
+
73
+ page.click_link_or_button 'Apply changes'
74
+ InstallationProgress.new(page: page)
75
+ end
76
+
77
+ def pending_changes?
78
+ pending_changes.any?
79
+ end
80
+
81
+ def pending_changes
82
+ page.all('.pending-changes-list li').map(&:text)
83
+ end
84
+
85
+ private
86
+
87
+ attr_reader :page
88
+
89
+ def check_no_modal!
90
+ raise ModalPresent, "A modal was present with text: '#{modal.message}'" if modal.present?
91
+ end
92
+
93
+ def modal
94
+ Modal.new(page: page)
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,53 @@
1
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
2
+ # All rights reserved.
3
+ # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
4
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
5
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
6
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
7
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
8
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
9
+ #
10
+
11
+ module Prof
12
+ class OpsManager
13
+ class WebAppInternals
14
+ module Page
15
+ class FlashMessage
16
+ def initialize(opts = {})
17
+ @page = opts.fetch(:page)
18
+ end
19
+
20
+ def text
21
+ page.find('.flash-message:not(.in-progress)', wait: 60).text
22
+ end
23
+
24
+ def success?
25
+ !error? && page.all('.flash-message.success').any?
26
+ end
27
+
28
+ def error?
29
+ page.all('.flash-message.error').any?
30
+ end
31
+
32
+ def installation_in_progress?
33
+ page.all('.flash-message.in-progress').any?
34
+ end
35
+
36
+ def icmp_error?
37
+ return false unless error?
38
+ error = page.all('.flash-message.error').first.text
39
+ error.include? 'ignorable if ICMP is disabled'
40
+ end
41
+
42
+ def ignore_warnings
43
+ page.find('#ignore-install-action').click
44
+ end
45
+
46
+ private
47
+
48
+ attr_reader :page
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,130 @@
1
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
2
+ # All rights reserved.
3
+ # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
4
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
5
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
6
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
7
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
8
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
9
+ #
10
+
11
+ require 'prof/ops_manager/web_app_internals/page/form_error'
12
+ require 'prof/ops_manager/web_app_internals/page/flash_message'
13
+ require 'prof/ops_manager/web_app_internals/page/form_fields'
14
+ require 'prof/ops_manager/web_app_internals/page/form_field'
15
+ require 'prof/ops_manager/web_app_internals/page/select_field'
16
+ require 'prof/ops_manager/web_app_internals/page/checkbox_field'
17
+ require 'prof/ops_manager/web_app_internals/page/click_field'
18
+
19
+ module Prof
20
+ class OpsManager
21
+ class WebAppInternals
22
+ module Page
23
+ class Form
24
+ def initialize(opts = {})
25
+ @page = opts.fetch(:page)
26
+ @form_element = opts.fetch(:form_element)
27
+ end
28
+
29
+ def update(config = {}, &_block)
30
+ case config
31
+ when Array
32
+ update_list(config)
33
+ when Hash, FormFields
34
+ raise "Add button on page #{page.current_url}, maybe you should update a list?" if add_button
35
+
36
+ update_fields(config)
37
+ else
38
+ raise "Unrecognised config #{config.inspect}"
39
+ end
40
+
41
+ yield self, page if block_given?
42
+
43
+ form_element.click_on 'Save'
44
+
45
+ # raise "Failed to save, the server 500ed" if page.status_code.to_i >= 500
46
+ raise "Failed to save, no success message. #{error_message}" unless success?
47
+ end
48
+
49
+ private
50
+
51
+ attr_reader :form_element, :page
52
+
53
+ def update_list(list)
54
+ raise "No add button on page #{page.current_url}, are you sure you want to update a list?" unless add_button
55
+ clear_list
56
+
57
+ list.each do |item_config|
58
+ add_button.click
59
+
60
+ update_fields(item_config)
61
+ end
62
+ end
63
+
64
+ def clear_list
65
+ form_element.all('.with-delete-record').each(&:click)
66
+ end
67
+
68
+ def add_button
69
+ form_element.first(:link_or_button, 'Add')
70
+ end
71
+
72
+ def update_fields(config)
73
+ if(config.is_a? FormFields)
74
+ update_fields_from_form_fields(config)
75
+ else
76
+ update_fields_from_string_hash(config)
77
+ end
78
+ end
79
+
80
+ def update_fields_from_string_hash(config)
81
+ config.each do |field, value|
82
+ selector = field_to_selector(field)
83
+ input = form_element.all(selector).last
84
+
85
+ raise "Could not find element with selector #{selector}" unless input
86
+
87
+ if input.tag_name == 'select'
88
+ input.find(:option, value).select_option
89
+ else
90
+ input.set(value)
91
+ end
92
+ end
93
+ end
94
+
95
+ def update_fields_from_form_fields(config)
96
+ config.each do |field|
97
+ field.set(form_element)
98
+ end
99
+ end
100
+
101
+ def field_to_selector(field)
102
+ if field.include?('[') && field.include?(']')
103
+ "[name='#{field}']"
104
+ else
105
+ "[name$='#{field}]']"
106
+ end
107
+ end
108
+
109
+ def success?
110
+ flash_message.success?
111
+ end
112
+
113
+ def error_message
114
+ "#{flash_message.text} #{errors.join(', ')}"
115
+ end
116
+
117
+ def flash_message
118
+ FlashMessage.new(page: page)
119
+ end
120
+
121
+ def errors
122
+ form_element.all('.help-block').map do |error_element|
123
+ FormError.new(error_element: error_element)
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,43 @@
1
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
2
+ # All rights reserved.
3
+ # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
4
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
5
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
6
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
7
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
8
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
9
+ #
10
+
11
+ module Prof
12
+ class OpsManager
13
+ class WebAppInternals
14
+ module Page
15
+ class FormError
16
+ def initialize(opts = {})
17
+ @error_element = opts.fetch(:error_element)
18
+ end
19
+
20
+ def name
21
+ /[^\[]*\[([^\]]+)\]$/.match(full_name).to_a[1]
22
+ end
23
+
24
+ def error
25
+ error_element.text
26
+ end
27
+
28
+ def to_s
29
+ "#{name} #{error}"
30
+ end
31
+
32
+ private
33
+
34
+ attr_reader :error_element
35
+
36
+ def full_name
37
+ error_element.find('~ input')[:name]
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,51 @@
1
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
2
+ # All rights reserved.
3
+ # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
4
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
5
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
6
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
7
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
8
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
9
+ #
10
+
11
+ module Prof
12
+ class OpsManager
13
+ class WebAppInternals
14
+ module Page
15
+ class FormField
16
+
17
+ def initialize(name:, value:)
18
+ @name = name
19
+ @value = value
20
+ end
21
+
22
+ def set(form_element)
23
+ field = find_field(form_element)
24
+ raise "Could not find element with name #{name} and selector #{selector}" unless field
25
+ set_value(field)
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :name, :value
31
+
32
+ def find_field(form_element)
33
+ form_element.all(selector).last
34
+ end
35
+
36
+ def set_value(field)
37
+ field.set(value)
38
+ end
39
+
40
+ def selector
41
+ if name.include?('[') && name.include?(']')
42
+ "[name='#{name}']"
43
+ else
44
+ "[name$='[#{name}]']"
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,35 @@
1
+ # Copyright (c) 2014-2015 Pivotal Software, Inc.
2
+ # All rights reserved.
3
+ # THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
4
+ # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
5
+ # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
6
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
7
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
8
+ # USE OR OTHER DEALINGS IN THE SOFTWARE.
9
+ #
10
+
11
+ module Prof
12
+ class OpsManager
13
+ class WebAppInternals
14
+ module Page
15
+ class FormFields
16
+ include Enumerable
17
+
18
+ def initialize(fields)
19
+ @fields = fields
20
+ end
21
+
22
+ def each
23
+ fields.each do |field|
24
+ yield field
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :fields
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end