下面列出了怎么用org.openqa.selenium.SearchContext的API类实例代码及写法,或者点击链接到github查看源代码。
private void fixLocator(SearchContext context, String cssLocator, WebElement element) {
if (element instanceof RemoteWebElement) {
try {
@SuppressWarnings("rawtypes")
Class[] parameterTypes = new Class[] { SearchContext.class,
String.class, String.class };
Method m = element.getClass().getDeclaredMethod(
"setFoundBy", parameterTypes);
m.setAccessible(true);
Object[] parameters = new Object[] { context, "cssSelector", cssLocator };
m.invoke(element, parameters);
} catch (Exception fail) {
//fail("Something bad happened when fixing locator");
}
}
}
/**
* {@inheritDoc}
*
* @throws WebDriverException when current session doesn't support the given selector or when
* value of the selector is not consistent.
* @throws IllegalArgumentException when it is impossible to find something on the given
* {@link SearchContext} instance
*/
@Override public WebElement findElement(SearchContext context) throws WebDriverException,
IllegalArgumentException {
Class<?> contextClass = context.getClass();
if (FindsByAccessibilityId.class.isAssignableFrom(contextClass)) {
return FindsByAccessibilityId.class.cast(context)
.findElementByAccessibilityId(getLocatorString());
}
if (FindsByFluentSelector.class.isAssignableFrom(contextClass)) {
return super.findElement(context);
}
throw formIllegalArgumentException(contextClass, FindsByAccessibilityId.class,
FindsByFluentSelector.class);
}
@Override
public WebElement findElement(SearchContext context) {
AppiumFunction<SearchContext, WebElement> searchingFunction = null;
for (By by: bys) {
searchingFunction = Optional.ofNullable(searchingFunction != null
? searchingFunction.andThen(getSearchingFunction(by)) : null).orElse(getSearchingFunction(by));
}
FluentWait<SearchContext> waiting = new FluentWait<>(context);
try {
checkNotNull(searchingFunction);
return waiting.until(searchingFunction);
} catch (TimeoutException e) {
throw new NoSuchElementException("Cannot locate an element using " + toString());
}
}
/**
* This method extract an instance of {@link WebDriver} from the given {@link SearchContext}.
* @param searchContext is an instance of {@link SearchContext}. It may be the instance of
* {@link WebDriver} or {@link org.openqa.selenium.WebElement} or some other
* user's extension/implementation.
* Note: if you want to use your own implementation then it should implement
* {@link WrapsDriver} or {@link WrapsElement}
* @return the instance of {@link WebDriver}.
* Note: if the given {@link SearchContext} is not
* {@link WebDriver} and it doesn't implement
* {@link WrapsDriver} or {@link WrapsElement} then this method returns null.
*
*/
public static WebDriver unpackWebDriverFromSearchContext(SearchContext searchContext) {
if (searchContext instanceof WebDriver) {
return (WebDriver) searchContext;
}
if (searchContext instanceof WrapsDriver) {
return unpackWebDriverFromSearchContext(
((WrapsDriver) searchContext).getWrappedDriver());
}
// Search context it is not only Webdriver. Webelement is search context too.
// RemoteWebElement and MobileElement implement WrapsDriver
if (searchContext instanceof WrapsElement) {
return unpackWebDriverFromSearchContext(
((WrapsElement) searchContext).getWrappedElement());
}
return null;
}
private List<WebElement> searchCheckboxLabels(SearchContext searchContext, SearchParameters parameters)
{
String checkBoxName = parameters.getValue();
SearchParameters nonDisplayedParameters = new SearchParameters(parameters.getValue(), Visibility.ALL,
parameters.isWaitForElement());
List<WebElement> checkboxLabels = findElements(searchContext,
getXPathLocator(String.format(CHECKBOX_LABEL_FORMAT, checkBoxName)), parameters);
List<WebElement> matchedCheckboxLabels = searchCheckboxByLabels(searchContext, nonDisplayedParameters,
checkboxLabels);
if (matchedCheckboxLabels.isEmpty())
{
checkboxLabels = findElements(searchContext, getXPathLocator(CHECKBOX_LABEL_DEEP), parameters).stream()
.filter(e -> getWebElementActions().getElementText(e).contains(checkBoxName))
.collect(Collectors.toList());
return searchCheckboxByLabels(searchContext, nonDisplayedParameters, checkboxLabels);
}
return matchedCheckboxLabels;
}
private List<WebElement> searchCheckboxByLabels(SearchContext searchContext, SearchParameters parameters,
List<WebElement> labelElements)
{
for (WebElement label : labelElements)
{
List<WebElement> checkboxes;
String checkBoxId = label.getAttribute("for");
if (checkBoxId != null)
{
checkboxes = findElements(searchContext,
getXPathLocator("input[@type='checkbox' and @id=%s]", checkBoxId), parameters);
}
else
{
checkboxes = label.findElements(getXPathLocator(PRECEDING_SIBLING_CHECKBOX_LOCATOR));
if (checkboxes.isEmpty())
{
continue;
}
}
return checkboxes.stream().map(e -> new Checkbox(e, label)).collect(Collectors.toList());
}
return List.of();
}
@Test
public void testBrowserName() {
WebDriver driver = getDriver();
ExamplePage page = getPage();
WebElement element = page.findElement(By.tagName("html"));
SeleniumConfig config = SeleniumConfig.getConfig();
String browserName = config.getCurrentCapabilities().getBrowserName();
assertThat(WebDriverUtils.getBrowserName((SearchContext) driver), equalToIgnoringCase(browserName));
assertThat(WebDriverUtils.getBrowserName(page), equalToIgnoringCase(browserName));
assertThat(WebDriverUtils.getBrowserName(element), equalToIgnoringCase(browserName));
try {
WebDriverUtils.getBrowserName(mock(WebDriver.class));
fail("No exception was thrown");
} catch (UnsupportedOperationException e) {
assertEquals(e.getMessage(), "The specified context is unable to describe its capabilities");
}
}
/**
* {@inheritDoc}
*
* @throws WebDriverException when current session doesn't support the given selector or when
* value of the selector is not consistent.
* @throws IllegalArgumentException when it is impossible to find something on the given
* {@link SearchContext} instance
*/
@SuppressWarnings("unchecked")
@Override
public List<WebElement> findElements(SearchContext context) throws WebDriverException,
IllegalArgumentException {
Class<?> contextClass = context.getClass();
if (FindsByAndroidViewTag.class.isAssignableFrom(contextClass)) {
return FindsByAndroidViewTag.class.cast(context)
.findElementsByAndroidViewTag(getLocatorString());
}
if (FindsByFluentSelector.class.isAssignableFrom(contextClass)) {
return super.findElements(context);
}
throw formIllegalArgumentException(contextClass, FindsByAndroidViewTag.class,
FindsByFluentSelector.class);
}
/**
* An expectation for checking that is at least one element present
* within the search context
* @param searchCriteria used to find elements
* @return the list of WebElements once they are located
*/
@Override
@SuppressWarnings("checkstyle:nonullforcollectionreturn")
public IExpectedSearchContextCondition<List<WebElement>> presenceOfAllElementsLocatedBy(final T searchCriteria)
{
return new IExpectedSearchContextCondition<>()
{
@Override
public List<WebElement> apply(SearchContext searchContext)
{
List<WebElement> elements = findElements(searchContext, searchCriteria);
return !elements.isEmpty() ? elements : null;
}
@Override
public String toString()
{
return "presence of any elements " + toStringParameters(searchCriteria);
}
};
}
/**
* {@inheritDoc}
*
* @throws WebDriverException when current session doesn't support the given selector or when
* value of the selector is not consistent.
* @throws IllegalArgumentException when it is impossible to find something on the given
* {@link SearchContext} instance
*/
@SuppressWarnings("unchecked")
@Override
public List<WebElement> findElements(SearchContext context) throws WebDriverException,
IllegalArgumentException {
Class<?> contextClass = context.getClass();
if (FindsByAndroidUIAutomator.class.isAssignableFrom(contextClass)) {
return FindsByAndroidUIAutomator.class.cast(context)
.findElementsByAndroidUIAutomator(getLocatorString());
}
if (FindsByFluentSelector.class.isAssignableFrom(contextClass)) {
return super.findElements(context);
}
throw formIllegalArgumentException(contextClass, FindsByAndroidUIAutomator.class,
FindsByFluentSelector.class);
}
@Test
void shouldNotExecuteStepsIfInitialElementsNumberIsNotValid()
{
SearchContext searchContext = mockWebUiContext();
SearchAttributes searchAttributes = mock(SearchAttributes.class);
when(searchActions.findElements(searchContext, searchAttributes)).thenReturn(List.of(mock(WebElement.class)));
nestedSteps.performAllStepsWhileElementsExist(ComparisonRule.EQUAL_TO, 2, searchAttributes, 5, subSteps);
verifyNoInteractions(subSteps);
verify(searchActions, times(1)).findElements(searchContext, searchAttributes);
verify(softAssert).assertThat(eq(ELEMENTS_NUMBER), eq(1), argThat(m ->
ComparisonRule.EQUAL_TO.getComparisonRule(2).toString().equals(m.toString())));
verify(softAssert, never()).recordFailedAssertion(anyString());
verify(webUiContext, never()).getSearchContextSetter();
}
/**
* {@inheritDoc}
*
* @throws WebDriverException when current session doesn't support the given selector or when
* value of the selector is not consistent.
* @throws IllegalArgumentException when it is impossible to find something on the given
* {@link SearchContext} instance
*/
@SuppressWarnings("unchecked")
@Override public List<WebElement> findElements(SearchContext context) {
Class<?> contextClass = context.getClass();
if (FindsByWindowsAutomation.class.isAssignableFrom(contextClass)) {
return FindsByWindowsAutomation.class.cast(context)
.findElementsByWindowsUIAutomation(getLocatorString());
}
if (FindsByFluentSelector.class.isAssignableFrom(contextClass)) {
return super.findElements(context);
}
throw formIllegalArgumentException(contextClass, FindsByWindowsAutomation.class,
FindsByFluentSelector.class);
}
private static AppiumFunction<SearchContext, WebElement> getSearchingFunction(By by) {
return input -> {
try {
return input.findElement(by);
} catch (NoSuchElementException e) {
return null;
}
};
}
@Override
public void executeAfterJSPreconditionHasBeenSatisfied(WebDriver driver, ReplayingState replayingState, Function<SearchContext, SearchContext> contextProvider) {
String dataId = this.dataId.startsWith("{{")
? replayingState.getValue(this.dataId)
: this.dataId;
By selector = By.cssSelector("input[data-id='" + dataId + "'");
contextProvider.apply(driver).findElement(selector).click();
}
@Test
void testInvisibilityOfElementLocatedSuccessNotDisplayed()
{
WebElement webElement = mock(WebElement.class);
SearchContext searchContext = mock(SearchContext.class);
when(searchContext.findElement(XPATH_LOCATOR)).thenReturn(webElement);
when(webElement.isDisplayed()).thenReturn(false);
assertTrue(expectedConditions.invisibilityOfElement(XPATH_LOCATOR).apply(searchContext)
.booleanValue());
}
@Test
void testElementToBeClickableNotVisible()
{
WebElement webElement = mock(WebElement.class);
SearchContext searchContext = mock(SearchContext.class);
when(searchContext.findElement(XPATH_LOCATOR)).thenReturn(webElement);
when(webElement.isDisplayed()).thenReturn(FALSE);
assertNull(expectedConditions.elementToBeClickable(XPATH_LOCATOR).apply(searchContext));
}
/**
* Boolean wrapper for a condition, which returns 'true' if the expectation is met.
*
* @param condition expected condition
* @return 'true' if the specified condition returns a 'positive' result
*/
public static Coordinator<Boolean> has(final Function<SearchContext, ?> condition) {
return new Coordinator<Boolean>() {
/**
* {@inheritDoc}
*/
@Override
public Boolean apply(SearchContext context) {
Object result = condition.apply(context);
if (result != null) {
if (result instanceof Boolean) {
return (Boolean) result;
} else {
return true;
}
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return "condition to be valid: " + condition;
}
/**
* {@inheritDoc}
*/
@Override
public TimeoutException differentiateTimeout(TimeoutException e) {
if (condition instanceof Coordinator) {
return ((Coordinator<?>) condition).differentiateTimeout(e);
}
return new ConditionStillInvalidTimeoutException(e.getMessage(), e.getCause());
}
};
}
final Supplier<SearchContext> getSearchContextSupplier() {
if (proxy instanceof Page) {
Browser browser = (( Page ) proxy).browser();
return browser::webDriver;
} else if (proxy instanceof PageFragment) {
PageFragment pageFragment = ( PageFragment ) proxy;
return pageFragment::webElement;
}
throw new IllegalStateException();
}
@SuppressWarnings("unchecked")
public List<E> findElements(SearchContext driver)
{
By by = getBy();
if(driver instanceof WebDriver)
{
elementWait((WebDriver) driver, getTimeout(), by);
}
return (List<E>) driver.findElements(by);
}
/**
* Returns a 'wait' proxy that switches focus to the specified context
*
* @param context search context on which to focus
* @return target search context
*/
static Coordinator<SearchContext> contextIsSwitched(final ComponentContainer context) {
return new Coordinator<SearchContext>() {
/**
* {@inheritDoc}
*/
@Override
public SearchContext apply(final SearchContext ignore) {
if (context.parent != null) {
context.parent.switchTo();
}
try {
return context.switchToContext();
} catch (StaleElementReferenceException e) { //NOSONAR
return context.refreshContext(context.acquiredAt());
}
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return "context to be switched";
}
};
}
/**
* {@inheritDoc}
*/
@Override
public SearchContext refreshContext(final long expiration) {
// if this context is past the expiration
if (expiration >= acquiredAt()) {
// refresh context ancestry
parent.refreshContext(expiration);
// refresh context element
((RobustWebElement) context).refreshContext(expiration);
}
return this;
}
@Test
void testTextToBePresentInElementLocatedSuccessException()
{
SearchContext searchContext = mock(SearchContext.class);
when(searchContext.findElement(XPATH_LOCATOR)).thenThrow(StaleElementReferenceException.class);
assertNull(
expectedConditions.textToBePresentInElementLocated(XPATH_LOCATOR, TEXT_TO_FIND).apply(searchContext));
}
@Test
void testTextToBePresentInElementLocatedSuccessContainsValidText()
{
WebElement webElement = mock(WebElement.class);
SearchContext searchContext = mock(SearchContext.class);
when(searchContext.findElement(XPATH_LOCATOR)).thenReturn(webElement);
when(webElement.getText()).thenReturn(ELEMENT_TEXT);
assertTrue(expectedConditions.textToBePresentInElementLocated(XPATH_LOCATOR, TEXT_TO_FIND)
.apply(searchContext).booleanValue());
}
protected List<WebElement> findElementsByText(SearchContext searchContext, By defaultLocator,
SearchParameters parameters, String... tagNames)
{
List<WebElement> elements = findElements(searchContext, defaultLocator, parameters);
if (elements.isEmpty())
{
String text = parameters.getValue();
By newLocator = generateCaseInsensitiveLocator(text, tagNames);
return findElements(searchContext, newLocator, parameters)
.stream()
.filter(element -> matchesToText(element, text))
.collect(Collectors.toList());
}
return elements;
}
@Override
public List<WebElement> search(SearchContext searchContext, SearchParameters parameters)
{
String searchValue = parameters.getValue();
By xpathLocator = caseSensitiveSearch ? LocatorUtil.getXPathLocator(LINK_WITH_PART_URL_PATTERN, searchValue)
: LocatorUtil.getXPathLocator(LINK_WITH_CASE_INSENSITIVE_URL_PART, searchValue.toLowerCase());
return findElements(searchContext, xpathLocator, parameters);
}
private List<WebElement> getWElements(SearchContext context, ObjectGroup<WebORObject> objectGroup, String prop) {
long startTime = System.nanoTime();
List<WebElement> elements = null;
for (WebORObject object : objectGroup.getObjects()) {
switchFrame(object.getFrame());
elements = getElements(context, object.getAttributes(), prop);
if (elements != null && !elements.isEmpty()) {
break;
}
}
printStats(elements, objectGroup, startTime, System.nanoTime());
return elements;
}
@Override
public List<WebElement> search(SearchContext searchContext, SearchParameters parameters)
{
String value = parameters.getValue();
List<WebElement> elements = findElementsByText(searchContext, LocatorUtil.getXPathLocatorByFullInnerText(value),
parameters, ANY);
return elements.isEmpty()
? findElementsByText(searchContext, LocatorUtil.getXPathLocatorByInnerText(value), parameters, ANY)
: elements;
}
@Override
public List<WebElement> search(SearchContext searchContext, SearchParameters parameters)
{
List<WebElement> checkboxLabels = searchCheckboxLabels(searchContext, parameters);
return checkboxLabels.isEmpty() ? findElements(searchContext, getXPathLocator(CHECKBOX_LOCATOR), parameters)
.stream()
.filter(c -> parameters.getValue().equals(getWebElementActions().getElementText(c)))
.map(Checkbox::new)
.collect(Collectors.toList()) : checkboxLabels;
}
/**
* Find element by sizzle css.
* @param context
*
* @param cssLocator
* the cssLocator
* @return the web element
*/
public WebElement findElementBySizzleCss(SearchContext context, String cssLocator) {
List<WebElement> elements = findElementsBySizzleCss(context, cssLocator);
if (elements != null && elements.size() > 0 ) {
return elements.get(0);
}
// if we get here, we cannot find the element via Sizzle.
throw new NoSuchElementException("selector '"+cssLocator+"' cannot be found in DOM");
}
protected <T extends VisualCheck> VisualCheckResult
execute(Function<T, VisualCheckResult> checkResultProvider, Supplier<T> visualCheckFactory, String templateName)
{
SearchContext searchContext = webUiContext.getSearchContext();
Validate.validState(searchContext != null, "Search context is null, please check is browser session started");
T visualCheck = visualCheckFactory.get();
visualCheck.setSearchContext(searchContext);
VisualCheckResult result = checkResultProvider.apply(visualCheck);
if (null != result)
{
attachmentPublisher.publishAttachment(templateName, Map.of("result", result), "Visual comparison");
}
return result;
}