ops_manager_ui_drivers 0.13.0 → 0.14.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 (24) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ops_manager_ui_drivers/page_helpers.rb +9 -1
  3. data/lib/ops_manager_ui_drivers/version.rb +1 -1
  4. data/lib/ops_manager_ui_drivers/version15/api_1_5.rb +42 -0
  5. data/lib/ops_manager_ui_drivers/version16/availability_zones.rb +54 -0
  6. data/lib/ops_manager_ui_drivers/version16/available_products.rb +24 -0
  7. data/lib/ops_manager_ui_drivers/version16/iaas_configuration.rb +28 -0
  8. data/lib/ops_manager_ui_drivers/version16/job_availability_zone_mapping_helper.rb +70 -0
  9. data/lib/ops_manager_ui_drivers/version16/job_network_mapping_helper.rb +47 -0
  10. data/lib/ops_manager_ui_drivers/version16/job_status_helper.rb +17 -0
  11. data/lib/ops_manager_ui_drivers/version16/networks.rb +55 -0
  12. data/lib/ops_manager_ui_drivers/version16/ops_manager_director.rb +190 -0
  13. data/lib/ops_manager_ui_drivers/version16/product_availability_zones.rb +38 -0
  14. data/lib/ops_manager_ui_drivers/version16/product_configuration.rb +34 -0
  15. data/lib/ops_manager_ui_drivers/version16/product_dashboard.rb +177 -0
  16. data/lib/ops_manager_ui_drivers/version16/product_form.rb +61 -0
  17. data/lib/ops_manager_ui_drivers/version16/product_logs.rb +38 -0
  18. data/lib/ops_manager_ui_drivers/version16/product_resource_configuration.rb +69 -0
  19. data/lib/ops_manager_ui_drivers/version16/product_status_helper.rb +64 -0
  20. data/lib/ops_manager_ui_drivers/version16/settings.rb +118 -0
  21. data/lib/ops_manager_ui_drivers/version16/setup.rb +44 -0
  22. data/lib/ops_manager_ui_drivers/version16/state_change_progress.rb +43 -0
  23. data/lib/ops_manager_ui_drivers/version16/web_ui.rb +110 -0
  24. metadata +23 -3
