32a20dd138efac9e0e10dd09f4dbfec75eb051ca
[sdc.git] /
1 /*
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
8  *
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.
15  *
16  *  SPDX-License-Identifier: Apache-2.0
17  *  ============LICENSE_END=========================================================
18  */
19
20 package org.onap.sdc.frontend.ci.tests.pages;
21
22 import static org.junit.jupiter.api.Assertions.assertTrue;
23
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.concurrent.atomic.AtomicInteger;
29
30 import org.onap.sdc.frontend.ci.tests.execute.setup.ExtentTestActions;
31 import org.onap.sdc.frontend.ci.tests.utilities.LoaderHelper;
32 import org.onap.sdc.frontend.ci.tests.utilities.NotificationComponent;
33 import org.onap.sdc.frontend.ci.tests.utilities.NotificationComponent.NotificationType;
34 import org.openqa.selenium.By;
35 import org.openqa.selenium.WebDriver;
36 import org.openqa.selenium.WebElement;
37 import org.openqa.selenium.support.ui.Select;
38
39 import com.aventstack.extentreports.Status;
40
41 import lombok.AllArgsConstructor;
42 import lombok.Getter;
43
44 /**
45  * Handles the Resource Properties Assignment Properties Tab UI actions
46  */
47 public class ResourcePropertiesAssignmentTab extends AbstractPageObject {
48
49     private WebElement wrappingElement;
50     private LoaderHelper loaderHelper;
51     private NotificationComponent notificationComponent;
52
53     public ResourcePropertiesAssignmentTab(final WebDriver webDriver) {
54         super(webDriver);
55         notificationComponent = new NotificationComponent(webDriver);
56         loaderHelper = new LoaderHelper(webDriver);
57     }
58
59     @Override
60     public void isLoaded() {
61        wrappingElement = waitForElementVisibility(XpathSelector.MAIN_DIV.getXpath());
62        waitForElementVisibility(XpathSelector.PROPERTIES_TAB.getXpath());
63        isPropertiesTableLoaded();
64     }
65
66     /**
67      * Waits for the table of properties to load
68      */
69     private void isPropertiesTableLoaded() {
70         waitForElementVisibility(By.xpath(XpathSelector.PROPERTIES_TABLE.getXpath()), 5);
71         waitForElementInvisibility(By.xpath(XpathSelector.NO_DATA_MESSAGE.getXpath()), 5);
72     }
73
74     /**
75      * Gets the software_version property values.
76      *
77      * @return the list of software versions found
78      */
79     public List<String> getSoftwareVersionProperty() {
80         isPropertiesTableLoaded();
81         final By swVersionCheckboxLocator = By.xpath(XpathSelector.SOFTWARE_VERSION_PROPERTY_CHECKBOX.getXpath());
82         waitForElementVisibility(swVersionCheckboxLocator, 5);
83
84         final List<String> softwareVersionList = new ArrayList<>();
85         final List<WebElement> elements = wrappingElement.findElements(By.xpath(XpathSelector.SOFTWARE_VERSION_INPUT.getXpath()));
86         for (final WebElement element : elements) {
87             softwareVersionList.add(element.getAttribute("value"));
88         }
89
90         return softwareVersionList;
91     }
92
93     /**
94      * Sets a property value
95      * @param propertyName the property name
96      * @param value the property value
97      */
98     public void setPropertyValue(final String propertyName, final Object value) {
99         if (value == null) {
100             return;
101         }
102
103         if (value instanceof String) {
104             setStringPropertyValue(propertyName, (String) value);
105             return;
106         }
107
108         if (value instanceof Integer) {
109             setStringPropertyValue(propertyName, ((Integer) value).toString());
110             return;
111         }
112
113         if (value instanceof Boolean) {
114             setBooleanPropertyValue(propertyName);
115             return;
116         }
117
118         if (value instanceof Map) {
119             setComplexPropertyValue(propertyName, value);
120             return;
121         }
122
123         if (value instanceof List) {
124             setComplexPropertyValue(propertyName, value);
125             return;
126         }
127
128         throw new UnsupportedOperationException("Cannot set property value of type: " + value.getClass());
129     }
130
131     /**
132      * Checks if a property exists.
133      * @param propertyName the property name
134      * @return the value of the property
135      */
136     public boolean isPropertyPresent(final String propertyName) {
137         isPropertiesTableLoaded();
138         try {
139             waitForElementVisibility(By.xpath(XpathSelector.PROPERTY_CHECKBOX.getXpath(propertyName)), 5);
140         } catch (final Exception ignored) {
141             return false;
142         }
143         return true;
144     }
145
146     /**
147      * Saves a property
148      */
149     public void saveProperties() {
150         final WebElement saveBtn = waitForElementVisibility(By.xpath(XpathSelector.PROPERTY_SAVE_BTN.getXpath()));
151         assertTrue(saveBtn.isEnabled(), "Property save button should be enabled.");
152         saveBtn.click();
153         loaderHelper.waitForLoaderInvisibility(20);
154         notificationComponent.waitForNotification(NotificationType.SUCCESS, 20);
155     }
156
157     /**
158      * Adds a property
159      * @param propertiesMap the properties map to be added
160      */
161     public void addProperties(final Map<String, String> propertiesMap) {
162         isPropertiesTableLoaded();
163         propertiesMap.forEach((propertyName, propertyType) -> {
164             final By addPropertyButtonLocator = By.xpath(XpathSelector.PROPERTY_ADD_BTN.getXpath());
165             waitForElementVisibility(addPropertyButtonLocator, 30);
166             final WebElement addPropertyRightColumn = findElement(By.xpath(XpathSelector.PROPERTY_ADD_RIGHT_COLUMN_DIV.getXpath()));
167             final WebElement propertyAddButton = addPropertyRightColumn.findElement(addPropertyButtonLocator);
168             assertTrue(propertyAddButton.isDisplayed(), "Property add button should be enabled.");
169             propertyAddButton.click();
170             createProperty(propertyName, propertyType);
171             verifyProperty(propertyName);
172             ExtentTestActions.takeScreenshot(Status.INFO, "added-property",
173                 String.format("Property '%s' was created on component", propertyName));
174         });
175     }
176
177     /**
178      * Creates a map based on property names and data types
179      */
180     public Map<String, String> getPropertyNamesAndTypes() {
181         isPropertiesTableLoaded();
182         final Map<String, String> namesAndTypes = new HashMap<>();
183         final List<WebElement> names = findElements(By.xpath(XpathSelector.PROPERTY_NAMES.getXpath()));
184         final List<WebElement> types = findElements(By.xpath(XpathSelector.PROPERTY_TYPES.getXpath()));
185
186         for (int i = 0;i < names.size();i++) {
187             namesAndTypes.put(names.get(i).getAttribute("innerText"), types.get(i).getAttribute("innerText"));
188         }
189
190         return namesAndTypes;
191     }
192
193     /**
194      * Gets the property row element for the given propertyName
195      * @param propertyName the property name
196      * @return the property row element
197      */
198     private WebElement getPropertyRow(String propertyName) {
199         final By propertyCheckboxLocator = By.xpath(XpathSelector.PROPERTY_CHECKBOX.getXpath(propertyName));
200         final WebElement propertyCheckbox = waitForElementVisibility(propertyCheckboxLocator, 5);
201         return propertyCheckbox.findElement(By.xpath("./../../.."));
202     }
203
204     /**
205      * Sets a String value to a TOSCA property.
206      * @param propertyName the property name
207      * @param value property value to be set
208      */
209     private void setStringPropertyValue(final String propertyName, final String value) {
210         if (value == null) {
211             return;
212         }
213         isPropertiesTableLoaded();
214         getPropertyRow(propertyName).findElement(By.xpath(XpathSelector.INPUT_PROPERTY.getXpath(propertyName))).sendKeys(value);
215     }
216
217     /**
218      * Sets a boolean value to a TOSCA property.
219      * @param propertyName
220      */
221     private void setBooleanPropertyValue(final String propertyName) {
222         isPropertiesTableLoaded();
223         new Select(getPropertyRow(propertyName).findElement(By.xpath(XpathSelector.SELECT_INPUT_PROPERTY.getXpath(propertyName)))).
224             selectByVisibleText("TRUE");
225     }
226
227     /**
228      * Sets a complex property  type value to a TOSCA property. It handles List and Map
229      * @param propertyName the property name
230      * @param objectValue the property complex type value
231      */
232     private void setComplexPropertyValue(final String propertyName, final Object objectValue) {
233         if (objectValue == null) {
234             return;
235         }
236         isPropertiesTableLoaded();
237         final WebElement addToListLink = getPropertyRow(propertyName)
238             .findElement(By.xpath(XpathSelector.PROPERTY_ADD_VALUE_COMPLEX_TYPE.getXpath(propertyName)));
239         if (objectValue instanceof List) {
240             setValueFromList(propertyName, (List) objectValue, addToListLink);
241         }
242         if (objectValue instanceof Map) {
243             setValueFromMap(propertyName, (Map<?, ?>) objectValue, addToListLink);
244         }
245     }
246
247     /**
248      * Sets a value to a complex (List) property type.
249      * @param propertyName the property name
250      * @param values the List of values to be added to the given property name
251      * @param addToListLink the link to add the input value
252      */
253     private void setValueFromList(final String propertyName, final List<String> values, final WebElement addToListLink) {
254         final AtomicInteger inputIndex = new AtomicInteger(0);
255         values.forEach(value -> {
256             addToListLink.click();
257             final WebElement propertyInput = addToListLink.findElement(By.xpath(XpathSelector.INPUT_PROPERTY_COMPLEX_TYPE_VALUE.getXpath(
258                 String.valueOf(new StringBuilder(propertyName).append(".").append(inputIndex)))));
259             propertyInput.sendKeys(value);
260             inputIndex.getAndIncrement();
261         });
262     }
263
264     /**
265      * Sets a value to a complex (Map) property type.
266      * @param propertyName the property name
267      * @param values the Map of values to be added to the given property name
268      * @param addToListLink the link to add the input value
269      */
270     private void setValueFromMap(final String propertyName, final Map<?, ?> values, final WebElement addToListLink) {
271         final AtomicInteger inputIndex = new AtomicInteger(0);
272         values.forEach((key, value) -> {
273             addToListLink.click();
274             WebElement propertyInput;
275             // Add Key
276             propertyInput = addToListLink.findElement(By.xpath(XpathSelector.INPUT_PROPERTY_COMPLEX_TYPE_KEY.getXpath(
277                 String.valueOf(new StringBuilder(propertyName).append(".").append(inputIndex)))));
278             propertyInput.sendKeys(key.toString());
279             // Add Value
280             propertyInput = addToListLink.findElement(By.xpath(XpathSelector.INPUT_PROPERTY_COMPLEX_TYPE_VALUE.getXpath(
281                 String.valueOf(new StringBuilder(propertyName).append(".").append(inputIndex)))));
282             propertyInput.sendKeys(value.toString());
283             inputIndex.getAndIncrement();
284         });
285     }
286
287     /**
288      * Fills the creation property modal.
289      * @param propertyName the property name to be created
290      * @param propertyType the property type to be selected
291      */
292     private void createProperty(final String propertyName, final String propertyType) {
293         final AddPropertyModal addPropertyModal = new AddPropertyModal(webDriver);
294         addPropertyModal.isLoaded();
295         addPropertyModal.fillPropertyForm(propertyName, propertyType);
296         addPropertyModal.clickOnCreate();
297     }
298
299     /**
300      * Verifies if the added property is displayed on the UI.
301      * @param propertyName the property name to be found
302      */
303     private void verifyProperty(final String propertyName) {
304         final By propertyCheckboxLocator = By.xpath(XpathSelector.PROPERTY_CHECKBOX.getXpath(propertyName));
305         final WebElement propertyCheckbox = waitForElementVisibility(propertyCheckboxLocator, 5);
306         assertTrue(propertyCheckbox.isDisplayed(), String.format("%s Property should be displayed", propertyName));
307         assertTrue(this.getPropertyNamesAndTypes().containsKey(propertyName),
308             String.format("%s Property should be listed but found %s", propertyName, this.getPropertyNamesAndTypes().toString()));
309     }
310
311     /**
312      * select property
313      */
314     public void selectProperty(String propertyName){
315         isPropertyPresent(propertyName);
316         waitToBeClickable(By.xpath(ResourcePropertiesAssignmentTab.XpathSelector.PROPERTY_CHECKBOX.getXpath(propertyName))).click();
317     }
318
319     public void loadComponentInstanceProperties(final String instanceName){
320         waitToBeClickable(By.xpath(ResourcePropertiesAssignmentTab.XpathSelector.INSTANCE_SPAN.getXpath(instanceName))).click();
321     }
322
323     public void clickOnDeclareInput(){
324         waitToBeClickable(By.xpath(ResourcePropertiesAssignmentTab.XpathSelector.DECLARE_INPUT_BTN.getXpath())).click();
325     }
326
327     public void loadCompositionTab(){
328         waitToBeClickable(By.xpath(ResourcePropertiesAssignmentTab.XpathSelector.COMPOSITION_TAB.getXpath())).click();
329     }
330
331     /**
332      * Enum that contains identifiers and xpath expressions to elements related to the enclosing page object.
333      */
334     @AllArgsConstructor
335     private enum XpathSelector {
336         MAIN_DIV("w-sdc-main-right-container", "//div[@class='%s']"),
337         PROPERTIES_TAB("//*[contains(@data-tests-id, 'Properties') and contains(@class, 'active')]"),
338         PROPERTIES_TABLE("properties-table", "//div[contains(@class,'%s')]"),
339         NO_DATA_MESSAGE("no-data", "//div[contains(@class,'%s') and text()='No data to display']"),
340         SOFTWARE_VERSION_PROPERTY_CHECKBOX("software_versions", "//checkbox[@data-tests-id='%s']"),
341         SOFTWARE_VERSION_INPUT("value-prop-software_versions", "//input[starts-with(@data-tests-id,'%s')]"),
342         PROPERTY_CHECKBOX("//checkbox[@data-tests-id='%s']"),
343         PROPERTY_SAVE_BTN("properties-save-button", "//button[@data-tests-id='%s']"),
344         PROPERTY_ADD_RIGHT_COLUMN_DIV("right-column", "//div[@class='%s']"),
345         PROPERTY_ADD_BTN("add-btn", "//div[contains(@class,'%s')]"),
346         PROPERTY_ADD_VALUE_COMPLEX_TYPE("//a[contains(@data-tests-id, 'add-to-list-%s')]"),
347         INPUT_PROPERTY_COMPLEX_TYPE_KEY("//input[contains(@data-tests-id, 'value-prop-key-%s')]"),
348         INPUT_PROPERTY_COMPLEX_TYPE_VALUE("//input[contains(@data-tests-id, 'value-prop-%s')]"),
349         INPUT_PROPERTY("//input[@data-tests-id='value-prop-%s']"),
350         SELECT_INPUT_PROPERTY("//select[@data-tests-id='value-prop-%s']"),
351         PROPERTY_TYPES("//*[contains(@data-tests-id, 'propertyType')]"),
352         PROPERTY_NAMES("//*[contains(@data-tests-id, 'propertyName')]"),
353         DECLARE_INPUT_BTN("declare-button declare-input", "//button[@data-tests-id='%s']"),
354         COMPOSITION_TAB("Composition", "//div[contains(@class,'tab') and contains(text(), '%s')]"),
355         INSTANCE_SPAN("//span[@data-tests-id='%s']");
356
357         @Getter
358         private String id;
359         private final String xpathFormat;
360
361         XpathSelector(final String xpathFormat) {
362             this.xpathFormat = xpathFormat;
363         }
364
365         public String getXpath() {
366             return String.format(xpathFormat, id);
367         }
368
369         public String getXpath(final Object... xpathParams) {
370             return String.format(xpathFormat, xpathParams);
371         }
372     }
373
374 }