Best way to take screenshots of tests in Selenium 2? - c#

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.

Related

Android Unity3D VideoPlayer Playing video "from URL" not working properly

Platform: Unity 2020.1.0f1
I have a weird problem while creating a little game that is meant to download videos from a remote URL to Application.PersistentDataPath and play them in the Unity3D-VideoPlayer using the "RenderTexture"-way by pressing a button for a specific video.
In the editor EVERYTHING works fine...
On IOS EVERYTHING works fine...
On Android (no matter which version) only the video from the asset folder is played properly. Accessing a downloaded file from Application.persistentDataPath is simply showing nothing on Android...
Things I checked (in addition to simple blindness):
"External Write Permission" > forced everything on "internal"... not working
Using Path.Combine() and/or "string filepath = ..."
"Different Video Formats" > nope... the asset video is playing properly without transcoding (it is h.264 AVC, 650x650px, 30fps - AAC Audio, 44,1kHz, Bps 32)
Sample code below, the test scene can also be downloaded here:
http://weristaxel.de/upload/Videotest.unity
http://weristaxel.de/upload/VideotestController.cs
Video in Unity asset folder:
https://corolympics.azurewebsites.net/assets/game1howto.mov
What am I missing?
public void PlayFromPersistent()
{
// NOT WORKING ON ANDROID
VideoPlayer VideoHowTo = VideotestCanvas.transform.Find("VideoPlayer").GetComponent<VideoPlayer>();
string filePath = Application.persistentDataPath + "/game2howto.mov";
VideoHowTo.Stop();
VideoHowTo.url = filePath;
VideoHowTo.source = VideoSource.Url;
DebugText.text = "VideoHowTo.url = " + filePath;
VideoHowTo.Prepare();
VideoHowTo.Play();
}
public void PlayFromAssets()
{
// WORKING ON ANDROID
VideoPlayer VideoHowTo = VideotestCanvas.transform.Find("VideoPlayer").GetComponent<VideoPlayer>();
VideoHowTo.Stop();
VideoHowTo.clip = assetVideo;
VideoHowTo.source = VideoSource.VideoClip;
DebugText.text = "VideoHowTo.clip set - original path " + assetVideo.originalPath;
VideoHowTo.Play();
}
public void DownloadVideo()
{
// THIS DOWNLOADS A TEST VIDEO TO "persistentDataPath"...
string url = "https://corolympics.azurewebsites.net/assets/game2howto.mov";
Debug.Log("Downloading " + url);
var uwr = new UnityWebRequest(url, UnityWebRequest.kHttpVerbGET);
string filename = url.Split('/').Last();
string path = Path.Combine(Application.persistentDataPath , filename);
uwr.downloadHandler = new DownloadHandlerFile(path);
uwr.SendWebRequest();
DebugText.text = "Download to " + path + " finished";
}
public void AddListener()
{
// NOT WORKING ON ANDROID - THIS ADDS A LISTENER TO AN EMPTY BUTTON TO EMULATE THE TARGET BEHAVIOUR
Button button = VideotestCanvas.transform.Find("FromPersistentListenerButton").GetComponent<Button>();
Color blueColor = new Color32(52, 152, 219, 255);
button.GetComponent<Image>().color = blueColor;
button.onClick.AddListener(() =>
{
VideoPlayer VideoHowTo = VideotestCanvas.transform.Find("VideoPlayer").GetComponent<VideoPlayer>();
string filePath = Application.persistentDataPath + "/game2howto.mov";
VideoHowTo.Stop();
VideoHowTo.url = filePath;
VideoHowTo.source = VideoSource.Url;
DebugText.text = "VideoHowTo.url = " + filePath;
VideoHowTo.Play();
});
}
If you're still stuck i would try creating an independant function for when you add the listener event. So it would be something like 'button.onClick.AddListener(() => IndFunction())' instead of creating a new instance each time. I was stuck on something similar a while back and i created an editable script for each button to store the info for each one and set each according to a list of image links and image names.

C# add extent report screenshot into HTML report

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());

Hows the following code run in autocad?

