Get variable name and comment from recording in UserCode?

Ask general questions here.
mrt
Posts: 88
Joined: Mon Mar 16, 2020 11:31 am

Get variable name and comment from recording in UserCode?

Post by mrt » Mon Mar 29, 2021 11:18 am

Dear all,

I have the situation that for certain input elements the value in data source is an empty string '',
but the value of the read-only input field is reported as null, so validation fails.

For the lack of better ideas I am now about to implement my own Validation function in UserCode, which can check ifNullOrEmpty and provide results accordingly.

I would want to keep this validation function as close as possible to the already implemented one,
preferably by looking at the report only, a user should not be able to distinguish between the predefined Ranorex-Validation and my own implementation.

What I am missing now is the comment for the recording action, and the variable name from the passed variable.

How can I get these two into the UserCode?

thank you!

doke
Posts: 15
Joined: Fri Mar 29, 2019 2:33 pm

Re: Get variable name and comment from recording in UserCode?

Post by doke » Fri Apr 02, 2021 4:22 pm

Hi mrt,
when you open the .cs file of your recording,
and copy a report.log() methode from a validate action from cs.file to your usercode.cs the output would be similar

mrt
Posts: 88
Joined: Mon Mar 16, 2020 11:31 am

Re: Get variable name and comment from recording in UserCode?

Post by mrt » Thu Apr 08, 2021 8:26 am

Hi,
yes, but in .cs file there is no dynamic reference, it has been already converted to a string, so it is a "hardcoded" value.

User avatar
odklizec
Ranorex Guru
Ranorex Guru
Posts: 6553
Joined: Mon Aug 13, 2012 9:54 am
Location: Zilina, Slovakia

Re: Get variable name and comment from recording in UserCode?

Post by odklizec » Thu Apr 08, 2021 8:47 am

Hi,

I'm not sure if there is a public API method to get these two pieces from recording? Anyway, have you considered evaluating value from data source, before passing it to validation action/method and simply replace 'null' with ""? So then you don't have to implement your own method?
Pavel Kudrys
Ranorex explorer at Descartes Systems

Please add these details to your questions:
  • Ranorex Snapshot. Learn how to create one >here<
  • Ranorex xPath of problematic element(s)
  • Ranorex version
  • OS version
  • HW configuration

mrt
Posts: 88
Joined: Mon Mar 16, 2020 11:31 am

Re: Get variable name and comment from recording in UserCode?

Post by mrt » Thu Apr 08, 2021 8:52 am

Hmm, no I haven't yet.
But my issue is the other way round.
In the data source there is "" already, but the UI element reports "null".

User avatar
odklizec
Ranorex Guru
Ranorex Guru
Posts: 6553
Joined: Mon Aug 13, 2012 9:54 am
Location: Zilina, Slovakia

Re: Get variable name and comment from recording in UserCode?

Post by odklizec » Thu Apr 08, 2021 9:00 am

I see. So then I would do something like this.

Code: Select all

elementContent = repoElement.Element.GetAttributeValueText("Text") ;
if (elementContent == null)
{
    elementContent = "";
}
And then I would do the validation against the value from ref. data source.
Pavel Kudrys
Ranorex explorer at Descartes Systems

Please add these details to your questions:
  • Ranorex Snapshot. Learn how to create one >here<
  • Ranorex xPath of problematic element(s)
  • Ranorex version
  • OS version
  • HW configuration

mrt
Posts: 88
Joined: Mon Mar 16, 2020 11:31 am

Re: Get variable name and comment from recording in UserCode?

Post by mrt » Thu Apr 08, 2021 10:43 am

Yes, that would work,
but that would mean I need to instantiate every element with CreateAdapter(), which is slow, add two recording actions for a single validation - first check the "elementContent" and return the variable value, and second to validate against this variable,
which I would like to avoid.

I have hundreds of validation actions and this would decrease readablity and maintainabilty of recordings pretty much.

that's why I would like to have it in one action, but then I lose the comments and the variable names ... how you do it, it's wrong. :wink:

Jacob
Certified Professional
Certified Professional
Posts: 21
Joined: Mon Mar 22, 2021 10:01 pm

Re: Get variable name and comment from recording in UserCode?

Post by Jacob » Thu Apr 08, 2021 10:35 pm

