Coded UI Test can not find WPF Controls when launched programatically - c#

When building a Coded UI Map, I specify the application that needs to be launched as shown below.
When I run the following test, the Coded UI Test passes, having been able to locate the controls I'm specifying. In this case, it's a ListViewItem.
[TestMethod]
public void UserOpensAnExistingDiary()
{
this.UIMap.OpenExistingDiary();
}
public void OpenExistingDiary()
{
#region Variable Declarations
WpfListItem uIPenAppsLogicModelsDiListItem = this.UIPENWindow.UIDiariesGroup.UIItemList.UIDiaryGroup.UIPenAppsLogicModelsDiListItem;
WpfWindow uIDiaryEditorWindow = this.UIDiaryEditorWindow;
#endregion
// Launch '%LOCALAPPDATA%\Pen\app-5.0.6018.18517\Pen.Apps.Desktop.exe'
ApplicationUnderTest penAppsDesktopApplication = ApplicationUnderTest.Launch(this.OpenExistingDiaryParams.ExePath, this.OpenExistingDiaryParams.AlternateExePath);
// Double-Click 'Pen.Apps.Logic.Models.DiaryModels.Diary' list item
Mouse.DoubleClick(uIPenAppsLogicModelsDiListItem, new Point(76, 72));
// Wait for 1 seconds for user delay between actions; Click 'Diary' window
Playback.Wait(1000);
Mouse.Click(uIDiaryEditorWindow, new Point(590, 25));
}
If I delete the Launch UI Action, and programmatically launch the app the test is unable to locate the ListViewItem. The only difference is my removing the Launch action, and adding the following code to my tests, so they're initialized with the window launched.
[TestInitialize]
public void Setup()
{
string appPath = ApplicationPath.GetApplicationPath();
var app = ApplicationUnderTest.Launch(appPath);
}
Does anyone know why this would be the case?

The examples you provided are confusing as to what works and what doesn't. Also, using the UI maps makes it extremely difficult to see what is going on. Please add one of the test methods that is failing and include the UI Map code for
this.UIPENWindow.UIDiariesGroup.UIItemList.UIDiaryGroup.UIPenAppsLogicModelsDiListItem
My hunch would be that the application under test is not being used as a search limiting container in the failing case.
What I would do, is change to something like:
[CodedUITest]
public class TestingClass
{
WpfWindow containingWindow;
[TestInitialize]
public void Initialize()
{
this.containingWindow = ApplicationUnderTest.Launch(appPath);
}
[TestMethod]
public void Test1()
{
WpfListItem toClick = new WpfListItem(this.containingWindow);
// look in the UI map to see what it is doing for search properties
// and take the simplest sub-set that makes sense
toClick.SearchProperties.Add("AutomationId", "SomeId");
Mouse.Click(toClick); // do not need point, typically
/*
//You may need to include more levels of searching,
//but you can see what you need from the UI Map
WpfTable table = new WpfTable(this.containingWindow);
table.SearchProperties.Add("AutomationId", "myTableId");
WpfListViewItem itemToClick = new WpfListViewItem(table);
itemToClick.SearchProperties.Add("Name", "Some name");
*/
}
}
The point here is that the list item is getting the launched window as it's container which seems to not be happening in your current case.

Related

Updating object at program level within class

