How to write my own customize locator for Selenium webdriver in java?

18,580

Solution 1

You would need to subclass the By class and provide an implementation for findElement and findElements methods, since this is where the 'meat' of the actual element finding occurs.

You should then be able to use it with the normal driver.FindElement then.

Solution 2

using c#

using OpenQA.Selenium;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

public class ImageBy : By
{
    public ImageBy(string imageByString)
    {
        FindElementMethod = (ISearchContext context) =>
        {
            IWebElement mockElement = context.FindElement(By.XPath("//img[@src='" + imageByString + "']"));
            return mockElement;
        };

        FindElementsMethod = (ISearchContext context) =>
        {
            ReadOnlyCollection<IWebElement> mockElements = context.FindElements(By.XPath("//img[@src='" + imageByString + "']"));
            return mockElements;
        };
    }
}

and the usage would be as follows

[FindsBy(How = How.Custom, Using = @"/path/to/img", CustomFinderType = typeof(ImageBy) )]
private IWebElement MenuStartButton = null;

Using Java

import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.WebElement;

public class ByImageSrc extends By 
{
    private final String imageByString;
    public ByImageSrc(String imageByString)
    {
        this.imageByString = imageByString;
    }

    @Override
    public List<WebElement> findElements(SearchContext context) 
    {
         List<WebElement> mockElements = context.findElements(By.xpath("//img[@src='" + imageByString + "']"));
         return mockElements;
    }
}

usage :

WebElement element = driver.findElement(new ByImageSrc("/path/to/image"));
Share:
18,580
BlueSky
Author by

BlueSky

Updated on June 16, 2022

Comments

  • BlueSky
    BlueSky almost 2 years

    I want to write my own locator to access the elements. WebDriver’s API offers currently eight locators allowing to retrieve elements by id, name attribute, tag name, complete or partial link text, XPath, class name, and css selector. However those default locators not enough for me now because I have to access the elements through a new attribute. Let me give an xample so that you can understand what I really want here.

    Example: Choose your username:

    Now I want to write a code so that I can access the username button using the myLocator locator like:

    *driver.findElement(By.myLocator("username")).*
    

    It would be very helpful if anybody can give us some good idea how could I rewrite the BY class to add my own locator.

    Thank you in advance for your help.

  • BlueSky
    BlueSky over 11 years
    Thank you for your quick answer. Actually in our current environment, xpath does not work most of the time since the internal structure changes frequently and in some scenario that is not possible. That’s why designers decided to add a new attribute for automation purpose and they don’t want us to use the id or name of an element, because they also change time to time according to their requirements. Thanks again.
  • BlueSky
    BlueSky over 11 years
    Thanks for your reply. Our current project is very very big and long term project. At the beginning we also thought to create a separate file to keep the change, however we found that would be more painful through out the project life time. Then we decided to implement new locator to avoid any future problem.
  • Nashibukasan
    Nashibukasan over 11 years
    I am currently working on a project that has been running for over 15 months and we just implemented our own 'Element' object that takes in a type and a string. From here the locating implementation is hidden in another layer. I guess this is much the same as what you are trying to achieve. Good luck!