Wrapping the native WebElement instances

100 views
Skip to first unread message

bobbit...@gmail.com

unread,
Oct 22, 2017, 9:52:36 PM10/22/17
to Selenium Users
Is there an official way to wrap the native WebElements produced by findElement() with my own wrapper class?  I need to execute custom behavior when various APIs like clear(), sendKeys(), etc. are called.  Obviously, I could just write a completely separate class and functions that take WebElements as arguments, but I'd prefer to wrap WebElement so everything looks the same.

Since WebElement is an interface, you'd think you could just write a container class, store the "real" WebElement as a member, and then implement all the interface methods, calling the same methods on the stored member.  Unfortunately, this isn't enough.  Various internals of WebDriver, such as the JavaScriptExecutor, and Actions, seem to need more than just that API.  In fact I found a few internal APis, such as WrapsElement, and others that may help, but obviously these internal methods aren't meant for external users of WebDriver, and presumably may change at any time.  If there's no official way to wrap WebElement without going down that rabbit hole, however, I suppose that's the only option.

Note that I'd like to do the same think for Actions, too, if that's possible.  One useful addition for actions would be something like actions.getState(), actions.setState(), so that if say an exception happens when you perform(), you can retry (if you called getState() before perform()) by just calling setState() on actions after the failure, and then perform()ing again.  As it stands, if perform() encounters an exception, you're basically screwed and the app code must handle rebuilding the chain of action calls.

Krishnan Mahadevan

unread,
Oct 22, 2017, 11:31:20 PM10/22/17
to seleniu...@googlegroups.com

Why not just extract out the org.openqa.selenium.remote.CommandExecutor, wrap it up with a decorated one, which does extra things based on the incoming org.openqa.selenium.remote.DriverCommand before/after executing the actual command ? That way you can execute your custom code and also not have to worry about building your wrapper class as well.

 

Ideally speaking, EventFiringWebDriver was created for this very need, but since it doesn’t support Actions class, the org.openqa.selenium.remote.CommandExecutor approach would be the easiest way out.

 

Please take a look at my blog post : https://rationaleemotions.wordpress.com/2015/04/18/eavesdropping-into-webdriver/ which shows all of this in action.

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to selenium-user...@googlegroups.com.
To post to this group, send email to seleniu...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/selenium-users/84bc6029-f465-414b-bbe7-36d330677474%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ross Rochford

unread,
Oct 23, 2017, 5:17:58 AM10/23/17
to Selenium Users
I ended up using a container class and this was sufficient for what I needed but sounds like it's not for your project. 

One annoying thing I found was, because I was caching data inside the container object, I had to use a central factor class for getting WebDriver elements. So for example both calls to driver.find_elements_by_xpath() and element.find_elements_by_xpath() had to go through the same factory object and return any container objects that were previously instantiated.
Reply all
Reply to author
Forward
0 new messages