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.)
Related
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).
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.
I am new to selenium and I am facing this null pointer exception in my code,
Here is a class of one of my page object (Login Page).
package Pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import Lib.lib;
public class LoginPage extends lib{
WebDriver driver;
By loginLink = By.xpath("/html/body/nav/div/a[7]");
By emailInput = By.name("email");
By passwordInput = By.name("password");
By signInBtn = By.className("btn btn-primary btn-lg");
public LoginPage(WebDriver driver)
{
this.driver=driver;
}
public void redirectToLogin()
{
driver.findElement(loginLink).click();
new WebDriverWait(driver, 30).until(ExpectedConditions.visibilityOfElementLocated(emailInput));
}
public void enterEmail(String email)
{
driver.findElement(emailInput).sendKeys(email);
}
public void enterPW(String password)
{
driver.findElement(passwordInput).sendKeys(password);
}
public void clickOnSignIn() throws Exception
{
driver.findElement(signInBtn).click();
Thread.sleep(3000);
}
public void loginToKB(String userEmail, String userPW) throws Exception
{
this.redirectToLogin();
this.enterEmail(userEmail);
this.enterPW(userPW);
this.clickOnSignIn();
}
}
And this is my Test Case code
package TestCases;
import org.testng.annotations.Test;
import Lib.lib;
import Pages.LoginPage;
public class logging_in extends lib {
LoginPage memLogin = new LoginPage(driver);
#Test
public void user_login() throws Exception
{
memLogin.loginToKB("uzii#test.com", "uziii");
}
}
I am importing the chrome driver configuration from the lib class, which is following,
package Lib;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.AfterTest;
public class lib {
protected static WebDriver driver = null;
#BeforeTest
public void chrome_extension()
{
System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.addArguments("--start-maximized");
driver = new ChromeDriver(options);
driver.get("http://www.testsite.com");
}
#AfterTest
public void quit()
{
driver.quit();
}
}
When I am running my Test Case (logging_in), I initially redirect to website page, but after that it stops the execution and gives me compound class error.
Error seems to be pointed towards this,
By signInBtn = By.className("btn btn-primary btn-lg");
Please let me know, how to handle compound classes. Any help/feedback will be appreciated. Thanks.
You are passing static driver instance without initialization to LoginPage(Webdriver driver) constructor. You would need to initialize the drive either in static block in lib or before initializing memLogin variable in logging_in page.
for compound classes you will have to use XPath. if you can show us html snippet of your DOM, we should be able to tell you the relevant XPath.
You have declared web-driver driver instance as private in class lib which is correct then your'e again declaring web-driver driver instance in class LoginPage which is incorrect.
Remove the second declaration to avoid the null pointer exception.
We recorded a test case to log into jira using Selenium IDE. And it was running correctly.BUT when it exported to java web driver(jUnit4), it did not worked and gave element not found error.
The code is :
package newjiralogin;
import java.util.concurrent.TimeUnit;
import org.junit.*;
import static org.junit.Assert.*;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
public class NewJiraLogin {
private WebDriver driver;
private String baseUrl;
private final StringBuffer verificationErrors = new StringBuffer();
#Before
public void setUp() throws Exception {
driver = new FirefoxDriver();
baseUrl = "http://jiratest/";
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
}
#Test
public void testUntitled2() throws Exception {
driver.get("http://jiratest");
driver.findElement(By.id("login-form-username")).clear();
driver.findElement(By.id("login-form-username")).sendKeys("saumlk");
driver.findElement(By.id("login-form-password")).clear();
driver.findElement(By.id("login-form-password")).sendKeys("saumlk");
driver.findElement(By.id("login")).click();
}
#After
public void tearDown() throws Exception {
driver.quit();
String verificationErrorString = verificationErrors.toString();
if (!"".equals(verificationErrorString)) {
fail(verificationErrorString);
}
}
The main Method class :
package newjiralogin;
import org.junit.runner.JUnitCore;
public class NewJiralogintest {
public static void main(String[] args) throws Exception {
JUnitCore.main("newjiralogin.NewJiraLogin");
}
}
The login form resides inside an iframe, i.e. before accessing the elements you have to switch the context of the driver, .e.g.
driver.switchTo().frame("gadget-0");
(assuming "gadget-0" is the id of the frame which contains the login box).
I'm not an expert for the IDE->WebDriver conversion, but it seems that the context switch got lost. If you want to implement UI automation for JIRA, have a look at the JIRA PageObjects which really ease many of the common tasks. A sample how they can be employed is available at the Atlassian documentation pages or here: https://blog.codecentric.de/en/2014/07/part-3-agile-testing-jira-plugins-system-tests/. This blog entry is part of a short series we wrote b/c we had similar issues and wanted to share what we learned.
I have dozens of Selenium Webdriver tests. I want to run them all at once. How do I run the test so that each test does not open a new Webdriver browser window?
Is a solution something like this possible? This causes nullPointError from driver.
#ClassnameFilters({"com.company.package*", ".*Test"})
public class TestSuite {
public static WebDriver driver;
#BeforeClass
public static void setUpClass() {
driver = new FirefoxDriver();
}
#AfterClass
public static void setDownClass() {
driver.quit();
}
}
public class Test {
private WebDriver driver = TestSuite.driver;
#Test.... {
}
Putting the new object initialization attribute gets the first test running, but then the others cause unreachable browser error. Please help!
hah, sorry for my inattentiveness.
This causes nullPointError from driver that can be caused only by improper web driver initialization.
As you declare public static WebDriver driver; in public class TestSuite and create instance in
#BeforeClass
public static void setUpClass() {
driver = new FirefoxDriver();
}
you don't need in
public class Test
initialize
private WebDriver driver = TestSuite.driver; once again.
Instead of it I would use inheritance public class Test from public class TestSuite in the following way and in my tests annotated by #Test simply called my driver as it is initialized as static. Code be like:
public class Test extends TestSuite {
#Test
public void findButtonAndClickOnIt(){
String buttonCssSelector ="...blablabla...";
driver.findElement(By.cssSelector(buttonCssSelector)).click();
}
}
hope now it works for you.
to handle this issue try using #BeforeClass, #AfterClass annotation:
import com.google.common.base.Function;
import com.thoughtworks.selenium.SeleneseTestBase;
import junit.framework.Assert;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.openqa.selenium.*;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
public class BaseSeleniumTest extends SeleneseTestBase {
static WebDriver driver;
#Value("login.base.url")
private String loginBaseUrl;
#BeforeClass
public static void firefoxSetUp() throws MalformedURLException {
DesiredCapabilities capability = DesiredCapabilities.firefox();
driver = new RemoteWebDriver(new URL("http://192.168.4.52:4444/wd/hub"), capability);
driver = new FirefoxDriver(); //for local check
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
driver.manage().window().setSize(new Dimension(1920, 1080));
}
#Before
public void openFiretox() throws IOException {
driver.get(propertyKeysLoader("login.base.url"));
}
#AfterClass
public static void closeFirefox(){
driver.quit();
}
....
#BeforeClass means that you initialize something and all the following selenium tests annotated by #Test be run in a single browser window open.
Hope this helps you.