Repository: appium/java-client
Issue: wait.until(ExpectedConditions.visibilityOf(elementName)) related issue

## Description

I've below code

`WebDriverWait wait = new WebDriverWait(AppiumController.instance.driver, timeout);
   wait.until(ExpectedConditions.visibilityOf(elementName));`

Here I pass timeout value but observed that instead of waiting for timeout value, it waits for default time mentioned in 

`PageFactory.initElements(new AppiumFieldDecorator(driver, 30, TimeUnit.SECONDS), this);`

## Environment

* java client build version or git revision if you use some shapshot: 5.0.0-BETA3
* Appium server version or git revision if you use some shapshot: 1.6.3
* Desktop OS/version used to run Appium if necessary: Mac 
* Node.js version (unless using Appium.app|exe) or Appium CLI or Appium.app|exe:
* Mobile platform/version under test:  iOS 10.2
* Real device or emulator/simulator: simulator

## Details

1.  When I set wait , I expect element to wait for that time interval itself.
2.  But value set for wait is ignored and element waits for default timeout mentioned in PageFactory.initElements
3. Later I tried `@WithTimeout(time = 3, unit = TimeUnit.SECONDS)` for this element but still it waits for defaulttime, my understanding is this particular tag overrides the default time. 


## Code To Reproduce Issue [ Good To Have ]

NA

## Ecxeption stacktraces
NA

## Link to Appium logs

https://gist.github.com/vikramvi/2eedd0643f89140fa3d6ffac8f347644


Changed files:
src/main/java/io/appium/java_client/pagefactory/WidgetInterceptor.java
src/main/java/io/appium/java_client/pagefactory/ElementInterceptor.java
src/main/java/io/appium/java_client/pagefactory/ElementListInterceptor.java
src/main/java/io/appium/java_client/pagefactory/AppiumElementLocator.java
src/main/java/io/appium/java_client/pagefactory/WidgetListInterceptor.java
src/main/java/io/appium/java_client/pagefactory/interceptors/InterceptorOfASingleElement.java

diff --git a/src/main/java/io/appium/java_client/pagefactory/AppiumElementLocator.java b/src/main/java/io/appium/java_client/pagefactory/AppiumElementLocator.java
index 1f1c9c0f..6ce4e3b1 100644
--- a/src/main/java/io/appium/java_client/pagefactory/AppiumElementLocator.java
+++ b/src/main/java/io/appium/java_client/pagefactory/AppiumElementLocator.java
@@ -151,6 +151,10 @@ class AppiumElementLocator implements CacheableLocator {
         return shouldCache;
     }
 
+    @Override public String toString() {
+        return String.format("Located by %s", by);
+    }
+
 
     // This function waits for not empty element list using all defined by
     private static class WaitingFunction<T> implements Function<Supplier<T>, T> {
diff --git a/src/main/java/io/appium/java_client/pagefactory/ElementInterceptor.java b/src/main/java/io/appium/java_client/pagefactory/ElementInterceptor.java
index 17d4a2a6..a95740af 100644
--- a/src/main/java/io/appium/java_client/pagefactory/ElementInterceptor.java
+++ b/src/main/java/io/appium/java_client/pagefactory/ElementInterceptor.java
@@ -16,6 +16,8 @@
 
 package io.appium.java_client.pagefactory;
 
+import static io.appium.java_client.pagefactory.ThrowableUtil.extractReadableException;
+
 import io.appium.java_client.pagefactory.interceptors.InterceptorOfASingleElement;
 import org.openqa.selenium.WebDriver;
 import org.openqa.selenium.WebElement;
@@ -37,7 +39,7 @@ class ElementInterceptor extends InterceptorOfASingleElement {
         try {
             return method.invoke(element, args);
         } catch (Throwable t) {
-            throw ThrowableUtil.extractReadableException(t);
+            throw extractReadableException(t);
         }
     }
 }
diff --git a/src/main/java/io/appium/java_client/pagefactory/ElementListInterceptor.java b/src/main/java/io/appium/java_client/pagefactory/ElementListInterceptor.java
index 0c326c2f..08c58627 100644
--- a/src/main/java/io/appium/java_client/pagefactory/ElementListInterceptor.java
+++ b/src/main/java/io/appium/java_client/pagefactory/ElementListInterceptor.java
@@ -16,6 +16,8 @@
 
 package io.appium.java_client.pagefactory;
 