Hello this is my code and i don't know how to run and get output of this code. Please suggest me the answer for this.And I want to create command for autocad using this code so suggest me according to this requirement.
using System;
using System.IO;
using System.Globalization;
using UDC;
using AutoCAD = Autodesk.AutoCAD.Interop;
namespace AutoCADtoPDF
{
class Program
{
static void PrintAutoCADtoPDF(string AutoCADFilePath)
{
//Create a UDC object and get its interfaces
IUDC objUDC = new APIWrapper();
IUDCPrinter Printer = objUDC.get_Printers("Universal Document Converter");
IProfile Profile = Printer.Profile;
//Use Universal Document Converter API to change settings of converterd drawing
//Load profile located in folder "%APPDATA%\UDC Profiles".
//Value of %APPDATA% variable should be received using Environment.GetFolderPath method.
//Or you can move default profiles into a folder you prefer.
string AppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string ProfilePath = Path.Combine(AppDataPath, #"UDC Profiles\Drawing to PDF.xml");
Profile.Load(ProfilePath);
Profile.OutputLocation.Mode = LocationModeID.LM_PREDEFINED;
Profile.OutputLocation.FolderPath = #"c:\UDC Output Files";
Profile.PostProcessing.Mode = PostProcessingModeID.PP_OPEN_FOLDER;
AutoCAD.AcadApplication App = new AutoCAD.AcadApplicationClass();
double Version = double.Parse(App.Version.Substring(0, 4), new CultureInfo("en-US"));
//Open drawing from file
Object ReadOnly = false;
Object Password = Type.Missing;
AutoCAD.AcadDocument Doc = App.Documents.Open(AutoCADFilePath, ReadOnly, Password);
//AutoCAD.Common.AcadPaperSpace ActiveSpace;
AutoCAD.Common.AcadLayout Layout;
//Change AutoCAD preferences for scaling the drawing to page
if (Doc.ActiveSpace == 0)
Layout = Doc.PaperSpace.Layout;
else
Layout = Doc.ModelSpace.Layout;
Layout.PlotType = AutoCAD.Common.AcPlotType.acExtents;
Layout.UseStandardScale = true;
Layout.StandardScale = AutoCAD.Common.AcPlotScale.acScaleToFit;
Layout.CenterPlot = true;
Object nBACKGROUNDPLOT = 0, nFILEDIA = 0, nCMDDIA = 0;
if (Version >= 16.1f)
{
nBACKGROUNDPLOT = Doc.GetVariable("BACKGROUNDPLOT");
nFILEDIA = Doc.GetVariable("FILEDIA");
nCMDDIA = Doc.GetVariable("CMDDIA");
Object xNull = 0;
Doc.SetVariable("BACKGROUNDPLOT", xNull);
Doc.SetVariable("FILEDIA", xNull);
Doc.SetVariable("CMDDIA", xNull);
}
Doc.Plot.QuietErrorMode = true;
//Plot the drawing
Doc.Plot.PlotToDevice("Universal Document Converter");
if (Version >= 16.1f)
{
//Restore AutoCAD default preferences
Doc.SetVariable("BACKGROUNDPLOT", nBACKGROUNDPLOT);
Doc.SetVariable("FILEDIA", nFILEDIA);
Doc.SetVariable("CMDDIA", nCMDDIA);
}
//Close drawing
Object SaveChanges = false;
Doc.Close(SaveChanges, Type.Missing);
//Close Autodesk AutoCAD
App.Quit();
}
static void Main(string[] args)
{
string TestFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestFile.dwg");
PrintAutoCADtoPDF(TestFilePath);
}
}
}
Did you read the comments in the original source ?
This code is a example of using a third part application name Universal Document Converter (UDC) to build a standalone application (exe) to print the active space of a dwg file into a pdf file.
It requires the UDC software to be installed.
It cannot be transformed into an AutoCAD plugin (dll with CommandMethod).
You certainly can get more informations about this with the UDC Support.
You will not learn .NET and AutoCAD API by copying codes found on the web that you do not understand and asking someone here or elsewhere to modify them to suit your needs.
first: add a using to the runtime.
using Autodesk.AutoCAD.Runtime;
next: Add an attribute to your method.
[CommandMethod("YOURCOMMANDNAMEINAUTOCAD")]
Last: Your class and method need to be public, for AutoCAD to see them.
Update: (Very last): your Method cannot take parameters.

Coded UI: Not able to capture a screen shot for pass test case

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)

How can I programmatically open and save a PowerPoint presentation as HTML/JPEG in C# or Perl?

I am looking for a code snippet that does just this, preferably in C# or even Perl.
I hope this not a big task ;)
The following will open C:\presentation1.ppt and save the slides as C:\Presentation1\slide1.jpg etc.
If you need to get the interop assembly, it is available under 'Tools' in the Office install program, or you can download it from here (office 2003). You should be able to find the links for other versions from there if you have a newer version of office.
using Microsoft.Office.Core;
using PowerPoint = Microsoft.Office.Interop.PowerPoint;
namespace PPInterop
{
class Program
{
static void Main(string[] args)
{
var app = new PowerPoint.Application();
var pres = app.Presentations;
var file = pres.Open(#"C:\Presentation1.ppt", MsoTriState.msoTrue, MsoTriState.msoTrue, MsoTriState.msoFalse);
file.SaveCopyAs(#"C:\presentation1.jpg", Microsoft.Office.Interop.PowerPoint.PpSaveAsFileType.ppSaveAsJPG, MsoTriState.msoTrue);
}
}
}
Edit:
Sinan's version using export looks to be a bit better option since you can specify an output resolution. For C#, change the last line above to:
file.Export(#"C:\presentation1.jpg", "JPG", 1024, 768);
As Kev points out, don't use this on a web server. However, the following Perl script is perfectly fine for offline file conversion etc:
#!/usr/bin/perl
use strict;
use warnings;
use Win32::OLE;
use Win32::OLE::Const 'Microsoft PowerPoint';
$Win32::OLE::Warn = 3;
use File::Basename;
use File::Spec::Functions qw( catfile );
my $EXPORT_DIR = catfile $ENV{TEMP}, 'ppt';
my ($ppt) = #ARGV;
defined $ppt or do {
my $progname = fileparse $0;
warn "Usage: $progname output_filename\n";
exit 1;
};
my $app = get_powerpoint();
$app->{Visible} = 1;
my $presentation = $app->Presentations->Open($ppt);
die "Could not open '$ppt'\n" unless $presentation;
$presentation->Export(
catfile( $EXPORT_DIR, basename $ppt ),
'JPG',
1024,
768,
);
sub get_powerpoint {
my $app;
eval { $app = Win32::OLE->GetActiveObject('PowerPoint.Application') };
die "$#\n" if $#;
unless(defined $app) {
$app = Win32::OLE->new('PowerPoint.Application',
sub { $_[0]->Quit }
) or die sprintf(
"Cannot start PowerPoint: '%s'\n", Win32::OLE->LastError
);
}
return $app;
}

Categories