Activity Request: Refresh UI Cache

Good day,

Having a “Refresh UI Cache” activity would be a great addition for when you need to have better control of UI interactions.

Background/context:
In past versions of UiPath, it was possible to use UI activities without scopes (as in - you could have a “standalone” Click and similar activities). This does not seem to be the case anymore (or I don’t know how to configure it to work). This approach was useful for tricky UI’s, where events are not always properly propagated, resulting in Element no longer valid and similar errors. This worked, because there was no caching issues (since no scopes).
Right now, the recommended way according to KB’s is to RetryScope things. That’s a pretty subpar solution (takes away speed), and from what I was able to gather the underlying reason behind it is that when an UI activity fails, it invalidates the cache.
Letting us trigger UI cache refresh in sections of the code we know cause issues, without resulting to need to force it to error first, could be a more refined solution.

Sidenote:
I understand that UiPath is trying to “streamline” things, and “compress” the number of activities needed for things, but in some cases this is getting a bit silly (a Click has enough properties that it has a scrollbar, while also inheriting some from appscope anyway…).
But, there’s a ton of different frameworks for frontend, with more and more appearing all the time, and implemented in various levels of correctness. It’s a neverending race to properly “automagically” handle all of them, and there will always be a newer way, that is not fully compatible.

“Back in my day” (old man yells at clouds, I know) UiPath was a tool that developers could use to solve problems. We had all the building blocks available, and fine-grained control on what happens, when, and how.
Now it’s getting more and more “automagic”, which is totally fine for the straightforward cases (even though I’d argue that the “magic spells” got more complex to use), but the moment we step into something that breaks the magic, I’d say it’s harder than ever to make things work, because of all the layers of indirection and abstraction. It does feel at times that we need to “fight with the software” to do just the thing we need it to do, step by step, and it’s fighting back trying to be “smart and convenient” (being annoying at best, and just straight up failing at worst).
I’m not sure when did UiPath stop trusting devs using their software to know what we’re doing, but it certainly does feel that way sometimes. Keep the streamlined “automagic stuff” for when it works, but do expose the underlying functionality we know is there for when the magic breaks. We can handle it.

Thank you very much for your detailed feedback, we are going to investigate the Refresh UI Cache, if you could give a specific example of an application where you needed this or more details about your use case that would be great.

I really appreciate it your detailed feedback related to UIAutomation, I’ve heard similar concerns multiple times, and we’re actively exploring ways to improve the experience.

I’d love to get your insights on a few specific points:

  1. Do you feel that the Classic UIA activities were more effective in helping you achieve your end goals?
  2. Do you find the Modern activities more challenging to configure? If so, could you provide concrete examples of what worked well and what didn’t?
  3. Are you currently using UIA for production-ready automation? If yes, have you noticed any changes or improvements in UIA reliability in prod on long term since transitioning to Modern UIA?
  4. When you say ““Back in my day” (old man yells at clouds, I know) UiPath was a tool that developers could use to solve problems. We had all the building blocks available, and fine-grained control on what happens, when, and how.” are you referring to UIA only or in general? Can you give examples, please?

Most of the updates in Modern UIA were aimed at enhancing long-term reliability in unattended automation. Another key goal was to improve the user experience for both junior and advanced users. However, professional users have expressed concerns that some activities are now harder to configure, certain settings are unclear, and features like fuzzy selectors are not well understood.

We are continuously working on improvements, but I’d really like to understand your main pain points, as you seem to be an experienced developer

In a way, yes. They had a much lower cognitive load, and were more fine grained in scope. This translated to being able to know at a glance what is happening in a workflow (more on that later). They were also not trying to be “smart” about what they do - a Click is a click, nothing more nothing less. When you see one in the workflow, you know what it does immediately. The new Click could also be just a click, or it could be a click text (native or CV), or a click image, and it could do a retriable verification (which could wait for page load, and also target by selector, image text and so on).
This sounds good on paper, until you’re doing a code review, and need to go through all properties of all UIA activities - not to check if they’re configured correctly, but to even know what is actually happening.

