How do I configure Spring STS to run Selenium test classes? - java

I'm using Spring STS (3.7) to develop an MVC application. I'm attempting to run a simple Selenium test using an example I've read in a book. I'm receiving a 'ClassNotFoundException' when I run the JUnit test. What's odd is that class that's not found is the test class itself: 'UIHomeTest'. I've verified that I have JUnit, Hamcrest and Selenium on the classpath. I've tried adding the JUnit library to the run configuration. Here is the code for the test class:
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverBackedSelenium;
import org.openqa.selenium.firefox.FirefoxDriver;
import static org.junit.Assert.assertEquals;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.thoughtworks.selenium.SeleneseTestBase;
public class UIHomeTest {
private WebDriver browser;
private static final String HOME_URL = "http://localhost:8080/";
#Before
public void setUp() throws Exception {
WebDriver driver = new FirefoxDriver();
}
#Test
public void testHomePage()
{
browser.get(HOME_URL);
assertEquals("Home", browser.findElement(By.id("title")).getAttribute("value"));
}
#After
public void tearDown() throws Exception
{
browser.close();
}
}
Here is the error:
Class not found org.test.ui.UIHomeTest
java.lang.ClassNotFoundException: org.test.ui.UIHomeTest
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadClass(RemoteTestRunner.java:685)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.loadClasses(RemoteTestRunner.java:421)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:444)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
I've been able to run a non-Selenium JUnit test class inside of Spring STS before. Can anyone help me properly configure Spring STS to run Selenium test classes? Thanks.

On observing the imports and selenium code i found there are few not required imports used like import org.openqa.selenium.WebDriverBackedSelenium; import com.thoughtworks.selenium.SeleneseTestBase; and also not used or initiated driver object. below is the complete code which works fine for me.
com.tesngtraining; is my package. If you are downloaded java specific selenium jars then please include all jars which are in different folders in build path or download standalone selenium jar file and give it in build path.
package com.tesngtraining;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class TestingJunit {
private WebDriver browser;
private static final String HOME_URL = "http://localhost:8080/";
#Before
public void setUp() throws Exception {
browser = new FirefoxDriver();
}
#Test
public void testHomePage()
{
browser.get(HOME_URL);
assertEquals("Home", browser.findElement(By.id("title")).getAttribute("value"));
}
#After
public void tearDown() throws Exception
{
browser.close();
}
}
Thank you,
Murali

Related

Unable to import the org.testng.annotations.Parameters; in Eclipse version 2020-06 using TestNG version 7.3.0

I have downloaded Eclipse version 2020-06 and have installed TestNG version 7.3.0 but am unable to import org.testng.annotations.Parameters; in my Class.
I have a pre-written test that uses the #Parameters annotation:
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class Parameters {
WebDriver driver = null;
#BeforeTest
public void setup() {
System.setProperty("webdriver.chrome.driver", "C:\\Temp\\browserDrivers\\New\\chromedriver.exe");
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
}
#Parameters({"email", "password"})
#Test
public void login(String email, String password) throws InterruptedException {
driver.get("http://website.com/login?back=my-account");
driver.findElement(By.cssSelector("section input[name='email']")).sendKeys(email);
Thread.sleep(3000); //slowing test down for demonstration purposes
driver.findElement(By.cssSelector("section input[name='password']")).sendKeys(password);
Thread.sleep(3000); //slowing test down for demonstration purposes
driver.findElement(By.cssSelector("button#submit-login")).click();
}
}
Import not found
Annotation not available
Any ideas why this is happening?
The issue was that my Class was named the same as the #Parameters annotation. After refactoring my Class name to something different, Eclipse found the import and I could then use the #Parameters annotation.

Mockito 2 + Junit 5 NoSuchMethodError on AnnotationSupport.findAnnotation

