Project

General

Profile

Download (11.6 KB) Statistics
| Branch: | Tag: | Revision:
1
package eu.etaxonomy.dataportal.pages;
2

    
3
import java.lang.reflect.Constructor;
4
import java.net.MalformedURLException;
5
import java.net.URL;
6
import java.util.ArrayList;
7
import java.util.List;
8
import java.util.concurrent.TimeUnit;
9

    
10
import org.apache.bcel.verifier.exc.LinkingConstraintException;
11
import org.apache.log4j.Logger;
12
import org.openqa.selenium.By;
13
import org.openqa.selenium.NoSuchElementException;
14
import org.openqa.selenium.WebDriver;
15
import org.openqa.selenium.WebElement;
16
import org.openqa.selenium.interactions.Actions;
17
import org.openqa.selenium.support.CacheLookup;
18
import org.openqa.selenium.support.FindBy;
19
import org.openqa.selenium.support.FindBys;
20
import org.openqa.selenium.support.PageFactory;
21
import org.openqa.selenium.support.ui.WebDriverWait;
22

    
23
import sun.swing.StringUIClientPropertyKey;
24

    
25
import com.google.common.base.Function;
26

    
27
import eu.etaxonomy.dataportal.DataPortalContext;
28
import eu.etaxonomy.dataportal.elements.BaseElement;
29
import eu.etaxonomy.dataportal.elements.ClassificationTreeBlock;
30
import eu.etaxonomy.dataportal.elements.LinkElement;
31
import eu.etaxonomy.dataportal.selenium.JUnitWebDriverWait;
32
import eu.etaxonomy.dataportal.selenium.UrlLoaded;
33

    
34
public abstract class  PortalPage {
35

    
36
    /**
37
     *
38
     */
39
    public static final int WAIT_SECONDS = 25;
40

    
41
    public static final Logger logger = Logger.getLogger(PortalPage.class);
42

    
43
    protected final static String DRUPAL_PAGE_QUERY_BASE = "?q=";
44

    
45
    protected WebDriver driver;
46

    
47
    protected DataPortalContext context;
48

    
49
    protected final JUnitWebDriverWait wait;
50

    
51
    public WebDriverWait getWait() {
52
        return wait;
53
    }
54

    
55

    
56
    /**
57
     * Implementations of this method will supply the relative
58
     * path to the Drupal page. This path will usally have the form
59
     * <code>cdm_dataportal/{nodetype}</code>. For example the taxon pages all
60
     * have the page base <code>cdm_dataportal/taxon</code>
61
     * @return
62
     */
63
    protected abstract String getDrupalPageBase();
64

    
65
    private String drupalPagePath;
66

    
67
    protected URL pageUrl;
68

    
69
    // ==== WebElements === //
70

    
71
    @FindBy(id="cdm_dataportal.node")
72
    protected WebElement portalContent;
73

    
74
    @FindBy(tagName="title")
75
    @CacheLookup
76
    protected WebElement title;
77

    
78
    @FindBy(className="node")
79
    protected WebElement node;
80

    
81
    @FindBys({@FindBy(id="tabs-wrapper"), @FindBy(className="primary")})
82
    @CacheLookup
83
    protected WebElement primaryTabs;
84

    
85
    @FindBy(id="block-cdm-dataportal-2")
86
    @CacheLookup
87
    protected WebElement searchBlockElement;
88

    
89
    @FindBy(id="block-cdm-taxontree-cdm-tree")
90
    @CacheLookup
91
    protected WebElement classificationBrowserBlock;
92

    
93
    /**
94
     * Creates a new PortaPage. Implementations of this class will provide the base path of the page by
95
     * implementing the method {@link #getDrupalPageBase()}. The constructor argument <code>pagePathSuffix</code>
96
     * specifies the specific page to navigate to. For example:
97
     * <ol>
98
     * <li>{@link #getDrupalPageBase()} returns <code>/cdm_dataportal/taxon</code></li>
99
     * <li><code>pagePathSuffix</code> gives <code>7fe8a8b6-b0ba-4869-90b3-177b76c1753f</code></li>
100
     * </ol>
101
     * Both are combined to form the URL pathelement <code>/cdm_dataportal/taxon/7fe8a8b6-b0ba-4869-90b3-177b76c1753f</code>
102
     *
103
     *
104
     * @param driver
105
     * @param context
106
     * @param pagePathSuffix
107
     * @throws MalformedURLException
108
     */
109
    public PortalPage(WebDriver driver, DataPortalContext context, String pagePathSuffix) throws MalformedURLException {
110

    
111
        this.driver = driver;
112

    
113
        this.context = context;
114

    
115
        this.wait = new JUnitWebDriverWait(driver, WAIT_SECONDS);
116

    
117
        this.drupalPagePath = getDrupalPageBase() + (pagePathSuffix != null ? "/" + pagePathSuffix: "");
118

    
119
        this.pageUrl = new URL(context.getBaseUri().toString() + DRUPAL_PAGE_QUERY_BASE + drupalPagePath);
120

    
121
        // tell browser to navigate to the page
122
        driver.get(pageUrl.toString());
123

    
124
        // This call sets the WebElement fields.
125
        PageFactory.initElements(driver, this);
126

    
127
        logger.info("loading " + pageUrl);
128

    
129
    }
130

    
131
    /**
132
     * Creates a new PortaPage at given URL location. An Exception is thrown if
133
     * this URL is not matching the expected URL for the specific page type.
134
     *
135
     * @param driver
136
     * @param context
137
     * @param url
138
     * @throws Exception
139
     */
140
    public PortalPage(WebDriver driver, DataPortalContext context, URL url) throws Exception {
141

    
142
        this.driver = driver;
143

    
144
        this.context = context;
145

    
146
        this.wait = new JUnitWebDriverWait(driver, 25);
147

    
148
        this.pageUrl = new URL(context.getBaseUri().toString());
149

    
150
        // tell browser to navigate to the given URL
151
        driver.get(url.toString());
152

    
153
        if(!isOnPage()){
154
            throw new Exception("Not on the expected portal page ( current: " + driver.getCurrentUrl() + ", expected: " +  pageUrl + " )");
155
        }
156

    
157
        this.pageUrl = url;
158

    
159
        logger.info("loading " + pageUrl);
160

    
161
        // This call sets the WebElement fields.
162
        PageFactory.initElements(driver, this);
163

    
164
    }
165

    
166
    /**
167
     * Creates a new PortaPage at the WebDrivers current URL location. An Exception is thrown if
168
     * driver.getCurrentUrl() is not matching the expected URL for the specific page type.
169
     *
170
     * @param driver
171
     * @param context
172
     * @throws Exception
173
     */
174
    public PortalPage(WebDriver driver, DataPortalContext context) throws Exception {
175

    
176
        this.driver = driver;
177

    
178
        this.context = context;
179

    
180
        this.wait = new JUnitWebDriverWait(driver, 25);
181

    
182
        // preliminary set the pageUrl to the base path of this page, this is used in the next setp to check if the
183
        // driver.getCurrentUrl() is a sub path of the base path
184
        this.pageUrl = new URL(context.getBaseUri().toString());
185

    
186
        if(!isOnPage()){
187
            throw new Exception("Not on the expected portal page ( current: " + driver.getCurrentUrl() + ", expected: " +  pageUrl + " )");
188
        }
189

    
190
        // now set the real URL
191
        this.pageUrl = new URL(driver.getCurrentUrl());
192

    
193
        logger.info("loading " + pageUrl);
194

    
195
        // This call sets the WebElement fields.
196
        PageFactory.initElements(driver, this);
197

    
198
    }
199

    
200
    /**
201
     * @return
202
     */
203
    protected boolean isOnPage() {
204
        return driver.getCurrentUrl().startsWith(pageUrl.toString());
205
    }
206

    
207
    /**
208
     * navigate and reload the page if not jet there
209
     */
210
    public void get() {
211
        if(!driver.getCurrentUrl().equals(pageUrl.toString())){
212
            driver.get(pageUrl.toString());
213
            wait.until(new UrlLoaded(pageUrl.toString()));
214
            PageFactory.initElements(driver, this);
215
        }
216
    }
217

    
218
    /**
219
     * go back in history
220
     */
221
    public void back() {
222
        driver.navigate().back();
223
    }
224

    
225
    public String getDrupalPagePath() {
226
        return drupalPagePath;
227
    }
228

    
229
    /**
230
     * returns the string from the <code>title</code> tag.
231
     * @return
232
     */
233
    public String getTitle() {
234
        return title.getText();
235
    }
236

    
237
    /**
238
     * returns the warning messages from the Drupal message box
239
     * @return
240
     */
241
    public String getWarnings() {
242
        return null; //TODO unimplemented
243
    }
244

    
245
    /**
246
     * returns the error messages from the Drupal message box
247
     * @return
248
     */
249
    public String getErrors() {
250
        return null; //TODO unimplemented
251
    }
252

    
253
    public String getAuthorInformationText() {
254

    
255
        WebElement authorInformation = null;
256

    
257
        try {
258
            authorInformation  = node.findElement(By.className("submitted"));
259
        } catch (NoSuchElementException e) {
260
            // IGNORE //
261
        }
262

    
263

    
264
        if(authorInformation != null){
265
            return authorInformation.getText();
266
        } else {
267
            return null;
268
        }
269
    }
270

    
271
    public List<LinkElement> getPrimaryTabs(){
272
        List<LinkElement> tabs = new ArrayList<LinkElement>();
273
        List<WebElement> links = primaryTabs.findElements(By.tagName("a"));
274
        for(WebElement a : links) {
275
            WebElement renderedLink = a;
276
            if(renderedLink.isDisplayed()){
277
                tabs.add(new LinkElement(renderedLink));
278
            }
279
        }
280

    
281
        return tabs;
282
    }
283

    
284
    public ClassificationTreeBlock getClassificationTree() {
285
        return new ClassificationTreeBlock(classificationBrowserBlock);
286
    }
287

    
288
    public void hover(WebElement element) {
289
        Actions actions = new Actions(driver);
290
        actions.moveToElement(element, 1, 1).perform();
291
        logger.debug("hovering");
292
    }
293

    
294

    
295
    /**
296
     * Returns the current URL string from the {@link WebDriver}
297
     * @return
298
     */
299
    public URL getPageURL() {
300
        return pageUrl;
301
    }
302

    
303

    
304
    /**
305
     * return the <code>scheme://domain:port</code> part of the initial url of this page.
306
     * @return
307
     */
308
    public String getInitialUrlBase() {
309
        return pageUrl.getProtocol() + "://" + pageUrl.getHost() + pageUrl.getPort();
310
    }
311

    
312
    public boolean equals(Object obj) {
313
        if (PortalPage.class.isAssignableFrom(obj.getClass())) {
314
            PortalPage page = (PortalPage) obj;
315
            return this.getPageURL().toString().equals(page.getPageURL().toString());
316

    
317
        } else {
318
            return false;
319
        }
320
    }
321

    
322

    
323
    /**
324
     * @param <T>
325
     * @param link the link to click
326
     * @param isTrue see {@link org.openqa.selenium.support.ui.FluentWait#until(Function)}
327
     * @param type the return type
328
     * @param duration may be null, if this in null <code>waitUnit</code> will be ignored.
329
     * @param waitUnit may be null, is ignored if <code>duration</code> is null defaults to {@link TimeUnit.SECONDS}
330
     * @return
331
     * @throws SecurityException
332
     */
333
    public <T extends PortalPage> T clickLink(BaseElement element, Function<? super WebDriver, Boolean> isTrue, Class<T> type, Long duration, TimeUnit waitUnit) {
334

    
335
        String targetWindow = null;
336
        List<String> targets = element.getLinkTargets(driver);
337
        if(targets.size() > 0){
338
            targetWindow = targets.get(0);
339
        }
340

    
341
        if(logger.isInfoEnabled() || logger.isDebugEnabled()){
342
            logger.info("clickLink() on " + element.toStringWithLinks());
343
        }
344
        element.getElement().click();
345
        if(targetWindow != null){
346
            driver.switchTo().window(targetWindow);
347
        }
348

    
349
        try {
350
            if(duration != null){
351
                if(waitUnit == null){
352
                    waitUnit = TimeUnit.SECONDS;
353
                }
354
                wait.withTimeout(duration, waitUnit).until(isTrue);
355
            } else {
356
                wait.until(isTrue);
357
            }
358
        } catch (AssertionError timeout){
359
            logger.info("current WindowHandles:" + driver.getWindowHandles());
360
            throw timeout;
361
        }
362

    
363

    
364
        Constructor<T> constructor;
365
        T pageInstance;
366
        try {
367
            constructor = type.getConstructor(WebDriver.class, DataPortalContext.class);
368
            pageInstance = constructor.newInstance(driver, context);
369
        } catch (Exception e) {
370
            throw new RuntimeException(e);
371
        }
372
        return pageInstance;
373
    }
374

    
375

    
376
    /**
377
     * @param <T>
378
     * @param link the link to click
379
     * @param isTrue see {@link org.openqa.selenium.support.ui.FluentWait#until(Function)}
380
     * @param type the return type
381
     * @return
382
     */
383
    public <T extends PortalPage> T clickLink(BaseElement element, Function<? super WebDriver, Boolean> isTrue, Class<T> type) {
384
        return clickLink(element, isTrue, type, null, null);
385
    }
386

    
387

    
388
    /**
389
     * replaces all underscores '_' by hyphens '-'
390
     *
391
     * @param featureName
392
     * @return
393
     */
394
    protected String normalizeClassAttribute(String featureName) {
395
        return featureName.replace('_', '-');
396
    }
397

    
398

    
399
}
(3-3/6)