I'm trying to input text into a username field. It appears to find an element, however SendKeys() errors stating that the element is not interactable. I'm already waiting until the element exists, so I wouldn't think its related to waiting. Here is my code:
Console.WriteLine("Hello, World!");
ChromeDriver cd = new
ChromeDriver(#"C:\Users\xxx\Downloads\chromedriver_win32\");
cd.Url = #"https://connect.ramtrucks.com/us/en/login";
cd.Navigate();
WebDriverWait wait = new WebDriverWait(cd,TimeSpan.FromSeconds(10));
IWebElement e = wait.Until(ExpectedConditions.ElementExists(By.ClassName("analytics-login-username")));
e.SendKeys("xxx#gmail.com");
Any suggestions would be much appreciated :)
There are 2 thing you need to fix here:
You are using locator that is not unique.
You need to wait for element clickability, not just existence. I couldn't find element clickability case in C#, so element visibility can be used instead.
So, instead of
IWebElement e = wait.Until(ExpectedConditions.ElementExists(By.ClassName("analytics-login-username")));
e.SendKeys("xxx#gmail.com");
Try this:
IWebElement e = wait.Until(ExpectedConditions.ElementIsVisible(By.CssSelector("input.analytics-login-username"))).SendKeys("xxx#gmail.com");
Related
PREFACE: After a lengthy Stack Overflow search I found two suggested solutions to solve the "element not interactable" problem I am having when I try to interact with the target node element. Neither of them worked, as described below.
I have a C# app that uses the OpenQA.Selenium package to remote control a YouTube web page. I am trying to click on a button on the page that opens a dialog box, but when I do I get the notorious "element not interactable" message. I found the following two suggestions on Stack Overflow:
Actions actions = new Actions(chromeDriver);
actions.MoveToElement(webElem);
actions.Perform();
And this suggestion that one commenter said is ill-advised because it can click on elements that are not visible or are below modal objects:
IJavaScriptExecutor executor = (IJavaScriptExecutor)chromeDriver;
executor.ExecuteScript("arguments[0].click();", webElem);
I tried the second one anyways to see if it worked. Unfortunately, with the first suggestion that uses the Actions interface, I still got "element not interactable" message but this time on the Perform() statement. The third attempt did not get the error message but it failed to click the button. I know this because clicking the button opens a dialog window when it works, and no dialog window appeared when I tried the third solution.
Below is the code I am using to try and click on the element. The collection it iterates are the elements I select via an XPath statement that finds the button I am want to click. It tries every button that matches the XPath statement and skips those that fail to work. Unfortunately, none of the 3 buttons found by the XPath statement work.
What is strange is that if I take the exact same XPath statement I am using in my C# app and plug it into the Chrome DevTools debugger, referencing the first element in the array of found elements, it works:
$x(strXPath)[0].click()
But so far nothing I have tried from C# app works. Does anyone have an idea on why I am having this problem?
public IWebElement ClickFirstInteractable(ChromeDriver chromeDriver)
{
string errPrefix = "(ClickFirstInteractable) ";
if (this.DOM_WebElemensFound == null || this.DOM_WebElemensFound.Count() < 1)
throw new NullReferenceException(errPrefix + "The DOM_WebElementsFound collection is empty.");
IWebElement webElemClicked = null;
foreach (IWebElement webElem in this.DOM_WebElemensFound)
{
// Try and "click" it.
try
{
// First make sure the element is visible, or we will get
// the "element not interactable" error.
/* FIRST ATTEMPT, didn't work.
*
webElem.scrollIntoView(true);
webElem.Click(); // <<<<<----- Error occurs here
*/
/* SECOND ATTEMPT using Actions, didn't work
* and I go the error message when the Perform() statement executes.
Actions actions = new Actions(chromeDriver);
actions.MoveToElement(webElem);
actions.Perform(); // <<<<<----- Error occurs here
*/
/* THIRD ATTEMPT using script execution, didn't work.
* I did not get the error message, but the button did not get clicked.
*/
IJavaScriptExecutor executor = (IJavaScriptExecutor)chromeDriver;
executor.ExecuteScript("arguments[0].scrollIntoView();", webElem);
executor.ExecuteScript("arguments[0].click();", webElem);
// Click operation accepted. Stop iteration.
webElemClicked = webElem;
break;
}
catch (ElementNotInteractableException exc)
{
// Swallow this exception and go on to the next element found by the XPath expression.
System.Console.WriteLine(exc.Message);
}
}
return webElemClicked;
}
I tried to reproduce your scenario by clicking on a "hidden" button, waiting for the modal to appear, then acting on that modal, etc.
I hope it helps you!
const string Target = #"https://www.youtube.com/";
using var driver = new ChromeDriver();
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20))
{
PollingInterval = TimeSpan.FromMilliseconds(250),
};
driver.Navigate().GoToUrl(Target);
// i don't consent cookies to
// save time, so just do it
// here manually and then press enter to console
Console.ReadLine();
var menuLocator = By.XPath("//a[#id = 'video-title-link'][1]" +
"/ancestor::div[#id = 'meta']" +
"/following-sibling::div[#id = 'menu']" +
"//button[#class = 'style-scope yt-icon-button']");
var menu = wait.Until(d => d.FindElement(menuLocator));
var actions = new Actions(driver);
actions.MoveToElement(menu).Click().Perform();
var shareLocator = By.XPath("//div[#id = 'contentWrapper']//*[normalize-space(text()) = 'Share']");
var share = wait.Until(d => d.FindElement(shareLocator));
actions.MoveToElement(share).Click().Perform();
var copyLinkLocator = By.XPath("//button[#aria-label = 'Copy']");
var copyLink = wait.Until(d => d.FindElement(copyLinkLocator));
actions.MoveToElement(copyLink).Click().Perform();
Is there a way to perform a wait.Until by somehow searching the element from another element, rather than from the whole driver?
example:
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSec));
IWebElement element = wait.Until(ExpectedConditions.ElementExists(by));
I cannot modify the 'by' to be too specific and when it is searched under the driver and gets the wrong element.
IWebElement element = wait.Until(drv => drv.FindElement(by));
this option also searches under the driver.
I want something like this:
public static IWebElement WaitElement(this IWebElement webElement, IWebDriver driver, By by, int timeoutInSec = 5)
{
try
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSec));
IWebElement element = wait.Until(webElement.FindElement(by));
}
When I try to write this code I get this error:
enter image description here
It may be late, but hopefully will help someone else. Just change the syntax of your last line in the 3rd option to the following:
IWebElement element = wait.Until(d => webElement.FindElement(by));
Following a tutorial to test search functionality on wikipedia using c#. My test keeps failing because the the text from the h1 element im trying to return keeps returning empty. There is definitely text inside the h1 header. Any idea why This element is returning empty when it has text?
IWebDriver driver = new FirefoxDriver();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5));
driver.Navigate().GoToUrl("https://en.wikipedia.org/wiki/Main_Page");
IWebElement searchInput = driver.FindElement(By.Id("searchInput"));
searchInput.SendKeys("Christiaan Barnard");
searchInput.SendKeys(Keys.Enter);
IWebElement firstHeading = driver.FindElement(By.Id("firstHeading"));
Assert.AreEqual("Christiaan Barnard", firstHeading.Text);
driver.Quit();
It may be because the element is found, but does not yet have the expected value. The best approach is to wait until the text has the expected value, using WebDriverWait:
var wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(5));
var result = wait.Until(ExpectedConditions.TextToBePresentInElementLocated(By.Id("firstHeading"), "Christiaan Barnard"));
Assert.IsTrue(result);
I'm trying to create an automated ui test with selenium in c#. Here is my code:
driver = new ChromeDriver();
driver.Manage().Window.Maximize();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(30));
driver.Navigate().GoToUrl("my_url");
driver.FindElementById("textBox").Clear();
driver.FindElementById("textBox").SendKeys("tire");
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(30));
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
wait.Until((ExpectedConditions.ElementIsVisible(By.Id("Moto"))));
driver.FindElementById("Moto").Click();
Before using a wait.until, I was getting the exception ElementNotVisibleException, but now I'm getting the exception WebDriverTimeoutException because the element with the id "Moto" is not visible.
Here is a screenshot of a part of the DOM:
So why the moto checkbox is not found or is not visible?
Try the below code (in Java) as it is working at my end for the same structure -
driver.findElement(By.xpath("//label[#for='Moto']")).click();
I don't know why it is causing problem to find <input> tag by id
You might need to scroll to the element to make it visible
IWebElement moto = driver.FindElement(By.Id("Moto"));
Actions actions = new Actions(driver);
actions.MoveToElement(moto).Perform();
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
wait.Until(ExpectedConditions.ElementIsVisible(By.Id("Moto"))).Click();
All is working well when I was using Selenium alone, but when i tried with phantomjs i get null in finding elements.
static void Main()
{
IWebDriver driver = new PhantomJSDriver();
driver.Navigate().GoToUrl("https://sellercentral.amazon.de/gp/homepage.html");
var username = driver.FindElement(By.Id("username"));
var password = driver.FindElement(By.Id("password"));
username.SendKeys("*************************");
password.SendKeys("*************");
driver.FindElement(By.Id("sign-in-button")).Submit();
string messagesURL = "https://sellercentral.amazon.de/gp/communication-manager/inbox.html/ref=ag_cmin__cmin?ie=UTF8&clcmResponseTimeSuboptions=&dateExactEnd=&dateExactStart=&dateFilter=&itemsPerPage=20&marketplaceId=A1PA6795UKMFR9&otherPartyId=&pageNum=1&refIndex=40&searchBoxText=&showFilters=0&sortBy=ArrivalDate&sortOrder=Descending";
driver.Navigate().GoToUrl(messagesURL);
ParseMessages(driver);
}
public static void ParseMessages(IWebDriver driver) {
var node = driver.FindElements(By.ClassName("list-row-white"));
foreach (var n in node) {
var refNo = n.FindElement(By.ClassName("data-display-field-border-lbr"));
Console.WriteLine(mi.refNo);
}
}
In this line of code, i get null: var node = driver.FindElements(By.ClassName("list-row-white"));
But when i used selenium alone with actual browser, all is working. But i wanted to get things to be headless.
I am new to phantomJS, correct me if i implemented it correctly and if my code is right.
In some cases, PhantomJS has issues working with css related stuff or element classes.
In such case, converting locator to XPath may solve the problem.
// Thread.Sleep(3000) // Please, replace me with WebDriverWait ^_^
var node = driver.FindElements(By.XPath("//*[contains(#class,'list-row-white')]"));
Another point, PhantomJS works much faster than any other browser.
Try to insert Thread.Sleep before the failed code line.
If the code will pass -- please, replace it with proper WebDriverWait expression