6

I'm trying to wait for Selenium to switch changing frames before waiting on another element. I.e.

var wait = new WebDriverWait(driver, 15);
wait.Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.Id("frameA"));

var wait2 = new WebDriverWait(driver, 15);
// wait for element within frameA to exist
wait2.Until(ExpectedConditions.ElementExists(By.Id("elementA")));

If I toss in a simple Thread.Sleep(1000); before the second wait it functions fine, but without that I get the following error:

'unknown error: unhandled inspector error: {"code":-32000,"message":"Cannot find context with specified id"}
    enter code here

Is there a better way to wait for the frame context to switch finishing before waiting for an element within that frame to be populated?

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352

4 Answers4

2

You can wait for the frame itself to be clickable:

wait2.Until(ExpectedConditions.ElementExists(By.Id("YOURFRAMEID")));
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
San
  • 37
  • 6
2

There are a couple of things you need to consider :

The line of code to switch to the frame looks perfect which doesn't throws any error :

var wait = new WebDriverWait(driver, 15);
wait.Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.Id("frameA"));

In the next line you have tried the ExpectedConditions method ElementExists. As per the API Docs ElementExists Method is defined as :

An expectation for checking that an element is present on the DOM of a page. This does not necessarily mean that the element is visible.

Selenium can't interact with elements until the element is visible. Hence you need to use the method ElementIsVisible as follows :

var wait2 = new WebDriverWait(driver, 15);
wait2.Until(ExpectedConditions.ElementIsVisible(By.Id("elementA")));

Here you can find a detailed discussion on Ways to deal with #document under iframe

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • Hmm this seemed to fix it for me, thanks! Odd behaviour because I'm not trying to interact with the element within the frame as is, just verify that the frame has completed loading by checking for an element. – Brian von Kuster Apr 06 '18 at 19:20
  • Tagged it as accepted and just did, I couldn't before because I wasn't at 15 karma yet – Brian von Kuster Apr 06 '18 at 20:46
  • Ugh now the problem's resurfaced even with ElementIsVisible. Weird that it worked fine for a couple days though. – Brian von Kuster Apr 09 '18 at 15:29
1

This is how you can do it:

var wait = new WebDriverWait(new SystemClock(), driver, TimeSpan.FromSeconds(timeout), TimeSpan.FromSeconds(sleepInterval)); 
wait.Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt("yourFrameName"); 
driver.SwitchTo().Frame("yourFrameName");
Anton Angelov
  • 1,705
  • 13
  • 16
-1

I am not sure which language you're working on. But in C#, you would need to SwitchTo default content first and then switch to the Iframe you're dealing with which is frameA. So here is my suggested code to try:

driver.SwitchTo().DefaultContent();
driver.SwitchTo().Frame(frameA);

Update: Implement a method that waits for element explicitly:

public void WaitForElementExplicitly(int WaitInMilliSeconds = 3000, By Selector = null)
{
  WebDriverWait wait = new WebDriverWait(CommonTestObjects.IWebDriver, TimeSpan.FromSeconds(WaitInMilliSeconds / 1000));
  IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
  {
    return d.FindElement(Selector);
  });
}

And then call the method to wait for your element

WaitForElementExplicitly(Selector: By.Id("elementA"));
Shahboz
  • 466
  • 2
  • 10
  • 30
  • Yeah I'm in C#. Switching frames is functional, it just seems to be switching too "slow" for my test so the driver throws an exception when it tries to wait for an element within the frame. I do have a SwitchTo() in before the Frame switch – Brian von Kuster Apr 05 '18 at 16:50
  • Still suffering from the same problem unfortunately, it seems to be trying to search for the element before the frame switch completes – Brian von Kuster Apr 05 '18 at 17:23
  • How do you know if the frame is actually switched? – Shahboz Apr 05 '18 at 17:33
  • I'm trying to figure out how to precisely figure that out, but the way I've been testing it is to see whether I can access elements outside the frame that I know are in the window. If I can't access them, I know I'm in the frame. That's how I know that the frame transition I'm doing is actually transitioning frames. I don't know how to wait for the driver to finish switching frames before searching though. The error I was hitting above happens as soon as the WebDriverWait.Until starts, it doesn't actually try to find it before timing out after 15s. – Brian von Kuster Apr 05 '18 at 17:46
  • Why do you have your default value for the `Selector` parameter set to `null`? You aren't handling `null` in the method and you don't require a locator which means that you are inviting people to call your code in a way that will cause an NPE. If you remove the `null` as a default value, that will no longer be a problem. – JeffC Jan 21 '20 at 22:47