I am setting up Coded UI Tests for WPF application and I want to use code approach instead of record-and-generate-code approach. I'd like to use page objects trough code and I need to declare control (buttons, tabs, etc.) variables in page objects that would be used by multiple functions.
I tried declaring the variable in a class and adding properties in constructor (pendingButton1)
and creating function which returns the control and assigning to a variable in a class (pendingButton2) but neither worked.
It works when I declare the variable (or create the variable by function) within the function that I want to use the variable in (pendingButton3 and 4).
public partial class Press : Header
{
WpfToggleButton pendingButton1 = new WpfToggleButton(_wpfWindow);
WpfToggleButton pendingButton2 = Controls.Press.getPendingButton(_wpfWindow);
public Press(WpfWindow wpfWindow):base(wpfWindow)
{
this.pendingButton1.SearchProperties[WpfControl.PropertyNames.AutomationId] = "Tab1Button";
}
public void clickPendingButton() {
WpfToggleButton pendingButton3 = new WpfToggleButton(_wpfWindow);
pendingButton3.SearchProperties[WpfControl.PropertyNames.AutomationId] = "Tab1Button";
WpfToggleButton pendingButton4 = Controls.Press.getPendingButton(_wpfWindow);
Mouse.Click(pendingButton1); //UITestControlNotFoundException
Mouse.Click(pendingButton2); //UITestControlNotFoundException
Mouse.Click(pendingButton3); //This works
Mouse.Click(pendingButton4); //This works
}
}
I'd like to make it work when I declare the pendingButton outside clickPendingButton() function since it is used in multiple other functions.
The helper function Controls.getWpfButton() return just properties of the button, not "real" button. It has to be used in a constructor, then it can be used anywhere within the class. I wouldn't say its best practice but it works for me.
Press.cs
public partial class Press : SharedElements
{
private WpfButton pendingButton;
public Press(WpfWindow wpfWindow):base(wpfWindow)
{
pendingTab = Controls.getWpfButton(_wpfWindow, "Tab1Button");
}
public void clickPendingButton() {
Mouse.Click(pendingButton);
}
}
Controls.cs
internal static WpfButton getWpfButton(WpfWindow wpfWindow, string AutomationId)
{
WpfButton button = new WpfButton(wpfWindow);
button.SearchProperties[WpfControl.PropertyNames.AutomationId] = AutomationId;
return button;
}
What you want appears to be exactly the sort f code that the Coded UI record and generate tool generates. It creates many pieces of code that have a structure of the following style:
public WpfToggleButton PendingButton
{
get
{
if ((this.mPendingButton == null))
{
this.mPendingButton = new WpfToggleButton( ... as needed ...);
this.mPendingButton.SearchProperties[ ... as needed ...] = ... as needed ...;
}
return this.mPendingButton;
}
}
private WpfToggleButton mPendingButton;
This code declares the button as the class property PendingButton with a private supporting field that has an initial and default value of null. The first time that property is needed the get code executes the required search and saves the found control in the private field. That value is then returned in each subsequent usage of the property. Note that assigning null to the supporting field can be done to cause a new search, as demonstrated in this Q&A.
Related
I create a user control like below:
public partial class TestControl : UserControl
{
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public State MyState
{
get { return new State(this); }
}
internal int[] _internalStates;
[TypeConverter(typeof(ExpandableObjectConverter))]
public struct State
{
private TestControl _myControl;
public State(TestControl _) { _myControl = _; }
public int Data
{
get { return _myControl._internalStates[0]; }
set { _myControl._internalStates[0] = value; }
}
}
}
Then I can drag the control from toolbox and modify the Data value in the designer.
The problem is the designer will generate this code in InitializeComponent method:
this.testControl1.MyState.Data = 0;
But this line will throw an error:
Cannot modify the return value of 'TestControl.MyState' because it is not a variable
I understand why the statement is error, the question is how can I control the code generation to correct the error, for example to generate code like this?
var myState = this.testControl1.MyState;
myState.Data = 0;
More information
State struct is just a bridge to modify the internal property in TestControl
So I want to keep State as a struct to avoid GC overhead.
The reason for not define property in TestControl class is there are multiple states in the class, and a state will contain multiple properties, so I need to wrap the modification methods rather than define a lot of properties in the TestControl class.
Why a compile time error for Control.StructProperty.Member = Value;?
Consider the following statement
this.Control.StructProperty.Value = 0;
StructProperty is a property, so first its getter will execute and since it's a structure and is a value type, it will return a copy of the struct and setting a property for that copy is not useful/working. The knows about the situation well and instead of compiling a confusing non-working code, it generates Compiler Error CS1612:
Cannot modify the return value of 'expression' because it is not a
variable
How can I generate a working code for a Struct property?
You probably have noticed that you cannot assign this.Size.Width = 100 with the same reason. And the way that form generates the code for Size property is:
this.Size = new Size(100,100);
You also can generate code for the property the same way, by implementing a type descriptor by deriving from TypeConverter returning an InstanceDescriptor in its ConvertTo method to generate the code for your structure property using a parametric constructor which you should have for the struct.
In general, I suggest using classes rather that structures for such property.
So, i'm not sure what i'm doing wrong here but for some reason the callback function in TypeScript that i have doesn't have anything but _proto in the response's .data property whenever i set private properties in C# and new up an object that is filled with constructed properties. However, if the properties are public and i don't use a constructor then i can see the response's .data property is filled like i would expect it to be. Here is an example of what works:
public class ThisWorks{
public string MyProperty{get;set;}
}
Inside application layer:
ThisWorks example = new ThisWorks();
example.MyProperty = myReflectedProperty;
return example;
However, this does not work:
public class ThisDoesNotWork{
private string MyPrivateProperty {get;set;}
public ThisDoesNotWork(string myPrivateProperty){
MyPrivateProperty = myPrivateProperty;
}
}
What's causing this to happen? My TypeScript service has not changed but for some reason the data isn't coming across from the service call...Any help would be greatly appreciated! Also, Serialization is NOT constructive for this thread.
If you want to control access to a property, you can normally do this very will without a method in C#...
It appears that you want the ability to set the property, but not read it. The following is an example of a public write-only property, which you can read and write in private context.
This appears as a property to callers, rather than a method.
public class Example
{
private string _exampleProperty;
public string ExampleProperty
{
set { _exampleProperty = value; }
}
}
I have 2 variables
Date-Time-Modified which is a Date-Time variables
Is-Deleted variable which is a boolean.
These two variables are found in each class I have and I need to have these variables initialized each time I insert, edit or delete an object from my database. Is there a way to do this?
Use a base class. Add the 2 needed properties (DateTime, IsDeleted). Every derived class now holds this properties. You can set them individually or iterate over the base type to assign a value.
You can also use events to trigger the update automatically. But i think you just want to create an entry and then set its DateTime property to the actual date time.
You also could delegate this task to the database. It will take care of setting this attributes.
An example for my lazy friend ;)
abstract class DatabaseEntryBase
{
public DatabaseEntryBase()
{
// You can initialize properties to a default value here
this.IsDeleted = false;
}
public DateTime ModifiedTime { get; set; }
public bool IsDeleted { get; set; }
}
class Entry : DatabaseEntryBase
{}
static void Main()
{
//-- Do your SQL stuff --//
var newEntry = new Entry();
newEntry.ModifiedTime = DateTime.Now;
newEntry.IsDeleted = false;
}
If you need all instances to hold the same values (e.g. multiple deletes) push them into a collection (here EntryCollection of type List<DatabaseEntryBase>) and iterate over them instead:
public void SetAllItems()
{
foreach (DatabaseEntryBase entry in EntryCollection)
{
entry.ModifiedTime = DateTime.Now;
entry.IsDeleted = [...];
}
}
Using an interface will accomplish the same! It could be named ITaggable and defines this two properties as a contract.
Have a base class that has these members and then have the other classes extend that one.
Then have a method on the base that initalises them. Then call that method on the inserts and such.
base.InitialiseVariables()
Is there any other way to just initialize them without the need of
calling a method?
Probably another approach for this is Aspect-Oriented Programming. For example, PostSharp.
Code will look something like this:
[UpdateTimestamp]
public void InsertProduct(Product product)
{
// Your logic here
}
Per the MSDN documentation, the following syntax is used:
// A read-write instance property:
public string Name
{
get { return name; }
set { name = value; }
}
However, the following code is generated by VS2010 automatically for a new library class:
public string Name
{
get
{
String s = (String)ViewState["Name"];
return ((s == null) ? String.Empty : s);
}
set
{
ViewState["Name"] = value;
}
}
When is it appropriate to use the ViewState syntax over the shorter example shown on MSDN?
ViewState is a feature of ASP.Net server controls that persists information across postbacks.
For simple properties that aren't in a server control, you should use an auto-implemented property:
public string Name { get; set; }
The first stores the value in a private property field inside the class, while the second (tries to) store the actual value in the ViewState.
So the 2nd is only possible when you are talking about ASP controls with viewstate enabled, which is a narrow subset of all possible cases.
A C# property is just a piece of syntactic sugar. This structure
public Foo MyValue { get ; private set ; }
is exactly as if you coded:
private Foo _myValue ;
public Foo
{
get
{
return _myValue ;
}
private set
{
this._myValue = value ;
}
}
In either case, the code that actually gets generates is pretty much this:
private Foo _myValue ;
public Foo MyValue_get()
{
return this._myValue ;
}
private Foo MyValue_set( Foo value )
{
this._MyValue = value ;
}
If you opt to instantiate your own getter/setter, then what happens in the body of the getter/setter is entirely up to you. There is no "right" or wrong: it's dependent on the needs of your program.
With respect to ViewState, ViewStateis a piece of ASP.Net. It has little do with properties one way or another. You example just exposes a ViewState item as a public read/write property.
The difference between the two is that one is just plain old C# property providing access to a (most likely) privately scoped variable in your class.
The other one is returning a value recovered from ASP.NET's ViewState.
These are two different things altogether.
1) I'm still quite new to programming and have read a bit about getters and setters. But I really don't understand why they are used.. Could anyone explain it, or point me to an article? (The ones I read were not really understandable for me...)
2) In my current project I have a class where I declare and initialize an array of structs. I now need to access the array from another class, but it gives me the error: An object reference is required to access non-static member 'BaseCharacter.Attributes'.
I figures this could mean I need to use getters and setters? But how does this work for arrays?
Thanks in advance!
Simon.
EDIT: 2nd question got solved, which brings me to something else. When I want to use some class in another one, I'm making a new instance of the class, right? And this means I get the original values?
But that's not what I want.
The second class is used to generate the UI, and needs the values I'm keeping in the first class.
At some point I will implement save files (XML or even on a server in later stage). Can I then just get the values from those files?
For the getters and setters (the things that use them are called Properties) it's just a convenient and nice-looking way to make people think they're using a variable, but to do some computation whenever the variable is updated or accessed. For instance:
BankAccount.Interest
looks better than
BankAccount.GetInterest()
Even though you can calculate the interest at the time it is requested in both cases.
They are also used to make a variable be able to be accessed from outside the class, but changeable only from within the class with this technique:
public double Interest {
get;
private set;
}
For an example of a setter being used, if you've ever used Windows Forms and updated a control's Height or Width property, you're using a setter. While it looks like you're using a normal instance variable like c.Height = 400, you're really letting c update it's position by redrawing at a new place. So setters notify you exactly when a variable is changed, so your class can update other things base on the new value.
Yet another application of Properties is that you can check the value people try to set the property to. For instance, if you want to maintain an interest rate for each bank account but you don't want to allow negative numbers or numbers over 50, you just use a setter:
private int _interestRate = someDefault;
public int InterestRate {
get { return _interestRate; }
set {
if (value < 0 || value > 50)
throw new SomeException(); // or just don't update _interestRate
_interestRate = value;
}
}
This way people can't set public values to invalid values.
For your second question, you can do one of two things depending on what you're trying to do.
One: You can make that member static. That means that just one of them exists for the entire class instead of one per instance of the class. Then you can access it by ClassName.MemberName.
You can do that this way:
// inside the BaseCharacter class definition:
public static SomeStruct[] Attributes = new SomeStruct[size];
// then to use it somewhere else in your code, do something with
BaseCharacter.Attributes[index]
Two: You have to make an instance of the class and access the array through that. This means that each object will have its own seperate array.
You'd do that like this:
BaseCharacter bc = new BaseCharacter();
// use bc.Attributes
The second one is probably what you'll want to do, since you probably will want to modify each character's attributes seperately from all the other characters.
Actually the error you mention is not related to the getters and setters concept, it's because after creating your class you need to create an object before using its members; think of the class as a template for a document and the object as the document
you are most likely doing something like this:
var someVar = BaseCharacter.Attributes;
When you should be doing something like this:
var someVar = new BaseCharacter();
var someOtherVar = someVar.Attributes;
And about why the getters and setters, Seth Carnegie's Answer covers it nicely.
If you are new to Object Oriented Programming, you may be missing an important concept, that is about encapsulation.
Fields (attributes) of a class should be accessed only from within the class (or it's inherited classes). That is, if we have a class person, only with a name, you can do
public class Person
{
public string Name;
}
So anywhere in your program, you will be able to access it by doing:
Person person = new Person();
person.Name = "Andre";
This works, but it's not encapsulated. In some languages like C++ or Java, it was done like this:
public class Person
{
private string _name;
public string setName(string newName)
{
this._name = newName;
}
public string getName()
{
return this._name;
}
}
Person person = new Person();
person.setName("Andre");
This makes our _name attribute encapsulated, it can only be retrieved by it's get and set methods (that is, by the interface of the class).
C# makes this easier, allowing getters and setters:
public class Person
{
private string name;
public string Name
{
get { return this.name; }
set { this.name = value; }
}
}
Person person = new Person();
person.Name = "Andre";
This is very much like the second example (Java/C++ way), but you treat Name as property, instead of methods, and leaving our name property encapsulated
1) They might seem optional but they allow you more control over code:
You're able to intercept new values and avoid them being set (e.g. to exclude pointless values). Also you're able to fire custom events in case a property is changed or updated (just like the WinForms controls do).
private string name;
public string Name
{
get
{
// running additional code, e.g. here I avoid returning 'null' for a name not set
if(name == null)
return "(Unknown)";
return name;
}
set
{
// checking incoming values, e.g. here I avoid setting an empty name
name = value != null && value.Length > 0 ? name : null;
// running more/additional code, e.g. here I raise an event
if(OnNameChange)
OnNameChange();
}
}
2) Without knowing the code it's hard to tell you the exact reason, but if you'd like to access some member variable or property you have to either create an object of that class or make the variable static (e.g. shared between all instances of the object):
class MyClass
{
public static int someNumber = 55;
public int thisNumber;
}
// ...
int someothervar = MyClass.someNumber; // access the static member variable
MyClass mc = new MyClass(); // create an object of the class
int yetanothervar = mc.thisNumber; // access the member variable