Hi mrt,

My name is Jacob and I'm one of the engineers here at Ranorex. If I understand your question correctly, you'd like to be able to add a comment and grab a name in a User Code action. If this is the case, I'd like to propose a solution that should work. First, let's address the comment in code.

How to Add Comments to a Report Via User Code
Technically, there is no method to add a comment to a report. Instead, comments added to Ranorex Reports (via the comment section for actions in a recording) are shown on the first line. To understand this, let's look at some code generated by Ranorex on the back end when a comment is added to an action in a recording. The code-behind for a mouse-click action before the comment is added:

Code: Select all

Report.Log(ReportLevel.Info, "Mouse", "Mouse Left Click item 'CommandPrompt.TextArea' at Center.", repo.CommandPrompt.TextAreaInfo, new RecordItemIndex(0));
When adding an action in a recording, the first line in the code-behind is always Report.Log. The method here requires a ReportLevel (Info is used), a message, a repo item, and an entry in the RecordItemIndex. This is all populated by default by Ranorex Studio. Now, if we were to take that same action item and write a comment in the Comment field, we would be presented with this in the code-behind:

Code: Select all

Report.Log(ReportLevel.Info, "Mouse", "This is the comment added to the action item.\r\nMouse Left Click item 'CommandPrompt.TextArea' at Center.", repo.CommandPrompt.TextAreaInfo, new RecordItemIndex(0));
You'll notice that both lines of code are the same, except the "message" field now contains the text "This is the comment added to the action item.\r\n" as the first part of the "message" parameter. Ranorex simply adds the comment to the "message" parameter and separates it with the carriage return and new line (\r\n) codes.

So the short answer to the question "How do I add comments in the code-behind?" is to add it to the "message" field followed by a carriage return and new line.
The good news is that we don't have to use all that code that Ranorex populates since this is a code module. Instead, we can simply use the following code:

Code: Select all

Report.Log(ReportLevel.Info, "This is the comment added to the action item.\r\nMouse Left Click item 'CommandPrompt.TextArea' at Center.");
At the end of the day, this will perform the same as what Ranorex scaffolds when using the recorder.

How To Access Variable In User Code
For some background, quite a bit of what will be covered below is also covered in the User Guide and in this Webinar. There are two main variable types available in Ranorex outside of User Code; local variables (which are only available within the Test Suite or Recording that they are used) and global variables (which are available to all user code methods and modules). These operate in the same way, but are differentiated by scope. Outside of local and global variables, we also have Repository Variables (which won't be discussed here) and Module Variables. Worth noting are the differences between User Code Methods and User Code Modules. User Code Methods are functions that are called from within a recording, while User Code Modules are created instead of a recording.

Local & Global Variables - User Code Methods
Local variables can be created in the Ranorex Studio UI using the Variables button in the top, right-hand corner or when using the Get or User Code Module action items in a recording. You can then pass these variables to your user code method using arguments and binding the variable to an argument that is then passed to your user code method. Once in the code, you can access the variable by using the name of the argument specified when creating the user code method.

Module Variables - User Code Modules
Code Module Variables are only accessible within a Code Module, but can be linked to a data source for data driven applications. In these instances, you will only be able to access this information once the variable is bound to the data source. For more information on this, please see this User Guide entry on creating a Module Variable.

If I'm off the mark the specifics of your questions, please let me know and I would be happy to speak more directly to your situation.

--Jacob
Image

mrt
Posts: 88
Joined: Mon Mar 16, 2020 11:31 am

Re: Get variable name and comment from recording in UserCode?

Post by mrt » Fri Apr 09, 2021 7:50 am

Hi Jacob,

first, thank you for you detailed answer.

Briefly recap of what I want to do:
I want to use validation of an read-only input webelement against a data source.
If the data source contains a value, this should be validated. -> This works out of the box
If the data source contains no value, the input element does not report an empty string '' but it reports 'null', therefore the built-in validation fails.

What I am searching for, is to use as much as possible from the built-in functionality,
I have no ambitions to reverse engineer Ranorex on my own. ;)
Because I have hundreds of validation actions, I want to find a solution where I have only one call per validation which is self-explanatory on the UI also to other users which work on the same project and are used to Ranorex standard functionality.