I'm trying to integrate JUnit 5 under Eclipse Oxygen3.
The project already has Mockito 2.
I have done all steps suggested in https://www.baeldung.com/mockito-junit-5-extension like so:
Dependencies:
junit-jupiter-engine 5.5.0
junit-jupiter-api 5.5.0
junit-vintage-engine 5.5.0
junit-platform-runner 1.5.0
mockito-core 2.28.2
mockito-junit-jupiter 2.28.2
Code:
public class Jupiter {
public boolean isAlpha() {
return true;
}
}
Test Code:
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import java.util.Date;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
#ExtendWith(MockitoExtension.class)
#RunWith(JUnitPlatform.class)
public class JupiterTest {
#InjectMocks
private Jupiter jupiter;
#BeforeEach
public void setup() {
//usually some stuff here
}
#Test
#DisplayName("heading jupiter - make it so")
public void test() {
boolean result = jupiter.isAlpha();
assertThat(result).isTrue();
}
}
Unfortunately, running tests fail.
Have anyone stumbled upon a similar problem? Is it something general or my project specific problem?
java.lang.NoSuchMethodError: org.junit.platform.commons.support.AnnotationSupport.findAnnotation(Ljava/util/Optional;Ljava/lang/Class;)Ljava/util/Optional;
at org.mockito.junit.jupiter.MockitoExtension.retrieveAnnotationFromTestClasses(MockitoExtension.java:178)
at org.mockito.junit.jupiter.MockitoExtension.beforeEach(MockitoExtension.java:160)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$null$0(TestMethodTestDescriptor.java:126)
...
Suppressed: java.lang.NullPointerException
at org.mockito.junit.jupiter.MockitoExtension.afterEach(MockitoExtension.java:214)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$null$11(TestMethodTestDescriptor.java:214)
at org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$13(TestMethodTestDescriptor.java:226)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAllAfterMethodsOrCallbacks(TestMethodTestDescriptor.java:224)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAfterEachCallbacks(TestMethodTestDescriptor.java:213)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:116)
... 43 more
Not sure why need all that vintage and platform stuff.. Your tests are org.junit.jupiter.api.Test;
I would do this:
1) Remove all the annotations from the class level
2) Init Mockito:
#BeforeEach
public void setup() {
MockitoAnnotations.initMocks(this);
}
3) These deps should be sufficient:
junit-jupiter 5.5.0
mockito-core 2.28.2
mockito-junit-jupiter 2.28.2 allows you to use this way, this may possibly solve your problem.
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.junit.jupiter.MockitoSettings;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.quality.Strictness.LENIENT;
#MockitoSettings(strictness = LENIENT)
public class JupiterTest {
#InjectMocks
private Jupiter jupiter;
#BeforeEach
public void setup() {
//usually some stuff here
}
#Test
#DisplayName("heading jupiter - make it so")
public void test() {
boolean result = jupiter.isAlpha();
assertThat(result).isTrue();
}
}

LeanFT & Selenium custom automation framework - no HTML report generated

