I've got a VS editor extension, and when the user performs a certain action, I'd like to send them to a specific location in the code- not unlike Go To Definition or what happens when you click on a stack frame in the debugger.
So far, I used dte.ItemOperations.OpenFile to open the actual file, and I have the relevant ITextDocument, but I don't know how to set the view to the relevant place in the file. It seems like ITextView and IVsTextView and friends have the methods that I need but I'm unsure how to get the instances I need from my ITextDocument.
How can I go to the file and location I want from a VS extension?
The easiest way to do this is to take the return of ItemOperations.OpenFile and navigate from it to the IWpfTextView
IWpfTextView GetWpfTextViewForDteWindow(
Window window,
System.IServiceProvider serviceProvider,
IVsEditorAdaptersFactoryService vsEditorAdaptersFactoryService)
{
var path = Path.Combine(window.Document.Path, window.Document.Name);
IVsUIHierarchy vsuiHierarchy;
uint itemID;
IVsWindowFrame vsWindowFrame;
if (VsShellUtilities.IsDocumentOpen(
serviceProvider,
path,
Guid.Empty,
out vsuiHierarchy,
out itemID,
out vsWindowFrame))
{
// Note this may have multiple IVsTextView instances associated with it in a split window but
// this will retrieve at least one
var vsTextView = VsShellUtilities.GetTextView(vsWindowFrame);
var wpfTextView = vsEditorAdaptersFactoryService.GetWpfTextView(vsTextView);
return wpfTextView;
}
return null;
}
Do note that there is not necessarily a 1-1 mapping between a DTE Window object and ITextView instance. The Window object essentially represents what is visually displayed as a tab and a given tab can contain many ITextView instances. The most common case is when there is a horizontal split in the window. Probably doesn't matter too much for this scenario but wanted to make sure that it got called out
Related
I'm trying to make an augmented reality application with vuforia and unity.
whenever it recognize the image target, it must tell a story by showing text , and it should enable the user to press next and back to go on reading the different parts of this story, I'm totally new to unity and don't know how to handle with UI throughout scripting, I need some help on how to accomplish the part of "going forward and backward on showing the story by hitting Next and Back buttons", and all these parts of story should be related to the same image target in the same scene.
I appreciate it if you help me with an example code.
You should create some script that attach on trackable object, maybe something like this.
public class DataBook {
string[] dataBook;
string idText;
bool isActive;
}
Then you must create another script to set that trackable object is active or not, this link can help you to get that.
https://developer.vuforia.com/forum/faq/unity-how-do-i-get-list-active-trackables
Then after you get the active trackable object, you can set the dialog from the book by create another controller script for button, example
public void Next() {
DataBook[] books = FindObjectsOfType<DataBook>(); // if the object more than one, it will be more easy if it only the one
foreach (var book in books)
{
if (book.isActive) {
book.idText += 1;
textUI.text = book.dataBook[idText]; //textUI assign to object text on canvas
}
}
}
you can learn about unity UI Button on this :
https://unity3d.com/learn/tutorials/modules/beginner/ui/ui-button
Good luck
I am new to UI test writing.
I wanted to know if it is possible to know what elements are/exists in view. I want to know how many and how they are called.
I tried something like this to loop through all elements, but it does not work.
for element in app.accessibilityElements! {
print(element)
}
You're looking for the debugDescription method of XCUIElement, in your case to get the entire hierarchy of the current visible window:
app.debugDescription
Quoting header comments:
Provides debugging information about the element. The data in the string will vary based on the
time at which it is captured, but it may include any of the following as well as additional data:
• Values for the elements attributes.
• The entire tree of descendants rooted at the element.
• The element's query.
This data should be used for debugging only - depending on any of the data as part of a test is unsupported.
You could always have a break point in the testcase and then make some print calls to the console.
po app.accessibilityElements
po app.accessibilityElements.elementBoundByIndex(0)
po app.buttons["Icon Menu Light"]
etc.
And see what comes back in the output view hierarchy to reference, or just a simple call to po app will print the hierarchy.
Once you know a particular view exists.. app.buttons["Icon Menu Light"].exists.. you can then try using something like this to confirm the button/element is visible within the current view by passing it to a helper function like:
func isElementInView(element: XCUIElement) -> Bool {
let window = XCUIApplication().windows.elementBoundByIndex(0)
return CGRectContainsRect(window.frame, element.frame) }
This will tell you whether the element is visible on the screen, because the element.exist call will return true, even if the element is off screen and hasnt been shown to the user (i.e. if something hides off screen and then transitions into the frame)
I am working on a, hand coded, Coded UI test for an application.
The application has a certain function that operates in 2 windows. When a button is clicked, a new window appears and then the user makes a selection upon which that window closes, and then the user continues taking actions on the main window.
With Selenium, I would handle that by iterating through all the window handles and switching by using passing it the URL of the page I wanted using the "driver.SwitchTo().Window(handle)" method. However, with Coded UI, I have not found a similar solution. Using the Process class I can do something similar that could work:
Process[] myList = Process.GetProcessesByName("iexplore");
foreach (Process item in myList)
if (item.MainWindowTitle.Contains("Window Title"))
{
item.Kill();
}
The problem is that the application that I am testing is poorly designed and all windows throughout the application have the same name, thus it will not work.
Is there a method which can be used to switch to a different window on Coded UI? Or what would be the best approach?
Take a look at this question, it might help: Interacting with multiple instances of an application in Coded UI
You don't do "switching" in CUIT, every window and control is accessed via a UITestControl object. If you want to do stuff on an other window you create a new object for it. If you can't differentiate the two windows with search properties you can use the Instance property or FindMatchingControls method.
To catch a window creation event you can use a winhook. It gives you the window handle of every window created. Using that you can find out if the window created is the window you are waiting for and then use the UITestControlFactory.FromWindowHandle to create a UITestControl for CUIT to interact with. If you have a generated class for that window you can create an instance of that class and call its CopyFrom method to pass to it the control you created from the window handle.
I am using:
public static HtmlDocument WaitForPopup(string popupName, string text)
{
BrowserWindow browser = new BrowserWindow();
browser.SearchProperties.Add(BrowserWindow.PropertyNames.Name, popupName,
PropertyExpressionOperator.Contains);
browser.WindowTitles.Add(popupName);
browser.WaitForControlExist();
browser.WaitForControlReady();
browser.SetFocus();
HtmlDocument html = new HtmlDocument(browser);
html.SearchProperties.Add(HtmlDocument.PropertyNames.InnerText, text,
PropertyExpressionOperator.Contains);
html.WaitForControlExist();
html.WaitForControlReady();
Playback.Wait(1000);
return html;
}
Just call WaitForPopup("your window name", "some constant text in window") and continue with tests there.
Note that this method will return html of the new window and you can use it further on.
I'm using SHOpenFolderAndSelectItems in order to open up a new explorer window showing a particular location (PIDL). I'm not interested in opening just file paths, so I need to use a PIDL as far as I know!
This works, however, I'm not interested in selecting any of the items in the window. If I don't pass any items to be selected, the parent folder is opened instead, as per the documentation:
A count of items in the selection array, apidl. If cidl is zero, then
pidlFolder must point to a fully specified ITEMIDLIST describing a
single item to select. This function opens the parent folder and
selects that item.
How am I able to simply open the location pointed to by my passed PIDL?
As a test, I passed one item to be selected, pointing to a null pointer. This seems to work, but I'm afraid this might have unintended side effects. This behavior doesn't seem to be documented. Is there a better way to go about what I want to achieve, or is the way I'm using this function now correct?
SHOpenFolder**AndSelectItems**() should be a good indication that this is the wrong function for you to use. If you just want to open the folder, use ShellExecuteEx() instead, eg:
SHELLEXECUTEINFO sei = {0};
sei.cbSize = sizeof(sei);
sei.fMaask = SEE_MASK_IDLIST;
sei.hwnd = ...;
sei.lpVerb = TEXT("explore"); // <-- not "open"
sei.lpIDList = ...; // <-- your pidl
sei.nShow = SW_SHOW;
ShellExecuteEx(&sei);
I'm working on a concept that works like copy & paste but uses my own algorithm instead of using the clipboard.
We have users that use many different programs that contain part numbers. This is how my concept would work.
User highlights part number from any application (word, excel, pdf, JDE, etc)
Either by hotkey or clicking on another application the user launches my routine.
My routine grabs that text from the original application and processes it accordingly.
I know how to use the clipboard to get text.
What I'm not sure of is how to get currently selected text from the application that was active prior to running my code? Do I need to force my user to copy to clipboard first and then run my app or can I create my own copy/paste type windows add-in?
Preferred VB for this but can also use C++ or C# if easier.
As to the question why, because we want to the action to be seamless to the user. There will be several behind the scenes actions that take place and then the user will be presented a browser with pertinent information related to that part number. Ultimately, I don't want an in-between screen to pop up, but rather completely hidden from the user. If I require them to copy and then run my routine then I'm adding in one extra step to the user path that I'm hoping to avoid.
I looked into right click menu context a bit but found that each program can have their own override. I wasn't able to locate a way to globally override all right click context menus to include a new action.
From this article:
var element = AutomationElement.FocusedElement;
if (element != null)
{
object pattern;
if (element.TryGetCurrentPattern(TextPattern.Pattern, out pattern))
{
var tp = (TextPattern) pattern;
var sb = new StringBuilder();
foreach (var r in tp.GetSelection())
{
sb.AppendLine(r.GetText(-1));
}
var selectedText = sb.ToString();
}
}
It's in C# but it should be pretty trivial to translate.