C#+ Selenium: click on submit - c#

I use C# with Selenium and testing the application running on Chrome at the moment but hoping to expand all browsers. So I try couple code below and they're not working on the click action. I use XPath, but it throws an exception saying there is no element found in the form. I don't put submit on the form. I also use the other normal way, but it does not submit anything:
<div id="textAreaSection">
<div class="textArea">
<label><b>TextArea:</b></label><br>
<textarea id="textAreaText" rows="14" cols="40"></textarea>
</div>
<div class="surveyBtn">
<input id="inputSubmit" onClick="inputText()" type="submit" value="Input Text">
</div>
</div>
I try this, but no clicking or submitting anything after it's executed:
IWebElement tagElement = driver.FindElement(By.Id("inputSubmit"));
tagElement.Submit();
I try XPath, but the exception is thrown saying that it cannot find an element in the form:
driver.FindElement(By.XPath("//input[#id='inputSubmit']")).Submit();
Update: 1
I try to use WebDriverWait suggested by LoflinA but still throws an exception about not clickable at point (387,590). Another element would receive the click:
public void WaitUntilClickable(IWebElement elementLocator, int timeout)
{
try
{
WebDriverWait waitForElement = new WebDriverWait(driver, TimeSpan.FromSeconds(timeout));
waitForElement.Until(ExpectedConditions.ElementToBeClickable(elementLocator));
}
catch (NoSuchElementException)
{
Console.WriteLine("Element with locator: '" + elementLocator + "' was not found in current context page.");
throw;
}
}
And here is the caller block:
IWebElement tag = driver.FindElement(By.XPath("//div[#class='surveyBtn']/input[#id='inputSubmit']"));
WaitUntilClickable(tag, 10);
tag.Click();
Update: 2
Thanks to #chris-crush-code below code works!
public void CallSubmitType(IWebElement tag, IWebDriver driver)
{
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
string script = tag.GetAttribute("onClick");
js.ExecuteScript(script);
}
[Then(#"SpecFlowTesting")]
public void SpecFlowTesting(string expectedStr)
{
IWebElement tag = driver.FindElement(By.Id("inputSubmit"));
CallSubmitType(tag, driver);
IWebElement tagTextArea = webDriver.FindElement(By.Id("textAreaText"));
string txt = tagTextArea.GetAttribute("value");
Assert.AreEqual(expectedStr, txt);
}

a recent update of chrome requires you to scroll to the clickable object. So:
var js = (IJavascriptExecutor)driver;
IWebElement obj = driver.FindElement(By.XPath("//input[#id='inputSubmit']"));
js.ExecuteScript("arguments[0].scrollIntoView(true);", obj);
obj.Click();

As you have mentioned receiving the error detailing that another element would receive the click, I am thinking that your page has not loaded completely prior to the action being attempted. Try the following to wait for the element to be clickable:
// Wait Until Object is Clickable
public static void WaitUntilClickable(IWebElement elementLocator, int timeout)
{
try
{
WebDriverWait waitForElement = new WebDriverWait(DriverUtil.driver, TimeSpan.FromSeconds(10));
waitForElement.Until(ExpectedConditions.ElementToBeClickable(elementLocator));
}
catch (NoSuchElementException)
{
Console.WriteLine("Element with locator: '" + elementLocator + "' was not found in current context page.");
throw;
}
}
Also see: Selenium Web Driver & Java. Element is not clickable at point (36, 72). Other element would receive the click:

As per the HTML you have shared the WebElement clearly have a onClick() attribute so Java click() should work. But we are not sure if the WebElement is within a form or not to guarantee submit() method to work.
To click() on the button with value as Input Text you can try the following line of code :
driver.FindElement(By.XPath("//div[#class='surveyBtn']/input[#id='inputSubmit']")).Click();

Related

Element not interactable with C# app that uses Chrome WebDriver

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

How do I validate that target="_blank" exists after a given link?

I have a link which I can validate correctly which is followed by the code target="_blank". I do not wish to click the link as it takes me outside of the system I am testing and requires a new login. What I want to do is simply validate target="_blank" is shown after the link. I am working in Selenium webdriver and C#
// Try and find the link for eTMAs http://www.open.ac.uk/assessment/documents/New-eTMA-Interface_000.pdf
string eTMAslink = "http://www.open.ac.uk/assessment/documents/New-eTMA-Interface_000.pdf";
Console.WriteLine($"Checking for eTMAs link http://www.open.ac.uk/assessment/documents/New-eTMA-Interface_000.pdf");
IWebElement eTMAsLink = Globals.GetElementByhref(eTMAslink);
Assert.IsNotNull(eTMAsLink);
Console.WriteLine($"Found eTMAsLink link ", eTMAsLink);
// Now validate target="_blank"> how?
IWebElementdefines the GetAttribute method that you can use to check whether the attribute target is present on the link, e.g.:
Assert.IsNotNull(eTMAsLink);
var targetValue = eTMAslink.GetAttribute("target");
Assert.AreEqual("_blank", targetValue);
Here is how you handle exception. You may try to improve your code for asserting about:blank
using OpenQA.Selenium;
using NUnit.Framework;
public void checknewTab(IWebDriver driver)
{
try
{
/* New tab window with IJavaScriptExecutor */
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript("window.open();");
/* Switch driver to last tab [which is blank tab] */
driver.SwitchTo().Window(driver.WindowHandles.Last());
/* Verify new Tab by using Assert If it is was not about:blank -
It will throw AssertionException */
Assert.AreEqual("about:blank", driver.Url);
}
catch(AssertionException ex)
{
/* Print [Console.Writeline] that there is not a new Tab
[about:blank] */
}
catch(Exception ex)
{
// Print to see other Exception
}
}

OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError at WebElement Submit click

I'm trying to automate a scenario for some web pages using C#, Selenium and Chrome Webdriver, where Submit button click on the page will submit the sendkeys values.
however when Submit is clicked, it's throwing an UnpackAndThrowOnError error in Visual Studio Test explorer Window (Nunit).
<button type="submit" class="btn btn-primary mr-4" name="postType" value="Submit">Submit<span class="glyphicon glyphicon-floppy-save"></span></button>
Detailed Error Description:
at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(ResponseerrorResponse)
at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary'2 parameters)
at OpenQA.Selenium.Remote.RemoteWebElement.Execute(String commandToExecute, Dictionary'2 parameters)<br>
at OpenQA.Selenium.Remote.RemoteWebElement.Click()
at Onrsr.Specflow.Sampletest.occurrence() in C:\Users\manish.sharma\source\repos\Onrsr.Specflow\Onrsr.Specflow\Sampletest.cs:line 180
I've tried the below code options, but they all are failing at submitBtnReview.Click()
IWebElement submitBtnReview = driver.FindElement(By.XPath("//button[contains(.,'Submit')]"));
submitBtnReview.Click();
IWebElement submitBtnReview = driver.FindElement(By.CssSelector("input[value='Submit']"));
submitBtnReview.Click();
IWebElement submitBtnReview = driver.FindElement(By.XPath("//button[#class='btn btn-primary mr-4']"));
submitBtnReview.Click();
IWebElement submitBtnReview = driver.FindElement(By.CssSelector("input[type='submit'][value='Submit']"));
submitBtnReview.Click();
I've also tried using submitBtnReview.Submit() with the IwebElement above, however it's crashing the page.
I'm using latest version of Selenium.WebDriver (3.141.0) and Selenium.Chrome.WebDriver (2.43.0), and using chrome version 70.0.3538.102 (Official Build) (64-bit) on windows 10 machine.
Any idea what I might be doing wrong here?
[05/12/2018] - thank you for all valuable feedbacks - I've now also tried the below and they are failing at submitBtnReview.Click() with a new error:
Message: OpenQA.Selenium.WebDriverException : unknown error: Element <button type="submit" class="btn btn-primary mr-4" name="postType" value="Submit">...</button> is not clickable at point (1792, 876). Other element would receive the click: <footer class="border-top bg-white">...</footer>
(Session info: chrome=70.0.3538.110)
(Driver info: chromedriver=2.43.600210 (68dcf5eebde37173d4027fa8635e332711d2874a),platform=Windows NT 10.0.17134 x86_64)
IWebElement submitBtnReview = driver.FindElement(By.CssSelector("button[type='submit'][value='Submit'][name='postType']"));
IWebElement submitBtnReview = driver.FindElement(By.XPath("//button[contains(#class, 'btn') and contains(#class, 'btn-primary') and contains(#class, 'mr-4')]"));
IWebElement submitBtnReview = driver.FindElement(By.XPath("//button[#class='btn btn-primary mr-4']"));
IWebElement submitBtnReview = new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("//button[#class='btn btn-primary mr-4' and #name='postType'][normalize-space()='Submit']")));
IWebElement submitBtnReview = new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(element_is_present(By.CssSelector("button[type='submit'][value='Submit'][name='postType']")))
public static Func<IWebDriver, IWebElement> element_is_present(By by)
{ return driver =>
{ IWebElement element = driver.FindElement(by);
try
{ if (element != null && element.Displayed && element.Enabled)
{ return element;
}
else
{ return null;
}
}catch (StaleElementReferenceException)
{ return null;
}
};
}
Setting some breakpoints, showing submitBtnReview LocationOnScreen coordinates with a new error, and this might be related.
LocationOnScreen = '((OpenQA.Selenium.Remote.RemoteCoordinates)((OpenQA.Selenium.Remote.RemoteWebElement)submitBtnReview ).Coordinates).LocationOnScreen' threw an exception of type 'System.NotImplementedException'
Submit button details from debugging:
Error image:
Hope this additional information help finding the cause - thanks in advance!!
No exact answer so far, just some observations. 3 of given locators look incorrect, although 1 looks ok.
1) By.XPath("//button[contains(.,'Submit')]")); ---> Looks correct --- explained here
Suggestion: if text value is modified by any of given element class values and a button is shown on a screen as 'SUBMIT' (all caps) or submit (all lowercase) you should use it in xpath as well to be "//button[contains(.,'SUBMIT')]" or "//button[contains(.,'submit')]" .
2) By.CssSelector("input[value='Submit']")); ---> By.CssSelector("button[value='Submit']")); --- your tag is <button> not <input>
3) By.XPath("//button[#class='btn btn-primary mr-4']"); ---> By.XPath("//button[contains(#class, 'btn') and contains(#class, 'btn-primary') and contains(#class, 'mr-4')]) --- explained here
4) By.CssSelector("input[type='submit'][value='Submit']")); ---> By.CssSelector("button[type='submit'][value='Submit']")); --- your tag is <button> not <input> explained here
Before clicking, make sure the element is clickable
public static Func<IWebDriver, IWebElement> ElementIsClickable(By locator)
{
return driver =>
{
var element = driver.FindElement(locator);
return (element != null && element.Displayed && element.Enabled) ? element : null;
};
}
Usable in something like:
var wait = new WebDriverWait(driver, TimeSpan.FromMinutes(1));
var clickableElement = wait.Until(ExpectedConditions.ElementIsClickable(By.Id("id"))
original source
[Addition after question as edited]
The error states that you have an element and that selenium is not able to click on it at the point. the problem is described and solved here
In my opinion, the most stable yet the hackiest way is to try out with the javascript click (it just have to click if you have an element on the screen, and based on the examples you do have it):
IJavaScriptExecutor ex = (IJavaScriptExecutor)Driver;
ex.ExecuteScript("arguments[0].click();", elementToClick);
Another case is to make sure your element is located in the visible area of a browser (you can see/click it during debug without any manual scrolling). If it's not visible or not entirely visible - scroll to it before clicking.
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].scrollIntoView()", Webelement);
Double check suggestion: make sure that there is exactly the one element with such locator. The usual case is when you think that you found 'the right' element but selenium founds the first-match and it is not the one you want.
Another suggestion is that your element might change it's position after you found it. So you found it, saved to a variable and then for some reason the page layout changed (e.g. something async load finished). You can carefully pay attention to how your page loads. Does layout change? If yes - you can create a custom wait function that will check that element coordinates does not change for, let's say, 1-2 seconds.
The element looks to be a dynamic element so you need to induce WebDriverWait for the element to be clickable and you can use either of the following solutions:
CssSelector:
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.CssSelector("button.btn.btn-primary.mr-4[name='postType'][value='Submit']"))).Click();
XPath:
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("//button[#class='btn btn-primary mr-4' and #name='postType'][normalize-space()='Submit']"))).Click();
Note: As you are using ChromeDriver v2.43 ensure that you are using Chrome v69-71

