Emailed extent reports doesn't load screenshots - java

I am trying to send my extent reports as email. The reports as being sent. The problem is the screenshots in my extent reports is missing in the email. If I open the report in my local device, the screenshot is there.
This is for a Selenium test am doing. I am using extent reports for my logs. I am trying to send my extent reports as email. The reports as being sent. The problem is the screenshots in my extent reports is missing in the email. If I open the report in my local device, the screenshot is there. Below is code of my Listeners.java
import com.relevantcodes.extentreports.ExtentReports;
import com.relevantcodes.extentreports.ExtentTest;
import com.relevantcodes.extentreports.LogStatus;
public class Listeners implements ITestListener {
protected static WebDriver driver;
protected static ExtentReports reports;
public static ExtentTest test;
Base B = new Base();
public void onTestStart(ITestResult result) {
test = reports.startTest(result.getMethod().getMethodName());
test.log(LogStatus.INFO, result.getMethod().getMethodName() + " test started");
}
public void onTestSuccess(ITestResult result) {
test.log(LogStatus.PASS, result.getMethod().getMethodName() + " test passed");
}
public void onTestFailure(ITestResult result) {
test.log(LogStatus.FAIL, result.getMethod().getMethodName() + " test failed");
try {
B.getScreenshot(result.getName());
String file =
test.addScreenCapture("/Users/username/Documents/Eclipse-Workspace/Test/test-output/"+result.getName()+"screenshot.png");
test.log(LogStatus.FAIL, result.getMethod().getMethodName() + "test failed", file);
} catch (IOException e) {
e.printStackTrace();
}
}
public void onTestSkipped(ITestResult result) {
test.log(LogStatus.SKIP, result.getMethod().getMethodName() + " test skipped");
}
public void onStart(ITestContext context) {
System.out.println("Started");
driver = new ChromeDriver();
reports = new ExtentReports( "./test-output/Extentreports.html");
}
public void onFinish(ITestContext context) {
driver.close();
reports.endTest(test);
reports.flush();
}
}
I expect to view the screenshot taken on test failure when I receive the email. But now I see an empty thumbnail in the emailed extent report.

This question has been raised multiple times in the past. A quick search would have pointed you in the right direction.
The solution is to email the report along with screenshots as a zip file, and ensuring images are saved relatively to the Html file.

Related

screen shot is not displayed in extent report

The screen shot is taken and stored in the folder. but its not displaying for the failed test.
displayed as corrupted image.
Java Code:
public synchronized void onTestFailure(ITestResult result) {
System.out.println((result.getMethod().getMethodName() + " failed!"));
test.get().fail(MarkupHelper.createLabel(result.getName()+ " - Test failed due to below issue/error: ", ExtentColor.RED));
test.get().fail(result.getThrowable());
//Take screenshot and allow automatic saving of media files relative to the report
//Extentreports log and screenshot operations for failed tests.
try {
File src=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// String base64Screenshot = "data:image/png;base64,"+((TakesScreenshot)driver).getScreenshotAs(OutputType.BASE64);
String path=prop.getProperty("Screenshot_Folder")+System.currentTimeMillis()+".png";
File destination=new File(path);
FileUtils.copyFile(src, destination);
test.get().fail("Below is Screen Shot of Error Page/Pop-up: ", MediaEntityBuilder.createScreenCaptureFromPath(path).build());
//test.get().fail("Below is Screen Shot of Error Page/Pop-up: ", MediaEntityBuilder.createScreenCaptureFromBase64String(base64Screenshot).build());
} catch (Exception e) {
e.printStackTrace();
System.out.println("Screen-capture has been taken but not attached to Extent report");
}
}
below is the property file.
AutomationReport_Folder = D://Shared//V1core_automation
ExtentReport_Folder = D://Shared//V1core_automation//ExtentReports//
Screenshot_Folder = D://Shared//V1core_automation//ExtentReports//Screenshots//
Method for screen shot
public static String getScreenshot(WebDriver driver)
{
TakesScreenshot ts=(TakesScreenshot) driver;
File src=ts.getScreenshotAs(OutputType.FILE);
String path=System.getProperty("user.dir")+"/Screenshots/"+System.currentTimeMillis()+".png";
File destination=new File(path);
try
{
FileUtils.copyFile(src, destination);
} catch (IOException e)
{
System.out.println("Capture Failed "+e.getMessage());
}
return path;
}
Replace this line in your code:
test.get().fail("Below is Screen Shot of Error Page/Pop-up: ", MediaEntityBuilder.createScreenCaptureFromPath(path).build());
With
MediaEntityBuilder.addScreenCaptureFromPath(path, result.getMethod().getMethodName());
and see it works.
I had a similar requirement to store screenshots in base64 as reports will be shared with multiple stakeholders across my team. The following solution worked well for me.
Screenshot.java
public static String getScreenshot(WebDriver driver) {
String screenshotBase64 = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BASE64);
return screenshotBase64;
}
TestListener.java
#Override
public void onTestFailure(ITestResult result) {
test.fail("Test case Failed");
test.fail("Failed step: ",MediaEntityBuilder.createScreenCaptureFromBase64String("data:image/png;base64,"+Screenshot.getScreenshot(driver)).build());
test.fail(result.getThrowable());
}

