Selenium C# ImplicitWait won't wait for element to load - c#

I have created a custom method to implicitly wait for an element to load, then I use this in a custom click method as so:
public static void WeElementToBeClickable(this IWebElement element, int sec = 10)
{
var wait = new WebDriverWait(Driver.Browser(), TimeSpan.FromSeconds(sec));
wait.Until(ExpectedConditions.ElementToBeClickable(element));
}
public static void WeClick(this IWebElement element, int sec = 10)
{
element.WeElementToBeClickable();
element.Click();
}
I then attach this to any element I click on to make sure it always polls the DOM to make sure the element has been loaded, but it doesn't seem to wait for some specific elements to load.
I'm searching for this element as so:
<span class="button add fr" onclick="GoToHash('/ContractorCommon/Contractor/ContractorAdd', null, 'Contractor'); "><span class="icon-add"></span> Contractor</span>
public IWebElement AddContractorIcon => Driver.FindElement(By.XPath("//span[#class='button add fr']"));
But it always gives off the following exception straight away:
OpenQA.Selenium.NoSuchElementException : no such element: Unable to locate element: {"method":"xpath","selector":"//span[#class='button add fr']"}
I've tried everything to get it to wait for this element to load but I can't seem to figure it out. Weirdly enough if I debug it...it finds the element.
Any help would be greatly appreciated!

Related

Clicking on element fails if page is scrolled down/up and element is outside current view

I want to click on specific element, but this element is not displayed in current view, clicking on that element fails.
I tried to set focus on needed element before clicking using the following code
Actions actions = new Actions(driver);
actions.MoveToElement(element);
actions.Perform();
But it fails. Can anyone please help?
One of two things. Is this on a popup by chance? If so you need to switch to the iframe.
public static void switchToIframe(string name)
{
_webDriver.SwitchTo().Frame(name);
}
If the element is off the page and it is a scrolling issue you can try this:
You can pass in a value of 100 to move down 100px.
public static void ScrollDownByAmount(string value)
{
var windowScroll = string.Format("window.scrollBy(0,{0})", value);
IJavaScriptExecutor javascript = (IJavaScriptExecutor)_webDriver;
javascript.ExecuteScript(windowScroll , "");
Thread.Sleep(500);
}

I want to select dropdown element

I want to click a dropdown element. I have mentioned element's xpath/css both. But it is constantly giving error "no element found". I am working on C# on selenium . I have also given dropdown ID first then wait for the dropdown element and then get it clicked but it gives same error always. Any idea ???
It depend of available iFrame or maybe you should switch to default content. It's complicated, without your code.
Any way try this code. It's working for me:
private static void ChooseZipCode(IWebDriver wd)
{
if (!wd.FindElement(By.XPath("//td[#id='divShipStateCombo']/select//option[3]")).Selected)
{
wd.FindElement(By.XPath("//td[#id='divShipStateCombo']/select//option[3]")).Click();
}
}
// where is "[3]" the position your element(ID) in drop down menu
// or
private static void SelectElement(IWebDriver wd, string CardType)
{
SelectElement cardSelect = newSelectElement(wd.FindElement(By.Name("CardType")));
cardSelect.SelectByText("Visa Card");
}

Why is Selenium Chrome driver not able to find elements below scroll bar?

I have been trying to write a clear dashboard step that would clear all objects we call widgets off of a dashboard page like this:
public static void ClearDashboard(string widgetToKeep = null)
{
var widgets = Driver.FindElements(
By.XPath(
$"//div[#widget-name and descendant::span[#class='title' and text()[not(contains(., '{widgetToKeep ?? "dummyText"}'))]]]"
));
if (widgets != null)
{
foreach (IWebElement widget in widgets)
{
var closeButton = widget.FindElement(By.XPath(".//span[#class='delete']"));
closeButton.Click();
}
}
It totally works.
It gets all span elements back with a title and I can roll through those elements, get a span delete button for each one, and delete the widget with:
closeButton.Click()
Except for a widget object which is a bit off of the screen.
It can't seem to find the span button if the widget is a little off the screen.
This is the exception:
InvalidOperation was unhandled by user code
An exception of type 'System.InvalidOperationException' occurred in WebDriver.dll but was not handled in user code
Additional information: unknown error: Element is not clickable at point (951, 760). Other element would receive the click: <div class="scroll" ng-class="{'getting-data': gettingNewData}" scroll-pag="">...</div>
(Session info: chrome=52.0.2743.116)
(Driver info: chromedriver=2.22.397933 (1cab651507b88dec79b2b2a22d1943c01833cc1b),platform=Windows NT 6.1.7601 SP1 x86_64)
You should use scrolling to reach every element before click using IJavascriptExecutor and wait until element to be clickable using WebDriverWait as below :-
IWait wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(3));
IJavaScriptExecutor js = Driver as IJavaScriptExecutor;
foreach (IWebElement widget in widgets)
{
var closeButton = widget.FindElement(By.XPath(".//span[#class='delete']"));
//Now scroll to this element first
js.ExecuteScript("arguments[0].scrollIntoView(true);", closeButton);
wait.Until(ExpectedConditions.ElementToBeClickable(closeButton)).Click();
}

How to fail the test if Element is found and pass the test if element is not found?

