Yi Zeng
Yi Zeng

Reputation: 32845

How to find a WebElement by another WebElement using Page Factory

Had a brief scan at the source code, not sure what's the best practice for this.

For example, say I have a page object 'DummyPage', which has two panel elements TopPanel and BottomPanel. Each of the panel has some elements, which are found by TopPanel.FindElement() instead of driver.FindElement(). How to apply Page Factory for this?

I'm aware of that PageFactory.InitElements(ISearchContext, Object) takes in ISearchContext, however, I'm not sure how can I use it for the page and the panel elements in one class.

public class DummyPage {

    private IWebDriver driver;

    public DummyPage(IWebDriver driver) {
        this.driver = driver;
    }

    public IList<IWebElement> DummyLinks {
        get { return driver.FindElements(By.CssSelector(".some-dummy-links")); }
    }

    public IWebElement TopPanel {
        get { return driver.FindElement(By.Id("top-panel")); }
    }

    public IWebElement BottomPanel {
        get { return driver.FindElement(By.Id("bottom-panel")); }
    }

    public IWebElement FooInTopPanel {
        get { return TopPanel.FindElement(By.CssSelector(".something")); }
    }

    public IWebElement FooInBottomPanel {
        get { return BottomPanel.FindElement(By.CssSelector(".something")); }
    }
}

public class DummyPageWithPageFactory {

    public DummyPageWithPageFactory(IWebDriver driver) {
        PageFactory.InitElements(driver, this);
    }

    [FindsBy(How = How.CssSelector, Using = ".some-dummy-links")]
    public IList<IWebElement> DummyLinks { get; private set; }

    [FindsBy(How = How.Id, Using = "top-panel")]
    public IWebElement TopPanel { get; private set; }

    [FindsBy(How = How.Id, Using = "bottom-panel")]
    public IWebElement BottomPanel { get; private set; }

    //public IWebElement FooInTopPanel { get; private set; }
    //public IWebElement FooInBottomPanel { get; private set; }
}

If I use driver.FindElement() for all instances and concatenate all locators, I might be facing another situation, that all locators are too long and I can't use variables within the C# attributes.

[FindsBy(How = How.CssSelector, Using = "#top-panel .blah .blah .super-long-blah .something")]
[FindsBy(How = How.CssSelector, Using = "#top-panel .blah .blah .super-long-blah .something-new")]
[FindsBy(How = How.CssSelector, Using = "#bottom-panel .blah .blah .super-long-blah .something")]

Upvotes: 2

Views: 3093

Answers (1)

user7720110
user7720110

Reputation: 11

See this example:

[FindsBy(How = How.Name, Using = "anElementName", Priority = 0)]
[FindsBy(How = How.Name, Using = "differentElementName", Priority = 1)]
public IWebElement thisElement;

Upvotes: 1

Related Questions