ops_manager_ui_drivers 0.13.0 → 0.14.0

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