Getting ElementNotFound Exception in TestNG - selenium-webdriver

The following code is for login and then click on Create quest Link. It does not click on the link and gives ElementNotFound exception and skips the test. It just logs in and logout. Please Help
public class Edit_Question {
WebDriver driver = new FirefoxDriver();#
BeforeTest
public void load() {
driver.get("Page url");
}
# Test
public void login() throws InterruptedException {
driver.findElement(By.id("userid")).sendKeys("4060#jhg.com");
driver.findElement(By.id("password")).sendKeys("mpcyn2");
driver.findElement(By.id("emLoginLink")).click();
Thread.sleep(10000);
}# Test
public void ques() throws InterruptedException {
//select create questions
driver.findElement(By.xpath("//xpath link")).click(); //throws ElementNotFound exception
Thread.sleep(5000);
}# Test
public void logout() {
//logout
driver.findElement(By.partialLinkText("SeeharackTest1, SherrodUATT")).click();
driver.findElement(By.id("logoutLink")).click();
}
# AfterSuite
public void close() {
driver.close();
}
}

The order of execution is not gauranteed. You need to use dependOnMethods to gaurantee order here. So ques should depend on login and logout should depend on ques to gaurantee the order of execution.
Other observations :
1. Try using #BeforeClass instead of #BeforeTest and #AfterClass instead of #AfterSuite
2. Avoid using sleeps wherever possible. Wait for a particular element instead.
3. Shouldn't this entire flow be one testcase?
Hope it helps.

Related

How to cancel delete using AbstractMongoEventListener?

Can I cancel delete event using onBeforeDelete method of MongoGenreCancelDeleteEventsListener? If yes then how?
#Component
public class MongoGenreCancelDeleteEventsListener extends AbstractMongoEventListener<Genre> {
private final BookRepository bookRepository;
#Override
public void onBeforeDelete(BeforeDeleteEvent<Genre> event) {
super.onBeforeDelete(event);
// check conditions and cancel delete
}
}
I know this is an old question, but I had the same issue and I found a solution.
Basically, your code should become like this:
#Component
public class MongoGenreCancelDeleteEventsListener extends AbstractMongoEventListener<Genre> {
private BookRepository bookRepository;
#Override
public void onBeforeDelete(BeforeDeleteEvent<Genre> event) {
super.onBeforeDelete(event);
boolean abort = false;
//do your check and set abort to true if necessary
if (abort) {
throw new IllegalStateException(); //or any exception you like
}
}
}
The thrown exception prevents the operation from going further and it stops there. Also, the exception gets propagated to the caller (anyway, it is wrapped inside a UndeclaredThrowableException, so this is what you should catch; make sure that the wrapped exception is indeed the one you've thrown by calling the getCause() method).
Hope it helps.

My XML file doesn't seem to be pushing the values to my code. Causing my tests to be skipped

I am setting up test cases for practice and trying to feed the parameters from an XML file for the website url, and the desired browser if available. The Switch logic, and webdriver commands look solid, but maybe i missed something that makes it skip them entirely. Should output that login was successful on both occasions.
In the past I've simply fed the data in as variables, this is my first try with xml handling the data injection.
public class NewTest {
WebDriver driver;
#Test(dataProvider="getData")
public void login(String username,String password)
{
//Code to Login to the application
driver.findElement(By.xpath("//*[#id=\'myNavbar\']/ul/li[4]/a")).click();
driver.findElement(By.id("usernameLogin")).sendKeys(username);
driver.findElement(By.id("passwordLogin")).sendKeys(password);
driver.findElement(By.id("login")).click();
try
{
//verifying the presence of webelement
````````````````````````````````````````````
new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.id("topMenu2")));
System.out.println("login success");
}
catch(Exception e)
{
System.out.println("Login failure");
}
driver.findElement(By.id("topMenu2")).click();
}
#DataProvider
public Object[][]getData() {
Object[][]data=new Object[2][2];
data[0][0]="pgGru";
data[0][1]="freezeray";
data[1][0]="pgAlmacho";
data[1][1]="freezeray";
return data;
}
#BeforeSuite
#Parameters({ "browsername", "url" })
public void setup(#Optional("Firefox")String browsername,String url) {
switch (browsername) {
case "IE":
WebDriver driver1;
driver1 = new InternetExplorerDriver();
System.setProperty("webdriver.IEDriverServer.driver", "D:\\Jarrrs\\Drivers\\IEDriverServer_win32");
driver1.get(url);
break;
case "Firefox":
WebDriver driver2;
driver2 = new FirefoxDriver();
System.setProperty("webdriver.geckodriver.driver","D:\\Jarrrs\\Drivers\\gecfkoDriver_win32");
driver2.get(url);
break;
case "chrome":
WebDriver driver3;
driver3 = new ChromeDriver();
System.setProperty("webdriver.chrome.driver, ","D:\\Jarrrs\\Drivers\\chromedriver_win32\\chromedriver.exe");
driver3.get(url);
break;
}
}
#AfterSuite
public void tearDown() {
driver.quit();
}
}
Right now the output is it is skipping the test cases for login and password
Expecting two passed or failed tests. Either one would be nice.
Newbie here. What do you mean by test is skipping? Are the actions within login() not being executed? I would put sys.out statements withing login() to check if the code is getting executed. How about adding a pause after page load? How about adding hardcoded value to username and password field to check if it is working fine?
Some times certain fields cannot be set by using Selenium's sendkeys. Need to use JavascriptExecutor to set the field values

