C# Selenium-发送密钥以在影子根(open)和多个iFrame中输入挪威银行ID的密码
我想使用来自挪威银行ID的测试数据进行自动测试。但我无法使用Selenium获得输入字段 我想做的是:C# Selenium-发送密钥以在影子根(open)和多个iFrame中输入挪威银行ID的密码,c#,selenium,iframe,shadow-dom,webdriverwait,C#,Selenium,Iframe,Shadow Dom,Webdriverwait,我想使用来自挪威银行ID的测试数据进行自动测试。但我无法使用Selenium获得输入字段 我想做的是: 去 点击“洛格酒店” 点击“BankID påmobil” 单击“用于登录的替代程序”下的“银行ID” 输入“02105892090”(来自上面链接的测试用户)并单击“Logg inn” 在“Engangskode”中再次输入“02105892090”,然后单击提交按钮 HTML: 但我得到了错误信息: OpenQA.Selenium.NoSuchElementException : no s
OpenQA.Selenium.NoSuchElementException : no such element: Unable to locate element: {"method":"css selector","selector":"input[type='password']"}
有人知道怎么做吗
编辑:
在大家的帮助下,这是最终起作用的代码:
public void EnterSsn(string ssn)
{
var driver = WebDriverFacade.GetDriver;
driver.SwitchTo().DefaultContent();
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.CssSelector("iframe#ifmSingicat")));
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.CssSelector("#bankid-container iframe")));
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable((IWebElement)((IJavaScriptExecutor)driver).ExecuteScript("return document.querySelector(\".full_width_height\").shadowRoot.querySelector(\"input[type=\'password\']\")"))).SendKeys(ssn);
}
这里有2个iframe(嵌套iframe),因此需要切换两次。
首先切换到id为ifmSingicat的iframe,然后切换到切换的iframe的第一个iframe
//Main document
driver.SwitchTo().DefaultContent();
//Find the first frame, and use switch to frame
IWebElement containerFrame = driver.FindElement(By.Id("ifmSingicat"));
driver.SwitchTo().Frame(containerFrame);
//You are now in iframe "containerFrame", now find the nested iframe
IWebElement contentFrame = driver.FindElement(By.CssSelector("#bankid-container iframe"));
driver.SwitchTo().Frame(contentFrame);
//Now find the elements you want in the nested frame
IWebElement foo = driver.FindElement(By.CssSelector("input[type='password']"));
注意:我不是C#开发者,希望上面的语法是正确的。如果切换到正确的iframe,那么只需要添加一些等待。它将提供一些时间来加载iframe元素。与文本Engangskode关联的字段位于父
中的子
中的\shadow root(open)中。因此,要将字符序列发送到所需字段,您需要:
- 诱导WebDriverWait使父帧可用并切换到它
- 诱导WebDriverWait使子帧可用并切换到它
- 为所需的
,该元素位于元素导入WebDriverWait to Eclickable()
中#shadow root(open)
- 您可以使用以下解决方案:
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.CssSelector("iframe#ifmSingicat"))); new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.CssSelector("iframe[title='BankID']"))); new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable((IWebElement)((IJavaScriptExecutor)driver).ExecuteScript("return document.querySelector('div.full_width_height').shadowRoot.querySelector('input')"))).SendKeys("02105892090");
- 浏览器快照:
你切换到iframe了吗?@NaelAbdeljawad我添加了一些代码来解释我所做的事情@NaelAbdeljawad谢谢你的回复。运行代码时,我被卡在上一页。我得到一个错误:“OpenQA.Selenium.NoSuchElementException:没有这样的元素:无法定位元素:{“方法”:“css选择器”,“选择器”:“#ifmSingicat”}”是的,我可以,但只要我尝试切换到iframe,我就会收到错误消息。我想它还没有加载?您可以在第一次切换时调试并添加断点,或者添加线程睡眠几秒钟来发现问题。我建议在运行脚本时观察浏览器行为。非常感谢@DebanjanB!经过一些修改,它终于成功了。将我的解决方案添加到原始帖子中。
//Main document
driver.SwitchTo().DefaultContent();
//Find the first frame, and use switch to frame
IWebElement containerFrame = driver.FindElement(By.Id("ifmSingicat"));
driver.SwitchTo().Frame(containerFrame);
//You are now in iframe "containerFrame", now find the nested iframe
IWebElement contentFrame = driver.FindElement(By.CssSelector("#bankid-container iframe"));
driver.SwitchTo().Frame(contentFrame);
//Now find the elements you want in the nested frame
IWebElement foo = driver.FindElement(By.CssSelector("input[type='password']"));
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.CssSelector("iframe#ifmSingicat")));
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.CssSelector("iframe[title='BankID']")));
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable((IWebElement)((IJavaScriptExecutor)driver).ExecuteScript("return document.querySelector('div.full_width_height').shadowRoot.querySelector('input')"))).SendKeys("02105892090");