001    // Copyright 2007, 2008, 2009 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry5.test;
016    
017    import com.thoughtworks.selenium.CommandProcessor;
018    import com.thoughtworks.selenium.DefaultSelenium;
019    import com.thoughtworks.selenium.HttpCommandProcessor;
020    import com.thoughtworks.selenium.Selenium;
021    import org.openqa.selenium.server.RemoteControlConfiguration;
022    import org.openqa.selenium.server.SeleniumServer;
023    import org.testng.Assert;
024    import org.testng.annotations.AfterClass;
025    import org.testng.annotations.BeforeClass;
026    
027    /**
028     * A base class for creating integration tests. Ths encapsulates starting up an in-process copy of Jetty, and in-process
029     * copy of {@link SeleniumServer}, and a Selenium client.
030     * <p/>
031     * Unless you are <em>very, very clever</em>, you will want to run the tests sequentially. TestNG tends to run them in
032     * an arbitrary order unless you explicitly set the order. If you have managed to get TestNG to run tests in parallel,
033     * you may see further problems caused by a single client jumping all over your web application in an unpredictable
034     * order.
035     * <p/>
036     * This class implements the {@link Selenium} interface, and delegates all those methods to the {@link DefaultSelenium}
037     * instance it creates. It also extends the normal exception reporting for any failed command or query to produce a more
038     * detailed report to the main console.
039     *
040     * @see org.apache.tapestry5.test.JettyRunner
041     */
042    public class AbstractIntegrationTestSuite extends Assert implements Selenium
043    {
044        /**
045         * Default directory containing the web application to be tested (this conforms to Maven's default folder).
046         */
047        public static final String DEFAULT_WEB_APP_ROOT = "src/main/webapp";
048    
049        /**
050         * Default browser in which to run tests - firefox
051         */
052        public static final String DEFAULT_WEB_BROWSER_COMMAND = "*firefox";
053    
054        /**
055         * 15 seconds
056         */
057        public static final String PAGE_LOAD_TIMEOUT = "15000";
058    
059        /**
060         * The port on which the internal copy of Jetty is executed.
061         */
062        public static final int JETTY_PORT = 9999;
063    
064        // This is likely to be a problem, since may want to test with a context path, rather than as
065        // root.
066        public static final String BASE_URL = String.format("http://localhost:%d/", JETTY_PORT);
067    
068        public static final String SUBMIT = "//input[@type='submit']";
069    
070    
071        private String webappRoot;
072    
073        private final String seleniumBrowserCommand;
074    
075        private JettyRunner jettyRunner;
076    
077        private Selenium selenium;
078    
079        private SeleniumServer server;
080        
081        private String[] virtualHosts;
082    
083        /**
084         * Initializes the suite using {@link #DEFAULT_WEB_APP_ROOT}.
085         */
086        public AbstractIntegrationTestSuite()
087        {
088            this(DEFAULT_WEB_APP_ROOT, DEFAULT_WEB_BROWSER_COMMAND, new String[0]);
089        }
090    
091        /**
092         * @param webAppRoot the directory containing the web application to be tested.
093         */
094        protected AbstractIntegrationTestSuite(String webAppRoot)
095        {
096            this(webAppRoot, DEFAULT_WEB_BROWSER_COMMAND);
097        }
098    
099        /**
100         * @param webAppRoot     web application root (default src/main/webapp)
101         * @param browserCommand browser command to pass to selenium. Default is *firefox, syntax for custom browsers is
102         *                       *custom &lt;path_to_browser&gt;, e.g. *custom /usr/lib/mozilla-firefox/firefox
103         * @param virtualHosts an array with virtual hosts
104         */
105        protected AbstractIntegrationTestSuite(String webAppRoot, String browserCommand, String... virtualHosts)
106        {
107            webappRoot = webAppRoot;
108            seleniumBrowserCommand = browserCommand;
109            this.virtualHosts = virtualHosts;
110        }
111    
112        protected final void assertSourcePresent(String... expected)
113        {
114            String source = selenium.getHtmlSource();
115    
116            for (String snippet : expected)
117            {
118                if (source.contains(snippet)) continue;
119    
120                System.err.printf("Source content '%s' not found in:\n%s\n\n", snippet, source);
121    
122                throw new AssertionError("Page did not contain source '" + snippet + "'.");
123            }
124        }
125    
126        /**
127         * Used when the locator identifies an attribute, not an element.
128         *
129         * @param locator  identifies the attribute whose value is to be asserted
130         * @param expected expected value for the attribute
131         */
132        protected final void assertAttribute(String locator, String expected)
133        {
134            String actual = null;
135    
136            try
137            {
138                actual = getAttribute(locator);
139            }
140            catch (RuntimeException ex)
141            {
142                System.err.printf("Error accessing %s: %s, in:\n\n%s\n\n", locator, ex.getMessage(),
143                                  selenium.getHtmlSource());
144    
145                throw ex;
146            }
147    
148            if (actual.equals(expected)) return;
149    
150            System.err.printf("Text for attribute %s should be '%s' but is '%s', in:\n\n%s\n\n", locator, expected, actual,
151                              getHtmlSource());
152    
153            throw new AssertionError(String.format("%s was '%s' not '%s'", locator, actual, expected));
154        }
155    
156        /**
157         * Asserts the text of an element, identified by the locator.
158         *
159         * @param locator  identifies the element whose text value is to be asserted
160         * @param expected expected value for the element's text
161         */
162        protected final void assertText(String locator, String expected)
163        {
164            String actual = null;
165    
166            try
167            {
168                actual = getText(locator);
169            }
170            catch (RuntimeException ex)
171            {
172                System.err.printf("Error accessing %s: %s, in:\n\n%s\n\n", locator, ex.getMessage(),
173                                  selenium.getHtmlSource());
174    
175                throw ex;
176            }
177    
178            if (actual.equals(expected)) return;
179    
180            System.err.printf("Text for %s should be '%s' but is '%s', in:\n\n%s\n\n", locator, expected, actual,
181                              getHtmlSource());
182    
183            throw new AssertionError(String.format("%s was '%s' not '%s'", locator, actual, expected));
184        }
185    
186        protected final void assertTextPresent(String... text)
187        {
188            for (String item : text)
189            {
190                if (isTextPresent(item)) return;
191    
192                System.err.printf("Text pattern '%s' not found in:\n%s\n\n", item, selenium
193                        .getHtmlSource());
194    
195                throw new AssertionError("Page did not contain '" + item + "'.");
196            }
197        }
198    
199        protected final void assertFieldValue(String locator, String expected)
200        {
201            try
202            {
203                assertEquals(getValue(locator), expected);
204            }
205            catch (AssertionError ex)
206            {
207                System.err.printf("%s:\n%s\n\n", ex.getMessage(), selenium.getHtmlSource());
208    
209                throw ex;
210            }
211        }
212    
213        protected final void clickAndWait(String link)
214        {
215            click(link);
216            waitForPageToLoad(PAGE_LOAD_TIMEOUT);
217        }
218    
219        protected final void assertTextSeries(String idFormat, int startIndex, String... values)
220        {
221            for (int i = 0; i < values.length; i++)
222            {
223                String id = String.format(idFormat, startIndex + i);
224    
225                assertText(id, values[i]);
226            }
227        }
228    
229        protected final void assertAttributeSeries(String idFormat, int startIndex, String... values)
230        {
231            for (int i = 0; i < values.length; i++)
232            {
233                String id = String.format(idFormat, startIndex + i);
234    
235                assertAttribute(id, values[i]);
236            }
237        }
238    
239    
240        protected final void assertFieldValueSeries(String idFormat, int startIndex, String... values)
241        {
242            for (int i = 0; i < values.length; i++)
243            {
244                String id = String.format(idFormat, startIndex + i);
245    
246                assertFieldValue(id, values[i]);
247            }
248        }
249    
250        @AfterClass(alwaysRun = true)
251        public void cleanup() throws Exception
252        {
253            selenium.stop();
254            selenium = null;
255    
256            server.stop();
257            server = null;
258    
259            jettyRunner.stop();
260            jettyRunner = null;
261        }
262    
263        @BeforeClass(alwaysRun = true)
264        public void setup() throws Exception
265        {
266            jettyRunner = new JettyRunner(TapestryTestConstants.MODULE_BASE_DIR, "/", JETTY_PORT, webappRoot, virtualHosts);
267    
268            server = new SeleniumServer();
269    
270            server.start();
271    
272            CommandProcessor cp = new HttpCommandProcessor("localhost", RemoteControlConfiguration.DEFAULT_PORT,
273                                                           seleniumBrowserCommand, BASE_URL);
274    
275            selenium = new DefaultSelenium(new ErrorReportingCommandProcessor(cp));
276    
277            selenium.start();
278        }
279    
280        public void start()
281        {
282            selenium.start();
283        }
284    
285        public void stop()
286        {
287            selenium.stop();
288        }
289    
290        public void click(String locator)
291        {
292            selenium.click(locator);
293        }
294    
295        public void doubleClick(String locator)
296        {
297            selenium.doubleClick(locator);
298        }
299    
300        public void contextMenu(String locator)
301        {
302            selenium.contextMenu(locator);
303        }
304    
305        public void clickAt(String locator, String coordString)
306        {
307            selenium.clickAt(locator, coordString);
308        }
309    
310        public void doubleClickAt(String locator, String coordString)
311        {
312            selenium.doubleClickAt(locator, coordString);
313        }
314    
315        public void contextMenuAt(String locator, String coordString)
316        {
317            selenium.contextMenuAt(locator, coordString);
318        }
319    
320        public void fireEvent(String locator, String eventName)
321        {
322            selenium.fireEvent(locator, eventName);
323        }
324    
325        public void focus(String locator)
326        {
327            selenium.focus(locator);
328        }
329    
330        public void keyPress(String locator, String keySequence)
331        {
332            selenium.keyPress(locator, keySequence);
333        }
334    
335        public void shiftKeyDown()
336        {
337            selenium.shiftKeyDown();
338        }
339    
340        public void shiftKeyUp()
341        {
342            selenium.shiftKeyUp();
343        }
344    
345        public void metaKeyDown()
346        {
347            selenium.metaKeyDown();
348        }
349    
350        public void metaKeyUp()
351        {
352            selenium.metaKeyUp();
353        }
354    
355        public void altKeyDown()
356        {
357            selenium.altKeyDown();
358        }
359    
360        public void altKeyUp()
361        {
362            selenium.altKeyUp();
363        }
364    
365        public void controlKeyDown()
366        {
367            selenium.controlKeyDown();
368        }
369    
370        public void controlKeyUp()
371        {
372            selenium.controlKeyUp();
373        }
374    
375        public void keyDown(String locator, String keySequence)
376        {
377            selenium.keyDown(locator, keySequence);
378        }
379    
380        public void keyUp(String locator, String keySequence)
381        {
382            selenium.keyUp(locator, keySequence);
383        }
384    
385        public void mouseOver(String locator)
386        {
387            selenium.mouseOver(locator);
388        }
389    
390        public void mouseOut(String locator)
391        {
392            selenium.mouseOut(locator);
393        }
394    
395        public void mouseDown(String locator)
396        {
397            selenium.mouseDown(locator);
398        }
399    
400        public void mouseDownAt(String locator, String coordString)
401        {
402            selenium.mouseDownAt(locator, coordString);
403        }
404    
405        public void mouseUp(String locator)
406        {
407            selenium.mouseUp(locator);
408        }
409    
410        public void mouseUpAt(String locator, String coordString)
411        {
412            selenium.mouseUpAt(locator, coordString);
413        }
414    
415        public void mouseMove(String locator)
416        {
417            selenium.mouseMove(locator);
418        }
419    
420        public void mouseMoveAt(String locator, String coordString)
421        {
422            selenium.mouseMoveAt(locator, coordString);
423        }
424    
425        public void type(String locator, String value)
426        {
427            selenium.type(locator, value);
428        }
429    
430        public void typeKeys(String locator, String value)
431        {
432            selenium.typeKeys(locator, value);
433        }
434    
435        public void setSpeed(String value)
436        {
437            selenium.setSpeed(value);
438        }
439    
440        public String getSpeed()
441        {
442            return selenium.getSpeed();
443        }
444    
445        public void check(String locator)
446        {
447            selenium.check(locator);
448        }
449    
450        public void uncheck(String locator)
451        {
452            selenium.uncheck(locator);
453        }
454    
455        public void select(String selectLocator, String optionLocator)
456        {
457            selenium.select(selectLocator, optionLocator);
458        }
459    
460        public void addSelection(String locator, String optionLocator)
461        {
462            selenium.addSelection(locator, optionLocator);
463        }
464    
465        public void removeSelection(String locator, String optionLocator)
466        {
467            selenium.removeSelection(locator, optionLocator);
468        }
469    
470        public void removeAllSelections(String locator)
471        {
472            selenium.removeAllSelections(locator);
473        }
474    
475        public void submit(String formLocator)
476        {
477            selenium.submit(formLocator);
478        }
479    
480        public void open(String url)
481        {
482            selenium.open(url);
483        }
484    
485        public void openWindow(String url, String windowID)
486        {
487            selenium.openWindow(url, windowID);
488        }
489    
490        public void selectWindow(String windowID)
491        {
492            selenium.selectWindow(windowID);
493        }
494    
495        public void selectFrame(String locator)
496        {
497            selenium.selectFrame(locator);
498        }
499    
500        public boolean getWhetherThisFrameMatchFrameExpression(String currentFrameString, String target)
501        {
502            return selenium.getWhetherThisFrameMatchFrameExpression(currentFrameString, target);
503        }
504    
505        public boolean getWhetherThisWindowMatchWindowExpression(String currentWindowString, String target)
506        {
507            return selenium.getWhetherThisWindowMatchWindowExpression(currentWindowString, target);
508        }
509    
510        /**
511         * Waits the default time for the page to load.
512         */
513        public void waitForPageToLoad()
514        {
515            waitForPageToLoad(PAGE_LOAD_TIMEOUT);
516        }
517    
518        public void waitForPopUp(String windowID, String timeout)
519        {
520            selenium.waitForPopUp(windowID, timeout);
521        }
522    
523        public void chooseCancelOnNextConfirmation()
524        {
525            selenium.chooseCancelOnNextConfirmation();
526        }
527    
528        public void chooseOkOnNextConfirmation()
529        {
530            selenium.chooseOkOnNextConfirmation();
531        }
532    
533        public void answerOnNextPrompt(String answer)
534        {
535            selenium.answerOnNextPrompt(answer);
536        }
537    
538        public void goBack()
539        {
540            selenium.goBack();
541        }
542    
543        public void refresh()
544        {
545            selenium.refresh();
546        }
547    
548        public void close()
549        {
550            selenium.close();
551        }
552    
553        public boolean isAlertPresent()
554        {
555            return selenium.isAlertPresent();
556        }
557    
558        public boolean isPromptPresent()
559        {
560            return selenium.isPromptPresent();
561        }
562    
563        public boolean isConfirmationPresent()
564        {
565            return selenium.isConfirmationPresent();
566        }
567    
568        public String getAlert()
569        {
570            return selenium.getAlert();
571        }
572    
573        public String getConfirmation()
574        {
575            return selenium.getConfirmation();
576        }
577    
578        public String getPrompt()
579        {
580            return selenium.getPrompt();
581        }
582    
583        public String getLocation()
584        {
585            return selenium.getLocation();
586        }
587    
588        public String getTitle()
589        {
590            return selenium.getTitle();
591        }
592    
593        public String getBodyText()
594        {
595            return selenium.getBodyText();
596        }
597    
598        public String getValue(String locator)
599        {
600            return selenium.getValue(locator);
601        }
602    
603        public String getText(String locator)
604        {
605            return selenium.getText(locator);
606        }
607    
608        public void highlight(String locator)
609        {
610            selenium.highlight(locator);
611        }
612    
613        public String getEval(String script)
614        {
615            return selenium.getEval(script);
616        }
617    
618        public boolean isChecked(String locator)
619        {
620            return selenium.isChecked(locator);
621        }
622    
623        public String getTable(String tableCellAddress)
624        {
625            return selenium.getTable(tableCellAddress);
626        }
627    
628        public String[] getSelectedLabels(String selectLocator)
629        {
630            return selenium.getSelectedLabels(selectLocator);
631        }
632    
633        public String getSelectedLabel(String selectLocator)
634        {
635            return selenium.getSelectedLabel(selectLocator);
636        }
637    
638        public String[] getSelectedValues(String selectLocator)
639        {
640            return selenium.getSelectedValues(selectLocator);
641        }
642    
643        public String getSelectedValue(String selectLocator)
644        {
645            return selenium.getSelectedValue(selectLocator);
646        }
647    
648        public String[] getSelectedIndexes(String selectLocator)
649        {
650            return selenium.getSelectedIndexes(selectLocator);
651        }
652    
653        public String getSelectedIndex(String selectLocator)
654        {
655            return selenium.getSelectedIndex(selectLocator);
656        }
657    
658        public String[] getSelectedIds(String selectLocator)
659        {
660            return selenium.getSelectedIds(selectLocator);
661        }
662    
663        public String getSelectedId(String selectLocator)
664        {
665            return selenium.getSelectedId(selectLocator);
666        }
667    
668        public boolean isSomethingSelected(String selectLocator)
669        {
670            return selenium.isSomethingSelected(selectLocator);
671        }
672    
673        public String[] getSelectOptions(String selectLocator)
674        {
675            return selenium.getSelectOptions(selectLocator);
676        }
677    
678        public String getAttribute(String attributeLocator)
679        {
680            return selenium.getAttribute(attributeLocator);
681        }
682    
683        public boolean isTextPresent(String pattern)
684        {
685            return selenium.isTextPresent(pattern);
686        }
687    
688        public boolean isElementPresent(String locator)
689        {
690            return selenium.isElementPresent(locator);
691        }
692    
693        public boolean isVisible(String locator)
694        {
695            return selenium.isVisible(locator);
696        }
697    
698        public boolean isEditable(String locator)
699        {
700            return selenium.isEditable(locator);
701        }
702    
703        public String[] getAllButtons()
704        {
705            return selenium.getAllButtons();
706        }
707    
708        public String[] getAllLinks()
709        {
710            return selenium.getAllLinks();
711        }
712    
713        public String[] getAllFields()
714        {
715            return selenium.getAllFields();
716        }
717    
718        public String[] getAttributeFromAllWindows(String attributeName)
719        {
720            return selenium.getAttributeFromAllWindows(attributeName);
721        }
722    
723        public void dragdrop(String locator, String movementsString)
724        {
725            selenium.dragdrop(locator, movementsString);
726        }
727    
728        public void setMouseSpeed(String pixels)
729        {
730            selenium.setMouseSpeed(pixels);
731        }
732    
733        public Number getMouseSpeed()
734        {
735            return selenium.getMouseSpeed();
736        }
737    
738        public void dragAndDrop(String locator, String movementsString)
739        {
740            selenium.dragAndDrop(locator, movementsString);
741        }
742    
743        public void dragAndDropToObject(String locatorOfObjectToBeDragged, String locatorOfDragDestinationObject)
744        {
745            selenium.dragAndDropToObject(locatorOfObjectToBeDragged, locatorOfDragDestinationObject);
746        }
747    
748        public void windowFocus()
749        {
750            selenium.windowFocus();
751        }
752    
753        public void windowMaximize()
754        {
755            selenium.windowMaximize();
756        }
757    
758        public String[] getAllWindowIds()
759        {
760            return selenium.getAllWindowIds();
761        }
762    
763        public String[] getAllWindowNames()
764        {
765            return selenium.getAllWindowNames();
766        }
767    
768        public String[] getAllWindowTitles()
769        {
770            return selenium.getAllWindowTitles();
771        }
772    
773        public String getHtmlSource()
774        {
775            return selenium.getHtmlSource();
776        }
777    
778        public void setCursorPosition(String locator, String position)
779        {
780            selenium.setCursorPosition(locator, position);
781        }
782    
783        public Number getElementIndex(String locator)
784        {
785            return selenium.getElementIndex(locator);
786        }
787    
788        public boolean isOrdered(String locator1, String locator2)
789        {
790            return selenium.isOrdered(locator1, locator2);
791        }
792    
793        public Number getElementPositionLeft(String locator)
794        {
795            return selenium.getElementPositionLeft(locator);
796        }
797    
798        public Number getElementPositionTop(String locator)
799        {
800            return selenium.getElementPositionTop(locator);
801        }
802    
803        public Number getElementWidth(String locator)
804        {
805            return selenium.getElementWidth(locator);
806        }
807    
808        public Number getElementHeight(String locator)
809        {
810            return selenium.getElementHeight(locator);
811        }
812    
813        public Number getCursorPosition(String locator)
814        {
815            return selenium.getCursorPosition(locator);
816        }
817    
818        public String getExpression(String expression)
819        {
820            return selenium.getExpression(expression);
821        }
822    
823        public Number getXpathCount(String xpath)
824        {
825            return selenium.getXpathCount(xpath);
826        }
827    
828        public void assignId(String locator, String identifier)
829        {
830            selenium.assignId(locator, identifier);
831        }
832    
833        public void allowNativeXpath(String allow)
834        {
835            selenium.allowNativeXpath(allow);
836        }
837    
838        public void ignoreAttributesWithoutValue(String ignore)
839        {
840            selenium.ignoreAttributesWithoutValue(ignore);
841        }
842    
843        public void waitForCondition(String script, String timeout)
844        {
845            selenium.waitForCondition(script, timeout);
846        }
847    
848        public void setTimeout(String timeout)
849        {
850            selenium.setTimeout(timeout);
851        }
852    
853        public void waitForPageToLoad(String timeout)
854        {
855            selenium.waitForPageToLoad(timeout);
856        }
857    
858        public void waitForFrameToLoad(String frameAddress, String timeout)
859        {
860            selenium.waitForFrameToLoad(frameAddress, timeout);
861        }
862    
863        public String getCookie()
864        {
865            return selenium.getCookie();
866        }
867    
868        public String getCookieByName(String name)
869        {
870            return selenium.getCookieByName(name);
871        }
872    
873        public boolean isCookiePresent(String name)
874        {
875            return selenium.isCookiePresent(name);
876        }
877    
878        public void createCookie(String nameValuePair, String optionsString)
879        {
880            selenium.createCookie(nameValuePair, optionsString);
881        }
882    
883        public void deleteCookie(String name, String optionsString)
884        {
885            selenium.deleteCookie(name, optionsString);
886        }
887    
888        public void deleteAllVisibleCookies()
889        {
890            selenium.deleteAllVisibleCookies();
891        }
892    
893        public void setBrowserLogLevel(String logLevel)
894        {
895            selenium.setBrowserLogLevel(logLevel);
896        }
897    
898        public void runScript(String script)
899        {
900            selenium.runScript(script);
901        }
902    
903        public void addLocationStrategy(String strategyName, String functionDefinition)
904        {
905            selenium.addLocationStrategy(strategyName, functionDefinition);
906        }
907    
908        public void setContext(String context)
909        {
910            selenium.setContext(context);
911        }
912    
913        public void attachFile(String fieldLocator, String fileLocator)
914        {
915            selenium.attachFile(fieldLocator, fileLocator);
916        }
917    
918        public void captureScreenshot(String filename)
919        {
920            selenium.captureScreenshot(filename);
921        }
922    
923        public void shutDownSeleniumServer()
924        {
925            selenium.shutDownSeleniumServer();
926        }
927    
928        public void keyDownNative(String keycode)
929        {
930            selenium.keyDownNative(keycode);
931        }
932    
933        public void keyUpNative(String keycode)
934        {
935            selenium.keyUpNative(keycode);
936        }
937    
938        public void keyPressNative(String keycode)
939        {
940            selenium.keyPressNative(keycode);
941        }
942    
943        /**
944         * Used to start a typical test, by opening to the base URL and clicking through a series of links.
945         * <p/>
946         * Note: Selenium 1.0-beta-2 has introduced a method start(String) which is distinct from this implementation (which
947         * dates back to Tapestry 5.0 and Selenium 1.0-beta-1).
948         */
949        protected final void start(String... linkText)
950        {
951            open(BASE_URL);
952    
953            for (String s : linkText)
954                clickAndWait(String.format("link=%s", s));
955        }
956    
957        public String getWebappRoot()
958        {
959            return webappRoot;
960        }
961    
962        public void setWebappRoot(String webappRoot)
963        {
964            this.webappRoot = webappRoot;
965        }
966    
967        /**
968         * @since 5.1.0.0
969         */
970        public void setExtensionJs(String extensionJs)
971        {
972            selenium.setExtensionJs(extensionJs);
973        }
974    
975        /**
976         * @since 5.1.0.0
977         */
978        public void start(Object optionsObject)
979        {
980            selenium.start(optionsObject);
981        }
982    
983        /**
984         * @since 5.1.0.0
985         */
986        public void showContextualBanner()
987        {
988            selenium.showContextualBanner();
989        }
990    
991        /**
992         * @since 5.1.0.0
993         */
994        public void showContextualBanner(String className, String methodName)
995        {
996            selenium.showContextualBanner(className, methodName);
997        }
998    
999        /**
1000         * @since 5.1.0.0
1001         */
1002        public void mouseDownRight(String locator)
1003        {
1004            selenium.mouseDownRight(locator);
1005        }
1006    
1007        /**
1008         * @since 5.1.0.0
1009         */
1010        public void mouseDownRightAt(String locator, String coordString)
1011        {
1012            selenium.mouseDownRightAt(locator, coordString);
1013        }
1014    
1015        /**
1016         * @since 5.1.0.0
1017         */
1018        public void captureEntirePageScreenshot(String filename, String kwargs)
1019        {
1020            selenium.captureEntirePageScreenshot(filename, kwargs);
1021        }
1022    
1023        /**
1024         * @since 5.1.0.0
1025         */
1026        public void rollup(String rollupName, String kwargs)
1027        {
1028            selenium.rollup(rollupName, kwargs);
1029        }
1030    
1031        /**
1032         * @since 5.1.0.0
1033         */
1034        public void addScript(String scriptContent, String scriptTagId)
1035        {
1036            selenium.addScript(scriptContent, scriptTagId);
1037        }
1038    
1039        /**
1040         * @since 5.1.0.0
1041         */
1042        public void removeScript(String scriptTagId)
1043        {
1044            selenium.removeScript(scriptTagId);
1045        }
1046    
1047        /**
1048         * @since 5.1.0.0
1049         */
1050        public void useXpathLibrary(String libraryName)
1051        {
1052            selenium.useXpathLibrary(libraryName);
1053        }
1054    
1055        /**
1056         * @since 5.1.0.0
1057         */
1058        public String captureScreenshotToString()
1059        {
1060            return selenium.captureScreenshotToString();
1061        }
1062    
1063        /**
1064         * @since 5.1.0.0
1065         */
1066        public String captureEntirePageScreenshotToString(String kwargs)
1067        {
1068            return selenium.captureEntirePageScreenshotToString(kwargs);
1069        }
1070    
1071        /**
1072         * @since 5.1.0.0
1073         */
1074        public String retrieveLastRemoteControlLogs()
1075        {
1076            return selenium.retrieveLastRemoteControlLogs();
1077        }
1078    
1079        /**
1080         * @since 5.1.0.0
1081         */
1082        public void mouseUpRight(String locator)
1083        {
1084            selenium.mouseUpRight(locator);
1085        }
1086    
1087        /**
1088         * @since 5.1.0.0
1089         */
1090        public void mouseUpRightAt(String locator, String coordString)
1091        {
1092            selenium.mouseUpRightAt(locator, coordString);
1093        }
1094    
1095        /**
1096         * This does NOT invoke {@link com.thoughtworks.selenium.Selenium#start(String)}; it invokes {@link
1097         * #start(String[])}.  This is necesasry due to the introduction of the start() method.
1098         *
1099         * @param linkText text of link to click
1100         * @since 5.1.0.0
1101         */
1102        public void start(String linkText)
1103        {
1104            start(new String[] { linkText });
1105        }
1106    }