How do I close() and quit() Selenium driver without affecting other steps in Cucumber and Selenium?

I have two feature files in Cucumber that are linked to corresponding step files. The problem is that when one of the step file finishes execution then it closes all the browser windows (because of driver.quit()) whereby killing the execution of other step file which hasn't done processing yet.
Here each step file opens a new browser window, executes the tests within it and then closes and quits the browser. Currently I have just two step files but in the future there are going to be many more.
Is there anything in Cucumber that would always get executed after all the steps are executed?
How do I solve this problem?
HelpStep.java
#Ignore
public class HelpStep {
private WebDriver driver;
#Before
public void setup() {
System.out.println("Into the setup method of HelpStep...");
this.driver = BrowserConfig.getIEWebDriver();
}
#Given("^The user is on the Help page$")
public void onPage() {
System.out.println("The user is on the Help page");
}
#When("^The user clicks on the links within the Help page$")
public void clickLinks() {
System.out.println("The user clicks on the links within the Help page");
}
#Then("^The user is navigated to that section$")
public void validate() {
System.out.println("The user is navigated to that section");
}
#After
public void cleanUp() {
System.out.println("Into the cleanUp method of HelpStep...");
//FOLLOWING METHOD CALL KILLS ALL THE OPEN BROWSERS ALSO :(
BrowserConfig.releaseResources(this.driver);
}
}
LinkStatsStep.java
#Ignore
public class LinkStatsStep {
private WebDriver driver;
#Before
public void setup() {
System.out.println("Into the setup method of LinkStatsStep...");
this.driver = BrowserConfig.getIEWebDriver();
}
#Given("^The user is on the Link Statistics page$")
public void onPage() {
System.out.println("The user is on the Link Statistics page");
}
#When("^The user does a search$")
public void clickLinks() {
System.out.println("The user does a search");
}
#Then("^The user is displayed search result$")
public void validate() {
System.out.println("The user is displayed search result");
}
#After
public void cleanUp() {
System.out.println("Into the cleanUp method of LinkStatsStep...");
BrowserConfig.releaseResources(this.driver);
}
}
TestRunner.java
#RunWith(Cucumber.class)
#CucumberOptions(
plugin = {"pretty", "json:target/cucumber-reports/cucumber.json"},
features = {"src/test/resources/features"})
public class TestRunner extends ApplicationTests {
}
BrowserConfig.java
public class BrowserConfig {
private static final String IE_DRIVER_EXE = "drivers/IEDriverServer.exe";
private static final String WEBDRIVER_IE_DRIVER = "webdriver.ie.driver";
private static final String BASE_URL = "https://www.google.com";
public static WebDriver getIEWebDriver() {
String filePath = ClassLoader.getSystemClassLoader().getResource(IE_DRIVER_EXE).getFile();
System.setProperty(WEBDRIVER_IE_DRIVER, filePath);
InternetExplorerOptions options = new InternetExplorerOptions().requireWindowFocus();
options.setCapability(INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
options.setCapability(ENABLE_ELEMENT_CACHE_CLEANUP, true);
options.setCapability(IE_ENSURE_CLEAN_SESSION, true);
options.setCapability(ACCEPT_SSL_CERTS, true);
options.setCapability("nativeEvents", false);
options.setCapability(INITIAL_BROWSER_URL, BASE_URL);
System.out.println("Initializing IE Driver now...........");
WebDriver driver = new InternetExplorerDriver(options);
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
return driver;
}
public static void releaseResources(WebDriver driver) {
System.out.println("Releasing resources now.....");
if (null != driver) {
driver.close();
driver.quit(); //CLOSES ALL THE OPEN BROWSER SESSIONS LEAVING OTHER STEP EXECUTIONS INCOMPLETE
}
}
}
help.feature
Feature: Check that the user is able to navigate to Help page
Scenario:
Given The user is on the Help page
When The user clicks on the links within the Help page
Then The user is navigated to that section
link-stats.feature
Feature: Check that the user is able to navigate to Link Statistics page
Scenario:
Given The user is on the Link Statistics page
When The user does a search
Then The user is displayed search result
System.outs
Initializing IE Driver now...........
Listening on port 47613
Into the setup method of LinkStatsStep...
Initializing IE Driver now...........
Listening on port 5009
The user is on the Help page
The user clicks on the links within the Help page
The user is navigated to that section
Into the cleanUp method of HelpStep...
Releasing resources now.....
Into the cleanUp method of LinkStatsStep...
Releasing resources now.....
Into the setup method of HelpStep...
Initializing IE Driver now...........
Listening on port 17291
Into the setup method of LinkStatsStep...
Initializing IE Driver now...........
Listening on port 23793
The user is on the Link Statistics page
The user does a search
The user is displayed search result
Into the cleanUp method of HelpStep...
Releasing resources now.....
Into the cleanUp method of LinkStatsStep...
Releasing resources now.....
Looking at your code it would appear to be correct.
Calling quit should close all open windows associated with that webdriver session. It should not close windows of other webdriver sessions. So I think you are facing a problem in the IEDriverServer.
If this is the case and if you are running your tests in a JVM that shuts down after all tests have been executed. Then as a work around you can use shut down hooks to call quite and close all web driver sessions. For example:
private static final Thread CLOSE_THREAD = new Thread() {
#Override
public void run() {
// Start a new webdriver to call quit on
// For IE this will terminate all webdriver sessions
getIEWebDriver().quit();
}
};
static {
Runtime.getRuntime().addShutdownHook(CLOSE_THREAD);
}
Posted the answer here as this question is more or less similar earlier one.
https://stackoverflow.com/a/55836832/2325154
It is because driver management not done properly. I would suggest to use qaf which does driver and resource management. With QAF your step file will look like below:
public class HelpStep {
//setup or tear-down not required here...
#Given("^The user is on the Help page$")
public void onPage() {
//you can access driver any where like below:
//WebDriver driver = new WebDriverTestBase().getDriver();
System.out.println("The user is on the Help page");
}
#When("^The user clicks on the links within the Help page$")
public void clickLinks() {
System.out.println("The user clicks on the links within the Help page");
}
#Then("^The user is navigated to that section$")
public void validate() {
System.out.println("The user is navigated to that section");
}
}
To access driver object any where in the code you can get it from test base.
WebDriver driver = new WebDriverTestBase().getDriver();
Below are examples of interacting with element anywhere in the code:
Using findBy
driver.findElement("name=q").click();
Using element factory
import static com.qmetry.qaf.automation.ui.webdriver.ElementFactory.$;
...
$("name=q").click();
Using inbuilt step library
import static com.qmetry.qaf.automation.step.CommonStep.*;
...
click("name=q");
in example above name=q is element locator using name as locator strategy, which will automatically converted to By.name.
LinkStatsStep
import static com.qmetry.qaf.automation.step.CommonStep.*;
...
public class LinkStatsStep {
#Given("^The user is on the Link Statistics page$")
public void onPage() {
get("/");
}
#When("^The user does a search$")
public void clickLinks() {
System.out.println("The user does a search");
click("elementlocator");
//$("elementlocator").click();
}
#Then("^The user is displayed search result$")
public void validate() {
verifyLinkWithPartialTextPresent("link text");
//$("partialLink=link text").verifyPresent();
}
}
Your gherkin file will remain same. To run your gherkin file use GherkinScenarioFactory
You can specify browser to use using driver.name property. You don't need to write code for creating or tearing down driver. You can set behavior of driver session by using selenium.singletone property.
#this will tear down driver after each testcase/scenario
selenium.singletone=method
#this will tear down driver after each xml test node in configuration file
selenium.singletone=test
#this will tear down driver after each xml test node in configuration file and will reuse same driver session for testcases/scenario configured under same xml test node.
selenium.singletone=test
#this will tear down driver after each xml suite node in configuration file.
selenium.singletone=suite

Trying to upload an image from android app to cloud using kinvey

I'm trying to upload an image, saved in the internal memory of my phone, clicked by an android app to a cloud service, and am using Kinvey to do so. But I'm facing some problems with it.
Every time I run the code that contains the upload part, I encounter an exception. I'm uploading an image of ".png" type. Any conversion to blob is not a necessary process that is required, unlike that in Google Cloud Platform.
Here is my .java code -
`Client mKinveyClient = new Client.Builder(APP_KEY, SECRET_KEY, this.getApplicationContext()).build();
mKinveyClient.enableDebugLogging();
mKinveyClient.ping(new KinveyPingCallback() {
public void onFailure(Throwable t) {
Log.e(TAG, "Kinvey Ping Failed", t);
}
public void onSuccess(Boolean b) {
Log.d(TAG, "Kinvey Ping Success");
}
});
java.io.File file = new java.io.File(Environment.getExternalStorageDirectory().getPath() + "/Camera/" + "IMG_20161115_193353.jpg");
mKinveyClient.file().upload(file, new UploaderProgressListener() {
public void onSuccess(Void result) {
Log.i(TAG, "successfully upload file");
}
#Override
public void onSuccess(FileMetaData fileMetaData) {
Log.i(TAG, "successfully uploaded file");
}
#Override
public void onFailure(Throwable error) {
Log.e(TAG, "failed to upload file.", error);
}
#Override
public void progressChanged(MediaHttpUploader uploader) throws IOException {
Log.i(TAG, "upload progress: " + uploader.getUploadState()); // all updates to UI widgets need to be done on the UI thread
}
});`
Now, although the ping call is giving me a successful response, the upload part is giving me an error.
E/Activity file: failed to upload file.
com.kinvey.java.KinveyException:
REASON: No user is currently logged in.
I've searched a lot on this topic, on kinvey's discussion platform and here too. But I'm still stuck. I don't know where I'm going wrong or what I might be missing.
If anyone is out there who has successfully managed to upload images through kinvey then please help me out.
Any kind of Kinvey operations must be provided via a logged user.
You must sign up (or login) before you start to i/o any information.
mKinveyClient.user().create("username", "password", new KinveyUserCallback()) {
#Override
public void onFailure(Throwable t) {
CharSequence text = "Could not sign up.";
Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
#Override
public void onSuccess(User u) {
//here we go on uploading file
}
});
You can find more info about users here
Sharmistha,
Yes, every app action needs an active user context.
So you will need to login in the app and then upload the file.
Please take a look at the following:
http://devcenter.kinvey.com/android/guides/users#ActiveUser
http://devcenter.kinvey.com/android/guides/files#Uploading
Thanks,
Pranav
Kinvey

Cucumber #Before hook opening multiple browser windows

I'm not clear why I am getting 3 chrome browsers opening for the following example. I have an #Before (cucumber version) annotation to simply setup a chrome webdriver instance before the scenario runs. As far as I can see, it should open one browser, run scenario (step defs) then close using the #After cucumber hook. What happens is 2 windows open before a third and final window actually executes the steps:
Scenario:
Given I am on the holidays homepage
When I select the departure location "LON"
And I select the destination location "PAR"
And I submit a search
Then search results are displayed
Step Def:
public class FindAHolidayStepDefs {
private WebDriver driver;
#Before
public void setup() {
System.setProperty("webdriver.chrome.driver",
System.getProperty("user.dir") + "\\drivers\\chromedriver.exe");
driver = new ChromeDriver();
}
#Given("^I am on the Holidays homepage$")
public void IAmOnTheThomasCookHomepage() {
driver.get("http://uat7.co-operativetravel.co.uk/");
driver.manage().window().maximize();
String pageTitle = driver.getTitle();
assertEquals("the wrong page title was displayed !", "Holidays - welcome", pageTitle);
}
#When("^I select the departure location \"([^\"]*)\"$")
public void ISelectTheDepartureLocation(String departureAirport) {
WebElement dropDownContainer = driver.findElement(By.xpath("(//div[#class=\"custom-select departurePoint airportSelect\"])[1]"));
dropDownContainer.click();
selectOption(departureAirport);
}
#When("^I select the destination location \"([^\"]*)\"$")
public void ISelectTheDestinationLocation(String destinationAirport) {
WebElement destinationField = driver.findElement(By.xpath(("(//div[#class=\"searchFormCol destinationAirport\"]/div[#class=\"combinedInput searchFormInput\"]/span/input)[1]")));
destinationField.sendKeys(destinationAirport);
selectOption("(" + destinationAirport + ")");
}
#When("^I submit a search$")public void iSubmitASearch() throws Throwable {
WebElement submitButton = driver.findElement(By.xpath("(.//*[#type='submit'])[1]"));
submitButton.click();
}
#Then("^search results are displayed$")
public void searchResultsAreDisplayed() throws Throwable {
waitForIsDisplayed(By.xpath(".//*[#id='container']/div/div[3]/div/div[1]/div/h3"), 30);
assertThat(checkPageTitle(), equalTo("Package Results"));
}
#After
public void tearDown() {
driver.quit();
}
}
When I step through the code in Intellij, the following method is called:
private void runHooks(List<HookDefinition> hooks, Reporter reporter, Set<Tag> tags, boolean isBefore)
and Intellij reports that hooks paramter = 3 at this point.
hooks: size=3 reporter: "null" tags: size = 0 isBefore: true
Do you have more then one scenario in your feature? -> The #Before method will be executed before each scenario.
Do you have a different stepdef class with #Before annotated method that opens chrome? -> All #Before methods will be called before a scenario is executed.