I have been trying to make LeanFT html reports work with my Selenium/Junit framework, however so far without any joy.
I have searched the topic multiple times on different forums incl. HP official materials and tried all setup methods that I could find.
An XML runresults file is still generated when using a custom Selenium/LeanFT framework.
I create a LeanFT Testing Project project using JUnit as my framework and Selenium as SDK. I also add relevant Selenium jars.
LeanFT version is 14.0.2816.0.
I am conscious of this issue: https://community.softwaregrp.com/t5/UFT-Practitioners-Forum/HTML-report-not-generated-in-custom-framework-using-LeanFT/td-p/1614027 .
I would be grateful, if someone could explain where I am making a mistake here or if the software version is the problem here. Any help is very much appreciated.
The actual setup contains more abstractions, is generally more complex and runs as a jar file, but I have simplified the code for the purpose of this topic as the outcome of both setups is the same - a runresults.xml and no html:
Test Class:
import com.hp.lft.report.CaptureLevel;
import com.hp.lft.report.ModifiableReportConfiguration;
import com.hp.lft.report.Reporter;
import com.hp.lft.sdk.ModifiableSDKConfiguration;
import com.hp.lft.sdk.SDK;
import com.hp.lft.sdk.web.Browser;
import com.hp.lft.sdk.web.BrowserDescription;
import com.hp.lft.sdk.web.BrowserFactory;
import com.hp.lft.sdk.web.BrowserType;
import core.Selenium;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.*;
import java.io.File;
import java.net.URI;
public class SeleniumTest extends Selenium {
WebDriver driver;
Browser browser;
public SeleniumTest() {
//Change this constructor to private if you supply your own public constructor
}
#BeforeClass
public static void setUpBeforeClass() throws Exception {
instance = new SeleniumTest();
globalSetup(SeleniumTest.class);
}
#AfterClass
public static void tearDownAfterClass() throws Exception {
globalTearDown();
}
#Before
public void setUp() throws Exception {
ModifiableSDKConfiguration sdkConfig = new ModifiableSDKConfiguration();
sdkConfig.setServerAddress(new URI("ws://localhost:5095"));
SDK.init(sdkConfig);
ModifiableReportConfiguration reportConfig = new ModifiableReportConfiguration();
reportConfig.setOverrideExisting(true);
reportConfig.setTargetDirectory("C:\\Users\\user\\IdeaProjects\\LeanFT_Selenium\\RunResults");
reportConfig.setReportFolder("LastRun");
reportConfig.setTitle("Summary");
reportConfig.setDescription("Description");
reportConfig.setSnapshotsLevel(CaptureLevel.All);
Reporter.init(reportConfig);
ChromeOptions options = new ChromeOptions();
options.addExtensions(new File
("C:\\Program Files (x86)\\HP\\Unified Functional Testing\\Installations\\Chrome\\Agent.crx"));
System.setProperty("webdriver.chrome.driver",
"C:\\HP_Reporting\\Webdriver\\chromedriver.exe");
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(ChromeOptions.CAPABILITY, options);
driver = new ChromeDriver(options);
browser = BrowserFactory.attach(new BrowserDescription.Builder()
.type(BrowserType.CHROME).build());
}
#After
public void tearDown() throws Exception {
driver.quit();
browser = null;
Reporter.generateReport();
SDK.cleanup();
}
#Test
public void test() throws Exception {
driver.get("https://www.google.co.uk/");
}
}
Selenium Class:
import com.hp.lft.report.Status;
import com.hp.lft.unittesting.UnitTestBase;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.rules.TestWatcher;
public class Selenium extends UnitTestBase{
protected static Selenium instance;
public static void globalSetup(Class<? extends Selenium> testClass) throws Exception {
if (instance == null)
instance = testClass.newInstance();
instance.classSetup();
}
#Before
public void beforeTest() throws Exception {
testSetup();
}
#After
public void afterTest() throws Exception {
testTearDown();
}
public static void globalTearDown() throws Exception {
instance.classTearDown();
getReporter().generateReport();
}
#ClassRule
public static TestWatcher classWatcher = new TestWatcher() {
#Override
protected void starting(org.junit.runner.Description description) {
className = description.getClassName();
}
};
#Rule
public TestWatcher watcher = new TestWatcher() {
#Override
protected void starting(org.junit.runner.Description description) {
testName = description.getMethodName();
}
#Override
protected void failed(Throwable e, org.junit.runner.Description description) {
setStatus(Status.Failed);
}
#Override
protected void succeeded(org.junit.runner.Description description) {
setStatus(Status.Passed);
}
};
#Override
protected String getTestName() {
return testName;
}
#Override
protected String getClassName() {
return className;
}
protected static String className;
protected String testName;
}
Libraries
TL;DR
The report is only generated in 14.00 by extending UnitTestBase. To have the report generated with a custom automation framework, you must upgrade to at least LeanFT 14.01 (latest one at the time of writting is 14.02 though).
Oh, and just for clarification: this issue has nothing to do with Selenium. You'd have the same behavior in C# LeanFT SDK using NUnit 3, for example.
Details
What is a custom automation framework in this context?
When I say custom automation framework I mean any framework that does the SDK and Reporter initialization and cleanup itself.
LeanFT does all the magic through its engine. To tell a custom framework to connect to the engine, you need perform the following steps:
at the beginning of a test suite:
SDK.init();
Reporter.init(); // This is not for the engine, but for the HTML report generation
at the end of a test suite
Reporter.generateReport();
SDK.cleanup();
When you are using the builtin templates, you'll notice that a UnitTestClassBase class is automatically created, that extends from UnitTestBase and that your LeanFtTest class extends from this UnitTestClassBase.
By doing so you are initializing the SDK and the Reporter in a very specific way, which is the reason why with this initialization the HTML report is generated. If you were to reproduce this specific way in your custom framework, you'll also have the HTML report generated. If you are curious, you can check the contents of the UnitTestBase.class file to see what it does.
You are extending from UnitTestBase. Why is it not working?
As mentioned in my comments, you are actually doing the SDK and Reporter initialization twice, once by extending the UnitTestBase (which, as I described above, does that initialization already) and the second time in your setUp method.
Since you are using LeanFT 14.00, you should let the UnitTestBase do the initialization, cleanup and report generation. This means that your Test Class file should be changed to no longer include the init of the SDK and Reporter, as follows:
import com.hp.lft.report.CaptureLevel;
import com.hp.lft.report.ModifiableReportConfiguration;
import com.hp.lft.report.Reporter;
import com.hp.lft.sdk.ModifiableSDKConfiguration;
import com.hp.lft.sdk.SDK;
import com.hp.lft.sdk.web.Browser;
import com.hp.lft.sdk.web.BrowserDescription;
import com.hp.lft.sdk.web.BrowserFactory;
import com.hp.lft.sdk.web.BrowserType;
import core.Selenium;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.*;
import java.io.File;
import java.net.URI;
public class SeleniumTest extends Selenium {
WebDriver driver;
Browser browser;
public SeleniumTest() {
//Change this constructor to private if you supply your own public constructor
}
#BeforeClass
public static void setUpBeforeClass() throws Exception {
instance = new SeleniumTest();
globalSetup(SeleniumTest.class);
}
#AfterClass
public static void tearDownAfterClass() throws Exception {
globalTearDown();
}
#Before
public void setUp() throws Exception {
/*
This will not work in LeanFT 14.00, so we are commenting it out
ModifiableSDKConfiguration sdkConfig = new ModifiableSDKConfiguration();
sdkConfig.setServerAddress(new URI("ws://localhost:5095"));
SDK.init(sdkConfig);
ModifiableReportConfiguration reportConfig = new ModifiableReportConfiguration();
reportConfig.setOverrideExisting(true);
reportConfig.setTargetDirectory("C:\\Users\\user\\IdeaProjects\\LeanFT_Selenium\\RunResults");
reportConfig.setReportFolder("LastRun");
reportConfig.setTitle("Summary");
reportConfig.setDescription("Description");
reportConfig.setSnapshotsLevel(CaptureLevel.All);
Reporter.init(reportConfig);
*/
ChromeOptions options = new ChromeOptions();
options.addExtensions(new File
("C:\\Program Files (x86)\\HP\\Unified Functional Testing\\Installations\\Chrome\\Agent.crx"));
System.setProperty("webdriver.chrome.driver",
"C:\\HP_Reporting\\Webdriver\\chromedriver.exe");
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(ChromeOptions.CAPABILITY, options);
driver = new ChromeDriver(options);
browser = BrowserFactory.attach(new BrowserDescription.Builder()
.type(BrowserType.CHROME).build());
}
#After
public void tearDown() throws Exception {
driver.quit();
browser = null;
//Reporter.generateReport();
//SDK.cleanup();
}
#Test
public void test() throws Exception {
driver.get("https://www.google.co.uk/");
}
}
But I need to configure the SDK and the Report. How can I achieve that in LeanFT 14.00?
The SDK and the Reporter can be configured in two ways:
At initialization, as you attempted to do through the ModifiableSDKConfiguration and ModifiableReportConfiguration
or
In the test settings file (resources/leanft.properties). You can see plenty details in the official help.
You can manipulate some report settings at runtime as well, through the Reporter API:
Set the report level: Reporter.setReportLevel(ReportLevel.All);
Set the snapshot capture level Reporter.setSnapshotCaptureLevel(CaptureLevel.All);
Even if you initialized the SDK and the Reporter through the base class, you can still add custom report events in the report (these work: Reporter.reportEvent();, Reporter.startReportingContext();, Reporter.startTest();, etc.)

