AutoIT send() commands not working properly - scripting

So I have a game client with 2 input fields: id pass and 1 button: login.
My login credentials are: $id=1234 and $pass=a_bCd.
I'm using AutoIT scripting to automate the login process (my script automatically inputs the id and pass in the login fields) and my AutoLogin() function looks like:
send($id + "{tab}")
Sleep(10)
send($pass + "{enter}")
Sometimes it works fine, but sometimes my script introduces 1234a- or 1234a_ in the ID field and the rest of the characters in the pass field. I tried many solutions like controlsend("Game","","","1234{tab}a_bCd{enter}"), or changing sleep() values, etc. but the input still goes wrong sometimes. Figured the send delay or sleep would have the problem, still don't know what to do.
Manually inserting the id and pass works properly. What would be a good solving of this problem? Thanks

I have had the same troubles with send. This post on autoitscript.com may help you with WinAPI_Keybd_Event() (documentation here):
#include <WinAPISys.au3>
_WinAPI_Keybd_Event(0x11, 0) # Push CTRL down
_WinAPI_Keybd_Event(0x11, 2) # Lift CTRL up again
This helped me with my problems.
NOTE: Sometimes, when your script breaks because of an error, it may happen that one of the keys on your keyboard is still pressed (i.e. pushed down but never lifted up). I use the on-screen keyboard that is integrated in Windows for these moments...

2 Solutions:
You add Strings with &:
send($id & "{tab}")
send($pass & "{enter}")
If that does not work just separate it:
send($id)
send("{tab}")
send($pass)
send("{enter}")
And you don't need that sleep

Related

SendKeys() method ignores some characters when sending to a text box