@@ -0,0 +1,177 @@
1
+ module OpsManagerUiDrivers
2
+ module Version16
3
+ class ProductDashboard
4
+ def initialize(browser:)
5
+ @browser = browser
6
+ @allowed_ignorable_errors = []
7
+ end
8
+
9
+ def apply_updates
10
+ open_dashboard
11
+ browser.click_on 'install-action'
12
+ fail 'Install failed verification' if nonignorable_verification_failed?
13
+ allow_cpu_verification_errors
14
+ allow_privilege_verification_errors
15
+ allow_icmp_verification_errors #this is only for AWS; consider moving out
16
+
17
+ ignore_allowable_errors
18
+ assert_installation_started
19
+ end
20
+
21
+ def import_installation_file(file_path)
22
+ open_dashboard
23
+ browser.click_on 'toggle-installation-dropdown-action'
24
+ browser.click_on 'show-settings'
25
+ browser.click_on 'close-warning'
26
+ browser.attach_file 'import[file]', file_path
27
+ browser.click_on 'import-settings'
28
+ browser.wait { browser.has_text?('Successfully imported installation.') }
29
+ end
30
+
31
+ def upgrade_microbosh
32
+ open_dashboard
33
+ browser.find('p', text: 'Ops Manager Director').trigger(:mouseover)
34
+ browser.click_on 'upgrade-microbosh'
35
+ end
36
+
37
+ def delete_product(product_name)
38
+ open_dashboard
39
+ browser.click_on "open-delete-#{product_name}-modal"
40
+ wait_for_modal_css_transition_to_complete
41
+ browser.click_on "delete-#{product_name}-action"
42
+ end
43
+
44
+ def import_product_from(full_path)
45
+ open_dashboard
46
+ browser.attach_file('component_add[file]', full_path, {visible: false})
47
+ end
48
+
49
+ def product_available?(product_name, product_version)
50
+ open_dashboard
51
+ browser.all("li.#{product_name} input#component_version[value='#{product_version}']", {visible: false}).any?
52
+ end
53
+
54
+ def upgrade_product(product_name)
55
+ open_dashboard
56
+ browser.find(".product.#{product_name} p").trigger(:mouseover)
57
+ browser.click_on "upgrade-#{product_name}"
58
+ expect_no_flash_errors
59
+ end
60
+
61
+ def version_for_product(product_name)
62
+ open_dashboard
63
+ browser.find("#show-#{product_name}-configure-action .version").text
64
+ end
65
+
66
+ def delete_whole_installation
67
+ open_dashboard
68
+ browser.click_on 'toggle-installation-dropdown-action'
69
+ browser.click_on 'show-delete-installation-modal-action'
70
+ wait_for_modal_css_transition_to_complete
71
+ browser.click_on 'delete-installation-action'
72
+ apply_updates
73
+ end
74
+
75
+ def wait_for_installation_to_be_deleted
76
+ browser.poll_up_to_mins(10) do
77
+ open_dashboard
78
+ assert_install_action_disabled
79
+ end
80
+ end
81
+
82
+ def delete_installation_available?
83
+ open_dashboard
84
+ browser.click_on 'toggle-installation-dropdown-action'
85
+ browser.all('#show-delete-installation-modal-action').any?
86
+ end
87
+
88
+ def deletion_in_progress?
89
+ open_dashboard
90
+ browser.all('#delete-in-progress-marker').any?
91
+ end
92
+
93
+ def reset_state(ops_manager)
94
+ revert_pending_changes if revert_available?
95
+ if delete_installation_available?
96
+ delete_whole_installation
97
+ browser.poll_up_to_mins(15) do
98
+ browser.expect(ops_manager.state_change_progress).to browser.be_state_change_success
99
+ end
100
+ end
101
+ end
102
+
103
+ private
104
+
105
+ attr_reader :browser
106
+
107
+ def assert_install_action_disabled
108
+ browser.expect(browser.page).to browser.have_css('#install-action.disabled')
109
+ end
110
+
111
+ def assert_installation_started
112
+ browser.expect(browser.page).to browser.have_text('Applying Changes')
113
+ end
114
+
115
+ def nonignorable_verification_failed?
116
+ browser.all('.flash-message.error').any? && browser.all('#ignore-install-action').empty?
117
+ end
118
+
119
+ def allow_cpu_verification_errors
120
+ return if @allowed_ignorable_errors.include?(/Installation requires \d+ CPU cores/)
121
+
122
+ @allowed_ignorable_errors << /Installation requires \d+ CPU cores/
123
+ end
124
+
125
+ def allow_privilege_verification_errors
126
+ return if @allowed_ignorable_errors.include?(/required privileges/i)
127
+
128
+ @allowed_ignorable_errors << /required privileges/i
129
+ end
130
+
131
+ def allow_icmp_verification_errors
132
+ return if @allowed_ignorable_errors.include?(/ignorable if ICMP is disabled/i)
133
+
134
+ @allowed_ignorable_errors << /ignorable if ICMP is disabled/i
135
+ end
136
+
137
+ def ignore_allowable_errors
138
+ flash_errors = browser.all('.flash-message.error')
139
+
140
+ if flash_errors.any?
141
+ unexpected_errors = flash_errors.reject do |error|
142
+ @allowed_ignorable_errors.select do |expected_error|
143
+ error.text =~ expected_error
144
+ end.any?
145
+ end
146
+
147
+ browser.click_on 'ignore-install-action' if unexpected_errors.empty?
148
+ end
149
+ end
150
+
151
+ def expect_no_flash_errors
152
+ if (flash_error = browser.all('.flash-message.error').first)
153
+ fail flash_error.text
154
+ end
155
+ end
156
+
157
+ def wait_for_modal_css_transition_to_complete
158
+ sleep 5 # Have to wait for the CSS shade effect
159
+ end
160
+
161
+ def open_dashboard
162
+ browser.visit '/'
163
+ end
164
+
165
+ def revert_pending_changes
166
+ open_dashboard
167
+ browser.click_on 'open-revert-installation-modal-action'
168
+ wait_for_modal_css_transition_to_complete
169
+ browser.click_on 'revert-installation-action'
170
+ end
171
+
172
+ def revert_available?
173
+ browser.all('#open-revert-installation-modal-action').any?
174
+ end
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,61 @@
1
+ module OpsManagerUiDrivers
2
+ module Version16
3
+ class ProductForm
4
+ def initialize(browser:, product_name:, form_name:)
5
+ @browser = browser
6
+ @product_name = product_name
7
+ @form_name = form_name
8
+ end
9
+
10
+ def property(property_reference)
11
+ browser.find_field("#{form_name}[#{property_reference}]")
12
+ end
13
+
14
+ def nested_property(property_reference, nested_reference)
15
+ browser.find_field("#{form_name}[#{property_reference}][#{nested_reference}]")
16
+ end
17
+
18
+ def generate_self_signed_cert(wildcard_domain)
19
+ browser.click_on 'Generate Self-Signed RSA Certificate'
20
+ browser.within '#rsa-certificate-form' do
21
+ browser.fill_in 'rsa_certificate[domains]', with: wildcard_domain
22
+ browser.click_on 'save-rsa-certificate-action'
23
+ end
24
+ end
25
+
26
+ def fill_in_selector_property(selector_input_reference:, selector_name:, selector_value:, sub_field_answers:)
27
+ radio = browser.first(%Q(input[type="radio"][name="#{form_name}[#{selector_input_reference}][value]"][value="#{selector_value}"]))
28
+ radio.click
29
+ sub_field_answers.each do |label, value|
30
+ selector_string = "#{form_name}[#{selector_input_reference}][#{selector_name}][#{label}]"
31
+
32
+ if value[:attribute_name]
33
+ selector_string += "[#{value[:attribute_name]}]"
34
+ end
35
+
36
+ browser.find_field(selector_string).set(value[:attribute_value])
37
+ end
38
+ end
39
+
40
+ def save_form(validate: true)
41
+ browser.click_on 'Save'
42
+
43
+ fail('unexpected failure') unless browser.has_css?('.flash-message')
44
+
45
+ if validate
46
+ fail(browser.find('.flash-message.error').text) unless browser.has_css?('.flash-message.success')
47
+ end
48
+ end
49
+
50
+ def open_form
51
+ browser.visit '/'
52
+ browser.click_on "show-#{product_name}-configure-action"
53
+ browser.click_on "show-#{form_name}-action"
54
+ end
55
+
56
+ private
57
+
58
+ attr_reader :browser, :product_name, :form_name
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,38 @@
1
+ require 'date'
2
+
3
+ module OpsManagerUiDrivers
4
+ module Version16
5
+ class ProductLogs
6
+ def initialize(browser:, product_name:)
7
+ @browser = browser
8
+ @product_name = product_name
9
+ end
10
+
11
+ def request_job_logs(job_name)
12
+ browser.visit('/')
13
+ browser.click_on("show-#{product_name}-configure-action")
14
+ browser.click_on('show-status-action')
15
+ browser.find(%Q(a[id^="download-#{job_name}-"][id$="-0-log-action"])).click
16
+ end
17
+
18
+ def most_recent_log_creation_time
19
+ browser.visit('/')
20
+ browser.click_on("show-#{product_name}-configure-action")
21
+ browser.click_on('show-logs-action')
22
+
23
+ log_row = browser.all('#downloaded_logs tr').
24
+ select { |e| e.find(%Q(a[href^="/products/#{product_name}"])) }.
25
+ last
26
+
27
+ return unless log_row
28
+
29
+ date_string = log_row.all('td').last.text
30
+ DateTime.parse(date_string)
31
+ end
32
+
33
+ private
34
+
35
+ attr_reader :product_name, :browser
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,69 @@
1
+ module OpsManagerUiDrivers
2
+ module Version16
3
+ class ProductResourceConfiguration
4
+ attr_reader :product_name
5
+
6
+ def initialize(browser:, product_name:)
7
+ @browser = browser
8
+ @product_name = product_name
9
+ end
10
+
11
+ def set_instances_for_job(job_name, instance_count)
12
+ open_form
13
+ browser.find_field("product_resources_form[#{job_name}][instances][value]").set(instance_count)
14
+ save_form
15
+ end
16
+
17
+ def set_instance_type_for_job(job_name, instance_type)
18
+ open_form
19
+ browser.
20
+ find("select[name='product_resources_form[#{job_name}][instance_type_id]']").
21
+ find("option[value='#{instance_type}']").
22
+ select_option
23
+ save_form
24
+ end
25
+
26
+ def set_elb_names_for_job(job_name, comma_delimited_elb_names)
27
+ open_form
28
+ browser.find_field("product_resources_form[#{job_name}][elb_names]").set(comma_delimited_elb_names)
29
+ save_form
30
+ end
31
+
32
+ def set_floating_ips_for_job(job_name, comma_delimited_floating_ips)
33
+ open_form
34
+ browser.find_field("product_resources_form[#{job_name}][floating_ips]").set(comma_delimited_floating_ips)
35
+ save_form
36
+ end
37
+
38
+ def set_resources_for_jobs(resources_by_job, validate: true)
39
+ open_form
40
+ resources_by_job.each do |job, resources|
41
+ resources.each do |resource_or_instance, value|
42
+ browser.fill_in("product_resources_form[#{job}][#{resource_or_instance}][value]", with: value)
43
+ end
44
+ end
45
+ save_form(validate: validate)
46
+ end
47
+
48
+ private
49
+
50
+ attr_reader :browser
51
+
52
+ def open_form
53
+ browser.visit '/'
54
+ browser.click_on "show-#{product_name}-configure-action"
55
+ browser.click_on "show-#{product_name}-resource-sizes-action"
56
+ end
57
+
58
+ def save_form(validate: true)
59
+ browser.click_on 'Save'
60
+
61
+ fail('unexpected failure') unless browser.has_css?('.flash-message')
62
+
63
+ if validate
64
+ fail(browser.find('.flash-message.error').text) unless browser.has_css?('.flash-message.success')
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,64 @@
1
+ module OpsManagerUiDrivers
2
+ module Version16
3
+ class ProductStatusHelper
4
+ def initialize(product_name:, browser:)
5
+ @product_name = product_name
6
+ @browser = browser
7
+ end
8
+
9
+ def job_status(job_name)
10
+ open_page
11
+
12
+ wait_for_loading_indicator_to_disappear
13
+
14
+ browser.within "##{product_name}-status" do
15
+ job_row = browser.find(:xpath, ".//tr[@data-ip-name = '#{job_name}']")
16
+
17
+ Version16::JobStatusHelper.from_job_row(job_row)
18
+ end
19
+ end
20
+
21
+ def job_status_in_az(job_name, az_guid)
22
+ open_page
23
+
24
+ wait_for_loading_indicator_to_disappear
25
+
26
+ browser.within "##{product_name}-#{az_guid}-status-table" do
27
+ job_row = browser.find(:xpath, ".//tr[@data-ip-name = '#{job_name}']")
28
+
29
+ Version16::JobStatusHelper.from_job_row(job_row)
30
+ end
31
+ end
32
+
33
+ def resource_pool_for_job_in_az(job_name, az_guid, vsphere_connection)
34
+ job_status = job_status_in_az("#{job_name}-partition-#{az_guid}", az_guid)
35
+
36
+ job_ip = job_status.ips.fetch(0)
37
+
38
+ vm = vsphere_connection.searchIndex.FindByIp(ip: job_ip, vmSearch: true)
39
+ vm.resourcePool.name
40
+ end
41
+
42
+ private
43
+
44
+ attr_reader :browser, :product_name
45
+
46
+ def open_page
47
+ browser.visit '/'
48
+
49
+ browser.click_on "show-#{dasherized_product_name}-configure-action"
50
+ browser.click_on 'show-status-action'
51
+ end
52
+
53
+ def wait_for_loading_indicator_to_disappear
54
+ Capybara.using_wait_time 10 do
55
+ browser.all('.status-loading', count: 0) # blocks until there are no spinners
56
+ end
57
+ end
58
+
59
+ def dasherized_product_name
60
+ product_name.to_s.gsub(/[_]/, '-')
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,118 @@
1
+ module OpsManagerUiDrivers
2
+ module Version16
3
+ module Settings
4
+ def self.for(test_settings)
5
+ settings_class = [Vcloud, Vsphere, AWS, OpenStack].find do |klass|
6
+ klass.works_with?(test_settings.iaas_type)
7
+ end or raise("Unsupported IaaS: #{test_settings.iaas_type.inspect}")
8
+ settings_class.new(test_settings)
9
+ end
10
+
11
+ class Vcloud
12
+ def self.works_with?(iaas_type)
13
+ iaas_type == 'vcloud'
14
+ end
15
+
16
+ def initialize(test_settings)
17
+ @test_settings = test_settings
18
+ end
19
+
20
+ def fields
21
+ {
22
+ 'vcd_url' => test_settings.ops_manager.vcloud.creds.url,
23
+ 'organization' => test_settings.ops_manager.vcloud.creds.organization,
24
+ 'vcd_username' => test_settings.ops_manager.vcloud.creds.user,
25
+ 'vcd_password' => test_settings.ops_manager.vcloud.creds.password,
26
+ 'datacenter' => test_settings.ops_manager.vcloud.vdc.name,
27
+ 'storage_profile' => test_settings.ops_manager.vcloud.vdc.storage_profile,
28
+ 'catalog_name' => test_settings.ops_manager.vcloud.vdc.catalog_name,
29
+ }
30
+ end
31
+
32
+ private
33
+
34
+ attr_reader :test_settings
35
+ end
36
+
37
+ class Vsphere
38
+ def self.works_with?(iaas_type)
39
+ iaas_type == 'vsphere'
40
+ end
41
+
42
+ def initialize(test_settings)
43
+ @test_settings = test_settings
44
+ end
45
+
46
+ def fields
47
+ {
48
+ 'vcenter_ip' => test_settings.ops_manager.vcenter.creds.ip,
49
+ 'vcenter_username' => test_settings.ops_manager.vcenter.creds.username,
50
+ 'vcenter_password' => test_settings.ops_manager.vcenter.creds.password,
51
+ 'datacenter' => test_settings.ops_manager.vcenter.datacenter,
52
+ 'datastores_string' => test_settings.ops_manager.vcenter.datastore,
53
+ 'microbosh_vm_folder' => test_settings.ops_manager.vcenter.microbosh_vm_folder,
54
+ 'microbosh_template_folder' => test_settings.ops_manager.vcenter.microbosh_template_folder,
55
+ 'microbosh_disk_path' => test_settings.ops_manager.vcenter.microbosh_disk_path,
56
+ }
57
+ end
58
+
59
+ private
60
+
61
+ attr_reader :test_settings
62
+ end
63
+
64
+ class AWS
65
+ def self.works_with?(iaas_type)
66
+ iaas_type == 'aws'
67
+ end
68
+
69
+ def initialize(test_settings)
70
+ @test_settings = test_settings
71
+ end
72
+
73
+ def fields
74
+ {
75
+ 'access_key_id' => test_settings.ops_manager.aws.aws_access_key,
76
+ 'secret_access_key' => test_settings.ops_manager.aws.aws_secret_key,
77
+ 'vpc_id' => test_settings.ops_manager.aws.vpc_id,
78
+ 'security_group' => test_settings.ops_manager.aws.security_group,
79
+ 'key_pair_name' => test_settings.ops_manager.aws.key_pair_name,
80
+ 'ssh_private_key' => test_settings.ops_manager.aws.ssh_key,
81
+ 'region' => test_settings.ops_manager.aws.region,
82
+ }
83
+ end
84
+
85
+ private
86
+
87
+ attr_reader :test_settings
88
+ end
89
+
90
+ class OpenStack
91
+ def self.works_with?(iaas_type)
92
+ iaas_type == 'openstack'
93
+ end
94
+
95
+ def initialize(test_settings)
96
+ @test_settings = test_settings
97
+ end
98
+
99
+ def fields
100
+ {
101
+ 'identity_endpoint' => test_settings.ops_manager.openstack.identity_endpoint,
102
+ 'username' => test_settings.ops_manager.openstack.username,
103
+ 'password' => test_settings.ops_manager.openstack.password,
104
+ 'tenant' => test_settings.ops_manager.openstack.tenant,
105
+ 'security_group' => test_settings.ops_manager.openstack.security_group_name,
106
+ 'key_pair_name' => test_settings.ops_manager.openstack.key_pair_name,
107
+ 'ssh_private_key' => test_settings.ops_manager.openstack.ssh_private_key,
108
+ 'region' => test_settings.ops_manager.openstack.region,
109
+ }
110
+ end
111
+
112
+ private
113
+
114
+ attr_reader :test_settings
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,44 @@
1
+ module OpsManagerUiDrivers
2
+ module Version16
3
+ class Setup
4
+ def initialize(browser: nil)
5
+ @browser = browser
6
+ end
7
+
8
+ def setup_and_login(user:, password:)
9
+ browser.visit '/setup'
10
+ browser.fill_in 'user[user_name]', with: user
11
+ browser.fill_in 'user[password]', with: password
12
+ browser.fill_in 'user[password_confirmation]', with: password
13
+ browser.check 'user_eula_accepted'
14
+ browser.click_on 'create-user-action'
15
+ end
16
+
17
+ def login(user: nil, password: nil)
18
+ browser.visit '/login'
19
+ browser.fill_in 'login[user_name]', with: user
20
+ browser.fill_in 'login[password]', with: password
21
+ browser.click_on 'login-action'
22
+
23
+ unless browser.first('#main-page-marker')
24
+ fail RuntimeError.new("failed to log in as #{user}/#{password}.")
25
+ end
26
+ end
27
+
28
+ def setup_or_login(user:, password:)
29
+ browser.visit '/'
30
+
31
+ if browser.current_path == '/setup'
32
+ setup_and_login(user: user, password: password)
33
+ elsif browser.current_path == '/login'
34
+ login(user: user, password: password)
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :browser
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,43 @@
1
+ module OpsManagerUiDrivers
2
+ module Version16
3
+ class StateChangeProgress
4
+ def initialize(browser:)
5
+ @browser = browser
6
+ end
7
+
8
+ def state_change_success?
9
+ open_install_progress
10
+ browser.all('#install-success-modal').any?
11
+ end
12
+
13
+ def errand_ran?(errand_name)
14
+ open_install_progress
15
+ browser.find('#install-output .output', visible: false).text(:all).
16
+ include?("Errand `#{errand_name}' completed successfully (exit code 0)")
17
+ end
18
+
19
+ def errand_ran_with_text?(errand_name)
20
+ {
21
+ errand_ran: errand_ran?(errand_name),
22
+ output: browser.find('#install-output .output', {visible: false}).text(:all),
23
+ }
24
+ end
25
+
26
+ private
27
+
28
+ def open_install_progress
29
+ browser.visit '/install' unless install_progress_open?
30
+ browser.fail_early('Install probably aborted immediately') unless install_progress_open?
31
+ browser.fail_early('Install failed') if browser.all('#install-failure-modal').any?
32
+ end
33
+
34
+ def install_progress_open?
35
+ browser.current_path =~ %r(^/+install)
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :browser
41
+ end
42
+ end
43
+ end