E2E testing multiple posibilities with exception - kotlin

i have a problem that i don't exactly know how to solve. I'm implementing an E2E test in which using selenium i need to click in a Link and check that is sending me to the right URL.
Here starts the problem...
There are 3 possibilities, mix of 2 types of links, just one type of link or the other type of link. No problems with the situations in which there are both types of links but when there is just one type when it searches for the identifier we use for the links that are not in page it gives me a timeoutException. This is not a failure because it's a posible situation but i will like to know if there is a way in which to check that if it finds no links it asserts that the exception is thrown.
I though using a runCatching (or try catch) wait for the link to appear and if it doesn't appear the test asserts that when i look for the element the timeout exception is thrown again.
It smells a bit for me this way of doing it and i don't know if it's correctly done.
EDIT: Im ussing AssertK and JUnit5 for testing.
EDIT 2: I've done this, i dont know if it a correct way of doing it
runCatching {
driver.waitFor(numberOfWidgetsToBeMoreThan(BrowserSelector.cssSelector(OFFERS_WITH_PRICE_AND_DATE), 0), ofMillis(2000))
}.onFailure {
assertThrows<WaitTimeoutException> {
findLink(OFFERS_WITH_PRICE_AND_DATE)
}
}.onSuccess {
val widget = findLink(OFFERS_WITH_PRICE_AND_DATE)
widget.click()
assertThat(driver.url).contains(NO_DATE_TEXT)
}

I'm not sure I understood your problem correctly, but you can use assertFails to assert that a piece of code throws an exception:
#Test
fun test() {
val exception = assertFails {
// some code that should throw
}
// some more assertions on the type of exception etc. may go here
}

Related

Exception flood using .await() when Single throws exception

I'm creating integration tests for my application using Spek. I have a set of Providers to test and each one makes a request and parses a response.
describe("Providers")
{
for(provider in providers)
{
on("Provider: $providerName")
{
try
{
//...
val responsePromise = when (provider)
{
is HtmlProvider -> connectionService.reactiveGetForHtml(connectionRequest)
is JsonProvider<*> -> connectionService.reactiveGetForJson(connectionRequest, provider.getJsonClass())
else -> throw IllegalStateException("Provider must be either Html or JSON")
}
val response = runBlocking { responsePromise.await() }
Both connectionService.reactiveGetForHtml() reactiveGetForJson() return a RxJava2's SingleSource.
The problem: one of Providers throws a bunch of exceptions (it has to parse a big JSON file and due to problems with data model Jackson throws huge number of exceptions). This is fine, test are designed to handle and report such errors. In this case, problematic Provider fails its own test with a Jackson exception. But, when runner executes remaining test cases, strange things happen. All next Providers' tests fail because of the same exceptions. runBlocking keeps throwing exceptions from faulty Provider on and on, no matter what responsePromise is. Don't know if this is a bug or some strange behaviour of .await(), but I don't hava any idea how to overcome this.
All test cases of Providers that don't throw multiple exceptions run well and report their own errors, but after executing that faulty Provider everything fails. It's not the case of this exact Provider, if I removed this particular test case, other Providers that thrown multiple exceptions caused simiar problem.

Spock & Spock Reports: how "catch" and customize the error message for AssertionError?

I am working with:
Spock Core
Spock Reports
Spock Spring
Spring MVC Testing
and I have the following code:
#FailsWith(java.lang.AssertionError.class)
def "findAll() Not Expected"(){
given:
url = PersonaUrlHelper.FINDALL;
when:
resultActions = mockMvc.perform(get(url)).andDo(print())
then:
resultActions.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_XML))
}
Here the code fails (how is expected) because the method being tested really returns (MediaType.APPLICATION_JSON) instead of (MediaType.APPLICATION_XML).
So that the reason of #FailsWith(java.lang.AssertionError.class).
Even if I use #FailsWith(value=java.lang.AssertionError.class, reason="JSON returned ...") I am not able to see the reason through Spock Reports
Question One: how I can see the reason on Spock Reports?.
I know Spock offers the thrown() method, therefore I am able to do:
then:
def e = thrown(IllegalArgumentException)
e.message == "Some expected error message"
println e.message
Sadly thrown does not work for AssertionError.
If I use thrown(AssertionError) the test method does not pass, unique way is through #FailsWith but I am not able to get the error message from AssertionError
Question Two how is possible get the Error Message from AssertionError?
I know I am able to do something like
then: "Something to show on Spock Reports"
But just curious if the question two can be resolved..
regarding Question one:
if you look at FailsWithExtension#visitFeatureAnnotation you can see that only value from the #FailsWith is evaluated, reason is not touched at all. What you could do is introduce you own type of annotation (custom one, e.g. same as #FailsWith) and override AbstractAnnotationDrivenExtension#visitFeatureAnnotation. There you have access to reason parameter.
regarding Question two:
please look at this link: http://spock-framework.3207229.n2.nabble.com/Validate-exception-message-with-FailsWith-td7573288.html
additionally maybe you could override AbstractAnnotationDrivenExtension#visitSpec and add custom listener (overriding AbstractRunListener). Then you have access to AbstractRunListener#error method whose documentation says:
Called for every error that occurs during a spec run. May be called multiple times for the same method, for example if both
* the expect-block and the cleanup-block of a feature method fail.
Didn't test for Question two, but it may work. I've used sth similar.
Enjoy,
Tommy

Condition- assert using Selenium

I want to write a script which can detect this message " System is not responding to your request. Kindly try after sometime." as shown in the screenshot below. When this message comes up then I want verify and send mail to the development team.
Snippet which I wrote for verification purpose but it is not working fine for me, pls suggest some alternative:
String s1 = d1.findElementByXPath(".//*[#id='showSearchResultDiv']").getText();
System.out.println(s1);
Remember to be careful when writing code for automation. If the scenario doesn't always show up, you cannot try and find an XPath, because you can't getText() if the object (based on the XPath) doesn't exist first. You probably need a try/catch around your code, and then put the println inside the try. This scenario will occur quite frequently, so you may want to write your own framework on top of WebDriver to handle these use cases.
If that is not the issue. Put a try/catch around the code that is failing to capture what the exception is.
You should try to wait for your element to appear before examining its text:
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if (d1.findElementByXPath(".//*[#id='showSearchResultDiv']").isDisplayed()) break; } catch (Exception e) {}
Thread.sleep(1000);
}
String s1 = d1.findElementByXPath(".//*[#id='showSearchResultDiv']").getText();
System.out.println(s1);
The exact code may be different, depending on the webpage you're testing (e.g. you should remove the 'fail' line if it's OK for the element not to appear every time.

