2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2021 Nordix Foundation
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 * SPDX-License-Identifier: Apache-2.0
17 * ============LICENSE_END=========================================================
20 package org.onap.sdc.frontend.ci.tests.pages;
22 import static org.junit.jupiter.api.Assertions.assertTrue;
24 import com.aventstack.extentreports.Status;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.List;
29 import java.util.concurrent.atomic.AtomicInteger;
30 import java.util.stream.Collectors;
31 import lombok.AllArgsConstructor;
33 import org.onap.sdc.frontend.ci.tests.execute.setup.ExtentTestActions;
34 import org.onap.sdc.frontend.ci.tests.utilities.LoaderHelper;
35 import org.onap.sdc.frontend.ci.tests.utilities.NotificationComponent;
36 import org.onap.sdc.frontend.ci.tests.utilities.NotificationComponent.NotificationType;
37 import org.openqa.selenium.By;
38 import org.openqa.selenium.WebDriver;
39 import org.openqa.selenium.WebElement;
40 import org.openqa.selenium.support.ui.Select;
43 * Handles the Resource Properties Assignment Properties Tab UI actions
45 public class ResourcePropertiesAssignmentTab extends AbstractPageObject {
47 private WebElement wrappingElement;
48 private LoaderHelper loaderHelper;
49 private NotificationComponent notificationComponent;
51 public ResourcePropertiesAssignmentTab(final WebDriver webDriver) {
53 notificationComponent = new NotificationComponent(webDriver);
54 loaderHelper = new LoaderHelper(webDriver);
58 public void isLoaded() {
59 wrappingElement = waitForElementVisibility(XpathSelector.MAIN_DIV.getXpath());
60 waitForElementVisibility(XpathSelector.PROPERTIES_TAB.getXpath());
61 isPropertiesTableLoaded();
65 * Waits for the table of properties to load
67 private void isPropertiesTableLoaded() {
68 waitForElementVisibility(By.xpath(XpathSelector.PROPERTIES_TABLE.getXpath()), 5);
69 waitForElementInvisibility(By.xpath(XpathSelector.NO_DATA_MESSAGE.getXpath()), 5);
73 * Gets the software_version property values.
75 * @return the list of software versions found
77 public List<String> getSoftwareVersionProperty() {
78 isPropertiesTableLoaded();
79 final By swVersionCheckboxLocator = By.xpath(XpathSelector.SOFTWARE_VERSION_PROPERTY_CHECKBOX.getXpath());
80 waitForElementVisibility(swVersionCheckboxLocator, 5);
82 final List<String> softwareVersionList = new ArrayList<>();
83 final List<WebElement> elements = wrappingElement.findElements(By.xpath(XpathSelector.SOFTWARE_VERSION_INPUT.getXpath()));
84 for (final WebElement element : elements) {
85 softwareVersionList.add(element.getAttribute("value"));
88 return softwareVersionList;
92 * Sets a property value
93 * @param propertyName the property name
94 * @param value the property value
96 public void setPropertyValue(final String propertyName, final Object value) {
101 if (value instanceof String) {
102 setStringPropertyValue(propertyName, (String) value);
106 if (value instanceof Integer) {
107 setStringPropertyValue(propertyName, ((Integer) value).toString());
111 if (value instanceof Boolean) {
112 setBooleanPropertyValue(propertyName);
116 if (value instanceof Map) {
117 setComplexPropertyValue(propertyName, value);
121 if (value instanceof List) {
122 setComplexPropertyValue(propertyName, value);
126 throw new UnsupportedOperationException("Cannot set property value of type: " + value.getClass());
130 * Gets the property value. Only properties with a text value like string, float, integer or a list of string, float, integer are supported.
132 * @param propertyName the property name
133 * @return the value of the given property
135 public Object getPropertyValue(final String propertyName) {
136 isPropertiesTableLoaded();
137 final Map<String, String> propertyNamesAndTypes = getPropertyNamesAndTypes();
138 final String propertyType = propertyNamesAndTypes.get(propertyName);
139 final WebElement propertyRow = getPropertyRow(propertyName);
140 switch (propertyType) {
144 final WebElement propertyInput = propertyRow.findElement(By.xpath(XpathSelector.INPUT_PROPERTY.getXpath(propertyName)));
145 return propertyInput.getAttribute("value");
147 final List<WebElement> elements = propertyRow
148 .findElements(By.xpath(XpathSelector.INPUT_PROPERTY_LIST_STRING_TYPE_VALUE.getXpath(propertyName)));
149 return elements.stream().map(webElement -> webElement.getAttribute("value")).collect(Collectors.toList());
151 throw new UnsupportedOperationException(String.format("Retrieve value of property type %s is not yet supported", propertyType));
156 * Checks if a property exists.
157 * @param propertyName the property name
158 * @return the value of the property
160 public boolean isPropertyPresent(final String propertyName) {
161 isPropertiesTableLoaded();
163 waitForElementVisibility(By.xpath(XpathSelector.PROPERTY_CHECKBOX.getXpath(propertyName)), 5);
164 } catch (final Exception ignored) {
173 public void saveProperties() {
174 final WebElement saveBtn = waitForElementVisibility(By.xpath(XpathSelector.PROPERTY_SAVE_BTN.getXpath()));
175 assertTrue(saveBtn.isEnabled(), "Property save button should be enabled.");
177 loaderHelper.waitForLoaderInvisibility(20);
178 notificationComponent.waitForNotification(NotificationType.SUCCESS, 20);
183 * @param propertiesMap the properties map to be added
185 public void addProperties(final Map<String, String> propertiesMap) {
186 isPropertiesTableLoaded();
187 propertiesMap.forEach((propertyName, propertyType) -> {
188 final By addPropertyButtonLocator = By.xpath(XpathSelector.PROPERTY_ADD_BTN.getXpath());
189 waitForElementVisibility(addPropertyButtonLocator, 30);
190 final WebElement addPropertyRightColumn = findElement(By.xpath(XpathSelector.PROPERTY_ADD_RIGHT_COLUMN_DIV.getXpath()));
191 final WebElement propertyAddButton = addPropertyRightColumn.findElement(addPropertyButtonLocator);
192 assertTrue(propertyAddButton.isDisplayed(), "Property add button should be enabled.");
193 propertyAddButton.click();
194 createProperty(propertyName, propertyType);
195 verifyProperty(propertyName);
196 ExtentTestActions.takeScreenshot(Status.INFO, "added-property",
197 String.format("Property '%s' was created on component", propertyName));
202 * Creates a map based on property names and data types
204 public Map<String, String> getPropertyNamesAndTypes() {
205 isPropertiesTableLoaded();
206 final Map<String, String> namesAndTypes = new HashMap<>();
207 final List<WebElement> names = findElements(By.xpath(XpathSelector.PROPERTY_NAMES.getXpath()));
208 final List<WebElement> types = findElements(By.xpath(XpathSelector.PROPERTY_TYPES.getXpath()));
210 for (int i = 0;i < names.size();i++) {
211 namesAndTypes.put(names.get(i).getAttribute("innerText"), types.get(i).getAttribute("innerText"));
214 return namesAndTypes;
218 * Gets the property row element for the given propertyName
219 * @param propertyName the property name
220 * @return the property row element
222 private WebElement getPropertyRow(String propertyName) {
223 final By propertyCheckboxLocator = By.xpath(XpathSelector.PROPERTY_CHECKBOX.getXpath(propertyName));
224 final WebElement propertyCheckbox = waitForElementVisibility(propertyCheckboxLocator, 5);
225 return propertyCheckbox.findElement(By.xpath("./../../.."));
229 * Sets a String value to a TOSCA property.
230 * @param propertyName the property name
231 * @param value property value to be set
233 private void setStringPropertyValue(final String propertyName, final String value) {
237 isPropertiesTableLoaded();
238 getPropertyRow(propertyName).findElement(By.xpath(XpathSelector.INPUT_PROPERTY.getXpath(propertyName))).sendKeys(value);
242 * Sets a boolean value to a TOSCA property.
243 * @param propertyName
245 private void setBooleanPropertyValue(final String propertyName) {
246 isPropertiesTableLoaded();
247 new Select(getPropertyRow(propertyName).findElement(By.xpath(XpathSelector.SELECT_INPUT_PROPERTY.getXpath(propertyName)))).
248 selectByVisibleText("TRUE");
252 * Sets a complex property type value to a TOSCA property. It handles List and Map
253 * @param propertyName the property name
254 * @param objectValue the property complex type value
256 private void setComplexPropertyValue(final String propertyName, final Object objectValue) {
257 if (objectValue == null) {
260 isPropertiesTableLoaded();
261 final WebElement addToListLink = getPropertyRow(propertyName)
262 .findElement(By.xpath(XpathSelector.PROPERTY_ADD_VALUE_COMPLEX_TYPE.getXpath(propertyName)));
263 if (objectValue instanceof List) {
264 setValueFromList(propertyName, (List) objectValue, addToListLink);
266 if (objectValue instanceof Map) {
267 setValueFromMap(propertyName, (Map<?, ?>) objectValue, addToListLink);
272 * Sets a value to a complex (List) property type.
273 * @param propertyName the property name
274 * @param values the List of values to be added to the given property name
275 * @param addToListLink the link to add the input value
277 private void setValueFromList(final String propertyName, final List<String> values, final WebElement addToListLink) {
278 final AtomicInteger inputIndex = new AtomicInteger(0);
279 values.forEach(value -> {
280 addToListLink.click();
281 final WebElement propertyInput = addToListLink.findElement(By.xpath(XpathSelector.INPUT_PROPERTY_COMPLEX_TYPE_VALUE.getXpath(
282 String.valueOf(new StringBuilder(propertyName).append(".").append(inputIndex)))));
283 propertyInput.sendKeys(value);
284 inputIndex.getAndIncrement();
289 * Sets a value to a complex (Map) property type.
290 * @param propertyName the property name
291 * @param values the Map of values to be added to the given property name
292 * @param addToListLink the link to add the input value
294 private void setValueFromMap(final String propertyName, final Map<?, ?> values, final WebElement addToListLink) {
295 final AtomicInteger inputIndex = new AtomicInteger(0);
296 values.forEach((key, value) -> {
297 addToListLink.click();
298 WebElement propertyInput;
300 propertyInput = addToListLink.findElement(By.xpath(XpathSelector.INPUT_PROPERTY_COMPLEX_TYPE_KEY.getXpath(
301 String.valueOf(new StringBuilder(propertyName).append(".").append(inputIndex)))));
302 propertyInput.sendKeys(key.toString());
304 propertyInput = addToListLink.findElement(By.xpath(XpathSelector.INPUT_PROPERTY_COMPLEX_TYPE_VALUE.getXpath(
305 String.valueOf(new StringBuilder(propertyName).append(".").append(inputIndex)))));
306 propertyInput.sendKeys(value.toString());
307 inputIndex.getAndIncrement();
312 * Fills the creation property modal.
313 * @param propertyName the property name to be created
314 * @param propertyType the property type to be selected
316 private void createProperty(final String propertyName, final String propertyType) {
317 final AddPropertyModal addPropertyModal = new AddPropertyModal(webDriver);
318 addPropertyModal.isLoaded();
319 addPropertyModal.fillPropertyForm(propertyName, propertyType);
320 addPropertyModal.clickOnCreate();
324 * Verifies if the added property is displayed on the UI.
325 * @param propertyName the property name to be found
327 private void verifyProperty(final String propertyName) {
328 final By propertyCheckboxLocator = By.xpath(XpathSelector.PROPERTY_CHECKBOX.getXpath(propertyName));
329 final WebElement propertyCheckbox = waitForElementVisibility(propertyCheckboxLocator, 5);
330 assertTrue(propertyCheckbox.isDisplayed(), String.format("%s Property should be displayed", propertyName));
331 assertTrue(this.getPropertyNamesAndTypes().containsKey(propertyName),
332 String.format("%s Property should be listed but found %s", propertyName, this.getPropertyNamesAndTypes().toString()));
338 public void selectProperty(String propertyName){
339 isPropertyPresent(propertyName);
340 waitToBeClickable(By.xpath(ResourcePropertiesAssignmentTab.XpathSelector.PROPERTY_CHECKBOX.getXpath(propertyName))).click();
343 public void loadComponentInstanceProperties(final String instanceName){
344 waitToBeClickable(By.xpath(ResourcePropertiesAssignmentTab.XpathSelector.INSTANCE_SPAN.getXpath(instanceName))).click();
347 public void clickOnDeclareInput(final String inputName){
348 waitToBeClickable(By.xpath(ResourcePropertiesAssignmentTab.XpathSelector.DECLARE_INPUT_BTN.getXpath())).click();
349 declareInputWithSetInputName(inputName);
352 private void declareInputWithSetInputName(final String inputName) {
353 final By setInputNameLocator = By.xpath(XpathSelector.SET_INPUT_NAME_FIELD.getXpath());
354 final WebElement inputNameField = waitForElementVisibility(setInputNameLocator, 5);
355 inputNameField.sendKeys(inputName);
356 waitToBeClickable(By.xpath(XpathSelector.INPUT_NAME_SAVE_BTN.getXpath())).click();
359 public void loadCompositionTab(){
360 waitToBeClickable(By.xpath(ResourcePropertiesAssignmentTab.XpathSelector.COMPOSITION_TAB.getXpath())).click();
364 * Enum that contains identifiers and xpath expressions to elements related to the enclosing page object.
367 private enum XpathSelector {
368 MAIN_DIV("w-sdc-main-right-container", "//div[@class='%s']"),
369 PROPERTIES_TAB("//*[contains(@data-tests-id, 'Properties') and contains(@class, 'active')]"),
370 PROPERTIES_TABLE("properties-table", "//div[contains(@class,'%s')]"),
371 NO_DATA_MESSAGE("no-data", "//div[contains(@class,'%s') and text()='No data to display']"),
372 SOFTWARE_VERSION_PROPERTY_CHECKBOX("software_versions", "//checkbox[@data-tests-id='%s']"),
373 SOFTWARE_VERSION_INPUT("value-prop-software_versions", "//input[starts-with(@data-tests-id,'%s')]"),
374 PROPERTY_CHECKBOX("//checkbox[@data-tests-id='%s']"),
375 SET_INPUT_NAME_FIELD("//*[@id=\"myText\"]"),
376 PROPERTY_SAVE_BTN("properties-save-button", "//button[@data-tests-id='%s']"),
377 PROPERTY_ADD_RIGHT_COLUMN_DIV("right-column", "//div[@class='%s']"),
378 PROPERTY_ADD_BTN("add-btn", "//div[contains(@class,'%s')]"),
379 PROPERTY_ADD_VALUE_COMPLEX_TYPE("//a[contains(@data-tests-id, 'add-to-list-%s')]"),
380 INPUT_PROPERTY_COMPLEX_TYPE_KEY("//input[contains(@data-tests-id, 'value-prop-key-%s')]"),
381 INPUT_PROPERTY_COMPLEX_TYPE_VALUE("//input[contains(@data-tests-id, 'value-prop-%s')]"),
382 INPUT_PROPERTY_LIST_STRING_TYPE_VALUE("//input[starts-with(@data-tests-id, 'value-prop-%s')]"),
383 INPUT_PROPERTY("//input[@data-tests-id='value-prop-%s']"),
384 SELECT_INPUT_PROPERTY("//select[@data-tests-id='value-prop-%s']"),
385 PROPERTY_TYPES("//*[contains(@data-tests-id, 'propertyType')]"),
386 PROPERTY_NAMES("//*[contains(@data-tests-id, 'propertyName')]"),
387 DECLARE_INPUT_BTN("declare-button declare-input", "//button[@data-tests-id='%s']"),
388 INPUT_NAME_SAVE_BTN("//button[@data-tests-id='Save']"),
389 COMPOSITION_TAB("Composition", "//div[contains(@class,'tab') and contains(text(), '%s')]"),
390 INSTANCE_SPAN("//span[@data-tests-id='%s']");
394 private final String xpathFormat;
396 XpathSelector(final String xpathFormat) {
397 this.xpathFormat = xpathFormat;
400 public String getXpath() {
401 return String.format(xpathFormat, id);
404 public String getXpath(final Object... xpathParams) {
405 return String.format(xpathFormat, xpathParams);