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

File AbstractXWikiTestCase.java

 
testLockingAndUnlocking: [Is This Page Locked true] isn't present.
testCodeToExecuteNotInlineIfNoConfigurationClass: [//span[@class='xwikirenderingerror']] is present.
testCodeToExecuteNotInline: [//span[@class='xwikirenderingerror']] is present.
 

Coverage histogram

../../../../../img/srcFileCovDistChart8.png
54% of files have more coverage

Code metrics

30
212
127
1
976
685
145
0.68
1.67
127
1.14

Classes

Class Line # Actions
AbstractXWikiTestCase 47 212 0% 145 83
0.7750677577.5%
 

Contributing tests

This file is covered by 331 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.selenium.framework;
21   
22    import java.io.ByteArrayInputStream;
23    import java.io.IOException;
24    import java.util.Map.Entry;
25    import java.util.Properties;
26   
27    import org.junit.Assert;
28    import org.junit.Before;
29    import org.openqa.selenium.By;
30    import org.openqa.selenium.Keys;
31    import org.openqa.selenium.Point;
32    import org.openqa.selenium.WebDriver;
33    import org.openqa.selenium.WebElement;
34    import org.openqa.selenium.interactions.Actions;
35    import org.xwiki.test.ui.AbstractTest;
36   
37    import com.thoughtworks.selenium.Selenium;
38    import com.thoughtworks.selenium.SeleniumException;
39    import com.thoughtworks.selenium.Wait;
40    import com.thoughtworks.selenium.webdriven.WebDriverBackedSelenium;
41   
42    /**
43    * All XWiki Selenium tests must extend this class.
44    *
45    * @version $Id: c7cb7a6044a1b7056ddb23ce1a8e62d04da4527e $
46    */
 
47    public abstract class AbstractXWikiTestCase extends AbstractTest implements SkinExecutor
48    {
49    public static final String BASEDIR = System.getProperty("basedir");
50   
51    public static final String DOC = "selenium.browserbot.getCurrentWindow().document.";
52   
53    private static final int WAIT_TIME = 30000;
54   
55    private SkinExecutor skinExecutor = new FlamingoSkinExecutor(this);
56   
57    private Selenium selenium;
58   
 
59  0 toggle public void setSkinExecutor(SkinExecutor skinExecutor)
60    {
61  0 this.skinExecutor = skinExecutor;
62    }
63   
 
64  587 toggle public SkinExecutor getSkinExecutor()
65    {
66  587 return this.skinExecutor;
67    }
68   
 
69  6276 toggle public Selenium getSelenium()
70    {
71  6276 if (this.selenium == null) {
72  333 String baseURL = "http://localhost:" + System.getProperty("xwikiPort", "8080");
73  333 this.selenium = new WebDriverBackedSelenium(getDriver(), baseURL);
74    }
75  6276 return this.selenium;
76    }
77   
 
78  333 toggle @Before
79    public void setUp()
80    {
81  333 loginAsAdmin();
82    }
83   
84    // Convenience methods wrapping Selenium
85   
 
86  902 toggle public void open(String url)
87    {
88  902 getSelenium().open(url);
89    }
90   
 
91  404 toggle public void open(String space, String page)
92    {
93  404 open(getUrl(space, page));
94    }
95   
 
96  26 toggle public void open(String space, String page, String action)
97    {
98  26 open(getUrl(space, page, action));
99    }
100   
 
101  399 toggle public void open(String space, String page, String action, String queryString)
102    {
103  399 open(getUrl(space, page, action, queryString));
104    }
105   
 
106  1 toggle public String getTitle()
107    {
108  1 return getSelenium().getTitle();
109    }
110   
 
111  0 toggle public void assertPage(String space, String page)
112    {
113  0 Assert.assertTrue(getTitle().matches(".*\\(" + space + "." + page + "\\) - XWiki"));
114    }
115   
116    /**
117    * Visits the specified page and checks if it exists, coming back to the current page.
118    *
119    * @param space the space name
120    * @param page the page name
121    * @return {@code true} if the specified page exists
122    */
 
123  7 toggle public boolean isExistingPage(String space, String page)
124    {
125  7 String saveUrl = getSelenium().getLocation();
126   
127  7 open(getUrl(space, page));
128  7 boolean exists = isExistingPage();
129   
130    // Restore original URL
131  7 open(saveUrl);
132   
133  7 return exists;
134    }
135   
136    /**
137    * @return {@code true} if we are on an existing page, {@code false} otherwise
138    */
 
139  26 toggle public boolean isExistingPage()
140    {
141  26 return !getSelenium().isTextPresent("The requested page could not be found.");
142    }
143   
 
144  0 toggle public void assertTitle(String title)
145    {
146  0 Assert.assertEquals(title, getTitle());
147    }
148   
 
149  658 toggle public boolean isElementPresent(String locator)
150    {
151  658 return getSelenium().isElementPresent(locator);
152    }
153   
 
154  422 toggle public boolean isElementPresentWithoutWaiting(By by)
155    {
156  422 return getDriver().hasElementWithoutWaiting(by);
157    }
158   
 
159  0 toggle public boolean isLinkPresent(String text)
160    {
161  0 return isElementPresent("link=" + text);
162    }
163   
 
164  25 toggle public void clickLinkWithText(String text)
165    {
166  25 clickLinkWithText(text, true);
167    }
168   
 
169  27 toggle public void assertTextPresent(String text)
170    {
171  27 Test failure here Assert.assertTrue("[" + text + "] isn't present.", getSelenium().isTextPresent(text));
172    }
173   
 
174  9 toggle public void assertTextNotPresent(String text)
175    {
176  9 Assert.assertFalse("[" + text + "] is present.", getSelenium().isTextPresent(text));
177    }
178   
 
179  576 toggle public void assertElementPresent(String elementLocator)
180    {
181  576 Assert.assertTrue("[" + elementLocator + "] isn't present.", isElementPresent(elementLocator));
182    }
183   
 
184  43 toggle public void assertElementNotPresent(String elementLocator)
185    {
186  43 Test failure here Assert.assertFalse("[" + elementLocator + "] is present.", isElementPresent(elementLocator));
187    }
188   
 
189  254 toggle public void waitPage()
190    {
191  254 waitPage(WAIT_TIME);
192    }
193   
194    /**
195    * @deprecated use {@link #waitPage()} instead
196    */
 
197  254 toggle @Deprecated
198    public void waitPage(int nbMillisecond)
199    {
200  254 getSelenium().waitForPageToLoad(String.valueOf(nbMillisecond));
201    }
202   
 
203  2 toggle public void createPage(String space, String page, String content)
204    {
205  2 createPage(space, page, content, null);
206    }
207   
 
208  14 toggle public void createPage(String space, String page, String content, String syntax)
209    {
210    // If the page already exists, delete it first
211  14 deletePage(space, page);
212  14 if (syntax == null) {
213  2 editInWikiEditor(space, page);
214    } else {
215  12 editInWikiEditor(space, page, syntax);
216    }
217  14 setFieldValue("content", content);
218  14 clickEditSaveAndView();
219    }
220   
 
221  24 toggle public void deletePage(String space, String page)
222    {
223  24 open(space, page, "delete", "confirm=1");
224    }
225   
 
226  1 toggle public void restorePage(String space, String page)
227    {
228  1 open(space, page, "view");
229  1 if (getSelenium().isTextPresent("Restore")) {
230  1 clickLinkWithText("Restore", true);
231    }
232    }
233   
 
234  195 toggle public void clickLinkWithLocator(String locator)
235    {
236  195 clickLinkWithLocator(locator, true);
237    }
238   
 
239  388 toggle public void clickLinkWithLocator(String locator, boolean wait)
240    {
241  388 assertElementPresent(locator);
242  388 getSelenium().click(locator);
243  388 if (wait) {
244  242 waitPage();
245    }
246    }
247   
 
248  34 toggle public void clickLinkWithText(String text, boolean wait)
249    {
250  34 clickLinkWithLocator("link=" + text, wait);
251    }
252   
 
253  1 toggle public boolean isChecked(String locator)
254    {
255  1 return getSelenium().isChecked(locator);
256    }
257   
 
258  38 toggle public String getFieldValue(String fieldName)
259    {
260    // Note: We could use getSelenium().getvalue() here. However getValue() is stripping spaces
261    // and some of our tests verify that there are leading spaces/empty lines.
262  38 return getSelenium().getEval(
263    "selenium.browserbot.getCurrentWindow().document.getElementById(\"" + fieldName + "\").value");
264    }
265   
 
266  275 toggle public void setFieldValue(String fieldName, String value)
267    {
268  275 getSelenium().type(fieldName, value);
269    }
270   
 
271  4 toggle public void checkField(String locator)
272    {
273  4 getSelenium().check(locator);
274    }
275   
 
276  13 toggle public void submit()
277    {
278  13 clickLinkWithXPath("//input[@type='submit']");
279    }
280   
 
281  93 toggle public void submit(String locator)
282    {
283  93 clickLinkWithLocator(locator);
284    }
285   
 
286  87 toggle public void submit(String locator, boolean wait)
287    {
288  87 clickLinkWithLocator(locator, wait);
289    }
290   
 
291  15 toggle public void clickLinkWithXPath(String xpath)
292    {
293  15 clickLinkWithXPath(xpath, true);
294    }
295   
 
296  58 toggle public void clickLinkWithXPath(String xpath, boolean wait)
297    {
298  58 clickLinkWithLocator("xpath=" + xpath, wait);
299    }
300   
 
301  64 toggle public void waitForCondition(String condition)
302    {
303  64 getSelenium().waitForCondition(condition, "" + WAIT_TIME);
304    }
305   
 
306  10 toggle public void waitForTextPresent(final String elementLocator, final String expectedValue)
307    {
308  10 new Wait()
309    {
 
310  20 toggle public boolean until()
311    {
312  20 return getSelenium().getText(elementLocator).equals(expectedValue);
313    }
314  10 }.wait(getSelenium().isElementPresent(elementLocator) ? "Element [" + elementLocator + "] not found"
315    : "Element [" + elementLocator + "] found but it doesn't have the expected value [" + expectedValue + "]");
316    }
317   
 
318  15 toggle public void waitForTextContains(final String elementLocator, final String containsValue)
319    {
320  15 new Wait()
321    {
 
322  19 toggle public boolean until()
323    {
324  19 return getSelenium().getText(elementLocator).indexOf(containsValue) > -1;
325    }
326  15 }.wait(getSelenium().isElementPresent(elementLocator) ? "Element [" + elementLocator + "] not found"
327    : "Element [" + elementLocator + "] found but it doesn't contain the expected value [" + containsValue
328    + "]");
329    }
330   
 
331  19 toggle public void waitForBodyContains(final String containsValue)
332    {
333  19 new Wait()
334    {
 
335  19 toggle public boolean until()
336    {
337  19 try {
338  19 return getSelenium().getBodyText().indexOf(containsValue) > -1;
339    } catch (SeleniumException e) {
340    // The page might not be loaded yet and so the BODY element is missing. Try again later.
341  0 return false;
342    }
343    }
344    }.wait("Body text doesn't contain the value [" + containsValue + "]");
345    }
346   
 
347  239 toggle public void waitForElement(final String elementLocator)
348    {
349  239 new Wait()
350    {
 
351  244 toggle public boolean until()
352    {
353  244 return getSelenium().isElementPresent(elementLocator);
354    }
355    }.wait("element [" + elementLocator + "] not found");
356    }
357   
358    /**
359    * Waits until an alert message appears or the timeout expires. You can use {@link Selenium#getAlert()} to assert
360    * the alert message afterwards.
361    */
 
362  1 toggle public void waitForAlert()
363    {
364  1 new Wait()
365    {
 
366  2 toggle public boolean until()
367    {
368  2 return getSelenium().isAlertPresent();
369    }
370    }.wait("The alert didn't appear.");
371    }
372   
373    /**
374    * Waits until a confirmation message appears or the timeout expires. You can use {@link Selenium#getConfirmation()}
375    * to assert the confirmation message afterwards.
376    */
 
377  6 toggle public void waitForConfirmation()
378    {
379  6 new Wait()
380    {
 
381  6 toggle public boolean until()
382    {
383  6 return getSelenium().isConfirmationPresent();
384    }
385    }.wait("The confirmation didn't appear.");
386    }
387   
388    /**
389    * Waits for a notification message of the specified type with the given message to be displayed.
390    *
391    * @param level the notification type (one of error, warning, done)
392    * @param message the notification message
393    */
 
394  99 toggle private void waitForNotificationMessage(String level, String message)
395    {
396  99 String xpath = String.format("//div[contains(@class,'xnotification-%s') and contains(.,'%s')]", level, message);
397  99 waitForElement(xpath);
398    // In order to improve test speed, clicking on the notification will make it disappear. This also ensures that
399    // this method always waits for the last notification message of the specified level.
400  99 try {
401    // The notification message may disappear before we get to click on it.
402  99 getSelenium().click(xpath);
403    } catch (Exception e) {
404    // Ignore.
405    }
406    }
407   
 
408  0 toggle public void waitForNotificationErrorMessage(String message)
409    {
410  0 waitForNotificationMessage("error", message);
411    }
412   
 
413  0 toggle public void waitForNotificationWarningMessage(String message)
414    {
415  0 waitForNotificationMessage("warning", message);
416    }
417   
 
418  99 toggle public void waitForNotificationSuccessMessage(String message)
419    {
420  99 waitForNotificationMessage("done", message);
421    }
422   
 
423  55 toggle public void clickButtonAndContinue(String locator)
424    {
425  55 submit(locator, false);
426  55 waitForNotificationSuccessMessage("");
427    }
428   
 
429  0 toggle @Override
430    public void clickEditPage()
431    {
432  0 getSkinExecutor().clickEditPage();
433    }
434   
 
435  11 toggle @Override
436    public void clickEditPageInWikiSyntaxEditor()
437    {
438  11 getSkinExecutor().clickEditPageInWikiSyntaxEditor();
439    }
440   
 
441  6 toggle @Override
442    public void clickEditPageInWysiwyg()
443    {
444  6 getSkinExecutor().clickEditPageInWysiwyg();
445    }
446   
 
447  1 toggle @Override
448    public void clickEditPageAccessRights()
449    {
450  1 getSkinExecutor().clickEditPageAccessRights();
451    }
452   
 
453  1 toggle @Override
454    public void clickEditPageInlineForm()
455    {
456  1 getSkinExecutor().clickEditPageInlineForm();
457    }
458   
 
459  0 toggle @Override
460    public void clickDeletePage()
461    {
462  0 getSkinExecutor().clickDeletePage();
463    }
464   
 
465  0 toggle @Override
466    public void clickCopyPage()
467    {
468  0 getSkinExecutor().clickCopyPage();
469    }
470   
 
471  1 toggle @Override
472    public void clickShowComments()
473    {
474  1 getSkinExecutor().clickShowComments();
475    }
476   
 
477  1 toggle @Override
478    public void clickShowAttachments()
479    {
480  1 getSkinExecutor().clickShowAttachments();
481    }
482   
 
483  1 toggle @Override
484    public void clickShowHistory()
485    {
486  1 getSkinExecutor().clickShowHistory();
487    }
488   
 
489  1 toggle @Override
490    public void clickShowInformation()
491    {
492  1 getSkinExecutor().clickShowInformation();
493    }
494   
 
495  3 toggle @Override
496    public void clickEditPreview()
497    {
498  3 getSkinExecutor().clickEditPreview();
499    }
500   
 
501  34 toggle @Override
502    public void clickEditSaveAndContinue()
503    {
504  34 getSkinExecutor().clickEditSaveAndContinue();
505    }
506   
 
507  5 toggle @Override
508    public void clickEditCancelEdition()
509    {
510  5 getSkinExecutor().clickEditCancelEdition();
511    }
512   
 
513  78 toggle @Override
514    public void clickEditSaveAndView()
515    {
516  78 getSkinExecutor().clickEditSaveAndView();
517    }
518   
519    /**
520    * Clicks on the add property button in the class editor. As a result the specified property is added to the edited
521    * class and the class is saved. This method waits for the class to be saved.
522    */
 
523  2 toggle @Override
524    public void clickEditAddProperty()
525    {
526  2 getSkinExecutor().clickEditAddProperty();
527    }
528   
529    /**
530    * Clicks on the add object button in the object editor. As a result an object of the specified class is added to
531    * the edited document and the document is saved. This method waits for the document to be saved.
532    */
 
533  4 toggle @Override
534    public void clickEditAddObject()
535    {
536  4 getSkinExecutor().clickEditAddObject();
537    }
538   
 
539  3 toggle @Override
540    public boolean isAuthenticated()
541    {
542  3 return getSkinExecutor().isAuthenticated();
543    }
544   
 
545  4 toggle @Override
546    public boolean isAuthenticated(String username)
547    {
548  4 return getSkinExecutor().isAuthenticated(username);
549    }
550   
 
551  4 toggle @Override
552    public boolean isAuthenticationMenuPresent()
553    {
554  4 return getSkinExecutor().isAuthenticationMenuPresent();
555    }
556   
 
557  3 toggle @Override
558    public void logout()
559    {
560  3 getSkinExecutor().logout();
561  3 recacheSecretToken();
562    }
563   
 
564  5 toggle @Override
565    public void login(String username, String password, boolean rememberme)
566    {
567  5 getSkinExecutor().login(username, password, rememberme);
568  5 recacheSecretToken();
569    }
570   
 
571  336 toggle @Override
572    public void loginAsAdmin()
573    {
574  336 getSkinExecutor().loginAsAdmin();
575  336 recacheSecretToken();
576    }
577   
578    /**
579    * If the user is not logged in already and if the specified user page exists, it is logged in. Otherwise the user
580    * is registered first and then the login is executed.
581    *
582    * @param username the user name to login as. If the user is to be created, this will also be used as the user first
583    * name while the user last name will be left blank
584    * @param password the password of the user
585    * @param rememberMe whether the login should be remembered or not
586    */
 
587  4 toggle public void loginAndRegisterUser(String username, String password, boolean rememberMe)
588    {
589  4 if (!isAuthenticationMenuPresent()) {
590    // navigate to the main page
591  0 open("Main", "WebHome");
592    }
593   
594    // if user is already authenticated, don't login
595  4 if (isAuthenticated(username)) {
596  0 return;
597    }
598   
599    // try to go to the user page
600  4 open("XWiki", username);
601    // if user page doesn't exist, register the user first
602  4 boolean exists = !getSelenium().isTextPresent("The requested page could not be found.");
603  4 if (!exists) {
604  2 if (isAuthenticated()) {
605  2 logout();
606    }
607  2 clickRegister();
608  2 fillRegisterForm(username, "", username, password, "");
609  2 submit();
610    // assume registration was done successfully, otherwise the register test should fail too
611    }
612   
613  4 login(username, password, rememberMe);
614    }
615   
 
616  2 toggle public void fillRegisterForm(String firstName, String lastName, String username, String password, String email)
617    {
618  2 setFieldValue("register_first_name", firstName);
619  2 setFieldValue("register_last_name", lastName);
620  2 setFieldValue("xwikiname", username);
621  2 setFieldValue("register_password", password);
622  2 setFieldValue("register2_password", password);
623  2 setFieldValue("register_email", email);
624    }
625   
 
626  0 toggle @Override
627    public void clickLogin()
628    {
629  0 getSkinExecutor().clickLogin();
630    }
631   
 
632  2 toggle @Override
633    public void clickRegister()
634    {
635  2 getSkinExecutor().clickRegister();
636    }
637   
 
638  0 toggle public String getEditorSyntax()
639    {
640  0 return getSkinExecutor().getEditorSyntax();
641    }
642   
 
643  0 toggle public void setEditorSyntax(String syntax)
644    {
645  0 getSkinExecutor().setEditorSyntax(syntax);
646    }
647   
 
648  3 toggle public void editInWikiEditor(String space, String page)
649    {
650  3 getSkinExecutor().editInWikiEditor(space, page);
651    }
652   
 
653  30 toggle public void editInWikiEditor(String space, String page, String syntax)
654    {
655  30 getSkinExecutor().editInWikiEditor(space, page, syntax);
656    }
657   
 
658  0 toggle public void editInWysiwyg(String space, String page)
659    {
660  0 getSkinExecutor().editInWysiwyg(space, page);
661    }
662   
 
663  0 toggle public void editInWysiwyg(String space, String page, String syntax)
664    {
665  0 getSkinExecutor().editInWysiwyg(space, page, syntax);
666    }
667   
 
668  0 toggle public void clearWysiwygContent()
669    {
670  0 getSkinExecutor().clearWysiwygContent();
671    }
672   
 
673  0 toggle public void keyPressAndWait(String element, String keycode) throws InterruptedException
674    {
675  0 getSelenium().keyPress(element, keycode);
676  0 waitPage();
677    }
678   
 
679  0 toggle public void typeInWysiwyg(String text)
680    {
681  0 getSkinExecutor().typeInWysiwyg(text);
682    }
683   
 
684  0 toggle public void typeInWiki(String text)
685    {
686  0 getSkinExecutor().typeInWiki(text);
687    }
688   
 
689  0 toggle public void typeEnterInWysiwyg()
690    {
691  0 getSkinExecutor().typeEnterInWysiwyg();
692    }
693   
 
694  0 toggle public void typeShiftEnterInWysiwyg()
695    {
696  0 getSkinExecutor().typeShiftEnterInWysiwyg();
697    }
698   
 
699  0 toggle public void clickWysiwygUnorderedListButton()
700    {
701  0 getSkinExecutor().clickWysiwygUnorderedListButton();
702    }
703   
 
704  0 toggle public void clickWysiwygOrderedListButton()
705    {
706  0 getSkinExecutor().clickWysiwygOrderedListButton();
707    }
708   
 
709  0 toggle public void clickWysiwygIndentButton()
710    {
711  0 getSkinExecutor().clickWysiwygIndentButton();
712    }
713   
 
714  0 toggle public void clickWysiwygOutdentButton()
715    {
716  0 getSkinExecutor().clickWysiwygOutdentButton();
717    }
718   
 
719  0 toggle public void clickWikiBoldButton()
720    {
721  0 getSkinExecutor().clickWikiBoldButton();
722    }
723   
 
724  0 toggle public void clickWikiItalicsButton()
725    {
726  0 getSkinExecutor().clickWikiItalicsButton();
727    }
728   
 
729  0 toggle public void clickWikiUnderlineButton()
730    {
731  0 getSkinExecutor().clickWikiUnderlineButton();
732    }
733   
 
734  0 toggle public void clickWikiLinkButton()
735    {
736  0 getSkinExecutor().clickWikiLinkButton();
737    }
738   
 
739  0 toggle public void clickWikiHRButton()
740    {
741  0 getSkinExecutor().clickWikiHRButton();
742    }
743   
 
744  0 toggle public void clickWikiImageButton()
745    {
746  0 getSkinExecutor().clickWikiImageButton();
747    }
748   
 
749  0 toggle public void clickWikiSignatureButton()
750    {
751  0 getSkinExecutor().clickWikiSignatureButton();
752    }
753   
 
754  0 toggle public void assertWikiTextGeneratedByWysiwyg(String text)
755    {
756  0 getSkinExecutor().assertWikiTextGeneratedByWysiwyg(text);
757    }
758   
 
759  0 toggle public void assertHTMLGeneratedByWysiwyg(String xpath) throws Exception
760    {
761  0 getSkinExecutor().assertHTMLGeneratedByWysiwyg(xpath);
762    }
763   
 
764  1 toggle public void assertGeneratedHTML(String xpath) throws Exception
765    {
766  1 getSkinExecutor().assertGeneratedHTML(xpath);
767    }
768   
 
769  21 toggle public void openAdministrationPage()
770    {
771  21 getSkinExecutor().openAdministrationPage();
772    }
773   
 
774  0 toggle public void openAdministrationSection(String section)
775    {
776  0 getSkinExecutor().openAdministrationSection(section);
777    }
778   
 
779  412 toggle public String getUrl(String space, String doc)
780    {
781  412 return getUrl(space, doc, "view");
782    }
783   
 
784  439 toggle public String getUrl(String space, String doc, String action)
785    {
786  439 return getUrl(space, doc, action, null);
787    }
788   
 
789  860 toggle public String getUrl(String space, String doc, String action, String queryString)
790    {
791  860 StringBuilder builder = new StringBuilder("/xwiki/bin/");
792  860 builder.append(action);
793  860 builder.append('/');
794  860 builder.append(space);
795  860 builder.append('/');
796  860 builder.append(doc);
797   
798  860 boolean needToAddSecretToken = !("view".equals(action) || "register".equals(action));
799  860 boolean needToAddQuery = queryString != null && queryString.length() > 0;
800  860 if (needToAddSecretToken || needToAddQuery) {
801  446 builder.append('?');
802    }
803  860 if (needToAddSecretToken) {
804  426 builder.append("form_token=");
805  426 builder.append(getSecretToken());
806  426 builder.append('&');
807    }
808  860 if (needToAddQuery) {
809  421 builder.append(queryString);
810    }
811  860 return builder.toString();
812    }
813   
 
814  0 toggle public void pressKeyboardShortcut(String shortcut, boolean withCtrlModifier, boolean withAltModifier,
815    boolean withShiftModifier) throws InterruptedException
816    {
817  0 getSkinExecutor().pressKeyboardShortcut(shortcut, withCtrlModifier, withAltModifier, withShiftModifier);
818    }
819   
820    /**
821    * Set global xwiki configuration options (as if the xwiki.cfg file had been modified). This is useful for testing
822    * configuration options.
823    *
824    * @param configuration the configuration in {@link Properties} format. For example "param1=value2\nparam2=value2"
825    * @throws IOException if an error occurs while parsing the configuration
826    */
 
827  2 toggle public void setXWikiConfiguration(String configuration) throws IOException
828    {
829  2 Properties properties = new Properties();
830  2 properties.load(new ByteArrayInputStream(configuration.getBytes()));
831  2 StringBuffer sb = new StringBuffer();
832   
833    // Since we don't have access to the XWiki object from Selenium tests and since we don't want to restart XWiki
834    // with a different xwiki.cfg file for each test that requires a configuration change, we use the following
835    // trick: We create a document and we access the XWiki object with a Velocity script inside that document.
836  2 for (Entry<Object, Object> param : properties.entrySet()) {
837  2 sb.append("{{velocity}}$xwiki.xWiki.config.setProperty('").append(param.getKey()).append("', '")
838    .append(param.getValue()).append("')").append("\n{{/velocity}}");
839    }
840  2 editInWikiEditor("Test", "XWikiConfigurationPageForTest", "xwiki/2.1");
841  2 setFieldValue("content", sb.toString());
842  2 clickEditSaveAndView();
843    }
844   
 
845  19 toggle @Override
846    public boolean copyPage(String spaceName, String pageName, String targetSpaceName, String targetPageName)
847    {
848  19 return getSkinExecutor().copyPage(spaceName, pageName, targetSpaceName, targetPageName);
849    }
850   
851    /**
852    * Waits for the specified live table to load.
853    *
854    * @param id the live table id
855    */
 
856  22 toggle public void waitForLiveTable(String id)
857    {
858  22 waitForElement("//*[@id = '" + id + "-ajax-loader' and @class = 'xwiki-livetable-loader hidden']");
859    }
860   
861    /**
862    * (Re)-cache the secret token used for CSRF protection. A user with edit rights on Main.WebHome must be logged in.
863    * This method must be called before {@link #getSecretToken()} is called and after each re-login.
864    *
865    * @since 3.2M1
866    * @see #getSecretToken()
867    */
 
868  344 toggle public void recacheSecretToken()
869    {
870  344 getUtil().recacheSecretToken();
871    }
872   
873    /**
874    * Get the secret token used for CSRF protection. Remember to call {@link #recacheSecretToken()} first.
875    *
876    * @return anti-CSRF secret token, or empty string if the token is not cached
877    * @since 3.2M1
878    * @see #recacheSecretToken()
879    */
 
880  445 toggle public String getSecretToken()
881    {
882  445 return getUtil().getSecretToken();
883    }
884   
885    /**
886    * Drags and drops the source element on top of the target element.
887    *
888    * @param sourceLocator locates the element to be dragged
889    * @param targetLocator locates the element where to drop the dragged element
890    */
 
891  6 toggle public void dragAndDrop(By sourceLocator, By targetLocator)
892    {
893    // Selenium#dragAndDropToObject(source, target) is not implemented over WebDriver.
894  6 WebDriver driver = getDriver();
895  6 WebElement source = driver.findElement(sourceLocator);
896  6 WebElement target = driver.findElement(targetLocator);
897    // Don't click in the middle of the element because it can contain a link.
898  6 new Actions(driver).moveToElement(source, 1, 1).clickAndHold().release(target).perform();
899    }
900   
901    /**
902    * Makes sure the specified element is not covered by the floating menu which is displayed at the top of the window.
903    * Use this method before clicking on an element that can end up beneath the floating menu.
904    *
905    * @param locator an element locator
906    */
 
907  570 toggle public void ensureElementIsNotCoveredByFloatingMenu(By locator)
908    {
909  570 WebDriver driver = getDriver();
910    // First scroll the element into view, if needed, by moving the mouse to the top left corner of the element.
911  570 new Actions(driver).moveToElement(driver.findElement(locator), 0, 0).perform();
912    // Then scroll the page up a bit so that the element is not at the top of the window where the floating menu is.
913  570 driver.findElement(By.xpath("//body")).sendKeys(Keys.ARROW_UP);
914    }
915   
916    /**
917    * Expands the object with the given number of the specified XClass. You need to call this method before editing any
918    * of the properties of the specified object using the object editor because the form elements used to edit the
919    * object properties have to be visible.
920    *
921    * @param className the XClass name
922    * @param objectNumber the object number
923    */
 
924  9 toggle public void expandObject(String className, int objectNumber)
925    {
926  9 String objectContentId = String.format("xobject_%s_%s_content", className, objectNumber);
927  9 if (!getDriver().findElement(By.id(objectContentId)).isDisplayed()) {
928    // First make sure that the group of objects of the specified class is expanded.
929  9 String objectTitleId = String.format("xobject_%s_%s_title", className, objectNumber);
930  9 WebElement objectTitle = getDriver().findElement(By.id(objectTitleId));
931  9 if (!objectTitle.isDisplayed()) {
932    // Expand the group of objects of the specified type.
933  0 getDriver().findElement(By.id(String.format("xclass_%s_title", className))).click();
934    }
935    // Expand the specified object.
936  9 objectTitle.click();
937    }
938    }
939   
940    /**
941    * @param elementLocator the locator used to get the desired element. e.g. By.id("someId")
942    * @return true if the element is in the window's viewport, i.e. is scrolled to; false otherwise.
943    * @since 6.2
944    */
 
945  12 toggle public boolean isElementInView(By elementLocator)
946    {
947  12 Point elementLocation = getDriver().findElement(elementLocator).getLocation();
948   
949  12 int windowXLeft = Integer.parseInt(getSelenium().getEval("window.scrollX"));
950  12 int windowYTop = Integer.parseInt(getSelenium().getEval("window.scrollY"));
951   
952  12 int width = Integer.parseInt(getSelenium().getEval("document.documentElement.clientWidth"));
953  12 int height = Integer.parseInt(getSelenium().getEval("document.documentElement.clientHeight"));
954   
955  12 int windowXRight = windowXLeft + width;
956  12 int windowYBottom = windowYTop + height;
957   
958  12 return (elementLocation.getX() >= windowXLeft && elementLocation.getX() <= windowXRight
959    && elementLocation.getY() >= windowYTop && elementLocation.getY() <= windowYBottom);
960    }
961   
962    /**
963    * Convenience method.
964    * @see #isElementInView(By)
965    * @since 6.2
966    */
 
967  12 toggle public void assertElementInView(By elementLocator)
968    {
969  12 Assert.assertTrue("[" + elementLocator + "] is not in view.", isElementInView(elementLocator));
970    }
971   
 
972  3 toggle public void clickAdministerWiki()
973    {
974  3 getSkinExecutor().clickAdministerWiki();
975    }
976    }