1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.test.ui.po

File BootstrapSelect.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

14
50
12
1
196
127
21
0.42
4.17
12
1.75

Classes

Class Line # Actions
BootstrapSelect 42 50 0% 21 5
0.9342105493.4%
 

Contributing tests

This file is covered by 5 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.test.ui.po;
21   
22    import java.util.ArrayList;
23    import java.util.Arrays;
24    import java.util.HashMap;
25    import java.util.List;
26    import java.util.Map;
27   
28    import org.openqa.selenium.By;
29    import org.openqa.selenium.NoSuchElementException;
30    import org.openqa.selenium.WebDriver;
31    import org.openqa.selenium.WebElement;
32    import org.openqa.selenium.support.ui.ExpectedCondition;
33    import org.xwiki.test.ui.XWikiWebDriver;
34   
35    /**
36    * Represent an select field enhanced with the "bootstrap-select" plugin.
37    *
38    * @version $Id: 1cd9e1697ff62a636eeb9ac7c4939de9d6b064d6 $
39    * @since 8.4.2
40    * @since 9.0RC1
41    */
 
42    public class BootstrapSelect
43    {
44    private WebElement element;
45   
46    private WebElement button;
47   
48    private WebElement menu;
49   
50    private WebElement hiddenSelect;
51   
52    private XWikiWebDriver driver;
53   
 
54  32 toggle public BootstrapSelect(WebElement element, XWikiWebDriver driver)
55    {
56  32 this.driver = driver;
57  32 this.element = element;
58  32 this.button = element.findElement(By.tagName("button"));
59  32 this.menu = element.findElement(By.cssSelector(".dropdown-menu"));
60  32 this.hiddenSelect = element.findElement(By.tagName("select"));
61    }
62   
 
63  32 toggle public boolean isMultiple()
64    {
65  32 String value = this.hiddenSelect.getAttribute("multiple");
66  32 return value != null && !"false".equals(value);
67    }
68   
 
69  27 toggle public void selectByValue(String value)
70    {
71  27 selectByValues(Arrays.asList(value));
72    }
73   
 
74  32 toggle public void selectByValues(List<String> values)
75    {
76  32 Map<String, String> valueTitles = new HashMap();
77   
78    // Get the list of all possible values in the hidden <select> field
79    // WARN: the order of the values is imported since their index will help us to identify
80    // them in the enhanced bootstrap-select widget.
81  32 List<String> options = new ArrayList<>();
82  32 for (WebElement element : this.hiddenSelect.findElements(By.tagName("option"))) {
83  3060 String value = element.getAttribute("value");
84  3060 options.add(value);
85  3060 valueTitles.put(value, element.getText());
86    }
87   
88    // Open the enhanced bootstrap-select widget
89  32 openMenu();
90   
91  32 if (isMultiple()) {
92    // For each of its option
93  5 for (WebElement element : this.menu.findElements(By.tagName("li"))) {
94    // We find the language associated to this item thanks to the attribute "data-original-index"
95  795 int index = Integer.parseInt(element.getAttribute("data-original-index"));
96  795 String value = options.get(index);
97   
98    // Now, click on the element to select/unselect it if its status is different from what we want
99  795 if (isElementSelected(element) != values.contains(value)) {
100  6 element.findElement(By.tagName("a")).click();
101   
102    // If the element is not displayed inside the window (selenium does not handle scrolling inside an
103    // element) the previous action has actually closed the menu, without changing the state of the element.
104    // So we need to check if the menu has been close.
105  6 if (!this.menu.isDisplayed()) {
106    // In that was, we reopen it
107  0 openMenu();
108    // When we reopen the menu, the element is now contained inside the viewport (the previous click
109    // had some effect) so we can click it.
110    // TODO: make this less hacky.
111  0 element.findElement(By.tagName("a")).click();
112    }
113    }
114    }
115    } else {
116  27 WebElement filterInput = getFilterInput();
117  27 if (filterInput != null) {
118  14 filterInput.sendKeys(valueTitles.get(values.get(0)));
119    }
120    // For each of its option
121  27 for (WebElement element : this.menu.findElements(By.tagName("li"))) {
122    // We find the language associated to this item thanks to the attribute "data-original-index"
123  641 int index = Integer.parseInt(element.getAttribute("data-original-index"));
124  641 String value = options.get(index);
125   
126    // Now, click on the element to select the value
127  641 if (element.isDisplayed() && values.contains(value)) {
128  27 element.findElement(By.tagName("a")).click();
129  27 waitUntilMenuIsClosed();
130  27 if (!button.getAttribute("title").startsWith(valueTitles.get(value))) {
131  0 throw new RuntimeException(
132    String.format("Failed to set the value [%s] with the title [%s]. Got [%s] instead.",
133    value, valueTitles.get(value), button.getAttribute("title")));
134    }
135  27 break;
136    }
137    }
138    }
139   
140    // To finish, close the enhanced bootstrap-select widget
141  32 if (this.menu.isDisplayed()) {
142  5 closeMenu();
143    }
144    }
145   
 
146  27 toggle private WebElement getFilterInput()
147    {
148  27 try {
149  27 return this.driver.findElementWithoutWaiting(this.menu, By.tagName("input"));
150    } catch (NoSuchElementException e) {
151  13 return null;
152    }
153    }
154   
 
155  32 toggle private void waitUntilMenuIsOpened()
156    {
157   
158  32 driver.waitUntilCondition(new ExpectedCondition<Object>()
159    {
 
160  32 toggle @Override
161    public Object apply(WebDriver webDriver)
162    {
163  32 return menu.isDisplayed();
164    }
165    });
166    }
167   
 
168  32 toggle private void waitUntilMenuIsClosed()
169    {
170  32 driver.waitUntilCondition(new ExpectedCondition<Object>()
171    {
 
172  32 toggle @Override
173    public Object apply(WebDriver webDriver)
174    {
175  32 return !menu.isDisplayed();
176    }
177    });
178    }
179   
 
180  32 toggle private void openMenu()
181    {
182  32 this.button.click();
183  32 waitUntilMenuIsOpened();
184    }
185   
 
186  5 toggle private void closeMenu()
187    {
188  5 this.button.click();
189  5 waitUntilMenuIsClosed();
190    }
191   
 
192  795 toggle private boolean isElementSelected(WebElement element)
193    {
194  795 return element.getAttribute("class").contains("selected");
195    }
196    }