After upgrading to selenium Java 3.8.1 the wait.until(ExpectedCondition) has started giving error message.
For the following piece of code
WebElement framei = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(".//*[#id='ctl00_ContentPlaceHolder1_dlgModal_IFrame']")));
driver.switchTo().frame(framei);
WebElement AcceptRadioButton=wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#id='RblStatus']/tbody/tr[1]/td/label")));
AcceptRadioButton.click();
The following error is given:
Type The method until(Function<? super WebDriver,V>) in the type FluentWait<WebDriver> is not applicable for the arguments (ExpectedCondition<WebElement>)
I tried to resolve the following issue by removing the Selenium java version 3.8.1 of
Same problem as you but not so sure about Eugene S answer I search in sources of selenium-java 2.53.1 and 3.8.1 to see what was different between FluentWait class. Here are until fonctions of the different version:
2.53.1 :
public void until(final Predicate<T> isTrue) {
until(new Function<T, Boolean>() {
public Boolean apply(T input) {
return isTrue.apply(input);
}
public String toString() {
return isTrue.toString();
}
});
}
OR
public <V> V until(Function<? super T, V> isTrue) {
long end = clock.laterBy(timeout.in(MILLISECONDS));
Throwable lastException = null;
while (true) {
try {
V value = isTrue.apply(input);
if (value != null && Boolean.class.equals(value.getClass())) {
if (Boolean.TRUE.equals(value)) {
return value;
}
} else if (value != null) {
return value;
}
} catch (Throwable e) {
lastException = propagateIfNotIgnored(e);
}
// Check the timeout after evaluating the function to ensure conditions
// with a zero timeout can succeed.
if (!clock.isNowBefore(end)) {
String message = messageSupplier != null ?
messageSupplier.get() : null;
String toAppend = message == null ?
" waiting for " + isTrue.toString() : ": " + message;
String timeoutMessage = String.format("Timed out after %d seconds%s",
timeout.in(SECONDS), toAppend);
throw timeoutException(timeoutMessage, lastException);
}
try {
sleeper.sleep(interval);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new WebDriverException(e);
}
}
}
AND IN 3.8.1:
public <V> V until(Function<? super T, V> isTrue) {
long end = clock.laterBy(timeout.in(MILLISECONDS));
Throwable lastException;
while (true) {
try {
V value = isTrue.apply(input);
if (value != null && (Boolean.class != value.getClass() || Boolean.TRUE.equals(value))) {
return value;
}
// Clear the last exception; if another retry or timeout exception would
// be caused by a false or null value, the last exception is not the
// cause of the timeout.
lastException = null;
} catch (Throwable e) {
lastException = propagateIfNotIgnored(e);
}
// Check the timeout after evaluating the function to ensure conditions
// with a zero timeout can succeed.
if (!clock.isNowBefore(end)) {
String message = messageSupplier != null ?
messageSupplier.get() : null;
String timeoutMessage = String.format(
"Expected condition failed: %s (tried for %d second(s) with %s interval)",
message == null ? "waiting for " + isTrue : message,
timeout.in(SECONDS), interval);
throw timeoutException(timeoutMessage, lastException);
}
try {
sleeper.sleep(interval);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new WebDriverException(e);
}
}
}
I don't see any difference between the three functions arguments but the project I work on did not return me any error with 2.53.1 version but with 3.8.1 I have the same error than Akhil.
As it says in the error message:
FluentWait<WebDriver> is not applicable for the arguments (ExpectedCondition<WebElement>)
Starting from Selenium 3, until method declaration now looks like this:
public <V> V until(Function<? super T, V> isTrue)
where Function is:
public interface Function<T, R>
So it has been converted to use Java 8 functional interface. You will need to rewrite your expected conditions accordingly.
As per best practices we must try to switch to a <iframe> with proper WebDriverWait as follows :
new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//iframe[#id='ctl00_ContentPlaceHolder1_dlgModal_IFrame']")));
Related
I am transforming an Image into pdf for test purposes.
To ensure that the Image is compatible with the printing process later on, I'm running a quick test print during the upload.
I'm creating a simple Test-PDF with a transformer. When I try to print an image with an incompatible format, the ImageManager of the transformer throws an ImageException, starting in the preloadImage() function:
public ImageInfo preloadImage(String uri, Source src)
throws ImageException, IOException {
Iterator iter = registry.getPreloaderIterator();
while (iter.hasNext()) {
ImagePreloader preloader = (ImagePreloader)iter.next();
ImageInfo info = preloader.preloadImage(uri, src, imageContext);
if (info != null) {
return info;
}
}
throw new ImageException("The file format is not supported. No ImagePreloader found for "
+ uri);
}
throwing it to:
public ImageInfo needImageInfo(String uri, ImageSessionContext session, ImageManager manager)
throws ImageException, IOException {
//Fetch unique version of the URI and use it for synchronization so we have some sort of
//"row-level" locking instead of "table-level" locking (to use a database analogy).
//The fine locking strategy is necessary since preloading an image is a potentially long
//operation.
if (isInvalidURI(uri)) {
throw new FileNotFoundException("Image not found: " + uri);
}
String lockURI = uri.intern();
synchronized (lockURI) {
ImageInfo info = getImageInfo(uri);
if (info == null) {
try {
Source src = session.needSource(uri);
if (src == null) {
registerInvalidURI(uri);
throw new FileNotFoundException("Image not found: " + uri);
}
info = manager.preloadImage(uri, src);
session.returnSource(uri, src);
} catch (IOException ioe) {
registerInvalidURI(uri);
throw ioe;
} catch (ImageException e) {
registerInvalidURI(uri);
throw e;
}
putImageInfo(info);
}
return info;
}
}
throwing it to :
public ImageInfo getImageInfo(String uri, ImageSessionContext session)
throws ImageException, IOException {
if (getCache() != null) {
return getCache().needImageInfo(uri, session, this);
} else {
return preloadImage(uri, session);
}
}
Finally it gets caught and logged in the ExternalGraphic.class:
/** {#inheritDoc} */
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
src = pList.get(PR_SRC).getString();
//Additional processing: obtain the image's intrinsic size and baseline information
url = URISpecification.getURL(src);
FOUserAgent userAgent = getUserAgent();
ImageManager manager = userAgent.getFactory().getImageManager();
ImageInfo info = null;
try {
info = manager.getImageInfo(url, userAgent.getImageSessionContext());
} catch (ImageException e) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
getUserAgent().getEventBroadcaster());
eventProducer.imageError(this, url, e, getLocator());
} catch (FileNotFoundException fnfe) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
getUserAgent().getEventBroadcaster());
eventProducer.imageNotFound(this, url, fnfe, getLocator());
} catch (IOException ioe) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
getUserAgent().getEventBroadcaster());
eventProducer.imageIOError(this, url, ioe, getLocator());
}
if (info != null) {
this.intrinsicWidth = info.getSize().getWidthMpt();
this.intrinsicHeight = info.getSize().getHeightMpt();
int baseline = info.getSize().getBaselinePositionFromBottom();
if (baseline != 0) {
this.intrinsicAlignmentAdjust
= FixedLength.getInstance(-baseline);
}
}
}
That way it isn't accessible for me in my code that uses the transformer.
I tried to use a custom ErrorListener, but the transformer only registers fatalErrors to the ErrorListener.
Is there any way to access the Exception and handle it myself without changing the code of the library?
It was easier than I thought. Before I call the transformation I register a costum EventListener to the User Agent of the Fop I'm using. This Listener just stores the Information what kind of Event was triggered, so I can throw an Exception if it's an ImageError.
My Listener:
import org.apache.fop.events.Event;
import org.apache.fop.events.EventListener;
public class ImageErrorListener implements EventListener
{
private String eventKey = "";
private boolean imageError = false;
#Override
public void processEvent(Event event)
{
eventKey = event.getEventKey();
if(eventKey.equals("imageError")) {
imageError = true;
}
}
public String getEventKey()
{
return eventKey;
}
public void setEventKey(String eventKey)
{
this.eventKey = eventKey;
}
public boolean isImageError()
{
return imageError;
}
public void setImageError(boolean imageError)
{
this.imageError = imageError;
}
}
Use of the Listener:
// Start XSLT transformation and FOP processing
ImageErrorListener imageListener = new ImageErrorListener();
fop.getUserAgent().getEventBroadcaster().addEventListener(imageListener);
if (res != null)
{
transformer.transform(xmlDomStreamSource, res);
}
if(imageListener.isImageError()) {
throw new ImageException("");
}
fop is of the type Fop ,xmlDomStreamSource ist the xml-Source I want to transform and res is my SAXResult.
I have to skip execution of the test case #bannerVerificationSMMDView only when the viewPort is Large
#Before
public void beforestartUp(Scenario scenario) throws IOException {
boolean runTest = true;
if (viewPort.contains("LARGE")) {
System.out.println("for Scenario " + scenario.getName() + " tagname are");
List<String> tags = (List<String>) scenario.getSourceTagNames();
for (String tagName : tags) {
if (tagName.contains("bannerVerificationLView"))
runTest = false;
}
try {
Assume.assumeTrue(runTest);
} catch (AssumptionViolatedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Not sure why, but exception is not getting caught
Throw a AssumptionViolatedException to skip the execution of scenario.
#Before(value="#bannerVerificationSMMDView")
public void before(Scenario scenario) {
if(viewPort.contains("LARGE"))
throw new AssumptionViolatedException("Skipping as view is LARGE");
}
If you are on cucumber version 3 plus, you can use a #BeforeStep annotation instead, keep everything else same. This will allow you to run any previous steps in the scenario and if condition is not met then skip the rest of the steps in the scenario
This is the code I am getting error on line 1. Instead of returning true or false it throws an exception " No response from server for url: http://test:4444/wd/hub/session/1382359342795/element
Getting error on line1 :
Boolean tInputElement = driver.FindElement(By.Id("locator")).Enabled;
if (tInputElement.ToString() == "True")
{
IWebElement InputElement=driver.FindElement(By.Id("locator"));
InputElement.SendKeys(InputData);
}
Please suggest how can I avoid no response error and catch objectnotfoundexception. Please note I am running this code using Hub.
This is how I got this working :
int _TotalTimeToWait = 0;
int TotalTimeToWaitinSecs = 40;
while (_TotalTimeToWait < TotalTimeToWaitinSecs && driver.FindElements(by).Count == 0)
{
Thread.Sleep(1000);
_TotalTimeToWait++;
}
if (_TotalTimeToWait == 0) { driver.FindElement(by).Click(); Thread.Sleep(2000); }
else { throw new ElementNotVisibleException(); }
_TotalTimeToWait = 0;
As far as i know, there is no property like Enabled for WebElement, but it does have a IsEnabled() method, so try:
if (driver.FindElement(By.Id("locator")).isEnabled())
{
IWebElement InputElement=driver.FindElement(By.Id("locator"));
InputElement.SendKeys(InputData);
}
Or something like:
IWebElement InputElement=driver.FindElement(By.Id("locator"));
if (InputElement != null && InputElement.isEnabled())
{
InputElement.SendKeys(InputData);
}
I am using Selenium with GhostDriver and sometimes I got the error:
org.openqa.selenium.remote.UnreachableBrowserException: Error communicating with the remote browser. It may have died., caused by exceptions include java.lang.InterruptedException
It happens when using findbyElement, findByElements, get, or click methods of Selenium.
It does not happens always and not in the same places, but it happens more frequently on Windows environments.
Does anyone knows how can I avoid this exception?
I tried adding more time while using waits but it did not work.
To avoid this exception, you can override the get method. (Usually, this exception append once)
public class CustomPhantomJSDriver extends PhantomJSDriver {
#Override
public void get(String url) {
int count = 0;
int maxTries = 5;
while (count < maxTries) {
try {
super.get(url);
break;
} catch (UnreachableBrowserException e) {
count++;
}
}
if (count == maxTries) {
throw new UnreachableBrowserException(url);
}
}
}
This worked for me: http://matejtymes.blogspot.co.uk/2014/10/webdriver-fix-for-unreachablebrowserexc.html
Use it anywhere you would otherwise use PhantomJSDriver (it covers all situations: get, click, findByElement, ...)
public class FixedPhantomJSDriver extends PhantomJSDriver {
private final int retryCount = 2;
public FixedPhantomJSDriver() {
}
public FixedPhantomJSDriver(Capabilities desiredCapabilities) {
super(desiredCapabilities);
}
public FixedPhantomJSDriver(PhantomJSDriverService service, Capabilities desiredCapabilities) {
super(service, desiredCapabilities);
}
#Override
protected Response execute(String driverCommand, Map<String, ?> parameters) {
int retryAttempt = 0;
while (true) {
try {
return super.execute(driverCommand, parameters);
} catch (UnreachableBrowserException e) {
retryAttempt++;
if (retryAttempt > retryCount) {
throw e;
}
}
}
}
}
I wanted to write a test for a method in Groovy that throws an IOException. The only way for me to simulate this in the test is to force the method to throw this exception
This is what the original code looks like:
public void cleanUpBermudaFiles(RequestMessage requestMessage)
{
final File sourceDirectory = new File(preferenceService.getPreference("bermuda.landingstrip") + File.separator + requestMessage.getWorkflowId().getValue());
if(sourceDirectory!=null && sourceDirectory.exists())
{
deleteDirectory(sourceDirectory);
}
else
{
LOG.error("Directory must exist in order to delete");
}
}
private void deleteDirectory(File directoryToDelete)
{
try {
FileUtils.deleteDirectory(directoryToDelete);
} catch (Exception e) {
LOG.error("Failed to delete Bermuda files directory located at:" + directoryToDelete.getPath() + "with an exception" + e.getMessage());
}
}
MY TEST: (I'm looking for a way to make deleteDirectory throw IOException)
public void testCleanUpBermudaFailure()
{
workflowId = new WorkflowId("123456")
workflowDirectory = new File(srcDirectory, workflowId.value)
workflowDirectory.mkdir()
File.createTempFile('foo','.lst', workflowDirectory)
def exception = {throw new IOException()}
expect(mockRequestMessage.getWorkflowId()).andReturn(workflowId)
expect(mockPreferenceService.getPreference("bermuda.landingstrip")).andReturn(srcDirectory.path)
replay(mockPreferenceService, mockRequestMessage)
fileCleanUpService.preferenceService = mockPreferenceService
fileCleanUpService.metaClass.deleteDirectory = exception
fileCleanUpService.cleanUpBermudaFiles(mockRequestMessage)
verify(mockPreferenceService, mockRequestMessage)
assert srcDirectory.listFiles().length == 0, 'CleanUp failed'
}
If the service class is a Groovy class, you would want to mock FileUtils like:
FileUtils.metaClass.static.deleteDirectory = { File f -> throw new IOException() }
However, as ataylor pointed out, you cannot intercept calls if it's a Java class. You can find a nice blog post about it here.
You are mocking a no-arg call to deleteDirectory, but the real deleteDirectory takes one argument of type File. Try this:
def exception = { File directoryToDelete -> throw new IOException() }
...
fileCleanUpService.metaClass.deleteDirectory = exception