Condition- assert using Selenium - 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.

Related

E2E testing multiple posibilities with exception

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
}

Unpredictable behaviour with Selenium and jUnit

I am working on a website and trying to test it with Selenium and jUnit. I'm getting race conditions between the test and the site, despite my best efforts.
The front end of the site is HTML and jQuery. The back end (via AJAX) is PHP.
The site
I have two required text input fields (year and age), plus some others that I'm not changing in the tests that give problems. As soon as both text inputs are non-empty, an AJAX call is made to the back end. This will return 0+ results. If 0 results are returned, a results div on the screen gets some text saying that there were no results. If >0 results are returned, a table is written to the results div showing the results.
I don't want the site to wait until e.g. 4 digits' worth of year is entered before doing the AJAX call as it could be looking at ancient history (yes, really). So, as soon as both are non-empty the call should be made. If you type slowly, this means that entering e.g. 2015 will trigger calls for year=2, year=20, year=201 and year=2015. (This is OK.)
The test
I'm using page objects - one for the inputs and one for the output. At the start of the test, I wait for a prompt to be present on the screen (please enter some data) as that is generated by JavaScript that checks the state of the input fields - so I know that the page has loaded and JavaScript has run.
The wait for a prompt is made immediately after the page object is created for the output. This is the relevant method in the page object:
// Wait until the prompt / help text is displayed. Assumes that the prompt text always contains the word "Please"
public void waitForText() {
wait.until(ExpectedConditions.textToBePresentInElementLocated(By.id("resultContainer"), "Please"));
}
The method for setting the year is
public void setYear(String year){
WebElement yearField = driver.findElement(By.id(yearInputId));
if (yearField == null) {
// This should never happen
Assert.fail("Can't find year input field using id " + yearInputId);
} else {
yearField.sendKeys(new String [] {year});
driver.findElement(By.id(ageInputId)).click(); // click somewhere else
}
}
and there's a corresponding one for age.
I have a series of methods that wait for things to happen, which don't seem to have prevented the problem (below). These do things like wait for the current result values to be different from a previous snapshot of them, wait for a certain number of results to be returned etc.
I create a driver for Chrome as follows:
import org.openqa.selenium.chrome.ChromeDriver;
// ...
case CHROME: {
System.setProperty("webdriver.chrome.driver", "C:\\path\\chromedriver.exe");
result = new ChromeDriver();
break;
}
The problem
Some of the time, things work OK. Some of the time, both inputs are filled in with sensible values by the test, but the "there are 0 results" message is displayed. Some of the time, the test hangs part-way through filling in the inputs. It seems to be fine when I'm testing with Firefox, but Chrome often fails.
The fact that there is unpredictable behaviour suggests that I'm not controlling all the things I need to (and / or my attempts to control things are wrong). I can't see that I'm doing anything particularly weird, so someone must have hit these kinds of issue before.
Is there a browser issue I'm not addressing?
Is there something I'm doing wrong in setting the values?
Is there something I'm doing wrong in my test choreography?
It could be that when you start typing, the script is still loading or that there's a pending Ajax call when you start handling the next field or validation.
You could try to synchronize the calls with a low level script :
const String JS_WAIT_NO_AJAX =
"var callback = arguments[0]; (function fn(){ " +
" if(window.$ && window.$.active == 0) " +
" return callback(); " +
" setTimeout(fn, 60); " +
"})();";
JavascriptExecutor js = (JavascriptExecutor)driver;
driver.manage().timeouts().setScriptTimeout(20, TimeUnit.SECONDS);
js.executeAsyncScript(JS_WAIT_NO_AJAX);
driver.findElement(By.Id("...")).sendKeys("...");
js.executeAsyncScript(JS_WAIT_NO_AJAX);
driver.findElement(By.Id("...")).click();

Fail Webdriver test if element is present

I'm new to Webdriver and I'm wondering how do I make my test case fail if an element is present. Using the following code I can send an output that if the element id errorMessages is present an output will be displayed. Is there anyway I can make the test fail also?
if (driver.findElements(By.id("errorMessages")).size() != 0) {
System.out.println("Error..Warning Subscriber already exists ");
}
With TestNG you can simply use Assert.fail("your message"); inside the if block to mark the test as failed. Something like:
if (driver.findElements(By.id("errorMessages")).size() != 0) {
Assert.fail("Error..Warning Subscriber already exists ");
}
See this for overloading
I think you are looking at it in the wrong way. Rather than checking if the size is what you expect and then forcing the test to fail, use the inbuilt assertion methods so it reads much more like a logical statement:
assertTrue(driver.findElements(By.id("errorMessages")).size() == 0, "Error..Warning Subscriber already exists");
Documentation from the TestNG site
The inbuilt assertion methods will then print out that message if that assertion fails.

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 );
}
}

unexpected behaviour in Appium

I am new in appium. I am running following test for IOS
#Test
public void Login() throws InterruptedException{
Thread.sleep(3000);
driver.findElement(By.xpath("//window[1]/textfield[9]")).sendKeys("john");
driver.findElement(By.xpath("//window[1]/secure[1]")).sendKeys("asdf1234");
driver.findElement(By.name("btn checkbox")).click();
driver.findElement(By.name("Login")).click();
Thread.sleep(6000);
here it works fine, it logins, but when I comment driver.findElement(By.name("btn checkbox")).click(); this line it does not login, but shows test is passed, there is no single exception
please can anybody tell me what is problem here?
It seems that your test doesn't check if it's logged in or not. You're performing the actions to make it login, but you're not actually validating anything. You're smoke testing.
What you want to do here...
Build something that lets you check for any indicator that you have finished the login process. (like welcome label!)
Use an explicit wait to do this.
Define your success criteria. Login usually takes 10 seconds. Our success criteria may be anything under 25 seconds.
If it doesn't find the element after 25 seconds in the exception that's thrown (TimeoutException), you should return something like "None", else return the element.
Should look something like this:
WebElement welcomeLabel = (new WebDriverWait(driver, 25))
.until(ExpectedConditions.presenceOfElementLocated(By.name("welcomeLabel")));
And then you'll say something like this:
Assert.assertIsNotNone(welcomeLabel) this assertion is what makes this NOT a smoke test
Of course that's happening. The only thing you do is clicking on that button. Appium is doing exactly that, doesn't encounter any problem, and returns a 'test passed'.
You have to write some kind of a test yourself, to know if you're logged in or not.
For example by searching for a logout button at the next page.
Example:
Assert.assertTrue(wd.findElement(By.name("Logout")).isDisplayed());