yandex-qatools / htmlelements

Html Elements is a Java framework providing easy-to-use way of interaction with web-page elements in web-page tests.
Other
271 stars 116 forks source link

Not informative 'Unable to locate the element' message #46

Open yashaka opened 11 years ago

yashaka commented 11 years ago

If the element could not be find by locator (in the chromedriver case at least), The following exception is thrown:

org.openqa.selenium.NoSuchElementException: Timed out after 5 seconds. Unable to locate the element
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '2.31.0', revision: '1bd294d185a80fa4206dfeab80ba773c04ac33c0', time: '2013-02-27 13:51:26'
System info: os.name: 'Linux', os.arch: 'amd64', os.version: '3.8.0-27-generic', java.version: '1.7.0_25'
Driver info: driver.version: unknown
    at ru.yandex.qatools.htmlelements.pagefactory.AjaxElementLocator.findElement(AjaxElementLocator.java:73)
    at ru.yandex.qatools.htmlelements.loader.decorator.proxyhandlers.WebElementNamedProxyHandler.invoke(WebElementNamedProxyHandler.java:29)
    at com.sun.proxy.$Proxy11.isDisplayed(Unknown Source)
    at com.swisscom.stargate.staf.webui.PagesContentStaticTest.assertPageExpectedElementsAreDisplayed(PagesContentStaticTest.java:45)

Why not add additional info about the element (annotated with @FindBy) which was not find? At least something to identify it from the test result... The variable name, locator (xpath, css used in FindBy, etc.), etc...

aik099 commented 11 years ago

:+1:

yashaka commented 11 years ago