It’s not that they’re harder to configure per se, it’s knowing what are the possible outcomes.
Let’s take the Click as an example. This is the Classic one:


The possible outcomes list is very short, and logical:

  • It clicked what it’s supposed to and moved on
  • SelectorNotFound
  • Timeout (default 30s or whatever you set explicitly)
  • ElementNoLongerValid / similar “sorry, couldn’t click this” exception

This is the Modern Click, with some options expanded:


What are the possible outcomes?

  • It clicked what it’s supposed to (by some method), and verified execution by some means (or not)

  • It clicked, but verification timed out due to wait for ready not happening

  • It clicked, but verification selector (or text, or image, or…) was not found

  • It clicked, but verification action did not happen (appear, dissappear etc.) or was not recognized

  • Timeout → what timed out - main target or verification? How does retrying impact timeout? How long this is going to run:

  • Selector not found → which one? Main target or verification?

  • XX not found → will it throw a different exception if it uses image, or text?

  • ElementNoLongerValid → again, which one? Main or verification?

It’s not that you can’t learn this, but the cyclomatic complexity of just one activity gets to really ridiculous levels.
You could argue that it’s just “it clicked or it didn’t”, but that’s not really true - not when you’re debugging something, and trying to figure out what actually went wrong and how it could be approached differently.
With Classic Click, if you need to validate something after, you explicitly do so - with ElementExists etc. You need a retry, do a RetryScope. Yes, the workflow becomes “longer”, but it also becomes explicit about what is actually there. And since it’s explicit activities, it’s easy to tweak and reaarrange.
Of course, you can just not use all the fancy intermittent things. But they’re there, so when it’s not you who wrote the code (or it’s you from X months ago), you have to check. Every time. And it’s only visible if that specific activity is highlighted, so one activity at a time, and hopefully you can remember all the implicit flows of them.

You can have a workflow with 10 clicks that on the surface look basically the same, that go through 7 different screens, use 3 different click strategies, and validate 10 different post-conditions, with retries or not. On the designer, it’s a very efficient use of space. On the mental load of “what this workflow does”, it’s very taxing. Most code is read orders of magnitude more than being written or rewritten.

This also has a side effect of what would previously be multiple workflows now becoming one. A workflow with 3 activities (that is an equivalent of 15, really) looks “empty” and is tempting to be expanded upon. This in turn leads to workflows doing more than they should. I’m not an SRP purist, but it’s very easy to overload workflow functionalities without realizing it when using Modern UIA, and that leads to worse tests and maintainability.

So to summarize - while the modern activities allow for doing more with less activities, it becomes more abstract of what is happening, and therefore harder to read, debug, and modify.

Now when it comes to actually using things, here’s the flow/decisions for different Clicks in just the Notepad:
Classic:
Add a Click activity
Click Indicate on screen
Click on the Notepad text area
Review the selector (wildcard the title etc.)
Change the Click method, if needed
Done

Modern:
Add a Click activity, which adds the Use App scope
Indicate the App on screen
Review the FilePath
Review the Selector
Indicate the Field on screen from the Click
Click on the Notepad text area
Review the Options
Review the Window selector
Review the Anchor(s)
Review the Target Strict Selector
Review the Target Fuzzy Selector
Remember what Accuracy refers to
Decide on if Text matters or not (if it could be read)
Decide on CV and Image options
Change the Click method, if needed
(not going to go into retries and verification targets now)

This might seem like a “well, isn’t a good thing that it makes you think about all this?” - which is a yes, but actually not really. Previous activities were split - if I want to ClickText, I’d use ClickText. If I’d want ClickImage… and so on. Everything was front and center, right there to see.

Yes and no, respectively. I can’t recall situations where Modern worked in situations where Classic would not, but the opposite was true (as in - when changing from Classic to Modern, using exact same selector setups etc. new issues appeared).

