Custom Locators Part 2
Now that we’ve developed our “custom” PageFactory, we need to create create a couple of more classes before our annotation is fully usable. The first of which is the CustomElementLocatorFactory. It will be responsible for telling the PageFactory to use our CustomElementLocator, which we will go over in just a minute. Here is the implementation for our Factory method:
public class CustomElementLocatorFactory implements ElementLocatorFactory { private final WebDriver driver; public CustomElementLocatorFactory(final WebDriver driver) { this.driver = driver; } @Override public ElementLocator createLocator(final Field field) { if (field.isAnnotationPresent(JQueryLocator.class)) { return new CustomElementLocator((JavascriptExecutor) driver, field); } else { return new DefaultElementLocator(driver, field); } } }
Once we’ve completed our CustomElementLocator we are good to go. Here’s the sample implementation:
public class CustomElementLocator implements ElementLocator { private final JavascriptExecutor driver; private final JQueryLocator jql; public CustomElementLocator(final JavascriptExecutor driver, final Field field) { this.driver = driver; this.jql = field.getAnnotation(JQueryLocator.class); } @Override public WebElement findElement() { return (WebElement) driver.executeScript("return $" + jql.$() + "[0];"); } @SuppressWarnings("unchecked") @Override public List<WebElement> findElements() { return (List<WebElement>) driver.executeScript("return $" + jql.$()); } }
We now can utilize the new annotation in any of our Page Objects, and have it work with our custom PageFactory. Here is a sample PageObject:
public class JQueryHomePage { private final WebDriver driver; @JQueryLocator($ = "('#jq-intro')") private WebElement introDivWithJQuery; @FindBy(id = "jq-intro") private WebElement introDivWithDefault; public JQueryHomePage(final WebDriver driver) { this.driver = driver; driver.get("http://jquery.com/"); CustomPageFactory.initElements(driver, this); } public WebElement getIntroDivWithJQuery() { return introDivWithJQuery; } public WebElement getIntroDivWithDefault() { return introDivWithDefault; } }
And here is a simple class to test that things are working as expected:
public class JQueryHomePageTest { private static WebDriver driver; private static JQueryHomePage homePage; @BeforeClass public static void setup() { driver = new FirefoxDriver(); homePage = new JQueryHomePage(driver); } @Test public void ensureItemsAreSame() { Assert.assertThat(homePage.getIntroDivWithJQuery().equals(homePage.getIntroDivWithDefault()), Matchers.is(true)); } @AfterClass public static void shutdown() { driver.quit(); } }
Advertisements
3 Comments
Leave a CommentTrackbacks