I want to get a result from the website when I submit a form. There are several things that can go wrong.
In a simple scenario I want to return:
true
- when form was submitted
false
- when form wasn't submitted
null
- when we don't know if form was submitted or not
I did that ugly try
, because of NullReferenceException
(if form is filled correctly, there would be no summary
element, and if form is filled incorrectly, there would be no popup
element).
How can I make this more elegant?
public bool? GetResult(TimeSpan timeout)
{
var deadline = DateTime.Now.Add(timeout);
do
{
// check if success
try
{
var success = new WebDriverWait(Driver, TimeSpan.FromSeconds(5))
.Until(ExpectedConditions.TextToBePresentInElement(Driver.FindElement(By.Id("summary")), "Success!"));
if (success) return true;
}
catch (Exception ex)
{ }
// check if not enough data
try
{
var notEnoughData = new WebDriverWait(Driver, TimeSpan.FromSeconds(5))
.Until(ExpectedConditions.TextToBePresentInElement(Driver.FindElement(By.Id("popup")), "Not enough data"));
if (notEnoughData) return false;
}
catch (Exception ex)
{ }
// check if too much data
try
{
var tooMuchData = new WebDriverWait(Driver, TimeSpan.FromSeconds(5))
.Until(ExpectedConditions.TextToBePresentInElement(Driver.FindElement(By.Id("popup")), "Too much data"));
if (tooMuchData) return false;
}
catch (Exception ex)
{ }
// check if empty data
try
{
var tooMuchData = new WebDriverWait(Driver, TimeSpan.FromSeconds(5))
.Until(ExpectedConditions.TextToBePresentInElement(Driver.FindElement(By.Id("popup")), "Empty data"));
if (tooMuchData) return false;
}
catch (Exception ex)
{ }
} while (DateTime.Now > deadline);
return null;
}
1 Answer 1
I did that ugly try, because of NullReferenceException (if form is filled correctly, there would be no summary element, and if form is filled incorrectly, there would be no popup element).
This problem can be easyly handled by a null
check of the returned WebElement
from the call to Driver.FindElement()
.
A little bit more problematic is IMO the looping condition because the condition only could evaluate to true
if the passed TimeSpan
is negativ. If this is what you want you really should place a comment there. If you didn't mean to pass a negative timespan then you should reverse the looping condition to DateTime.Now < deadline
.
Extracting the repeated call to TimeSpan.FromSeconds(5)
to a variable will make the code easier to read.
You know although copy & pasta will save time, you need to check if the pasted code is correct (empty data vs tooMuchData)
// check if empty data try { var tooMuchData = new WebDriverWait(Driver, TimeSpan.FromSeconds(5)) .Until(ExpectedConditions.TextToBePresentInElement(Driver.FindElement(By.Id("popup")), "Empty data")); if (tooMuchData) return false;
Implementing the mentioned points will look like so
public bool? GetResult(TimeSpan timeout)
{
var deadline = DateTime.Now.Add(timeout);
var waitTimeout = TimeSpan.FromSeconds(5);
do
{
WebElement summaryWebElement = Driver.FindElement(By.Id("summary"));
if (summaryWebElement != null)
{
var success = new WebDriverWait(Driver, waitTimeout).Until(ExpectedConditions.TextToBePresentInElement(summaryWebElement , "Success!"));
if (success) return true;
}
WebElement popupWebElement = Driver.FindElement(By.Id("popup"));
if (popupWebelement != null)
{
var notEnoughData = new WebDriverWait(Driver, waitTimeout).Until(ExpectedConditions.TextToBePresentInElement(popupWebElement, "Not enough data"));
if (notEnoughData) return false;
var tooMuchData = new WebDriverWait(Driver, waitTimeout).Until(ExpectedConditions.TextToBePresentInElement(popupWebelement, "Too much data"));
if (tooMuchData) return false;
var emptyData = new WebDriverWait(Driver, waitTimeout).Until(ExpectedConditions.TextToBePresentInElement(popupWebElement, "Empty data"));
if (emptyData) return false;
}
} while (DateTime.Now > deadline);
return null;
}
Because the checks for the popup text only differs from the expected text you could think about using a foreach loop over an array containing the expected strings.
-
\$\begingroup\$ the only thing I would change is to get rid of that DateTime for checking elapsed time. \$\endgroup\$dfhwze– dfhwze2019年06月07日 04:31:07 +00:00Commented Jun 7, 2019 at 4:31
WebDriverWait
(so we can review async operations on it) andDriver
(so we can try to avoid null reference exceptions). And useStopWatch
for verifying elapsed time. \$\endgroup\$WebDriverWait
is part of Selenium api: seleniumhq.org/docs/04_webdriver_advanced.jsp. \$\endgroup\$