Java program won't write to firebase [duplicate]

I'm trying to write a simple test of the Firebase user creation and authentication routines so that I can test my Firebase security settings. The code runs smoothly but the callbacks are not invoked and no users are created on the Firebase side.
The output of below with the print statements is:
Begin process
Start Create User
Creating User
End Creating User
End process
Process finished with exit code 0
The code is using the firebase-client-android-2.2.3.jar file for the Firebase classes though I'm just running my test as a java application on a Mac OS. Later this will go into an Android app but I'd like to be able to run it inside my IDE for now. Any insights from experienced Firebase coders much appreciated.
import com.firebase.client.Firebase;
import com.firebase.client.AuthData;
import com.firebase.client.FirebaseError;
import java.util.*;
public class FireRulesTest {
static String firebase_baseUrl = "https://<myfirebase>.firebaseio.com/";
public static void main(String[] args)
throws FirebaseException {
System.out.println("Begin process");
FireRulesTest tester = new FireRulesTest();
tester.createUser();
System.out.println("End process");
}
private void createUser()
throws FirebaseException {
try {
System.out.println("Start Create User");
final String mEmail = "me#email.com";
final String mPassword = "password";
final Firebase ref = new Firebase(firebase_baseUrl);
System.out.println("Creating User");
ref.createUser(mEmail, mPassword,
new Firebase.ValueResultHandler<Map<String, Object>>() {
#Override
public void onSuccess(Map<String, Object> result) {
System.out.println("Successfully created user account with uid: " + result.get("uid"));
ref.authWithPassword(mEmail, mPassword, new Firebase.AuthResultHandler() {
#Override
public void onAuthenticated(AuthData authData) {
//success, save auth data
HashMap<String, Object> authMap = new HashMap<String, Object>();
authMap.put("uid", authData.getUid());
authMap.put("token", authData.getToken());
authMap.put("email", mEmail);
authMap.put("password", mPassword);
Firebase currentUserRef = new Firebase(firebase_baseUrl + "movo/users/" + authData.getUid());
authMap.put("currentUser", currentUserRef);
System.out.println("User ID: " + authData.getUid() +
", Provider: " + authData.getProvider() +
", Expires:" + authData.getExpires());
System.out.println("Authentication complete");
}
#Override
public void onAuthenticationError(FirebaseError firebaseError) {
System.out.println("Authentication Error authenticating newly created user. This could be an issue. ");
System.out.println(firebaseError.getMessage());
}
});
}
#Override
public void onError(FirebaseError firebaseError) {
System.out.println("On Error authenticating newly created user. This could be an issue. ");
System.out.println(firebaseError.getMessage());
}
});
System.out.println("End Creating User");
} catch (Exception fbe) {
System.out.println("Exception: " + fbe.getMessage());
fbe.printStackTrace();
}
}
}
You'll want to add a Thread.sleep at the end of the program. Likely your program exits before Firebase gets a chance to send anything to the server.
A more proper solution would be to introduce actual lifecycle management into your app, e.g. waiting for the createUser call to finish. But given that you'll be migrating this to Android (which handles app lifecycle completely different anyway) that might not be worth the effort.

Categories

Resources