Ok, to put the comment also into the message parameter would print it in the report, but it is hardly readable inside the parameter columns.
To me, the purpose of a comment is to see on first glance, what the recording action is about.
If you have to search for the message column and when found expand the column to see what the line is about, it seems to me that this misses the point.
Putting a comment into the comment column as well as the message parameter would lead to double entries which will go for sure out of sync over time.
So my idea was, to just grab the value from the comment (e.g. by some metadata variable) rather than duplicating it, without the need to maintain one comment in two places, and to keep the Studio UI structure easy to follow (comment is always the last column).

According to variables this is all clear to me, but what I meant was to get the variable name inside the report.
When I run a builtin validation the reports looks like this:

Code: Select all

00:00.001 Info Validation 
Validate myValue
Validating AttributeEqual (InnerText=$myValue) on item 'repository.folder.folder.item'.  

00:00.601 Success Validation 
Attribute 'InnerText' of element for item 'repository.folder.folder.item' does matchthe specified value.  
So the variable name $myValue is inside the report, which let's me check on the very first glance if the correct variable is picked up e.g. for debugging if there is some data binding issue or else.
I like this functionality and also want to keep it.

But if I understood you right, both is not possible at the current Ranorex version, so I am a bit out of luck here?

thank you, BR mrt

Jacob
Certified Professional
Certified Professional
Posts: 21
Joined: Mon Mar 22, 2021 10:01 pm

Re: Get variable name and comment from recording in UserCode?

Post by Jacob » Fri Apr 09, 2021 9:04 pm

Hi mrt,

Thank you for the additional information1 I think we may be able to handle both of these within Ranorex, but I'll explain my initial thoughts here in a bit more detail.
mrt wrote:
Fri Apr 09, 2021 7:50 am
According to variables this is all clear to me, but what I meant was to get the variable name inside the report.
When I run a builtin validation the reports looks like this:

Code: Select all

00:00.001 Info Validation 
Validate myValue
Validating AttributeEqual (InnerText=$myValue) on item 'repository.folder.folder.item'. 

00:00.601 Success Validation 
Attribute 'InnerText' of element for item 'repository.folder.folder.item' does matchthe specified value. 
So the variable name $myValue is inside the report, which let's me check on the very first glance if the correct variable is picked up e.g. for debugging if there is some data binding issue or else.
I like this functionality and also want to keep it.
Let me start with getting the variable name. This is something that's possible in C#, but your implementation may vary slightly. Below is a small code example showing how to pull the variable name from a variable, and pass it to the Report Logger:

Code: Select all

public void reportTest(string exampleVariable)
        {
        	Report.Log(ReportLevel.Info, "Variable name: " + nameof(exampleVariable));
        }
I have a User Code Method (from within a recording) called reportTest that accepts a single string variable called "exampleVariable" (very creative, I know!) Since the variable called exampleVariable is available to my reportTest function, I can use the "nameof" Operator to get the name of the variable as a string. So when I create my Report.Log call to log data to the report, I just concatenated "Variable name: " in a very basic way with the result of the "nameof" Operator to produce this entry in the Ranorex Log:

Code: Select all

Time | Level | Category | Message
00:02.305 Info User Variable Name: variable  
That should allow you to report back the variable name to the report for review after the fact. I hope that helps!
mrt wrote:
Fri Apr 09, 2021 7:50 am
Briefly recap of what I want to do:
I want to use validation of an read-only input webelement against a data source.
If the data source contains a value, this should be validated. -> This works out of the box
If the data source contains no value, the input element does not report an empty string '' but it reports 'null', therefore the built-in validation fails.
For the validation action, this may be a good place for a User Code Module. Once setup, you can call a User Code Module's functions from anywhere in your project by adding the action to a recording. This way, whenever you need to validate a field that may have a null value, you can accommodate that situation. Something like this should suffice, although please add proper checks and coding practices. This is just meant as an example:

Code: Select all

public void reportTest(string exampleVariable)
        {
        	if (repo.RepoFolder.RepoItem.TextValue is null && exampleVariable == "") {
        		Report.Log(ReportLevel.Success, "Variable $" + nameof(exampleVariable) + " is empty and matches the null value in the UI");
        	} else {
    			Validate.AttributeRegex(repo.RepoFolder.RepoItemInfo, "Text", new Regex(exampleVariable));
        	}
        	
        }
