Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 229
BlueSky Avatar asked Jan 10 '13 17:01

BlueSky


People also ask

What are custom locators in Selenium?

Selenium supports 8 different types of locators namely id, name, className, tagName, linkText, partialLinkText, CSS selector and xpath.

Which is the best locator to use in Selenium?

ID locator in Selenium is the most preferred and fastest way to locate desired WebElements on the page. ID Selenium locators are unique for each element in the DOM. Since IDs are unique for each element on the page, it is considered the fastest and safest method to locate elements.

How do I practice locators in Selenium?

Aim for the long-hanging fruit One of Selenium best practices for locators is to always look for unique stuff. In ~90% of cases, we're talking about unique IDs. The remaining 10% account for things like unique name tags, link content (anchor texts), or links that you can use in combination with parent-child structures.


2 Answers

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"));
like image 159
Sridhar Avatar answered Sep 18 '22 05:09

Sridhar


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.

like image 29
Arran Avatar answered Sep 19 '22 05:09

Arran