I have an issue finding i good way of checking if an element is present.
I´m using Page Object Model when automating my test cases meaning i declare all elements in a specific class, and not in the actual [tests]. How can i transform this simple method for verifying declared elements like this:
private IWebElement LoginButton => driver.FindElement(By.Id("LoginButton"));
IsElementPresent(IWebElement element)
{
try
{
//Something something
}
catch(NoSuchElementException)
{
return false;
}
return true;
}
I had a similar issue not long ago:
Managed to include a retry strategy/policy in it, so I'm waiting for the element to exist in the DOM.
public static void WaitForElementToExistInDom(Func<IWebElement> action)
{
RetryPolicy.Do(() =>
{
if (!DoesElementExistInDom(action))
throw new RetryPolicyException();
}, TimeSpan.FromMilliseconds(Timeouts.DefaultTimeSpanInMilliseconds), TestConstants.DefaultRetryCount);
}
public static bool DoesElementExistInDom(Func<IWebElement> action)
{
var doesExist = false;
try
{
var element = action.Invoke();
if (element != null)
doesExist = true;
}
catch (StaleElementReferenceException)
{
}
catch (NullReferenceException)
{
}
catch (NoSuchElementException)
{
}
return doesExist;
}
And you can call it like this:
WebDriverExtensionMethods.WaitForElementToExistInDom(() => Map.YourElement);
If the element is stalled or not existing, internally we're going to handle the exceptions and try again.
And because the evaluation 'if the element exists in the DOM' is done when you're getting calling the element from the MAP, we're wrapping it in an Action/Func, this way the evaluation is done in method (and so the catching of the exceptions), you don't have to use find selector outside of the element map itself.
I think you are looking for something simple like
public bool ElementExists(By locator)
{
return Driver.FindElements(locator).Any();
}
You would call it like
if (ElementExists(By.Id("LoginButton")))
{
// do something
}
You can't pass in an element because in order to pass it in, you would have to locate it first which would not be possible (it would throw an exception) if it's not present.
If you are trying to check an existing element, you could do something like the below.
public bool ElementExists(IWebElement e)
{
try
{
bool b = e.Displayed;
return true;
}
catch (Exception)
{
return false;
}
}
Related
I'm trying to create a script where I can check if the element is or is not displayed on the UWP app. I have a methods that checks if the element is Displayed or Not Displayed..
if the element is actually displayed and I called the "IsElementDisplayed", the test seems to works fine and continue the test execution.. But when the element is really NOT displayed and I called the "IsElementDisplayed", It doesn't return false boolean value.. but it just stops the test execution and says, "no such given parameters found"...
Please check my sample code....
I have a class which contains my locators and returns the instance of WindowsElement:
protected WindowsElement Id(string id)
{
return Driver.FindElementById(id);
}
protected WindowsElement XPath(string xpath)
{
return Driver.FindElementByXPath(xpath);
}
protected WindowsElement Name(string name)
{
return Driver.FindElementByName(name);
}
protected WindowsElement AccessibilityId(string id)
{
return Driver.FindElementByAccessibilityId(id);
}
and then I have Page class which contains properties of my elements.. sample code below:
public WindowsElement SaveObligation_Btn => this.AccessibilityId("OBLGTN_saveObligation_btn");
public WindowsElement CancelObligation_Btn => this.AccessibilityId("OBLGTN_CancelObligation_btn");
public WindowsElement ObligationAdd_Btn => this.AccessibilityId("SMMRY_AddObligation_btn");
And lastly I have a testhelper class that contains methods such as:
public bool IsNotDisplayed(WindowsElement element)
{
try
{
Assert.IsFalse(element.Displayed, $"Element: {element} is not displayed on the page!");
return false;
}
catch (Exception)
{
return true;
}
}
but when I trying to call the "IsNotDisplayed" method to return false if it caught any exceptions.., My test execution stops and I will have an error that is pointing to my Locator class and says, the "element is NOT found with the given parameters"...
I expect the method "isNotDisplayed" should return false boolean value, so I can validate if the element is visible or not.
I'm not familiar with C#.
But in Python, I will write like this:
try:
element = //find your element
if element.is_displayed():
return True
else:
raise AssertionError
except Exception:
return False
first question is what you want to do when noElementIsDisplayed? Of course, it will catch some exceptions. In your scenario, if you do not want to do anything when exception thrown then you should leave catch block empty.
try the following code:
public bool IsNotDisplayed(WindowsElement element)
{
try
{
Assert.IsFalse(element.Displayed, $"Element: {element} is not displayed on the page!");
return false;
}
catch (Exception e)
{
// do nothing and it will continue your script.
}
}
This will return true if the element is displayed else it will return false.
C# Code
public bool IsNotDisplayed(WindowsElement element)
{
try
{
element.Displayed;
}
catch (Exception)
{
return false;
}
return true;
}
Java Code
public static boolean IsDispayed(WebElement webelement)
{
try {
webelement.isDisplayed();
} catch (Exception e) {
return false;
}
return true;
}
Python Code
try:
element = driver.find_element_by_xpath('XPATH')
if element.is_displayed():
return True
else:
raise AssertionError
except Exception:
return False
Try the below code for c#. This is an alternative..
private bool IsElementPresent(By by)
{
try
{
driver.FindElement(by);
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
I have this method:
public object LongRunningTask()
{
return SomethingThatTakesTooLong();
}
I wrote the following code so I can transform a normal method in an async one and still get the Exception:
public async Task<object> LongRunningTaskAsync()
{
Exception ex = null;
object ret = await Task.Run(() =>
{
object r = null;
try
{
//The actual body of the method
r = SomethingThatTakesTooLong();
}
catch (Exception e)
{
ex = e;
}
return r;
});
if (ex == null)
return ret;
else
throw ex;
}
When I need to do this in several methods, I have to copy all this code and change only the middle.
Is there a way to do something like this?
[SomeAttributeThatDoesThatMagically]
public async Task<object> LongRunningTaskAsync()
{
return SomethingThatTakesTooLong();
}
Attributes are generally metadata though it is possible to define attributes that can be executed (such as security behaviours in WCF) however, something has to be looking for it first. Your attributes won't just magically run.
I suspect you might have to use a dynamic proxy.
Take a look at how WCF does things for ideas.
I have two identical methods, but one of them have return statement inside try catch
public void A(Guid agentId)
{
var agent = _agentsProvider.GetAgentById(agentId);
var updateCompletionSource = C(agentId);
try
{
var cacheEntry = UpdateAgentMetadataCacheEntry(agent, true, false);
updateCompletionSource.SetResult(cacheEntry);
}
catch (Exception e)
{
updateCompletionSource.SetException(e);
}
}
private Entry B(IAgent agent)
{
var updateCompletionSource = C(agent.Id);
try
{
var cacheEntry = UpdateAgentMetadataCacheEntry(agent, false, false);
updateCompletionSource.SetResult(cacheEntry);
return cacheEntry;
}
catch (Exception e)
{
updateCompletionSource.SetException(e);
return GetPreviousCacheEntry();
}
}
How to collect identical part and create new method with this part?
Unless GetPreviousCacheEntry could have problematic side-effects, it seems to me that you don't need method A at all.
Just call method B and ignore the return value if you're not interested in it.
As noted in comments, the methods aren't identical other than the return statements though - because they use a different second argument for UpdateAgentMetadataCacheEntry, and they have different parameters too (one has a Guid and one has an Agent). You could refactor this into:
private Entry B(IAgent agent, bool foo)
{
var updateCompletionSource = C(agent.Id);
try
{
var cacheEntry = UpdateAgentMetadataCacheEntry(agent, foo, false);
updateCompletionSource.SetResult(cacheEntry);
return cacheEntry;
}
catch (Exception e)
{
updateCompletionSource.SetException(e);
return GetPreviousCacheEntry();
}
}
... with a meaningful name for foo, obviously. I'll assume the difference in parameter type isn't a problem in reality.
Like Jon said, you don't need method A. Just add another parameter for boolean value.
public void A(Guid agentId)
{
var agent = _agentsProvider.GetAgentById(agentId);
AnotherA(agent, true);
}
private Entry B(IAgent agent)
{
return AnotherA(agent, false);
}
private Entry AnotherA(IAgent agent, bool a)
{
try
{
var cacheEntry = UpdateAgentMetadataCacheEntry(agent, a, false);
updateCompletionSource.SetResult(cacheEntry);
return cacheEntry;
}
catch (Exception e)
{
updateCompletionSource.SetException(e);
return GetPreviousCacheEntry();
}
}
I am trying to find the cleanest solution for returning value or error message from function / method in c#.
For now I have tried:
public float ValidateValue (float value)
{
if (value == VALID_VALUE)
{
return value;
}
else
{
throw new ArgumentException("Invalid value", "value");
}
}
This solution seems to be good enough but in Clean Code Cheap Sheet I have found:
Using Exceptions for Control Flow – Don't do this
Using exceptions for control flow:
has bad performance, is hard to understand and results in very hard
handling of real exceptional cases.
What will you do in the case of invalid input?
If you are writing code at the UI level that is taking the input from the user then it makes most sense to do something like:
private bool IsValid(float value)
{
return value == VALID_VALUE; // replace with real check.
}
Then in the calling code you would have:
public void ReactToInput()
{
float value = HoweverYouGetTheFloatFromTheUser();
if(!IsValid)
{
//Code to display error message.
}
else
{
//Code to do something useful.
//
//Code to display result.
}
}
Because your job at this level is "take what the user gave me, return what they want as best I can" and at this level its best to have the possibility of the user doing something incorrect front and centre.
If you are writing code for other code to make use of, then it makes most sense to do something like:
private void CheckValid(float valid)
{
if(value != VALID_VALUE) // replace with real check.
throw new ArgumentException();
}
Then in the calling code you would have:
public float DoWork(float value)
{
CheckValid(value)
//Code to do something useful.
//
//Code to return result.
}
Here your job is to do what the method's task is cleanly and return a meaninful result (or void if there isn't one). If you can't do that job, because the input you were given is nonsense (or for any other reason) then you need to stop as soon as you can and deal with that problem. You could do this by returning an error/success code every time and having calling code checking it every time, but while this approach does indeed have some advantages, exceptions let us:
Write with a focus on the correct behaviour.
Pass up exceptions.
For an example of 1, compare:
private bool WithExceptions()
{
return A() > B() && C() > D();
}
private bool WithExplicitChecks(out bool result)
{
result = false;
int a;
int b;
if(!A(out a))
return false;
if(!B(out b))
return false;
if(a <= b)
return true;
int c;
int d;
if(!C(out c))
return false;
if(!D(out d))
return false;
result = c > d;
return true;
}
For an example of 2, consider:
private void A()
{
if(_someField == null)
throw new InvalidOperationException("field not ready");
_someField.DoSomething();
}
private void B()
{
A();
}
private void C()
{
B();
}
private string D()
{
try
{
C();
}
catch(InvalidOperationException)
{
Console.Error.WriteLine("Was not ready");
}
}
Obviously a real case would have B() and C() do more, but we can see here that only A() has to worry about raising exceptions and only D() about dealing with them, B() and C() can both just concentrate on the main concern.*
The two approaches can be mixed. Consider:
private static string CheckValid(string path)
{
if(path.Length == 0)
return "You cannot enter an empty file path";
switch(path[path.Length - 1])
{
case '\\':
case '/':
return "You cannot enter a directory path";
}
return null;
}
public static void Main(string[] args)
{
Console.WriteLine("Enter a file path");
var path = Console.ReadLine().Trim();
var validationError = CheckValid(path);
if(validationError != null)
Console.Error.WriteLine(validationError);
else
{
try
{
using(var reader = new StreamReader(path))
Console.WriteLine(reader.ReadToEnd());
}
catch(FileNotFoundException)
{
Console.Error.WriteLine("File not found");
}
catch(UnauthorizedAccessException)
{
Console.Error.WriteLine("Access denied");
}
catch(IOException ioe)
{
Console.Error.WriteLine(string.Format("I/O Exception: {0}", ioe.Message));
}
}
Console.Read();
}
This simple program takes a file path from the user, and opens the relevant file and outputs the contents as text. It takes both approaches to error-handling.
Because we can easily check for invalid input that is empty, or which ends with / or \, that is done with simple control-flow and we present an error message instead of doing something.
Other issues we can only know about by trying to open the file and failing, so in those cases we handle the exceptions. I combine both explicit checks for two types of problem along with one for a general class of problems, and act accordingly.
There is a third type of exception handling here; if an exception happens that I don't expect at all, the program fails with a exception message being dumped for debugging purposes. This is the case anywhere you don't catch all exceptions, but a very useful one; because I don't have a blanket catch or catch(Exception) I don't confuse exceptions I'm expecting to deal with (go me for handling them!) with exceptions that are there because I made a mistake in not realising they could happen (boo me! now I have to fix it).
This is a simple program that takes a file path from the user, and outputs the contents of the file. Note that it combines both approaches:
*Do though always consider that something started in a method may not be finished if an exception busts through it.
If you want to validate some input value, I would expect a bool to be returned indicating 'valid' or 'invalid', or no return value and an exception thrown when the value is invalid.
So I would suggest to use this:
public bool ValidateValue(float value)
{
return value == VALID_VALUE;
}
Or this:
public void ValidateValue(float value)
{
if (value != VALID_VALUE)
{
throw new ArgumentException("Invalid value", "value");
}
}
So throwing an exception is not a problem, especially when there are multiple reasons to reject, and you want to distinguish the various reasons. Otherwise, just use a bool, like int.TryParse does for example.
A tuple may be useful to solve that issue:
public Tuple<float,string> ValidateValue (float value)
if (value == VALID_VALUE)
{
return new Tuple<bool, string>(value,string.Empty);
}
else
{
return new Tuple<bool, string>(false,"Invalid value");
}
When calling a function, check if the error string is empty first:
var validation = ValidateValue(myFloatValue);
if (validation.Item2 != string.Empty)
{
// report error
}
else
{
// No error core here validation.Item1 is your result
}
One idea could be to have some generic model. You may have some model roughly like:
public class MyReturnModel
{
public bool Success { get; set; }
public string ErrorOrSuccessMessage { get; set; }
public dynamic AnyModelToReturn { get; set; }
}
Now let's apply this on your provided case:
public MyReturnModel ValidateValue(float value)
{
//function logic here
bool result = value == VALID_VALUE;
string msg = result ? "valud is valid" : "value is invalid";
return new MyReturnModel { Success = result, ErrorOrSuccessMessage = msg }
}
What strategy do you use to give to the user the reason why a certain method "failed"
Exemple:
public List<Balance> GetBalanceFinale(Periode periode)
{
if (periode == null || periode.DateStart >= DateTime.Now || isBalanceFinished(periode.PeriodeID))
return null;
//My other code...
}
I want to tell the user which of the steps went wrong. I don't want to use a messagebox in such class. I can't return the description of the failure because I already return something.
What do you usally do? Any advice? Thanks!
You can throw an exception with a descriptive message.
Consider throwing exceptions instead of returning null.
In this case you will be able to provide descriptive information with each exception, which later can be properly handled and presented to the caller.
I am assuming you don't want to throw an exception otherwise you would've already done that. Something like an alert / warning without stopping execution of the program. In that case, you can still use an exception, just don't throw it, instead pass it as an out parameter or put it somewhere where the user can access it if desired. If that seems over the top then just use a message instead.
Also framing it as a 'Try' method might be a good idea. It makes it very clear that the method is prone to failure under certain conditions.
These are all different options:
public bool TryGetBalanceFinale(Periode periode, out List<Balance> list, out string msg)
{
// return false if anything is wrong, and have an out parameter for the result & msg
}
public bool TryGetBalanceFinale(Periode periode, out List<Balance> list, out Exception ex)
{
// return false if anything is wrong, and have an out parameter for the exception
}
These first two above are my two preferred approaches. The following are possibilities as well, however they are somewhat non-standard:
public Tuple<string, bool> TryGetBalanceFinale(Periode periode, out List<Balance> list)
{
// return false if anything is wrong, and include message in the returned Tuple
}
// an anonymous type approach
public object TryGetBalanceFinale(Periode periode, out List<Balance> list)
{
return new {
Successful = false,
Message = // reason why here
};
}
// a functional approach
public List<Balance> list GetBalanceFinale(Periode periode, Action<String> messageAct)
{
// when something is wrong, do:
messageAct("Something went wrong...");
}
I think the 'Try' strategy makes the most sense when you consider how it will be used:
string message;
List<Balance> result;
if (!TryGetBalanceFinale(periode, out result, out message))
{
// examine the msg because you know the method failed
Console.WriteLine(message);
}
else
{
// you know the method succeeded, so use the result
Console.WriteLine("The result is: " + result.ToString());
}
I like to wrap my results in a ResultState<T> object (usually for Json or Xml serialization). Might be helpful if you are building a framework for someone else to consume as each result can be handled the same way by the consumer.
public class ResultState<T>
{
public T ResultValue { get; set; }
public Exception ExceptionThrown { get; set; }
public bool IsValid { get; set; }
public string FriendlySummary { get; set; }
// whatever else properties you think are needed
}
public interface IResultState<T>
{
public T ResultValue { get; }
public Exception ExceptionThrown { get; }
public bool IsValid { get; }
public string FriendlySummary { get; }
// whatever else properties you think are needed
}
public IResultState<List<Balance>> GetBalanceFinale(Periode periode)
{
ResultState<List<Balance>> result = new ResultState<List<Balance>>();
try
{
if (periode == null
|| periode.DateStart >= DateTime.Now
|| isBalanceFinished(periode.PeriodeID))
{
result.IsValid = false;
result.FriendlySummary = "Periode is in an invalid state.";
}
//My other code...
result.ResultValue = new List<Balance>();
result.ResultValue.Add(...);
}
catch(Exception ex)
{
result.IsValid = false;
result.Exception = ex;
// Ambigious is bad.. so for bad example..
result.FriendlySummary = "An unknown exception happened.";
}
}
An alternative that has worked for me in the past is the Notification pattern.
This is a way of getting information out of your domain layer and up into the presentation. For example, create something like this:
public class Notification
{
public List<Message> Messages;
public bool HasMessages;
// etc
}
and use an instance of it as a property on your domain.
You can then do something like this:
myDomain.GetBalanceFinale(periode);
if(myDomain.Notification.HasMessages)
// get the messages and do something with them
You need to re-factor your code first. before calling GetBalanceFinale you can validate it and show proper message if validation failed. if validation pass you can call GetBalanceFinale method.
Sometimes you may not able to do all the validation before calling the method. in that case you can throw exception with proper message or use out parameters.
If I need to return a value and a message, I just use an out parameter.
public List<Balance> GetBalanceFinale(Periode periode, out string errorMessage)
{
if (periode == null)
{
errorMessage = "Periode is null";
return null;
}
// Other checks
}
Then just call it like
string errorMessage;
var value = GetBalanceFinale(periode, out errorMessage);
if(value == null)
// Do whatever with errorMessage
You can decompose your logic into 3 separate tests, and then define an 'out' argument to return the "reason"
public List<Balance> GetBalanceFinale(Periode periode, out string reasonFailed)
{
reasonFailed = false;
if (periode == null)
{
reasonFailed = "preiod is null";
return null;
}
// etc.....
//periode.DateStart >= DateTime.Now || isBalanceFinished(periode.PeriodeID))
//My other code...
}