I have to develop a unit test which fails if element is present and passes the test if element is not present.
To be detailed, I have a simple form like name, email, address etc. When I click on the save button, error message is displayed if required fields are empty. If error message is displayed then I have to fail the test and if not displayed then pass the test. Is there any solution?
try
{
//Click on save button
IWebElement save_profile = driver.FindElement(By.XPath("//div[#class='form-group buttons']/div/input"));
save_profile.Click();
//Locate Error Message below the text box
IWebElement FirstNameError = driver.FindElement(By.XPath("//form[#class='default form-horizontal']/fieldset/div[4]/div[2]/span/div"));
//I want to fail the test here if above element is found
}
catch
{
//pass the test if element is not found in try statement
}
I think I am going in the wrong direction but couldn't find the solution. Please advice. Thansk in advance.
Following is the behavior of "findElement"
If the element you are looking exists, it returns the WebElement.
If the element does not exist, it throws Exception and if not handled properly leads troubles.
So use "findElements"(here observe 's' at the end)
Following is the behavior of "findElements"
It returns a list,
If the element exists, the size obviously more than 0,
If the element does not exist the size will be 0. So you can just put a if condition with size
Here is pseudo code in Java
if (driver.findElements(By.XPath("//div[#class='form-group buttons']/div/input")).size()>0)
//print element exists
else
//print element does not exists.
I hope the above helps.
You have two options to do this.
Firstly, by using Assert.assertTrue(boolean value);
try
{
//Click on save button
IWebElement save_profile = driver.FindElement(By.XPath("//div[#class='form-group buttons']/div/input"));
save_profile.Click();
//Locate Error Message below the text box
IWebElement FirstNameError = driver.FindElement(By.XPath("//form[#class='default form-horizontal']/fieldset/div[4]/div[2]/span/div"));
//I want to fail the test here if above element is found
Assert.assertTrue(false);
}
catch
{
//pass the test if element is not found in try statement
Assert.assertTrue(true);
}
Secondly, by using boolean return type if used inside a method.:
boolean isValidated = false;
try
{
//Click on save button
IWebElement save_profile = driver.FindElement(By.XPath("//div[#class='form-group buttons']/div/input"));
save_profile.Click();
//Locate Error Message below the text box
IWebElement FirstNameError = driver.FindElement(By.XPath("//form[#class='default form-horizontal']/fieldset/div[4]/div[2]/span/div"));
//I want to fail the test here if above element is found
isValidated =false;
return isValidated;
}
catch(Exception e)
{
//pass the test if element is not found in try statement
isValidated = true;
return isValidated;
}
If the method returns true, pass the test and vice versa

Selenium2 Webdriver C# .Click() List - Stale Reference Exception

I need some help because I keep getting a StaleElementReference when I try to parse a list of a tags to click.
What I have done is on page land I iterate through the page and generate an object List<> with with all the a tags
private List<IWebElement> _pageLinks;
public List<IWebElement> pageLinks
{
get
{
if (_pageLinks == null)
{
_pageLinks = InfoDriver.FindElements(By.TagName("a")).ToList();
}
return _pageLinks;
}
}
Then I want to parse this list, and click each one and then go back to the page it was referenced from.
private static SeleniumInformation si = new SeleniumInformation(ffDriver);
si.pageLinks.ForEach(i =>
{
i.Click();
System.Threading.Thread.Sleep(1000);
ffDriver.Navigate().Back();
});
What happens is that after the first click it goes to the new page and then goes back to the starting page but it can't get the next link. I've tried setting it to a static element, setting a backing field so that it checks to see if there is data there already however it appears that on click the IwebElement looses the list and it doesn't rebuild the list either so I get a StaleElementReference exception not handled and element not found in cache.
Is this a bug in Selenium with the IWebElement class or am I doing something wrong? Any help would be greatly appreciated.
This is the expected behavior. You left the page the element was on. When you navigated back, it is a new page and that element is no longer on it.
To work around this I would suggest passing around Bys instead, if you can. Assuming your anchorlinks all have unique hrefs, you could instead generate a list as follows (java code, but should translate to c#):
private static List<By> getLinks(WebDriver driver)
{
List<By> anchorLinkBys = new ArrayList<By>();
List<WebElement> elements = driver.findElements(By.tagName("a"));
for(WebElement e : elements)
{
anchorLinkBys.add(By.cssSelector("a[href=\"" + e.getAttribute("href") + "\"]"));
//could also use another attribute such as id.
}
return anchorLinkBys;
}
I don't know the makeup of your page so I don't know if it is possible to generate By's dynamically that uniquely identify the elements you want. For example if all the elements have the same parent, you could use the css level 3 selector nth-child(n). Hopefully you get some ideas from the above code.
private void YourTest()
{
IWebDriver browserDriver = new FirefoxDriver();
browserDriver.Navigate().GoToUrl(pageUrl);
int linkCount= browserDriver.FindElements(By.TagName("a")).Count;
for (int i = 0; i <= linkCount-1; i++ )
{
List<IWebElement> linksToClick = browserDriver.FindElements(By.TagName("a")).ToList();
linksToClick[i].Click();
System.Threading.Thread.Sleep(4000);
if(some boolean check)
{
//Do something here for validation
}
browserDriver.Navigate().Back();
}
broswerDriver.Quit();
}

Categories