I wrote some JUnit test cases at Winium which is nearly same as Selenium for Calculator. My problem is with every test a new calculator.exe is started but I want to do all the test for the same calculator.exe but I also want to seperate the JUnit test. Below you can see my code:
public class calculatorTest {
#Test
public void additionTest() throws MalformedURLException, InterruptedException {
DesktopOptions option = new DesktopOptions();
option.setApplicationPath("C:\\Windows\\System32\\calc.exe");
WiniumDriver driver = new WiniumDriver(new URL("http://localhost:9999") , option);
Thread.sleep(2000);
driver.findElement(By.name("Seven")).click();
driver.findElement(By.name("Plus")).click();
driver.findElement(By.name("Eight")).click();
driver.findElement(By.name("Equals")).click();
String output = driver.findElement(By.id("CalculatorResults")).getAttribute("Name");
System.out.println("Result is " + output);
assertEquals("Display is 15", output);
}
#Test
public void subtractionTest() throws MalformedURLException, InterruptedException {
DesktopOptions option = new DesktopOptions();
option.setApplicationPath("C:\\Windows\\System32\\calc.exe");
WiniumDriver driver = new WiniumDriver(new URL("http://localhost:9999") , option);
Thread.sleep(2000);
driver.findElement(By.name("Nine")).click();
driver.findElement(By.name("Minus")).click();
driver.findElement(By.name("Eight")).click();
driver.findElement(By.name("Equals")).click();
String output = driver.findElement(By.id("CalculatorResults")).getAttribute("Name");
System.out.println("Result is " + output);
}
You can add a configuration method to your test class, which is a part of JUnit
#BeforeClass
public void openCalculator() {
DesktopOptions option = new DesktopOptions();
option.setApplicationPath("C:\\Windows\\System32\\calc.exe");
WiniumDriver driver = new WiniumDriver(new URL("http://localhost:9999") , option);
Thread.sleep(2000);
}
Related
I have a maven project that runs testng and cucumber. If I run the testng and my test fails my program takes screenshots and creates a report. However if I run my cucumber tests and it fails, I get java.lang.NullPointerException: Cannot invoke "org.openqa.selenium.TakesScreenshot.getScreenshotAs(org.openqa.selenium.OutputType)" because "screenShot" is null.
Both the testng and cucumber references the same listeners and base class.
My listeners class (on failure):
#Override
public void onTestFailure(ITestResult result) {
ExtentThred.get().fail(result.getThrowable());
WebDriver driver = null;
String testMethodName = result.getMethod().getMethodName();
try {
driver = (WebDriver)result.getTestClass().getRealClass().getDeclaredField("driver").get(result.getInstance());
}
catch (Exception e)
{
}
try {
ExtentThred.get().addScreenCaptureFromPath(getScreenshotPath(testMethodName, driver),result.getMethod().getMethodName());
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
My base class:
public class Base {
public static WebDriver driver;
public Properties prop;
public WebDriver initializeDriver() throws IOException {
prop = new Properties();
FileInputStream file = new FileInputStream(System.getProperty("user.dir") + "\\src\\main\\java\\resources\\data.properties");
prop.load(file);
String browserName = prop.getProperty("browser");
if (browserName.contains("chrome")) {
System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir") + "\\chromedriver.exe");
ChromeOptions chromeOptions = new ChromeOptions();
if (browserName.contains("headless")){
chromeOptions.addArguments("headless");
}
driver = new ChromeDriver(chromeOptions);
}
else if (browserName == "firefox") {
}
else if (browserName == "edge") {
}
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
return driver;
}
public String getScreenshotPath(String testCaseName, WebDriver driver) throws IOException
{
TakesScreenshot screenShot = (TakesScreenshot) driver;
File source = screenShot.getScreenshotAs(OutputType.FILE);
String destinationFile = System.getProperty("user.dir")+"\\reports\\"+ testCaseName +".png";
FileUtils.copyFile(source, new File(destinationFile));
return destinationFile;
}
}
My testng class that works fine:
public class ValidateLoggedIn extends Base {
public WebDriver driver;
#BeforeTest
public void initialize() throws IOException {
driver = initializeDriver();
}
#Test(dataProvider = "getData")
public void HomePageTitle(String mobileNumber, String password, String access) throws IOException {
driver.get(prop.getProperty("cars"));
MainPage mainPage = new MainPage(driver);
mainPage.getLogin().click();
mainPage.getMobileNumber().sendKeys(mobileNumber);
mainPage.getPassword().sendKeys(password);
mainPage.getLoginButton().click();
if (access == "Allowed User") {
LoggedInPage loggedInPage = new LoggedInPage(driver);
Assert.assertTrue(loggedInPage.getLogOutButton().isDisplayed());
loggedInPage.getLogOutButton().click();
}
else {
mainPage.getLoginButton();
Assert.assertTrue(mainPage.getLoginButton().isDisplayed());
}
}
#DataProvider
public Object[][] getData() {
Object[][] userData = new Object[1][3];
userData[0][0] = "0720127992";
userData[0][1] = "Dr0medar!s";
userData[0][2] = "Allowed User";
return userData;
}
#AfterTest
public void teardown()
{
driver.close();
}
}
My step definition for my cucumber:
public class StepDefinition extends Base {
public WebDriver driver;
#Given("^Initilize the browser with Chrome$")
public void initilize_the_browser_with_chrome() throws Throwable {
driver = initializeDriver();
}
#When("^User enters (.+) and (.+) and logs in$")
public void user_enters_and_and_logs_in(String mobilenumber, String password) throws Throwable {
MainPage mainPage = new MainPage(driver);
mainPage.getLogin().click();
mainPage.getMobileNumber().sendKeys(mobilenumber);
mainPage.getPassword().sendKeys(password);
mainPage.getLoginButton().click();
}
#Then("^verify if user is successfully logged in$")
public void verify_if_user_is_successfully_logged_in() throws Throwable {
LoggedInPage loggedInPage = new LoggedInPage(driver);
Assert.assertTrue(loggedInPage.getLogOutButton().isDisplayed());
loggedInPage.getLogOutButton().click();
}
#And("^Navigate to \"([^\"]*)\" site$")
public void navigate_to_something_site(String strArg1) throws Throwable {
driver.get(strArg1);
}
#And("^Close Browser$")
public void close_browser() throws Throwable {
driver.quit();
}
}
My test runner:
#CucumberOptions(
features = "src/test/java/features",
glue = "stepDefinitions")
public class TestRunner extends AbstractTestNGCucumberTests {
}
My error:
java.lang.NullPointerException: Cannot invoke "org.openqa.selenium.TakesScreenshot.getScreenshotAs(org.openqa.selenium.OutputType)" because "screenShot" is null
at resources.Base.getScreenshotPath(Base.java:53)
at cars.Listeners.onTestFailure(Listeners.java:52)
at org.testng.internal.TestListenerHelper.runTestListeners(TestListenerHelper.java:96)
at org.testng.internal.TestInvoker.runTestResultListener(TestInvoker.java:220)
at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:832)
at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:147)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
at java.base/java.util.ArrayList.forEach(Unknown Source)
at org.testng.TestRunner.privateRun(TestRunner.java:764)
at org.testng.TestRunner.run(TestRunner.java:585)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:384)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:378)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:337)
at org.testng.SuiteRunner.run(SuiteRunner.java:286)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1218)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1140)
at org.testng.TestNG.runSuites(TestNG.java:1069)
at org.testng.TestNG.run(TestNG.java:1037)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
I am not sure why cucumber gives a NullPointerException and testng one does not. using `e.printStackTrace()' I see that the driver is null.
I have looked at answers such as null-pointer-exception-when-trying-to-take-a-screenshot-with-selenium and exception-while-taking-screenshot but nothing helped.
Replace getDeclaredField with getField
driver = (WebDriver)result.getTestClass().getRealClass().getDeclaredField("driver").get(result.getInstance());
getField can get a field inherited from a superclass but getDeclaredField cannot. getDeclaredField restricts itself to the class you call the function on.
And Remove static from public static WebDriver Driver from base class.
It has a close browser step and then you are trying to access this session in the listener class so obviously, the session will be null.
remove the after test and try
I think that the problem might be with your base file, where you have:
"public static WebDriver driver;"
remove "static" and it should work properly
How to test sub links on a page in Selenium. I have an events page. Then from that events page i collect all the different events links. Then i want to recursively run tests on those links.
I have attached an image of the page. The green text are all links. So i collected the href values of all these. After that I have some tests to run on those pages. I have a test class called EventsPageTest for the main page. The test class for the sub pages is called SingleEventsPageTest. How do I transfer the href values from the main class to the other class. Or is there any other method I need to follow.
I searched the internet so much but was of no use.
Any help would be appreciated.
Thanks
EventsPageTest
package test;
import pages.EventsPageObjects;
#Listeners(listeners.TestListener.class)
public class EventsPageTest {
private static ExtentHtmlReporter htmlReporter;
private static ExtentReports extent;
private static ExtentTest test;
static WebDriver driver = null;
private static EventsPageObjects eventsPage;
public MutableCapabilities capabilities;
static Set<String> eventsLinks = new HashSet<String>();
String url;
#BeforeSuite
public void setUp() {
// initialize the HtmlReporter
htmlReporter = new ExtentHtmlReporter("extentReportsEventsPage.html");
// initialize ExtentReports and attach the HtmlReporter
extent = new ExtentReports();
// attach only HtmlReporter
extent.attachReporter(htmlReporter);
}
#BeforeTest
public void setUpTest() throws IOException{
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
url = "abc.com";
driver.get(url);
System.out.println("Inside setUpTest");
//Create eventsPageObject
eventsPage = new EventsPageObjects(driver);
}
#Test(alwaysRun=true)
public void collectEventsLinks() throws InterruptedException, IOException {
test = extent.createTest("Collect all Events Links on a page","Test to Collect all Events Links on a page ");
test.log(Status.INFO, "Starting Test Case");
List<WebElement> links = driver.findElements(By.tagName("a"));
for (int i = 0; i<links.size(); i++) {
if(Pattern.matches("^https://"+ TestRunner.url +"/events/[^/]+[^\\s]$", links.get(i).getAttribute("href")))
eventsLinks.add((links.get(i).getAttribute("href")));
}
test.log(Status.INFO, "Finished Test Case");
}
#AfterTest(alwaysRun = true)
public void tearDownTest() {
//close browser
driver.close();
driver.quit();
}
#DataProvider(name="getURLS")
#AfterTest
public Object[] getURLS() {
System.out.println("Inside get Urls");
System.out.println("getURLS : " + eventsLinks.size());
Object[] objArray = eventsLinks.toArray();
System.out.println(eventsLinks.size());
return objArray;
}
#AfterSuite
public void tearDown() {
extent.flush();
}
}
SingleEventsPageTest
package test;
#Listeners(listeners.TestListener.class)
public class SingleEventsPageTest{
private static ExtentHtmlReporter htmlReporter;
private static ExtentReports extent;
private static ExtentTest test;
static WebDriver driver;
private static SingleEventsPageObjects singleEventsPage;
static List<Object> eventsURLS = new ArrayList<Object>();
#BeforeSuite
public void setUp() {
PropertiesFile.getProperties();
// initialize the HtmlReporter
htmlReporter = new ExtentHtmlReporter("extentReportsSingleEventsPage.html");
// initialize ExtentReports and attach the HtmlReporter
extent = new ExtentReports();
// attach only HtmlReporter
extent.attachReporter(htmlReporter);
}
#BeforeTest
public void setUpTest() throws IOException{
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
//Create eventsPageObject
singleEventsPage = new SingleEventsPageObjects(driver);
}
#Test(dataProvider="getURLS",dataProviderClass=EventsPageTest.class,alwaysRun=true)
public void findIfEventsTitleExists(String url) throws InterruptedException, IOException {
driver.get(url);
System.out.println("Inside findIfEventsTitleExists : " + driver.getCurrentUrl());
test = extent.createTest("Events Title Exists","Test to verify if the Events Title exists after opening the page");
test.log(Status.INFO, "Starting Test Case");
test.log(Status.INFO, "Checking If the URL points to the events page else navigate to that");
Assert.assertEquals(true,singleEventsPage.findIfEventsTitleExists());
test.log(Status.INFO, "Finished Test Case");
}
#Test(dataProvider="getURLS",dataProviderClass=EventsPageTest.class,alwaysRun=true)
public void verifyIfEventDescriptionExists(String url) throws InterruptedException, IOException {
driver.get(url);
test = extent.createTest("Events description Exists","Test to verify if the Events description exists");
test.log(Status.INFO, "Starting Test Case");
test.log(Status.INFO, "Checking If the URL points to the events page else navigate to that");
if(singleEventsPage.getCurrentUrl() != url)
singleEventsPage.navigateTo(url);
test.log(Status.INFO, "Checking If the Page Sub Title Exists");
Assert.assertEquals(true,singleEventsPage.checkIfElementExists(singleEventsPage.getEventDesc()));
test.log(Status.INFO, "Finished Test Case");
}
#AfterTest(alwaysRun = true)
public void tearDownTest() {
//close browser
driver.close();
driver.quit();
}
#AfterSuite
public void tearDown() {
extent.flush();
}
}
It would be good if you could post your code here. You can try to store them in one class as List, then pass them to another.
I am not sure how your framework is working now. I am thinking of something like this. Please post more code here.
class EventsPageTest {
public List<T> getAllHref() {
// return List
}
}
class SingleEventsPage {
#Test
public void someTest () {
EventsPageTest eventsPageTest = new EventsPageTest();
List<T> hrefs = eventsPageTest.getAllHref();
}
}
Hope this helps
I am using the FirefoxDriverInstance as the singleton for calling driver. Also, using a firefox profile to bypass 2-factor-authentication.
public class FirefoxDriverInstance {
public static WebDriver Instance = null;
public static void Initialize() {
if (Instance == null) {
System.out.println("Initializing Firefox Driver!!!");
System.setProperty("webdriver.gecko.driver","./src/test/resources/driver/geckodriver2.exe");
ProfilesIni profile = new ProfilesIni();
FirefoxOptions options = new FirefoxOptions();
options.setProfile(profile.getProfile("SeleniumTester"));
Instance = new FirefoxDriver(options);
}
Instance.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
Instance.manage().window().maximize();
}
public static void close() {
System.out.println("Closing Browser!!!");
Instance.close();
Instance = null;
}
public static void quit() {
System.out.println("Quitting Browser!!!");
Instance.quit();
Instance = null;
}
}
Below is my login code using cucumber-selenium-webdriver. I have used the same driver instance.
public class TC01_Login {
#BeforeMethod
public void openbrowser() throws IOException {
FirefoxDriverInstance.Initialize();
}
public Properties propertyFileReader() throws Exception {
Properties obj = new Properties();
FileInputStream objfile = new FileInputStream(System.getProperty("user.dir")+"\\src\\test\\resources\\testdata\\application.properties");
obj.load(objfile);
return obj;
}
WebDriverWait wait = new WebDriverWait(FirefoxDriverInstance.Instance, 150);
#Given("^user has entered the required URL$")
public void user_has_entered_the_required_URL() throws Throwable {
Properties obj = propertyFileReader();
System.out.println("In the First Loop!!");
FirefoxDriverInstance.Instance.get(obj.getProperty("baseUrl"));
String actualTitle = FirefoxDriverInstance.Instance.getTitle();
System.out.println("Actual Title :" + actualTitle);
if (actualTitle.contains("test")){
System.out.println("INFO : Title is being displayed as expected.");
}
else {
System.out.println("ERROR : Title is NOT being displayed as expected."); }
}
}
Unable to understand how to bypass this error.
Try to put below code in constructor :
FirefoxDriverInstance.Initialize();
Example:
public class TC01_Login {
public TC01_Login (){
FirefoxDriverInstance.Initialize();
}
}
Remove it from BeforeMethod
I have declared 2 methods #after annotation but it will execute only the first method, it does not allow me to execute the second method. Please have a look at the below code
I want to execute 1 method every time for the exit of the browser.
I want to execute the second method for failed test cases.
#Before
public void databaseLoading(Scenario scenario) {
//System.out.println("Test Environment Set Up");
System.out.println("\n------------------------------------------------ TEST ENVIRONMENT SET UP ------------------------------------------------------------------------------\n");
System.out.println("Executing Scenario :-> " + scenario.getName());
}
#After
public void browserTearDown()
{
System.out.println("End the browser");
driver.close();
}
public void Screenshot(Scenario scenario) {
// take the screenshot at the end of every test
String location = ".\\target\\TakeScreenshot";
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy hh-mm-ss", Locale.ENGLISH);
Date date = new Date();
File scrFile =
((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
// now save the screenshto to a file some place
if (scenario.isFailed()) {
try {
FileUtils.copyFile(scrFile, new File(location + "\\" + dateFormat.format(date) + ".png"));
System.out.println("Screenshot saved");
} catch (IOException e) {
System.out.println("Error in taking Screenshot --> " + e);
}
}
}
Method 'Screenshot(cucumber.api.Scenario)' is never used. This error message comes for the second method.
You only tagged browserTearDown() method.
Add the #After tag to the Screenshot() method, as well:
#After
public void browserTearDown()
{
System.out.println("End the browser");
driver.close();
}
#After
public void Screenshot(Scenario scenario) {
...
}
I need to run tests classes and show the results in screen, following this structure, but just after running all.
#RunWith(Suite.class)
#Suite.SuiteClasses({
LoginTest.class,
LogoutTest.class
})
public class AllTests {
protected static WebDriver driver;
#BeforeClass
public static void beforeClass() throws Exception {
driver = Selenium.getDriver();
driver.navigate().to(Property.SITE_ADDRESS);
driver.manage().window().maximize();
}
#AfterClass
public static void afterClass() throws Exception {
String resultString = "";
Result result = JUnitCore.runClasses(AllTests.class);
for (Failure fail : result.getFailures()) {
resultString += result.getClass() +": "+ fail.toString()+"\n";
}
if (result.wasSuccessful()) {
resultString += result.getClass() +": "+ result + "\n";
}
JFrame frame = new JFrame("Results");
JOptionPane.showMessageDialog(frame, resultString, "Title", JOptionPane.INFORMATION_MESSAGE);
driver.quit();
}
My #AfterClass is re-running my test classes, is there any other solution?