UIA, and in general.
With Modern Activities, and in newer activities in general, there’s a lot more going on in a single activity, and there’s a lot more forced interdependencies between activities (i.e. everything is in scopes etc.). Not all of it is bad, but there’s definitely more cognitive load to keep in your head at all times.
As with the Click example, it’s overloaded to the brim in what it does, and it’s not straightforward to say what will actually happen, in what exact order, and what could fail and how.
In a more general sense, the overall design decisions when it comes to activities is to overload them and/or make them “smart”.

I like some of the “smartness”, to an extent - ForEach auto-detecting type is a nice addition. Not so much when it does it again, because you added a LINQ and it didn’t know about an implicit conversion, and suddenly everything inside of it has validation errors. Or when it autorenames your variables until you set an explicit name. (Sidenote - those autonames usually are awful, but they also promote naming variables from the type that they are, not what they represent). Or when you’re working with custom types and it gets confused all the time (base classes and interfaces are a thing it can’t set to automatically).

What I’m trying to say is that I can completely relate to why this happens:

What is the Output UI Element of a Click activity? Docs don’t say, and the concept of a Click having an element output puts people into a pause, if they think about it (and professional users want to understand how things work, not only how to use them in base cases). Is it the element it clicked? Is it the element it used for verification? Effectively you need to test to figure it out. And since docs don’t say, with next version it could be slightly different, and now your workflow doesn’t work.
Just looking at the docs page for the NClick compared to classic Click is a night and day difference. The thing is so bloated even the docs become unreadable (they’re not written badly per se, there’s just too much going on). Also notice how many things in the NClick are interdependent.
It’s not even the biggest offender (O365 scopes are even weirder), but it’s the one that is definitely in front when it comes to seeing how far things have changed.

I understand that, and “nudging” devs to think about all the possible options all the time is certainly a way to make them think about reliability, at least until the point where they start auto-ignoring all the additional options because of cognitive overload.
On the other hand, the tools to do almost everything the Modern activities do were always there, for most of them even as far back as v8 (2015). So to be honest, I don’t think the activities were the issue - building reliable unattended automations for non-trivial processes is not the easiest thing under the sun, and the more widespread the technology becomes, the lower the entry bar gets, the lower the average quality of the implementation. Building anything that needs to run on its own reliably is not easy, even if you control all the components, and RPA’s explicit reason for existence is to operate on 3rd party systems which are by definition outside of control.

From UiPath’s stability perspective, we stopped having reliability issues around… 2019 I think? Maybe 2020, when there were no more memory and handle leaks. 2021 versions were just icing on the cake. After that, virtually all issues were root caused to either an external system update that broke something, we goofed up and didn’t think of something, or a UiPath update broke something.
That last one is unfortunately on the rise, and we’re more and more hesitant to update any dependency in a project. This was not the case before.

I’ve already addressed advanced users (or at least my take on this), but for juniors I’m not sure if it’s better either. The initial complexity hill to do even a simple click is waaay higher, the platform is way more complex to use in totality, and the amount of things you need to take into account (and know well) to do almost anything is higher than it ever was.

