Extent Reports 4 - Java - java

Trying to generate one extent report, that will allow me to run a suite of test classes and give output as one report.
My current code below runs fin, it will run my testNG.xml file and successfully run all test classes in my suite. THe extent report itself however, only seems to save the last test cases run to it. I can't for the life of me figure out how to stop it overwriting, and append to it instead. Older version of extent report uses htmlreporter.setAppendExisting(true); but that does not exist in extent 4..
public class ExtentManager {
ExtentHtmlReporter htmlReporter;
ExtentReports extent;
ExtentTest parentTest;
ExtentTest childTest;
DriverManager driverManager;
WebDriver driver;
Screenshot screenshot;
Properties config;
String timeStamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
/** Suite test as it will run, with Before/After instructions*/
#BeforeTest
public void beforeTest() throws IOException {
/**Create extent reports and configure html report*/
htmlReporter = new ExtentHtmlReporter(".//reports/ExtentReport"+timeStamp+".html");
extent = new ExtentReports();
extent.attachReporter(htmlReporter);
htmlReporter.config().setTheme(Theme.DARK);
htmlReporter.config().setDocumentTitle("Automation Testing");
htmlReporter.config().setReportName("My Report");
htmlReporter.config().setAutoCreateRelativePathMedia(true);
htmlReporter.config().setTimeStampFormat("HH:mm:ss");
screenshot = new Screenshot();
config = new Properties();
FileInputStream fis = new FileInputStream(System.getProperty("user.dir") + "/src/main/resources/Config.properties");
config.load(fis);
}
public ExtentReports getExtent(){
if(extent != null){
return this.extent;
} else {
return new ExtentReports();
}
}
#BeforeClass
public void beforeClass() {
/**Setup parent test, all child tests to follow
*will attach to it for html report*/
extent = getExtent();
parentTest = extent.createTest(getClass().getSimpleName());
driverManager = new DriverManager();
driver = driverManager.getWebDriver();
driver.manage().timeouts().pageLoadTimeout(15, TimeUnit.SECONDS);
}
#AfterMethod
public void getResult(ITestResult result) throws IOException {
if (result.getStatus() == ITestResult.SUCCESS){
childTest.log(Status.PASS, MarkupHelper.createLabel("Test Case: " + result.getName() + " PASSED", ExtentColor.GREEN));
}else if(result.getStatus() == ITestResult.FAILURE){
String screenshotPath = screenshot.getScreenshot(driver, result.getName());
childTest.log(Status.FAIL, MarkupHelper.createLabel("Test Case: " + result.getName() + " FAILED", ExtentColor.RED));
childTest.fail(result.getThrowable().getMessage());
childTest.log(Status.WARNING, "Error screenshot captured and stored # " + screenshotPath);
childTest.addScreenCaptureFromPath(screenshotPath);
}else if(result.getStatus() == ITestResult.SKIP){
childTest.log(Status.SKIP, MarkupHelper.createLabel("Test Case: " + result.getName() + " SKIPPED", ExtentColor.AMBER));
childTest.log(Status.SKIP, "Skipped test: " + result.getName());
}
}
#AfterTest
public void afterTest(){
driverManager.quitWebDriver();
}
#AfterSuite
public void afterSuite() {
extent.flush();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="sanity_tests" parallel="false" verbose="10">
<test name="test1" parallel="false" preserve-order="true" verbose="10">
<classes>
<class name="com.testFramework.Tests.test1"/>
</classes>
</test>
<test name="test2" parallel="false" preserve-order="true" verbose="10">
<classes>
<class name="com.testFramework.Tests.test2"/>
</classes>
</test>
</suite>

you can use the Extent report adapters and with that there is no need to write any code, check the below article out. In your case- you will need to use the TestNG adapter-
Try this: https://www.linkedin.com/pulse/extent-framework-adapters-anshoo-arora/`

Related

TestNG Dataprovider closing driver after each iteration

I am trying to run a dataprovider based test using ANT. My main class points to testNG file
XmlSuite suite=new XmlSuite();
suite.setName("Test Results");
suite.setPreserveOrder(true);
List<XmlSuite> suits=new ArrayList<XmlSuite>();
suits.add(suite);
List<XmlPackage> xpackage=new ArrayList<XmlPackage>();
xpackage.add(new XmlPackage(TestProperties.TESTNG_PACKAGE.toString()));
XmlTest test=new XmlTest(suite);
test.setPackages(xpackage);
String groups=TestProperties.TESTNG_GROUP.toString();
System.out.println("groups are:"+groups);
String groupArray[]=groups.split(",");
List<String> includedGroups=new ArrayList<String>();
includedGroups.addAll(Arrays.asList(groupArray));
test.setIncludedGroups(includedGroups);
TestNG tng=new TestNG();
tng.setOutputDirectory("test-output");
tng.setXmlSuites(suits);
tng.run();
System.exit(0);
Now, in my Testcase file, I have
#BeforeClass(alwaysRun = true)
public void pretest() throws IOException, GeneralSecurityException {
Pretest
}
#Test(groups= {"indicatorGroup","",""},description = "Validate indicator uploaded", dataProvider = "getIndicatorData")
public void indicatorUpload(String txt){
test
}
#DataProvider
public Object[] getIndicatorData() throws IOException, GeneralSecurityException
{
bla bla
for(int i=0; i<contents.length; i++) {
System.out.println(contents[i]);
if(!contents[i].contains("README")) {
blah blah
System.out.println(path);
names.add(path);
}
}
String[] myArray = new String[names.size()];
names.toArray(myArray);
return myArray;
}
#AfterClass(alwaysRun = true)
public void afterMethod() throws IOException {
System.out.println("Deleting all files after operation.....");
}
The problem is, they run without any issues, if i run from Testng. ie if i right click on the file, click on run, click on Run as Testng Test.
But if I run from my build file, after the first iteration, the driver I bring up in before class, closes and the rest of the tests fail. This causes my tests to fail in jenkins.
Can someone please help me out?
After many trials, I found out that the testng xml created By my trigger file had
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="IndicatorSuite" data-provider-thread-count="1">
<test name="Test Basics 1">
<groups>
<run>
<include name="indicatorUpload" />
</run>
</groups>
<classes>
<class name="Uploads.IndicatorFileUpload">
<class name="Uploads.IndicatorFileUpload1">
<class name="Uploads.IndicatorFileUpload2">
</methods>
</class>
</classes>
</test>
</suite>
Even though my test group was correct, I had given test package, because of which all my testcase files had been added as classes. All of these had a listener which would close the driver after testrun. I dont know much about testng, but I think it mixed up the listeners. In my Trigger file, when I added just
TestNG tng=new TestNG();
tng.setOutputDirectory("test-output");
//tng.setXmlSuites(suits);
tng.setTestClasses(new Class[] { IndicatorFileUpload.class });
tng.run();
it worked!

TestNG does not continue execute tests after failure

I have test automation framework with a page object model.
All my test are located in separate classes in same package.
In testng.xml i have
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Smoke Test">
<test name="SmokeTest">
<classes>
<class name="name.test1"/>
<class name="name.test2"/>
<class name="name.test3"/>
</classes>
</test>
</suite>
Problem is that after running TestNG.xml if the 1st test will fail, it will stop test execution. But i want to continue executing of all test cases.
I use Jenkins on my project and if one of the tests are failed it stops execution immediately.
Example of test
public class LoginTestTest {
public AndroidDriver<AndroidElement> driver;
public AOWebClient aoWebClient;
AOWebClient aoWeb;
public LoginTestTest(AndroidDriver<AndroidElement> driver, AOWebClient aoWeb){
this.driver = driver;
this.aoWeb = aoWeb;
PageFactory.initElements(new AppiumFieldDecorator(driver), this);
}
public LoginTestTest() {
}
SoftAssert softAssert = new SoftAssert();
#BeforeClass
public void setUp() throws Exception {
driver = DesiredCapabilitiesSetup.startAppiumServer();
aoWebClient = DesiredCapabilitiesSetup.getAOWeb();
LogIn logIn = new LogIn(driver,aoWebClient);
logIn.logIn();
}
#org.testng.annotations.Test
public void goToSettings() throws InterruptedException {
HeaderMenu header = new HeaderMenu(driver,aoWeb);
HamburgerMenuList ham = new HamburgerMenuList(driver);
header.clickHamburgerButton();
header.clickHamburgerButton();
header.editButtonClick();
softAssert.assertAll();
}
#AfterClass
public void tearDown(ITestResult result) throws Exception {
if (result.getStatus() == ITestResult.FAILURE) {
TakeScreenshot screenshot = new TakeScreenshot();
screenshot.TakeScreenshot("screenshots/");
}
LogOut logOut = new LogOut(driver,aoWeb);
logOut.logOut();
}
}
If my test will fail in #Test it will never continue to #AfterClass method.
And I want that if #Test fail it will continue to #AfterClass method and After This Class continue executes test from other classes from testng.xml.
Your suite tag in your xml should include configfailurepolicy="continue". This tells testng that even though a config failed in one class, you still want to run other classes in that suite. See "configfailurepolicy" in the documentation.
So your xml would become:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Smoke Test" configfailurepolicy="continue">
<test name="SmokeTest">
<classes>
<class name="name.test1"/>
<class name="name.test2"/>
<class name="name.test3"/>
</classes>
</test>
</suite>
From the documentation:
alwaysRun: For after methods (afterSuite, afterClass, ...): If set to
true, this configuration method will be run even if one or more
methods invoked previously failed or was skipped.
Then, just replace your #AfterClass by #AfterClass(alwaysRun = true).
Add below attribute in testng.xml file under Suite syntax
<suite thread-count="25" name="Smoke" parallel="classes" skipfailedinvocationcounts="true">
Work for me, hope it will work for you as well :)

Test framework architecture using Selenium WebDriver and TestNG

guys. I trying to solve a problem with parallel running using RC Webdriver and TestNG, but unfortunately, I can't find solution last few hours. Maby you will see the code, and show me what, I actually doing wrong.
Goal:
Create architecture using RC WebDriver and TestNG, with an ability to run tests on a remote machine.
Main settings class is Sut:
private RemoteWebDriver driver = null;
#BeforeClass
public WebDriver getWebDriver() {
DesiredCapabilities dc = new DesiredCapabilities();
FirefoxProfile fp = new FirefoxProfile();
dc.setCapability(FirefoxDriver.PROFILE, fp);
dc.setBrowserName(DesiredCapabilities.firefox().getBrowserName());
try {
driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), dc);
} catch (MalformedURLException e) {
e.printStackTrace();
}
return driver;
}
#AfterClass
public void tearDown() {
driver.quit();
}
In this class we have two methods: getWebDriver() - for setup our remote webdriver, and tearDown() - for close web-page, when a test will be complete.
Class BaseStep:
private static ThreadLocal<Sut> sut = new ThreadLocal<Sut>();
public static Sut getSut() {
Sut currentSut = sut.get();
if (currentSut == null) {
currentSut = new Sut();
}
return currentSut;
}
It's an additional layer, which create 'new state for each new thread'.
Few page objects:
public class FacebookPage {
public void testLink() {
getSut().getWebDriver().get("http://facebook.com");
}
}
public class GooglePage {
public void testLink() {
getSut().getWebDriver().get("http://google.com");
}
}
And scenarious classes:
public class VerifyGooglePage {
GooglePage googlePage = new GooglePage();
#Test
public void verifyGoogleMainPage() {
googlePage.testLink();
}
}
public class VerifyFacebookPage {
Facebook facebookPage = new Facebook();
#Test
public void verifyFacebookeMainPage() {
facebookPage.testLink();
}
}
And my and testNG.xml file for running
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite thread-count="1" name="Suite" parallel="tests">
<test name="FirstTest">
<classes>
<class name="scenarious.VerifyGooglePage"/>
</classes>
</test> <!-- Test -->
<test name="SecondTest">
<classes>
<class name="scenarious.VerifyFacebookPage"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
The problems is: When test complete, browser is not closed.
the Picture
I watched a lot of tutorials and articles in internet about it, but in no-one I cant found solution for my case. Could you please help me to find what I doing wrong.

