1

I am trying to click "Radio Button" which is inside iFrame. I tried to switch iFrame but facing issues.

I have tried to identify in which iFrame my Element lies but facing error as No such Frame.

Sharing my Script, which navigate to the page where I am facing issue clicking on any of the Radio Button.

WebDriver driver;
JavascriptExecutor jse;

public static void main(String[] args) 
{

    Sap_Demo demoObj = new Sap_Demo();

    demoObj.invokeBrowser();
    demoObj.initializeSAPFiory();
    demoObj.forecastMD61();

}



public void invokeBrowser()
{
    System.setProperty("webdriver.chrome.driver", "U:\\Research Paper\\Selenium\\Drivers\\Chrome\\chromedriver_win32\\chromedriver.exe");
    driver = new ChromeDriver();

    driver.manage().deleteAllCookies();
    driver.manage().window().maximize();
    driver.manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
    driver.manage().timeouts().pageLoadTimeout(40, TimeUnit.SECONDS);
}

public void initializeSAPFiory()
{

    try 
    {
        Thread.sleep(1200);
        driver.get("https://dijon.cob.csuchico.edu:8042/erp");
        driver.findElement(By.id("USERNAME_FIELD-inner")).sendKeys("H4");
        Thread.sleep(1200);

        driver.findElement(By.id("PASSWORD_FIELD-inner")).sendKeys("Onsjhjsa1087");
        Thread.sleep(1200);

        driver.findElement(By.id("CLIENT_FIELD-inner")).clear();
        Thread.sleep(1200);

        driver.findElement(By.id("CLIENT_FIELD-inner")).sendKeys("485");
        Thread.sleep(1200);

        driver.findElement(By.xpath("//span[@class='sapMBtnContent sapMLabelBold sapUiSraDisplayBeforeLogin']")).click();
    } 
    catch (InterruptedException e) 
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

public void forecastMD61()
{

    try {
        driver.findElement(By.id("erpsim-tcode-btn-img")).click();
        Thread.sleep(1200);

        driver.findElement(By.id("TCode-input-inner")).sendKeys("MD61");
        Thread.sleep(1200);

        driver.findElement(By.id("TCode-launchBtn-content")).click();
        Thread.sleep(1200);


        /*driver.switchTo().frame(driver.findElement(By.xpath("//span[@id='M0:46:::4:2-imgSymb']")));
        driver.findElement(By.xpath("//span[@id='M0:46:::4:2-imgSymb']")).sendKeys("ABC");*/


        //driver.manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
        //Thread.sleep(1600);


        driver.switchTo().frame("ITSFRAME1");
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("ITSFRAME1"));

        //WebElement E1 = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("M0:46:::4:2-imgStd")));
        WebElement E1 = driver.findElement(By.xpath("//span[@id='M0:46:::4:2-imgSymb']"));
        E1.click();

        //driver.findElement(By.id("M0:46:::4:2-imgStd")).click();
        //driver.findElement(By.xpath("//span[@id='M0:46:::4:2-imgStd']")).click();
        //Thread.sleep(1200);
    } 
    catch (InterruptedException e) 
    {
        e.printStackTrace();
    }

}

}

Receiving error as :

Exception in thread "main" org.openqa.selenium.NoSuchFrameException: no such frame

HTML Source:

for iframe:

<iframe id="ITSFRAME1" name="itsframe1_20190401041759.3908120" noresize="1" frameborder="0" framespacing="0" border="0" scrolling="no" onload="null" style="visibility: visible; z-index: 999; top: 0px; left: 0px;" src="javascript:(function(){document.open();document.domain='dijon.cob.csuchico.edu';self.frameElement.oWguHandlerItsMgrFrame.finalize(); })();"></iframe> 

For Radio Buttons:

enter code here <span id="M0:46:::4:2-imgStd" class="lsRBImgStd lsCBImgStdDef lsCBImgStdDefHv"><span id="M0:46:::4:2-imgSymb" class="lsRBImgSymb lsRBImgSel"></span></span> 
SagarBhatt
  • 15
  • 5
  • There are no iframes, radio buttons or id `M0:46:::4:2-imgStd` in the page you linked. Correct it and add the relevant html to the question. – Guy Apr 01 '19 at 04:35
  • @Guy, 1. iframe Code : Radio Button : – SagarBhatt Apr 01 '19 at 04:45
  • 1
    @Guy, You might not find it because it requires credentials to log in and then you can find page consisting of Radio buttons. – SagarBhatt Apr 01 '19 at 04:56
  • Why don't you switch to frame by id or name? are they dynamic? – supputuri Apr 01 '19 at 06:27
  • @supputuri, I tried with id / name but still showing me the same error. See below is the snippet. driver.switchTo().frame("ITSFRAME1"); WebDriverWait wait = new WebDriverWait(driver, 10); wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("ITSFRAME1")); – SagarBhatt Apr 01 '19 at 06:28
  • Share full HTML in text format. In your shared iframe is empty – Sers Apr 01 '19 at 06:46

