Starting a specific Firefox Profile with Selenium 3 - c#

I am trying to upgrade from Selenium 2 to Selenium 3 but the old handling, which was pretty easy and fast doesn't work anymore (and the documentation is nonexisting as it seems)
This is the program at the moment and what I want is to open a Firefox driver with the profile: SELENIUM
Sadly it doesn't work and always shuts down with the Error:
An unhandled exception of type 'System.InvalidOperationException' > occurred in WebDriver.dll
Additional information: corrupt deflate stream
This is my program at the moment:
public Program()
{
FirefoxOptions _options = new FirefoxOptions();
FirefoxProfileManager _profileIni = new FirefoxProfileManager();
FirefoxDriverService _service = FirefoxDriverService.CreateDefaultService(#"C:\Programme\IMaT\Output\Release\Bin");
_service.FirefoxBinaryPath = #"C:\Program Files (x86)\Mozilla Firefox\firefox.exe";
try
{
if ((_options.Profile = _profileIni.GetProfile("SELENIUM")) == null)
{
Console.WriteLine("SELENIUM PROFILE NOT FOUND");
_profile.SetPreference("network.proxy.type", 0); // disable proxy
_profile = new FirefoxProfile();
}
}
catch
{
throw new Exception("Firefox needs a Profile with \"SELENIUM\"");
}
IWebDriver driver = new FirefoxDriver(_service,_options,new System.TimeSpan(0,0,30));
driver.Navigate().GoToUrl("ld-hybrid.fronius.com");
Console.Write("rtest");
}
static void Main(string[] args)
{
new Program();
}
Without Loading the Profile it works with just new FirefoxDriver(_service) but the profile is mandatory.
In Selenium 2 I handled it with this code:
FirefoxProfileManager _profileIni = new FirefoxProfileManager();
// use custom temporary profile
try {
if ((_profile = _profileIni.GetProfile("SELENIUM")) == null)
{
Console.WriteLine("SELENIUM PROFILE NOT FOUND");
_profile.SetPreference("network.proxy.type", 0); // disable proxy
_profile = new FirefoxProfile();
}
}
catch
{
throw new Exception("Firefox needs a Profile with \"SELENIUM\"");
}
_profile.SetPreference("intl.accept_languages", _languageConfig);
_driver = new FirefoxDriver(_profile);
Fast and simple, but as the Driver doesn't support a Constructor with service and profile I don't really know how to get this to work, any help would be appreciated

This exception is due to a bug in the .Net library. The code generating the Zip of the profile is failing to provide a proper Zip.
One way to overcome this issue would be to overload FirefoxOptions and use the archiver from .Net framework (System.IO.Compression.ZipArchive) instead of the faulty ZipStorer:
var options = new FirefoxOptionsEx();
options.Profile = #"C:\Users\...\AppData\Roaming\Mozilla\Firefox\Profiles\ez3krw80.Selenium";
options.SetPreference("network.proxy.type", 0);
var service = FirefoxDriverService.CreateDefaultService(#"C:\downloads", "geckodriver.exe");
var driver = new FirefoxDriver(service, options, TimeSpan.FromMinutes(1));
class FirefoxOptionsEx : FirefoxOptions {
public new string Profile { get; set; }
public override ICapabilities ToCapabilities() {
var capabilities = (DesiredCapabilities)base.ToCapabilities();
var options = (IDictionary)capabilities.GetCapability("moz:firefoxOptions");
var mstream = new MemoryStream();
using (var archive = new ZipArchive(mstream, ZipArchiveMode.Create, true)) {
foreach (string file in Directory.EnumerateFiles(Profile, "*", SearchOption.AllDirectories)) {
string name = file.Substring(Profile.Length + 1).Replace('\\', '/');
if (name != "parent.lock") {
using (Stream src = File.OpenRead(file), dest = archive.CreateEntry(name).Open())
src.CopyTo(dest);
}
}
}
options["profile"] = Convert.ToBase64String(mstream.GetBuffer(), 0, (int)mstream.Length);
return capabilities;
}
}
And to get the directory for a profile by name:
var manager = new FirefoxProfileManager();
var profiles = (Dictionary<string, string>)manager.GetType()
.GetField("profiles", BindingFlags.Instance | BindingFlags.NonPublic)
.GetValue(manager);
string directory;
if (profiles.TryGetValue("Selenium", out directory))
options.Profile = directory;

Related

can't Specify an audio profile using Google.Cloud.TextToSpeech.V1 in c#

I'm trying to convert Text To audio using Google.Cloud.TextToSpeech.V1. it works fine but I do not know how can I Specify an audio profile to use using c# while I found code in Node.js and python But Not anything in c# this is my code
static void Main(string[] args)
{
List<Word> lst = IntialData();
System.Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", #"C:\Users\Admin\TextToSpeechApiDemo\key.json");
var client = TextToSpeechClient.Create();
// The input to be synthesized, can be provided as text or SSML.
foreach (Word item in lst)
{
var input = new SynthesisInput
{
Text = item.Name,
};
// Build the voice request.
var voiceSelection = new VoiceSelectionParams
{
LanguageCode = "ar",
//SsmlGender = SsmlVoiceGender.Female,
Name = "ar-XA-Wavenet-A"
};
// Specify the type of audio file.
var audioConfig = new AudioConfig
{
AudioEncoding = AudioEncoding.Linear16,
};
// Perform the text-to-speech request.
var response = client.SynthesizeSpeech(input, voiceSelection, audioConfig);
// Write the response to the output file.
using (var output = File.Create(#"E:\Noursound\sim\ar-XA-Wavenet-A\" + item.Id.ToString() + ".wav"))
{
response.AudioContent.WriteTo(output);
}
}
}
I found this code in python he set effects_profile_id
audio_config = texttospeech.AudioConfig(
audio_encoding=texttospeech.AudioEncoding.MP3,
effects_profile_id=[effects_profile_id],
How can i do that using c#
The problem was in the version on the NuGet package i used 1.0.0-beta01 , and it's not have the EffectsProfileId property but after update it to version to Google.Cloud.TextToSpeech.V1 version 2.3.0 i found the property.
using Google.Cloud.TextToSpeech.V1;
class Program
{
static void Main(string[] args)
{
var config = new AudioConfig
{
AudioEncoding = AudioEncoding.Mp3,
EffectsProfileId = { "your profile ID" }
};
}
}
i created git issue for that on github Here's a link!

How to get Saucelabs tunnelidentifier set up using AddAdditionalCapability in C#?

Here is my sample code which I tried but I cannot get the tunnelidentifier set up and launch test url. Other than generic sites which are not blocked by proxy. Any help is appreciated. Thanks
[Test]
public void SimpleTest1()
{
Uri sauceHubURL = new Uri("https://USERNAME:SOMEACCESSKEY#123.saucelabs.com:443/wd/hub");
InternetExplorerOptions options = new InternetExplorerOptions();
options.AddAdditionalCapability("parentTunnel", "PQSauceLabs");
options.AddAdditionalCapability("tunnelIdentifier", "Mys-sauce-Tests");
options.AddAdditionalCapability("EnsureCleanSession", true);
string url = "https://www.google.com";
string companyurl = "https://www.sample.com";
var remoteDriver = new RemoteWebDriver(sauceHubURL, options.ToCapabilities(), TimeSpan.FromSeconds(300));
remoteDriver.Navigate().GoToUrl(url);
//remoteDriver.SwitchTo().Alert().SetAuthenticationCredentials("q25215", "test#");
//IAlert alert = remoteDriver.SwitchTo().Alert();
//alert.SendKeys("q25215"+ Keys.Tab + "test#" + Keys.Tab);
//alert.Accept();
string title = remoteDriver.Title;
Console.WriteLine("Getting the page title: " + title);
NUnit.Framework.Assert.AreEqual(title, "Google", "Compared values not equal");
remoteDriver.Quit();
}
I'm guessing this was run using the W3C Selenium bindings, so the sauce-specific options like parentTunnel need to be namespaced under sauce:options:
var driverOptions = new FirefoxOptions();
driverOptions.PlatformName = "macOS 10.13";
var sauceOptions = new Dictionary<string, object>();
sauceOptions.Add("username", sauceUserName);
sauceOptions.Add("accessKey", sauceAccessKey);
sauceOptions.Add("name", TestContext.CurrentContext.Test.Name);
sauceOptions.Add("parentTunnel", "Mys-sauce-Tests");
sauceOptions.Add("tunnelIdentifier", "PQSauceLabs");
driverOptions.AddAdditionalOption("sauce:options", sauceOptions);
//create a new Remote driver that will allow your test to send
//commands to the Sauce Labs grid so that Sauce can execute your tests
_driver = new RemoteWebDriver(new Uri("http://ondemand.saucelabs.com:80/wd/hub"),
driverOptions);

Winform Cefsharp: Can't clear cache directory

I'm using CefSharp in my WinForm project.
I wan't to clear the cache directory in real time:
if (browser != null)
{
BrowserPanel.Controls.Remove(browser);
browser = null;
}
String cachePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + #"\TelegramParser\Users\" + userName;
if (Directory.Exists(cachePath))
{
Directory.Delete(cachePath, true);
}
But I always get an error that it is not possible to delete this directory.
This is how I declare the browser:
String cachePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + #"\TelegramParser\Users\" + userName;
if (!System.IO.Directory.Exists(cachePath))
{
System.IO.Directory.CreateDirectory(cachePath);
}
var requestContextSettings = new RequestContextSettings { CachePath = cachePath };
if (browser != null && BrowserPanel.Controls.Contains(browser))
BrowserPanel.Controls.Remove(browser);
browser = new ChromiumWebBrowser();
browser.RequestContext = new RequestContext(requestContextSettings, new CustomRequestContextHandler());
browser.Dock = DockStyle.Fill;
JsDialogHandler js1 = new JsDialogHandler();
browser.JsDialogHandler = js1;
BrowserPanel.Controls.Add(browser);
browser.Load("https://google.com/");
What can I do to fix this?
As of 85.4 it is possible to delete cache of a running CefSharp browser using DevToolsClient and Network.ClearBrowserChache. As mentioned on General Usage wiki of CefSharp.
private async Task ClearCache(object sender)
{
using (var devToolsClient = Browser.GetDevToolsClient())
{
var response = await devToolsClient.Network.ClearBrowserCacheAsync();
}
}
Note: this will not deleted the entire folder, it will however clear cached objects.

Hanging TuesPechkin after initial conversion

I am attempting to create a Web API that can convert a styled HTML file into a PDF.
I am using TuesPechkin and have installed my application into IIS (as a 32-bit app: I have modified the application pool to run in 32bit mode).
IIS 8.5 is running on Windows Server 2012 R2.
PDFConversion class in C#:
using System.Drawing.Printing;
using System.IO;
using TuesPechkin;
namespace PDFApi
{
public class PDFcreator
{
public void convert(string path, string uri)
{
IConverter converter = new StandardConverter(
new RemotingToolset<PdfToolset>(
new Win64EmbeddedDeployment(
new TempFolderDelpoyment())));
var document = new HtmlToPdfDocument
{
GlobalSettings =
{
ProduceOutline = true,
DocumentTitle = "Converted Form",
PaperSize = PaperKind.A4,
Margins =
{
All = 1.375,
Unit = Unit.Centimeters
}
},
Objects =
{
new ObjectSettings { RawData = File.ReadAllBytes(uri) }
}
};
byte[] pdfBuf = converter.Convert(document);
FileStream fs = new FileStream(path, FileMode.Create);
fs.Write(pdfBuf, 0, pdfBuf.Length);
fs.Close();
}
}
}
The Controller is as follows:
[Route("converthtml")]
[HttpPost]
[MIMEContentFilter]
public async Task<HttpResponseMessage> ConvertHtml()
{
string temppath = System.IO.Path.GetTempPath();
var streamProvider = new MultipartFormDataStreamProvider(temppath);
await Request.Content.ReadAsMultipartAsync(streamProvider);
string filepath = streamProvider.FileData.Select(entry => entry.LocalFileName.Replace(temppath + "\\", "")).First<string>();
string pdfpath = System.IO.Path.GetTempFileName();
pdfpath = pdfpath.Substring(0, pdfpath.LastIndexOf('.')) + ".pdf";
new PDFcreator().convert(pdfpath, filepath);
var stream = new FileStream(pdfpath, FileMode.Open);
var result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
return result;
}
Here's where it gets a little odd: Experimenting in Fiddler, sending a file once will return the PDF immediately. However, all subsequent POSTs will leave Fiddler hanging.
Examining Task Manager shows the CPU and Memory for this task to jump up to 13.5% and ~96MB respectively.
The Temp folder (where the files are stored), on a successful run, will have three files in it: the original uploaded file (stored with a GUID-like name), the file generated via wkHtmlToPdf (in the form "wktemp-"), and the generated pdf (as tempXXXX.pdf).
In the case of it hanging, only the first file can be found, indicating that the problem is somewhere in wkHtmlToPdf itself.
However, the real kicker is when the process is manually killed in Task Manager, the API completes successfully, returns the pdf, fully created!
If IIS is reset, the process returns to the original state; a new attempt will work without issue.
Obviously, resetting IIS after every call is hardly viable, nor is manually killing the process each time...
Is this a bug / are there any solutions to this issue?
EDIT: Very important - this answer had a lot of votes, but is not complete. Check the marked solution
var tempFolderDeployment = new TempFolderDeployment();
var win32EmbeddedDeployment = new Win32EmbeddedDeployment(tempFolderDeployment);
var remotingToolset = new RemotingToolset<PdfToolset>(win32EmbeddedDeployment);
var converter =
new ThreadSafeConverter(remotingToolset);
byte[] pdfBuf = converter.Convert(document);
remotingToolset.Unload();
Unload remotingToolset will prevent hanging
RemotingToolset.Unload();
Very important-
#toshkata-tonev answer helped me, but when a lot of sessions used this function our server crushed because over CPU!
The point is that the process should be shared by all sessions as static shared function.
So this was the solution for me:
Implementation:
Create a static class in your application:
public static class TuesPechkinInitializerService {
private static string staticDeploymentPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wkhtmltopdf");
public static void CreateWkhtmltopdfPath()
{
if (Directory.Exists(staticDeploymentPath) == false)
{
Directory.CreateDirectory(staticDeploymentPath);
}
}
public static IConverter converter =
new ThreadSafeConverter(
new RemotingToolset<PdfToolset>(
new Win64EmbeddedDeployment(
new StaticDeployment(staticDeploymentPath)
)
)
);
}
In GLOBAL.asax, I initialize that class on project start:
TuesPechkinInitializerService.CreateWkhtmltopdfPath();
And to use it:
HtmlToPdfDocument pdfDocument = new HtmlToPdfDocument
{
GlobalSettings = new GlobalSettings(),
Objects =
{
new ObjectSettings
{
ProduceLocalLinks = true,
ProduceForms = true,
HtmlText = htmlContent
}
}
};
byte[] pdfDocumentData = TuesPechkinInitializerService.converter.Convert(pdfDocument);
Thanks to:
https://github.com/tuespetre/TuesPechkin/issues/152
It seems you are using WkHtmlToPdf 64 bits and you've installed the 32 bits one.
You should change :
IConverter converter = new StandardConverter(
new RemotingToolset<PdfToolset>(
new Win64EmbeddedDeployment(
new TempFolderDelpoyment())));
to
IConverter converter = new StandardConverter(
new RemotingToolset<PdfToolset>(
new Win32EmbeddedDeployment(
new TempFolderDelpoyment())));

How can I programmatically check-out an item for edit in TFS?

I'm working on a utility processing files being under source control using TFS 2010.
If an item is not yet checked-out for edit, I'm getting an exception, what is definitely predictable because file is in read-only mode.
What ways exist to check-out a file?
P.S. I want something for programmatic rather then Process.Start("tf.exe", "..."); if that's applicable.
Some of the other approaches mentioned here only work for certain versions of TFS or make use of obsolete methods. If you are receiving a 404, the approach you are using is probably not compatible with your server version.
This approach works on 2005, 2008, and 2010. I don't use TFS any longer, so I haven't tested 2013.
var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(fileName);
using (var server = new TfsTeamProjectCollection(workspaceInfo.ServerUri))
{
var workspace = workspaceInfo.GetWorkspace(server);
workspace.PendEdit(fileName);
}
private const string tfsServer = #"http://tfsserver.org:8080/tfs";
public void CheckOutFromTFS(string fileName)
{
using (TfsTeamProjectCollection pc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(tfsServer)))
{
if (pc != null)
{
WorkspaceInfo workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(fileName);
if (null != workspaceInfo)
{
Workspace workspace = workspaceInfo.GetWorkspace(pc);
workspace.PendEdit(fileName);
}
}
}
FileInfo fi = new FileInfo(fileName);
}
Note that Microsoft.TeamFoundation.Client.TeamFoundationServerFactory is obsolete: The TeamFoundationServer class is obsolete. Use the TeamFoundationProjectCollection or TfsConfigurationServer classes to talk to a 2010 Team Foundation Server.
In order to talk to a 2005 or 2008 Team Foundation Server use the TeamFoundationProjectCollection class. The corresponding factory class for that is the TfsTeamProjectCollectionFactory.
You can use Team Foundation Version Control client API.
The method is PendEdit()
workspace.PendEdit(fileName);
Checkout detailed example on MSDN
http://blogs.msdn.com/b/buckh/archive/2006/03/15/552288.aspx
First get the workspace
var tfs = new TeamFoundationServer("http://server:8080/tfs/collection");
var version = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
var workspace = version.GetWorkspace("WORKSPACE-NAME", version.AuthorizedUser);
With the workspace you can checkout the file
workspace.PendEdit(fileName);
var registerdCollection = RegisteredTfsConnections.GetProjectCollections().First();
var projectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(registerdCollection);
var versionControl = projectCollection.GetService<VersionControlServer>();
var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(_fileName);
var server = new TeamFoundationServer(workspaceInfo.ServerUri.ToString());
var workspace = workspaceInfo.GetWorkspace(server);
workspace.PendEdit(fileName);
I have two approaches how to do that: simple and advanced.
1). Simple:
#region Check Out
public bool CheckOut(string path)
{
using (TfsTeamProjectCollection pc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(ConstTfsServerUri)))
{
if (pc == null) return false;
WorkspaceInfo workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(path);
Workspace workspace = workspaceInfo?.GetWorkspace(pc);
return workspace?.PendEdit(path, RecursionType.Full) == 1;
}
}
public async Task<bool> CheckoutAsync(string path)
{
return await Task.Run(() => CheckOut(path));
}
#endregion
2). Advanced (with receiving status):
private static string GetOwnerDisplayName(PendingSet[] pending)
{
var result = pending.FirstOrDefault(pendingSet => pendingSet.Computer != Environment.MachineName) ?? pending[0];
return result.OwnerDisplayName;
}
private string CheckoutFileInternal(string[] wsFiles, string folder = null)
{
try
{
var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(folder);
var server = new TfsTeamProjectCollection(workspaceInfo.ServerUri);
var workspace = workspaceInfo.GetWorkspace(server);
var request = new GetRequest(folder, RecursionType.Full, VersionSpec.Latest);
GetStatus status = workspace.Get(request, GetOptions.None);
int result = workspace.PendEdit(wsFiles, RecursionType.Full, null, LockLevel.None);
if (result == wsFiles.Length)
{
//TODO: write info (succeed) to log here - messageText
return null;
}
var pending = server.GetService<VersionControlServer>().QueryPendingSets(wsFiles, RecursionType.None, null, null);
var messageText = "Failed to checkout !.";
if (pending.Any())
{
messageText = string.Format("{0}\nFile is locked by {1}", messageText, GetOwnerDisplayName(pending));
}
//TODO: write error to log here - messageText
return messageText;
}
catch (Exception ex)
{
UIHelper.Instance.RunOnUiThread(() =>
{
MessageBox.Show(Application.Current.MainWindow, string.Format("Failed checking out TFS files : {0}", ex.Message), "Check-out from TFS",
MessageBoxButton.OK, MessageBoxImage.Error);
});
return null;
}
}
public async Task<string> CheckoutFileInternalAsync(string[] wsFiles, string folder)
{
return await Task.Run(() => CheckoutFileInternal(wsFiles, folder));
}

Categories