So, in my humble opinion, if you want to make DX better, more focus should be put on:

  • Stability of the core elements of the framework (I’m thinking of UiPath as a framework here) → basic activities should change as little as possible, and if they do, it should be with a very good reason. That includes all the basic UI interactions, but also things like logical constructs. I’m not sure why so many companies are almost allergic to something being “done”. I don’t mean things will never need to change (f.e. O365 authentication changes), but the number of “change for changes sake” is growing for reasons that are only valid for UiPath, and not the actual users. Unifying design experience between desktop Studio and Studio Web? It’s a different audience (as was stated by UiPath in some thread), but that was the stated reason to change TryCatch in desktop Studio, which resulted in bugs in something that absolutely cannot have any bugs ever.
  • Activity designs should encourage good development practices → this is a bit of a pet peeve of mine. When you’re changing the activities to “help users”, you need to think about what are you actually encouraging. Biggest offender here is the If activity - changing it to vertical is IMHO one of the worst changes that was ever done in UiPath history. I know why it happened, and it should’ve been a hard no. Excessive nesting should be hard to read, it discourages itself by design. It was explicitly made horizontal to “mimic” the no-more-than-80-chars principle from coding, and to allow for easy visual tracing of code execution. It surfaces the arrow code problem. Having it vertical alleviates all of it, which might seem good, but is actually antithetical to good design. All that was actually needed was an If without the else block (for guard clauses etc.)
  • Slow down the changes, drop CalVer and adapt a proper SemVer for activity packages → this is going to be controversial, but a lot of the issues with activity changes can be IMHO boiled down to expectations. When UiPath switched to CalVer, all expectations got thrown out the window when it comes to stability and compatibility, and now it’s users responsibility to validate all compatibilities every time. And if you find a bug? Well, it will be fixed in the next .x version, which may or may not also include other breaking changes to other activities in that package, so womp womp, retest everything. As a side effect, looking from the outside at how the activity package maintenance changed in UiPath, when CalVer entered the picture things started going downhill - suddenly, all core packages must be updated with major releases, even if there’s little reason for them to do so. So it fuels the “change for change’s sake” cycle (and is another reason why an innocent looking change can have long lasting, negative, unforeseen consequences).

Side tangent:
The learning curve before was similar to actually learning programming - get to know variables, arguments, separation concepts, and simple framework concepts (UIElement, selectors and so on). Build something that runs. Now add safe guards to make it reliable. Now add optimizations to make it more important.
Now it’s a bit of a “this is all you need to take into account” in-your-face, it’s easy to get overloaded, and I wouldn’t be surprised if people just phase out a lot of the information they should be absorbing, because it’s very hard to learn all the concepts at once, especially when half of them are partially abstracted away (but not really).
/endtangent

Now, for the actual use case :slight_smile:

This most often is needed with websites that are not implemented with best practices in mind, like internal sites/services in closed off environments (you know, those legacy dont-touch-or-it-will-brake systems that drive many companies to look into RPA instead of trying to change something built X years ago by someone who’s not there anymore).
A concrete example recently was an internal customer webapp used for database searches across different sources. It was built with no accessibility in mind, as a purely internal thing ages ago, and until recently didn’t even run on anything other than IE. Now it has been updated a bit to run on Edge, but that was minimum effort facelift, just to make it work for human users without needing them to use IE.

The whole process is to switch to different tabs within a single page, enter search criteria, press search and read the resulting table. The page is very fast, and the automation on it is running for… 6? 7? years now. Everything was working fine with Classic activities.
When we switched to Modern, a couple of things happened:

  • Execution times skyrocketed (~4x times or more, depending on activity)
  • We started getting ElementNoLongerValid errors all over the place

While the process has been stabilized (and performance improved to some extent), the root cause of the issues with Modern UIA was traced to caching and page state (WaitForReady). When the search tab was changed, and when the results were populated (and afterwards cleared), UIA’s were not picking up on changes, and started throwing errors. Modern UIA was also not able to pickup on when the page was loaded, so it was waiting more than it should for no reason.
Classic activities (explicitly unscoped for these reasons) were working fine, since we could circumvent caching completely.
Solution ended up being to force full page reloads, just to have UIA pick up on the page changing. There could be other approaches (like splitting the scopes etc., but that made the workflows completely unreadable since almost every UI interaction would need its own scope).

Therefore this request, to be able to trigger the cache refresh as an activity, or to effectively be able to “tell” the scopes “I know you might not have picked up on this, but UI have changed, so recache it please” without forcing an execution error to do so.
Aside of helping with our specific case, I think it could help with a lot of edge cases with caching (which by the popularity of topics about ElementNoLongerValid errors, is still a thing all these years later).

Small comment on this, just for context - me and my team are working on UiPath since 2015 (10th anniversary in May, actually), so some of the things above can be a bit biased to “how things were”. With that caveat out of the way, the feedback above, to the best of my ability, reflects the thoughts of other devs I know and/or work(ed) with that have similar level of experience, and are using more than just UiPath to solve problems.