Kaustubh
Kaustubh

Reputation: 506

How to deal with parent and child iframes

I have a scenario where I 1st iframe (i.e parent iframe) which has one button on it and clicking on it another iframe gets open (child iframe). I am able to switch to Parent iframe but when I click on button and tries to interact with Child iframe I'm not able to do it. Can you suggest what should be the better approach to get this type of scenarios working?

My Script:

public class Iframe {
    public static void main (String []args) throws InterruptedException {
        System.setProperty("webdriver.chrome.driver", Constants.Chrome_Driver);
        WebDriver driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        driver.get("http://automation.cloudaccess.host/administrator"); 
        driver.findElement(By.id("mod-login-username")).sendKeys("admin");
        driver.findElement(By.id("mod-login-password")).sendKeys("admin@123");
        driver.findElement(By.id("mod-login-password")).submit();
        driver.findElement(By.linkText("Components")).click();
        Actions action = new Actions(driver);
        action.moveToElement(driver.findElement(By.linkText("Messaging"))).build().perform();
        driver.findElement(By.linkText("New Private Message")).click();
        driver.findElement(By.className("wf-editor-header")).click();
        new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//button[@id=\"jform_message_imgmanager\"]"))).click();
        new WebDriverWait(driver, 20).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//iframe[contains(@src,'&plugin=imgmanager')]")));
        new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id=\"browser-actions\"]/a[@id=\"help\"]"))).click();
        driver.switchTo().defaultContent();            
        new WebDriverWait(driver, 20).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//iframe[@id=\"mce_inlinepopups_50_ifr\"]")));
        new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id=\"imgmanager.insert\"]/i[@class=\"icon-file\"]"))).click();
        driver.quit();
    }
}

Error:

   Exception in thread "main" org.openqa.selenium.TimeoutException: Expected condition failed: waiting for frame to be available: By.xpath: //iframe[@id="mce_inlinepopups_50_ifr"] (tried for 20 second(s) with 500 milliseconds interval)
    at org.openqa.selenium.support.ui.WebDriverWait.timeoutException(WebDriverWait.java:81)
    at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:271)
    at testScripts.Iframe.main(Iframe.java:51)
Caused by: org.openqa.selenium.NoSuchElementException: Cannot locate an element using By.xpath: //iframe[@id="mce_inlinepopups_50_ifr"]
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '3.12.0', revision: '7c6e0b3', time: '2018-05-08T15:15:08.936Z'
System info: host: 'vowellt4', ip: '127.0.1.1', os.name: 'Linux', os.arch: 'amd64', os.version: '4.15.0-24-generic', java.version: '1.8.0_171'
Driver info: driver.version: unknown
    at org.openqa.selenium.support.ui.ExpectedConditions.lambda$findElement$0(ExpectedConditions.java:896)
    at java.util.Optional.orElseThrow(Optional.java:290)
    at org.openqa.selenium.support.ui.ExpectedConditions.findElement(ExpectedConditions.java:895)
    at org.openqa.selenium.support.ui.ExpectedConditions.access$000(ExpectedConditions.java:44)
    at org.openqa.selenium.support.ui.ExpectedConditions$17.apply(ExpectedConditions.java:517)
    at org.openqa.selenium.support.ui.ExpectedConditions$17.apply(ExpectedConditions.java:513)
    at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:248)
    ... 1 more

Upvotes: 1

Views: 1553

Answers (2)

cruisepandey
cruisepandey

Reputation: 29362

Just after click on help button , you can try with this code :

 driver.switchTo().defaultContent();
 new WebDriverWait(driver, 20).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.cssSelector("iframe[src^='/administrator/index.php?option=com_jce&view=help&tmpl=component&lang=en&section=editor&category=imgmanager&']")));  

You are using //iframe[@id=\"mce_inlinepopups_50_ifr\"] this xpath to switch to frame but the problem is the id is getting generated dynamically , so we do not know what will be the id every time we visit the page through automation.

I have simply converted that xpath to a valid and reliable css selector and it is working extremely good at my end.

In case you want to have xpath :

//iframe[contains(@src,'/administrator/index.php?option=com_jce&view=help&tmpl=component&lang=en&section=editor&category=imgmanager&')]

Hope this will help.

Upvotes: 2

Subburaj
Subburaj

Reputation: 2334

After clicking on the help button, you need to switch to the default content from the parent iframe and then need to navigate to the respective child frame.

Child Frame Xpath needs to be changed as below

Xpath: //*[@class='mceModalContainer']//div[@id='mce_inlinepopups_45_content']//iframe

Modified Working Code:

new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id=\"browser-actions\"]/a[@id=\"help\"]"))).click();

driver.switchTo().defaultContent();

new WebDriverWait(driver, 20).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//*[@class='mceModalContainer']//div[@id='mce_inlinepopups_45_content']//iframe")));

new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id='help-menu']//*[@id=\"imgmanager.insert\"]/i[@class=\"icon-file\"]"))).click();

Upvotes: 0

Related Questions