Selenium Webdriver Testng : How to fail a test in assertion and send meaningful message in a report instead of "Nosuchelementexception" trace

Their are numerous resources on internet but I couldn't find a simple answer to my problem.
I want my test case to fail and report a one liner meaningful message instead of full stack trace.
I tried using try, catch, if, else but I want my test to fail not to pass and throw message.
Scenario - Load url, if url doesn't load throw error and abort test and move to next iteration of loading next url
Any solution ?
You can try... try catch
try {
doStuff();//this code is failing
}
catch (YourExpectedException e){ //catch the correct exception here
//this passes your custom message AND the caught exception
//should also stop the test
throw new AssertionError("This is my custom message", e);
}
There are two ways how to do it. I would like to suggest you the most simple and beautiful ways.
1) Checking exception and if exception on of you specify you will execute some code or do something. Here is the example:
#AfterMethod
public void afterMethod(ITestResult result) throws IOException {
Throwable exception = result.getThrowable();
if (exception instanceof org.openqa.selenium.TimeoutException
||
exception instanceof org.openqa.selenium. NoSuchElementException) {
Assert.fail("Some message or code");
}
}
2)
You can implement WebDriverEventListener in your project.
What it means?
It means that WebDriver allow to execute some logic before and after some events. You can add try-catch in the implementation of methods.
Example:
#Override
public void beforeFindBy(By by, WebElement webElement, WebDriver webDriver) {
// your code
}
#Override
public void afterFindBy(By by, WebElement webElement, WebDriver webDriver) {
// your code
}
#Override
public void beforeClickOn(WebElement webElement, WebDriver webDriver) {
// your code
}
#Override
public void afterClickOn(WebElement webElement, WebDriver webDriver) {
// your code
}
Here is more detail example: link

cucumber giving null pointer exception with multiple scenario in feature file

