我正在尝试单击 iFrame 内的“单选按钮”。我尝试切换 iFrame 但遇到问题。
我尝试确定我的元素位于哪个 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>
最佳答案
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 将其手伸入兔子洞,直到它遇到您想要的对象。
关于java - 在 iFrame 内定位元素时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55447852/