...34import org.openqa.selenium.Point;35import org.openqa.selenium.Rotatable;36import org.openqa.selenium.ScreenOrientation;37import org.openqa.selenium.TakesScreenshot;38import org.openqa.selenium.UnsupportedCommandException;39import org.openqa.selenium.WebDriver;40import org.openqa.selenium.WebDriverException;41import org.openqa.selenium.WebElement;42import org.openqa.selenium.interactions.internal.Coordinates;43import org.openqa.selenium.internal.Locatable;44import org.openqa.selenium.internal.WrapsDriver;45import org.openqa.selenium.internal.WrapsElement;46import org.openqa.selenium.logging.Logs;47import org.openqa.selenium.remote.Augmenter;48import org.openqa.selenium.remote.RemoteWebElement;49import org.openqa.selenium.remote.Response;50import org.openqa.selenium.security.Credentials;51import org.openqa.selenium.support.events.EventFiringWebDriver;52import org.primitive.webdriverencapsulations.eventlisteners.IExtendedWebDriverEventListener;53import org.primitive.webdriverencapsulations.interfaces.IComplexFind;54import org.primitive.webdriverencapsulations.interfaces.IGetsAppStrings;55import org.primitive.webdriverencapsulations.interfaces.IGetsNamedTextField;56import org.primitive.webdriverencapsulations.interfaces.IHasActivity;57import org.primitive.webdriverencapsulations.interfaces.IHidesKeyboard;58import org.primitive.webdriverencapsulations.interfaces.IPerformsTouchActions;59import org.primitive.webdriverencapsulations.interfaces.IPinch;60import org.primitive.webdriverencapsulations.interfaces.IScrollsTo;61import org.primitive.webdriverencapsulations.interfaces.ISendsKeyEvent;62import org.primitive.webdriverencapsulations.interfaces.ISendsMetastateKeyEvent;63import org.primitive.webdriverencapsulations.interfaces.IShakes;64import org.primitive.webdriverencapsulations.interfaces.ISwipe;65import org.primitive.webdriverencapsulations.interfaces.ITap;66import org.primitive.webdriverencapsulations.interfaces.IZoom;6768/**69 * @author s.tihomirov For some functions of EventFiringWebDriver70 */71public class ClosedFiringWebDriver extends EventFiringWebDriver72 implements HasCapabilities, MobileDriver, Rotatable, FindsByIosUIAutomation,73 FindsByAndroidUIAutomator, FindsByAccessibilityId, IHasActivity, IPerformsTouchActions, IGetsAppStrings,74 ISendsKeyEvent, ISendsMetastateKeyEvent, ITap, ISwipe, IPinch, IZoom, IScrollsTo, IGetsNamedTextField,75 IHidesKeyboard, IShakes, IComplexFind76 {7778 static class DefaultTimeouts implements Timeouts {79 private Timeouts timeouts;80 private ClosedFiringWebDriver driver;8182 private DefaultTimeouts(Timeouts timeouts,83 ClosedFiringWebDriver driver) {84 this.timeouts = timeouts;85 this.driver = driver;86 }8788 @Override89 public Timeouts implicitlyWait(long arg0, TimeUnit arg1) {90 driver.extendedDispatcher.beforeWebDriverSetTimeOut(91 driver.originalDriver, timeouts, arg0, arg1);92 timeouts.implicitlyWait(arg0, arg1);93 driver.extendedDispatcher.afterWebDriverSetTimeOut(94 driver.originalDriver, timeouts, arg0, arg1);95 return timeouts;96 }9798 @Override99 public Timeouts pageLoadTimeout(long arg0, TimeUnit arg1) {100 driver.extendedDispatcher.beforeWebDriverSetTimeOut(101 driver.originalDriver, timeouts, arg0, arg1);102 timeouts.pageLoadTimeout(arg0, arg1);103 driver.extendedDispatcher.afterWebDriverSetTimeOut(104 driver.originalDriver, timeouts, arg0, arg1);105 return timeouts;106 }107108 @Override109 public Timeouts setScriptTimeout(long arg0, TimeUnit arg1) {110 driver.extendedDispatcher.beforeWebDriverSetTimeOut(111 driver.originalDriver, timeouts, arg0, arg1);112 timeouts.setScriptTimeout(arg0, arg1);113 driver.extendedDispatcher.afterWebDriverSetTimeOut(114 driver.originalDriver, timeouts, arg0, arg1);115 return timeouts;116 }117118 }119120 /**121 * @author s.tihomirov122 * 123 */124 static class DefaultOptions implements Options {125 private Options option;126 private ClosedFiringWebDriver driver;127128 private DefaultOptions(Options option,129 ClosedFiringWebDriver driver) {130 this.option = option;131 this.driver = driver;132 }133134 @Override135 public void addCookie(Cookie cookie) {136 option.addCookie(cookie);137 }138139 @Override140 public void deleteAllCookies() {141 option.deleteAllCookies();142 }143144 @Override145 public void deleteCookie(Cookie cookie) {146 option.deleteCookie(cookie);147 }148149 @Override150 public void deleteCookieNamed(String cookieName) {151 option.deleteCookieNamed(cookieName);152 }153154 @Override155 public Cookie getCookieNamed(String cookieName) {156 return option.getCookieNamed(cookieName);157 }158159 @Override160 public Set<Cookie> getCookies() {161 return option.getCookies();162 }163164 @Override165 public ImeHandler ime() {166 return option.ime();167 }168169 @Override170 @Beta171 public Logs logs() {172 return option.logs();173 }174175 @Override176 public Timeouts timeouts() {177 return new DefaultTimeouts(option.timeouts(),178 driver);179 }180181 @Override182 @Beta183 public Window window() {184 return option.window();185 }186187 }188189 /**190 * @author s.tihomirov191 * 192 */193 static class DefaultTargetLocator implements194 TargetLocator {195 private TargetLocator targetLocator;196 private ClosedFiringWebDriver driver;197198 private DefaultTargetLocator(TargetLocator targetLocator,199 ClosedFiringWebDriver driver) {200 this.targetLocator = targetLocator;201 this.driver = driver;202 }203204 @Override205 public WebElement activeElement() {206 return new DefaultWebElement(207 targetLocator.activeElement(), driver);208 }209210 @Override211 public Alert alert() {212 return new DefaultAlert(targetLocator.alert(), driver);213 }214215 @Override216 public WebDriver defaultContent() {217 targetLocator.defaultContent();218 return driver;219 }220221 @Override222 public WebDriver frame(int arg0) {223 targetLocator.frame(arg0);224 return driver;225 }226227 @Override228 public WebDriver frame(String arg0) {229 targetLocator.frame(arg0);230 return driver;231 }232233 @Override234 public WebDriver frame(WebElement arg0) {235 targetLocator.frame(arg0);236 return driver;237 }238239 @Override240 public WebDriver window(String arg0) {241 targetLocator.window(arg0);242 return driver;243 }244245 @Override246 public WebDriver parentFrame() {247 targetLocator.parentFrame();248 return driver;249 }250251 }252253 /**254 * @author s.tihomirov For some functions of EventFiringWebEvement255 */256 static class DefaultWebElement implements WebElement,257 Locatable, WrapsElement, FindsByAccessibilityId, FindsByAndroidUIAutomator,258 FindsByIosUIAutomation{259 private final WebElement element;260 private WebElement wrapped;261 private ClosedFiringWebDriver extendedDriver;262263 private DefaultWebElement(final WebElement element,264 ClosedFiringWebDriver driver) {265 wrapped = element;266 this.extendedDriver = driver;267 268 this.element = (WebElement) Proxy.newProxyInstance(269 IExtendedWebDriverEventListener.class.getClassLoader(),270 element.getClass().getInterfaces(),271 new InvocationHandler() {272 public Object invoke(Object proxy, Method method,273 Object[] args) throws Throwable {274 try {275 return method.invoke(element, args);276 } catch (InvocationTargetException e) {277 extendedDriver.extendedDispatcher.onException(278 e.getTargetException(),279 extendedDriver.originalDriver);280 throw e.getTargetException();281 }282 }283 });284 }285286 @Override287 public void clear() {288 element.clear();289 }290291 @Override292 public void click() {293 element.click();294 }295296 @Override297 public WebElement findElement(By by) {298 return new DefaultWebElement(element.findElement(by), extendedDriver);299 }300301 @Override302 public List<WebElement> findElements(By by) {303 List<WebElement> temp = element.findElements(by);304 return extendedDriver.getDefaultElementList(temp);305 }306307 @Override308 public String getAttribute(String arg0) {309 return element.getAttribute(arg0);310 }311312 @Override313 public String getCssValue(String arg0) {314 return element.getCssValue(arg0);315 }316317 @Override318 public Point getLocation() {319 return element.getLocation();320 }321322 @Override323 public Dimension getSize() {324 return element.getSize();325 }326327 @Override328 public String getTagName() {329 return element.getTagName();330 }331332 @Override333 public String getText() {334 return element.getText();335 }336337 @Override338 public boolean isDisplayed() {339 return element.isDisplayed();340 }341342 @Override343 public boolean isEnabled() {344 return element.isEnabled();345 }346347 @Override348 public boolean isSelected() {349 return element.isSelected();350 }351352 @Override353 public void sendKeys(CharSequence... arg0) {354 element.sendKeys(arg0);355 }356357 @Override358 public void submit() {359 extendedDriver.extendedDispatcher.beforeSubmit(360 extendedDriver.originalDriver, wrapped);361 element.submit();362 extendedDriver.extendedDispatcher.afterSubmit(363 extendedDriver.originalDriver, wrapped);364 }365366 @Override367 public Coordinates getCoordinates() {368 return ((Locatable) element).getCoordinates();369370 }371372 public WebElement getWrappedElement() {373 return extendedDriver.unpackOriginalElement(wrapped);374 }375376 @Override377 public WebElement findElementByIosUIAutomation(String arg0) {378 MobileElement me = new MobileElement(379 extendedDriver.unpackOriginalElement(wrapped),380 extendedDriver);381 WebElement temp = me.findElementByIosUIAutomation(arg0);382 return new DefaultWebElement(temp, extendedDriver);383 }384385 @Override386 public List<WebElement> findElementsByIosUIAutomation(String arg0) {387 MobileElement me = new MobileElement(388 extendedDriver.unpackOriginalElement(wrapped),389 extendedDriver);390 List<WebElement> temp = me.findElementsByIosUIAutomation(arg0);391 return extendedDriver.getDefaultElementList(temp);392 }393394 @Override395 public WebElement findElementByAndroidUIAutomator(String arg0) {396 MobileElement me = new MobileElement(397 extendedDriver.unpackOriginalElement(wrapped),398 extendedDriver);399 WebElement temp = me.findElementByAndroidUIAutomator(arg0);400 return new DefaultWebElement(temp, extendedDriver);401 }402403 @Override404 public List<WebElement> findElementsByAndroidUIAutomator(String arg0) {405 MobileElement me = new MobileElement(406 extendedDriver.unpackOriginalElement(wrapped),407 extendedDriver);408 List<WebElement> temp = me.findElementsByAndroidUIAutomator(arg0);409 return extendedDriver.getDefaultElementList(temp);410 }411412 @Override413 public WebElement findElementByAccessibilityId(String arg0) {414 MobileElement me = new MobileElement(415 extendedDriver.unpackOriginalElement(wrapped),416 extendedDriver);417 WebElement temp = me.findElementByAccessibilityId(arg0);418 return new DefaultWebElement(temp, extendedDriver);419 }420421 @Override422 public List<WebElement> findElementsByAccessibilityId(String arg0) {423 MobileElement me = new MobileElement(424 extendedDriver.unpackOriginalElement(wrapped),425 extendedDriver);426 List<WebElement> temp = me.findElementsByAccessibilityId(arg0);427 return extendedDriver.getDefaultElementList(temp);428 }429 }430431 /**432 * @author s.tihomirov433 * 434 */435 static class DefaultAlert implements Alert {436 private Alert alert;437 private ClosedFiringWebDriver driver;438439 private DefaultAlert(Alert alert,440 ClosedFiringWebDriver driver) {441 this.alert = alert;442 this.driver = driver;443 }444445 @Override446 public void accept() {447 driver.extendedDispatcher.beforeAlertAccept(448 driver.originalDriver, alert);449 alert.accept();450 driver.extendedDispatcher.afterAlertAccept(451 driver.originalDriver, alert);452 }453454 @Override455 @Beta456 public void authenticateUsing(Credentials arg0) {457 alert.authenticateUsing(arg0);458 }459460 @Override461 public void dismiss() {462 driver.extendedDispatcher.beforeAlertDismiss(463 driver.originalDriver, alert);464 alert.dismiss();465 driver.extendedDispatcher.afterAlertDismiss(466 driver.originalDriver, alert);467 }468469 @Override470 public String getText() {471 return alert.getText();472 }473474 @Override475 public void sendKeys(String arg0) {476 driver.extendedDispatcher.beforeAlertSendKeys(477 driver.originalDriver, alert, arg0);478 alert.sendKeys(arg0);479 driver.extendedDispatcher.afterAlertSendKeys(480 driver.originalDriver, alert, arg0);481 }482483 }484485 private final List<IExtendedWebDriverEventListener> extendedEventListeners = new ArrayList<IExtendedWebDriverEventListener>();486487 private final WebDriver originalDriver;488 private final IExtendedWebDriverEventListener extendedDispatcher = (IExtendedWebDriverEventListener) Proxy489 .newProxyInstance(490 IExtendedWebDriverEventListener.class.getClassLoader(),491 new Class[] { IExtendedWebDriverEventListener.class },492 new InvocationHandler() {493 public Object invoke(Object proxy, Method method,494 Object[] args) throws Throwable {495 for (IExtendedWebDriverEventListener eventListener : extendedEventListeners) {496 method.invoke(eventListener, args);497 }498 return null;499 }500 });501502 ClosedFiringWebDriver(WebDriver driver) {503 super(driver);504 originalDriver = driver;505 }506507 public void register(IExtendedWebDriverEventListener eventListener) {508 super.register(eventListener);509 extendedEventListeners.add(eventListener);510 }511512 public void unregister(IExtendedWebDriverEventListener eventListener) {513 super.unregister(eventListener);514 extendedEventListeners.remove(eventListener);515 }516517 public Capabilities getCapabilities() {518 return ((HasCapabilities) originalDriver).getCapabilities();519 }520521 public WebDriver.TargetLocator switchTo() {522 WebDriver.TargetLocator target = super.switchTo();523 return new DefaultTargetLocator(target, this);524 }525526 public List<WebElement> findElements(By by) {527 List<WebElement> temp = super.findElements(by);528 return getDefaultElementList(temp);529 }530531 public WebElement findElement(By by) {532 WebElement temp = super.findElement(by);533 return new DefaultWebElement(temp, this);534 }535536 public Options manage() {537 Options option = super.manage();538 return new DefaultOptions(option, this);539 }540541 public <X> X getScreenshotAs(OutputType<X> target) {542 X result = null;543 try {544 result = ((TakesScreenshot) originalDriver).getScreenshotAs(target);545 } catch (ClassCastException e) {546 WebDriver augmentedDriver = new Augmenter().augment(originalDriver);547 result = ((TakesScreenshot) augmentedDriver).getScreenshotAs(target);548 }549 return result;550 }551 552 /**553 * It seals wrapped driver forever554 */555 @Deprecated556 @Override557 public WebDriver getWrappedDriver(){558 //I exclude wrapsDriver from this and super class559 Class<?>[] implemented = ClosedFiringWebDriver.class.getInterfaces();560 Class<?>[] implementedBySuper = EventFiringWebDriver.class561 .getInterfaces();562 563 Class<?>[] editedInterfaceArray = new Class<?>[(implemented.length + implementedBySuper.length)-1];564 565 int index = 0;566 for (int i=0; i<implemented.length; i++){567 if (!implemented[i].equals(WrapsDriver.class)){568 editedInterfaceArray[index] = implemented[i]; 569 index++;570 }571 }572 573 for (int i=0; i<implementedBySuper.length; i++){574 if (!implementedBySuper[i].equals(WrapsDriver.class)){575 editedInterfaceArray[index] = implementedBySuper[i]; 576 index++;577 }578 }579580 581 // and create proxy object582 final ClosedFiringWebDriver proxyfied = this;583 WebDriver sealedDriver = (WebDriver) Proxy.newProxyInstance(584 WebDriver.class.getClassLoader(), editedInterfaceArray,585 new InvocationHandler() {586 public Object invoke(Object proxy, Method method,587 Object[] args) throws Throwable {588 try {589 return method.invoke(proxyfied, args);590 } catch (Exception e) {591 throw e;592 }593 }594 });595596 return sealedDriver; 597 }598599 @Override600 public WebDriver context(String name) {601 ((MobileDriver) originalDriver).context(name);602 return this;603 }604605 @Override606 public Set<String> getContextHandles() {607 return ((MobileDriver) originalDriver).getContextHandles();608 }609610 @Override611 public String getContext() {612 return ((MobileDriver) originalDriver).getContext();613 }614615 @Override616 public Response execute(String driverCommand, Map<String, ?> parameters) {617 return ((MobileDriver) originalDriver).execute(driverCommand,618 parameters);619 }620621 @Override622 public TouchAction performTouchAction(TouchAction touchAction) {623 return ((MobileDriver) originalDriver)624 .performTouchAction(touchAction);625 }626627 @Override628 public void performMultiTouchAction(MultiTouchAction multiAction) {629 ((MobileDriver) originalDriver)630 .performMultiTouchAction(multiAction);631 }632633 @Override634 public void rotate(ScreenOrientation orientation) {635 ((Rotatable) originalDriver).rotate(orientation); 636 }637638 @Override639 public ScreenOrientation getOrientation() {640 return ((Rotatable) originalDriver).getOrientation();641 }642643 @Override644 public WebElement findElementByIosUIAutomation(String using) {645 WebElement temp = super.findElement(MobileBy.IosUIAutomation(using));646 return new DefaultWebElement(temp, this);647 }648649 @Override650 public List<WebElement> findElementsByIosUIAutomation(String using) {651 List<WebElement> temp = super.findElements(MobileBy.IosUIAutomation(using));652 return getDefaultElementList(temp);653 }654655 @Override656 public WebElement findElementByAndroidUIAutomator(String using) {657 WebElement temp = super.findElement(MobileBy.AndroidUIAutomator(using));658 return new DefaultWebElement(temp, this);659 }660661 @Override662 public List<WebElement> findElementsByAndroidUIAutomator(String using) {663 List<WebElement> temp = super.findElements(MobileBy.AndroidUIAutomator(using));664 return getDefaultElementList(temp);665 }666667 @Override668 public WebElement findElementByAccessibilityId(String using) {669 WebElement temp = super.findElement(MobileBy.AccessibilityId(using));670 return new DefaultWebElement(temp, this);671 }672673 @Override674 public List<WebElement> findElementsByAccessibilityId(String using) {675 List<WebElement> temp = super.findElements(MobileBy676 .AccessibilityId(using));677 return getDefaultElementList(temp);678 }679 680681 @Override682 public String currentActivity() {683 try {684 return ((AppiumDriver) originalDriver).currentActivity();685 } catch (ClassCastException e) {686 throw new UnsupportedCommandException(687 "Getting activity is not supported by "688 + originalDriver.getClass().getSimpleName());689 }690 catch (WebDriverException e){691 return ""; //iOS Appium tools don't support getting of activity. It is frustrating.692 }693 }694695 @Override696 public String getAppStrings() {697 try {698 return ((AppiumDriver) originalDriver).getAppStrings();699 } catch (ClassCastException e) {700 throw new UnsupportedCommandException(701 "Getting App Strings is not supported");702 }703 }704705 @Override706 public String getAppStrings(String language) {707 try {708 return ((AppiumDriver) originalDriver).getAppStrings(language);709 } catch (ClassCastException e) {710 throw new UnsupportedCommandException(711 "Getting App Strings is not supported. Requred language is " + language);712 }713 }714715 @Override716 public void sendKeyEvent(int key, Integer metastate) {717 try {718 ((AppiumDriver) originalDriver).sendKeyEvent(key, metastate);719 } catch (ClassCastException e) {720 throw new UnsupportedCommandException(721 "Metastate key event sending is not supported.");722 } 723 }724725 @Override726 public void sendKeyEvent(int key) {727 try {728 ((AppiumDriver) originalDriver).sendKeyEvent(key);729 } catch (ClassCastException e) {730 throw new UnsupportedCommandException(731 "Key event sending is not supported.");732 } 733 }734735 @Override736 public void tap(int fingers, WebElement element, int duration) {737 try {738 ((AppiumDriver) originalDriver).tap(fingers, unpackOriginalElement(element), 739 duration);740 } catch (ClassCastException e) {741 throw new UnsupportedCommandException(742 "Tap is not supported.");743 } 744 }745746 @Override747 public void tap(int fingers, int x, int y, int duration) {748 try {749 ((AppiumDriver) originalDriver).tap(fingers, x, y, duration);;750 } catch (ClassCastException e) {751 throw new UnsupportedCommandException(752 "Tap is not supported.");753 }754 }755756 private List<WebElement> getDefaultElementList(List<WebElement> originalList){757 List<WebElement> result = new ArrayList<WebElement>();758 for (WebElement element : originalList) {759 result.add(new DefaultWebElement(element, this));760 }761 return result; 762 }763 764 private RemoteWebElement unpackOriginalElement(WebElement original){765 while (original instanceof WrapsElement) {766 original = ((WrapsElement) original).getWrappedElement(); 767 }768 return (RemoteWebElement) original;769 }770771 @Override772 public void swipe(int startx, int starty, int endx, int endy, int duration) {773 try {774 ((AppiumDriver) originalDriver).swipe(startx, starty, endx, endy, duration);775 } catch (ClassCastException e) {776 throw new UnsupportedCommandException(777 "Swipe is not supported.");778 } 779 }780781 @Override782 public void pinch(WebElement el) {783 try {784 ((AppiumDriver) originalDriver).pinch(unpackOriginalElement(el));785 } catch (ClassCastException e) {786 throw new UnsupportedCommandException(787 "Pinch is not supported.");788 } 789 }790791 @Override792 public void pinch(int x, int y) {793 try {794 ((AppiumDriver) originalDriver).pinch(x,y);795 } catch (ClassCastException e) {796 throw new UnsupportedCommandException(797 "Pinch is not supported.");798 } 799 }800801 @Override802 public void zoom(WebElement el) {803 try {804 ((AppiumDriver) originalDriver).zoom(unpackOriginalElement(el));805 } catch (ClassCastException e) {806 throw new UnsupportedCommandException(807 "Zoom is not supported.");808 } 809 }810811 @Override812 public void zoom(int x, int y) {813 try {814 ((AppiumDriver) originalDriver).zoom(x,y);815 } catch (ClassCastException e) {816 throw new UnsupportedCommandException(817 "Zoom is not supported.");818 } 819 }820821 @Override822 public WebElement scrollTo(String text) {823 try {824 return new DefaultWebElement(((AppiumDriver) originalDriver).scrollTo(text), this);825 } catch (ClassCastException e) {826 throw new UnsupportedCommandException(827 "Scroll is not supported.");828 }829 }830831 @Override832 public WebElement scrollToExact(String text) {833 try {834 return new DefaultWebElement(((AppiumDriver) originalDriver).scrollToExact(text), this);835 } catch (ClassCastException e) {836 throw new UnsupportedCommandException(837 "Scroll to exact is not supported.");838 }839 }840841 @Override842 public void hideKeyboard(String keyName) {843 try {844 ((AppiumDriver) originalDriver).hideKeyboard(keyName);845 } catch (ClassCastException e) {846 throw new UnsupportedCommandException(847 "Keydoard hiding is not supported.");848 } 849 }850851 @Override852 public void hideKeyboard() {853 try {854 ((AppiumDriver) originalDriver).hideKeyboard();855 } catch (ClassCastException e) {856 throw new UnsupportedCommandException(857 "Keydoard hiding is not supported.");858 } 859 }860861 @Override862 public WebElement getNamedTextField(String name) {863 try {864 return new DefaultWebElement(((AppiumDriver) originalDriver).getNamedTextField(name), this);865 } catch (ClassCastException e) {866 throw new UnsupportedCommandException(867 "Named text field getting is not supported.");868 } 869 }870871 @Override872 public void shake() {873 try {874 ((AppiumDriver) originalDriver).shake();875 } catch (ClassCastException e) {876 throw new UnsupportedCommandException(877 "Shaking is not supported.");878 } 879 }880881 @Override882 public WebElement complexFind(String complex) {883 try {884 return new DefaultWebElement(((AppiumDriver) originalDriver).complexFind(complex), this);885 } catch (ClassCastException e) {886 throw new UnsupportedCommandException(887 "Named text field getting is not supported.");888 } 889 }
...