Using TestComplete's UIAObject with Microsoft UI Automation Control Patterns - ui-automation

In TestComplete, the UIAObject "ControlPatterns" property lists the Microsoft UIA Control Patterns for an object.
General Question :
How do you invoke these control patterns against the UIAObject?
Specific Question:
How do you get the column header for a DataGridCell given you have the UIAObject?

As far as I know, TestComplete supports patterns for UI Automation objects. The patterns' members are available as the corresponding object's members in TestComplete. You do not need to cast an object to a pattern or invoke a pattern in any other special ways.
As for your specific question, you can get the index of the column via the column property and then find the corresponding column by this index.
var dataCellObj = dataGridObj.UIAObject("RowsPresenter").UIAObject("Example_Nutrition_2").UIAObject("DataGridCell");
var colIndex = dataCellObj.column;
var column = dataGridObj.UIAObject("ColumnHeadersPresenter").Child(colIndex);
Log.Message(column.NativeUIAObject.Name);

Related

Creating a structure within a structure with a dynamic name

I have large data sets which i want to work with in matlab.
I have a struct called Trail containing serveral structures called trail1, trail2 ...
which then contain several matrices. I now want to add another point to for instance trail1
I can do that with Trail.trail1.a2rotated(i,:) = rotpoint'; the problem is that i have to do it in a loop where the trail number as well as the a2rotated changes to e.g. a3rot...
I tired to do it like that
name ="trail"+num2str(z)+".a2rotated"+"("+i+",:)";
name = convertStringsToChars(name);
Trail.(name) = rotpoint'
But that gives me the error: Invalid field name: 'trail1.a2rotated(1,:)'.
Does someone have a solution?
The name in between brackets after the dot must be the name of a field of the struct. Other indexing operations must be done separately:
Trail.("trail"+z).a2rotated(i,:)
But you might be better off making trail(z) an array instead of separate fields with a number in the name.

mirth connect Database Reader automatic column mapping

Please could somebody confirm the following..
I am using Mirth Connect 3.5.08232.
My Source Connector is a Database Reader.
Say, I am using a query that returns multiple rows, and return the result (via JavaScript), as documentation suggests, so that Mirth would treat each row as a separate message. I also use a couple of mappers as source transformers, and save the mapped fields in my channel map (which ends up to contain only those fields that I define in transformers)
In the destination, and specifically, in destination response transformer (or destination body, if it is a JavaScript writer), how do I access the source fields?
the only way I found by trial and error is
var rawMsg = connectorMessage.getRawData();
var xmlMsg = new XML(rawMsg);
logger.info(xmlMsg.some_field); // ignore the root element of rawMsg
Is this the right way to do this? I thought that maybe the fields that were nicely automatically detected would be put in some kind of a map, like sourceMap - but that doesn't seem to be the case, right?
Thank you
If you are using Mapper steps in your transformer to extract the data and put it into a variable map (like the channel map), then you can use any of the following methods to retrieve it from a subsequent JavaScript context (including a JavaScript Writer, and your response transformer):
var value = channelMap.get('key');
var value = $c('key');
var value = $('key');
Look at the Variable Maps section of the User Guide for more information.
So to recap, say you're selecting a column "mycolumn" with a Database Reader. The XML sent to the channel will be something like this:
<result>
<mycolumn>value</mycolumn>
</result>
Then you can choose to extract pieces of that message into specific variables for later use. The transformer allows you to easily drag-and-drop pieces of the sample inbound message.
Finally in your JavaScript Writer (or in any subsequent filter, transformer, or response transformer), just drag the value into the field you want:
And the corresponding JavaScript code will automatically be inserted:
One last note, if you are selecting a lot of variables and don't want to make Mapper steps for each one individually, you can use a JavaScript Step to iterate through the message and extract each column into a separate map variable:
for each (child in msg.children()) {
channelMap.put(child.localName(), child.toString());
}
Or, you can just reference the columns directly from within the JavaScript Writer:
var msg = new XML(connectorMessage.getEncodedData());
var column1 = msg.column1.toString();
var column2 = msg.column2.toString();
...

Getting the column name (sspace) from an ospace property name

