Cloning "By": Defensive Programming with Selenium

186 Views Asked by At

So I'm writing a Panel Object API for a website I'm testing with Selenium, and since this one is likely to be used by many people outside of my control in the future, I thought I may as well make it defensive (as seen in Effective Java). However, I've hit a wall when it comes to returning a clone of By.

I was expecting a method like arrayList has:

By newBy = new By(oldBy);

Doesn't exist as By is made statically. Further, I don't know of any way to get the information out of a By once the information is in there except for toString(). So I can write a parser for By.toString(), but that seems like a lot of effort for what the job is, and not very elegant to boot.

Can anyone suggest a less cumbersome way of cloning a By locator in selenium?

2

There are 2 best solutions below

3
On BEST ANSWER

mind you, this is simply an alternative.

In terms of defensive programming, one thing I could recommend to you, which i've done in several other automation frameworks using Selenium...

Is to wrap the driver.findElement then accept only CSS selectors, IDs, Xpath, whatever you want. An example would be this:

@Config(
    url="http://wordpress.org",
    browser = Browser.CHROME
)
public class GettingStarted extends AutomationTest {
    @Test
    public void testSeleniumHQ() {
        navigateTo("http://docs.seleniumhq.org")
        .click("a[title='Selenium Projects']")
        .click(By.xpath("//div[contains(@class, 'bigMenu')]//p/a[@href='webdriver/']"))
        .validateTextPresent("Selenium 1.0 + WebDriver = Selenium 2.0")
        ;
    }
}

(exerpt from this class using the Getting Started with Selenium framework)

In here, click is overloaded to accept a String (CSS selector) but can also accept the By class.

If you want all of your developers to use one thing in particular, instead of accepting a By, just make it accept a String, and the String HAS to be CSS, an ID, or Xpath (whatever you prefer). This would make it a little cleaner, and definitely more consolidated. (Your testers would be forced to use CSS or whatever you choose)

0
On

By is an abstract class. As stated here you can't create deep clone of abstract class because they can't be instantiated. You can take a look at the suggested hack though but I think you don't need to be so defensive