Project

General

Profile

Download (11 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2011 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.dataportal.elements;
10

    
11
import static org.junit.Assert.assertEquals;
12

    
13
import java.util.ArrayList;
14
import java.util.HashMap;
15
import java.util.List;
16

    
17
import org.openqa.selenium.By;
18
import org.openqa.selenium.JavascriptExecutor;
19
import org.openqa.selenium.NoSuchElementException;
20
import org.openqa.selenium.WebDriver;
21
import org.openqa.selenium.WebElement;
22

    
23
/**
24
 * @author andreas
25
 * @since Jul 4, 2011
26
 *
27
 */
28
public class FeatureBlock extends DrupalBlock {
29

    
30
    /**
31
     * JQuery Selector for footnotekeys
32
     */
33
    private static final String SELECTOR_FOOTNOTE_KEY = "span.footnote-key a";
34

    
35
    /**
36
     * JQuery Selector for footnotes
37
     */
38
    private static final String SELECTOR_FOOTNOTE = "span.footnote";
39

    
40
    private final WebDriver driver;
41

    
42
    private List<BaseElement> originalSources = null;
43

    
44
    private String featureType = null;
45

    
46
    private final String[] elementTags;
47

    
48
    private final List<WebElement> descriptionItemElements;
49

    
50
    protected List<WebElement> featureBlockelements;
51

    
52
    /**
53
     *
54
     * @param index 0 based
55
     */
56
    public LinkElement getFootNoteKey(int index) {
57
        WebElement footNoteKeyElement = jsGetElement(SELECTOR_FOOTNOTE_KEY, index);
58
        if(footNoteKeyElement != null) {
59
            return new LinkElement(footNoteKeyElement);
60
        } else {
61
            return null;
62
        }
63
    }
64

    
65
    public boolean hasFootNoteKeys() {
66
        return countFootNoteKeys() > 0;
67
    }
68

    
69
    public long countFootNoteKeys() {
70
        return jsCountElements(SELECTOR_FOOTNOTE_KEY);
71
    }
72

    
73
    /**
74
     *
75
     * @param index 0 based
76
     */
77
    public BaseElement getFootNote(int index) {
78
        WebElement footNoteElement = jsGetElement(SELECTOR_FOOTNOTE, index);
79
        if(footNoteElement != null) {
80
            return new BaseElement(footNoteElement);
81
        } else {
82
            return null;
83
        }
84
    }
85

    
86

    
87
    public long countFootNotes() {
88
        return jsCountElements(SELECTOR_FOOTNOTE);
89
    }
90

    
91
    public boolean hasFootNotes() {
92
        return countFootNotes() > 0;
93
    }
94

    
95
    public List<BaseElement> getOriginalSourcesSections() {
96
        if(originalSources == null) {
97
            initSources();
98
        }
99
        return originalSources;
100
    }
101

    
102

    
103
    public DescriptionElementRepresentation getDescriptionElement(int index) {
104
        WebElement descriptionElement = descriptionItemElements.get(index);
105
        if(descriptionElement != null) {
106
            if(elementTags.length > 1){
107
                // it is a multipart element e.g. <dt></dt><dd></dd>
108
                return new MultipartDescriptionElementRepresentation(
109
                        descriptionItemElements.toArray(new WebElement[descriptionItemElements.size()]));
110
            } else {
111
                return new DescriptionElementRepresentation(descriptionElement);
112
            }
113
        }
114
        return null;
115
    }
116

    
117
    public String getFeatureType() {
118
        return featureType;
119
    }
120

    
121
    public WebElement getTitle() {
122
        return titleElement;
123
    }
124

    
125
    public FeatureBlock(WebDriver driver, WebElement element, String enclosingTag, String ... elementTags) {
126
        this(driver, element, false, enclosingTag, elementTags);
127
    }
128

    
129
    public FeatureBlock(WebDriver driver, WebElement element, boolean hasHiddenTitle, String enclosingTag, String ... elementTags) {
130

    
131
        super(element, hasHiddenTitle);
132
//        logger.setLevel(Level.TRACE);
133
        logger.trace("FeatureBlock() - constructor after super()");
134

    
135
        this.driver = driver;
136
        this.elementTags = elementTags;
137

    
138
        WebElement featureBlockElementsWrapper =  element.findElement(By.className("feature-block-elements"));
139

    
140
        featureBlockelements = element.findElements(By.className("feature-block-element"));
141

    
142
        featureType = featureBlockElementsWrapper.getAttribute("id");
143

    
144
        //TODO throw exception instead of making an assertion! selenium should have appropriate exceptions
145
        assertEquals("Unexpected tag enclosing description element representations", enclosingTag, featureBlockElementsWrapper.getTagName());
146

    
147
        logger.trace("FeatureBlock() - loading all elements ...");
148
        descriptionItemElements = new ArrayList<WebElement>();
149
        if(elementTags.length > 1){
150

    
151
            // handle multipart elements e.g. <dt></dt><dd></dd>
152
            HashMap<String, List<WebElement>> elementsByTag = new HashMap<String, List<WebElement>>();
153
            Integer lastSize = null;
154
            for (String elementTag : elementTags) {
155
                List<WebElement> foundElements = featureBlockElementsWrapper.findElements(By.tagName(elementTag));
156
                if(lastSize != null && foundElements.size() != lastSize){
157
                    throw new NoSuchElementException("Mulitpart element lists differ in size");
158
                }
159
                lastSize = foundElements.size();
160
                elementsByTag.put(elementTag, foundElements);
161
            }
162

    
163
            for (int descriptionElementIndex = 0; descriptionElementIndex < lastSize; descriptionElementIndex++){
164
                for (String elementTag : elementTags) {
165
                    descriptionItemElements.add(elementsByTag.get(elementTag).get(descriptionElementIndex));
166
                }
167
//                descriptionElements.add(new MultipartDescriptionElementRepresentation(descriptionItemElements.toArray(new WebElement[descriptionItemElements.size()])));
168

    
169
            }
170
        } else {
171
            // handle single elements
172
            String elementTag = elementTags[0];
173
            for(WebElement el : featureBlockElementsWrapper.findElements(By.tagName( elementTag ))) {
174
                descriptionItemElements.add(el);
175
//                descriptionElements.add(new DescriptionElementRepresentation(el));
176
            }
177
        }
178
        logger.trace("FeatureBlock() - loading all elements DONE");
179

    
180
    }
181

    
182

    
183
    public List<WebElement> getFeatureBlockElements() {
184
        return featureBlockelements;
185
    }
186

    
187

    
188
    private Long jsCountElements(String jQuerySelector) {
189
        if(driver instanceof JavascriptExecutor) {
190
            String blockId = getElement().getAttribute("id");
191
            if(!blockId.startsWith("block-cdm-dataportal-feature-")) {
192
                throw new IllegalStateException("The block with id " + blockId + " is not a proper feature block");
193
            }
194
            // NOTE: jQuery(document).ready() must not be used here, otherwise
195
            // the executeScript() function will return null
196
            String js = "var elementCnt = jQuery('#" + blockId + "')."
197
                    + "    find('" + jQuerySelector + "').length;"
198
//                    + "  // console.log('count is ' + elementCnt);"
199
                    + "return elementCnt;";
200
            Object resultO  = ((JavascriptExecutor) driver).executeScript(js);
201
            logger.debug("FootNoteKeys count is " + resultO);
202
            if(resultO !=  null) {
203
                return Long.valueOf(resultO.toString());
204
            }
205
            return null;
206
        }
207
        throw new IllegalStateException("The driver must be a JavascriptExecutor");
208
    }
209

    
210

    
211
    private WebElement jsGetElement(String jQuerySelector, int elementIndex) {
212
        if(driver instanceof JavascriptExecutor) {
213
            String blockId = getElement().getAttribute("id");
214
            if(!blockId.startsWith("block-cdm-dataportal-feature-")) {
215
                throw new IllegalStateException("The block with id " + blockId + " is not a proper feature block");
216
            }
217
            // NOTE: jQuery(document).ready() must not be used here, otherwise
218
            // the executeScript() function will return null
219
            String js = "var elements = jQuery('#" + blockId + "')."
220
                            + "   find('" + jQuerySelector + "');"
221
//                            + "console.log(elements.length);"
222
                            + "return elements[" + elementIndex +"];";
223
            Object resultO  = ((JavascriptExecutor) driver).executeScript(js);
224
            logger.debug("FootNoteKeys count is " + resultO);
225
            if(resultO instanceof WebElement) {
226
                return (WebElement)resultO;
227
            }
228
            if(resultO instanceof List) {
229
                throw new IllegalStateException("The selector '" + jQuerySelector + "' matches multiple elements, this is not allowed.");
230
            }
231
            return null;
232
        }
233
        throw new IllegalStateException("The driver must be a JavascriptExecutor");
234
    }
235

    
236

    
237
    private void initSources() {
238
        originalSources = new ArrayList<BaseElement>();
239
        List<WebElement> sourcesList = getElement().findElements(By.className("sources"));
240
        for(WebElement source : sourcesList) {
241
            originalSources.add(new BaseElement(source));
242
        }
243
    }
244

    
245
    /**
246
     * @param indent TODO
247
     * @param computedFontSize TODO
248
     * @param expectedCssDisplay TODO
249
     * @param expectedListStyleType only applies if cssDisplay equals list-item
250
     * @param expectedListStylePosition only applies if cssDisplay equals list-item
251
     * @param expectedListStyleImage only applies if cssDisplay equals list-item
252
     */
253
    public void testDescriptionElementLayout(int descriptionElementId, int indent, int computedFontSize
254
            , String expectedCssDisplay, String expectedListStyleType, String expectedListStylePosition, String expectedListStyleImage) {
255

    
256
        DescriptionElementRepresentation firstDescriptionElement = getDescriptionElement(descriptionElementId);
257

    
258
        if(firstDescriptionElement instanceof MultipartDescriptionElementRepresentation){
259
            int multipartElementIndex = 0;
260
            firstDescriptionElement = ((MultipartDescriptionElementRepresentation)firstDescriptionElement).multipartElements.get(multipartElementIndex);
261
        }
262
        int parentX = getElement().getLocation().getX();
263
        int elementX = firstDescriptionElement.getElement().getLocation().getX();
264
        double elementPadLeft = pxSizeToDouble(firstDescriptionElement.getElement().getCssValue("padding-left"));
265

    
266
        assertEquals(indent, elementX - parentX + elementPadLeft, PIXEL_TOLERANCE);
267
        assertEquals("css font-size:", computedFontSize, firstDescriptionElement.getComputedFontSize(), 0.5);
268
        assertEquals("css display:", expectedCssDisplay, firstDescriptionElement.getElement().getCssValue("display"));
269

    
270
        if(expectedCssDisplay.equals("list-item")){
271
            assertEquals("css list-style-position: ", expectedListStylePosition, firstDescriptionElement.getElement().getCssValue("list-style-position"));
272
            assertEquals("css list-style-image: ",  expectedListStyleImage, firstDescriptionElement.getElement().getCssValue("list-style-image"));
273
            assertEquals("css list-style-type: ", expectedListStyleType, firstDescriptionElement.getElement().getCssValue("list-style-type"));
274
        }
275
    }
276

    
277
    public List<GalleryImage> getGalleryMedia() {
278
        List<GalleryImage> galleryImages = null; //getGalleryImages(getElement());
279

    
280
        return galleryImages;
281

    
282
    }
283

    
284
}
(7-7/20)