Not download/init browser driver when used webdrivermanager-x.x.x.jar (without Maven)

For my Selenium/Java project [without Maven], using webdrivermanager-1.7.2.jar in to automate binary downloads for chromedriver but I'm getting "java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory" message.
My code:
package selenium_webdriver_api;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import io.github.bonigarcia.wdm.ChromeDriverManager;
public class Topic_29_ManageBrowserVersion {
private WebDriver driver;
#BeforeClass
public static void setupClass() {
ChromeDriverManager.getInstance().version("2.33").setup();
// Or: ChromeDriverManager.getInstance().setup();
}
#Before
public void setupTest() {
driver = new ChromeDriver();
}
#After
public void teardown() {
if (driver != null) {
driver.quit();
}
}
#Test
public void test() {
driver.get("https://github.com/bonigarcia/webdrivermanager");
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
driver.manage().window().maximize();
}
}
WebDriverManager depends on several libraries such as slf4j-api, commons-io, gson, among others (see its pom.xml for the complete list). If you are using WebDriverManager without the help of a build tool (e.g. Maven, Gradle) you need to resolve these dependencies manually. The other option is to generate a fat jar from the source, for example using the maven-assembly-plugin (info here) or maven-shade-plugin (info here).

Selenium RC is not opening url given in my code

The RC launches the firefox browser but it tries to open the following link
"chrome://src/content/RemoteRunner.html?sessionId=94c0e90deec8470ab358718255d27575&multiWindow=true&baseUrl=https%3A%2F%2Fwww.facebook.com%2F&debugMode=false&driverUrl=http://localhost:4444/selenium-server/driver/"
instead of "https://www.facebook.com/"
import static org.junit.Assert.*;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;
#SuppressWarnings("deprecation")
public class DemoClass {
private Selenium selenium;
#Before
public void setUp() throws Exception {
selenium = new DefaultSelenium("localhost", 4444, "*firefox C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe", "https://www.facebook.com/");
selenium.start();
}
#Test
public void Assignment1() throws Exception {
selenium.open("/");
assertTrue(selenium.isElementPresent("id=email"));
assertTrue(selenium.isElementPresent("id=pass"));
selenium.type("id=email", "devranipankaj163#gmail.com");
selenium.type("id=pass", "demo#123");
assertEquals("devranipankaj163#gmail.com", selenium.getValue("id=email"));
selenium.click("id=u_0_n");
selenium.waitForPageToLoad("30000");
}
#After
public void tearDown() throws Exception {
selenium.stop();
}
}
Don't use Selenium RC as it is heavily outdated and not maintained anymore.
You should be using Selenium Webdriver with the latest version being 3.1.0 for Java. If you want to run your tests against Firefox you will also need Geckodriver.
Here is a good blog post that explains the setup and other basics of Selenium 3 and Geckodriver.

Categories