Element not clickable being blocked still fails using ExpectedConditions - c#

Using SeleniumExtras.WaitHelpers nuget pkg
Trying to click a button on a page but as the page is loading there is a sort of blocking div that is causing an error. I noticed that if I just gradually step through the code, things work as expected, but when I just let the code run, I catch an exception that mentions something is blocking it. Browsing the site I can see the blocking div occasionally. First I tried just using a wait, and that was when I discovered the error, but when using ExpectedConditions I am still getting it. What cam I missing?
IWebElement dtLink = new WebDriverWait(Driver, TimeSpan.FromSeconds(45))
.Until(ExpectedConditions.ElementToBeClickable(By.XPath(date_link_path)));
dtLink .Click();
The exception message mentions this:
...is not clickable at point (115,311) ...because another element obscures it

When this error occurs there are 2 main ways to deal with that:
It is your way that you already did it.
Using 'Javascript' executor it will definitely work.
Here it is code example:
IJavaScriptExecutor executor = (IJavaScriptExecutor)driver ;
executor.ExecuteScript("arguments[0].click();", dtLink);

Related

Webdriver wait cant find element that exists

Hello I'm a little new to selenium I'm trying to automate a page for work. The issue I'm having is that webdriver waits are not finding my elements, but I can use those elements if I comment out the wait portion. The issue seems to start after I switch the frame. Is there any additional steps I need to do after that?
Update: When I am debugging and stepping through it works fine. But never works in test run
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(120));
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.CssSelector("iframe[src='/CreditAdmin/']")));
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementExists(By.CssSelector("input[aria-label='Filter for column']"))); //This never finds the Element
IWebElement companySearch = driver.FindElement(By.CssSelector("input[aria-label='Filter for column']")); //This works fine if I comment out previous
companySearch.SendKeys(fieldValue);
Try to change
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementExists(By.CssSelector("input[aria-label='Filter for column']")));
to:
wait.Until(c => c.FindElement(By.CssSelector("input[aria-label='Filter for column']")));

Implicit wait Command Not Working-selenium webdriver C#

