user3921936
user3921936

Reputation: 23

Waiting for a frame to load using Selenium

I have seen many posts on handling switching between frames in Selenium but they all seem to reference the Java 'ExpectedConditions' library for the below method.

ExpectedConditions.frameToBeAvailableAndSwitchToIt

I was wondering if there is any C# implementation anywhere or if anyone has any such work around?

Cheers

Upvotes: 2

Views: 4754

Answers (3)

kuradac
kuradac

Reputation: 494

These answers are old and I had the same issue. I was able to use SeleniumExtras.WaitHelpers.ExpectedConditions from nuget to achieve this easily.

//wait for 10 seconds max for the frame
WebDriverWaitwait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.Id("FRAMEID")));

Upvotes: 2

vt100
vt100

Reputation: 1013

I have just committed such a ugly code. Dropping here for the future!

     protected void SwitchToFrame(int iframe = 1)
    {
        var driver = GetWebDriver();
        driver.SwitchTo().DefaultContent();
        bool done = false, timeout = false;
        int counter = 0;
        do
        {
            counter++;
            try
            {
                driver.SwitchTo().Frame(iframe);
                done = true;
            }
            catch (OpenQA.Selenium.NoSuchFrameException)
            {
                if (counter <= Constants.GLOBAL_MAX_WAIT_SEC)
                {
                    Wait(1);
                    continue;
                }
                else timeout = true;
            } 
        } while (!done && !timeout);
        if (timeout) throw new OpenQA.Selenium.NoSuchFrameException(iframe.ToString());
    }

Upvotes: 0

Arran
Arran

Reputation: 25076

There isn't a direct equivalent in the C# bindings but it's very easy to do this yourself.

Remember that Selenium is open source so let's dig out the source code. Here is the Java ExpectedConditions and here is the C# set.

So what's the Java version doing? Well, not a lot I tell you.

try {
  return driver.switchTo().frame(frameLocator);
} catch (NoSuchFrameException e) {
  return null;
}

All it's doing is attempting to switch to the frame you tell it to, and providing it was successful (as in, there was no exception in attempting to do that), then it's assumed it can carry on.

So, all you'll need to do is do the same thing in C#, so something like (not compiled):

public static Func<IWebDriver, bool> WaitUntilFrameLoadedAndSwitchToIt(By byToFindFrame)
{
    return (driver) =>
            {
                try
                {
                    return driver.SwitchTo().Frame(driver.FindElement(byToFindFrame));
                }
                catch (Exception)
                {
                    return null;
                }

                return true;
            };
}

As in, keep the same concept: try to find the frame and switch to it, any exceptions then we return null and force the caller (usually a WebDriverWait instance) to iterate through again. Returning true will tell the caller that we are happy we can move on.

All the waiting & expected conditions classes live in the OpenQA.Selenium.Support.UI namespace which lives in the WebDriver.Support.dll assembly.

Upvotes: 4

Related Questions