C# 必须切换同一iframe两次才能进入iframe IE

C# 必须切换同一iframe两次才能进入iframe IE,c#,iframe,selenium,webdriver,C#,Iframe,Selenium,Webdriver,我的应用程序必须在IE中使用。我正在自动化测试,脚本将按列出的顺序执行以下操作 在下拉框“类别”中选择选项“会计”,以获取下拉框“类别”中显示的会计相关选项 在“会计付款过滤器”页面的“名称”下拉框中选择“付款”选项以显示 验证此页面中的“员工”文本框是否可见 选择“付款”选项之前的HTML源(未显示“会计付款筛选器”页面): 即使我增加等待时间,脚本也找不到文本框。然后我尝试查找ID“drop_Name”,脚本可以找到该drop box。这意味着它没有切换到iframe。因此,我再次切换相

我的应用程序必须在IE中使用。我正在自动化测试,脚本将按列出的顺序执行以下操作

  • 在下拉框“类别”中选择选项“会计”,以获取下拉框“类别”中显示的会计相关选项

  • 在“会计付款过滤器”页面的“名称”下拉框中选择“付款”选项以显示

  • 验证此页面中的“员工”文本框是否可见

选择“付款”选项之前的HTML源(未显示“会计付款筛选器”页面):

即使我增加等待时间,脚本也找不到文本框。然后我尝试查找ID“drop_Name”,脚本可以找到该drop box。这意味着它没有切换到iframe。因此,我再次切换相同的iframe:

public static bool IsTextboxVisible (IWebDriver driver, Dictionary of all needed data )
{
     //....
     //Call to switch into iframe
     SwitchIFrame(driver,stringXPath);
     //Call again to switch into the same iframe 
     SwitchIFrame(driver,stringXPath);

     //Verify text-box is visible
     var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(1)); 
     //Script crashes here- can't find element
     var Textbox = wait.Until(d => d.FindElement(By.Id(TexboxID))); 
     return Textbox.Displayed;
}
现在,脚本可以找到文本框,但有时仍然会出现无法计算XPath或未生成web元素的异常。I更新函数SwitchIFrame:

public static void SwitchIFrame (IWebDriver driver,string strXPath)
{
    var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); 
    try
    {
      var iFrame = wait.Until(d => d.FindElement(By.XPath(strXPath)));
      driver.SwitchTo().Frame(iFrame);
    }
    catch (NoSuchFrameException)
    {
       var iFrame = wait.Until(d => d.FindElement(By.XPath(strXPath)));
       driver.SwitchTo().Frame(iFrame);
    }
}
但在“try…”块中有时也会出现相同的异常。我的问题是:

  • 为什么我必须切换同一个iframe两次才能进入一个iframe
  • 为什么SwitchIframe函数中的“try…catch…”没有捕获 例外

非常感谢您的帮助。

您可能需要稍微改变一下事件顺序。根据您的代码,我实际上会等待在选择后加载的附加div变为可见

public static bool IsTextboxVisible (IWebDriver driver, Dictionary of all needed data )
{    
 //Verify text-box is visible
  var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); 

  var Textbox = wait.Until(d => d.FindElement(By.ClassName("ig_content")));

  SwitchIFrame(driver,stringXPath);
  return Textbox.Displayed;
}

public static void SwitchIFrame (IWebDriver driver,string strXPath)
{
    //var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); 
    var iFrame = driver.FindElement(By.XPath(strXPath));
    driver.SwitchTo().Frame(iFrame);
}
更改顺序的原因是这些div连接到原始html文档。假设这些div在加载iFrame时出现,您应该能够切换到新的iFrame文档。如果您的xPath不工作(即可能会或可能不会很好地使用它)我会尝试在切换到中使用帧的索引位置。这可能更可靠,因为帧没有要查找的id

驱动程序切换到()帧(1)

我从switch语句中删除了wait,因为在这种情况下,如果iFrame依赖于div加载,那么您需要做的就是将div放在那里,然后用它加载一个长的帧

public static bool IsTextboxVisible (IWebDriver driver, Dictionary of all needed data )
{
     //....
     //Call to switch into iframe
     SwitchIFrame(driver,stringXPath);
     //Call again to switch into the same iframe 
     SwitchIFrame(driver,stringXPath);

     //Verify text-box is visible
     var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(1)); 
     //Script crashes here- can't find element
     var Textbox = wait.Until(d => d.FindElement(By.Id(TexboxID))); 
     return Textbox.Displayed;
}
public static void SwitchIFrame (IWebDriver driver,string strXPath)
{
    var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); 
    try
    {
      var iFrame = wait.Until(d => d.FindElement(By.XPath(strXPath)));
      driver.SwitchTo().Frame(iFrame);
    }
    catch (NoSuchFrameException)
    {
       var iFrame = wait.Until(d => d.FindElement(By.XPath(strXPath)));
       driver.SwitchTo().Frame(iFrame);
    }
}
public static bool IsTextboxVisible (IWebDriver driver, Dictionary of all needed data )
{    
 //Verify text-box is visible
  var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); 

  var Textbox = wait.Until(d => d.FindElement(By.ClassName("ig_content")));

  SwitchIFrame(driver,stringXPath);
  return Textbox.Displayed;
}

public static void SwitchIFrame (IWebDriver driver,string strXPath)
{
    //var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); 
    var iFrame = driver.FindElement(By.XPath(strXPath));
    driver.SwitchTo().Frame(iFrame);
}