So i have NUnit tests and Extent Report HTML report. After each test execution, in case of failure i want to show the screenshot inside my HTML report.
So this is what i have tried:
After each test execution, in case of test failure:
[TearDown]
public void AfterEachTest()
{
var status = TestContext.CurrentContext.Result.Outcome.Status;
if (status == TestStatus.Failed)
{
string path = Browser.CaptureScreeshot();
BaseReport.ExtentTest.Log(Status.Fail, "Test fail");
BaseReport.ExtentTest.AddScreenCaptureFromPath(path);
}
}
As you can see string path = Browser.CaptureScreeshot() returns my .png screenshot, this path is valid and exist but inside the report this look like that:
Why my picture is not recognized ?
I also tried AddScreenCaptureFromBase64String instead of AddScreenCaptureFromPathbut even that didn't work.
Please check with this:
//To take screenshot
Screenshot file = ((ITakesScreenshot)driver).GetScreenshot();
//To save screenshot
file.SaveAsFile(parentDirName + "\\Screenshots\\" + SSName + ".png", ScreenshotImageFormat.Png);
//To log screenshot
testlog.Info("Details", MediaEntityBuilder.CreateScreenCaptureFromPath( "\\Screenshots\\" + SSName + ".png").Build());
Related
I am using coded UI platform for automation. If test case fails system automatic take screen shot but once it pass system is not able to capture screenshot of the test case. I am using C# selenium commands in the script.
Environment
Visual studio premium 2012.
I tried following thing.
Enable a log trace in QTAgent32.exe.config ( ).
LoggerOverrideState = HtmlLoggerState.AllActionSnapshot; but getting error in LoggerOverrideState.
[TestMethod]
public void demo2()
{
TestContext.WriteLine("Go to URL\n");
driver.Navigate().GoToUrl("http://www.test.com/");
driver.Manage().Window.Maximize();
// Enter username
TestContext.WriteLine("TestContext Writeline: test context \n");
js.ExecuteScript("arguments[0].setAttribute('value','username')", driver.FindElement(By.XPath("//*[#id='txtUsername']")));
//Enter password
js.ExecuteScript("arguments[0].setAttribute('value','password')", driver.FindElement(By.XPath("//*[#id='txtPassword']")));
// Click on the login Button
js.ExecuteScript("arguments[0].click();", driver.FindElement(By.XPath("//*[#id='btLoginNow']")));
You could put something like the following in your code to take a screenshot at any given point:
Image SubmissionPic = UITestControl.Desktop.CaptureImage();
SubmissionPic.Save(#"C:\AutomatedScreenShots\SubmissionPage_" + TestContext.DataRow["Division"].ToString() + "_" + DateTime.Now.ToString("yyyy-MM-dd") + ".bmp");
Note: The filename formatting I've used above can be changed to whatever suits your needs. I just pulled this code from a test I'd written a while back.
After every Testcase you can call the Take Screen shot in both the case either Pass or Fail
ex.
Suppose Test Method to do Successful Login
#Test
public void ValidUserNamePasswordLoginTest() {
// Your code to do Assertion
}
Now use #AfterMethod in your call which will execute as soon as your test perform
#AfterMethod
public void takeScreenShot(ITestResult testResult) throws IOException
{
if(testResult.getStatus() == ITestResult.SUCCESS)
{
File src = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(src, new File("Screensot\\"+filename+".jpg"));
}
if(testResult.getStatus() == ITestResult.FAILURE)
{
File src = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(src, new File("Screensot\\"+filename+".jpg"));
}
}
Couldn't you just use the [TestCleanup] and create a method using that Attribute that will take a screenshot, that way you will always get a Screenshot not matter the result? Is that what you require?
So, You could so this on the WebDriver setup:
public static IWebDriver SetUp()
{
private static IWebDriver _webDriver;
firingDriver = new EventFiringWebDriver(new ChromeDriver()); //Or whatever driver you want. You could also use the Activator class and create a Generic instance of a WebDriver.
var screenshot = new CustomScreenshot(firingDriver);
firingDriver.ScriptExecuted += screenshot.TakeScreenshotOnExecute;
_webDriver = firingDriver;
return _webDriver;
}
Then for the screenshot something like:
public class CustomScreenshot
{
private IWebDriver _webDriver;
public CustomScreenshot(IWebDriver webDriver)
{
_webDriver = webDriver;
}
public void TakeScreenshotOnExecute(object sender, WebDriverScriptEventArgs e)
{
var filePath = "Where you want to save the file.";
try
{
_webDriver.TakeScreenshot().SaveAsFile(filePath, ImageFormat.Png);
}
catch (Exception)
{
//DO something
}
}
}
The whole issue of taking a screen shot of a browser window & naming it based on unique properties (e.g., browser title, date-time stamp, etc) proved to be extremely difficult because of the tool (CodedUI) not what I wanted to do. I won't editorialize concerning my opinion of the functionality (lack of) of this tool but it is definitely not as robust as Selenium. So how I accomplished this was I got a high level 'browser title' from this-> and used the following for taking & storing the screen shot in my MyTestCleanup() method.
public void MyTestCleanup()
{
//Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.AllThreads;
//--------------------------------------------------------------------------------------------
DateTime time = DateTime.Now;
this.UIMap
var ttest = time.Millisecond.ToString();
var timeSecs = DateTime.Now.Millisecond;
var Window = this;
var ext = ".png";
Image screen = UITestControl.Desktop.CaptureImage();
string dirPath = string.Format("C\\:Users\\smaretick\\Desktop\\SCREENS\\{0}{1}", ttest, ext);
string dirPathN = string.Format("/C copy C:\\Users\\smaretick\\Desktop\\SCREENS\\CUIT.png C:\\Users\\smaretick\\Desktop\\SCREENS\\{0}{1}", ttest, ext);
string dirPathF = string.Format("/C copy C:\\Users\\smaretick\\Desktop\\SCREENS\\CUIT.png C:\\Users\\smaretick\\Desktop\\SCREENS\\{0}{1}{2}", Window, ttest, ext);
//string dirPathF = string.Format("/C copy C:\\Users\\smaretick\\Desktop\\SCREENS\\{0}{1}{2}", Window, ttest, ext);
UITestControl.Desktop.CaptureImage().Save("C:\\Users\\smaretick\\Desktop\\SCREENS\\CUIT.png");
string cmdF = string.Format("C\\:Users\\smaretick\\Desktop\\SCREENS\\{0}{1}", ttest, ext);
Process.Start("CMD.exe", dirPathF);
//--------------------------------------------------------------------------------------------
LogOut();
contact me if you need any more help (scottmaretick51#gmail.com)
I am using asp.net file upload control
I am uploading the image to the server as as UserID+"ProfilePic" .
After uploading I am setting an image src to this via code behind
string FolderPath = System.Configuration.ConfigurationManager.AppSettings["PATH"].ToString();
string assoid = HttpContext.Current.Session["strAssociateId"].ToString()+"ProfilePic.jpg";
if (FileUpload1.HasFile)
{
try
{
string fileName = FileUpload1.FileName;
FileUpload1.PostedFile.SaveAs(FolderPath +assoid);
string imagePath = "serverpath" +assoid;
face_crop_original.Src = imagePath; //Problem is here
}
}
So here what happens is the image is getting uploaded, but when I set the image.Src=xxxx it's taking the old image from cache!! Please help.
public static string VersionCssUrl(string url)
{
// Get physical path.
try
{
var path = HttpContext.Current.Server.MapPath(url);
return url + "?v=" + String.Format(File.GetLastWriteTime(path).ToString("MMddyyhhmmss"));
}
catch
{
return url;
}
}
and your code will look like this
<img src="<%= VersionCssUrl("your src".ToString()) %>" />
Now,Explaination you know what will happen is this will request the file everytime but it will check modification date of your file so you will have previous one if does not changed will definately load from cache.....
and if your file has been changed it will load new file automatically this all depends on your datetime.....
i hope this will help you regards...:)
I found a simple solution which is working for me :)
You can check the source here
What I did is I attached the datetime.now as #dholakiyaankit suggested but in a different place
string fileName = FileUpload1.FileName;
FileUpload1.PostedFile.SaveAs(FolderPath +assoid);
string imagePath = "server path" +assoid;
face_crop_original.Src = imagePath+"?"+DateTime.Now;
NOTE: Here my imagepath variable will be "xxxxxx.jpg" so
face_crop_original.Src = imagePath+"?"+DateTime.Now;
will be "http://xxxxxxxx.com/imagename.jpg?Randomnumber"
This enabled me to upload the image with same name (USERID+"Profilepic") and i need not write code for deleting older file as the name will be same and it will be replaced in server !
I am using Telerik asp.net MVC 3 file control in my Razor view (Catalog/Product View) like this:
#(Html.Telerik().Upload()
.Name("orderImageAtachment")
.Async(async => async.Save("Save", "Catalog").AutoUpload(true))
.ClientEvents(events => events
.OnSuccess("ItemImageOnSuccess")
.OnError("ItemImageOnError")
)
)
I have created an ActionResult like this:
public ActionResult Save(IEnumerable<HttpPostedFileBase> orderImageAtachment, string CompID)
{
// The Name of the Upload component is "attachments"
foreach (var file in orderImageAtachment)
{
// Some browsers send file names with full path. This needs to be stripped.
var fileName = Path.GetFileName(file.FileName);
var physicalPath = Path.Combine(Server.MapPath("~/Content/Docs"), fileName);
// The files are not actually saved in this demo
file.SaveAs(physicalPath);
}
// Return an empty string to signify success
return Content("");
}
and client side functions like this:
function onSuccess(e) {
// Array with information about the uploaded files
var files = e.files;
if (e.operation == "upload") {
alert("Successfully uploaded " + files.length + " files");
}
}
function onError(e) {
alert('Error in file upload');
// Array with information about the uploaded files
var files = e.files;
if (e.operation == "upload") {
alert("Failed to uploaded " + files.length + " files");
}
// Suppress the default error message
e.preventDefault();
}
I get select button which opens browse window. But clicking it does nothing.... I am not sure whats wrong. Do I need to add something in web.config? Please suggest.
I'm a little confused at which point its not working, but I'm assuming its not hitting the action in your controller. I'd make sure you are trying a fairly small file, the default limit is 4mb.
Also it looks like the signature of your Save Action does not match the route you are giving it in the upload's async.Save(...). I'm not sure it will matter since its a string, but you might try removing the Save actions's CompID parameter (doesn't look like its used in the snippet at least).
I'd try using fiddler or the developer tools in whichever browser you are using to see if u are getting a 404 error by chance.
everytime i change a file such as a .rft or .txt i want it to display the name in the title for e.g RFT Editor:docment.rft
here the code i am using atm
this.Text = "RFT Editor:" + saveFileDialog1.FileName;
hope someone can help
Your question is poorly worded. You don't describe how the result you are getting is different from what you'd like it to be.
I can only guess the problem is that "RFT Editor:" + saveFileDialog1.FileName gives you a file name with an entire path, and to get "RFT Editor:docment.rft" as in your example you'd need "RFT Editor:" + System.IO.Path.GetFileName(saveFileDialog1.FileName) instead.
Assuming you need this:
...
...
// Save clicked inside, not Cancel
if(saveFileDialog1.openDialog() == DialogResult.OK)
{
// this.Text is same as only Text - in case of current class (matter of choice)
Text = "RTF Editor: " + savefileDialog1.FileName;
...
...
}
I need a way to take screenshots of my functional tests. Right now I'm using Selenium 2 with C# bindings. I pretty much want to take a screenshot at the end of the test to make sure the desired page is displayed. Are there any particular tools you guys know of that I can incorporate into my C# code that will trigger a screenshot? I couldn't find a built-in Selenium 2 solution (without looking it over).
To do screenshots in Selenium 2 you need to do the following
driver = new FireFoxDriver(); // Should work in other Browser Drivers
driver.Navigate().GoToUrl("http://www.theautomatedtester.co.uk");
Screenshot ss = ((ITakesScreenshot) driver).GetScreenshot();
//Use it as you want now
string screenshot = ss.AsBase64EncodedString;
byte[] screenshotAsByteArray = ss.AsByteArray;
ss.SaveAsFile("filename", ImageFormat.Png); //use any of the built in image formating
ss.ToString();//same as string screenshot = ss.AsBase64EncodedString;
That code should work, as I quickly tested it in IronPython Repl. See the IronPython code below
import clr
clr.AddReference("WebDriver.Common.dll")
clr.AddReference("WebDriver.Firefox.dll")
from OpenQA.Selenium import *
from OpenQA.Selenium.Firefox import *
driver = FirefoxDriver()
driver.Navigate().GoToUrl("http://www.theautomatedtester.co.uk")
s = driver.GetScreenshot()
s.AsBaseEncodedString
# HUGE string appears in the REPL
var driver = new InternetExplorerDriver();
driver.Navigate().GoToUrl("http://www.google.com");
var ss = driver.GetScreenshot();
ss.SaveAsFile("ss.png", System.Drawing.Imaging.ImageFormat.Png);
I don't know if it matters, but I ended up having to cast the driver when i was writing in c#.
something like:
Screenshot ss = ((ITakesScreenshot)driver).GetScreenshot();
Just use the extension method TakeScreenshot() in one line of code.
IWebDriver driver = new InternetExplorerDriver();
driver.Navigate().GoToUrl("Your_Homepage_Url");
driver.TakeScreenshot().SaveAsFile("file_name_string", ImageFormat.Jpeg);
Add a reference of System.Drawing in your solution/project.
Use System.Drawing.Imaging namespace in your test.
Here I am capturing the screen shot of Facebook Home page.
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using NUnit.Framework;
using System.IO;
using System.Collections;
using System.Drawing.Imaging;
namespace FacebookRegistrationUsingC_Sharp
{
[TestFixture]
public class ScreenShot
{
IWebDriver driver = null;
IWebElement element = null;
[SetUp]
public void SetUp()
{
driver = new ChromeDriver("G:\\Selenium_Csharp\\Jar\\chromedriver_win32");
driver.Navigate().GoToUrl("https://www.Facebook.com");
driver.Manage().Window.Maximize();
}
[Test]
public void TestScreenShot()
{
Screenshot ss = ((ITakesScreenshot)driver).GetScreenshot();
ss.SaveAsFile("e:\\pande", System.Drawing.Imaging.ImageFormat.Jpeg);
}
[TearDown]
public void TearDown()
{
driver = null;
element = null;
}
}
}
public void TakeScreenshot(string saveLocation) {
var location = GetPath() + _name + "\\" + saveLocation + ".png";
var ssdriver = _driver as ITakesScreenshot;
var screenshot = ssdriver.GetScreenshot();
screenshot.SaveAsFile(location, ImageFormat.Png);
}
This code will help you to take screen shot
JAVA
protected void fullPageScreenshot(String testname) {
String timeStamp = new SimpleDateFormat("dd_MM_yyyy_HH_mm_ss").format(Calendar.getInstance().getTime());
String imageName = testname + "-" + timeStamp + ".png";
Screenshot screenshot = new AShot().shootingStrategy(ShootingStrategies.viewportPasting(2000))
.takeScreenshot(DriverManager.getDriver());
try {
ImageIO.write(screenshot.getImage(), "PNG", new File("./FullPage_Screenshots/" + imageName));
} catch (Exception e) {
System.out.println("Capturing FullPage Screenshot failed");
}
}
use Ashot library to take fullpage screenshots - even where pages needs to be scrolled
https://mvnrepository.com/artifact/ru.yandex.qatools.ashot/ashot/1.5.4
Use System.Drawing.Imaging reference.
Following code can be used for taking screenshot.
IWebDriver driver = new FirefoxDriver();
ITakesScreenshot screenshotDriver = driver as ITakesScreenshot;
Screenshot screenshot = screenshotDriver.GetScreenshot();
String fp = "D:\\" + "snapshot" + "_"+ DateTime.Now.ToString("dd_MMMM_hh_mm_ss_tt") + ".png";
screenshot.SaveAsFile(fp, ImageFormat.Png);
Notes:
Timestamp has two advantages:
1) You'll get to know the perfect DateTime when screenshot is taken.
2) SaveAsFile function overwrites the existing file. So, DateTime can help for different file creation.
ScreenCaptureJob scj;
scj = new ScreenCaptureJob();
// Specify the path & file name in which you want to save
scj.OutputScreenCaptureFileName = #"C:\Users\jpavankumar\Desktop\Screencaptuere\ScreenRecording4.wmv";
// Start the Screen Capture Job
scj.Start(); scj.Stop();
Try this code out here ... hope it will be useful to you .... !
Define this in global code :
var counter = DateTime.Now.Ticks.ToString();
((ITakesScreenshot)driver).GetScreenshot().SaveAsFile((snap +counter + ".jpg").ToString(), OpenQA.Selenium.ScreenshotImageFormat.Jpeg);
test.Log(LogStatus.Fail, "Snapshot below: " + test.AddScreenCapture(snap + counter + ".jpg"));
driver.Url = "https://www.amazon.in/";
//Store image in bin folder
((ITakesScreenshot)driver).GetScreenshot().SaveAsFile("CurrentPage.png");
//Store image in D drive
((ITakesScreenshot)driver).GetScreenshot().SaveAsFile(#"D:\CurrentPage.png");
Best way to take screenshot and store in the file location in a generic way in python :
def screenShots(self):
fileName= NewFile + "." + str(round(time.time() * 1000)) + ".png"
screenshotDirectory = "../screenshot/" #Move to that directory where you want ot store the screenshot
relativeFileName = screenshotDirectory + fileName
currentDirectory = os.path.dirname(__file__)
destinationFile = os.path.join(currentDirectory,relativeFileName)
destinationDirectory = os.path.join(currentDirectory,screenshotDirectory)
try:
if not os.path.exists(destinationDirectory):
os.makedirs(destinationDirectory)
self.driver.save_screenshot(destinationFile)
self.log.info("Screenshot saved to directory" + destinationFile)
except:
self.log.error("Exception Occured")
print_stack()
Using selenium there were two calls I was familiar with: captureEntirePageScreenshot and captureScreenshot. You might want to look into those calls to see if they'll accomplish what you're after.