How to initialize String originalHandle = driver.getWindowHandle(); once? - java

I am using TestNG with Selenium.
I am trying to use driver.getWindowHandle(); to switch between pop-ups, iframes and such.
The thing is, if I declare it like this in the TNGDriver class
public String originalHandle = driver.getWindowHandle();
I get a java.lang.NullPointerException (obviously, because this is initialized before the driver).
How can I declare it once and start using it in other classes? Keep in mind my classes are extended between them and I need to use this originalHandle variable inside methods in other classes, e.g.:
public void clickOnFacebookIcon() {
Assert.assertTrue(true, driver.findElement(By.id(FACEBOOK_ICON)).getText());
driver.findElement(By.id(FACEBOOK_ICON)).click();
for(String handle : driver.getWindowHandles()) {
if (!handle.equals(originalHandle)) {
driver.switchTo().window(handle);
driver.close();
}
}
driver.switchTo().window(originalHandle);
}
Here are my other classes:
TNGDriver class
public class TNGDriver {
public static WebDriver driver;
public static final String CHROME_DRIVER_PATH = "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chromedriver.exe";
private WebDriverWait wait;
#SuppressWarnings("deprecation")
public void init() {
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
ChromeOptions options = new ChromeOptions();
options.addArguments("--incognito");
capabilities.setCapability(ChromeOptions.CAPABILITY, options);
System.setProperty("webdriver.chrome.driver", CHROME_DRIVER_PATH);
driver = new ChromeDriver(capabilities);
driver.manage().window().maximize();
}
public WebDriverWait getWait() {
wait = new WebDriverWait(driver, 60);
return wait;
}
Testcase1 class
public class Testcase1 extends Registration {
TNGDriver tngDriver = new TNGDriver();
#BeforeTest
public void setup() {
tngDriver.init();
}
#Test(priority = 1)
public void step1_clickOnSignIn() {
clickOnSignIn();
}
#Test(priority = 2)
public void step2_clickOnFacebookIcon() {
clickOnFacebookIcon();
}

You can use a desing pattern to do that
https://en.wikipedia.org/wiki/Singleton_pattern
With this pattern you will only have one instance of the object.
class Singleton
{
// static variable single_instance of type Singleton
private static Singleton single_instance = null;
// variable of type String
public String originalHandle = driver.getWindowHandle();
// private constructor restricted to this class itself
private Singleton()
{
//Do something on constructor
}
// static method to create instance of Singleton class
public static Singleton getInstance()
{
if (single_instance == null)
single_instance = new Singleton();
return single_instance;
}
}
To access it you may do something like this
Singleton x = Singleton.getInstance();
//To access the String variable
x.s

Related

How to replace static driver method

public class CommonFunctions {
public static WebDriver driver;
public void openWebsite(String url) {
driver.get(url);
}
public void closeBrowser() {
driver.close();
}
}
public class TestCase {
CommonFunctions commonFunctions = new CommonFunctions();
#BeforeMethod
public void openWeb() {
homePage.openWeb();
}
#Test
public void navigateLoginPage() {
homePage.login();
}
#AfterMethod
public void closeBrowser() {
commonFunctions.closeBrowser();
}
}
I have two class (commonfunction,homepage and testcase). When I run code without "static" at "public static Webdriver driver", the code throw nullpointerexception at function "closeBrowser". How to fix this error. I don't want use method "public static Webdriver driver" as code.
You need to initialize your driver variable in your CommonFunctions class.
WebDriver driver = new WebDriver(... etc);
Or, write a constructor that initializes this variable.
public class CommonFunctions
{
public WebDriver driver;
public CommonFunctions() // Constructor
{
driver = new WebDriver();
}

Error While creating PageObject Module in selenium For simple Tesng Testcase

I tried to Create a Simple Program in Selenium Using PageObjectModel. While Running the Program it throws Null Pointer Exception. Don't Know what i am doing wrong.Is my initialization of Variable is Wrong. I know i am making mistake in initializing the By locator but don't know what i am doing wrong.
public class main extends Base{
private static final int TIMEOUT = 5;
private static final int POLLING = 100;
protected WebDriverWait wait;
protected static WebElement ele;
protected By locator;
public void Base() {
wait = new WebDriverWait(driver, TIMEOUT, POLLING);
}
public WebElement waitForElementToAppear(By locator) {
wait.until(ExpectedConditions.presenceOfElementLocated(locator));//Line which Throws Null
return ele;
}
protected void waitForElementToDisappear(By locator) {
wait.until(ExpectedConditions.invisibilityOfElementLocated(locator));
}
protected void waitForTextToDisappear(By locator, String text) {
wait.until(ExpectedConditions.not(ExpectedConditions.textToBe(locator, text)));
}
#Test()
public void getURL() {
driver.get("https://www.google.com");
waitForElementToAppear(By.name("q")).sendKeys("Pom");// Line Which Throws Null.
}
And My Base Class Code where i have saved the properties of the driver.
public class Base {
protected WebDriver driver;
public WebDriver getDriver() {
return driver;
}
public void setDriver(WebDriver driver) {
this.driver = driver;
}
#BeforeSuite
public void beforeSuite() {
System.setProperty("webdriver.chrome.driver", "D:\\Selenium\\chromedriver.exe"); // You can set this property elsewhere
driver=new ChromeDriver();
driver.manage().window().maximize();
}
}
The problem lies in the way in which you are initialising the WebDriverWait object.
Your WebDriver object will get instantiated only when the #BeforeSuite method runs in your Base class.
The logic of initialising the WebDriverWait is part of the method public void Base() in your main class.
But your #Test annotated getURL() method does not invoke Base() method. So your wait object is always null.
To fix this, invoke Base() within your #Test method or have your Base() method annotated with #BeforeClass annotation, so that it gets automatically called by TestNG.
There are multiple problems in your code
Probably you do not need global variable declarations. Of course you can do it like that but make sure you initialize them.
Do not put test methods in your page object
ele will always be null
Call the constructor
Probably you need something like following:
public class MyPageObject extends Base{
private static final int TIMEOUT = 5;
private static final int POLLING = 100;
protected WebDriverWait wait;
public void MyPageObject() {
super(); //Call constructor of Base if needed
wait = new WebDriverWait(driver, TIMEOUT, POLLING); //init wait
}
public WebElement waitForElementToAppear(By locator) {
wait.until(ExpectedConditions.presenceOfElementLocated(locator));
return driver.findElement(locator); //return WebElement
}
protected void waitForElementToDisappear(By locator) {
wait.until(ExpectedConditions.invisibilityOfElementLocated(locator));
}
protected void waitForTextToDisappear(By locator, String text) {
wait.until(ExpectedConditions.not(ExpectedConditions.textToBe(locator, text)));
}
}
public class MyTestClass {
#Test()
public void getURL() {
MyPageObject myPageObject = new MyPageObject(); //Initialize your page object
driver.get("https://www.google.com");
myPageObject.waitForElementToAppear(By.name("q")).sendKeys("Pom");
}

Figuring Out How To Take Screenshots with TestNG on Test Failure

Okay, I've looked on this topic for quite a bit and have tried multiple solutions to my problem, but I seem to keep getting into roadblocks. I'm trying to setup a general TakeScreenshot after it hits the max of retry attempts with my RetryAnalyzer class. However, I keep getting hit with ClasscastExceptions when adding the Driver and I'm having trouble how to get that same driver initialized in the Base Test, (besides setting to static). Here are my classes I have setup for Screenshot Capture:
Driver Class:
public class Driver implements WebDriver {
protected WebDriver driver;
String browserName;
public static JavascriptExecutor js;
public Driver (String browserName) {
this.browserName = browserName;
if(browserName.equalsIgnoreCase("chrome")) {
System.setProperty("webdriver.chrome.driver", "./resources/webdrivers/chromedriver_win32/chromedriver.exe");
this.driver = new ChromeDriver();
js = (JavascriptExecutor) this.driver;
}
// Other methods for different browsers
BaseTest (Start Portion):
#Listeners({TestMethodListener.class, ScreenshotListstener.class})
public class BaseTest {
protected Driver driver;
DummyTestAccount dummyAccount = new DummyTestAccount();
String browserName = getParamater("browser");
#BeforeClass(alwaysRun = true)
public void setUp() {
driver = new Driver(browserName);
driver.manage().window().maximize();
}
private String getParamater(String name) {
String value = System.getProperty(name);
if(value == null) {
throw new RuntimeException(name + "missing parameter");
}
return value;
}
//Further setup for my extended test classes
RetryAnalyzer:
public class RetryAnalyzer extends BaseTest implements IRetryAnalyzer {
int count = 0;
private static int maxTry = 1;
ScreenshotListstener picCapture = new ScreenshotListstener();
public boolean retry(ITestResult arg0) {
if(count < maxTry) {
count++;
return true; //Retry for flaky tests with unexpected variables
} else {
picCapture.onTestFailure(driver, arg0);
return false; //Don't retry the failed test Capture Screenshot.
}
}
Screenshot Class:
public class ScreenshotListstener extends TestListenerAdapter {
public void onTestFailure(Driver driver, ITestResult result) {
Calendar calendar = Calendar.getInstance();
String methodName = result.getMethod().getMethodName();
SimpleDateFormat formater = new SimpleDateFormat("dd_MM_yyyy_hh_mm_ss");
File bugPic = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
try {
Files.copy(bugPic, new File("./target/surefire-reports/error-pics/"+ methodName + "_" +formater.format(calendar.getTime()) + ".png"));
} catch(IOException e) {
e.printStackTrace();
}
}
}
Currently with this setup, I'm getting hit with a NullPointerException occurring in ScreenshotListener class when initializing on the bugPic File instance. Is there something that I'm missing? Would this current setup be following towards a good practice for test frameworks?
Any advice is helpful.
Thanks.
(Update):
Figured out my issue thanks to Grasshopper's advice.
Driver Class:
public class Driver implements WebDriver {
protected WebDriver driver;
String browserName;
public static JavascriptExecutor js;
public TakesScreenshot bugCapture;
public Driver (String browserName) {
this.browserName = browserName;
if(browserName.equalsIgnoreCase("chrome")) {
System.setProperty("webdriver.chrome.driver", "./resources/webdrivers/chromedriver_win32/chromedriver.exe");
this.driver = new ChromeDriver();
js = (JavascriptExecutor) this.driver;
bugCapture = (TakesScreenshot)driver;
}
// Other methods for different browsers
BaseTest (Start Portion):
#Listeners({TestMethodListener.class, ScreenshotListstener.class})
public class BaseTest {
protected Driver driver;
public static final ThreadLocal<Driver> driverThread = new ThreadLocal<Driver>();
DummyTestAccount dummyAccount = new DummyTestAccount();
String browserName = getParamater("browser");
#BeforeClass(alwaysRun = true)
public void setUp() {
driver = new Driver(browserName);
driver.manage().window().maximize();
driverThread.set(driver);
}
private String getParamater(String name) {
String value = System.getProperty(name);
if(value == null) {
throw new RuntimeException(name + "missing parameter");
}
return value;
}
//Further setup for my extended test classes
RetryAnalyzer:
public class RetryAnalyzer extends BaseTest implements IRetryAnalyzer {
int count = 0;
private static int maxTry = 1;
ScreenshotListstener picCapture = new ScreenshotListstener();
public boolean retry(ITestResult arg0) {
if(count < maxTry) {
count++;
return true; //Retry for flaky tests with unexpected variables
} else {
picCapture.onTestFailure(driverThread.get(), arg0);
return false; //Don't retry the failed test Capture Screenshot.
}
}
Screenshot Class:
public class ScreenshotListstener extends TestListenerAdapter {
public void onTestFailure(Driver driver, ITestResult result) {
Calendar calendar = Calendar.getInstance();
String methodName = result.getMethod().getMethodName();
SimpleDateFormat formater = new SimpleDateFormat("dd_MM_yyyy_hh_mm_ss");
File bugPic = driver.bugCapture.getScreenshotAs(OutputType.FILE);
try {
Files.copy(bugPic, new File("./target/surefire-reports/error-pics/"+ methodName + "_" +formater.format(calendar.getTime()) + ".png"));
} catch(IOException e) {
e.printStackTrace();
}
}
}

WebDriver cannot be initialized

I got NullPointerException when I run the #testCase
1. In FrameworkTestCases.class -> #BeforeClass I initialize the instance of the selected webdriver. The browser is running when I start the FrameworkTestCases.class as jUnit test, but when I reach the testCase it says NullPointerException. What is the reason? I also used a constructor with 2 arguments to inherit the driver from the Generic.class to LoginPageFactory.class, but nothing happened.
Here is my FrameworkTestCases class:
public class FrameworkTestCases {
static WebDriver driver;
private static String baseURl = "https://management.tacticlicks.com/";
static LoginPageFactory loginPage;
static Generic generic;
//WebDriver driver;
//static LoginPageFactory lpFactory;
#BeforeClass
public static void setUp() {
generic = new Generic(driver);
generic.getDriver(baseURl, "chrome");
}
#Test
public void test() {
System.out.println("Executing test");
loginPage
.fillUsernameField("ivailostefanov1989#gmail.com")
.fillPasswordField("astral8909")
.clickSubmit();
}
#AfterClass
public static void tearDown() {
driver.quit();
}
}
public class LoginPageFactory extends Generic {
public LoginPageFactory(WebDriver driver2, Class<LoginPageFactory> class1) {
super(driver2, class1);
// TODO Auto-generated constructor stub
}
WebDriver driver;
#FindBy(name="email") //.//*[#id='login']/div[1]/div/div/table/tbody/tr/td[2]/div[1]/form/div[1]/input
WebElement loginUsernameField;
#FindBy(name="password")
WebElement loginPasswordField;
#FindBy(tagName="button")
WebElement loginSubmitButton;
public LoginPageFactory(WebDriver driver) {
System.out.println("LoginPageFactory");
this.driver = driver;
PageFactory.initElements(driver, this);
}
public LoginPageFactory fillUsernameField(String username) {
System.out.println("Before field initializing");
WebElement emailField = driver.findElement(By.name("email"));
emailField.click();
emailField.sendKeys(username);
return this;
}
public LoginPageFactory fillPasswordField(String password) {
loginPasswordField.click();
loginPasswordField.clear();
loginPasswordField.sendKeys(password);
return this;
}
public LoginPageFactory clickSubmit() {
loginSubmitButton.click();
return this;
}
}
public class Generic {
WebDriver driver;
public Generic(WebDriver driver) {
this.driver = driver;
}
public Generic(WebDriver driver2, Class<LoginPageFactory> class1) {
// TODO Auto-generated constructor stub
}
private void getBrowser(String browser) {
if (browser.equalsIgnoreCase("Firefox")) {
File chromeDriver = new File("C:\\Users\\Ivo\\Desktop\\geckodriver.exe");
System.setProperty("webdriver.gecko.driver", chromeDriver.getAbsolutePath());
driver = new FirefoxDriver();
} else if (browser.equalsIgnoreCase("Chrome")) {
//set chromedriver property
File chromeDriver = new File("C:\\Users\\Ivo\\Desktop\\chromedriver.exe");
System.setProperty("webdriver.chrome.driver", chromeDriver.getAbsolutePath());
driver = new ChromeDriver();
} else {
System.out.println("Browser cannot be launched");
}
}
public WebDriver getDriver(String appUrl, String browser) {
getBrowser(browser);
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.get(appUrl);
return driver;
}
}
You are missing a variable assignment in #BeforeClass method.
Change
#BeforeClass
public static void setUp() {
generic = new Generic(driver);
generic.getDriver(baseURl, "chrome");
}
to
#BeforeClass
public static void setUp() {
generic = new Generic(driver);
driver = generic.getDriver(baseURl, "chrome");
}
And also you did not create any instance of LoginPageFactory class. You have created a variable static LoginPageFactory loginPage; but didn't initialize it (at least nowhere in provided code).
In method
#Test
public void test() {
System.out.println("Executing test");
//add this line of code to initialize elements via Page Factory
loginPage = new LoginPageFactory(driver);
loginPage
.fillUsernameField("ivailostefanov1989#gmail.com")
.fillPasswordField("astral8909")
.clickSubmit();
}

Error: Either make it static or add a no-args constructor to your class

I am running this class as testNG and getting error either make it static or add a no-args constructor. If I add no arg constructor, I get error: "implicit super constructor BaseClass() is undefined."
public class testmaven extends BaseClass{
public testmaven(WebDriver driver) {
super(driver);
// TODO Auto-generated constructor stub
}
#Test
public void myMethod() throws Exception {
logInPage.openApp("Chrome","http://url.com");
}
Here is the Base Class:
public class BaseClass {
public WebDriver driver;
public boolean isDisplay;
public LogInPage logInPage;
public WaitForObj wait;
public DashboardPage dashboardPage;
public Actions action;
public Util util;
public BaseClass(WebDriver driver){
this.driver = driver;
this.isDisplay = false;
logInPage = new LogInPage(driver);
wait = new WaitForObj(driver);
dashboardPage = new DashboardPage(driver);
util = new Util (driver);
action = new Actions(driver);
}
Here is the Login class
public class LogInPage extends BaseClass {
BrowserFactory browserfactory = new BrowserFactory();
public LogInPage(WebDriver driver){
super(driver);
}
public void openApp(String browserName, String env) throws Exception{
driver = browserfactory.getBrowser(browserName);
Log.info("Browser:" + browserName);
driver.manage().window().maximize();
driver.get(env);
Log.info("Env: " + env);
wait.wait(1);
}
You have to explain to TestNG how it is supposed to instanciate your test class.
A solution is using a #Factory.
Another solution, which is a more common pattern, is having an empty constructor and using #BeforeX and/or #AfterX methods for the initialisation of attributes.

Categories

Resources