Element Click Intercepted Exception - c#

I am unable to perform click operation on Sign-in button in my application.
Below is the HTML code.and u can find the exact button element in last line.
<div class="form-group dl-padding-10">
<select class="form-control form-control-solid" name="SelectedRoleID" id="SelectedRoleID" onchange="removeBorderColor()" required="">
<option id="default_val" selected="" disabled="" hidden="">Profile </option>
<option value="15">Service Consultant</option>
<option value="11">DLBO Developer</option>
<option value="16">Admin Agent</option>
<option value="17">Team Leader</option>
<option value="18">Manager</option>
<option value="19">CV Mandator</option>
<option value="20">CV Agent</option>
<option value="21">Forensics Agent</option>
</select>
<div class="dl-align-left" id="show_text" style="color:red">
</div>
</div>
<div class="circle1-mask form-group" id="FingerprintContent" style="height:140px;z-index:2; background-image: none;">
<img src="Assets/img/fingerprint4.gif" id="fingerprint-img" data-status="active" style="height:140px; width:100px;" onclick="DeviceScript.scanFingerPrint(event)">
</div>
<div class="form-group dl-padding-10">
<button type="submit" id="register-btn" class="btn btn-block dl-button-primary dl-no-margin">Sign In (For Testing Purpose Only)</button>
</div>
</div>
</div>
</form> </div>
</div>
Kindly help me with the suitable xpath to perform click operation on the sign-in button.
Also find the image of code tried.Code
Xpath=”//button[contains(text(), 'Sign In (For Testing Purpose Only)')]”
(Or)
IWebElement Signin = driver.FindElement(By.Id("register-btn"));
Signin.Click();
(Or)
IWebElement Signinbutton = driver.FindElement(By.XPath("//button[contains(text(), 'Sign In (For Testing Purpose Only)')]"));
Actions action = new Actions(driver);
action.MoveToElement(Signinbutton).Click().Perform();
The error which i get:
OpenQA.Selenium.ElementClickInterceptedException : element click intercepted: Element <button type="submit" id="register-btn" class="btn btn-block dl-button-primary dl-no-margin">...</button> is not clickable at point (758, 646). Other element would receive the click: <div class="footer navbar-fixed-bottom">...</div>

Try with javascript:
IWebElement Signinbutton = driver.FindElement(By.XPath("//button[contains(text(), 'Sign In (For Testing Purpose Only)')]"));
IJavaScriptExecutor javascriptExecutor = (IJavaScriptExecutor)driver;
executor.ExecuteScript("arguments[0].click();", Signinbutton );

Looks like you are missing some html since the error references a footer.
Not a fan of thread sleeps but try one and see if the thread sleep allows the page to load. I am wondering if your page is still loading and trying to click. If the sleep works, I would remove that and do a move to element or try a java click.
Thread.Sleep(1000);
driver.FindElement(By.XPath("//button[contains(text(), 'Sign In')]")).Click();
driver.FindElement(By.Id("register-btn")).Click();

The exception you are getting is because the button you are trying to click is behind this element
<div class="footer navbar-fixed-bottom">...</div>
Which seems to be the footer of your page.
You can try any of the following steps to solve the issue
Scroll to any element below the sign-in button(If any). You can use the below code for that:
protected boolean scrollToElement(WebElement element)
throws NoSuchElementException, StaleElementReferenceException {
try {
jsExecutor.executeScript("arguments[0].scrollIntoView(true);", element);
return true;
} catch (NoSuchElementException e) {
logError("Element Not found exception when scrolling to element (JavaScript)", e);
throw e;
} catch (StaleElementReferenceException e) {
logError("Stale element exeption when scrolling to element (JavaScript)", e);
throw e;
}
}
Close the footer if it is for accept cookies or something similar, or you can also apply Custom CSS to that element to hide it and then try to click the element.
String css= "display:none !important;"
protected void addCustomCSS(WebElement webElement, String css) {
registerCall(new Object() {
}.getClass().getEnclosingMethod().getName());
try {
String style = (String) jsExecutor.executeScript("arguments[0].getAttribute('style')", webElement);
jsExecutor.executeScript("arguments[0].setAttribute('style', " + css + ")", webElement);
stylesQueue.add(style);
} catch (Exception e) {
e.printStackTrace();
}
}

Related

Blazor Dropdown with Search field - Handle Onfocusout

