I want to add some buttons to the text editor in VS. In the ViewPortTextViewCreationListener when ViewPort manager is created I would like to know the path of the document or it
public void TextViewCreated(IWpfTextView textView) {
var result = _textDocumentFactoryService.TryGetTextDocument(TextView.TextBuffer, out ITextDocument textDocument);
new ViewPortSwitcher(textView);
}
I've tried to use ITextDocumentFactoryService to get ITextDocument from TextBuffer (see answer here). If I open cs file it works properly. But if I open cshtml file TryGetTextDocument returns false.
Finally, I've found the solution see MSDN forum:
public static string GetPath(this IWpfTextView textView) {
textView.TextBuffer.Properties.TryGetProperty(typeof(IVsTextBuffer), out IVsTextBuffer bufferAdapter);
var persistFileFormat = bufferAdapter as IPersistFileFormat;
if (persistFileFormat == null) {
return null;
}
persistFileFormat.GetCurFile(out string filePath, out _);
return filePath;
}
Related
I'm having the following issue:
I'm saving the locators as
public static By CopyUrl = By.XPath("//a[#data-key='UrlLink']");
In the test, I cannot GetText(), or store the whole CopyUrl in a var, since it's void. Driver.Click(XPath.MainMenu.Tabs.CopyUrl);
How can I store the link which is saved in clipboard after I click on it, and paste it in a new tab.
I tried:
var elem =Driver.SwitchTo().NewWindow(WindowType.Tab).Navigate().GoToUrl("myCopiedUrl").ToString();
Driver.SwitchTo().NewWindow(WindowType.Tab).Navigate().GoToUrl(elem);
It is not working for you since both Click() and Navigate().GoToUrl() methods are returning void.
In order to get the current URL you should use this method:
String currentURL = driver.Url;
or
String currentURL = driver.getCurrentUrl();
or
String currentURL = driver.getLocation();
[Test, Order(01234)]
public void t_Document_CopyUrl_Downloaded()
{
NavigateToYourPage();
UploadNewDocument();
NavigateToTheSpecificTab();
//Click on "Copy URL"
string fileName = Driver.FindElement(XPath.Input).GetValue();
IWebElement copyUrl = Driver.FindElement(XPath.CopyUrl);
string currentUrl = copyUrl.GetAttribute("textContent");
Driver.Click(XPath.CopyUrl);
Driver.WaitForNoSpinner();
// Opens a new tab and switches to new tab
Driver.SwitchTo().NewWindow(WindowType.Tab);
Driver.Navigate().GoToUrl(currentUrl);
Driver.Navigate().GoToUrl("chrome://downloads/");
string downloadedFileName = Driver.ExecuteJavaScript<string>("return document.querySelector('downloads-manager').shadowRoot.querySelector('downloads-item').shadowRoot.querySelector('#name').textContent;");
Driver.SwitchTo().Window(Driver.WindowHandles[0]);
Assert.IsTrue(downloadedFileName.StartsWith(fileName));
}
I am using System.Web.Optimization BundleTable for CSS and JavaScript file bundling. I was able to save bundle files manually by going to Chrome Developer Tools, Sources tab then clicking on bundle I would like to save and then clicking right mouse button on code and Save as (screenshot below)
I was wondering is there a way to save them programmatically (javascript or .NET I don't mind ether) as I need to test changes in bundle files by comparing them with old versions to see if they have changed or not. The end product will be selenium test most likely.
Sorted it out myself.
public static string GetBundleContents(string virtualPath)
{
OptimizationSettings config = new OptimizationSettings()
{
ApplicationPath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath,
BundleTable = BundleTable.Bundles
};
BundleResponse response = Optimizer.BuildBundle(virtualPath, config);
return response.Content;
}
public static void WriteBundlesToDisk(string path)
{
foreach (var bundle in BundleTable.Bundles)
{
var bundleContents = BundleConfig.GetBundleContents(bundle.Path);
File.WriteAllText(string.Format("{0}/{1}.{2}", path, bundle.Path.Split('/').Last(), BundleConfig.GetFileExtensionByBundleType(bundle)), bundleContents);
}
}
public static string GetFileExtensionByBundleType(Bundle bundle)
{
if (bundle is ScriptBundle)
return "js";
else if (bundle is StyleBundle)
return "css";
return "folderBundle";
}
usage:
BundleConfig.WriteBundlesToDisk("c://bundles");
sidenote: there's a type of bundle called System.Web.Optimization.DynamicFolderBundle that is not being handled properly by the solution above, it will save it as .folderBundle file type.
Background: I'm using the HTML 5 Offline App Cache and dynamically building the manifest file. Basically, the manifest file needs to list each of the static files that your page will request. Works great when the files are actually static, but I'm using Bundling and Minification in System.Web.Optimization, so my files are not static.
When in the DEBUG symbol is loaded (i.e. debugging in VS) then the actual physical files are called from the MVC View. However, when in Release mode, it calls a virtual file that could look something like this: /bundles/scripts/jquery?v=FVs3ACwOLIVInrAl5sdzR2jrCDmVOWFbZMY6g6Q0ulE1
So my question: How can I get that URL in the code to add it to the offline app manifest?
I've tried:
var paths = new List<string>()
{
"~/bundles/styles/common",
"~/bundles/styles/common1024",
"~/bundles/styles/common768",
"~/bundles/styles/common480",
"~/bundles/styles/frontend",
"~/bundles/scripts/jquery",
"~/bundles/scripts/common",
"~/bundles/scripts/frontend"
};
var bundleTable = BundleTable.Bundles;
foreach (var bundle in bundleTable.Where(b => paths.Contains(b.Path)))
{
var bundleContext = new BundleContext(this.HttpContext, bundleTable, bundle.Path);
IEnumerable<BundleFile> files = bundle.GenerateBundleResponse(bundleContext).Files;
foreach (var file in files)
{
var filePath = file.IncludedVirtualPath.TrimStart(new[] { '~' });
sb.AppendFormat(formatFullDomain, filePath);
}
}
As well as replacing GenerateBundleResponse() with EnumerateFiles(), but it just always returns the original file paths.
I'm open to alternative implementation suggestions as well. Thanks.
UPDATE: (7/7/14 13:45)
As well as the answer below I also added this Bundles Registry class to keep a list of the required static files so that it works in debug mode in all browsers. (See comments below)
public class Registry
{
public bool Debug = false;
public Registry()
{
SetDebug();
}
[Conditional("DEBUG")]
private void SetDebug()
{
Debug = true;
}
public IEnumerable<string> CommonScripts
{
get
{
if (Debug)
{
return new string[]{
"/scripts/common/jquery.validate.js",
"/scripts/common/jquery.validate.unobtrusive.js",
"/scripts/common/knockout-3.1.0.debug.js",
"/scripts/common/jquery.timepicker.js",
"/scripts/common/datepicker.js",
"/scripts/common/utils.js",
"/scripts/common/jquery.minicolors.js",
"/scripts/common/chosen.jquery.custom.js"
};
}
else
{
return new string[]{
"/scripts/common/commonbundle.js"
};
}
}
}
}
I'm by no means happy with this solution. Please make suggestions if you can improve on this.
I can suggest an alternative from this blog post create your own token.
In summary the author suggests using web essentials to create the bundled file and then creating a razor helper to generate the token, in this case based on the last changed date and time.
public static class StaticFile
{
public static string Version(string rootRelativePath)
{
if (HttpRuntime.Cache[rootRelativePath] == null)
{
var absolutePath = HostingEnvironment.MapPath(rootRelativePath);
var lastChangedDateTime = File.GetLastWriteTime(absolutePath);
if (rootRelativePath.StartsWith("~"))
{
rootRelativePath = rootRelativePath.Substring(1);
}
var versionedUrl = rootRelativePath + "?v=" + lastChangedDateTime.Ticks;
HttpRuntime.Cache.Insert(rootRelativePath, versionedUrl, new CacheDependency(absolutePath));
}
return HttpRuntime.Cache[rootRelativePath] as string;
}
}
Then you can reference the bundled file like so...
#section scripts {
<script src="#StaticFile.Version("~/Scripts/app/myAppBundle.min.js")"></script>}
Then you have control of the token and can do what you want with it.
I am writing an app in C# winForm, and I am using ListView to store some data.
I need to save this list of item when the form is closed and load it again when the form is opened again.
This is the code to add a new element on the list:
string[] timeitem = new string[2];
timeitem[0] = txtDescription.Text;
timeitem[1] = msktime.Text;
ListViewItem lvi = new ListViewItem(timeitem);
lstTimes.Items.Add(lvi);
What is the best way to save and load this list? I do not need a Dialog for the user, this list should be saved and loaded automatically each time the user open the form that contains the ListView item. I am open to use either .txt or xml file, whatever is the best/more easy to handle.
You could write a simple helper class for that:
class ListItemsHelper
{
private const string FILE_NAME = "items.dat";
public static void SaveData(Items items)
{
string data = SerializeItems(items);
File.WriteAllText(GetFilePath(), data);
}
public static Items LoadData()
{
string data = File.ReadAllText(GetFilePath());
return DeserializeItems(data);
}
private static string GetFilePath()
{
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, FILE_NAME);
}
private static string SerializeItems(Items items)
{
//Do serialization here
}
private static Items DeserializeItems(string data)
{
//Do deserialization here
}
}
Use:
ItemsStateHelper.SaveData(items);
Items data = ItemsStateHelper.LoadData();
Additionally, you would have to include some exception handling and choose where you want to save the file. In the code i posted it is saving on folder where the exe file is located.
I would like to know how to load string resource from another class library. Here is my structure.
Solution\
CommonLibrary\
EmbeddedResource.resx
MainGUI\
If I get the string on classes of CommonLibrary I just use EmbeddedResource.INFO_START_MSG but when I try to use typed string resource It cannot recognize the resource file. Note that the CommonLibrary is already referenced in the MainGUI.
I usually do it this way.
Solution\
CommonLibrary\
MainGUI\
EmbeddedResource.resx
But I want to use the same resource on both projects.
Add the reference to the library to the main application. Make certain that (on the Resources file) the "Access Modifier" is set to public.
Reference the string like so:
textBox1.Text = ClassLibrary1.Resource1.ClassLibrary1TestString;
I added the resource file via right clicking, thus the "1" in the name. If you go to the Properties page for the class library and click on the "Resources" tab, you can add the default resources file, which will not have the numeral "1" in the name.
Just make certain your values are public, and that you have the reference in the main project and you should have no issues.
By default the resource class is internal which means it won't be directly available in other assemblies. Try by changing it to public. A part from this you will also have to make the string properties in resource class public
The is the way I've done it in the past. However, this might not work across assemblies:
public static Stream GetStream(string resourceName, Assembly containingAssembly)
{
string fullResourceName = containingAssembly.GetName().Name + "." + resourceName;
Stream result = containingAssembly.GetManifestResourceStream(fullResourceName);
if (result == null)
{
// throw not found exception
}
return result;
}
public static string GetString(string resourceName, Assembly containingAssembly)
{
string result = String.Empty;
Stream sourceStream = GetStream(resourceName, containingAssembly);
if (sourceStream != null)
{
using (StreamReader streamReader = new StreamReader(sourceStream))
{
result = streamReader.ReadToEnd();
}
}
if (resourceName != null)
{
return result;
}
}