How call a method webdriver from another class in java? - java

i have a class Test1 where i use this line to click on a button:
try{
driver.findElement (By.xpath(Component._emp)).click();
System.out.println("Employment is clicked");
} catch (NoSuchElementException e17) {
System.out.println("Employment is not found [TEST FAILED]");
}
And another class named Util, in this class i copied the code above like this:
public static void click_person_employment(){
try{
driver.findElement (By.xpath(Component._emp)).click();
System.out.println("Employment is clicked");
} catch (NoSuchElementException e17) {
System.out.println("Employment is not found [TEST FAILED]");
}
}
So in my class Test1 when i call like this:
Util.click_person_employment()
it throws java.lang.Nullpointer exception
Whta is the proper way to call this method.
My goal is to reduce code in my class Test1 because i have more than 100 buttons to click.
Thank you

I would recommend creating more general methods in your Utils class, ones that you can reuse over and over.
Also, System.out.println is not recommended in code. Instead you can use a logging framework - SLF4J is a good one. If you insist on using System.out.println, you can pass on the message as well.
So I'd do something like:
private static final Logger LOGGER = Logger.getLogger([className].class.getName());
public static void clickOnElement(By by){
try {
WebElement element = driver.findElement(by).click();
} catch (NoSuchElementException e) {
LOGGER.log(Level.WARNING, e.getMessage(), e);
}
}
and then call it in test as:
Util.clickOnElement(By.xpath(...));
If you want the test to fail when the button is not found, you can rethrow the exception in the catch block.
PS. also, explicit waiting is always preferred to Thread.sleep - avoid that one in your tests as much as possible. :)

To achieve your goal, you can follow the below way:
First return WebElement from the Util class method -
public static WebElement click_person_employment(String empPath){
WebElement elem = null;
try{
elem = driver.findElement(By.xpath(empPath));
//System.out.println("Employment is clicked");
} catch (NoSuchElementException e17) {
System.out.println("Employment is not found [TEST FAILED]");
}
return elem;
}
Then call this method from Test1 class like
String empXpathStr = Component._emp;
WebElement element = Util.click_person_employment(empXpathStr);
element.click();
//Use WebDriverWait wait functionality here [Wait until element is visible]
You can also try removing the static keyword and creating the instance of Util class in your Test1 class. Finally call the method from Test1 class using the instance object.

Related

how to pass the instance value from one class the other class containing test annotated method

