0

I'v AJAX based application and have some frames on it and want to switch to it hence I've used frameToBeAvailableAndSwitchToIt() method.

Suppose now I'm on default context of a page(i.e not in any of the frames) and want to switch to testFrame using following code -

   WebDriverWait wait = new WebDriverWait(driver, 30);
   wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(testFrame));

   JavascriptExecutor jsExecutor = (JavascriptExecutor)driver;
   String currentFrameName = (String) jsExecutor.executeScript("return self.name");
   System.out.println("***************** Current frame using self.name " + currentFrameName);

This returns empty string as a value of currentFrameName which indicates that we haven't switched to testFrame, even though explicit wait call has succeeded.

This issue reproduces intermittently which causes tests to be flaky. Could you please suggest how to make this stable?

EDIT

I edited my question where earlier I had mentioned - I'm in frameA and then want to switch to frameB but that is not a case. I want to switch from default content of a page to a frame. Sorry for putting wrong information at first place.

Alpha
  • 13,320
  • 27
  • 96
  • 163
  • Can you please try with --> String frame = (String) jsExecutor.executeScript("return self.location.toString()"); – Muzzamil Jan 13 '20 at 13:02
  • @Muzzamil, it returns me an url. – Alpha Jan 13 '20 at 13:05
  • I think you have switched already. try this after switch --> WebElement testFrame= driver.findElement(By.tagName("iframe"));WebElement el = (WebElement) ((JavascriptExecutor) driver).executeScript("return window.frameElement"); assert testFrame.equals(el) – Muzzamil Jan 13 '20 at 13:09

2 Answers2

3

You need to switch back from previous frame in order to move to another frame.using

driver.switchTo().defaultContent();

Now it should look like.

WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(frameA));
//Do somenthing.
driver.switchTo().defaultContent();
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(frameB));

Hope this helps.

KunduK
  • 32,888
  • 5
  • 17
  • 41
0

If you are within frameA and want to switch to frameB will depend on the alignment of frameA and frameB.

  • If frameB is a child frame of frameA, then while being in frameA you have to switchTo() the child frame frameB once again as follows:

    new WebDriverWait(driver, 30).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(frameA));
    new WebDriverWait(driver, 30).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(frameB));
    

You can find a relevant discussion in Unable to locate the child iframe element which is within the parent iframe through Selenium in Java

  • If frameA and frameB both are direct child of the Top Level Browsing Context, then while being in frameA you have to switch_to() the defaultContent() (which selects either the first frame on the page, or the main document when a page contains iframes.) first then to the frame frameB as follows:

    new WebDriverWait(driver, 30).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(frameA));
    driver.switchTo().defaultContent(); #incase frameA and frameB are immediate child of the Top Level Content
    new WebDriverWait(driver, 30).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(frameB));
    

You can find a relevant discussion in Multiple iframe tags Selenium webdriver


tl; dr

You can find a relevant detailed discussion in:

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • Sorry for putting wrong details. I corrected my question now. – Alpha Jan 13 '20 at 12:20
  • Unfortunately your solution did not help. There is no issue with my code, it works as expected which indicates code is correct, only thing is it causes tests to fail intermittent. Hence my question is how to make it stable so it passes every time. – Alpha Jan 13 '20 at 12:31