I am trying to refresh the page when an element I am trying to find isnt displayed I have written this code but instead of just skipping the if statement the test just fails
while (true)
{
if (Driver.Instance.FindElement(By.LinkText("Leather Utility Vest")).Displayed)
{
var clickButton = Driver.Instance.FindElement(By.LinkText("Leather Utility Vest"));
clickButton.Click();
break;
}
Driver.Instance.Navigate().Refresh();
}
I just used this code instead
while (true)
{
try
{
var clickButton = Driver.Instance.FindElement(By.LinkText("Leather Utility Vest"));
clickButton.Click();
break;
}
catch(Exception)
{
Driver.Instance.Navigate().Refresh();
}
}
This catches the error that the element wasn't found which was why the test was failing and runs the catch block which refreshes the webpage
Related
I am using Selenium with C# on NUNit framework and I am trying to put an Conditional statement looking for an element (banner to be specific). I already have a piece of code to click that banner and go forward in my test flow.
Now, I am after a condition that IF that banner is not present THEN user should have to perform additional steps to set the banner and proceed.
So, I want my IF to check not present condition to execute that piece of code otherwise will skip it.
var banner = FindElement(By.Id("bannerId"));
IF ( checking if above element not present)
{ execute set of steps to set the banner }
ELSE
{
WebDriverWait wait2 = new WebDriverWait(driver, TimeSpan.FromSeconds(40));
wait2.Until(ExpectedConditions.ElementIsVisible(By.Id("bannerId")));
banner.Click();
Thread.Sleep(2000);
}
I hope I was able to explain my problem and will appreciate any help.
try this code :
public bool IsElementVisible(IWebElement element)
{
return element.Displayed && element.Enabled;
}
IF(IsElementVisible(banner) == false)
{ execute set of steps to set the banner }
You could use the try and catch,
try
{
var banner = FindElement(By.Id("bannerId"));
IF ( checking if above element not present)
{ execute set of steps to set the banner }
ELSE
{
WebDriverWait wait2 = new WebDriverWait(driver, TimeSpan.FromSeconds(40));
wait2.Until(ExpectedConditions.ElementIsVisible(By.Id("bannerId")));
banner.Click();
Thread.Sleep(2000);
}
}
catch(Exception ex)
{
//check what will be the return message from ex.Message
//and from here you could add a logic what would be your next step.
}
I have validated your code. I can see some mistakes. Please find the suggestions below:
The line of your code :
var banner = FindElement(By.Id("bannerId")); will throw a "NoSuchElementException" and the if statement on the next line will not be executed. Hence, the simplest option will be to use try and catch where you are finding the element and skip the if block.
Your code snippet can be:
try
{
var banner = FindElement(By.Id("bannerId"));
WebDriverWait wait2 = new WebDriverWait(driver,
TimeSpan.FromSeconds(40));
wait2.Until(ExpectedConditions.ElementIsVisible(By.Id("bannerId")));
banner.Click();
Thread.Sleep(2000);
}
catch (NoSuchElementException ex)
{
//Give the appropriate message
}
If you want to follow the approach you have mentioned in your code then please try the code snippet below. You will have to store the elements in the List and check the list size. If the size of the list is not zero, then you can click the banner else display the appropriate message.
Second code snippet:
IList<IWebElement> banner = driver.FindElements(By.Id("bannerId"));
IF ( list size is zero)
{ execute set of steps to set the banner }
ELSE
{
WebDriverWait wait2 = new WebDriverWait(driver,
TimeSpan.FromSeconds(40));
wait2.Until(ExpectedConditions.ElementIsVisible(By.Id("bannerId")));
//Click on the first element of the list
}
Use FindElements instead, it will prevent the exception and you can check the size of the returned collection to check if the banner exists
IList<IWebElement> elements = driver.FindElements(By.Id("bannerId")).ToList();
if(elements.Count == 0)
{
do something
}
else
{
//do something with the banner at elements[0]
wait2.Until(ExpectedConditions.ElementToBeClickable(elements[0])).Click();
}
I'm trying to figure out how it's possible to wait for a condition in order to login into a web page with Selenium Driver. However it is not as straightforward as it may seem. I'm working around with Thread.Sleep(3000); but I'm sure there should be a better solution. So, my code works as follows:
Load page with firefox driver.
Execute a javascript snnipet to change language (I need to wait for this in order to login).
IJavaScriptExecutor executor = (IJavaScriptExecutor)firefox;
executor.ExecuteScript("arguments[0].click();", idioma_español);
Above instruction leads to a page reload.
Next instruction is intented to wait for page to be reloaded
WebDriverWait wait = new WebDriverWait(newDriver,TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.TextToBePresentInElementValue(element,textToAppear));
Continue to login.
However, when I run the code, it throws the following exception:
Looking closer into de output, I found this:
I tried with different expected conditions such as: TextToBePresentInElement,ElementExists; but it throws the same exception.
I also tried with ExecuteAsyncScript("arguments[0].click();", idioma_español); method, but it throws "Document was unloaded " exception.
It looks like the text element has been replaced, so the element was stale. I think you can solve it by fetch the new element every time. See code below:
public bool WaitForTextToAppear(IWebDriver driver, By elementLocator, string textToAppear, int timeoutInSec=10)
{
IWait<IWebDriver> wait = new DefaultWait<IWebDriver>(driver);
wait.Timeout = TimeSpan.FromSeconds(timeoutInSec);
wait.PollingInterval = TimeSpan.FromMilliseconds(300);
try
{
wait.Until(d => IsTextPresentedIn(d, elementLocator, textToAppear));
return true;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Error: " + ex.Message);
return false;
}
}
private bool IsTextPresentedIn(IWebDriver driver, By elementLocator, string textToAppear)
{
try
{
var elements = driver.FindElements(elementLocator);
if (elements.Count>0 && elements[0].Text.Equals(textToAppear, StringComparison.OrdinalIgnoreCase))
return true;
}
catch
{
return false;
}
return false;
}
// using the web driver extension.
bool textAppeared = WaitForTextToAppear(driver, By.CssSelector("selector-of-the-text-element"), "HERE IS THE EXPECTED TEXT");
I want to wait my selenium programe for max 30 seconds (GlobalVar.timetomaximumwait) with explicit wait.But when ever its unable to locate the element its pausing at wait.until(...) line and displaying OpenQA.Selenium.NoSuchElementException was unhandled by user code
If i press continue or press F10 its trying again to find the element and continuing the same for my defined time spam.
Not able to understand why the programme paused and the error message is coming in between.
I am using VS2010, c#, selenium 2.45,Ie 9
Any kind of help is much appreciated .
public string SetValueInTextBox(string InputData, string xPathVal)
{
try
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(GlobalVar.timetomaximumwait));
wait.Until<IWebElement>((d) =>
{
return d.FindElement(By.XPath(xPathVal));
});
IWebElement TargetElement = driver.FindElement(By.XPath(xPathVal));
// IWebElement TargetElement = driver.FindElement(By.XPath(xPathVal));
elementHighlight(TargetElement);
TargetElement.Clear();
TargetElement.SendKeys(InputData);
//driver.FindElement(By.XPath(xPathVal)).SendKeys(InputData);
return "Pass";
}
catch (Exception e)
{
return "Fail";
}
finally
{
// string SSName = "temp.jpg";
TakeScreenshot("SetValueInTextBox");
}
}
The problem lies here:
wait.Until<IWebElement>((d) =>
{
return d.FindElement(By.XPath(xPathVal));
});
You need to handle the exception that gets thrown when the element is not found.
wait.Until<IWebElement>((d) =>
{
try
{
return d.FindElement(By.XPath(xPathVal));
}
catch(NoSuchElementException e)
{
return null;
}
});
I would suggest adding in some logging into the catch block, so you know every time the driver fails to find the element.
How do i pause execution for my CS-Script, How to wait main calling thread.
i have a loop. but second iteration started without completion of the first iteration.
and second csscript executed.
foreach (var website in siteList)
{
try
{
string url = Common.GetWebSearchURL(website.ToUpper());
string webFile = Common.GetWebSearchURL(website.ToUpper() + "_SCRIPT");
CSScript.Evaluator.ReferenceAssembliesFromCode(webFile, true);
ICommon script = CSScript.Evaluator.LoadFile<ICommon>(webFile);
script.Run(ref pnlBroswer, website, url);
}
catch (Exception ex) { }
}
You could also have the script leave some evidence that it completed. It could output a value to a text file, or just create a file, whatever. You call the script, then check for that indicator until you find it (or decide to give up), then continue.
bool CheckFile() { return someFileContainsValue }
try
{
bool completed = false;
executeScript(); // will update a text file when complete
while(!completed)
{
completed = CheckFile();
}
}
Obviously an async version would be cleaner, but the principle is the same.
I have my program written in C#. It has label link. I need to define programmatically, when I click this link (programmatically too), if default browser opens the needed page.
C#
Process.Start("http://example.com"); // <-- put your url there.
Also see this short article on how to use that to greatest effect:
http://code.logos.com/blog/2008/01/using_processstart_to_link_to.html
In summary:
void OpenBrowser(string url)
{
try
{
Mouse.OverrideCursor = Cursors.AppStarting;
Process.Start(url);
}
catch (Exception)
{ //swallow: exception is sometimes thrown even though
} // the call completed without error
finally
{
Mouse.OverrideCursor = null;
}
}