Parellel testing with TestNG - Tests only run on one browser

I have created a test suite using
DataProvider
DataFactory
and my TestNG file is sending browser details as parameters. In testNG XML I'm calling my data factory class. I'm also using browsestack for testing (although I doubt this has anything to do with the problem I"m having)
Tests run without any issues when I don't add parrellel="true" to testng file.
I have a feeling it has something to do with same driver being used by each browser, but I'm out of depth to solve this at the moment.
Any guidance is appreciated.
Here's the code.
TestNG.XML
<suite name="Suite" verbose="1" parallel="tests">
<!-- Test with Chrome -->
<test name="ChromeTest" group-by-instances="true">
<parameter name="browser" value="Chrome"></parameter>
<parameter name="browserVersion" value="47"></parameter>
<parameter name="platform" value="Windows"></parameter>
<parameter name="platformVersion" value="7"></parameter>
<classes>
<class name="Resources.TestFactory"/>
</classes>
</test>
<!-- Test with Firefox -->
<test name="FirefoxTest" group-by-instances="true">
<parameter name="browser" value="Firefox"></parameter>
<parameter name="browserVersion" value="43"></parameter>
<parameter name="platform" value="Windows"></parameter>
<parameter name="platformVersion" value="7"></parameter>
<classes>
<class name="Resources.TestFactory"/>
</classes>
</test>
</suite>
Data Factory Class
public class TestFactory {
#Factory(dataProvider = "LoginCredentials", dataProviderClass=TestData.class)
public Object[] createInstances(int testNo, String userName, String password) {
Object[] result = new Object[1];
int i=0;
System.out.println("Inside LoginCredentials Factory - " + userName + "---" + password);
if(testNo==1){
result[i] = new Test_BookingEngine_Login(userName, password);
i++;
System.out.println("Object Array : " + Arrays.deepToString(result));
}
else if(testNo==2){
result[i] = new Test_BookingManagement_OpenBooking(userName);
i++;
System.out.println("Object Array : " + Arrays.deepToString(result));
}
System.out.println("outside for");
return result;
}
}
Suite - Driver Initialization
#BeforeTest
#Parameters(value ={"browser", "browserVersion", "platform", "platformVersion"})
public void initBrowser(String browser, String browserVersion, String platform, String platformVersion) throws Exception{
//Initializing browser in cloud
cloudCaps = new DesiredCapabilities();
cloudCaps.setCapability("browser", browser);
cloudCaps.setCapability("browser_version", browserVersion);
cloudCaps.setCapability("os", platform);
cloudCaps.setCapability("os_version", platformVersion);
cloudCaps.setCapability("browserstack.debug", "true");
cloudCaps.setCapability("browserstack.local", "true");
driver = new RemoteWebDriver(new URL(URL), cloudCaps);
}
Sample Test
public Test_BookingEngine_Login(String userName, String password) {
this.userName = userName;
this.password = password;
}
#Test (groups = {"Login"})
public void testHomePageAppearCorrect() throws InterruptedException{
//Starting test and assigning test category
test = logger.startTest("Login to Temptation", "<b>Successful user login or Pop up advising incorrect login details</b><br/><br/>" + browserInfo)
.assignCategory("Regression", "Booking Engine")
.assignAuthor("Dinesh Cooray");
System.out.println("Inside login test");
System.out.println("Browser inside login test : ");
driver.get("http://dev-thor2.tempoholidays.com/");
test.log(LogStatus.INFO, "HTML", "Navigated to http://dev-thor2.tempoholidays.com/");
//create Login Page object
objLogin = new BookingEngine_Login(driver);
//login to application
objLogin.loginToTemptationBookingEngine(userName, password, test);
//check if alert advising username or password is is incorrect
try {
//incorrect login details, user should not allow login
if(driver.switchTo().alert().getText().toLowerCase().contains("user name or password is wrong")){
test.log(LogStatus.INFO, "HTML", "<b>Popup - </b>" + driver.switchTo().alert().getText());
driver.switchTo().alert().accept();
Assert.assertTrue(true);
}
}
I am guessing RemoteWebDriver driver; would be a line you added at the class level.
What is happening is that you have already declared the variable at class level. i.e. memory is already allocated to it.When you do something like this driver = new RemoteWebDriver(new URL(URL), cloudCaps); you are just setting and resetting the values of the same variable in every #BeforeTest
What you need to do is create a factory that will return an instance of RemoteWebDriver based on a parameter you pass to it.Essentially the factory will create a new object and return only if an existing object doesn't exist.
Declare and initialise the driver (from factory) in your #Test Methods
Sample code for the factory would be something like
static RemoteWebDriver firefoxDriver;
static RemoteWebDriver someOtherDriver;
static synchronized RemoteWebDriver getDriver(String browser, String browserVersion, String platform, String platformVersion)
{
if (browser == 'firefox')
{
if (firefoxDriver == null)
{
DesiredCapabilities cloudCaps = new DesiredCapabilities();
cloudCaps.setCapability("browser", browser);
cloudCaps.setCapability("browser_version", browserVersion);
cloudCaps.setCapability("os", platform);
cloudCaps.setCapability("os_version", platformVersion);
cloudCaps.setCapability("browserstack.debug", "true");
cloudCaps.setCapability("browserstack.local", "true");
firefoxDriver = new RemoteWebDriver(new URL(URL),cloudCaps);
}
}
else
{
if (someOtherDriver == null)
{
DesiredCapabilities cloudCaps = new DesiredCapabilities();
cloudCaps.setCapability("browser", browser);
cloudCaps.setCapability("browser_version", browserVersion);
cloudCaps.setCapability("os", platform);
cloudCaps.setCapability("os_version", platformVersion);
cloudCaps.setCapability("browserstack.debug", "true");
cloudCaps.setCapability("browserstack.local", "true");
someOtherDriver = new RemoteWebDriver(new URL(URL),cloudCaps);
}
return someOtherDriver;
}
}
}

testNG parallel execution not working

I am trying to run following test in parallel for two browsers using testNG, while running both the browsers are getting launched with the URL, but the complete test execution is happening for only one browser.
Here is my Test Suite class
#Test (groups = {"Enable"})
#SuppressWarnings("unused")
public class EETestSuite_01 extends ApplicationFunctions{
String URL = Globals.GC_EMPTY;
#BeforeTest
#Parameters("browser")
public void loadTest(String browser) throws IOException{
InitializeTestEnv("EE|BizApp");
if(browser.equalsIgnoreCase("Firefox"))
GetBrowser("Firefox");
else if(browser.equalsIgnoreCase("Chrome")){
GetBrowser("Chrome");
}
}
#AfterMethod
public void cleartest() throws InterruptedException{
driver.close();
driver.quit();
driver = null;
}
public void TC001_Phone_First_Acquisition_Journey_PAYM() throws InterruptedException{
URL = EnvDetail.get(Globals.GC_HOME_PAGE);
Map<String,String> TDChoosePlan = null;
TDChoosePlan = getData(appName+Globals.GC_TEST_DATA_SHEET,"ChoosePlan",1);
try{
launchApp(URL);
//driver.navigate().to("javascript:document.getElementById('overridelink').click()");
EEHomePage homePage = PageFactory.initElements(driver, EEHomePage.class);
EEShopPage shopPage = homePage.GetToShopPage();
EEPhoneMatrixPage phonePage = shopPage.GetToPhoneMatrixPage();
EEChoosePlanPage planPage = phonePage.ChoosePhone("NokiaLumia1020"); // Implement select phone
EEAddonsPage addonPage = planPage.SelectPhonesPlan(TDChoosePlan);
EEBasket basketPage = addonPage.GoToBasketPage();
EESecureCheckOut secureChkOutPage = basketPage.GoToSecureCheckOutPage();
secureChkOutPage.ChooseNonExistingCustomer();
EEConfirmation confPage = secureChkOutPage.FillUserRegisterForm(2);
}catch(Exception e){
e.printStackTrace();
}
}
}
My XML looks like this
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name = "EEAutomationTestSuite" verbose="2" parallel = "tests" thread-count="100">
<test name="PAYM Acquisition in Chrome">
<parameter name="browser" value="Firefox"></parameter>
<classes>
<class name="com.testsuite.EETestSuite_01">
</class>
</classes>
</test>
<test name="PAYM Acquisition in FF">
<parameter name="browser" value="Firefox"></parameter>
<classes>
<class name="com.testsuite.EETestSuite_01">
</class>
</classes>
</test>
</suite>
And my code for the Home page is this
*/ public EEShopPage GetToShopPage() throws InterruptedException{
// longWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(OR.getProperty("wblShopHeader"))));
lblShopHeader = driver.findElement(By.cssSelector(OR.getProperty("wblShopHeader")));
Actions builder = new Actions(driver);
Actions hoverOverRegistrar = builder.moveToElement(lblShopHeader);
hoverOverRegistrar.perform();Thread.sleep(10000);
lnkStartShopping = driver.findElement(By.cssSelector(OR.getProperty("lnkStartShopping")));
mediumWait.until(ExpectedConditions.elementToBeClickable(By.cssSelector(OR.getProperty("lnkStartShopping"))));
lnkStartShopping.click();
return PageFactory.initElements(driver,EEShopPage.class );
}
}
Here is the driver
public static void GetBrowser(String browser){
try{
if (browser.equalsIgnoreCase("firefox")) {
// FirefoxProfile firefoxProfile = new FirefoxProfile();
// File pathToBinary = new File(Globals.GC_FIREFOX_BIN_PATH);
// FirefoxBinary ffBinary = new FirefoxBinary(pathToBinary);
//firefoxProfile.setPreference("webdriver.load.strategy","unstable");
driver = new FirefoxDriver();
} else if (browser.equalsIgnoreCase("iexplorer")){
System.setProperty("webdriver.ie.driver", System.getProperty("user.dir") +
"//resource//drivers//IEDriverServer.exe");
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
driver = new InternetExplorerDriver(capabilities);
} else if (browser.equalsIgnoreCase("chrome")){
System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir") +
"//resource//drivers//chromedriver.exe");
I am just guessing that there is a hover action in the home page, and for one browser it works fine but for the other nothing happens.... is it due focus issue ??
Please let me know how to solve this with an example
I cannot make it out from your code, which constructor you are using for your page Object EEHomePage.
Because, if you are using default constructor then your PageFactory will not be able to initialize your web elements unless they are defined by #FindBy annotation,
PageFactory takes webDriver and Object class as arguments and internally initializes that Object class with provided webDriver.This can be achieved by two ways as below :
1) either define your webElements in your pageObjects using #FindBy annotations as follow :
#FindBy(css=//your locator value here)
private WebElement lblShopHeader;
OR
2) define constructor and initialize your pageobject webdriver by PageFactory provided webdriver as follow :
EEHomeShop(WebDriver driver){
this.driver=driver;
}

Categories

Resources