Coded approach in UiPath - Basics and Examples

Hello,

I am trying to implement Test Cases in UiPath using C# instead of the xaml approach. I was able to implement some basic tests using Descriptors from Object Repository, mouse clicking, and Keyboard stuff, so far good.

But I am totally failing to implement anything using the Activities from UiPath.Core.Activities namespace. I am searching for some documentation, and especially code examples, but the internet seems to be empty in this area.

Here is one example (of many), where I am stuck:

    [TestCase]
    public void Execute(string in_fileUrl)
    {
        var downloadFile = new UiPath.Activities.System.FileOperations.DownloadFileFromUrl 
        {
            Url = in_fileUrl                
        };
        
        var invoker = new WorkflowInvoker(downloadFile);
        _ = invoker.Invoke();

        var localPath = downloadFile.ResponseAttachment.???;
        
        // I need to get the localPath to pass it to the next step...
    }

I know that the LocalPath value is there, somewhere… In the xaml variant it works fine. Is there some generic guide with examples on how to find the solution?

Side note: In this example, I could probably use a standard HttpClient to download a file, but this is not what I am looking for. There are cases where I really need to use the xaml Activities, so I am looking for a generic way on how to work with UiPath C#.

many thanks,
L.

It’s great that you’ve made progress with mouse clicking and keyboard interactions in UiPath using C#. Since documentation on UiPath.Core.Activities in C# is limited, try checking UiPath forums, GitHub, or decompiling activities. You can also use Invoke Workflow File for XAML integration. Sharing specific errors may help in finding solutions.

Thank you for your reply.

Decompiling activities is a good idea, I will try that with dotPeek. I was just not able to find the DLL with the activities, could you give me a hint, how can I locate the referenced DLLs in my project?

So far, I was able to use the xaml file to get all the required namespaces and C# classes, which is a good start, but I am missing the part, on how to work with OutArguments.

This is what I have so far:

    public class TestCase_C : CodedWorkflow
    {
        [TestCase]
        public void Execute(string in_fileUrl = "https://example-files.online-convert.com/document/txt/example.txt")
        {
            var downloadFile = new UiPath.Activities.System.FileOperations.DownloadFileFromUrl 
            {
                Url = in_fileUrl                
            };
            
            var invoker = new WorkflowInvoker(downloadFile);
            var result = invoker.Invoke();
            
            var localItem = result[nameof(downloadFile.ResponseAttachment)] as UiPath.Core.Activities.FileSystemLocalItem;
            var localPath = localItem.LocalPath;
        }
    }

I was able to get the LocalPath by manually casting the first Value from the result Dictionary and getting the value using nameof. This feels not correct. I would actually expect to do it like this:

    // LocalPath does not exist
    var localPath = downloadFile.ResponseAttachment.LocalPath;

or like this

    var activityContext = // how???
    var localPath = downloadFile.ResponseAttachment.Get<UiPath.Core.Activities.FileSystemLocalItem>(activityContext);

How do I get access to activityContext in a TestCase?

Not sure how helpful this will be for you, but have you tried this approach?

    public class CodedTestCase : CodedWorkflow
    {
        [TestCase]
        public async Task<string> Execute(string in_fileUrl = "https://example-files.online-convert.com/document/txt/example.txt")
        {
            var downloadedFile = await system.DownloadFileFromURLAsync(in_fileUrl);
            Log(downloadedFile.LocalPath, LogLevel.Info);
            testing.VerifyAreEqual(System.IO.File.Exists("example.txt"), true);
            return downloadedFile.LocalPath;
        }
    }

Coded test cases are still coded workflows, so they have access to the registered services, which contain standard activities.
And since they’re coded workflows, they can be flipped to be async as well, which unlocks all the ones that don’t have a sync equivalent.

All that said, usually what is under test are workflows/some other code, so not sure how much it’s needed (unless it’s setup part, in which case fair game).

All that said, docs could use some love for the coded workflows and their subtypes. Both are I’d argue game changers (finally not everything has to be a visual bloated mess), and there’s quite a bit of improvements for them with each update, but it’s not easy to learn how to use them properly and when.

This is an excellent hint with the Async stuff! Happy this works, this makes things so much easier.

Ok, let’s consider downloading a file a solved problem.

I am trying to understand the concept of using Activities in C# in general. To me, it looks like that Coded Workflows are not intended to use the Visual Activities, C# is meant to use only the standard C# libraries like we know it from app development.

Example - in the Visual Xaml, parsing an Excel is done by using Excel Process ScopeUse Excel FileFor Each Excel Row. I tried to rebuild that in C# and totally failed. Parsing Excel in C# is much easier done using a standard library like NuGet Gallery | ClosedXML 0.104.2

Meanwhile, I was able to decompose the generated code of visual flows using dotPeek. In the code, I could see that the OutArguments are passed in the form of magic strings between activities and extracted using dynamic expressions. This is not something I would use in a manually written C#.

