下面列出了怎么用org.openqa.selenium.support.pagefactory.ElementLocator的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
public void shouldAlwaysLocateTheElementPerCall() {
final ElementLocator locator = mock(ElementLocator.class);
final WebElement element = mock(WebElement.class);
when(locator.findElement()).thenReturn(element);
LocatingElementHandler handler = new LocatingElementHandler(locator);
WebElement proxy =
(WebElement) Proxy.newProxyInstance(getClass().getClassLoader(),
new Class[] {WebElement.class}, handler);
proxy.sendKeys("Fishy");
proxy.submit();
verify(locator, times(2)).findElement();
verify(element).sendKeys("Fishy");
verify(element).submit();
verifyNoMoreInteractions(locator, element);
}
@Test
public void shouldNotRepeatedlyLookUpElementsMarkedAsNeverChanging() {
final ElementLocator locator = mock(ElementLocator.class);
final WebElement element = mock(WebElement.class);
when(locator.findElement()).thenReturn(element);
LocatingElementHandler handler = new LocatingElementHandler(locator);
WebElement proxy =
(WebElement) Proxy.newProxyInstance(getClass().getClassLoader(),
new Class[] {WebElement.class}, handler);
proxy.isEnabled();
proxy.sendKeys("Cheese");
verify(element).isEnabled();
verify(element).sendKeys("Cheese");
}
@SuppressWarnings("unchecked")
@Test
public void shouldAlwaysLocateTheElementPerCall() {
final ElementLocator locator = mock(ElementLocator.class);
final WebElement element1 = mock(WebElement.class, "webElement1");
final WebElement element2 = mock(WebElement.class, "webElement2");
final List<WebElement> list = Arrays.asList(element1, element2);
when(locator.findElements()).thenReturn(list);
LocatingElementListHandler handler = new LocatingElementListHandler(locator);
List<WebElement> proxy =
(List<WebElement>) Proxy.newProxyInstance(getClass().getClassLoader(),
new Class[] {List.class}, handler);
proxy.get(1).sendKeys("Fishy");
assertThat(proxy).hasSize(2);
verify(locator, times(2)).findElements();
verify(element2, times(1)).sendKeys("Fishy");
verifyNoMoreInteractions(locator, element2);
verifyNoInteractions(element1);
}
public AbstractUIObjectListHandler(Class<?> clazz, WebDriver webDriver, ElementLocator locator, String name) {
this.clazz = clazz;
this.webDriver = webDriver;
this.locator = locator;
this.name = name;
this.locatorBy = getLocatorBy(locator);
}
protected ExtendedWebElement proxyForLocator(ClassLoader loader, Field field, ElementLocator locator) {
InvocationHandler handler = new LocatingElementHandler(locator);
WebElement proxy = (WebElement) Proxy.newProxyInstance(loader, new Class[] { WebElement.class, WrapsElement.class, Locatable.class },
handler);
return new ExtendedWebElement(proxy, field.getName(),
field.isAnnotationPresent(FindBy.class) || field.isAnnotationPresent(ExtendedFindBy.class)? new LocalizedAnnotations(field).buildBy() : null);
}
@SuppressWarnings("unchecked")
protected List<ExtendedWebElement> proxyForListLocator(ClassLoader loader, Field field, ElementLocator locator) {
InvocationHandler handler = new LocatingElementListHandler(webDriver, locator, field.getName(), new LocalizedAnnotations(field).buildBy());
List<ExtendedWebElement> proxies = (List<ExtendedWebElement>) Proxy.newProxyInstance(loader, new Class[] { List.class }, handler);
return proxies;
}
@SuppressWarnings("unchecked")
protected <T extends AbstractUIObject> List<T> proxyForListUIObjects(ClassLoader loader, Field field,
ElementLocator locator) {
LOGGER.debug("Setting setShouldCache=false for locator: " + getLocatorBy(locator).toString());
((ExtendedElementLocator) locator).setShouldCache(false);
InvocationHandler handler = new AbstractUIObjectListHandler<T>((Class<?>) getListType(field), webDriver,
locator, field.getName());
List<T> proxies = (List<T>) Proxy.newProxyInstance(loader, new Class[] { List.class }, handler);
return proxies;
}
/**
* Returns scope represented by this locator factory.
*/
@Override
public ElementLocator getCurrentScope() {
return new WebElementLocator(webElement);
}
/**
* Return a DefaultElementLocator.
*/
@Override
public ElementLocator createLocator(Field field) {
return new DefaultElementLocator(resolveContext(field),
FieldAnnotationsProvider.create(field, injector));
}
@Override
public ElementLocator getCurrentScope() {
return parentFactory.createLocator(parentField);
}
@Override
public ElementLocator createLocator(final Field field) {
return AnnotationsHelper.isGlobal(field) ?
new DefaultElementLocator(webDriver, FieldAnnotationsProvider.create(field, injector)) :
new ScopedElementLocator(parentFactory, parentField, field, injector);
}
public ElementLocator createLocator(Field field) {
return new DefaultElementLocator(searchContext,
FieldAnnotationsProvider.create(field, injector));
}
@Override
public ElementLocator createLocator(Field field) {
return null;
}
@Override
public ElementLocator createLocator(Field field) {
return null;
}
@Override
public ElementLocator getCurrentScope() {
return null;
}
private WebElement proxyForAnElement(ElementLocator locator) {
ElementInterceptor elementInterceptor = new ElementInterceptor(locator, webDriver);
return getEnhancedProxy(getElementClass(platform, automation), elementInterceptor);
}
ElementInterceptor(ElementLocator locator, WebDriver driver) {
super(locator, driver);
}
public InterceptorOfASingleElement(ElementLocator locator, WebDriver driver) {
this.locator = locator;
this.driver = driver;
}
public InterceptorOfAListOfElements(ElementLocator locator) {
this.locator = locator;
}
ElementListInterceptor(ElementLocator locator) {
super(locator);
}
public LocatingElementListHandler(ElementLocator locator) {
this.locator = locator;
}
public LocatingElementHandler(ElementLocator locator) {
this.locator = locator;
}
public ElementLocator createLocator(Field field) {
return new ExtendedElementLocator(searchContext, field);
}
public LocatingElementListHandler(WebDriver driver, ElementLocator locator, String name, By by) {
this.driver = driver;
this.locator = locator;
this.name = name;
this.by = by;
}
public Object decorate(ClassLoader loader, Field field) {
if ((!field.isAnnotationPresent(FindBy.class) && !field.isAnnotationPresent(ExtendedFindBy.class) && !field.isAnnotationPresent(FindByAI.class))
/*
* Enable field decorator logic only in case of
* presence the FindBy/FindByCarina/FindByAI annotation in the
* field
*/ ||
!(ExtendedWebElement.class.isAssignableFrom(field.getType()) || AbstractUIObject.class.isAssignableFrom(field.getType())
|| isDecoratableList(field)) /*
* also verify that it is ExtendedWebElement or derived from AbstractUIObject or DecoratableList
*/) {
// returning null is ok in this method.
return null;
}
ElementLocator locator;
try {
locator = factory.createLocator(field);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
return null;
}
if (locator == null) {
return null;
}
if (((ExtendedElementLocatorFactory) factory).isRootElementUsed()) {
LOGGER.debug("Setting setShouldCache=false for locator: " + getLocatorBy(locator).toString());
((ExtendedElementLocator) locator).setShouldCache(false);
}
if (ExtendedWebElement.class.isAssignableFrom(field.getType())) {
return proxyForLocator(loader, field, locator);
}
if (AbstractUIObject.class.isAssignableFrom(field.getType())) {
return proxyForAbstractUIObject(loader, field, locator);
} else if (List.class.isAssignableFrom(field.getType())) {
Type listType = getListType(field);
if (ExtendedWebElement.class.isAssignableFrom((Class<?>) listType)) {
return proxyForListLocator(loader, field, locator);
} else if (AbstractUIObject.class.isAssignableFrom((Class<?>) listType)) {
return proxyForListUIObjects(loader, field, locator);
} else {
return null;
}
} else {
return null;
}
}
/**
* Constructs the PageObjectListInvocationHandler.
*
* @param genericType Type of the element stored in the list.
* @param elementLocator Locator that is used to fetch elements from the page.
* @param injector Injector that will create items from webelements identified by
* elementLocator.
* @param cacheResults If this flag is set, PageObjectListInvocationHandler will generate the
* list once.
* If it's false, list will be generated each time this handler is invoked.
* @param framePath Injector performs injection in the frame indicated by framePath.
*/
public PageObjectListInvocationHandler(Class<?> genericType, ElementLocator elementLocator,
PageObjectInjector injector, boolean cacheResults, FramePath framePath) {
this.type = genericType;
this.injector = injector;
this.locator = elementLocator;
this.cacheResults = cacheResults;
this.framePath = framePath;
}
/**
* @return Locator that represents the scope where all child elements will be searched for.
*/
ElementLocator getCurrentScope();