Test Steps
public class TestSmoke {
WebDriver driver;
#Given("^open firefox and start application$")jjj
public void open_firefox_and_start_application() throws Throwable {
driver=new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
driver.get("https://example.com");
}
**Scenario 1**
#When("^I click on Login$")
public void I_click_on_Login() throws Throwable {
driver.findElement(By.xpath("//a[contains(.,'Login')]")).click();
}
#When("^enter valid \"([^\"]*)\" and valid \"([^\"]*)\"$")
public void enter_valid_and_valid(String uname, String pass) throws Throwable {
driver.findElement(By.id("Username")).sendKeys(uname);
driver.findElement(By.id("Password")).sendKeys(pass);
}
#Then("^Click on login and User should be able to login successfully$")
public void Click_on_login_and_User_should_be_able_to_login_successfully() throws Throwable {
driver.findElement(By.id("loginUser")).click();
}
jkjbjkkjhjknjkbjkhjkbjbjbbjbnmbbnmb
**Scenario 2:**
#Given("^Click on shop for carts$")
public void Click_on_shop_for_carts() throws Throwable {
hhjbhbhgjbkjbhlhihjbhbb
driver.findElement(By.xpath("//span[text()='Shop for Parts']")).click();
}
#Given("^select plates$")
public void select_plates() throws Throwable {
driver.findElement(By.xpath("//a[contains(.,'Plates ')]")).click();
}
#When("^I click on drsired product$")
public void I_click_on_drsired_product() throws Throwable {
driver.findElement(By.xpath("//a[#data-itemnumber='PLT01096096046']")).click();
}
#When("^click on item increment$")
public void click_on_item_increment() throws Throwable {
WebElement ele=driver.findElement(By.xpath("//i[contains(#class,'fa fa-caret-up')]"));
for(int i=0;i<=3;i++)
{
ele.click();
}
}
#When("^Click on buy now$")
public void Click_on_buy_now() throws Throwable {
driver.findElement(By.xpath("//button[contains(.,'Buy Now')]")).click();
}
#Then("^Product should be added to the cart successfully$")
public void Product_should_be_added_to_the_cart_successfully() throws Throwable {
}
Feature File
Feature: Test test Smoke scenario
Scenario: Test login with valid credentials
Given open firefox and start application
When I click on Login
And enter valid "s#yopmail.com" and valid "passw0rd"
Then Click on login and User should be able to login successfully
Scenario: Test shop for cart
Given Click on shop for carts
And select plates
When I click on drsired product
And click on item increment
And Click on buy now
Then Product should be added to the cart successfully
Test runner
#RunWith(Cucumber.class)
#Cucumber.Options(features="features",glue={"steps"})
public class TestRunnr {
While i am running this cucumber script its throwing an NullPointer Exception :
java.lang.NullPointerException
at steps.testmoke.Click_on_shop_for_carts(testSmoke.java:47)
at ?.Given Click on shop for carts(MyApplication.feature:11)
First scenario is executing successfully but second scenario is not executing.I am login in a ecommerce website and try to click on shop for parts .
Each scenario creates a fresh instance of all the step definitions.
In your case you instantiate the driver in the Given step public void open_firefox_and_start_application() so the first scenario is successful.
Now for the second scenario a new instance of your class has a webdriver which is null and you are not calling the earlier step to instantiate it.
You can use a static webdriver, but you will run into issues with parallel tests. If you are planning for parallel tests look up ThreadLocal to make sure your webdriver is attached to the specific thread.
Another way could be to move the login tests to a separate file. For the other scenarios move the login steps into the Background cucumber tag. This way the webdriver will be instantiated for each scenario. But you will need to decide if you want to keep logged in across scenarios, delete cookies or a new browser for each scenario.

Null pointer exception due to driver instance is null in onTestFailureMethod

Need help on - I am getting null pointer exception in onTestFailure method. If any of my #Test method fails control goes to onTestFailure but driver is null in that method. my code is like -
import statements...
#Listeners(ScreenShot.class)
public class ScreenShot implements ITestListener{
WebDriver driver;
#BeforeClass
public void launch(){
System.setProperty("webdriver.ie.driver", "D:\\Jars\\Drivers\\IEDriverServer.exe");
driver = new InternetExplorerDriver();
driver.get("url");
}
#Test
public void test1(){
//driver.findElement(By.id("Email")).sendKeys("E#E.COM");
System.out.println("Method1 begins");
//some code here - exception occurs here
System.out.println("Method ended");
}
public void onTestFailure(ITestResult result){
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE); //Getting exception here as driver is null
try {
FileUtils.copyFile(scrFile, new File("C:\\snaps\\"+result.getMethod().getMethodName()+".png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
i am running this class by right click->run as testng.
The reason you are getting a NullPointerException is because Testng creates a new instance of each listener. So that new instance has driver not initialized.
In your case, the object of Screenshot class running the #Test method and the instance of the Screenshot class as a listener being invoked by TestNG is different.
There are couple of ways to solve this.
Move the code from onTestFailure to #AfterMethod with the ITestResult as the method argument. Work on the result data to take screenshot.
#AfterMethod
public void afterMet(ITestResult res){
if(res.isSuccess())
Make the driver as a global static. - if you plan to run only sequential tests
Consider threadlocal if you plan to run parallely.

Resources