Project

General

Profile

Download (10.9 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
    private WebElement titleElement;
51

    
52
    private WebElement contentContainer;
53

    
54

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

    
68
    public boolean hasFootNoteKeys() {
69
        return countFootNoteKeys() > 0;
70
    }
71

    
72
    public long countFootNoteKeys() {
73
        return jsCountElements(SELECTOR_FOOTNOTE_KEY);
74
    }
75

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

    
89

    
90
    public long countFootNotes() {
91
        return jsCountElements(SELECTOR_FOOTNOTE);
92
    }
93

    
94
    public boolean hasFootNotes() {
95
        return countFootNotes() > 0;
96
    }
97

    
98
    public List<BaseElement> getOriginalSourcesSections() {
99
        if(originalSources == null) {
100
            initSources();
101
        }
102
        return originalSources;
103
    }
104

    
105

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

    
120
    public String getFeatureType() {
121
        return featureType;
122
    }
123

    
124
    public WebElement getTitle() {
125
        return titleElement;
126
    }
127

    
128
    @Override
129
    public WebElement getContent() {
130
        return contentContainer;
131
    }
132

    
133

    
134
    public FeatureBlock(WebDriver driver, WebElement element, String enclosingTag, String ... elementTags) {
135

    
136
        super(element);
137
//        logger.setLevel(Level.TRACE);
138
        logger.trace("FeatureBlock() - constructor after super()");
139

    
140
        this.driver = driver;
141
        this.elementTags = elementTags;
142

    
143
        titleElement =  element.findElement(By.className("title"));
144

    
145
        contentContainer = element.findElement(By.className("content"));
146

    
147
        WebElement descriptionElementsRepresentation =  element.findElement(By.className("feature-block-elements"));
148
        featureType = descriptionElementsRepresentation.getAttribute("id");
149

    
150
        //TODO throw exception instead of making an assertion! selenium should have appropriate exceptions
151
        assertEquals("Unexpected tag enclosing description element representations", enclosingTag, descriptionElementsRepresentation.getTagName());
152

    
153
        logger.trace("FeatureBlock() - loading all elements ...");
154
        descriptionItemElements = new ArrayList<WebElement>();
155
        if(elementTags.length > 1){
156

    
157
            // handle multipart elements e.g. <dt></dt><dd></dd>
158
            HashMap<String, List<WebElement>> elementsByTag = new HashMap<String, List<WebElement>>();
159
            Integer lastSize = null;
160
            for (String elementTag : elementTags) {
161
                List<WebElement> foundElements = descriptionElementsRepresentation.findElements(By.tagName(elementTag));
162
                if(lastSize != null && foundElements.size() != lastSize){
163
                    throw new NoSuchElementException("Mulitpart element lists differ in size");
164
                }
165
                lastSize = foundElements.size();
166
                elementsByTag.put(elementTag, foundElements);
167
            }
168

    
169
            for (int descriptionElementIndex = 0; descriptionElementIndex < lastSize; descriptionElementIndex++){
170
                for (String elementTag : elementTags) {
171
                    descriptionItemElements.add(elementsByTag.get(elementTag).get(descriptionElementIndex));
172
                }
173
//                descriptionElements.add(new MultipartDescriptionElementRepresentation(descriptionItemElements.toArray(new WebElement[descriptionItemElements.size()])));
174

    
175
            }
176
        } else {
177
            // handle single elements
178
            String elementTag = elementTags[0];
179
            for(WebElement el : descriptionElementsRepresentation.findElements(By.tagName( elementTag ))) {
180
                descriptionItemElements.add(el);
181
//                descriptionElements.add(new DescriptionElementRepresentation(el));
182
            }
183
        }
184
        logger.trace("FeatureBlock() - loading all elements DONE");
185

    
186
    }
187

    
188

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

    
211

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

    
237

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

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

    
257
        DescriptionElementRepresentation firstDescriptionElement = getDescriptionElement(descriptionElementId);
258

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

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

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

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

    
281
        return galleryImages;
282

    
283
    }
284

    
285
}
(6-6/15)