【问题标题】:Facing issue in locating element inside iFrame在 iFrame 中定位元素时面临问题
【发布时间】:2019-04-01 03:43:40
【问题描述】:

我正在尝试单击 iFrame 内的“单选按钮”。我试图切换 iFrame 但遇到问题。

我试图确定我的 Element 位于哪个 iFrame 中,但遇到了 No such Frame 错误。

共享我的脚本,该脚本导航到我在单击任何单选按钮时遇到问题的页面。

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();
    }

}

}

接收错误为:

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

HTML 源代码:

对于 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> 

对于单选按钮:

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> 

【问题讨论】:

  • 您链接的页面中没有 iframe、单选按钮或 ID M0:46:::4:2-imgStd。更正它并将相关的html添加到问题中。
  • @Guy,1. iframe 代码: 单选按钮:
  • @Guy,您可能找不到它,因为它需要凭据才能登录,然后您可以找到包含单选按钮的页面。
  • 为什么不按id或name切换到frame呢?它们是动态的吗?
  • @supputuri,我尝试使用 id / name 但仍然显示相同的错误。见下图是sn-p。 driver.switchTo().frame("ITFSFRAME1"); WebDriverWait 等待 = 新 WebDriverWait(驱动程序, 10); wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("ITFSFRAME1"));

标签: java selenium selenium-webdriver iframe


【解决方案1】:

Here is my answer from a previous question on this。 (复制/粘贴)它 100% 的时间都有效(假设您的页面上有可用的 JQuery;如果没有,我们可以替代):

所以这最终是我制作的扩展的完美用例。这是其中最重要的部分:

        /// <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;

        }

使用此逻辑,您可以通过 javascript 执行器将 Jquery 选择器传递到您的浏览器。 JQuery 在查找嵌套在 iframe 中的元素时没有问题。试试这样的:

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

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

请随意删除该方法/类中不适用于您的情况的任何内容。

为什么/如何突然让 Selenium 可以找到一个元素???

您可能已经注意到,如果您告诉 selenium 查找一个 iframe html 元素,然后在 iframe 的 WebElement 中显式搜索,您可以在它下面找到子元素。但是,如果没有首先找到每个子 iframe,Selenium 似乎不会在没有您通过 DOM 显式帮助的情况下查看 iframe 内部。

JQuery 没有这个限制。它可以很好地看到每个注册的 DOM 元素,并且会正常抓取它。将元素作为 JQuery 对象后,您可以构建标签路径,逐个父级,一直到 DOM。逻辑完成后,您将拥有从 DOM 顶部到嵌套子元素的完全限定 XPath。然后,一旦将此显式 XPath 提供给 Selenium,您就可以通过一个或多个 iframe 将它的手放在兔子洞中,直到它遇到您想要的对象。

【讨论】:

    【解决方案2】:

    试试这些... driver.SwitchTo().DefaultContent(); IWebElement iframe = driver.FindElement(By.Id("ITSFRAME1")); driver.SwitchTo().Frame(iframe);

    【讨论】:

    • 收到的编译错误为:WebDriver.TargetLocator 类型中的方法 frame(int) 不适用于参数 (IWebElement) 请您帮忙解决一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-12
    • 1970-01-01
    • 1970-01-01
    • 2015-09-13
    相关资源
    最近更新 更多