I have a dropdown with a search field to filter the list. Here is the basic structure:
<div class="dropdown">
<button class="dropdown-button dropdown-toggle" #onclick="e => this.show = !this.show"></button>
<div class="dropdown-menu #(show ? "show" : "")">
<input class="form-control form-control-sm" placeholder="type filter..."/>
<div class="scrollable-menu">
<table>
...
</table>
</div>
</div>
</div>
How do I hide the dropdown when the user clicks somewhere else?
If I use the onblur event of the button the dropdown gets hidden when the user clicks inside the filter input --> doesnt work.
The dropdown-menu is outside the dropdown div so I can't use that.
It would be ideal if I could group the button and the dropdown list together somehow so that the focusout event only gets triggered when the user clicks outside this "group" of elements.
EDIT
I updated the code snipped to show where how I toggle the dropdown.
The show variable is also inverted when the user selects an element in the list.
The simplest way is to use CSS - hide the scrollable-menu by default, then display it when anything in the dropdown has focus.
.scrollable-menu {
display: none;
}
.dropdown:focus-within .scrollable-menu {
display: block;
}
Edit: Add more complicated Blazor event based version
This problem (which I had not understood fully before) is usually solved in javascript detecting whether the target element of a focus change is within the container, but that then means interop calls to set/update your show field.
A purely Blazor solution could be handled by delaying the hide and cancelling if focus remains inside.
<div class="dropdown">
<button class="dropdown-button dropdown-toggle" #onclick=HandleClick #onfocus=HandleFocus #onblur=HandleBlur ></button>
<div class="dropdown-menu #(show ? "show" : "")" #onfocusin=HandleFocus #onfocusout=HandleBlur tabindex="-1">
<input class="form-control form-control-sm" placeholder="type filter..."/>
<div class="scrollable-menu">
<table>
...
</table>
</div>
</div>
</div>
#code{
bool show;
CancellationTokenSource tokenSource;
void HandleClick() => show = !show;
async Task HandleBlur(FocusEventArgs a)
{
tokenSource = new CancellationTokenSource();
await Task.Factory.StartNew(async ()=> {
await Task.Delay(100);
show = false;
await InvokeAsync(StateHasChanged);
},tokenSource.Token);
}
void HandleFocus(FocusEventArgs a)
{
if (tokenSource is CancellationTokenSource)
tokenSource.Cancel();
}
}
Try it out here: https://blazorrepl.com/repl/wFESlpaa33iocZJR52
use InvokeVoidAsync. It will not work if you make it async.
#onclick="#(e => {
JsRuntime.InvokeVoidAsync("eval",$"bootstrap.Dropdown(yourID).toggle()");
})"

How to wait until div dropdown is loaded using selenium webdriver?

There are two dropdown menus on a page.
When i click on First dropdown, then in second dropdown options will be automatically loaded after couple of seconds.
Here comes my problem, that how can i wait for the second dropdown to load fully using selenium webdriver.
<div name="ddlFruit_N" id="ddlFruit_N" class="Searchddl">
<div class="chosen-drop">
<div class="chosen-search">
<input class="chosen-search-input" type="text" autocomplete="off">
</div>
<ul class="chosen-results">
<li class="active-result" data-option-array-index="0">Select</li><li class="active-result" data-option-array-index="1">Apple</li><li class="active-result" data-option-array-index="2">Mango</li><li class="active-result" data-option-array-index="3">Grapes</li><li class="active-result" data-option-array-index="4">Banana</li><li class="active-result" data-option-array-index="5">Guava</li>
</div>
Note: This is div dropdown
Second dropdown list xpath: //*[#id='ddlFruit_N']/div/ul/li
Am using C# Thank you
Please try below code. We will check for options to load in Div
public static IWebElement waitForDropdownPopulate(IWebDriver driver, By by, int delayInSeconds)
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(delayInSeconds));
return wait.Until<IWebElement>(drv =>
{
IWebElement elementList = drv.FindElement(by);
elementList.Click();
if (elementList.FindElements(By.XPath("./div/ul//li")).Count >= 2)
{
return elementList;
}
return null;
}
);
}
and I call it like this:
Myclass.waitForDropdownPopulate(driver, By.XPath("//*[#id='ddlFruit_N']"), 30);
Try below code
var items = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(By.XPath("//*[#id='ddlFruit_N']/div/ul/li")))
.FindElements(By.XPath("//*[#id='ddlFruit_N']/div/ul/li"));
To use seleniumExtras library install DotNetSeleniumExtras.WaitHelpers from NugetPackage

Selenium clicking button hidden by span

