Writing UI tests for RTL language - android

I am trying to write UI tests for RTL language. Here is a scenario. I have an AutoCompleteTextView, on which when I try to tag a user ("#user"), it shows dropdown of suggested users. This works for RTL & LTR languages when I manually type the strings.
However, if I try to test using espresso the functionality it doesn't work as expected.
Here is how I am trying to write UI test :
Whenever I tell edit text to type “#u” using onView(withId(R.id.message_input_field)).perform(typeText("#u")), Espresso generates key events to inject the characters into edit text. Something like, KEY_DOWN_SHIFT, KEY_DOWN_2, KEY_UP_SHIFT, KEY_UP_2, this types “#” and so on. Everything works fine for English language.
Problem occurs when we try to tag using RTL characters, using something like onView(withId(R.id.message_input_field)).perform(typeText("#פ")). Espresso fails to recognize the RTL characters & can not generate key events, eventually throws java.lang.RuntimeException: Failed to get key events for string פ (i.e. current IME does not understand how to translate the string into key events)
I tried to do replaceText(…) instead of typeText(…) but replaceText in turn does editText.setText(…). but it doesn’t show the drop down. Weird.
How do I write UI test for this scenario?
P.S. It doesn’t matter what is your device language or what is you currently selected keyboard is.

Related

Android textfield elements are tapable, but not editable

I am playing around with Xamarin UITest and I have noticed that on my Android device (Samsung S10E, v. 10) Xamarin UITest (v. 3.0.7) when I tap on an entry text element I cannot then enter text inside of that element.
The entry element is focused with the cursor inside of the entryfield and the keyboard is displayed, but no text is entered. To add another level of complexity, my test PASSES and does not FAIL even though the text was never entered.
Here is my code:
app.WaitForElement(c => c.Class("UsernameID"));
Thread.Sleep(3000);
app.EnterText(c => c.Id("UsernameID"), "Password1");
Also, tried this:
app.EnterText(c => c.TextField("LoginUserIDEntry"), "oaqa_Clark6_ps");
I inserted a thread sleep in case the keyboard was not loading in time for the EnterText call.
The same code on iOS works perfectly fine.
I understand that Xamarin.UITest does not use the soft keyboard. Instead, it injects itself between the soft keyboard and the application and simulates key presses. Whereas iOS actually simulates the presses on the keyboard.
Can anyone tell me if this is a syntax issue, device specific issue, or Xamarin issue?
In order to identify xamarin element you need to use either x:Name or even AutomationId field in shared project xaml.
Class will try to find it by Class name in native android or iOS. It's highly unlikely that class names in both platforms are same as you seems to have mentioned in the first code block.
To be generic you should mostly use Marked should work UITest projext
<Entry x:Name="entryXName" AutomationId="entryAutoId" />
app.EnterText(c => c.Marked("entryXName"), "oaqa_Clark6_ps");
//by id
app.EnterText(x=> x.Id("entryAutoId"),"foobarblahblackship");
There is whole good documentation here on official site
You can check sample as well.
I have learnt that Thread.Sleep will block UI main thread,instead you should use await Task.Delay

Xamarin | Android | Custom Keyboard Android.Views.KeyCode

I am creating a custom keyboard for a Xamarin Android Application. I have it working, and my listener receives the input. My issue is the parameter Android.Views.Keycode. This enumeration does not have all of the possible keys. I have found some of them generate the correct keystroke if the KeyEvent is created with MetaKeyStates.ShiftOn. But even in that I have not found the right combination for the {} keys. There also doesn't appear to be a clear answer to which key or key/MetaState combination maps to backspace, Next, Done, etc.
I have not found documentation that shows which Keyode in conjunction with the required MetaState will generate which key strokes. Does such documentation exists? Does anyone have an exhaustive example showing which Keycode and which metastates create which characters?
Also, in the case of my keyboard, the ! and ? characters will appear on the screen with the normal text. Do I need to use a custom Keycode for them so I can tell the difference between them and the character that would have the same Keycode without a metastate?
Why are you using keycodes? Those are for hardware buttons. Software keyboards usually use InputConnection.commitText and skip keycodes entirely.
Next, Done, etc are the action button. That's another call on InputConnection- performEditorAction.
Delete is generally done by InputConenction.deleteSurroundingText.
Shifts are generally an internal state and not connected to any keycode.
You're doing everything the wrong way, basically. Here's the android implementation, I assume xamarin has its wrappers. https://developer.android.com/reference/android/view/inputmethod/InputConnection