I can see from the following example how to get the table name of an OSpace type:
https://lowrymedia.com/2014/06/10/ef6-1-mapping-between-types-tables-including-derived-types/
But how do I go about getting the SSpace column name from an OSpace property name (i.e. CLR type property)?
By browsing the MetadataProperties from the corresponding CSpace property, I can see there is a "Configuration" entry containing the column name if changed using the Fluid API or ColumnAttribute, but the value of the entry is an internal class on EF's part. Is it at all possible?
I have browsed a few answers regarding this topic, but none of them take into account the Fluid API configuration.
P.S. the specific property I'm looking for is scalar, if that can simplify things...
Column Name
To get the column name, you have to first get the EdmProperty associated with that column in the “structural space” (SSpace). I provide code to do that below. Once you have the EdmProperty, the name of the column is simply EdmProperty.Name:
string GetColumnName(DbContext context, PropertyInfo property) {
return GetStructuralSpaceEdmProperty(context, property).Name;
}
Structural Space Property
This is based on an article. That article gives you enough information to map all the way to the structural EntityType. I added a bit at the end to do the actual property mapping to get the EdmProperty representing the column. As the article states, these APIs require ≥EntityFramework-6.1.
EdmProperty GetStructuralSpaceEdmProperty(DbContext context, PropertyInfo property) {
IObjectContextAdapter adapter = context;
var metadata = adapter.ObjectContext.MetadataWorkspace;
// First, you map the Object Space to the Conceptual Space.
var objectItemCollection = (ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace);
var objectEntityType = metadata.GetItems<EntityType>(DataSpace.OSpace)
.Single(oet => objectItemCollection.GetClrType(oet) == property.DeclaringType);
// Note: we are assuming that CSpace and OSpace name their properties the
// same instead of trying to use EF’s own OSSpace mappings here.
var conceptualEntityType = metadata.GetItems<EntityType>(DataSpace.CSpace)
.Single(cet => objectEntityType.Name == cet.Name);
var conceptualEdmProperty = conceptualEntityType.Properties
.Single(ep => ep.Name == property.Name);
// Then you map the conceptual space onto the structural space.
var entitySet = metadata.GetItems<EntityContainer>(DataSpace.CSpace)
.Single().EntitySets
.Single(es => es.ElementType.Name == conceptualEntityType.Name);
var entityMapping = metadata.GetItems<EntityContainerMapping>(DataSpace.CSSpace)
.Single().EntitySetMappings
.Single(esm => esm.EntitySet == entitySet);
// The entity may be split to different tables or fragments.
var fragments = entityMapping.EntityTypeMappings
.SelectMany(etm => etm.Fragments);
var propertyMappings = fragments.SelectMany(f => f.PropertyMappings);
// Normal properties will be “ScalarPropertyMapping”.
// Depending on what information you are seeking or your
// model, you may be interested in other PropertyMapping.
var structuralSpaceProperty = propertyMappings
.OfType<ScalarPropertyMapping>()
.Single(pm => pm.Property == conceptualEdmProperty).Column;
return structuralSpaceProperty;
}
Note that once you have EdmProperty in structural space, there are a bunch of other useful properties you can read from it. For example, for SQL Server, EdmProperty.IsUnicode will be true for NVARCHAR/NCHAR and false for VARCHAR/CHAR types whereas this property is not set to a useful value in the conceptual space.
Random Information
Spaces in EF
Alex D. James’s blog post “Tip 10 — How to understand Entity Framework jargon” explains some of the terms of the API which do not make sense on their own. DataSpace.OSpace stands for “Object Space”, meaning the .net POD classes. DataSpace.SSpace stands for “Structural Space”, probably named after “structured” in the term “SQL” and thus meaning it most directly describes the backend database. DataSpace.CSpace stands for “Conceptual Space” which seems intended to be a neutral space which both the “Object Space” and “Structural Space” can map into. DataSpace.OCSpace stands for the mapping from the object space onto the conceptual space. We bypass this mapping because we assume that property names in the object space are the same as in our .net types. DataSpace.CSSpace stands for the mapping of conceptual space onto structural space. We use this mapping because the model may be configured to use a different column name via the fluent API or ColumnAttribute.
API Confusion
The metadata API of EF seems to assume that the consumer of the API has an understanding of the internals of EF to an extent. It is not made in a very type safe way which helps consumers. For example, the fact that we had to use Enumerable.OfType<TResult> to get to ScalarPropertyMapping means that one has to know to expect the collection to have ScalarPropertyMapping instances in it. Likewise, the MetadataWorkspace.GetItems<T>() method requires us to know that the sorts of items one would find in the metadata include EntityType. Thus, a deep understanding of the internals of EF or complete examples are necessary to write code that consumes the mapping portion of these APIs.

SugarCRM: How to retrieve complex SQL statements with sugar internal functions?