If this would be interested for anybody... So far I am using the following workaround:


    public static void assertElementIsDisplayed(WebElement element, boolean expectedIsDisplayed) {
        //get '@FindBy' locator from the element
        By locatorBy = null;
        try {
            Field locatorField = null;
            InvocationHandler innerProxy = Proxy.getInvocationHandler(((Proxy) element));
            locatorField = innerProxy.getClass().getDeclaredField("locator");
            locatorField.setAccessible(true);
            AjaxElementLocator locator = (AjaxElementLocator) locatorField.get(innerProxy);
            Field byField = locator.getClass().getSuperclass().getDeclaredField("by");
            byField.setAccessible(true);
            locatorBy = (By) byField.get(locator);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassCastException e) { //TODO: refactor: why? somehow HtmlElement objects can't be cast to Proxy...
            e.printStackTrace();
        }

        String errorMsg = element +  " element should be displayed? - " + expectedIsDisplayed +
                "\nElement locator: " + ((locatorBy != null) ? locatorBy : "Could not get, see sources...");

        try {
            assertEquals(element.isDisplayed(), expectedIsDisplayed, errorMsg);
        } catch (NoSuchElementException e) {
            fail(errorMsg + "\n" + e + "\n" + e.getStackTrace());
        }
artkoshelev commented 11 years ago

Can you provide the test reproducing the problem? Described behavior looks weird for me, cause we use @Name annotation to format pretty message when element is not found, and when there is no @Name annotation we use field name to create one.

yashaka commented 11 years ago

Thid is a test:

public class TempTest {
    @Test
    public void test(){
        class GooglePage {
            private WebDriver driver;

            @FindBy(name = ".gbqfif.WRONG")
            WebElement myWebElement;

            GooglePage(WebDriver driver) {
                this.driver = driver;
                driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
                HtmlElementLoader.populate(this, driver);
                driver.get("http://google.com");
            }
        }
        WebDriver driver = new FirefoxDriver();
        GooglePage page = new GooglePage(driver);
        try {
            page.myWebElement.isDisplayed();
        } catch (NoSuchElementException e) {
            System.out.println("\n*** With Firefox driver ***\n\n\n");
            e.printStackTrace();
        }

        System.setProperty("webdriver.chrome.driver", "webdriver-webui-tests/webdriver/" + System.getProperty("os.name") + "/chromedriver");
        driver = new ChromeDriver();
        page = new GooglePage(driver);
        try {
            page.myWebElement.isDisplayed();
        } catch (NoSuchElementException e) {
            System.out.println("\n\n*** With Chrome driver (latest version) ***\n\n");
            e.printStackTrace();
        }

        driver.quit();
    }
}

And this is console output:

*** With Firefox driver ***

org.openqa.selenium.NoSuchElementException: Timed out after 5 seconds. Unable to locate the element
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '2.31.0', revision: '1bd294d185a80fa4206dfeab80ba773c04ac33c0', time: '2013-02-27 13:51:26'
System info: os.name: 'Linux', os.arch: 'amd64', os.version: '3.8.0-29-generic', java.version: '1.7.0_25'
Driver info: driver.version: unknown
    at ru.yandex.qatools.htmlelements.pagefactory.AjaxElementLocator.findElement(AjaxElementLocator.java:73)
    at ru.yandex.qatools.htmlelements.loader.decorator.proxyhandlers.WebElementNamedProxyHandler.invoke(WebElementNamedProxyHandler.java:29)
    at com.sun.proxy.$Proxy6.isDisplayed(Unknown Source)
    at com.swisscom.stargate.staf.webui.TempTest.test(TempTest.java:93)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    ...
Caused by: org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"name","selector":".gbqfif.WRONG"}
Command duration or timeout: 2.07 seconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '2.31.0', revision: '1bd294d185a80fa4206dfeab80ba773c04ac33c0', time: '2013-02-27 13:51:26'
System info: os.name: 'Linux', os.arch: 'amd64', os.version: '3.8.0-29-generic', java.version: '1.7.0_25'
Session ID: 740acdaf-4324-446a-a39a-6e7f4b2ed269
Driver info: org.openqa.selenium.firefox.FirefoxDriver
Capabilities [{platform=LINUX, databaseEnabled=true, cssSelectorsEnabled=true, javascriptEnabled=true, acceptSslCerts=true, handlesAlerts=true, browserName=firefox, browserConnectionEnabled=true, nativeEvents=false, webStorageEnabled=true, rotatable=false, locationContextEnabled=true, applicationCacheEnabled=true, takesScreenshot=true, version=23.0}]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    ...
Caused by: org.openqa.selenium.remote.ErrorHandler$UnknownServerException: Unable to locate element: {"method":"name","selector":".gbqfif.WRONG"}
Build info: version: '2.31.0', revision: '1bd294d185a80fa4206dfeab80ba773c04ac33c0', time: '2013-02-27 13:51:26'
System info: os.name: 'Linux', os.arch: 'amd64', os.version: '3.8.0-29-generic', java.version: '1.7.0_25'
Driver info: driver.version: unknown
    at <anonymous class>.FirefoxDriver.prototype.findElementInternal_(file:///tmp/anonymous8175408390086870472webdriver-profile/extensions/fxdriver@googlecode.com/components/driver_component.js:8281)
    at <anonymous class>.fxdriver.Timer.prototype.setTimeout/<.notify(file:///tmp/anonymous8175408390086870472webdriver-profile/extensions/fxdriver@googlecode.com/components/driver_component.js:382)
Started ChromeDriver (v2.1) on port 24962
org.openqa.selenium.NoSuchElementException: Timed out after 5 seconds. Unable to locate the element

For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html

*** With Chrome driver (latest version) ***

Build info: version: '2.31.0', revision: '1bd294d185a80fa4206dfeab80ba773c04ac33c0', time: '2013-02-27 13:51:26'

System info: os.name: 'Linux', os.arch: 'amd64', os.version: '3.8.0-29-generic', java.version: '1.7.0_25'

Driver info: driver.version: unknown
    at ru.yandex.qatools.htmlelements.pagefactory.AjaxElementLocator.findElement(AjaxElementLocator.java:73)
    at ru.yandex.qatools.htmlelements.loader.decorator.proxyhandlers.WebElementNamedProxyHandler.invoke(WebElementNamedProxyHandler.java:29)
    at com.sun.proxy.$Proxy6.isDisplayed(Unknown Source)
    at com.swisscom.stargate.staf.webui.TempTest.test(TempTest.java:103)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    ...
Caused by: org.openqa.selenium.NoSuchElementException: no such element
  (Session info: chrome=29.0.1547.57)
  (Driver info: chromedriver=2.1,platform=Linux 3.8.0-29-generic x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 2.03 seconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '2.31.0', revision: '1bd294d185a80fa4206dfeab80ba773c04ac33c0', time: '2013-02-27 13:51:26'
System info: os.name: 'Linux', os.arch: 'amd64', os.version: '3.8.0-29-generic', java.version: '1.7.0_25'
Session ID: 315dbf800f3308b5213ba58b88bad1c1
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities [{platform=LINUX, acceptSslCerts=true, javascriptEnabled=true, browserName=chrome, chrome={chromedriverVersion=2.1}, rotatable=false, locationContextEnabled=true, version=29.0.1547.57, cssSelectorsEnabled=true, databaseEnabled=true, handlesAlerts=true, browserConnectionEnabled=false, webStorageEnabled=true, nativeEvents=true, applicationCacheEnabled=false, takesScreenshot=true}]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    ...

===============================================
Custom suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================

As you can see there is a locator info in case of Firefox driver:

Caused by: org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"name","selector":".gbqfif.WRONG"}

And there is no any info in case of Chrome driver:

Caused by: org.openqa.selenium.NoSuchElementException: no such element
  (Session info: chrome=29.0.1547.57)
  (Driver info: chromedriver=2.1,platform=Linux 3.8.0-29-generic x86_64) (WARNING: The server did not provide any stacktrace information)

In both cases I did not find any 'pretty print' of the name of my element. I would expect something like: 'My Web Element' what is the output of the

myWebElement.toString();

Maybe something is wrong with my environment... It would be great if you try to reproduce the issue on your env.

olionajudah commented 10 years ago

just encountered this myself.

the lack of locator info using the chrome driver was sufficient motivation to download firefox and switch my testing there.

chrome driver: selenium.common.exceptions.NoSuchElementException: Message: 'no such element\n (Session info: chrome=36.0.1985.125)\n (Driver info: chromedriver=2.10.267517,platform=Mac OS X 10.8.5 x86_64)'

firefox driver: selenium.common.exceptions.NoSuchElementException: Message: 'Unable to locate element: {"method":"id","selector":"id_new_item"}' ;

aik099 commented 10 years ago

What you actually posted looks like log of Selenium server. It's up to Selenium server whatever or not to display used selector.

What @artkoshelev meant is that in your Java test suite you'll get nice exception back (when element location failed by given @FindBy annotation) and in there you'll see it's name and actual locator.

Selenium server isn't displaying any test suite exception except ones that it generates by itself.

olionajudah commented 10 years ago

you're right. sorry for the confusion

lanwen commented 9 years ago

Will be added cause info with selector in #75. Can i close this issue for now? @olionajudah