Is there a way to use UIAutomator to enter cyrillic letters?

I'm trying to test my company's browser's auto suggest functionality for the Russian language with UIAutomator and am hitting a snag:
There are no KeyEvent.KeyCode_* code for Russian letters and UiDevice.pressKeyCode(KeyEvent.KEYCODE_LANGUAGE_SWITCH) doesn't appear to help. What documentation I found inside the KeyEvent class seems to suggest that I just need to use the same KeyCodes as the english letters but magically they would be mapped across to the letters of of the other languages. That does not appear to actually happen however as I'm still seeing the English letter show up when I try that.
Normally with Russian I just use UiObject2.setText(...) but that method does not trigger auto suggestions.
I've tried delving into what UiDevice.pressKeyCode is doing and attempting a couple workarounds such as:
KeyEvent eventsб2 = new KeyEvent(SystemClock.currentThreadTimeMillis(), "б", KeyCharacterMap.VIRTUAL_KEYBOARD, 0);
Instrumentation.sendKeySync(eventsб2);
or
KeyEvent[] eventsа = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD).getEvents(new char[] {'a'});
Instrumentation.sendKeySync(eventsа[0]);
But they either don't enter the letter or throw a permission exception regarding needing the INJECT_EVENTS permission. Overall I'm feeling like I'm stumbling in the dark and would love some advice on how to proceed.
I tried this and worked.
/**
* ##Test comment here##
*
* #throws Exception
*/
#Test
public void culebraGeneratedTest_CyrillicKeyBoardAndSelectSuggestion() throws Exception {
mDevice.pressHome();
mDevice.findObject(By.res("com.android.quicksearchbox:id/search_widget_text").clazz("android.widget.TextView").text(Pattern.compile("")).pkg("com.android.quicksearchbox")).clickAndWait(Until.newWindow(), DEFAULT_TIMEOUT);
mDevice.findObject(By.desc("й").clazz("com.android.inputmethod.keyboard.Key").text(Pattern.compile("")).pkg("com.android.inputmethod.latin")).clickAndWait(Until.newWindow(), DEFAULT_TIMEOUT);
(new UiScrollable(new UiSelector().resourceId("com.android.quicksearchbox:id/suggestions").index(1).packageName("com.android.quicksearchbox"))).getChildByText(new UiSelector().className("android.widget.RelativeLayout").packageName("com.android.quicksearchbox"), "йемен", true).click();
}
I have to admit that I don't know Russian or what I was selecting on the Cyrillic keyboard, so bear with me.
To generate this test I used CulebraTester as it seems to be an interesting use case for the tool.
The steps were:
start recording the test (generating Java UiAutomator, can also generate python and other languages)
press Home
select the Quick Search Box
Press the key
Select one of the suggestions
You will be able to create a similar test using AndroidViewClient/culebra in python but because this tool is based on the information obtained from uiautomator dump it won't be able to detect the letters on the keyboard, but you can also touch them using DIPs
vc.dump(window=-1)
vc.findViewByIdOrRaise("com.android.quicksearchbox:id/search_widget_text").touch()
vc.sleep(_s)
vc.dump(window=-1)
device.touchDip(15.33, 393.33, 0)
but this is not as device independent as the first solution.
Hope this helps you.

How to use AndroidViewClient findViewWithText() with regex

