Question

Preface: While this question includes a lot of WebDriver terminology, it's really a Java proxies question, which I am still trying to wrap my head around. If you don't understand WebDriver, skip down, and I'll post a simplified problem

I currently have a wrappers around WebElement and List<WebElement>, namely EnhancedWebElement and WebElementList. It is for quite a few reasons, and has allowed me quite a bit of flexibility. I also use the page object pattern, and declare all of my elements as the two wrappers I have created (which works great).

However, I recently asked this question. I wanted to find an element within an element, and still keep the entire thing within a proxy. The answer worked great, and I made it generic and put it in my EnhancedWebElement class. It looks like this:

public EnhancedWebElement findEnhancedWebElement(final By by){
        return (EnhancedWebElement) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class<?>[] { WebElement.class }, new InvocationHandler() {
            // Lazy initialized instance of WebElement
            private EnhancedWebElement webElement;

            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                if (webElement == null) {
                    webElement = new EnhancedWebElement(findElement(by), driver);
                }
                return method.invoke(webElement, args);
            }
        });
    }

However...this has one problem. If I find an element within an element within an element, I lose the first proxy. This is because it instantiates the element in order to perform the next findEnhancedWebElement() function.

While you may think my crazy, my goal is to have a set of functions so I could do something like this:

EnhancedWebElement newElement = element.findElements(By.foo).getElementFoundBy(By.bar).findElement(By.foobar);

and still not performed any selecting on the page until I do newElement.click() or whatever action on the element.

(If you are really wondering why, it is because I have quite a few functions in EnhancedWebElement and WebElementList that depend on it not being instantiated. If I was just going to perform a click(), then I wouldn't need all this)

For all people that don't understand WebDriver. I have Object X. It has a function that can return another object X, but only after doing some processing. Object X also has other functions. If I do X someObject = new X().getX().getX().getX(), I don't want any of the processing to be done until I do someObject.otherFunction()

Was it helpful?

Solution

I figured it out. I needed to create a proxy around the original WebElement, not the new EnhancedWebElement, and then create a new instance of EnhancedWebElement wrapped around it. That way, when I am using the findEnhancedWebElement(), I never touch the original WebElement.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top