Unable to find the Element on the pop up using Selenium Webdriver with C#

namespace ABC.ABCManager.UIAutomation.Authorization
{
[TestClass]
public class VerifyCreateUsersSendInvite : BaseTest
{
[TestMethod]
public void VerifySendAnInviteLink()
{
Actions actions = new Actions(driver);
selectAndClickOnCustomerName();
Thread.Sleep(3000);
try
{
//Click Send an Invite link
var LinksOnOverview = driver.FindElements(By.CssSelector(".popupFrameLink.summary-tool-link"));
LinksOnOverview[2].Click();
//Verification point to see "Send an Invite" link has opened by checking "TextName" textbox is present or not by using CSS selector
if (IsElementPresent(By.CssSelector("#FirstName")))
{
ExtentManager.verifySafely(driver.FindElement(By.CssSelector("#FirstName")).TagName, "input", "VerifySendAnInviteLink", "link has opened ", driver);
Console.WriteLine("'Send an Invite' link has opened ");
}
}
catch (Exception ex)
{
driver.Close();
}
}
}
}
In above code,I am clicking link "Send an Invitation" and after that, I am getting exception "Element not found" on the line :
if (IsElementPresent(By.CssSelector("#FirstName")))
.... I am inspecting element by CssSelector. I tried xpath then also same exception I am getting. I am unable to find any other element(including first name) on that pop up.Please suggest me solution. Thanks in advance!!!
Probably you should change frame on which you looking for elements
ReadOnlyCollection<string> windowHandles = driver.WindowHandles;
driver.SwitchTo().Window(windowHandles[1]);
// ELEMENTS on Second frame (window)
driver.SwitchTo().Window(windowHandles[0]);
// ELEMENTS on First Frame
try
{
List<IWebElement> frames = new List<IWebElement>(driver.FindElements(By.TagName("iframe")));
driver.SwitchTo().Frame(1);
//Verification point to see "Send an Invite" link has opened by checking Text Name textbox is present or not by using CSS selector
if (IsElementPresent(By.CssSelector("#FirstName")))
{
ExtentManager.verifySafely(driver.FindElement(By.CssSelector("#FirstName")).TagName, "input", "VerifySendAnInviteLink", "link has opened ", driver);
Console.WriteLine("'Send an Invite' link has opened ");
}

Must switch the same iframe twice to get inside the iframe IE

My application must be used in IE. I am automating test in which the script will do the following in listed order
select option 'Accounting' in drop-box "Category" to get Accounting-associated options displayed in drop-box "Category"
select option 'Payment" in drop-box "Name" for page 'Accounting Payment Filter' to display
verify that the 'Employee' text-box in this page is visible
HTML source BEFORE option 'Payment' is selected (the page 'Accounting Payment Filter' has not displayed):
<form id="Main">
<span id="Entity">
<div>
<select id="drop_Category">
<option value =""/>
<option value = "Accounting">
<select id="drop_Name"> <-!
<option value =""/>
<option value ="Payment">
HTML source AFTER option 'Payment' is selected (page 'Accounting Payment Filter' displays and there is an iframe)
<form id="Main">
<span id="Entity">
<div class="ig_Control">
<div class ="ig_content">
<iframe title ="javascript:''">
<html>
<body>
<form id="Form1">
<div id="Panel1">
<table id="table1"
<tr>
<td>
<input id="Employee">
<div>
<select id="drop_Category">
<option value =""/>
<option value = "Accounting">
<select id="drop_Name"> <-!
<option value =""/>
<option value ="Payment">
I have the code up to 'Payment' option is selected. Now I call SwitchIframe function, then find and verify the text-box:
public static bool IsTextboxVisible (IWebDriver driver, Dictionary of all needed data )
{
//....
//Call to switch into 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));
var iFrame = wait.Until(d => d.FindElement(By.XPath(strXPath)));
driver.SwitchTo().Frame(iFrame);
}
Script can't find the text-box even when I increase the waiting time. Then I tried finding the ID "drop_Name" instead, and the script can find that drop-box. That means it did not switch into the iframe. So I switch that SAME iframe one more time:
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;
}
Now script can find the text-box though sometimes is still given the exception that the XPath cannot be evaluated or not results in a web element. I update function 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);
}
}
But the same exception still happens sometimes in the 'try...' block. My questions:
Why do I have to switch the same iframe twice to get inside one iframe?
Why didn't 'try...catch...' in SwitchIframe function catch the
exception?
Any help is highly appreciated.
You may need to switch around the order of events a little bit. Based on the code you have I would actually wait on those additional divs that are loaded after the selection to become visible.
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);
}
The reason for the change of order is that those divs are connected to the original html document. Assuming those divs appear when the iFrame is loaded you should be the able to switch to the new iFrame document. If your xPath does not work (IE may or may not play well with it) I would try using the index position of the frame in the switch to. This might be more reliable since the frame does not have an id to find.
driver.SwitchTo().Frame(1);
I removed the wait from the switch statement because in this case if the iFrame is dependent on the divs loading all you should need to do is have the divs there and the frame is loaded a long with it.

Categories

Resources