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