In the event that the value in the UI is NULL and the variable was passed an empty string, we can use a basic IF statement to create the logic that will then log a Success message to the Report. Otherwise, we need to go through a full validation. The example above uses a regular expression for the evaluation method, but you should use AttributeEqual if you want an exact match. You'll also see that I'm writing to the Report with the nameof Operator in the IF block. If you also need this in your ELSE block, you can add it there as well. With this function in a User Code Module, it is available for the entire project, so adding it to a recording will be exactly the same as adding any other action. Just add a new action, select User Code from the context menu, and then choose "Select from library." You'll be presented with a pop-up window and you can pick your function in the User Code Module that you want to use. Once selected, pass any variable (for Data Driven tests, you can pass the variable that is bound to the data source you selected for the Test Case). The upside with this approach is that it is usable across all Test Suites, Test Cases, and Recordings, it just needs to be added as the validation step instead of the traditional validation step.
mrt wrote:
Fri Apr 09, 2021 7:50 am
Ok, to put the comment also into the message parameter would print it in the report, but it is hardly readable inside the parameter columns.
To me, the purpose of a comment is to see on first glance, what the recording action is about.
If you have to search for the message column and when found expand the column to see what the line is about, it seems to me that this misses the point.
Putting a comment into the comment column as well as the message parameter would lead to double entries which will go for sure out of sync over time.
So my idea was, to just grab the value from the comment (e.g. by some metadata variable) rather than duplicating it, without the need to maintain one comment in two places, and to keep the Studio UI structure easy to follow (comment is always the last column).
I think I see where you're going with this one. Unfortunately I don't have a clever solution, but I will continue to think on it. In the meantime, I'd be happy to have your feedback on the options above to see if these meet your needs.

--Jacob
Image

mrt
Posts: 88
Joined: Mon Mar 16, 2020 11:31 am

Re: Get variable name and comment from recording in UserCode?

Post by mrt » Mon Apr 12, 2021 8:08 am

Hey Jacob,

thanks for the ideas.
... I can use the "nameof" Operator to get the name of the variable as a string...
Unfortunately, the 'nameof' function does not seem to help, because it resolves to the name of the current variable inside the method, and not to the name of the passed variable from recording action.
So, nameof(variable) will always be resolved as 'exampleVariable' no matter what was the original variable name passed from recording.

Jacob
Certified Professional
Certified Professional
Posts: 21
Joined: Mon Mar 22, 2021 10:01 pm

Re: Get variable name and comment from recording in UserCode?

Post by Jacob » Wed Apr 14, 2021 9:54 pm

Hi mrt,

Sorry for the delay in this response, things have been quite busy this week.
You should be able to use the "nameof" on the original variable if you'd like, depending on the scope. For example, if I have a User Code Method, I can access a variable from the Recording, Test Case, or Test Suite and print it to the Ranorex Log. Let's say I have a Variable set in the "Variables" button in a recording, I can access that variable directly via a User Code Method with the following code:

Code: Select all

Report.Log(ReportLevel.Info, nameof(stringVariable) + " " + stringVariable);
This will work without passing a single argument to the User Code Method.

Another possibility (and this is just a shot in the dark as I'm not fully aware of your particular situation) but is it possible that the variables you bind to your functions can share similar names? This would still make "nameof" an effective tool, albeit indirectly. For example, you could pass a variable from a data-driven application as $firstNameDataSource to a Code Module as $firstNameCodeModule (or a similar arrangement).
Image

mrt
Posts: 88
Joined: Mon Mar 16, 2020 11:31 am

Re: Get variable name and comment from recording in UserCode?

Post by mrt » Thu Apr 15, 2021 6:01 am

Hey Jacob,

thank you for pointing out that I can use variables directly from the recordings, I was not aware of that.
Although I think it can decrease collaboration because then it is not obvious anymore which variable is used in code, and which isn't.

But anyway, I am afraid that it does not help to pick the variable directly from recording.

I use the UserCode method, because I can call it multiple times with different variables out of the same recording and also across multiple recordings, so this is no one-time operation and needs to be fully dynamic.
This project currently has about ~30 data sources and ~130 recordings with about 10-30 variables per recording, and most of them have different variable names, that's why I want the variable names to be printed in the report.