Guys, I have started to work on selenium web driver. You can assume I am a beginner. At the moment I am having difficulties in implementing the implicit wait command in my code (C#). it is not working as it should and result in an exception due to Element not found, however when I add the "Thread.Sleep(3000) the code get executed flawlessly. I have been looking for the solution all over the internet but not able to resolve the problem. Below I have mentioned sample code.
class Entrypoint
{
static void Main()
{
IWebDriver driver = new ChromeDriver();
**driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(20);**
driver.Navigate().GoToUrl("https://r1.netrevelation.com:8443/mcba-cms/pages/flight-transfer.cab");
driver.Manage().Window.Maximize();
driver.FindElement(By.Id("loginlink")).Click();
driver.FindElement(By.Id("headerSubView:inputUserName:input")).SendKeys("st001");
driver.FindElement(By.Id("headerSubView:inputPassword:input")).SendKeys("hello321" + Keys.Enter);
driver.FindElement(By.Id("dateOfFlight:input")).Click();**//This Step does not get Executed , it throws exception element not found.**
driver.FindElement(By.Id("ui-datepicker-div")).Click();
driver.FindElement(By.XPath(".//*[#id='ui-datepicker-div']/div/a[2]/span")).Click();
driver.FindElement(By.LinkText("28")).Click();
IWebElement Flightno = driver.FindElement(By.Id("selectedFlight:input"));
Flightno.SendKeys("BA901" + Keys.Enter);
IWebElement Flighttick = driver.FindElement(By.Id("flightTickImg"));
driver.Quit();
Please note that at the moment I don't want to use explicit wait, as implicit will serve my need (if it starts working). The above code Run in supersonic speed for somehow it manages to Login into the system but afterward it Fails every time reason being once Login request is made system pauses for 2-3 seconds. Please provide your comment in this regard.
As per the documentation, an Implicit Wait is to tell the WebDriver to poll the HTML DOM for a certain amount of time when trying to find an element() or find all elements() if they are not immediately available. But availability of an element in the DOM Tree doesn't guarantees that the ElementToBeClickable as you have tried in your code block. Hence you face the exception as Element not found.
Solution:
So the solution to your issue is to induce Explicit Wait i.e. WebDriverWait with ExpectedConditions clause as ElementToBeClickable which will not only confirm the availability of an element in the HTML DOM but also ensure that the Element is Clickable i.e. Element is Displayed and Enabled as follows:
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement element = wait.Until(ExpectedConditions.ElementToBeClickable(By.Id("loginlink")));

Selenium c# wait.until(expectedconditions)... function fails to find objects/elements on screen

I am new to using selenium Webdriver and writing c#. I was using lots of thread.sleep() commands in my script to make sure Selenium didn't try and click too quick. Upon lots of research I found this is frowned upon and there are "better" ways to do it, so I started to use:-
wait.Until(ExpectedConditions.ElementToBeClickable(By.Id("FieldId")));
Wait is defined in another class as:-
wait = new WebDriverWait(driver, new TimeSpan(0, 0, 0, 10));
I can only get this to work 2/10 times of running the script without getting :
No such element exception: cannot locate element......
I have tons of examples of this problem now I have stopped using thread.sleep. After lots of research I always come to find this is the advised way but it seems totally unreliable. Have I missed something? The element is always there after 2 seconds and the error occurs before 10sec has passed. I have read at least 10 other posts which sound similar but none of them have a solution which works...except Thread.Sleep(5000) !
Try adding the NoSuchElementException type to the IgnoreExceptionTypes of the waiter after you create it.
wait = new WebDriverWait(driver, new TimeSpan(0, 0, 0, 10));
wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
wait.Until(ExpectedConditions.ElementToBeClickable(By.Id("FieldId")));
In general, if the waiter is returning before the timeout you indicate is expired, it's because an exception occurred that is not currently ignored.
The WebDriverWait class is derived from the DefaultWait class. Both of which you can review on github which I found really helpful in understanding how to use it.

How to handle cases where Selenium click action succeeds, but nothing happens

I am using Selenium to test the user interface of a website. 95% of the time, things work fine. I find my elements, execute my clicks, and check the results. Unfortunately, maybe 5% of the time, I'll find the element, verify that it is clickable, run the click event with no error... but nothing actually changes.
Here's an example bit of code:
WebDriverWait waitForTimeout = new WebDriverWait(Driver, TimeSpan.FromSeconds(60));
IWebElement selectMaskButton = waitForTimeout.Until(ExpectedConditions.ElementToBeClickable(By.Id("mask_expander")));
Thread.Sleep(250); // A slight delay ensures that the button really is clickable
selectMaskButton.ClickAndWait(Driver);
I have that sleep statement in there because this is a case where, frequently, that click event goes awry. The quarter second wait works most of the time, but not always. For this case, I could probably surround it with custom code to pause, and then click again if the specified follow-up element doesn't work out, but that's clunky and involves a different target for everywhere that I click on things. And adding delays everywhere is less than optimal too because it leads to a bunch of fixed delays that just keep getting incremented as people run into issues.
I don't know that it's entirely a matter of going too fast because I've had the occasional case where I set a debug statement on a Click command, run the test in debug, and waited a few seconds before executing the Click, and still it doesn't work. As a tester, I don't have access to some of the inner code, so I don't know exactly what gets executed inside the click, and the developers I've spoken to are basically telling me that it works fine when they manually click on it, so they don't see the problem.
Is there a generic way to handle clicking on an element and ensuring that the action actually fires?
Additional code for helper function ClickAndWait:
public static void WaitUntilPageLoads(this IWebDriver driver)
{
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
wait.Until(d => ((RemoteWebDriver)d).ExecuteScript("return document.readyState").Equals("complete"));
Thread.Sleep(500);
}
public static void ClickAndWait(this IWebElement element, IWebDriver driver)
{
element.Click();
driver.WaitUntilPageLoads();
}
In this case, ClickAndWait actually isn't useful because the page is changing dynamically rather than all at once, so the page claims to be loaded right away. I had just forgotten to replace the call.

Selenium Webdriver c# without waiting for page to load

I have the following scenario:
I want to navigate to a page. Then click a button as soon as it appears(not wait for page to load ). I don't want to wait for the initial page to load as it takes a long time. My program currently is stuck until the page loads and then clicks the button.
I basically want to navigate to link and then have no wait for page and continue with my code.
Is there anyway round this?
With the latest version of the .NET bindings, you can set a page load timeout. However, there are some caveats you'll need to be aware of. First, this hasn't been implemented by all browsers. It should work for IE and Firefox, if memory serves. Secondly, you'll need to catch an exception to make that work properly, but it can be done.
// WARNING! Completely untested code written without
// the benefit of an IDE!
IWebDriver driver = new InternetExplorerDriver();
driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(1));
try
{
driver.Url = "http://your.long.loading.page.com";
}
catch (TimeoutException)
{
// NOTE: In 2.26 or later, this will be WebDriverTimeoutException
}
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement element = wait.Until<IWebElement>((d) =>
{
return d.FindElement(By.Id("yourId"));
}
IWebDriver driver = new FirefoxDriver();
driver.Url = "http://somedomain/url_that_delays_loading";
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
{
return d.FindElement(By.Id("someDynamicElement"));
});
It does exactly what you want. It queries the page to find the element, catches exceptions if no element found and returns an element when found.
After that, you can manipulate the button ignoring the fact that page can be not loaded
http://seleniumhq.org/docs/04_webdriver_advanced.html
Short answer: No.
Long answer: Selenium is by default trying to simulate the real user - I know that it kinda sucks, especially at a times you need to test a deploy after deploy after deploy...
But: If real user has to wait for button to appear, then the program has to do it also...
BTW: If the button really appears among first on the page, you can try this:
search for the button by ID, xpath ... the way you do it
Catch exception (I am Java guy, so dont ask me how)
If there was error, wait short time (e.g. 200 milliseconds) and then go to 1
If not, click the button
The cycle should end also if certain amount of time passes (10s) and if so, throw exception
As stated above: Language of my choice is Java. There I can do that. But I dont know how to write that in C#

Categories

Resources