I am trying to automate an environment selection screen where there are multiple selectable buttons individually hidden by a span, these display as tiles.
I have managed to navigate to a given tile and pull up the button but I am unable to click it.
Here is the code I have
public static void NavigateToEnvironment(IWebDriver driver, string environment)
{
IWait<IWebDriver> wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5.00));
wait.Until(ExpectedConditions.ElementIsVisible(By.XPath($"//span[text()='{environment}']")));
var tile = driver.FindElement(By.XPath($"//span[text()='{environment}']"));
Actions action = new Actions(driver);
action.MoveToElement(tile).Perform();
wait.Until(ExpectedConditions.ElementIsVisible(By.XPath($"//*[#span=(text()='{environment}')][#btn=(starts-with(text(), 'Start'))]")));
driver.FindElement(By.XPath($"//*[starts-with(text(), 'Start')]")).Click();
}
The first part successfully moves to the correct tile and opens the span so on screen the button is there.
The wait.until condition is fine too so Selenium can see the element so its the final click command I have an issue with.
It seems only to look for the button hidden within tile one but I am trying tile three. All the buttons have the same HTML tags.
In the current code state I get element not visible.
I have tried to use the xpath as in the wait condition but that returns that the parameters are not elements so again fails.
I am kind of at a loss. Any ideas?
UPDATE:
Some HTML of one of the buttons. This basically repeats with a different application name
<li class="trans tile">
<div class="tileWrap noselect" aria-haspopup="true">
<div class="divNavIcon">
<span class="spnNavIcon primarycolorfont enable" data-bind="css: Code"></span>
</div>
<div class="tilePopup primarycolor">
<span data-bind="text: ApplicationNameAlias ? ApplicationNameAlias : ApplicationName">Enable QA</span>
<span data-bind="text: Description" class="tileSubText">Enable CI Environment</span>
<div class="tilePopupToggle">
<button type="button" data-bind="click: $parent.startApp, css: { disabled: IsRevoked }" class="btn">Start <i class="fa fa-fw fa-desktop"></i></button>
<button type="button" style="display:none;" data-bind="click: $parent.startAppNew, css: { disabled: IsRevoked }" class="btn">Start New <i class="fa fa-fw fa-external-link"></i></button>
<button type="button" style="display:none;" data-bind="attr: { "data-target": "#appPreview_" + ApplicationID }" class="btn" data-toggle="modal" data-target="#appPreview_3043">Preview <i class="fa fa-fw fa-play"></i></button>
</div>
</div>
</div>
Screenshot to help understanding - Each tile acts in the same way with a hidden start button. My code works fine for this first tile but if I want the second or third tiles it cannot find the start button
As per the HTML you have shared to click on the button with text as Start you can use the following code block :
wait.Until(ExpectedConditions.ElementToBeClickable(By.XPath("//div[#class='tilePopup primarycolor']//div[#class='tilePopupToggle']/button[#class='btn' and normalize-space()='Start']/i[#class='fa fa-fw fa-desktop']"))).Click();
Update
Can you try removing the <button> tag as :
wait.Until(ExpectedConditions.ElementToBeClickable(By.XPath("//div[#class='tilePopup primarycolor']//div[#class='tilePopupToggle']//i[#class='fa fa-fw fa-desktop']"))).Click();
Note : As per aurelia/binding/issues/163 disable.bind disables button but inner content is still clickable and we are targeting i[#class='fa fa-fw fa-desktop']
I have managed a pretty elegant work around to this issue. The buttons are contained in li items so i'm just finding the relevant one of those.
public void NavigateToEnvironment(IWebDriver driver, string environment)
{
var tile = driver.FindElement(By.XPath($"//span[text()='{environment}']"),5);
Actions action = new Actions(driver);
action.MoveToElement(tile).Perform();
var tile2 = driver
.FindElement(By.XPath("//*[#id='content']/div/div/div/div/ul"))
.FindElements(By.TagName("li"))
.Where(x => !string.IsNullOrWhiteSpace(x.Text))
.ToList();
var singleTile = tile2.Single(x => x.Text.Contains(environment));
driver.FindElement(By.XPath($"//*[#id='content']/div/div/div/div/ul/li[{tile2.IndexOf(singleTile) + 1}]/div[1]/div[2]/div/button[1]")).Click();
}

Click event not working from Dialog box in asp.net

I have created a dialog box that open up from the aspx page. The dialog box contains information along with the buttons on the footer. MERGE and Close.
Below is the dialog box that I used for opening. This is successfully getting created and information a getting populated. However, when I am clicking on the "MERGE" button of the dialog box it does nothing as navigation is not transferred to the code behind file.
I have successfully defined the Click event on my code behind, but I don't understand why it is not firing it.
aspx page
<div class="modal-dialog" id="updateConfirmPopUp" style="display: none">
<div class="modal-content">
<div class="modal-header" id="popUpHeader">
<button type="button" class="close closePopup">
<span>×</span></button>
</div>
<div class="modal-body" id="confirmData">
<div id="random"></div>
<div class="dataTable_wrapper">
<div class="table-responsive">
<uc:ReviewGroupGrids ID="reviewGroupCtrls" runat="Server" />
</div>
</div>
</div>
<div class="modal-footer">
<asp:Button ID="Button1" runat="server" Text="Review Next" OnClick="btnMerge_Click" />
<button type="button" id="btnClosePopUp" class="btn btn-default closePopup">
Okay</button>
</div>
</div>
</div>
aspx.cs page
protected void btnMerge_Click(object sender, EventArgs e)
{
try
{
// SessionUtility.SetSession(Constants.LASTREVIEWGROUPIDPROCESSED, this.ReviewGroup.ReviewGroupId);
if (preventEvents)
{
Response.Redirect(Request.RawUrl, false);
return;
}
// ensure no action taken on current review group(partially or completly)
#region Handle review group for completly processed case
var selectedAssignment = SessionUtility.GetSession(Constants.SELECTEDUSERASSIGNMENT) as Assignment;
var currentReviewGroupID = hdnReviewGroupID.Value.ToString();
if (currentReviewGroupID != selectedAssignment.ReviewGroupId)
{
selectedAssignment.ReviewGroupId = currentReviewGroupID;
SessionUtility.SetSession(Constants.SELECTEDUSERASSIGNMENT, selectedAssignment);
LoadNextReviewGroup(null, null);
lblPreviousReviewGroupId.Text = string.Format(StaticConstants.REVIEWGROUPVALIDATIONMESSAGE, currentReviewGroupID);
lblPreviousReviewGroupId.Visible = true;
return;
}
#endregion
if (!string.IsNullOrEmpty(selectedIds))
{
SessionUtility.SetSession(Constants.USERSERLECTIONROWIDS, selectedIds);
if (BtnMerge_Click != null)
{
BtnMerge_Click(sender, e);
}
Response.Redirect("MergeGroup.aspx", false);
}
}
catch (Exception ex)
{
SessionUtility.SetSession(Constants.Error, ex);
NavigationHelper.ToErrorPage(false);
}
}
My client click event is working fine.The only problem is with the onClick event.
An HTML Button can't call server side code. You have to use asp button with the runat="server" tag. something like
<asp:Button ID="btnMerge" runat="server" Text="MERGE" OnClick="btnMerge_Click" />

How to remove an item in DropDownList in ASP MVC using JavaScript

I am developing an ASP .Net MVC 3 application using C# and SQL Server 2005.
In a view, I have a DropDownList, a button.
How can I remove an item from the DropDownList for each click of the button.
I try to use javascript, but I think that's not working because when I click on the button, nothing happens.
This is the code :
<%:Html.Label("Poste :")%>
<%:Html.DropDownListFor(
model => model.SelectedPoste,
Model.PostesItems,
new { #id = "poste" })%>
<div>
<input type="submit"
value="Enregistrer"
id="btnSave"
onclick="remove()" />
</div>
<script type="text/javascript">
function remove() {
var rm = document.getElementById('btnSave');
var poste = document.getElementById('poste');
poste.removeItem();
}
</script>
using jQuery
<select id="poste">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<br />
<input type="button" id="btnSave" value="Remove current item" />
<script type="text/javascript">
$(function () {
$('#btnSave').click(function () {
$('#poste option:selected').remove();
return false;
});
});
</script>
EDIT: binding the click event using jQuery
The generated HTML will give the select element an ID of "SelectedPoste", not "poste" as you are attempting to set.
Use remove to remove an item.
Change your javascript to be:
var poste = document.getElementById('SelectedPoste');
poste.remove(poste.selectedIndex);
Edit: The generated HTML for the select will be:
<select id="poste" name="SelectedPoste">...</select>
Either of these two lines will get that elements:
var poste = document.getElementById('poste');
or
var poste = document.getElementById('SelectedPoste');
(Atleast in IE10)
Then to remove the selected item from the list, do:
poste.remove(poste.selectedIndex);
This does not remove the button :)
Edit 2: Like Dimitar's answer, you need to change your function name from remove to something else.
Once you do that, my code above works in IE and Chrome.
Using vanilla JavaScript you can do:
<script type="text/javascript">
function removeOption() {
var posteElement = document.getElementById('poste');
var currentIndex = posteElement.selectedIndex;
posteElement.removeChild(posteElement[currentIndex]);
return false;
}
</script>
That's all you need. Also make sure you rename your function to anything other than remove():
<input type="submit"
value="Enregistrer"
id="btnSave"
onclick="removeOption()" />
Check out this (not very nice inline-fiddle).
However I'd strongly suggest at least looking into a library such as jquery, (this would be much easier than with vanilla.js). Check out Andre's answer.
Try this:
$("#poste option[value='X']").each(function() {
$(this).remove();
});
Or to be more terse, this will work just as well:
$("#poste option[value='X']").remove();
Example:
$("#btnSave").click(function(){
$("#poste option[value='X']").remove();
});
Remember to use JQuery :)

Categories