Class1-UIHandler1.java
public WebDriver Assettype_dropdown(WebDriver driver,WebElement dropdown,String name) throws InterruptedException {
wait_until_clickable(driver,dropdown,120);
dropdown.click();
search.click();
search.sendKeys(name);
insearchesult2.click();
view_btn.click();
return driver;
}
public WebDriver result_verification(WebDriver driver,String APIR,String msg) throws InterruptedException
{
Thread.sleep(5000);
search_view.sendKeys(APIR);
assertEquals(driver,table_data,APIR,msg);
return driver;
}
Class 2 testng class
public class cucumbermain extends AbstractTestNGCucumberTests {
public static WebDriver driver;
#AfterMethod() //AfterMethod annotation - This method executes after every test execution
public static void screenShot(ITestContext context){
//using ITestResult.FAILURE is equals to result.getStatus then it enter into if condition
if(ITestResult.SUCCESS==result.getStatus()){
try{
// To create reference of TakesScreenshot
TakesScreenshot screenshot=(TakesScreenshot)driver;
// Call method to capture screenshot
File src=screenshot.getScreenshotAs(OutputType.FILE);
// Copy files to specific location
// result.getName() will return name of test case so that screenshot name will be same as test case name
FileUtils.copyFile(src, new File("D:\\"+result.getName()+".png"));
System.out.println("Successfully captured a screenshot");
}catch (Exception e){
System.out.println("Exception while taking screenshot "+e.getMessage());
}
}
}
Here I have to pass the driver value returned from **UI Handler1.java to the After method in cucumber main.The driver in UIHandler class is obtained from another test class which holds the test class information
I couldn't store the driver value in the testng After method from another class**
Error Iam geting
Exception while taking screenshot null
Screenshot action entry
To report the results and to take a screenshot on Cucumber project you need to use cucumber hooks and not testng annotations, the way you're using is confusing. Read more here about hooks.
And if you're trying to do something on failure you can create listeners that implement some testng listeners, try this.

Jumping to another class using a JButton

I have the below code where I made a simple GUI. I would like Button2 to navigate to class 'Project2', which should start another piece of code. Just to note, in its current state, 'Project2' has no GUI, though I intend to add one soon. Anyway, this 'code jump' which I used by adding: String[] args = {};
Project2.main(args);
is not working, as the IDE says 'IOException must be caught or thrown'. I know how this works, though I am not sure how to implement it in the program.
Thanks in advance!
You can try to use dynamic class loading for your program. Below you can find lambda, which calls main method from com.stackoverflow.ExternalCaller class.
If you do not like to use lambda, you can create a simple anonymous class.
button.addActionListener(s -> {
try {
Class<?> externalCaller = Class.forName("com.stackoverflow.ExternalCaller");
Method main = externalCaller.getDeclaredMethod("main", new Class[]{String[].class});
main.invoke(null, new Object[]{new String[0]});
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
});
ExternalCaller class in its turn looks something like that:
package com.stackoverflow;
public class ExternalCaller {
public static void main(String args[]) {
System.out.println("Hello World");
}
}
In result once you click on the button you will get Hello World output in console.
If you would like to work with external jars etc. please look on Process class. Quick example:
Process proc = Runtime.getRuntime().exec("java -jar External.jar");
Or even more on fork/exec. You can read From Runtime.exec() to ProcessBuilder for more details.
Hope this will help. Good luck.
In most of the IDE's, when you right-click on the Button2 in the Design(GUI) pane, you can travel through:
Events -> Actions -> actionPerformed().
And write this code in the selected method to switch classes:
this.setVisible(false); //turns off the visibility of the current class
outputClass out = new outputClass(); //creating the object of the class you want to redirect to
out.setVisible(true);//turns on the visibility of the class you want to redirect to

Appium/Selenium - assert that element declared as field is NOT displayed

I declare a button as field in following fashion:
#AndroidFindBy(name = "Schedule")
private WebElement calendarButton;
... and later I make sure it's NOT displayed because the app is in some special mode.
Assert.assertFalse(this.calendarButton.isDisplayed());
It gives me org.openqa.selenium.NoSuchElementException, but the test is failed. Any ideas how can I make such assertion?
The thing I don't want to define By condition a few times in the code, so using property is handy.
After some thinking I came up with following solution:
public static boolean elementIsPresent(AndroidElement element) {
try {
element.isDisplayed();
} catch (org.openqa.selenium.NoSuchElementException e) {
return false;
}
return true;
}
I use this method in following way:
Assert.assertFalse(elementIsPresent(this.calendarButton));
I was inspired by one of the answers in this thread.

How to execute code which comes after a section where element is not found in a test method?

Suppose, I am testing method which checks whether all links are present on page. Ex :
#Test
public void testLinks(){
driver.findElement(By.linkText("link1"));
driver.findElement(By.linkText("link2"));
driver.findElement(By.linkText("link3"));
driver.findElement(By.linkText("link4"));
driver.findElement(By.linkText("link5"));
}
In above code, suppose all links are present except link3 then test method's execution will stop after throwing error for link3 but still if I want code to be executed for checking link4 and link5, how can I achieve that using Java?
I think you mean throwing exceptions.
You can test links one by one in another method which handle exceptions.
public void testOne(String link) {
try {
driver.findElement(By.linkText(link));
}
catch (Exception e) {
System.out.println(link+" failed to find");
}
}
public void test() {
testOne("link1");
testOne("link2");
testOne("link3");
testOne("link4");
testOne("link5");
}
The testOne() method will catch exceptions and print a failed note, and your test method won't be disrupted.
Try this, you can use TestNg reporter to make your test pass or fail or log4j logs, try this.
sResult = "Pass";
public void testOne(String link) {
try {
driver.findElement(By.linkText(link));
}
catch (Exception e) {
System.out.println(link+" failed to find");
sResult = "Fail";
}
}
public void test() {
testOne("link1");
testOne("link2");
testOne("link3");
testOne("link4");
testOne("link5");
}
if(sResult.equals("Pass")){
System.out.println("Pass");
}else{
System.out.println("Fail");
}

WebDriver: How to check if an page object web element exists?

How to check if an Element exists, when using Page Objects with webdriver.
So far I am doing it this way.
DefaultPage defaultPage = PageFactory.initElements(this.driver,
DefaultPage.class);
assertTrue(defaultPage.isUserCreateMenuLinkPresent());
Page Object:
public class DefaultPage {
#FindBy(id = "link_i_user_create")
private WebElement userCreateMenuLink;
public boolean isUserCreateMenuLinkPresent() {
try {
this.userCreateMenuLink.getTagName();
return true;
} catch (NoSuchElementException e) {
return false;
}
}
}
But I can not believe that this try/catch is the way one should do it. So what would be a better way to check if the elements exits (with using Page Objects)?
The problem is the pattern itself. It uses #FindBy annotation (used by PageFactory to init the fields that must be wrapped by Proxy) that replaces the standard elements with their proxy instances which contain InvocationHandler.
Each time you try to access a field, annotated with #FindBy, the invocation handler tries to find the element using the default ElementLocator.The problem is that the ElementLocator.findElement() method throws an TimeoutException / NoSuchElementException if there are no elements presented in the DOM.
public WebElement findElement(SearchContext context) {
List<WebElement> allElements = findElements(context);
if (allElements == null || allElements.isEmpty())
throw new NoSuchElementException("Cannot locate an element using "
+ toString());
return allElements.get(0);
}
Therefore, each time you need to check whether an element is displayed or not you have to search for a List of elements and check its size.
#FindBy(css = "div.custom")
private List<WebElement> elements
...
public isElementPresented(){
return elements != null && elements.size > 0
}
Another way to solve this problem is to create your own implementation of LocatingElementHandler and ElementLocator
So, if you need your own isDisplayed() method to return false instead of Exception, you have to replace the findElement() method in ElementLocator with something like that:
...
List<WebElement> elements = searchContext.findElements(by)
if(elements != null && elements.size() > 0){
List<WebElement> visibleElements = []
elements.each {
if(it.displayed){
visibleElements.add(it)
}
}
if(visibleElements.size() > 0){
return visibleElements.get(0)
}
}
return null
...
And add new conditions to LocatingElementHandler.invoke()
Something like:
element = locator.findElement()
if(element == null){
if(method.name == "isDisplayed"){
return false
}
}
Webdriver is designed to throw an exception if an element is not found, So there aren't any methods to verify presence of an element in Webdriver.
Check this - http://groups.google.com/group/webdriver/browse_thread/thread/909a9b6cb568e341
#Ralph: I do it the same way: try/catch. I've never found another way.
You could swap out the try/catch block in a super class and design it generic. In other words: You could write a method which expects an object of type WebElement. This method contains the try/catch block and return true/false...
So I wrote the following public method in the test framework's super class and am now able to use it in every page object:
public boolean isElementExisting(WebElement we) {
try {
we.isDisplayed();
return true;
} catch(NoSuchElementException e) {
LOGGER.severe("Element does not exist.");
return false;
}
}
I don't know why this is not implemented in WebDriver...
Otherwise you could use WebDriverWait.
I'm using this pattern, works fine for me:
public void login()
{
if (!loginButton.isDisplayed())
{
throw new IllegalStateException("Login button is not displayed!");
} else
{
loginButton.click();
}
}
or:
public boolean loginButtinIsDisplayed() {
try {
this.loginButton.getTagName();
return true;
} catch (NoSuchElementException e) {
e.printStackTrace();
return false;
}
}
I recently came across this old post and believe I've found one solution.
I was testing a page that had an Add User button. When the button was clicked, various editable text fields appeared (for First Name, Last Name, Email, etc..) and a single dropdown.
When a Cancel button was clicked, the fields disappeared and no longer existed. Using WebDriverWait with ExpectedConditions.visibilityOf() would not work since the elements no longer existed in the DOM.
I found that #FindAll was a solution for me, though I must admit my test ran noticeably slow at the my List assertion.
For your code, something like this:
public class DefaultPage {
#FindAll({#FindBy(id = "link_i_user_create")}) List<WebElement> userCreateMenuLink;
public boolean isUserCreateMenuLinkPresent() {
if (this.userCreateMenuLink.isEmpty()) fail("Link does not exist");}
I am able to use something similar in my own tests though, and it seems like a dependable way to skirt the 'No such element' exception. It's basically a page object adaptation of asserting: driver.findElements(By.locator).size() < 1.
Here is a nice pattern to access optional elements on a page:
#FindBy(...)
private List<WebElement> element;
public Optional<WebElement> getElement() {
return element.stream().findFirst();
}
In a test, you could then use the following assertions:
assertEquals(Optional.empty(), page.getElement()); // element should be absent
assertTrue(page.getElement().isPresent()); // element should be present
var e = page.getElement().orElseThrow(AssertionFailedError::new); // check and use element
Arquillian has implemented that feature in Graphene extension.
Check ElementLocatorConditionFactory.isPresent() function.
They more or less do what you wrote in your question (from ExpectedConditions.findElement in selenium-support.jar) :
try {
return driver.findElement(by);
} catch (NoSuchElementException e) {
throw e;
} catch (WebDriverException e) {
// [...] some log
throw e;
}
Using C# bindings:
using System.Collections.Generic;
using System.Linq;
public class DefaultPage
{
[FindsBy(How = How.Id, Using = "link_i_user_create")]
private IList<IWebElement> userCreateMenuLink;
public bool isUserCreateMenuLinkPresent()
{
return userCreateMenuLink.Any();
}
}
You're telling Selenium to grab all elements that match that Id and put them into a List of IWebElement. You then call .Any() on the list which evaluates to true if at least one IWebElement was found.
try this is defiantly work in pom
public boolean isPrebuiltTestButtonVisible() {
try {
if (preBuiltTestButton.isEnabled()) {
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
this will definitely work in page object model surround with try catch

Categories

Resources