Gino Mortillero
Gino Mortillero

Reputation: 125

Selenium C#: How to Find Element Again

First time here. So I was wanting some help on a selenium testing that's got me stuck now for several hours.

So I stored a IList<IWebElement> on a page, composed of <a>. I was able to click the 1st element of that IList through a foreach, get what I need from the new page and go back to the page of the list using driver.manage.navigate.back().

However, this time, I can't click the 2nd element of the list.

Is there a way to find that 2nd element, 3rd element, 4th element, etc?

static void Main(string[] args)
{
    IWebDriver driver = new FirefoxDriver();
    string url = "http://DummyPageOne.Com";        
    driver.Navigate().GoToUrl(url);
    driver.Manage().Timeouts().ImplicitlyWait(Timespan.FromSeconds(10));

    PageOne page = new PageOne();

    foreach (IWebElement item in page.Items)
    {
        item.Click();
        ItemDetails details = new ItemDetails();
        details.SaveImage(@"D:\Images\");
        driver.Navigate().Back();
    }
}


public class PageOne()
{
    public PageOne()
    {
        PageFactory.InitElements(driver, this);
    }

    public IList<IWebElement> Items;

    public void StoreItems()
    {
        string locator = "DummyLocator";
        Items = driver.FindElements(By.Xpath(locator));
    }
}

public class ItemDetails()
{
    public ItemDetails()
    {
        PageFactory.InitElements(driver, this);
    }

    public void SaveImage()
    {
    }
}

Upvotes: 0

Views: 1745

Answers (3)

amitbobade
amitbobade

Reputation: 510

On the basis of what I understood from your question, here is the way to achieve that. I checked the following C# Code on Chrome and it's working perfectly. I hope this helps.

    [Test]
    public void ClickAllLinks()
    {
        //Navigate to URL
        driver.Navigate().GoToUrl(@"https://www.google.co.in/#q=Selenium");

        //Store Links in IList
        IList<IWebElement> resultLinks = driver.FindElements(By.CssSelector("div#ires>ol>div:not(:first-child)>div>div>h3>a"));

        //Print Count
        //Console.WriteLine(googleLinks.Count);

        for (int i = 0; i < resultLinks.Count; i++)
        {
            int j = i + 1;

            //Click on Link
            driver.FindElement(By.CssSelector("div#ires>ol>div:not(:first-child)>div:nth-child(" + j + ")>div>h3>a")).Click();

            //Print Element Locator
            //Console.WriteLine("div#ires>ol>div:not(:first-child)>div:nth-child(" + j + ")>div>h3>a");

            Thread.Sleep(2000); //Static wait is not recommended, add conditional wait

            //Get what you need from new page

            //Navigate back parent page
            driver.Navigate().Back();

            Thread.Sleep(2000); //Static wait is not recommended, add conditional waits
        }
    }

If this is not what you want please let me know.

Upvotes: 1

Leon Barkan
Leon Barkan

Reputation: 2703

The simple way is to initialize that list again in the end of loop.

Upvotes: 1

Baaleos
Baaleos

Reputation: 1825

Ok, the thing to remember about .Net and Selenium, is that the C# variables/types are references to things that exist in memory (on screen) in the browser.

When the browser window navigates away, the reference held by those variables will be invalid. You must 're-find' them.

I would be very surprised if you could click the first item in the list either.

The only way to click on these objects, is to reacquire the object after the page has reloaded. Eg: Driver.FindElement(By.XPath("\\div[@class='somelocator']"));

If you can, I would recommend constructing a collection of 'By' classes. Then loop through the By classes using them in the Find method.

That way, each iteration of the loop, you will be acquiring the object fresh.

Upvotes: 0

Related Questions