Selenium: Handling exceptions for element that may not be present

I have a handful of pages where I want to look for an element, and if it is present, get the text. But I've run into a bit of a conundrum with respect to exception handling.
I can use WebDriverWait:
wait.until(EC.presence_of_element_located((By.XPATH, '//div[#class="className"]')))
But if this throws an exception, I technically have no way of knowing whether it occurred because the element is in fact not present on the page, or because of something else (e.g. I didn't wait long enough or there's some other error in the code).
In my particular case I've been able to deal with this so far by using the presence of some other elements on the page to infer whether the one I'm looking for will be present. However, I am bound to run into some pages where I can't use other elements as proxies.
Is there any way for me to distinguish between an exception caused by the element actually not being in the page source versus some other reason?
You should specify the Exception you want to catch and then do something in the catchblock, refer to the Java Doc here to give you more insight on exceptions
http://selenium.googlecode.com/git/docs/api/java/index.html
public void aMethod() {
try {
//do someting
} catch( Exception e ) {
textLog( "Element not present -------" );
detailedText( e );
}
}

PHP Error handling: die() Vs trigger_error() Vs throw Exception

In regards to Error handling in PHP -- As far I know there are 3 styles:
die()or exit() style:
$con = mysql_connect("localhost","root","password");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
throw Exception style:
if (!function_exists('curl_init')) {
throw new Exception('need the CURL PHP extension.
Recomplie PHP with curl');
}
trigger_error() style:
if(!is_array($config) && isset($config)) {
trigger_error('Error: config is not an array or is not set', E_USER_ERROR);
}
Now, in the PHP manual all three methods are used.
What I want to know is which style should I prefer & why?
Are these 3 drop in replacements of each other & therefore can be used interchangeably?
Slightly OT: Is it just me or everyone thinks PHP error handling options are just too many to the extent it confuses php developers?
The first one should never be used in production code, since it's transporting information irrelevant to end-users (a user can't do anything about "Cannot connect to database").
You throw Exceptions if you know that at a certain critical code point, your application can fail and you want your code to recover across multiple call-levels.
trigger_error() lets you fine-grain error reporting (by using different levels of error messages) and you can hide those errors from end-users (using set_error_handler()) but still have them be displayed to you during testing.
Also trigger_error() can produce non-fatal messages important during development that can be suppressed in production code using a custom error handler. You can produce fatal errors, too (E_USER_ERROR) but those aren't recoverable. If you trigger one of those, program execution stops at that point. This is why, for fatal errors, Exceptions should be used. This way, you'll have more control over your program's flow:
// Example (pseudo-code for db queries):
$db->query('START TRANSACTION');
try {
while ($row = gather_data()) {
$db->query('INSERT INTO `table` (`foo`,`bar`) VALUES(?,?)', ...);
}
$db->query('COMMIT');
} catch(Exception $e) {
$db->query('ROLLBACK');
}
Here, if gather_data() just plain croaked (using E_USER_ERROR or die()) there's a chance, previous INSERT statements would have made it into your database, even if not desired and you'd have no control over what's to happen next.
I usually use the first way for simple debugging in development code. It is not recommended for production. The best way is to throw an exception, which you can catch in other parts of the program and do some error handling on.
The three styles are not drop-in replacements for each other. The first one is not an error at all, but just a way to stop the script and output some debugging info for you to manually parse. The second one is not an error per se, but will be converted into an error if you don't catch it. The last one is triggering a real error in the PHP engine which will be handled according to the configuration of your PHP environment (in some cases shown to the user, in other cases just logged to a file or not saved at all).