+import static io.appium.java_client.pagefactory.ThrowableUtil.extractReadableException;
+
 import io.appium.java_client.pagefactory.interceptors.InterceptorOfAListOfElements;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.support.pagefactory.ElementLocator;
@@ -37,7 +39,7 @@ class ElementListInterceptor extends InterceptorOfAListOfElements {
         try {
             return method.invoke(elements, args);
         } catch (Throwable t) {
-            throw ThrowableUtil.extractReadableException(t);
+            throw extractReadableException(t);
         }
     }
 
diff --git a/src/main/java/io/appium/java_client/pagefactory/WidgetInterceptor.java b/src/main/java/io/appium/java_client/pagefactory/WidgetInterceptor.java
index 76823a5c..37fb1c21 100644
--- a/src/main/java/io/appium/java_client/pagefactory/WidgetInterceptor.java
+++ b/src/main/java/io/appium/java_client/pagefactory/WidgetInterceptor.java
@@ -16,6 +16,7 @@
 
 package io.appium.java_client.pagefactory;
 
+import static io.appium.java_client.pagefactory.ThrowableUtil.extractReadableException;
 import static io.appium.java_client.pagefactory.utils.WebDriverUnpackUtility.getCurrentContentType;
 
 import io.appium.java_client.pagefactory.bys.ContentType;
@@ -76,7 +77,7 @@ class WidgetInterceptor extends InterceptorOfASingleElement {
             method.setAccessible(true);
             return method.invoke(cachedInstances.get(type), args);
         } catch (Throwable t) {
-            throw ThrowableUtil.extractReadableException(t);
+            throw extractReadableException(t);
         }
     }
 
diff --git a/src/main/java/io/appium/java_client/pagefactory/WidgetListInterceptor.java b/src/main/java/io/appium/java_client/pagefactory/WidgetListInterceptor.java
index 86647f9a..ff4a9f74 100644
--- a/src/main/java/io/appium/java_client/pagefactory/WidgetListInterceptor.java
+++ b/src/main/java/io/appium/java_client/pagefactory/WidgetListInterceptor.java
@@ -16,6 +16,7 @@
 
 package io.appium.java_client.pagefactory;
 
+import static io.appium.java_client.pagefactory.ThrowableUtil.extractReadableException;
 import static io.appium.java_client.pagefactory.utils.WebDriverUnpackUtility.getCurrentContentType;
 
 import io.appium.java_client.pagefactory.bys.ContentType;
@@ -70,7 +71,7 @@ class WidgetListInterceptor extends InterceptorOfAListOfElements {
         try {
             return method.invoke(cachedWidgets, args);
         } catch (Throwable t) {
-            throw ThrowableUtil.extractReadableException(t);
+            throw extractReadableException(t);
         }
     }
 }
diff --git a/src/main/java/io/appium/java_client/pagefactory/interceptors/InterceptorOfASingleElement.java b/src/main/java/io/appium/java_client/pagefactory/interceptors/InterceptorOfASingleElement.java
index 1dca59a4..6322a3c0 100644
--- a/src/main/java/io/appium/java_client/pagefactory/interceptors/InterceptorOfASingleElement.java
+++ b/src/main/java/io/appium/java_client/pagefactory/interceptors/InterceptorOfASingleElement.java
@@ -23,7 +23,6 @@ import org.openqa.selenium.WebElement;
 import org.openqa.selenium.internal.WrapsDriver;
 import org.openqa.selenium.support.pagefactory.ElementLocator;
 
-import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
 
@@ -37,7 +36,7 @@ public abstract class InterceptorOfASingleElement implements MethodInterceptor {
     }
 
     protected abstract Object getObject(WebElement element, Method method, Object[] args)
-        throws InvocationTargetException, IllegalAccessException, InstantiationException, Throwable;
+        throws Throwable;
 
     /**
      * Look at
@@ -45,6 +44,11 @@ public abstract class InterceptorOfASingleElement implements MethodInterceptor {
      */
     public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
         throws Throwable {
+
+        if (method.getName().equals("toString") && args.length == 0) {
+            return locator.toString();
+        }
+
         if (Object.class.equals(method.getDeclaringClass())) {
             return proxy.invokeSuper(obj, args);
         }