In order to retrieve a contact, having a cell phone number of 09362724853, I use following code:
$newSMS_contact = new Contact;
$newSMS_contact->retrieve_by_string_fields(array('phone_mobile'=>'09362724853'));
How about retrieving a contact having a cell phone number of 09362724853 OR 9362724853 OR +989362724853 with sugar internal functions?
This doesn't work:
$newSMS_contact = new Contact;
$newSMS_contact->retrieve_by_string_fields(array('phone_mobile'=>'09362724853', 'phone_mobile'=>'9362724853', 'phone_mobile'=>'+989362724853'));
The thing is that the function which you are trying to utilize was created for other goals. Since it fetches only one row from DB and fills a Bean with it, the Array of parameters will be turned into a string separated by AND operators. But you have completely different case.
I would suggest to use another approach, which is less convenient but more reliable:
$contact_bean = new Contact();
$contacts_list = $contact_bean->get_full_list(null, '(phone_mobile = "09362724853" OR phone_mobile = "9362724853" OR phone_mobile = "+989362724853")');
Eventually, you will have an array of beans.
Probably, for some modules, you will need to use table aliases for fields definition into SQL supplement.
If I were you, I'd have strict rules when the phone numbers are put in the system so you can be sure your phone numbers follow a certain format in the database. (Something like E.164: http://en.wikipedia.org/wiki/E.164) You can enforce the rules with a custom SugarField (or override one that exists) that has Javascript and Server-side validation.
This way, you won't have to worry about that logic in this piece of the code or anywhere else you want to deal with phone numbers.

Text input through SSRS parameter including a Field name

I have a SSRS "statement" type report that has general layout of text boxes and tables. For the main text box I want to let the user supply the value as a parameter so the text can be customized, i.e.
Parameters!MainText.Value = "Dear Mr.Doe, Here is your statement."
then I can set the text box value to be the value of the parameter:
=Parameters!MainText.Value
However, I need to be able to allow the incoming parameter value to include a dataset field, like so:
Parameters!MainText.Value = "Dear Mr.Doe, Here is your [Fields!RunDate.Value] statement"
so that my report output would look like:
"Dear Mr.Doe, Here is your November statement."
I know that you can define it to do this in the text box by supplying the static text and the field request, but I need SSRS to recognize that inside the parameter string there is a field request that needs to be escaped and bound.
Does anyone have any ideas for this? I am using SSRS 2008R2
Have you tried concatenating?
Parameters!MainText.Value = "Dear Mr.Doe, Here is your" & [Fields!RunDate.Value] & "statement"
There are a few dramatically different approaches. To know which is best for you will require more information:
Embedded code in the report. Probably the quickest to
implement would be embedded code in the report that returned the
parameter, but called String.Replace() appropriately to substitute
in dynamic values. You'll need to establish some code for the user for which strings will be replaced. Embedded code will get you access to many objects in the report. For example:
Public Function TestGlobals(ByVal s As String) As String
Return Report.Globals.ExecutionTime.ToString
End Function
will return the execution time. Other methods of accessing parameters for the report are shown here.
1.5 If this function is getting very large, look at using a custom assembly. Then you can have a better authoring experience with Visual Studio
Modify the XML. Depending on where you use
this, you could directly modify the .rdl/.rdlc XML.
Consider other tools, such as ReportBuilder. IF you need to give the user
more flexibility over report authoring, there are many tools built
specifically for this purpose, such as SSRS's Report Builder.
Here's another approach: Display the parameter string with the dataset value already filled in.
To do so: create a parameter named RunDate for example and set Default value to "get values from a query" and select the first dataset and value field (RunDate). Now the parameter will hold the RunDate field and you can use it elsewhere. Make this parameter hidden or internal and set the correct data type. e.g. Date/Time so you can format its value later.
Now create the second parameter which will hold the default text you want:
Parameters!MainText.Value = "Dear Mr.Doe, Here is your [Parameters!RunDate.Value] statement"
Not sure if this syntax works but you get the idea. You can also do formatting here e.g. only the month of a Datetime:
="Dear Mr.Doe, Here is your " & Format(Parameters!RunDate.Value, "MMMM") & " statement"
This approach uses only built-in methods and avoids the need for a parser so the user doesn't have to learn the syntax for it.
There is of course one drawback: the user has complete control over the parameter contents and can supply a value that doesn't match the report content - but that is also the case with the String Replace method.
And just for the sake of completeness there's also the simplistic option: append multiple parameters: create 2 parameters named MainTextBeforeRunDate and MainTextAfterRunDate.
The Textbox value expression becomes:
=Parameters!MainTextBeforeRunDate.Value & Fields!RunDate.Value & Parameters!MainTextAfterRunDate.Value.
This should explain itself. The simplest solution is often the best, but in this case I have my doubts. At least this makes sure your RunDate ends up in the final report text.