I move my Selenium installation to a new server, since then some tests using logins no longer work.
After investigation, I found that the password field was populated with an incorrect value. Therefore the tests failed.
I'm trying to do the following :
_passWordTextBox.Clear();
_passWordTextBox.SendKeys("!!ä{dasd$352310!!!\\_XY>èà$£<?^^");
Here is how the field is populated after those lines:
The "!" character was the only one missing. It worked on the previous server. Some other suspicious characters (like $ éà<) also worked.
I've looked at locale settings (culture differences) between the servers.
From these characters sent in a Password string:
!"#$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
All of these worked correctly:
"#$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\ _ abcdefghijklmnopqrstuvwxyz{|}
Only these failed to be sent correctly:
!]^`~
I've also tried in other fields (such as a Description field) and see the same failure.
I've tried to see if the command was sent correctly to the selenium server, but the logs seem to suggest it worked:
08:05:35.850 DEBUG [ReverseProxyHandler.execute] - To upstream: {"value":["!\"#$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~?"]}
It means that the server receives the command correctly, but for some reason the driver or the server doesn't execute properly.
Try this:
_passWordTextBox.SendKeys(#"!!ä{dasd$352310!!!\\_XY>èà$£<?^^");
Maybe is for the validates from field.
You can try using clipboard:
public static void SendValueFromClipboard(this IWebElement txtField, string value)
{
Clipboard.SetText(value);
txtField.SendKeys(OpenQA.Selenium.Keys.Control + "v");
}
This is written on C#, you will need to rewrite it in language, you are using.
After looking into multiple system settings i discovered that both my piloting and executing machine add the same regional settings (Format : French(Switzerland) , Keyboard : French(Switzerland), and I didn't look any further.
While fiddling around i discovered this setting :
As it turns out , the Language for non-Unicode programs was set to French(Switzerland) on the machine executing the tests. Changing it to English(UK) resolved the problem.
Probably a bug in chromedriver.
Your solution doesn't work for me, since I already have that setting set to English, but here's a solution I found if anyone else's interested.
Just change your keyboard to ENG UK in task bar.

Is it possible to include the same few lines of scenario at the beginning of a new one?

I have a 138 tests long scenario that allows me to test if a workflow works as it should.
However, I'm not a huge fan of having to repeat the same 6 lines that allows me to log in as an administrator, which are:
Given I am on "user/login"
And I fill in "admin#admin.com" for "name"
And I fill in "admin" for "pass"
And I press "Log in"
Then I should get a "200" HTTP response
And I should see "Dashboard"
I repeat this part 6 times so far, and I'm planning on needing to add this a few more time for some other tests.
So my question is the following: is there a way, through the FeatureContext file or any other way, to make these lines repeat?
Thank you in advance
So this is how I did:
Instead of calling Gherkin sentence one after the other, I parsed the vendor/ directory to find examples of how sentences where made.
my function to that connects me looks like the following:
/**
* #throws ElementNotFoundException
* #throws Exception
* #Given I am the administrator
*/
public function iAmTheAdministrator(){
$this->visitPath('/user/login');
$element = $this->getSession()->getPage();
$element->fillField('name', 'admin#admin.com');
$element->fillField('pass', 'admin');
$element->pressButton("Se connecter");
$this->assertSession()->pageTextContains('Dashboard');
}
This is pretty straight forward, and works well
There are 2 ways I know of that repeats steps. One is with background steps and the other involves running snippets of steps.
Background steps run at the start of each scenario.
Background:
Given I have done this
And this other thing
Scenario: Do stuff
When I do this
Then stuff should happen
This only works if all tests have the same starting procedure...
Snippets run whenever you call them which I assume you would rather want
Given I have logged in as an administrator
Step definition:
Given(/^I have logged in as an administrator$/) do
steps %{
Given I am on "user/login"
And I fill in "admin#admin.com" for "name"
And I fill in "admin" for "pass"
And I press "Log in"
Then I should get a "200" HTTP response
And I should see "Dashboard"
}
end
This allows you to use only one step which you can call at any time to run multiple steps
Hope this helps.

Selenium Timing issue: form fields are not filled correctly

I am using clj-webdriver to fill out a form in my test case.
(quick-fill-submit {"#firstname" "Firstnam"}
{"#lastname" "Lastnaem"}
{"#username" "Username"}
{"#password" "Password"}
{"#password2" "Password"}
{"#roles" "user"})
(click "button#add-user")
Every time I run this code in my test case the third value is filled in blank.
I moved the fields around and verified it. It is always the third field.
When execute my test case step by step in a repl it works fine but when
running it through lein test it fails.
This seems to be some kind of timing issue. When I for example stall the
execution by adding a
(wait-until #(= 1 2) 10000)
between the two functions the field gets filled. A simple
(Thread/sleep n)
does not work in this case. Why is Selenium not filling in the form correctly?
WebDriver and AJAX calls usually require tweaking the wait settings. You should try setting implicit-wait to something bigger than 0 (which is the default). Another option would be to use wait-until and a predicate that checks for the presence of the elements.

AHK: Manage multiple scripts

I got many scripts. I want to be able to manage them all in 1 in script.
What I want is that the main script will activate a certain script, then when the secondary script is done, it returns a value to the main script. After that, the main script calls another secondary script, etc...
Is there a proper way to do this?
More precise question:
Is it possible to activate a AHK script from another script AHK?
At the moment, to detect that at a secondary script is complete, the way I currently use is that right before the end of the secondary script, I press a combinaison of keys that the main script will detect. And once detected, it will increase a main script variable by one and this will trigger the activation of the next script. Is there a better way to achieve this?
The main script could call the other scripts using RunWait. The scripts could then communicate back before terminating themselves.
The best option for communication would be to use OnMessage.
The following is a working example from the documentation:
; Example: Send a string of any length from one script to another. This is a working example.
; To use it, save and run both of the following scripts then press Win+Space to show an
; InputBox that will prompt you to type in a string.
; Save the following script as "Receiver.ahk" then launch it:
#SingleInstance
OnMessage(0x4a, "Receive_WM_COPYDATA") ; 0x4a is WM_COPYDATA
return
Receive_WM_COPYDATA(wParam, lParam)
{
StringAddress := NumGet(lParam + 2*A_PtrSize) ; Retrieves the CopyDataStruct's lpData member.
CopyOfData := StrGet(StringAddress) ; Copy the string out of the structure.
; Show it with ToolTip vs. MsgBox so we can return in a timely fashion:
ToolTip %A_ScriptName%`nReceived the following string:`n%CopyOfData%
return true ; Returning 1 (true) is the traditional way to acknowledge this message.
}
; Save the following script as "Sender.ahk" then launch it. After that, press the Win+Space hotkey.
TargetScriptTitle = Receiver.ahk ahk_class AutoHotkey
#space:: ; Win+Space hotkey. Press it to show an InputBox for entry of a message string.
InputBox, StringToSend, Send text via WM_COPYDATA, Enter some text to Send:
if ErrorLevel ; User pressed the Cancel button.
return
result := Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
if result = FAIL
MsgBox SendMessage failed. Does the following WinTitle exist?:`n%TargetScriptTitle%
else if result = 0
MsgBox Message sent but the target window responded with 0, which may mean it ignored it.
return
Send_WM_COPYDATA(ByRef StringToSend, ByRef TargetScriptTitle) ; ByRef saves a little memory in this case.
; This function sends the specified string to the specified window and returns the reply.
; The reply is 1 if the target window processed the message, or 0 if it ignored it.
{
VarSetCapacity(CopyDataStruct, 3*A_PtrSize, 0) ; Set up the structure's memory area.
; First set the structure's cbData member to the size of the string, including its zero terminator:
SizeInBytes := (StrLen(StringToSend) + 1) * (A_IsUnicode ? 2 : 1)
NumPut(SizeInBytes, CopyDataStruct, A_PtrSize) ; OS requires that this be done.
NumPut(&StringToSend, CopyDataStruct, 2*A_PtrSize) ; Set lpData to point to the string itself.
Prev_DetectHiddenWindows := A_DetectHiddenWindows
Prev_TitleMatchMode := A_TitleMatchMode
DetectHiddenWindows On
SetTitleMatchMode 2
SendMessage, 0x4a, 0, &CopyDataStruct,, %TargetScriptTitle% ; 0x4a is WM_COPYDATA. Must use Send not Post.
DetectHiddenWindows %Prev_DetectHiddenWindows% ; Restore original setting for the caller.
SetTitleMatchMode %Prev_TitleMatchMode% ; Same.
return ErrorLevel ; Return SendMessage's reply back to our caller.
}
Well, I'm not sure why you'd want to make one script run another one... but here are a few other methods:
Include a script in another one
but, you know you can include a script inside another one, right? That is, you can use another scripts functions in your main script.
Make sure a particular script is loaded
"I got many scripts" too. Sometimes I need to make sure that a particular one is included before I can use it, so I put this at the top:
;make sure core.ahk is loaded since it is required
#include c:\ahk\core.ahk
And you don't have to worry about it getting included more than once (unless you need it) because:
#Include ensures that FileName is included only once, even if multiple inclusions are encountered for it. By contrast, #IncludeAgain allows
multiple inclusions of the same file, while being the same as #Include
in all other respects.
Now, when I include file.ahk in main.ahk, I am assured of no problems using the functions from core.ahk that file.ahk requires. And even if I include core.ahk again in main.ahk it is no worry (unless it contains subroutines instead of just functions - in which case they get run at the point where they were included, so it's best not to put subroutines in your ahk libraries).
Use good ole' RUN on Scripts
Aside from that, you know you can always use the run command to launch an ahk script. You don't have to do all that fancy WM_SENDMESSAGE stuff.
Communicate betweenst scripts using a hidden GUI
Another way for two scripts to communicate between each other is for script #1 to keep open a hidden GUI window that has an edit box and a submit button. This window will never be shown. Now, Script #2 hunts for that message box, uses send to put a string in the edit box, and then control-click to push the submit button. Now script #1 has just received input from script #2. And you don't even have to hunt for the window if you put the windows hwnd value in both scripts (so they already know it ahead of time). This works like a charm.
Tell if a script has completed
If you use ahk's run command, there is an parameter that will give you back the PID of that process (PID = Process ID). You can use this PID to check to see if the script is running, and you can use it to terminate the process.
Also, if you use runwait - the script using that command will pause and wait for the runn-ed process to complete and close before continuing.
theoretically you could also use a file object between the scripts as a sort of stdin/stdout method as when opening a file with the file object you can set it as shared.
You could also set an environment variable and pass the name of the variable to the script ,given that you have setup argument handling in the target script, which then sets the environment variable value on closing. using RunWait and this you could find out what the return result of the script is after it runs.
Lastly, look into using a function as that is probably the "best practice" for what you are trying to do. Since a function can do anything a script can do and you can pass it an array to operate on or with using ByRef on the array param. This would mean that you don't have to write in a bunch of parameters when writing the function and the variables would release memory once the function is complete, automatically. You can even write your functions in a separate file and use #Include to use them in your script.

Maven an java.io.scanner(System.in)

I'm running into issues with my project. When running in Netbeans it seems to work fine with user interaction. However when I run using mvn test it does not. I see the command line menu but I am not prompted to make a selection. When I force terminate the project, I get an error about No Line Found.
Any Ideas? I'm stumped.
The line that isn't working is essentially:
System.out.print("1) Print String\n"
+ "0) Exit\n"
+ "Enter Selection: ");
String line = (new java.util.Scanner(System.in)).nextLine();
I see the output Similar to this:
1) Print String
0) Exit
But I don't see "Enter Selection: " and it doesn't prompt for the String input. I terminate and get "No Line Found" though after I cancel the execution I see the whole string int he "Test Results window".
It's abnormal for unit tests to pause for user interaction. I wouldn't be surprised if it acts strangely. I expect the testing libraries don't really anticipate this sort of thing.
In practice, one should not interact with user while performing JUnit tests. Tests should be designed to operate automatically and continuously. If you want to test underlying code with two separate values, two tests should be implemented and call each the underlying code with their own value. This should cover for the two options offered to your user.