I have a project where I need to automatically download and process an excel file from a public web site.
the site is the following:
http://apps.ahca.myflorida.com/dm_web/(S(rhlzd0ac2qwvvccbyp3lx2or))/doc_results_fo.aspx
you can see a link called Export Results which downloads the excel file. This link does a postback and I have been looking all over the place to find a way to automate it without success.
This is the last code I tried:
try
{
byte[] b = webClient.DownloadData("http://apps.ahca.myflorida.com/dm_web/(S(eha2oijpqo5mro1aywok4lly))/doc_results_fo.aspx");
string s = System.Text.Encoding.UTF8.GetString(b);
var __EVENTVALIDATION = ExtractVariable(s, "__EVENTVALIDATION");
var forms = new NameValueCollection();
forms["__EVENTTARGET"] = "lbtSpreadsheet";
forms["__EVENTARGUMENT"] = "";
forms["__VIEWSTATE"] = ExtractVariable(s, "__VIEWSTATE");
forms["mTbdate"] = "11%2F15%2F2011";
forms["__EVENTVALIDATION"] = __EVENTVALIDATION;
webClient.Headers.Set(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded");
var responseData = webClient.UploadValues(#"http://apps.ahca.myflorida.com/dm_web/(S(eha2oijpqo5mro1aywok4lly))/doc_results_fo.aspx", "POST", forms);
System.IO.File.WriteAllBytes(#"c:\tmp\FLORIDA.xls", responseData);
}
catch (Exception ex)
{
Console.Write(ex.StackTrace);
}
}
private static string ExtractVariable(string s, string valueName)
{
string tokenStart = valueName + "\" value=\"";
string tokenEnd = "\" />";
int start = s.IndexOf(tokenStart) + tokenStart.Length;
int length = s.IndexOf(tokenEnd, start) - start;
return s.Substring(start, length);
}
This is supposed to get the value of view state and other fields and issue a POST , but when I run it the file that gets downloaded is the page itself and not the excel file.
I am not sure if this is possible using WebClient, or I should use WebBrowser control (or similar controls), or maybe an atomated browsing tool that I can record a sequence of steps and run it every x days.
Any help will be greatly appreciated.
Thank you
I figured it out using Selenium .NET
FirefoxProfile firefoxProfile = new FirefoxProfile();
firefoxProfile.SetPreference("browser.download.folderList", 2);
firefoxProfile.SetPreference("browser.download.dir", strFullpath);
firefoxProfile.SetPreference("browser.helperApps.neverAsk.openFile", "application/vnd.ms-Excel");
firefoxProfile.SetPreference("browser.helperApps.neverAsk.saveToDisk", "application/vnd.ms-Excel");
IWebDriver driver = new FirefoxDriver(firefoxProfile);
driver.Navigate().GoToUrl(link);
driver.FindElement(By.Id(lookup)).Click();
driver.Quit();
Related
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.
I am trying to create a torrent file with monotorrent package using C#.
I already created the torrent file with the torrent creator but I want to add some other options that I can't find in the torrent creator methods or properties.
Options that I am looking for :
adding tracking url(S),
Web seed URL(S),
Source,
Optimize alignment.
Here is a snippet of my code:
string filepath = ofd.FileName;
PathDirectoryTxt.Text = filepath;
MonoTorrent.Common.TorrentCreator torrentcreaotr = new MonoTorrent.Common.TorrentCreator();
ITorrentFileSource fileSource = new TorrentFileSource(filepath);
torrentcreaotr.Comment = CommentsRichTxt.Text;
torrentcreaotr.CreatedBy = "Google using " + VersionInfo.ClientVersion;
torrentcreaotr.Publisher = "www.itsitus.com";
if ((PrivateTorrentCheckbox.Checked))
{
torrentcreaotr.Private = true;
}
else if (!PrivateTorrentCheckbox.Checked)
{
torrentcreaotr.Private = false;
}
string savepath = sfd.FileName;
torrentcreaotr.Create(fileSource, savepath);
MessageBox.Show("torrent file has been created successfully !");
Have you tried setting the 'Announce' property with the URL for your tracker, or setting the 'Announces' if you have tracker tiers/fallbacks? Similarly, Webseeds are set using the GetrightHttpSeed property.
In my web application which has some automation process to download the files from the website. To achieve that I used selenium c# chrome driver.
Sample code snippets
public void Download(string name,string pass)
{
try
{
ChromeOptions options = new ChromeOptions();
options.AddArguments("--proxy-server=http://192.168.5.62:8095");
options.AddUserProfilePreference("safebrowsing.enabled", true);
options.AddUserProfilePreference("disable-popup-blocking", "true");
options.AddUserProfilePreference("download.default_directory",#"C:\Temp");
using (var driver = new ChromeDriver(HostingEnvironment.ApplicationPhysicalPath, options)){
//driver.findElement(By.xpath("//a/u[contains(text(),'Re-Submit')]")).click();
driver.FindElementById("save").Click();
}
}
catch (Exception ex)
{
Logger.LogWriter("LAS", ex, "CusDataLogic", "Download");
}
}
above code (not complete code) works fine and save file properly. But I need to rename that file downloading or after download. Have any possible way to rename that file?
Edited: Please don't mark this as a duplicate. I'm asking for C#, not python. I saw that question too. but it not helped to me
watching directory is not always good, because sometime saved filename is different than filename in URL.
go to chrome download page and loop until all download complete, you can see below how to select special element #shadow-root with CSS selector
using (var driver = new ChromeDriver(HostingEnvironment.ApplicationPhysicalPath, options)))
{
//driver.findElement(By.xpath("//a/u[contains(text(),'Re-Submit')]")).click();
driver.FindElementById("save").Click();
// wait 5 second until download started
Thread.Sleep(5000);
// Go to chrome download page
driver.Navigate().GoToUrl("chrome://downloads/");
string oldName = "";
bool downloadcomplete = false;
string cssNames = "downloads-manager /deep/ downloads-item /deep/ [id='name']";
string cssDlProgress = "downloads-manager /deep/ downloads-item /deep/ [class*='show-progress']";
while (!downloadcomplete)
{
var progressElements = driver.FindElements(By.CssSelector(cssDlProgress));
// check until no download progress bar
if (progressElements.Count() == 0)
{
oldName = driver.FindElement(By.CssSelector(cssNames)).Text;
downloadcomplete = true;
}
else
{
// download still in progress, wait.
Thread.Sleep(1000);
}
}
// download complete
// remove downloaded file
driver.FindElement(By.CssSelector("downloads-manager /deep/ downloads-item /deep/ [id='remove']")).Click();
// rename
File.Move(#"C:\Temp\" + oldName, #"C:\Temp\newname.ext");
}
The Snippet Below Will wait Until File downloaded Then return FilePath I Wrote this as an extension method :
public static string GetDonwloadedFileName(this IWebDriver driver)
{
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript("window.open()");
var allWinowHandles = driver.WindowHandles;
foreach (var winHandle in allWinowHandles)
{
//Switch to second window
if (!winHandle.Equals(driver.CurrentWindowHandle))
{
driver.SwitchTo().Window(winHandle);
}
}
// navigate to chrome downloads
driver.Navigate().GoToUrl("chrome://downloads");
IJavaScriptExecutor downloadWindowExecutor = (IJavaScriptExecutor)driver;
// Wait for Download till 100% completion
double percentageProgress = (double)0;
while (percentageProgress != 100)
{
try
{
percentageProgress = (long)downloadWindowExecutor.ExecuteScript("return document.querySelector('downloads-manager').shadowRoot.querySelector('#downloadsList downloads-item').shadowRoot.querySelector('#progress').value");
Thread.Sleep(100);
}
catch (Exception)
{
break;
}
}
string fileTitle = (string)downloadWindowExecutor.ExecuteScript("return document.querySelector('downloads-manager').shadowRoot.querySelector('#downloadsList downloads-item').shadowRoot.querySelector('#show').getAttribute('title')");
downloadWindowExecutor.ExecuteScript("window.close()");
return fileTitle;
}
Then You can use file Path to rename it to whatever you need
My company has purchased the CoolUtils TotalPDFPrinterX from https://www.coolutils.com/TotalPDFPrinterX
I make an HTTP PUT from Postman to the API and I get “Could not get any response”.
When running on my Windows machine the PDF prints fine however on the server the site crashes and in the event log I get the error "A process serving application pool '[MY_APP_POOL]' failed to respond to a ping. The process id was '[MY_PROCESS_ID]'."
Here is my C# code:
PDFPrinterX ppx = new PDFPrinterX();
ppx.Print(fileName, printerName, "-ap Default");
if (ppx.ErrorMessage != null)
{
WriteToSQL(id, false, ppx.ErrorMessage, 2);
Console.WriteLine(ppx.ErrorMessage);
}
By writing to the event log I know the site crashes on this line: PDFPrinterX ppx = new PDFPrinterX(); I have also surrounded the above code with a try catch and no exception is thrown. The site still crashes.
Things I have tried:
Uninstalling and Reinstalling the CoolUtils software
Giving EVERYONE Full control to the site folder and the CoolUtils program folder
Creating a C# desktop application using the same code. THIS WORKS FINE ON THE SERVER. It's just the ASP site that crashes.
Does anyone know what might be causing this?
The more I research this thing online the more I'm inclined to say that ActiveX which is the X in PDFPrinterX doesn't seem to work well when hosted in IIS.
I've seen a few forums where they say it works fine when they debug on localhost but when deployed to server is crashes.
...works fine when used inside localhost(Visual studio)
One of their feature pages shows that it requires Win 2000/NT/XP/2003/Vista/7
You should look into whether your server supports ActiveX components that can work in conjunction with IIS.
Looking at one of their other products support page: TotalPDFConverterX:
the following note in my opinion may also apply to TotalPDFPrinterX, given its dependency on ActiveX as well.
Note: Pay attention to some details during installation Total PDF Converter X:
Do not forget to register ActiveX in your web-server account.
Total PDF Converter X supports only Internet Explorer, Mozilla and Firefox browsers.
ActiveX works only with 32-bit internet information server. 64-bit server is not supported. Use command line version instead.
Thanks to #Nkosi I was able to find a workaround.
ActiveX works only with 32-bit internet information server. 64-bit server is not supported. Use command line version instead.
Our IIS server is 64 bit so that is what probably caused the site to hang up.
Buttt... the command line still worked in printing the PDFs on the server.
Client side code (makes the HTTP POST):
private void SendToPrinter(string fileName, string printerName, int id, decimal documentSequence)
{
// use http client to make a POST to the print api
using (var client = new HttpClient())
{
// compile the values string to transfer in POST
// should finish to look something like this:
// C:\print.pdf&PRTFTW_OFIT&ValShip-155320-1
var values = new Dictionary<string, string>
{
{ "", fileName + "&" + printerName + "&ValShip-" + id + "-" + documentSequence},
};
// URL encode the values string
var content = new FormUrlEncodedContent(values);
// make the POST
// DEBUG
var response = client.PostAsync("http://localhost:54339/api/print", content);
// retrieve the response
var responseString = response.Result.ToString();
}
}
Server side code (receives the HTTP POST):
using System;
using System.Net.Http;
using System.Web;
using System.Web.Http;
namespace api.valbruna.print.Controllers
{
public class PrintController : ApiController
{
// POST api/print
public HttpResponseMessage Post(HttpRequestMessage request)
{
try
{
// parse the content recieved from the client
var content = request.Content.ReadAsStringAsync().Result;
// decode the content, certain characters such as
// '&' get encoded to URL lingo such as '%26'
content = HttpUtility.UrlDecode(content);
// split the string into 3 seperate parts
String[] str = content.Split('&');
// remove the equal sign from the first string
str[0] = str[0].Trim('=');
// compile the arguments command line string
// should finish to look something like this:
// "C:\Program Files (x86)\CoolUtils\Total PDF PrinterX\PDFPrinterX.exe" "C:\print.pdf" -p"\\PRINTERS\PRTFTW_OFIT" -ap Default -log "C:\inetpub\logs\CoolUtils\log-ValShip-155320-4.txt" -verbosity detail"
String arguments = "\"" + str[0] + "\" -p\"\\\\PRINTERS\\" + str[1] +
"\" -ap Default -log \"C:\\inetpub\\logs\\CoolUtils\\log-" + str[2] +
".txt\" -verbosity detail";
// file location for PDFPrinterX.exe
String file = #"C:\Program Files (x86)\CoolUtils\Total PDF PrinterX\PDFPrinterX.exe";
// start the process
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
startInfo.FileName = file;
startInfo.Arguments = arguments;
process.StartInfo = startInfo;
process.Start();
return new HttpResponseMessage() { Content = new StringContent(content) };
}
catch (Exception e)
{
return new HttpResponseMessage() { Content = new StringContent(e.Message) };
}
}
}
}
I am a novice in programming. I have a project where I have to get data from a website (I ll be posting the website below). But it happens that I first have to select a date and press a 'Go' button and then click on another Button/Link 'View in Excel' to download this data. I cannot find a way to first click the 'Go' button after selecting my required date and then click the second button 'View in Excel' through my c# code.
Any help will be appreciated.
PS: You can check the link for yourselves http://www.mcxindia.com/sitepages/BhavCopyDateWiseArchive.aspx
private void Form1_Load(object sender, EventArgs e)
{
WebClient webClient = new WebClient();
byte[] b = webClient.DownloadData("http://www.mcxindia.com/sitepages/BhavCopyDatewise.aspx");
string s = System.Text.Encoding.UTF8.GetString(b);
var __EVENTVALIDATION = ExtractVariable(s, "__EVENTVALIDATION");
//__EVENTVALIDATION.Dump();
var forms = new NameValueCollection();
forms["__EVENTTARGET"] = "btnLink_Excel";
forms["__EVENTARGUMENT"] = "";
forms["__VIEWSTATE"] = ExtractVariable(s, "__VIEWSTATE");
forms["mTbdate"] = "01%2F15%2F2013";
forms["__EVENTVALIDATION"] = __EVENTVALIDATION;
webClient.Headers.Set(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded");
var responseData = webClient.UploadValues(#"http://www.mcxindia.com/sitepages/BhavCopyDatewise.aspx", "POST", forms);
System.IO.File.WriteAllBytes(#"c:\11152011.csv", responseData);
}
private static string ExtractVariable(string s, string valueName)
{
string tokenStart = valueName + "\" value=\"";
string tokenEnd = "\" />";
int start = s.IndexOf(tokenStart) + tokenStart.Length;
int length = s.IndexOf(tokenEnd, start) - start;
return s.Substring(start, length);
}
The above code gives me the file only for the last available date. I am not able to get it for the date I want.
Seems like you need to made a HTTP Post request with one post data (date). This should be easy enough. Have a look at this question and see if it helps you. Send HTTP Post Request through ASP.net
I found a solution to this question.
pls see here