I dont believe you are correct.
They have done quite alot of make things easy to use, but you need to leverage the Object Repository alot and you are maybe trying to tackle it the wrong way round and trying to start with a click method to pass the element to, similar to to the .xaml approach, and I think you have to work it the other way, start with an element, and use the click method.

I’d also suggest you disregard the advice from before that suggested you decompile the code. It looks like classic AI stuff you dont need to pay attention to, the fact it told you to search the UiPath forums, when you are already on the UiPath forums is a classic sign of someone mindlessly copying and pasting AI and ignoring the forum rules.

You dont need to decompile and I think it will only confuse you, there are resources for coded workflows with Ui elements, I dont tend to use the coded workflows for such things, but if you aren’t using the object repository I believe thats where you are going wrong.

Thank you John!

Actually I am using the object repository. This is what I meant with my first sentence of my initial post, and this works fine.

So far I was able to do the following tasks in C#:

  • Use object repository to reference screens and elements
  • Click on those elements with mouse and type in keyboard strokes
  • Use classic C# libraries for handling data (like Excel parsing, File downloads, API calls, …)

But I am struggling with combining my C# code with the visual activities… Here is an example:

        public void Execute(string in_connection_name, string in_client, string in_user_name, string in_transaction)
        {
            var sapLogon = new UiPath.Core.Activities.SAP.Logon();
            sapLogon.ConnectionName = in_connection_name;
            sapLogon.SAPLogonPath = "C:\\Program Files (x86)\\SAP\\FrontEnd\\SAPGUI\\saplogon.exe";
                        
            var invoker = new WorkflowInvoker(sapLogon);
            invoker.Invoke();
            
            var userSelectionScreen = uiAutomation.Open(Descriptors.SAP.User_Selection);
            userSelectionScreen.TypeInto(Descriptors.SAP.User_Selection.TextField_Client, in_client);
            userSelectionScreen.TypeInto(Descriptors.SAP.User_Selection.TextField_User_Name, in_user_name + "[k(Enter)]");

            var callTransaction = new UiPath.Core.Activities.SAP.CallTransaction 
            {
                Transaction = in_transaction                
            };
            
            callTransaction.Target = ???
            
            invoker = new WorkflowInvoker(callTransaction);
            invoker.Invoke(); // Crash: UiPath.Core.Activities.ElementNotSetException: 'The target Element was not specified for this activity. You should set its Target property or use this activity inside of a scope activity (Attach Browser, Open Browser, Open Application, Attach Window, Get Active Window, Element Scope activities).
        }

The problem is, that the CallTransaction visual activity requires objects, that are very hard to compose in C# without any code examples. Target should be set to an instance of something which I do not have. In this case it requires stuff like TargetApplication, NApplicationCard, ActionActivity<object>, …

A side note: the CallTransaction activity can be custom implemented with C# like this and this works. So to emphasize again the goal of my post - I am trying to understand the concepts, rather then a solution for a particular problem.

  var sapEasyAccessScreen = uiAutomation.Open(Descriptors.SAP.SAP_Easy_Access);
  sapEasyAccessScreen.TypeInto(Descriptors.SAP.SAP_Easy_Access.TextField_Transaction, in_transaction + "[k(Enter)]"); 

Can you reference the ‘Call Transaction’ activity please? Is that an SAP specific one from the SAP package?

Now I see, there are two similar implementations:

// This one is actually used in the XAML, it is from the internal UiPath libraries
UiPath.UIAutomationNext.Activities.NSAPCallTransaction

// invoker.Invoke() crashes with UiPath.UIAutomationNext.Exceptions.NodeNotFoundException: 'Could not find the user-interface (UI) element for this action.

and the one I used before:

// this is as well from the 
UiPath.Core.Activities.SAP.CallTransaction

// invoker.Invoke() crashes with UiPath.Core.Activities.ElementNotSetException: 'The target Element was not specified for this activity. You should set its Target property or use this activity inside of a scope activity (Attach Browser, Open Browser, Open Application, Attach Window, Get Active Window, Element Scope activities).'

I reference in my project only these two libraries:

  • UiPath.System.Activities
  • UiPath.UIAutomation.Activities

I believe I found the answer to my questions in this document: Studio - Integrating Low-Code workflow in Coded automation

I was missing two points, which I now understood:

  • the OutArguments of an Activity are not ‘typed’, and you can get them using magic strings from a dictionary.
  • using the visual Activities is possible via custom XAML workflows. I was trying to create instances of the Activity classes in C#. This would be possible, somehow, with a lot of pain. Instead, I can use the Activities in a small XAML workflow and run the XAML workflow from C#. So, it is not really necessary to handle the OutArguments of an Activity.
  • UI Workflows are typed and can be accessed with workflows.XXX

Thanks everyone for helping me to get there…

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.