I have a program that runs in the system tray that communicates with our server and "syncs" data based on a users preferenced jobs. The idea is similar to Dropbox, but for our surveying software called 12d Synergy. The idea is that users can sync data without needing to navigate through the softwares Client.
I want to add the functionality so that when the program is syncing, the icon in the system tray changes to indicate that its still syncing, but i can't figure out how to get access to the original object within the portion of the program where the event is located.
My program stucture is as follows (in c#):
Program.cs
using (ProcessingIcon pi = new ProcessingIcon())
{
pi.SetIcon(Resources._12d);
pi.Display();
Application.Run();
}
ProcessingIcon.cs
NotifyIcon ni;
public void SetIcon(Icon path)
{
ni.Icon = path;
}
public void Display()
{
ni.Text = "Sunrise Surveying 12d Synergy Sync Tool";
ni.Visible = true;
ni.ContextMenuStrip = new ContextMenus().Create();
}
ContextMenus.cs
public ContextMenuStrip Create()
{
// Sync Now
item = new ToolStripMenuItem();
item.Text = "Sync Now";
item.Click += new EventHandler(syncNow_Click);
item.Image = Resources.Sync.ToBitmap();
cms.Items.Add(item);
}
void syncNow_Click(object sender, EventArgs e)
{
string[] jobs = Sync.GetSharedFiles();
string[] files = Sync.GetDataToSync(jobs);
Sync.SyncData(files);
}
What i want to happen, is in the syncNow_click, call the ProcessingIcon.SetIcon() to change the icon, but i can't figure out how to get access to an object that exists 3 layers up in the program.
I should note that i am not a programmer, i'm a surveyor with an interest in programming. I am completely self taught, so i know there is probably something relatively simple i'm missing. This is also my first post in StackOverflow, so i'm not 100% how to use this site to the full capability, so if this has been answered somewhere i apologise.
Any help or advice would be greatly appreciated.
So i worked out a way to answer my own question. Just putting it here in case anyone has the same issue. It turned out to be incredibly simple, and purely just by me not fully understanding the classes/objects structure.
I added a constructor for my ContextMenus object which passed in the the NotifyIcon that was calling it. This was passed to a NotifyIcon variable in that class which i could then access.
class ContextMenus
{
public NotifyIcon ni;
public ContextMenus(NotifyIcon ni)
{
this.ni = ni;
}
}

How to get registered actions from UnityEngine.UIElements.TextField & Button

I am creating automated unit tests in Unity, and want to test if a method used
TextField.RegisterValueChangedCallback(SomeMethod);
with a specific method. I also want to test if a UIElement Button has a specific method registered with: Button.clicked += SomeMethod;.
My question: Is there a way to access all registered methods from these text fields and buttons? Or maybe a (not too messy) work around?
I am using UnityEngine.UIElements; in my project.
Simple version of what method I want to test:
VisualTreeAsset root; // Assigned in some other method
public void TestedMethod(){
// Get the field from the VisualTreeAsset root
textField = root.Q<TextField>("FieldName");
// Register
// This is the line I want to be tested:
textField.RegisterValueChangedCallback(SomeMethod);
}
Pseudo code to illustrate what I want to test:
[Test]
public void SomeTest()
{
// Get references from wherever they may be...
Action SomeMethod = [...];
TextField textField = [...];
Button button = [...];
// Assertions
// This is the part I need help with:
Assert.IsTrue( textField.GetRegisteredValueChange().Contains(SomeMethod) );
Assert.IsTrue( button.clicked.Contains(SomeMethod) );
}
I have looked through the Unity API, and can't find anything that seems usefull:
https://docs.unity3d.com/ScriptReference/UIElements.TextField.html
https://docs.unity3d.com/ScriptReference/UIElements.Button.html
You might use UnityEngine.EventSystems
unityengine.eventsystems

How to access & use an object which has been created on a different thread in WPF

I am having following scenario that I need to show preview option in my application like what ms-word does. When we click the info option under File menu item, then preview of document is shown.
In the same way, I also want to show the preview of my data rendering part in my application when someone clicks File\Info panel. For this i have written a method which gets the preview or screenshots of my app but that method is taking some time So when somebody click on the File menu then application hangs for a while. So, i tried to call that method on different thread using background worker as well as normal thread mechanism. but the thing is that method I am calling on different thread it returns an image source object and when I try to access that object on run worker completed event of background worker, then it shows an exception like owner of this object is a different thread which means that returned image has been created on a different thread therefore I can't use it. So, what is the optimized way to get and use that image in my case.
Code tends to be like this.
public void ShowPreview()
{
ImageSource source =null;
var bgWorkerThread = new BackgroundWorker()
bgWorkerThread.DoWork +=(SENDER,ARGS)=> {
source = planView.GetPreviewImage();
}
bgWorkerThread.RunWorkerCompleted += (sender,args)=>
{
// Application crashes at this point
infoPanel.PreviewImage.source = args.Result as ImageSource;
}
}
you can use invoke or you could create a "storage class" (i think its called a singleton but I'm not sure) reuse the same instance across several classes and/or threads like this.
class Test
{
void main()
{
newThread nt = new newThread();
Storage store = new Storage();
nt.store = store;
Thread t = new Thread(new ThreadStart(nt.runMe));
t.Start();
}
}
public class newThread
{
public Storage store;
public void runMe()
{
store.someNum = 8;
}
}
public class Storage
{
public int someNum;
}

evenhandler not getting called when executed from UnitTest Code in WP7

I m doing unit test for one of my app in WP7. I want to check whether the button_click function works properly. When I try to call the button_click function from my unit testcode
like below
CheckUrVacabolary.MainPage cpage = new CheckUrVacabolary.MainPage();
cpage.txtFind.Text = "home";
cpage.butMeaning_Click(cpage,null);
But the eventhandler(OnDefineInDictCompleted) inside the button_click(OnDefineInDictCompleted)
is not getting called. Here is the code
internal void butMeaning_Click(object sender, RoutedEventArgs e)
{
graphPass.Visibility = Visibility.Collapsed;
graphFail.Visibility = Visibility.Collapsed;
if (txtFind.Text.ToString() != "Enter the word")
{
butNext.IsEnabled = true;
DictServiceSoapClient client = GetDictServiceSoapClient();
String meaningfor;
if (txtRandomWord.Text.Trim().Length != 0)
{
txtRandomWord.Text = "";
meaningfor = wordToGuess;
}
else
{
meaningfor = txtFind.Text.Trim().ToString();
}
if (meaningfor.Length != 0)
{
client.DefineInDictCompleted +=
new EventHandler<DefineInDictCompletedEventArgs
(OnDefineInDictCompleted);
client.DefineInDictAsync("gcide", meaningfor);
}
}
}
I m not using MVVM model in my app. Is there any way I could call the event handler also.
The easy answer would be: do use MVVM nonetheless. One of its benefits is easier unit testing. But if you choose not to, you should make a separate method in a service-like class that is called by the event handler but can also be called from a unit test.
The method should contain only the business logic you want to test and not the UI behaviour. (With a view model you could even test UI behaviour, because it is abstracted). That means it should have arguments for the values you obtain from controls like txtRandomWord.
The event handler that client connects to is a problem.
First, the life cycle of each client instance you create by pressing the button is extended to that of the page, which introduces a potential memory leak.
Second, I assume OnDefineInDictCompleted is a method in your page, so you should extract that from the page as well in a way that it is accessible to unit tests. If that method touches UI elements, this may be a real headache. Again, a strong case for a view model.

C# How can I update a form Control from foreign code

I'm trying to optimize my code to be called from both an UI-less commandline call or call it from the UI.
The problem is that I have is I have written the lets call It worker-code inside the Form-class.
Now I want to pull out that worker code into a separate class.
Lets make a small sample to make my needs clearer:
public partial class form1 :Form
{
void AddLogmessage(String msg)
{
// update an listview
ListViewItem item = new ListViewItem();
item.Text = msg;
// Add the item to the ListView
LogView.Items.Add(item);
}
// button on ui to start working
private void btnStartTestRun_Click(object sender, EventArgs e)
{
try
{
DoSomeWork();
}
catch(Exception ex)
{}
}
private void DoSomeWork()
{
// do some really generic hard work....
AddLogMessage("working");
// do some more generic long lasting hard work....
AddLogMessage("working goes on...");
// in case of an error throw Exception
}
Now I want to refcator the worker code to work outside the form class, but be able to report the things that happen to the UI (if there is one) or to call the workercode without UI and do other reportings to an different target (communicate with other library which reports the results to an server)
Something like this:
public void AutomaticTaskHandler()
{
string[] cmdline = Environment.GetCommandLineArgs();
Arguments args = new Arguments(cmdline);
if (args["automatic"] != null)
{
doSomeWork();
}
}
In this case I don't have to report the Messages to the UI, but send some other messages (NOT the same Messages!!) to an server.
So my question is how do I make this the best way not having to write the doSomeWork - code twice but be able to send only the messages which are in the current scene are needed?
I thought about Delegates and Events, but I'm not too familiar to this to make this work.
Any help will be appreciated.
Thanks Meister_Schnitzel
Basically, you would create an interface IMessageTarget with a method SendMessage. Your UI code would create an implementation of that interface that outputs the messages to the UI and your console code would create an implementation of that interface that sends the messages to a server. On calling the doWork method, you would supply an instance of IMessageTarget.

Categories