Used "^%{L}" for performing cntrl+Alt+L in BluePrism but the required window is not opening up, the command is working fine in general when executed manually.
First of all, you need to make sure that you are following the appropriate steps to send keys to an application. The recommendation is to first activate the application (this ensures the keys are sent to the proper application), then use a wait stage (this ensures that BluePrism is sending the keys at the right time; i.e. when the application is ready to accept keys), then use the navigation stage on the root application where the send keys is located, something like this:
(If you are typing in a specific field in the window, then use an additional Focus navigation stage on the Field itself before sending keys).
Within the navigation stage, you have two possible options to send keys:
Global Send Keys
Global Send Key Events
Global Send Keys
You can find the official guide (section 10.2) on the BluePrism portal. It doesn't really detail the sending of combination keys for Global Send Keys, but you really have to do it like this:
^(%l)
Do note that if you send ^(%L), this is similar to sending Ctrl+Alt+Shift+L. The parens indicate that for the keying of %l, Shift is held down. The above is equivalent to ^(%(l)). Normal keys do not require braces either, and they cause issues if used in Global Send Key Events (i.e. {L} means Shift+L in Global Send Keys, but will give you an error in Global Send Key Events).
The relevant part of the guide:
So what you were doing with ^%{L} didn't really make sense to BluePrism. It was probably sending Ctrl+Alt, then separately Shift+L (I cannot really confirm this, but this is my guess following testing on BluePrism which definitely show it doesn't work, however).
Global Send Key Events
You can find the documentation in the same guide and section I linked earlier. This time, it does show exactly how to send combination keys, so for your case, the other option with Global Send Key Events will be:
<{CTRL}<{ALT}l>{ALT}>{CTRL}
I don't really like Global Send Key Events because it's longer to type and you have to be careful about more things, but essentially, it becomes easier if you type the opening and closing syntax before proceeding with the next key. For example to do the above, it's easier to first type <{CTRL}>{CTRL}, then insert the ALT part in the middle: <{CTRL}<{ALT}>{ALT}>{CTRL}, then insert the l (do note here that l and L are equivalent here, which is also weird considering that they are not in Global Send Keys).
I presume that it's a GLOBAL SEND KEY EVENT value that you're looking for.
This is shift+I action value:
"<{SHIFT}I>{SHIFT}"
I would try for ctrl+Alt+L maybe something like this:
"<{CTRL}{ALT}L>{CTRL}"
the "<" & ">" is Push down & Release
Global Send Keys is going to send the keys to whatever application has focus on screen, so I would recommend:
Set focus on the desired window by either using a Navigate stage to "Activate Application" or "Global Mouse Click".
Use Global Send Keys
Keep in mind that a Global Mouse Click could again result in something unexpected as its sending the event directly to the screen, and another application/window might be covering the area you've just clicked.
For more info on Global Send Keys and Global Send Keys Event I would read the BluePrism manual for this: Send Keys and Send Key Events
It might also be worthwhile studying some surface automation principles as it can help get you a better understanding of what these Global actions are doing: Introduction to Surface Automation
Activate the application using navigate stage.
Add a 1sec wait between activate and send keys.
Use global send keys event. <{ctrl}<{alt}L>{alt}>{ctrl}
Ensure you are using the root element in Application Modeller (the first at the top of the list) and not any of the child elements. Use a navigate stage with that element and either Global Send Key or Global Send Key Event action. The syntax "^%{L}" is otherwise correct, although you don't say what is it that you are trying to automate (Excel, Word, IE, Citrix...??).
Try to use Global SendKey instead of G.S.Events. I.e. SHIFT+HOME = "+({HOME})"
regular brackets needed for blue prism to understand where to release Shift ("+").
Related
I want to create a button factory that creates buttons by a specific configuration as parameters. The button have to emit a signal if there is pressed. I can't find any method to add that functionality programatically.
I know, that i can add buttons by the editor and add that function to it by a script. But with a factory, i don't need to add every button by my self.
Big thanks!
Buttons emit a signal when they are pressed, it is called "pressed". That is not a functionality you need to add.
Perhaps what you need is something else? The Godot editor is built on the same API as your game, so you can do from code virtually anything the editor can do… such as…
You can add a script from code
If you need to add a signal, the usual way is to attach a script that has the signal declared and the logic to emit it.
If you have such script created, you can load or preload it in your code, and then attach the script to the Object you want (with set_script). There is also a get_script method to retrieve it. And a "script_changed".
And yes, you can create scripts from code too. Create a GDScript object, set its source_code, and reload it. Then you can attach it to an Object just as if you had loaded it.
By the way, the script is a Resource which is why you can load it or preload it. See also ResourceLoader. It also means that you can save it with ResourceSaver. However, I remind that resource paths aren't always writable.
You can add signals from code
Yes, you can add dynamically signals from code. I mean custom signals that are not declared in a script, and that could be added at any moment. To do that you call add_user_signal on the Object. You can check with has_user_signal (use has_signal if you don't care if it was added with add_user_signal or not). And no, there is no remove method for these. So use these sparingly and with intent.
By the way, you can get an Array of all signals on an object with get_signal_list.
You can emit signals from code
You do that you can call emit_signal.
And you can call it on other objects too (I mean, you don't have to call emit_signal from an script attached to the Object that has the signal, it can be from a different one).
You can manage connections from code
I also remind you that you can connect a signal with the connect method. See also disconnect and is_connected.
Oh, and you can query the connections with get_incoming_connections and get_signal_connection_list (Here is an example, it also demonstrates get_signal_list). No, you don't need to worry about disconnecting the signals when freeing the object. Godot takes care of that.
And you can block signals too
You can have an object block its signals with set_block_signals, and check with is_blocking_signals. I - personally - haven't used this, never had the necessity. I just mentioning it for completeness sake.
I am trying to use the option condition to show that by pressing [edit, view & delete] UI Buttons, the admin can execute admin privileges. I am not sure if this is the correct way of implementing it. Currently, my thought process is that, if a button is pressed, the button being pressed becomes the opt fragment condition and then I show what happens if it's pressed within the optional fragment. I have nested an alt fragment within the opt fragment to handle errors that can occur. From what I have read and seen, I feel this is a suitable implementation, but any feedback to improve and make this diagram clearer is more than welcome. Thanks in advance
The question is, what do you mean with [click edit user]? As modeled it is a flag, that determins what option is happening if it is set. Now the first message in this fragment comes from the Admin. That means it is a flag in his or her head. Do you really want to model the brain here?
I rather think, what you want to model is, that there are two possible sequences, either the admin will send the edit user message or the delete user message. Depending on what he or she does, different things will happen next. This can be expressed by an alternative fragment without guards. Guards are optional and are only misleading when you are dealing with human actors, whose actions are often unpredictable.
Maybe you omitted a select option message (that's perfectly legal), whose result could be the flag. But then I don't understand, why the admin will send edit user, after she has already selected an option.
In your nested alternative fragment (shown overlapping in your diagram, but I assume that is just a rendering problem), you have the guard [user found]. This would probably be a local flag of the verify username operation. While it is very much possible, that such a flag exists, it is unnecessary to show it here. The two fragments are distinguishable by their respective first messages username valid and username invalid. So I recommend to omit the guard.
As a sidenote: The operator for the alternative fragment is abreviated alt
I am trying to enter a password into a Citrix window using global send key events and the username works fine, but I cannot send a password as is. My guess is that I would need to create individual key events for each special character, but that would reveal too much of the password in the design of the action.
Is there another approach?
I don't know how it is specifically with Citrix, but I do know RDP blocks certain SendKey events as a security precaution. In either case, you should be able to leverage AutoHotKey via command-line to get around it.
So you need first to create the object to accept the pass that will be inserted into the field. In the start of the object insert the pass as text, do all the required steps and in the process collect the dynamic pass and import it into the object (when you create the action by assigning the right business object, that you created already). Hope I made my self clear.
Then in the Global Send Keys Events action put the variable of the pass you want to type and that is it.
I am using cucumber in combination with selenium for testing the java web application. The following is the Scenario that we have
get generate PIN page
enter user name
enter password
click on submit button
Now it generates a PIN in the database depending on so many calculations. now i need that particular PIN, to give it as an input to a different scenario. how can i achieve this? Thanks in advance.
I would assume that you can access the PIN within the database after the above scenario. That being the case, I would add one more step to the scenario that acquires - and confirms - that the PIN was indeed generated. At that point, you can store the PIN in a local variable and then use it within the next scenario.
So your first scenario would look like this:
Get generate PIN page
Enter user name
Enter password
Click on submit button
Confirm PIN number in database
The last step would not be done within Selenium, but via an API call or some other means to acquire the PIN from the database. It would confirm the PIN (e.g.; regex=/^\d{4}$/) and then store it in a local variable, say something like #customer_pin (assuming you're using Ruby).
Your next scenario would start off something like this:
Get generate login page
Enter customer ID
Enter customer PIN
etc
When you hit the "Enter customer PIN" step, you pull it from the locally stored variable (#customer_pin).
My advice is that when executing this second scenario, you confirm that you have a legitimate PIN within your locally stored variable, in case someone should run this scenario out of sequence. You could do this by using a global variable and running a "Before" hook in your features/support/env.rb file like this:
Before do
$dunit ||= false
return if $dunit
$customer_pin = nil
$dunit = true
end
In this case, I use $customer_pin instead of #customer_pin in order to make the variable globally accessible. Then after running your first scenario, $customer_pin would be assigned to a legitimate value so that it can be used in any subsequent scenarios. Subsequent scenarios would use the regex expression to confirm it has a legitimate value, and raise/throw an exception if not.
I would divide your problem into two.
One that verifies the pin generation as this may be important for your stakeholders.
One that implement a backdoor to support other cases where a valid PIN is needed. Maybe an API that is able to generate or retrieve a valid pin number. Maybe create and store the PIN in the database without touching the system from the outside. I would use this way to retrieve a PIN whenever I need a valid PIN for other scenarios.
The technical solution on how to get a valid PIN isn't too important. What is important is to decouple the execution order of the scenarios. The execution order of the scenarios is undefined. Each scenario must be able to be executed in isolation and in random order.
Coupling scenarios is a well known anti pattern described here and here.
To Solve this kind of situation you have to use Cucumber Background feature, This is run before each step. and will generate a PIN based on given inputs and then generated PIN will be available across the scenarios.
Find feature file definition based on your requirements.
Background:
Given I Get generate PIN page
Then I Enter user name
And Enter password
And I Click on submit button
And I Confirm PIN number in database
#TC01_GetUserInformationByPinTest #NoBrowser
Scenario: Get User information by generated PIN from background.
Given I Get User Information by using generated PIN
And I verified that given username is same as response Data
I believe this will help you to solve your issue.
I've created a QTreeWidget that displays data that's pulled from 3rd party API calls.
I want the data to be fresh when the user either clicks on or uses the arrow keys to navigate to any QTreeWidgetItem. This means making an API call each time the user clicks or uses an arrow key. Importantly: If the user clicks on the same item a second time, I would like the item to display fresh data (in other words, make another API call and populate with new data, aka refresh)
So far, I've tried:
connecting both itemSelectionChanged and itemClicked to the same update function. This works, but it means that for every click on a new QTreeWidgetItem, I get two calls to the update function (one from itemClicked and the other from itemSelectionChanged), and therefore two API calls that do the exact same thing. Not ideal.
Only handling itemClicked, but then using an event filter to look for Key_Up or Key_Down and then manually emitting an itemClicked. The problem with this is that the key event is handled before the selection is changed, so when using the arrow keys, I'm always getting data for the last QTreeWidgetItem selected, not the current QTreeWidgetItem.
I thought about creating a very short timer or a flag and starting/setting at the start of the update function. If the timer is running or the flag is set, don't run the function (the idea being that the first slot would run, but the second would not because the flag is set/timer is running), but that seems both sloppy and prone to race conditions.
Unfortunately, using a QTreeView with a QAbstractItemModel is not an option.
With that, is there any way to handle both a repeated click on the same item and arrow keys to select new items without double-calling the same update function?
As #ekhumoro pointed out, this can be done by handling both itemClicked and itemSelectionChanged, but introducing some logic so that both functions don't run at the same time.
When a user clicks on the widget, an itemClicked signal is fired. When the user changes selection, the itemSelectionChanged signal is fired. In my case, then, I've created two slots (functions): update (a slot for itemSelectionChanged) and updateFromClick (a slot for itemClicked). updateFromClick checks to see if the selection has changed (this means you always have to store and keep track of the current selection). If, in updateFromClick, I see that the selection has changed, then I do nothing, as update will have been called from itemSelectionChanged. If, in updateFromClick, I see that the selection has not changed, I know that itemSelectionChanged has not been fired, so I call the update function explicitly from updateFromClick.
Again, this is just a long-winded version of #ekhumoro's comment that I'm putting here so the question doesn't go unanswered.