I have a script to monitor the Notifications screen page.
I can open it via "Culebra" option "UiDevice" -> "Open Notifications".
The notifications error message from some apps have starting characters which are changing, only a constant pattern like "error for" is common but located at different position of the TextView error messages.
Therefore I can't use a regex with the method findViewWithText(regex) as it seems to use a regex match() instead of regex search(). Another solution for my problem is to use traverse() method with my own transform method which can do a regex search() of the view attribute text, but I can't figure out how to pass a parameter like a regex to my own transform method!?
This works for me to touch on a notification with text USB debugging connected:
vc.findViewWithTextOrRaise(re.compile('.*USB.*'), root=vc.findViewByIdOrRaise('id/no_id/3')).touch()
vc.sleep(_s)
notice this is a modified culebra script, that's why findViewWithTextOrRaise() is using the root argument to limit the search to the subtree which may not be needed in all cases, but it's safer to use.
It's worth to mention, that this works too
vc.findViewWithTextOrRaise(re.compile('.*debugging.*'), root=vc.findViewByIdOrRaise('id/no_id/3')).touch()

Is it possible to define a suggestion list in webview applications?

When entering a string in a text type input element in a webview based app, a list of possible words is showed above the virtual keyboard.
In my application the user is not allowed to input arbitrary words, instead only words and phrases from a database are legal.
So, I want to set the list of words from my phonegap app and disable the automatic creation of this list.
Q: Is this possible to create the list - and how?
(This is a phonegap app and I am testing on android, but this might be a problem for webview / text input fields on different platforms)
EDIT:
Just found out (yes, I'm new to android development), that one can disable the suggestion list with: Settings / Language and Keyboard / Android keyboard / Show suggestions.
But of course, this setting should be made only for the app, from inside the app, without user interaction and not changing anything outside the app.
Any chance to get this done?
EDIT 2:
Instead of disabling the suggestion list I tried to use it.
The displayCompletions method of InputMethodManager sounded promising, so I tried the following code:
...
// data member
InputMethodManager mInputMethodManager = null;
...
...
// initialized
mInputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
...
public void showSuggestions(String[] words) {
Log.d(TAG, "showSuggestions (in Java!): " + words.length); // yes, this code is executed
CompletionInfo[] completions = new CompletionInfo[words.length];
for (int i=0; i<words.length; i++) {
completions[i] = new CompletionInfo(i, i, words[i]); // no idea, what the 2 extra integers mean
}
mInputMethodManager.displayCompletions(mView, completions);
}
The method is executed, whenever a new list is available (after the input has changed and the server has answered a request).
However, nothing has changed - the builtin mechanism is still doing its disadvantageous work.
Why don't you use something like the auto complete in jQuery UI.
http://jqueryui.com/demos/autocomplete/
Also, it's not too hard to whip this up yourself in JavaScript.
http://www.javascript-examples.com/autocomplete-demo/
In case there are different variants of virtual keyboard(swype and others) there might be no list of possible words. So, I suppose there is no general solution for not showing this list.
There is a parameter http://developer.android.com/reference/android/widget/TextView.html#attr_android:editorExtras editorExtras which defines parameters passed to input method implementation, but I'm not sure how would you use it in PhoneGap application
Edit:
I suppose you can extend default input method and make it not to show suggestions
inputmethod reference http://developer.android.com/reference/android/inputmethodservice/InputMethodService.html
Providing Custom Software Keyboards
If you are interested in developing your own software keyboards, we highly recommend the following references:
IMEs are implemented as an Android service. Begin by reviewing the Android packages called android.inputmethodservice and android.view.inputmethod, which can be used to implement custom input methods.
The SoftKeyboard sample application in the Android SDK provides an implementation of a software keyboard.
The Android Developer technical articles on onscreen input methods and creating an input method.
found it here http://e-university.wisdomjobs.com/android/chapter-946-288/handling-advanced-user-input.html

Categories

Resources