Android Toast Accumulation Testing - android

Like many others, i've been trying to solve the problem of toast accumulation.
How to prevent Multiple Toast Overlaps
toast issue in android
Cancelling an already open toast in Android
Best way to avoid Toast accumulation in Android
I finally decided to keep track of the current displayed toast and cancel it when another arrives (there's some more logic involved), but i could have use only one toast and change it message. What i want to know is this... Is there a way to TEST this behaviour? Im currently using Robotium and tried different things, but unfortunately the methods to check for toasts (solo.waitForText and solo.searchForText) aren't helping me as i can't make something like
assertTrue(solo.waitForText(text));
//maybe even some sleep here
assertFalse(solo.searchText(text);
Has anyone done something like this? Is there a way to test this using Robotium? using somethig else?

You can use a robotium condition to wait for the text to disappear. Here's a method I use for that.
private void waitForTextToDisappear(final String text, int wait) {
Condition textNotFound = new Condition() {
#Override
public boolean isSatisfied() {
return !solo.searchText(text);
}
};
assertTrue("Text gone: " + text, solo.waitForCondition(textNotFound, wait));
}

Related

Creating a toast in android and specifying the location

I am working on my first Android app and I am trying to create a toast and specify the location where I want it to appear. When I was using the code that is now commented (it didn't customize the toast's location) the app ran perfectly on the emulator, but now that I am trying to customize the location and using the code below the comments, the app stops running when I click in the UI on the button meant to show the toast.
Do you have any idea of why this is happening? Because I have seen very similar codes (almost the same) presented as correct, so this should be working. I know this is a very simple code and a simple question, but still, I cannot figure out what is wrong with my code.
This is the code on my onButtonClick:
public void onClick(View V) {
// Toast.makeText(QuizActivity.this,
// R.string.correct_toast,
// Toast.LENGTH_SHORT).show();
Toast t = new Toast(QuizActivity.this);
t.setText(R.string.correct_toast);
t.setDuration(Toast.LENGTH_SHORT);
t.setGravity(Gravity.TOP|Gravity.LEFT,0,0);
t.show();
}
From https://developer.android.com/reference/android/widget/Toast#Toast(android.content.Context) :
Construct an empty Toast object. You must call setView(View) before you can call show().
Your code crashes because now you are using the Toast() constructor. And you need to setView(View) before show(). While this is not necessary with makeText().
As I understand, makeText() creates a View for you setting the text from the second parameter. But the constructor doesn't, and the setText() method does not either. setText() only update the an existing text:
From https://developer.android.com/reference/android/widget/Toast#setText(int) :
Update the text in a Toast that was previously created using one of the makeText() methods.
Here is an example of how to do that:
Custom toast on Android: a simple example
Edit
In any case, you can create the Toast with your initial code, without calling show().
public void onClick(View V) {
Toast t = Toast.makeText(QuizActivity.this,
R.string.correct_toast,
Toast.LENGTH_SHORT);
t.setGravity(Gravity.TOP|Gravity.LEFT,0,0);
t.show();
}
Edit 2
Now you have edited your code, but you are passing the Button View.

Robotium Solo - wait for broadcast

I want to create a condition to wait for a broadcast upon a button press
right now I am just doing solo.sleep(10000)
but I dont want to sleep solo for nothing
How do I formulate the condition "broadcast received" ?
Ok explanations
Robotium Solo is an instrumentation framework with nice api
It has a method called "solo.waitForCondition(Condition, int timeout)"
I want to formulate (the word formulate means say what i want to say in correct words)
the correct condition that will tell me that the broadcast was indeed received
I want to write some code (I don't know which exactly) to know that the broadcast was indeed sent
for example, if i want to know that a button is now visible i would write
solo.waitForCondition(new Condition(){
public boolean isSatisfied(){
Button b = getActivity().findViewById(R.id.myButton);
return b.getVisibility() == View.VISIBLE;
}
}
now back to my question - What (not how, but what) do I write in order to know for sure that the broadcast was sent inside the isSatisfied method
I suppose you meant that you don't want to sleep for 10 seconds, if you get the broadcast earlier. What you can do is
long beginTime = new Date().getTime();
while (new Date().getTime() - beginTime < 10000) {
solo.sleep(500);
if (conditionMet) {
// Do something
break;
}
}
This way you can do these checks on smaller intervals.
Ok, so in fact this is more or less how waitForCondition is implemented. Unfortunately I don't think you can listen for events with robotium. What you can do is monitor the view hierarchy. In your case, there should be some difference to the views that is triggered when the button is clicked, so that is what you need to check for in the Condition (and your example does that).
This is if you don't want to edit the code you are testing. If you are willing to change the code, you can add an onClickListener() and in that you can set a view's Tag to a boolean for example. Later in robotium you can check for that tag for being set. This is however not good way to do it, because you are adding more code just for the sake of the tests.

Android - AutoCompleteTextView not showing after setText is called

I'm having a weird issue with AutoCompleteTextView.
I have a AutoCompleteTextView that shows suggestions of cities when typing in it.
The list of cities is retrieved from a remote server via JSON. When I use the soft keyboard or the Mic Button on the soft keyboard, the suggestions work fine. AutoCompleteTextView does show the suggested cities.
But, I have a problem when I try to set the text using myAutoCompleteTextView.setText("Chi") , the auto complete does not show..
I have also tried myAutoCompleteTextView.append("Chi") but still no luck..
The adapter is there, its just that the suggestions don't show.
Any tips?
Thanks.
Yes you are right there is a bug in AutocompleteTextview to show default suggestion using setText(""); method.
But you can achieve this by adding some more lines of code as below.
autoText.postDelayed(new Runnable() {
#Override
public void run() {
autoText.showDropDown();
}
},500);
autoText.setText("chi");
autoText.setSelection(autoText.getText().length());
It is due to filtering,
No Need to any extra code for manage it, I found it in very easy and working way.
Google Dev. Reference link
autoText.setText("Default Value here",false)
autoText.setSelection(autoText.text.count()) // kotlin
as per documentation second parameter you can pass for filtering.
boolean: If false, no filtering will be performed as a result of this call.
Biraj Zalavadia's answer work, but you must write to "settext" in Runnable.
Like this:
mACTextViewEmail.postDelayed(new Runnable() {
#Override
public void run() {
mACTextViewEmail.showDropDown();
mACTextViewEmail.setText("My text is here");
mACTextViewEmail.setSelection(mACTextViewEmail.getText().length());
}
},500);
I searched for it and just found this solution that worked so well
Look at this issue
fun AutoCompleteTextView.showDropdown(adapter: ArrayAdapter<String>?) {
if(!TextUtils.isEmpty(this.text.toString())){
adapter?.filter?.filter(null)
}
}
In kotlin language, you can use this extension function.

Updating an EditText with Espresso

I'm attempting to update an EditText as part of an Espresso test with:
onView(allOf(withClassName(endsWith("EditText")), withText(is("Test")))).perform(clearText())
.perform(click())
.perform(typeText("Another test"));
However I receive the following error:
com.google.android.apps.common.testing.ui.espresso.NoMatchingViewException: No views in hierarchy found matching: (with class name: a string ending with "EditText" and with text: is "Test")
By breaking down the test line I can see that this occurs after performing clearText(), so I assume that the matchers are being re-run prior to each perform and fail the prior to the second action. Although this makes sense, it leaves me somewhat confused as to how to update the EditText using Espresso. How should I do this?
Note that I cannot use a resource ID or similar in this scenario and have to use the combination as shown above to identify the correct view.
You can use the replaceText method.
onView(allOf(withClassName(endsWith("EditText")), withText(is("Test"))))
.perform(replaceText("Another test"));
Three things to try:
1. You can run performs in succession.
onView(...)
.perform(clearText(), typeText("Some Text"));
2. There is a recorded issue on the Espresso page which was marked as invalid (but is still very much a bug). A workaround for this is to pause the test in-between performs.
public void test01(){
onView(...).perform(clearText(), typeText("Some Text"));
pauseTestFor(500);
onView(...).perform(clearText(), typeText("Some Text"));
}
private void pauseTestFor(long milliseconds) {
try {
Thread.sleep(milliseconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
3. Are you absolutely sure that your EditText contains the text, "Test"?
To set value in EditText with Espresso
simple like this
onView(withId(R.id.yourIdEditText)).perform(typeText("Your Text"))
I was having a similar issue and solved it using the containsString matcher and Class.getSimpleName(). Like this:
onView(withClassName(containsString(PDFViewPagerIVZoom.class.getSimpleName()))).check(matches(isDisplayed()));
You can see the full code here
You could try two things. First I would try to use
onView(withId(<id>).perform...
This way you would always have access to the EditText field even when other EditText fields are on the screen.
If that's not an option, you could split up your perform calls.
onView(allOf(withClassName(endsWith("EditText")),withText(is("Test")))).perform(clearText());
onView(withClassName(endsWith("EditText"))).perform(click());
onView(withClassName(endsWith("EditText"))).perform(typeText("Another Test");

android show toast in surfacview onDraw

In my game i use a surfaceview. There i update my game logic and draw on an ondraw loop.
I want to show a toast like "good catch" but it doesn't show. I think its because its in a loop. Even if i put it in an if block that limit it to show once, it doesn't work.
void onDraw()
{
if(isGood)
Toast.makeText((Activity)getContext(), adMessage, Toast.LENGTH_SHORT).show();
}
Thanks
That code should work if isGood is true.
BTW - you dont need to cast with (Activity)

Categories

Resources