1cddda72410c992a12db61cef26713b498e31fea4Thanh Le/* 2cddda72410c992a12db61cef26713b498e31fea4Thanh Le * Copyright (C) 2013 DroidDriver committers 3cddda72410c992a12db61cef26713b498e31fea4Thanh Le * 4cddda72410c992a12db61cef26713b498e31fea4Thanh Le * Licensed under the Apache License, Version 2.0 (the "License"); 5cddda72410c992a12db61cef26713b498e31fea4Thanh Le * you may not use this file except in compliance with the License. 6cddda72410c992a12db61cef26713b498e31fea4Thanh Le * You may obtain a copy of the License at 7cddda72410c992a12db61cef26713b498e31fea4Thanh Le * 8cddda72410c992a12db61cef26713b498e31fea4Thanh Le * http://www.apache.org/licenses/LICENSE-2.0 9cddda72410c992a12db61cef26713b498e31fea4Thanh Le * 10cddda72410c992a12db61cef26713b498e31fea4Thanh Le * Unless required by applicable law or agreed to in writing, software 11cddda72410c992a12db61cef26713b498e31fea4Thanh Le * distributed under the License is distributed on an "AS IS" BASIS, 12cddda72410c992a12db61cef26713b498e31fea4Thanh Le * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cddda72410c992a12db61cef26713b498e31fea4Thanh Le * See the License for the specific language governing permissions and 14cddda72410c992a12db61cef26713b498e31fea4Thanh Le * limitations under the License. 15cddda72410c992a12db61cef26713b498e31fea4Thanh Le */ 16cddda72410c992a12db61cef26713b498e31fea4Thanh Le 17cddda72410c992a12db61cef26713b498e31fea4Thanh Lepackage com.google.android.droiddriver.base; 18cddda72410c992a12db61cef26713b498e31fea4Thanh Le 19cddda72410c992a12db61cef26713b498e31fea4Thanh Leimport com.google.android.droiddriver.DroidDriver; 20cddda72410c992a12db61cef26713b498e31fea4Thanh Leimport com.google.android.droiddriver.Poller; 21cddda72410c992a12db61cef26713b498e31fea4Thanh Leimport com.google.android.droiddriver.UiElement; 2274676fdd3c8a9e599eddd13bea56898674d9916aKevin Jinimport com.google.android.droiddriver.actions.InputInjector; 237b1b7d4561b60f8b3bcd7c2d592454dd7bfef619Kevin Jinimport com.google.android.droiddriver.exceptions.ElementNotFoundException; 246a6c19d612923a0350ab46898df513c66bac2d66Kevin Jinimport com.google.android.droiddriver.exceptions.TimeoutException; 257576fbbba2bf515908b45293b7156b5bfe088938Kevin Jinimport com.google.android.droiddriver.finders.ByXPath; 267576fbbba2bf515908b45293b7156b5bfe088938Kevin Jinimport com.google.android.droiddriver.finders.Finder; 276316362de61fca700d7d5a455ad5c0ac9717c365Kevin Jinimport com.google.android.droiddriver.util.Logs; 28cddda72410c992a12db61cef26713b498e31fea4Thanh Le 29cddda72410c992a12db61cef26713b498e31fea4Thanh Le/** 307c8b54f99e678a1b40b98fc3069217877ec5199cKevin Jin * Base DroidDriver that implements the common operations. 31cddda72410c992a12db61cef26713b498e31fea4Thanh Le */ 3274676fdd3c8a9e599eddd13bea56898674d9916aKevin Jinpublic abstract class BaseDroidDriver<R, E extends BaseUiElement<R, E>> implements DroidDriver { 33cddda72410c992a12db61cef26713b498e31fea4Thanh Le 34985b3bff6691575b23da83c3e7cfd8552b6f4c55Kevin Jin private Poller poller = new DefaultPoller(); 3574676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin private E rootElement; 3621a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin 37b75721c8fc51bd5678f5a8d0df9a1e868d69aa12Kevin Jin @Override 387576fbbba2bf515908b45293b7156b5bfe088938Kevin Jin public UiElement find(Finder finder) { 397576fbbba2bf515908b45293b7156b5bfe088938Kevin Jin Logs.call(this, "find", finder); 40e4de29ac873c9e0ffaec34832dcc8b120850d8f7Kevin Jin return finder.find(getRootElement()); 417576fbbba2bf515908b45293b7156b5bfe088938Kevin Jin } 427576fbbba2bf515908b45293b7156b5bfe088938Kevin Jin 43985b3bff6691575b23da83c3e7cfd8552b6f4c55Kevin Jin @Override 447576fbbba2bf515908b45293b7156b5bfe088938Kevin Jin public boolean has(Finder finder) { 45985b3bff6691575b23da83c3e7cfd8552b6f4c55Kevin Jin try { 46e4de29ac873c9e0ffaec34832dcc8b120850d8f7Kevin Jin refreshUiElementTree(); 477576fbbba2bf515908b45293b7156b5bfe088938Kevin Jin find(finder); 48985b3bff6691575b23da83c3e7cfd8552b6f4c55Kevin Jin return true; 49985b3bff6691575b23da83c3e7cfd8552b6f4c55Kevin Jin } catch (ElementNotFoundException enfe) { 50985b3bff6691575b23da83c3e7cfd8552b6f4c55Kevin Jin return false; 51985b3bff6691575b23da83c3e7cfd8552b6f4c55Kevin Jin } 526a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin } 53cddda72410c992a12db61cef26713b498e31fea4Thanh Le 546a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin @Override 557576fbbba2bf515908b45293b7156b5bfe088938Kevin Jin public boolean has(Finder finder, long timeoutMillis) { 566a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin try { 57f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin getPoller().pollFor(this, finder, Poller.EXISTS, timeoutMillis); 586a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin return true; 596a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin } catch (TimeoutException e) { 606a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin return false; 616a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin } 626a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin } 636a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin 646a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin @Override 657576fbbba2bf515908b45293b7156b5bfe088938Kevin Jin public UiElement on(Finder finder) { 667576fbbba2bf515908b45293b7156b5bfe088938Kevin Jin Logs.call(this, "on", finder); 67f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin return getPoller().pollFor(this, finder, Poller.EXISTS); 68cddda72410c992a12db61cef26713b498e31fea4Thanh Le } 69cddda72410c992a12db61cef26713b498e31fea4Thanh Le 70cddda72410c992a12db61cef26713b498e31fea4Thanh Le @Override 71ce3d103d2784040f32d1a97b848d58a1c9592a15Kevin Jin public void checkExists(Finder finder) { 72ce3d103d2784040f32d1a97b848d58a1c9592a15Kevin Jin Logs.call(this, "checkExists", finder); 73f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin getPoller().pollFor(this, finder, Poller.EXISTS); 746a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin } 756a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin 766a6c19d612923a0350ab46898df513c66bac2d66Kevin Jin @Override 77ce3d103d2784040f32d1a97b848d58a1c9592a15Kevin Jin public void checkGone(Finder finder) { 78ce3d103d2784040f32d1a97b848d58a1c9592a15Kevin Jin Logs.call(this, "checkGone", finder); 79f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin getPoller().pollFor(this, finder, Poller.GONE); 80cddda72410c992a12db61cef26713b498e31fea4Thanh Le } 81cddda72410c992a12db61cef26713b498e31fea4Thanh Le 82cddda72410c992a12db61cef26713b498e31fea4Thanh Le @Override 83cddda72410c992a12db61cef26713b498e31fea4Thanh Le public Poller getPoller() { 84cddda72410c992a12db61cef26713b498e31fea4Thanh Le return poller; 85cddda72410c992a12db61cef26713b498e31fea4Thanh Le } 86cddda72410c992a12db61cef26713b498e31fea4Thanh Le 87cddda72410c992a12db61cef26713b498e31fea4Thanh Le @Override 88cddda72410c992a12db61cef26713b498e31fea4Thanh Le public void setPoller(Poller poller) { 89cddda72410c992a12db61cef26713b498e31fea4Thanh Le this.poller = poller; 90cddda72410c992a12db61cef26713b498e31fea4Thanh Le } 916316362de61fca700d7d5a455ad5c0ac9717c365Kevin Jin 9274676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin public abstract InputInjector getInjector(); 9321a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin 9474676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin protected abstract E newRootElement(); 9521a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin 9674676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin /** 9774676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin * Returns a new UiElement of type {@code E}. 9874676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin */ 9974676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin protected abstract E newUiElement(R rawElement, E parent); 10074676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin 10174676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin public E getRootElement() { 10221a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin if (rootElement == null) { 103e4de29ac873c9e0ffaec34832dcc8b120850d8f7Kevin Jin refreshUiElementTree(); 10421a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin } 10521a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin return rootElement; 10621a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin } 10721a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin 108e4de29ac873c9e0ffaec34832dcc8b120850d8f7Kevin Jin @Override 109e4de29ac873c9e0ffaec34832dcc8b120850d8f7Kevin Jin public void refreshUiElementTree() { 11074676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin rootElement = newRootElement(); 11121a0001e2426644dd68e6140b5873ebaeafcc3dcKevin Jin } 1126316362de61fca700d7d5a455ad5c0ac9717c365Kevin Jin 1136316362de61fca700d7d5a455ad5c0ac9717c365Kevin Jin @Override 1146316362de61fca700d7d5a455ad5c0ac9717c365Kevin Jin public boolean dumpUiElementTree(String path) { 115985b3bff6691575b23da83c3e7cfd8552b6f4c55Kevin Jin Logs.call(this, "dumpUiElementTree", path); 1166316362de61fca700d7d5a455ad5c0ac9717c365Kevin Jin return ByXPath.dumpDom(path, getRootElement()); 1176316362de61fca700d7d5a455ad5c0ac9717c365Kevin Jin } 118cddda72410c992a12db61cef26713b498e31fea4Thanh Le} 119