2 Answers2

0

Try these... driver.SwitchTo().DefaultContent(); IWebElement iframe = driver.FindElement(By.Id("ITSFRAME1")); driver.SwitchTo().Frame(iframe);

josephthomaa
  • 158
  • 1
  • 11
  • Compilation error received as : The method frame(int) in the type WebDriver.TargetLocator is not applicable for the arguments (IWebElement) Would you please help to figure this out. – SagarBhatt Apr 01 '19 at 15:47
0

Here is my answer from a previous question on this. (Copy/Paste) It works 100% of the time (assuming you have JQuery available on the page; if not we can make an alternative):

So this is ultimately the perfect use case for an extension I made. Here is the most important part of it:

        /// <summary>
        /// Selenium sometimes has trouble finding elements on the page. Give it some help by using JQuery to grab the full qualified xpath to that element.
        /// </summary>
        /// <param name="cssSelector"></param>
        /// <returns></returns>
        public static string GetFullyQualifiedXPathToElement(string cssSelector, bool isFullJQuery = false, bool noWarn = false)
        {

            if (cssSelector.Contains("$(") && !isFullJQuery) {

                isFullJQuery = true;

            }
            string finder_method = @"
                        function getPathTo(element) {
                            if(typeof element == 'undefined') return '';
                            if (element.tagName == 'HTML')
                                return '/HTML[1]';
                            if (element===document.body)
                                return '/HTML[1]/BODY[1]';

                            var ix= 0;
                            var siblings = element.parentNode.childNodes;
                            for (var i= 0; i< siblings.length; i++) {
                                var sibling= siblings[i];
                                if (sibling===element)
                                    return getPathTo(element.parentNode)+'/'+element.tagName+'['+(ix+1)+']';
                                if (sibling.nodeType===1 && sibling.tagName===element.tagName)
                                    ix++;
                            }
                        }
            ";
            if(isFullJQuery) {

                cssSelector = cssSelector.TrimEnd(';');

            }
            string executable = isFullJQuery ? string.Format("{0} return getPathTo({1}[0]);", finder_method, cssSelector) : string.Format("{0} return getPathTo($('{1}')[0]);", finder_method, cssSelector.Replace("'", "\""));
            string xpath = string.Empty;
            try {

                xpath = BaseTest.Driver.ExecuteJavaScript<string>(executable);

            } catch (Exception e) {

                if (!noWarn)  {

                    Check.Warn(string.Format("Exception occurred while building a dynamic Xpath. Css selector supplied to locate element is \"{0}\". Exception [{1}].", cssSelector, e.Message));

                }

            }
            if (!noWarn && string.IsNullOrEmpty(xpath)) {

                Check.Warn(string.Format("Supplied cssSelector did not point to an element. Selector is \"{0}\".", cssSelector));

            }
            return xpath;

        }

With this logic, you can pass a Jquery selector into your browser via javascript executor. JQuery has no problems finding elements nested within iframes. Try something like this:

driver.FindElement(By.XPath(GetFullyQualifiedXPathToElement("#MyDeeplyNestedElement")).Click();

https://gist.github.com/tsibiski/04410e9646ee9ced9f3794266d6c5a82

Feel free to remove whatever is in that method/class that does not apply to your situation.

Why/How does this suddenly make an element findable to Selenium????

You may have noticed that if you tell selenium to find an iframe html element, and then explicitly search within the WebElement of the iframe, that you can find child elements under it. However, without first finding each child iframe, Selenium does not seem to look inside the iframes without you explicitly helping it through the DOM.

JQuery does not have this limitation. It sees every registered DOM element just fine, and will grab it normally. Once you have the element as a JQuery object, you can build out a path of tags, parent by parent, all the way up the DOM. When the logic is complete, you will have a fully-qualified XPath from the top of the DOM down to the nested child element. Then, once this explicit XPath is supplied to Selenium, you are holding its hand down the rabbit hole through one or more iframes until it runs into the object you want.

Asyranok
  • 950
  • 1
  • 7
  • 17