Java tutorial
/* * Catroid: An on-device visual programming system for Android devices * Copyright (C) 2010-2015 The Catrobat Team * (<http://developer.catrobat.org/credits>) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * An additional term exception under section 7 of the GNU Affero * General Public License, version 3, is available at * http://developer.catrobat.org/license_additional_term * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.catrobat.catroid.uitest.util; import android.annotation.TargetApi; import android.app.Activity; import android.app.Instrumentation; import android.app.NotificationManager; import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Rect; import android.net.Uri; import android.os.Build; import android.os.Handler; import android.os.SystemClock; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.test.ActivityInstrumentationTestCase2; import android.text.InputType; import android.util.Log; import android.util.SparseArray; import android.util.SparseIntArray; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewParent; import android.view.Window; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import com.actionbarsherlock.app.SherlockFragmentActivity; import com.actionbarsherlock.internal.ActionBarSherlockCompat; import com.actionbarsherlock.internal.view.menu.ActionMenuItem; import com.robotium.solo.Condition; import com.robotium.solo.Solo; import junit.framework.AssertionFailedError; import org.catrobat.catroid.ProjectManager; import org.catrobat.catroid.R; import org.catrobat.catroid.common.BrickValues; import org.catrobat.catroid.common.Constants; import org.catrobat.catroid.common.FileChecksumContainer; import org.catrobat.catroid.content.BroadcastScript; import org.catrobat.catroid.content.Project; import org.catrobat.catroid.content.Script; import org.catrobat.catroid.content.Sprite; import org.catrobat.catroid.content.StartScript; import org.catrobat.catroid.content.WhenScript; import org.catrobat.catroid.content.bricks.Brick; import org.catrobat.catroid.content.bricks.BroadcastBrick; import org.catrobat.catroid.content.bricks.BroadcastReceiverBrick; import org.catrobat.catroid.content.bricks.BroadcastWaitBrick; import org.catrobat.catroid.content.bricks.ChangeBrightnessByNBrick; import org.catrobat.catroid.content.bricks.ChangeSizeByNBrick; import org.catrobat.catroid.content.bricks.ChangeTransparencyByNBrick; import org.catrobat.catroid.content.bricks.ChangeVariableBrick; import org.catrobat.catroid.content.bricks.ChangeVolumeByNBrick; import org.catrobat.catroid.content.bricks.ChangeXByNBrick; import org.catrobat.catroid.content.bricks.ChangeYByNBrick; import org.catrobat.catroid.content.bricks.ClearGraphicEffectBrick; import org.catrobat.catroid.content.bricks.ComeToFrontBrick; import org.catrobat.catroid.content.bricks.ForeverBrick; import org.catrobat.catroid.content.bricks.FormulaBrick; import org.catrobat.catroid.content.bricks.GlideToBrick; import org.catrobat.catroid.content.bricks.GoNStepsBackBrick; import org.catrobat.catroid.content.bricks.HideBrick; import org.catrobat.catroid.content.bricks.IfLogicBeginBrick; import org.catrobat.catroid.content.bricks.IfLogicElseBrick; import org.catrobat.catroid.content.bricks.IfLogicEndBrick; import org.catrobat.catroid.content.bricks.IfOnEdgeBounceBrick; import org.catrobat.catroid.content.bricks.LoopEndBrick; import org.catrobat.catroid.content.bricks.MoveNStepsBrick; import org.catrobat.catroid.content.bricks.NextLookBrick; import org.catrobat.catroid.content.bricks.NoteBrick; import org.catrobat.catroid.content.bricks.PlaceAtBrick; import org.catrobat.catroid.content.bricks.PlaySoundBrick; import org.catrobat.catroid.content.bricks.PointInDirectionBrick; import org.catrobat.catroid.content.bricks.PointInDirectionBrick.Direction; import org.catrobat.catroid.content.bricks.PointToBrick; import org.catrobat.catroid.content.bricks.PointToBrick.SpinnerAdapterWrapper; import org.catrobat.catroid.content.bricks.RepeatBrick; import org.catrobat.catroid.content.bricks.SetBrightnessBrick; import org.catrobat.catroid.content.bricks.SetLookBrick; import org.catrobat.catroid.content.bricks.SetSizeToBrick; import org.catrobat.catroid.content.bricks.SetTransparencyBrick; import org.catrobat.catroid.content.bricks.SetVariableBrick; import org.catrobat.catroid.content.bricks.SetVolumeToBrick; import org.catrobat.catroid.content.bricks.SetXBrick; import org.catrobat.catroid.content.bricks.SetYBrick; import org.catrobat.catroid.content.bricks.ShowBrick; import org.catrobat.catroid.content.bricks.SpeakBrick; import org.catrobat.catroid.content.bricks.StopAllSoundsBrick; import org.catrobat.catroid.content.bricks.TurnLeftBrick; import org.catrobat.catroid.content.bricks.TurnRightBrick; import org.catrobat.catroid.content.bricks.UserBrick; import org.catrobat.catroid.content.bricks.WaitBrick; import org.catrobat.catroid.formulaeditor.DataContainer; import org.catrobat.catroid.formulaeditor.Formula; import org.catrobat.catroid.formulaeditor.FormulaElement; import org.catrobat.catroid.formulaeditor.InternToken; import org.catrobat.catroid.formulaeditor.InterpretationException; import org.catrobat.catroid.io.StorageHandler; import org.catrobat.catroid.stage.StageListener; import org.catrobat.catroid.test.utils.Reflection; import org.catrobat.catroid.ui.MainMenuActivity; import org.catrobat.catroid.ui.ProgramMenuActivity; import org.catrobat.catroid.ui.ProjectActivity; import org.catrobat.catroid.ui.ScriptActivity; import org.catrobat.catroid.ui.UserBrickScriptActivity; import org.catrobat.catroid.ui.dialogs.NewSpriteDialog; import org.catrobat.catroid.ui.dialogs.NewSpriteDialog.ActionAfterFinished; import org.catrobat.catroid.ui.dialogs.NewSpriteDialog.DialogWizardStep; import org.catrobat.catroid.ui.fragment.AddBrickFragment; import org.catrobat.catroid.ui.fragment.FormulaEditorDataFragment; import org.catrobat.catroid.utils.NotificationData; import org.catrobat.catroid.utils.StatusBarNotificationManager; import org.catrobat.catroid.utils.UtilFile; import org.catrobat.catroid.utils.Utils; import org.catrobat.catroid.web.ServerCalls; import org.catrobat.catroid.web.WebconnectionException; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.List; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; import static junit.framework.Assert.fail; public final class UiTestUtils { private static ProjectManager projectManager = ProjectManager.getInstance(); private static SparseIntArray brickCategoryMap; private static List<InternToken> internTokenList = new ArrayList<InternToken>(); private static final String TAG = UiTestUtils.class.getName(); public static final String DEFAULT_TEST_PROJECT_NAME = "testProject"; public static final String PROJECTNAME1 = "testingproject1"; public static final String PROJECTNAME2 = "testingproject2"; public static final String PROJECTNAME3 = "testingproject3"; public static final String PROJECTNAMEOFFENSIVELANGUAGE = "fuck i have to use fuck penis"; public static final String PROJECTDESCRIPTION1 = "testdescription1"; public static final String PROJECTDESCRIPTION2 = "testdescription2"; public static final String DEFAULT_TEST_PROJECT_NAME_MIXED_CASE = "TeStPROjeCt"; public static final String COPIED_PROJECT_NAME = "copiedProject"; public static final String JAPANESE_PROJECT_NAME = "?????"; public static final String TEST_USER_BRICK_NAME = "New Brick 1"; public static final String TEST_USER_BRICK_VARIABLE = "Variable 1"; public static final String NORMAL_AND_SPECIAL_CHAR_PROJECT_NAME = "[Hey+, =lo_ok. I'm; -special! ?<>]"; public static final String NORMAL_AND_SPECIAL_CHAR_PROJECT_NAME2 = "../*T?E\"S/T:%22T<E>S?T\\T\\E|S%|"; public static final String JUST_SPECIAL_CHAR_PROJECT_NAME = "*\"/:<>?\\|"; public static final String JUST_SPECIAL_CHAR_PROJECT_NAME2 = "*\"/:<>?\\|%"; public static final String JUST_ONE_DOT_PROJECT_NAME = "."; public static final String JUST_TWO_DOTS_PROJECT_NAME = ".."; public static final int DRAG_FRAMES = 35; public static final int SCRIPTS_INDEX = 0; public static final int LOOKS_INDEX = 1; public static final int SOUNDS_INDEX = 2; private static final List<Integer> FRAGMENT_INDEX_LIST = new ArrayList<Integer>(); static { FRAGMENT_INDEX_LIST.add(R.id.fragment_script); FRAGMENT_INDEX_LIST.add(R.id.fragment_look); FRAGMENT_INDEX_LIST.add(R.id.fragment_sound); } public static SetVariableBrick createSendBroadcastAfterBroadcastAndWaitProject(String message) { Project project = new Project(null, DEFAULT_TEST_PROJECT_NAME); Sprite firstSprite = new Sprite("sprite1"); Script scriptOfSprite1 = new StartScript(); firstSprite.addScript(scriptOfSprite1); project.addSprite(firstSprite); Script startScript = firstSprite.getScript(0); SetVariableBrick setVariableBrick = new SetVariableBrick(1.0f); startScript.addBrick(setVariableBrick); startScript.addBrick(new BroadcastWaitBrick(message)); startScript.addBrick(new ChangeVariableBrick(10.0f)); Sprite secondSprite = new Sprite("sprite2"); Script scriptOfSprite2 = new StartScript(); secondSprite.addScript(scriptOfSprite2); scriptOfSprite2.addBrick(new WaitBrick(300)); scriptOfSprite2.addBrick(new ChangeVariableBrick(100.0f)); scriptOfSprite2.addBrick(new BroadcastBrick(message)); project.addSprite(secondSprite); Sprite thirdSprite = new Sprite("sprite3"); Script whenIReceive = new BroadcastScript(message); thirdSprite.addScript(whenIReceive); whenIReceive.addBrick(new ChangeVariableBrick(1000.0f)); project.addSprite(thirdSprite); projectManager.setFileChecksumContainer(new FileChecksumContainer()); projectManager.setProject(project); projectManager.setCurrentSprite(firstSprite); projectManager.setCurrentScript(scriptOfSprite2); return setVariableBrick; } public static int createSendBroadcastInBroadcastAndWaitProject(String message1, String message2, double degreesToTurn, Sprite secondSprite, Sprite thirdSprite) { Project project = new Project(null, DEFAULT_TEST_PROJECT_NAME); Sprite firstSprite = new Sprite("sprite1"); Script testScript = new StartScript(); firstSprite.addScript(testScript); project.addSprite(firstSprite); projectManager.setFileChecksumContainer(new FileChecksumContainer()); projectManager.setProject(project); projectManager.setCurrentSprite(firstSprite); projectManager.setCurrentScript(testScript); int initialRotation = (int) firstSprite.look.getRotation(); Script startScript = firstSprite.getScript(0); startScript.addBrick(new BroadcastBrick(message1)); Script whenIReceiveSecondSprite = new BroadcastScript(message1); secondSprite.addScript(whenIReceiveSecondSprite); whenIReceiveSecondSprite.addBrick(new TurnRightBrick(degreesToTurn)); whenIReceiveSecondSprite.addBrick(new WaitBrick(1000)); whenIReceiveSecondSprite.addBrick(new BroadcastWaitBrick(message2)); project.addSprite(secondSprite); Script whenIReceiveThirdSprite = new BroadcastScript(message1); thirdSprite.addScript(whenIReceiveThirdSprite); whenIReceiveThirdSprite.addBrick(new TurnLeftBrick(degreesToTurn)); whenIReceiveThirdSprite.addBrick(new WaitBrick(1000)); whenIReceiveThirdSprite.addBrick(new BroadcastBrick(message1)); project.addSprite(thirdSprite); return initialRotation; } public static SetVariableBrick createSameActionsBroadcastProject(String message) { Project project = new Project(null, DEFAULT_TEST_PROJECT_NAME); Sprite firstSprite = new Sprite("sprite1"); Script firstScript = new StartScript(); firstSprite.addScript(firstScript); project.addSprite(firstSprite); Script startScript = firstSprite.getScript(0); SetVariableBrick setVariableBrick = new SetVariableBrick(0.0f); startScript.addBrick(setVariableBrick); RepeatBrick repeatBrick = new RepeatBrick(10); LoopEndBrick endBrick = new LoopEndBrick(repeatBrick); repeatBrick.setLoopEndBrick(endBrick); startScript.addBrick(repeatBrick); startScript.addBrick(new BroadcastWaitBrick(message)); startScript.addBrick(endBrick); Sprite secondSprite = new Sprite("sprite2"); Script secondScript = new BroadcastScript(message); secondSprite.addScript(secondScript); IfLogicBeginBrick ifBeginBrickSecondScript = new IfLogicBeginBrick(1); IfLogicElseBrick ifElseBrickSecondScript = new IfLogicElseBrick(ifBeginBrickSecondScript); IfLogicEndBrick ifEndBrickSecondScript = new IfLogicEndBrick(ifElseBrickSecondScript, ifBeginBrickSecondScript); secondScript.addBrick(ifBeginBrickSecondScript); secondScript.addBrick(new ChangeVariableBrick(1.0f)); secondScript.addBrick(ifElseBrickSecondScript); secondScript.addBrick(ifEndBrickSecondScript); project.addSprite(secondSprite); Sprite thirdSprite = new Sprite("sprite3"); Script thirdScript = new BroadcastScript(message); thirdSprite.addScript(thirdScript); IfLogicBeginBrick ifBeginBrickThirdScript = new IfLogicBeginBrick(1); IfLogicElseBrick ifElseBrickThirdScript = new IfLogicElseBrick(ifBeginBrickThirdScript); IfLogicEndBrick ifEndBrickThirdScript = new IfLogicEndBrick(ifElseBrickThirdScript, ifBeginBrickThirdScript); thirdScript.addBrick(ifBeginBrickThirdScript); thirdScript.addBrick(new ChangeVariableBrick(1.0f)); thirdScript.addBrick(ifElseBrickThirdScript); thirdScript.addBrick(ifEndBrickThirdScript); project.addSprite(thirdSprite); projectManager.setFileChecksumContainer(new FileChecksumContainer()); projectManager.setProject(project); projectManager.setCurrentSprite(firstSprite); projectManager.setCurrentScript(thirdScript); return setVariableBrick; } public static enum FileTypes { IMAGE, SOUND, ROOT } // Suppress default constructor for noninstantiability private UiTestUtils() { throw new AssertionError(); } public static ProjectManager getProjectManager() { return projectManager; } public static void enterText(Solo solo, int editTextIndex, String text) { solo.sleep(50); final EditText editText = solo.getEditText(editTextIndex); solo.getCurrentActivity().runOnUiThread(new Runnable() { public void run() { editText.setInputType(InputType.TYPE_NULL); } }); solo.clearEditText(editTextIndex); solo.enterText(editTextIndex, text); solo.sleep(50); } /** * Clicks on the EditText given by editTextId, inserts the integer value and closes the Dialog * * @param value The value you want to put into the EditText */ public static void insertIntegerIntoEditText(Solo solo, int value) { insertValue(solo, value + ""); } /** * Clicks on the EditText given by editTextId, inserts the double value and closes the Dialog * * @param value The value you want to put into the EditText */ public static void insertDoubleIntoEditText(Solo solo, double value) { insertValue(solo, value + ""); } public static void insertStringIntoEditText(Solo solo, String newValue) { solo.clickOnView(solo.getView(R.id.formula_editor_keyboard_string)); UiTestUtils.clickEnterClose(solo, 0, newValue); } private static void insertValue(Solo solo, String value) { for (char item : value.toCharArray()) { switch (item) { case '-': solo.clickOnView(solo.getView(R.id.formula_editor_keyboard_minus)); break; case '0': solo.clickOnView(solo.getView(R.id.formula_editor_keyboard_0)); break; case '1': solo.clickOnView(solo.getView(R.id.formula_editor_keyboard_1)); break; case '2': solo.clickOnView(solo.getView(R.id.formula_editor_keyboard_2)); break; case '3': solo.clickOnView(solo.getView(R.id.formula_editor_keyboard_3)); break; case '4': solo.clickOnView(solo.getView(R.id.formula_editor_keyboard_4)); break; case '5': solo.clickOnView(solo.getView(R.id.formula_editor_keyboard_5)); break; case '6': solo.clickOnView(solo.getView(R.id.formula_editor_keyboard_6)); break; case '7': solo.clickOnView(solo.getView(R.id.formula_editor_keyboard_7)); break; case '8': solo.clickOnView(solo.getView(R.id.formula_editor_keyboard_8)); break; case '9': solo.clickOnView(solo.getView(R.id.formula_editor_keyboard_9)); break; case '.': case ',': solo.clickOnView(solo.getView(R.id.formula_editor_keyboard_decimal_mark)); } } } public static void createUserVariableFromDataFragment(Solo solo, String variableName, boolean forAllSprites) { assertTrue("FormulaEditorDataFragment not shown: ", solo.waitForFragmentByTag(FormulaEditorDataFragment.USER_DATA_TAG)); solo.clickOnView(solo.getView(R.id.button_add)); assertTrue("Add Data Dialog not shown", solo.waitForText(solo.getString(R.string.formula_editor_data_dialog_title))); solo.waitForView(solo.getView(R.id.dialog_formula_editor_data_name_edit_text)); EditText editText = (EditText) solo.getView(R.id.dialog_formula_editor_data_name_edit_text); solo.enterText(editText, variableName); if (forAllSprites) { solo.waitForView(solo.getView(R.id.dialog_formula_editor_data_name_global_variable_radio_button)); solo.clickOnView(solo.getView(R.id.dialog_formula_editor_data_name_global_variable_radio_button)); } else { solo.waitForView(solo.getView(R.id.dialog_formula_editor_data_name_local_variable_radio_button)); solo.clickOnView(solo.getView(R.id.dialog_formula_editor_data_name_local_variable_radio_button)); } solo.clickOnButton(solo.getString(R.string.ok)); } public static void createUserListFromDataFragment(Solo solo, String userListName, boolean forAllSprites) { assertTrue("FormulaEditorDataFragment not shown: ", solo.waitForFragmentByTag(FormulaEditorDataFragment.USER_DATA_TAG)); solo.clickOnView(solo.getView(R.id.button_add)); assertTrue("Add Data Dialog not shown", solo.waitForText(solo.getString(R.string.formula_editor_data_dialog_title))); solo.waitForView(solo.getView(R.id.dialog_formula_editor_data_name_edit_text)); solo.clickOnView(solo.getView(R.id.dialog_formula_editor_data_is_list_checkbox)); EditText editText = (EditText) solo.getView(R.id.dialog_formula_editor_data_name_edit_text); solo.enterText(editText, userListName); if (forAllSprites) { solo.waitForView(solo.getView(R.id.dialog_formula_editor_data_name_global_variable_radio_button)); solo.clickOnView(solo.getView(R.id.dialog_formula_editor_data_name_global_variable_radio_button)); } else { solo.waitForView(solo.getView(R.id.dialog_formula_editor_data_name_local_variable_radio_button)); solo.clickOnView(solo.getView(R.id.dialog_formula_editor_data_name_local_variable_radio_button)); } solo.clickOnButton(solo.getString(R.string.ok)); } /** * For bricks using the FormulaEditor. Tests starting the FE, entering a new number/formula and * ensures its set correctly to the bricks edit text field */ public static void testBrickWithFormulaEditor(Solo solo, Sprite sprite, int editTextId, double newValue, Brick.BrickField brickField, FormulaBrick theBrick) { solo.clickOnView(solo.getView(editTextId)); insertDoubleIntoEditText(solo, newValue); assertEquals("Text not updated within FormulaEditor", newValue, Double.parseDouble( ((EditText) solo.getView(R.id.formula_editor_edit_field)).getText().toString().replace(',', '.'))); solo.clickOnView(solo.getView(R.id.formula_editor_keyboard_ok)); solo.sleep(200); Formula formula = theBrick.getFormulaWithBrickField(brickField); try { assertEquals("Wrong text in field", newValue, formula.interpretDouble(sprite), 0.01f); } catch (InterpretationException interpretationException) { fail("Wrong text in field."); } assertEquals("Text not updated in the brick list", newValue, Double.parseDouble(((TextView) solo.getView(editTextId)).getText().toString().replace(',', '.')), 0.01f); } public static void testBrickWithFormulaEditor(Sprite sprite, Solo solo, int editTextId, String newValue, Brick.BrickField brickField, FormulaBrick theBrick) { solo.clickOnView(solo.getView(editTextId)); solo.sleep(200); insertStringIntoEditText(solo, newValue); solo.sleep(200); String formulaEditorString = ((EditText) solo.getView(R.id.formula_editor_edit_field)).getText().toString(); assertEquals("Text not updated within FormulaEditor", "\'" + newValue + "\'", formulaEditorString.substring(0, formulaEditorString.length() - 1)); solo.clickOnView(solo.getView(R.id.formula_editor_keyboard_ok)); solo.sleep(200); Formula formula = (Formula) theBrick.getFormulaWithBrickField(brickField); formulaEditorString = ((TextView) solo.getView(editTextId)).getText().toString(); try { assertEquals("Wrong text in field", newValue, formula.interpretString(sprite)); } catch (InterpretationException interpretationException) { fail("Wrong text in field."); } assertEquals("Text not updated in the brick list", "\'" + newValue + "\'", formulaEditorString.substring(0, formulaEditorString.length() - 1)); } public static void insertValueViaFormulaEditor(Solo solo, int editTextId, double value) { solo.clickOnView(solo.getView(editTextId)); UiTestUtils.insertDoubleIntoEditText(solo, value); assertEquals("Text not updated within FormulaEditor", value, Double.parseDouble( ((EditText) solo.getView(R.id.formula_editor_edit_field)).getText().toString().replace(',', '.'))); solo.clickOnView(solo.getView(R.id.formula_editor_keyboard_ok)); solo.sleep(200); } public static void clickEnterClose(Solo solo, int editTextNumber, String value) { solo.clickOnEditText(editTextNumber); solo.clearEditText(0); solo.enterText(0, value); String buttonPositiveText = solo.getString(R.string.ok); // if click is not successful, try workaround try { solo.clickOnText(buttonPositiveText); } catch (AssertionFailedError e) { solo.sendKey(Solo.ENTER); } solo.sleep(50); } public static void clickEnterClose(Solo solo, EditText editText, String value, int buttonIndex) { Log.v("debug", "Solo.Enter clickEnterClose"); solo.enterText(editText, value); solo.waitForText(solo.getString(R.string.ok)); solo.clickOnButton(buttonIndex); } private static void initBrickCategoryMap() { brickCategoryMap = new SparseIntArray(); //brickCategoryMap.put(R.string.brick_place_at_x, R.string.category_motion); brickCategoryMap.put(R.string.brick_set_x, R.string.category_motion); brickCategoryMap.put(R.string.brick_set_y, R.string.category_motion); brickCategoryMap.put(R.string.brick_change_x_by, R.string.category_motion); brickCategoryMap.put(R.string.brick_change_y_by, R.string.category_motion); brickCategoryMap.put(R.string.brick_go_back, R.string.category_motion); brickCategoryMap.put(R.string.brick_come_to_front, R.string.category_motion); brickCategoryMap.put(R.string.brick_if_on_edge_bounce, R.string.category_motion); //brickCategoryMap.put(R.string.brick_move_n_steps, R.string.category_motion); brickCategoryMap.put(R.string.brick_turn_left, R.string.category_motion); brickCategoryMap.put(R.string.brick_turn_right, R.string.category_motion); brickCategoryMap.put(R.string.brick_point_in_direction, R.string.category_motion); brickCategoryMap.put(R.string.brick_point_to, R.string.category_motion); brickCategoryMap.put(R.string.brick_glide, R.string.category_motion); brickCategoryMap.put(R.string.brick_set_look, R.string.category_looks); brickCategoryMap.put(R.string.brick_set_size_to, R.string.category_looks); brickCategoryMap.put(R.string.brick_change_size_by, R.string.category_looks); brickCategoryMap.put(R.string.brick_hide, R.string.category_looks); brickCategoryMap.put(R.string.brick_show, R.string.category_looks); brickCategoryMap.put(R.string.brick_set_transparency, R.string.category_looks); brickCategoryMap.put(R.string.brick_set_brightness, R.string.category_looks); brickCategoryMap.put(R.string.brick_change_brightness, R.string.category_looks); brickCategoryMap.put(R.string.brick_clear_graphic_effect, R.string.category_looks); //brickCategoryMap.put(R.string.brick_say, R.string.category_looks); //brickCategoryMap.put(R.string.brick_think, R.string.category_looks); brickCategoryMap.put(R.string.brick_play_sound, R.string.category_sound); brickCategoryMap.put(R.string.brick_stop_all_sounds, R.string.category_sound); brickCategoryMap.put(R.string.brick_set_volume_to, R.string.category_sound); brickCategoryMap.put(R.string.brick_change_volume_by, R.string.category_sound); brickCategoryMap.put(R.string.brick_speak, R.string.category_sound); brickCategoryMap.put(R.string.brick_when_started, R.string.category_control); brickCategoryMap.put(R.string.brick_when, R.string.category_control); brickCategoryMap.put(R.string.brick_wait, R.string.category_control); brickCategoryMap.put(R.string.brick_broadcast_receive, R.string.category_control); brickCategoryMap.put(R.string.brick_broadcast, R.string.category_control); brickCategoryMap.put(R.string.brick_broadcast_wait, R.string.category_control); brickCategoryMap.put(R.string.brick_note, R.string.category_control); brickCategoryMap.put(R.string.brick_forever, R.string.category_control); brickCategoryMap.put(R.string.brick_repeat, R.string.category_control); brickCategoryMap.put(R.string.brick_if_begin, R.string.category_control); brickCategoryMap.put(R.string.brick_change_variable, R.string.category_data); brickCategoryMap.put(R.string.brick_set_variable, R.string.category_data); brickCategoryMap.put(R.string.nxt_brick_motor_move, R.string.category_lego_nxt); } public static int getBrickCategory(Solo solo, int brickStringId) { if (brickCategoryMap == null) { initBrickCategoryMap(); } Integer brickCategoryid = brickCategoryMap.get(brickStringId); if (brickCategoryid == null) { String brickString = solo.getCurrentActivity().getString(brickStringId); throw new RuntimeException("No category was found for brick string \"" + brickString + "\".\n" + "Please check brick string or add brick string to category map"); } return brickCategoryMap.get(brickStringId); } public static void addNewBrick(Solo solo, int brickStringId) { int categoryStringId = getBrickCategory(solo, brickStringId); addNewBrick(solo, categoryStringId, brickStringId); } public static void addNewBrick(Solo solo, int categoryStringId, int brickStringId) { addNewBrick(solo, categoryStringId, brickStringId, 0); } public static void addNewBrick(Solo solo, int categoryStringId, int brickStringId, int nThElement) { String brickName = solo.getCurrentActivity().getString(brickStringId); addNewBrick(solo, categoryStringId, brickName, nThElement); } public static void addNewBrick(Solo solo, int categoryStringId, String brickName, int nThElement) { clickOnBottomBar(solo, R.id.button_add); solo.sleep(1000); clickOnBrickCategory(solo, solo.getCurrentActivity().getString(categoryStringId)); boolean fragmentAppeared = solo.waitForFragmentByTag(AddBrickFragment.ADD_BRICK_FRAGMENT_TAG, 5000); if (!fragmentAppeared) { fail("add brick fragment should appear"); } if (categoryStringId == R.string.category_user_bricks) { solo.sleep(300); clickOnBottomBar(solo, R.id.button_add); } solo.sleep(600); boolean succeeded = clickOnBrickInAddBrickFragment(solo, brickName, false); if (!succeeded) { fail(brickName + " should appear. Failed to scroll to find it."); } if (categoryStringId == R.string.category_user_bricks) { String stringOnAddToScriptButton = solo.getCurrentActivity() .getString(R.string.brick_context_dialog_add_to_script); if (!solo.waitForText(stringOnAddToScriptButton, 0, 2000)) { fail("Text '" + stringOnAddToScriptButton + "' not shown in 5 secs!"); } solo.clickOnText(stringOnAddToScriptButton); } solo.sleep(600); } public static void deleteFirstUserBrick(Solo solo, String brickName) { boolean fragmentAppeared = solo.waitForFragmentByTag(AddBrickFragment.ADD_BRICK_FRAGMENT_TAG, 5000); if (!fragmentAppeared) { fail("add brick fragment should appear"); } solo.sleep(600); UiTestUtils.openActionMode(solo, solo.getString(R.string.delete), R.id.delete, solo.getCurrentActivity()); solo.clickOnCheckBox(1); UiTestUtils.acceptAndCloseActionMode(solo); solo.clickOnButton(solo.getString(R.string.yes)); } public static void clickOnBrickCategory(Solo solo, String category) { if (!solo.waitForText(category, 0, 300)) { solo.drag(40, 40, 300, 40, DRAG_FRAMES); } solo.clickOnText(category); } public static void showSourceAndEditBrick(String brickName, Solo solo) { showSourceAndEditBrick(brickName, true, solo); } public static void showSourceAndEditBrick(String brickName, boolean click, Solo solo) { if (click) { solo.clickOnText(UiTestUtils.TEST_USER_BRICK_NAME); } String stringOnShowSourceButton = solo.getCurrentActivity() .getString(R.string.brick_context_dialog_show_source); solo.waitForText(stringOnShowSourceButton); solo.clickOnText(stringOnShowSourceButton); boolean addBrickShowedUp = solo.waitForFragmentByTag(AddBrickFragment.ADD_BRICK_FRAGMENT_TAG, 2000); if (!addBrickShowedUp) { fail("addBrickFragment should have showed up"); } solo.sleep(1000); // if (brickName.equals(UiTestUtils.TEST_USER_BRICK_NAME)) { // clickOnBottomBar(solo, R.id.button_add); // } boolean clicked = UiTestUtils.clickOnBrickInAddBrickFragment(solo, brickName, false); if (!clicked) { fail("was unable to click on " + brickName + "!"); } String stringOnEditButton = solo.getCurrentActivity().getString(R.string.brick_context_dialog_edit_brick); boolean editButtonShowedUp = solo.waitForText(stringOnEditButton, 0, 3000); if (!editButtonShowedUp) { fail(stringOnEditButton + " should have showed up"); } solo.clickOnText(stringOnEditButton); boolean activityShowedUp = solo.waitForActivity(UserBrickScriptActivity.class, 3000); if (!activityShowedUp) { fail("UserBrickScriptActivity should have showed up"); } solo.sleep(50); } public static boolean clickOnBrickInAddBrickFragment(Solo solo, String brickName, boolean addToScript) { boolean success = false; int lowestIdTimeBeforeLast = -2; int lowestIdLastTime = -1; while (!success && lowestIdLastTime != lowestIdTimeBeforeLast) { lowestIdTimeBeforeLast = lowestIdLastTime; int farthestDownThisTime = -999999; int highestUpThisTime = 999999; ArrayList<TextView> array = solo.getCurrentViews(TextView.class); for (TextView candidate : array) { View greatGreatGrandParent = greatGreatGrandParent(candidate); if (greatGreatGrandParent != null && greatGreatGrandParent.getId() == R.id.add_brick_fragment_list) { int bottom = getBottomOfBrickGivenViewInsideThatBrick(candidate); if (farthestDownThisTime < bottom) { farthestDownThisTime = bottom; lowestIdLastTime = candidate.getId(); } if (highestUpThisTime > bottom) { highestUpThisTime = bottom; } if (candidate.getText().toString().equals(brickName)) { solo.sleep(500); solo.clickOnView(candidate); success = true; break; } } } if (!success) { int difference = farthestDownThisTime - highestUpThisTime; solo.drag(40, 40, difference * 0.75f, 40, DRAG_FRAMES); } } return success; } private static int getBottomOfBrickGivenViewInsideThatBrick(View view) { return ((View) (view.getParent().getParent())).getBottom(); } private static View greatGreatGrandParent(View view) { ViewParent parent = view.getParent(); int i = 0; while (i < 3 && parent != null) { parent = parent.getParent(); i++; } return (parent != null && parent instanceof View ? ((View) parent) : null); } public static int[] tapFloatingBrick(Solo solo) { return dragFloatingBrick(solo, 0); } public static int[] dragFloatingBrickUpwards(Solo solo) { return dragFloatingBrick(solo, -1); } public static int[] dragFloatingBrickUpwards(Solo solo, int bricks) { return dragFloatingBrick(solo, -bricks); } public static int[] dragFloatingBrickDownwards(Solo solo) { return dragFloatingBrick(solo, 1); } public static int[] dragFloatingBrickDownwards(Solo solo, int bricks) { return dragFloatingBrick(solo, bricks); } public static int[] dragFloatingBrick(Solo solo, float offsetY) { int[] location = null; int width = 0; int height = 0; ArrayList<View> views = solo.getCurrentViews(); for (View view : views) { if (view.getId() == R.id.drag_and_drop_list_view_image_view) { location = new int[2]; view.getLocationOnScreen(location); width = view.getWidth(); height = view.getHeight(); } } if (location == null) { return null; } int originX = location[0] + Math.round(width * 0.2f); int originY = location[1] + Math.round(height * 0.5f); int destinationX = originX; int destinationY = Math.round(originY + height * offsetY); solo.drag(originX, destinationX, originY, destinationY, DRAG_FRAMES); solo.sleep(1000); location[0] = destinationX; location[1] = destinationY; return location; } public static List<Brick> createTestProjectWithTwoSprites(String projectName) { int xPosition = 457; int yPosition = 598; double size = 0.8; Project project = new Project(null, projectName); Sprite firstSprite = new Sprite("cat"); Sprite secondSprite = new Sprite("second_sprite"); Script testScript = new StartScript(); ArrayList<Brick> brickList = new ArrayList<Brick>(); brickList.add(new HideBrick()); brickList.add(new ShowBrick()); brickList.add(new SetSizeToBrick(size)); brickList.add(new GoNStepsBackBrick(1)); brickList.add(new ComeToFrontBrick()); brickList.add(new PlaceAtBrick(xPosition, yPosition)); for (Brick brick : brickList) { testScript.addBrick(brick); } firstSprite.addScript(testScript); project.addSprite(firstSprite); project.addSprite(secondSprite); projectManager.setFileChecksumContainer(new FileChecksumContainer()); projectManager.setProject(project); projectManager.setCurrentSprite(firstSprite); projectManager.setCurrentScript(testScript); StorageHandler.getInstance().saveProject(project); // the application version is needed when the project will be uploaded // 0.7.3beta is the lowest possible version currently accepted by the web Reflection.setPrivateField(project.getXmlHeader(), "applicationVersion", "0.7.3beta"); return brickList; } public static List<Brick> createTestProject(String projectName) { int xPosition = 457; int yPosition = 598; double size = 0.8; Project project = new Project(null, projectName); Sprite firstSprite = new Sprite("cat"); Script testScript = new StartScript(); ArrayList<Brick> brickList = new ArrayList<Brick>(); brickList.add(new HideBrick()); brickList.add(new ShowBrick()); brickList.add(new SetSizeToBrick(size)); brickList.add(new GoNStepsBackBrick(1)); brickList.add(new ComeToFrontBrick()); brickList.add(new PlaceAtBrick(xPosition, yPosition)); for (Brick brick : brickList) { testScript.addBrick(brick); } firstSprite.addScript(testScript); project.addSprite(firstSprite); projectManager.setFileChecksumContainer(new FileChecksumContainer()); projectManager.setProject(project); projectManager.setCurrentSprite(firstSprite); projectManager.setCurrentScript(testScript); StorageHandler.getInstance().saveProject(project); // the application version is needed when the project will be uploaded // 0.7.3beta is the lowest possible version currently accepted by the web Reflection.setPrivateField(project.getXmlHeader(), "applicationVersion", "0.7.3beta"); return brickList; } public static List<Brick> createTestProject() { return createTestProject(DEFAULT_TEST_PROJECT_NAME); } public static List<Brick> createTestProjectNestedLoops() { Project project = new Project(null, DEFAULT_TEST_PROJECT_NAME); Sprite firstSprite = new Sprite("cat"); Script testScript = new StartScript(); ArrayList<Brick> brickList = new ArrayList<Brick>(); ForeverBrick firstForeverBrick = new ForeverBrick(); ForeverBrick secondForeverBrick = new ForeverBrick(); brickList.add(firstForeverBrick); brickList.add(new ShowBrick()); brickList.add(secondForeverBrick); brickList.add(new ComeToFrontBrick()); brickList.add(new LoopEndBrick(secondForeverBrick)); brickList.add(new LoopEndBrick(firstForeverBrick)); for (Brick brick : brickList) { testScript.addBrick(brick); } firstSprite.addScript(testScript); project.addSprite(firstSprite); projectManager.setFileChecksumContainer(new FileChecksumContainer()); projectManager.setProject(project); projectManager.setCurrentSprite(firstSprite); projectManager.setCurrentScript(testScript); return brickList; } public static List<Brick> createTestProjectWithUserBrick() { int xPosition = 457; int yPosition = 598; double size = 0.8; Project project = new Project(null, DEFAULT_TEST_PROJECT_NAME); Sprite firstSprite = new Sprite("cat"); Script testScript = new StartScript(); projectManager.setProject(project); projectManager.setCurrentSprite(firstSprite); projectManager.setCurrentScript(testScript); ArrayList<Brick> brickList = new ArrayList<Brick>(); brickList.add(new HideBrick()); brickList.add(new ShowBrick()); brickList.add(new SetSizeToBrick(size)); brickList.add(new GoNStepsBackBrick(1)); brickList.add(new ComeToFrontBrick()); brickList.add(new PlaceAtBrick(xPosition, yPosition)); for (Brick brick : brickList) { testScript.addBrick(brick); } firstSprite.addScript(testScript); UserBrick firstUserBrick = new UserBrick(0); firstSprite.addUserBrick(firstUserBrick); firstUserBrick.getDefinitionBrick().addUIText(TEST_USER_BRICK_NAME); firstUserBrick.getDefinitionBrick().addUILocalizedVariable(TEST_USER_BRICK_VARIABLE); firstUserBrick.appendBrickToScript(new ChangeXByNBrick(BrickValues.CHANGE_X_BY)); testScript.addBrick(firstUserBrick); project.addSprite(firstSprite); projectManager.setFileChecksumContainer(new FileChecksumContainer()); StorageHandler.getInstance().saveProject(project); return brickList; } public static void createTestProjectWithNestedUserBrick() { Project project = new Project(null, DEFAULT_TEST_PROJECT_NAME); Sprite firstSprite = new Sprite("cat"); Script testScript = new StartScript(); projectManager.setProject(project); projectManager.setCurrentSprite(firstSprite); projectManager.setCurrentScript(testScript); UserBrick firstUserBrick = new UserBrick(0); firstUserBrick.getDefinitionBrick().addUIText(TEST_USER_BRICK_NAME + "2"); firstUserBrick.getDefinitionBrick().addUILocalizedVariable(TEST_USER_BRICK_VARIABLE + "2"); firstUserBrick.appendBrickToScript(new ChangeXByNBrick(BrickValues.CHANGE_X_BY)); firstSprite.addUserBrick(firstUserBrick); UserBrick secondUserBrick = new UserBrick(1); secondUserBrick.getDefinitionBrick().addUIText(TEST_USER_BRICK_NAME); secondUserBrick.getDefinitionBrick().addUILocalizedVariable(TEST_USER_BRICK_VARIABLE); secondUserBrick.appendBrickToScript(firstUserBrick); secondUserBrick.appendBrickToScript(new ChangeYByNBrick(BrickValues.CHANGE_Y_BY)); testScript.addBrick(secondUserBrick); testScript.addBrick(new SetSizeToBrick(BrickValues.SET_SIZE_TO)); testScript.addBrick(new SetVariableBrick(BrickValues.SET_BRIGHTNESS_TO)); firstSprite.addUserBrick(secondUserBrick); firstSprite.addScript(testScript); project.addSprite(firstSprite); projectManager.setFileChecksumContainer(new FileChecksumContainer()); StorageHandler.getInstance().saveProject(project); } public static List<Brick> createTestProjectIfBricks() { Project project = new Project(null, DEFAULT_TEST_PROJECT_NAME); Sprite firstSprite = new Sprite("cat"); Script testScript = new StartScript(); ArrayList<Brick> brickList = new ArrayList<Brick>(); IfLogicBeginBrick ifBeginBrick = new IfLogicBeginBrick(0); IfLogicElseBrick ifElseBrick = new IfLogicElseBrick(ifBeginBrick); IfLogicEndBrick ifEndBrick = new IfLogicEndBrick(ifElseBrick, ifBeginBrick); brickList.add(ifBeginBrick); brickList.add(new ShowBrick()); brickList.add(ifElseBrick); brickList.add(new ComeToFrontBrick()); brickList.add(ifEndBrick); for (Brick brick : brickList) { testScript.addBrick(brick); } firstSprite.addScript(testScript); project.addSprite(firstSprite); projectManager.setFileChecksumContainer(new FileChecksumContainer()); projectManager.setProject(project); projectManager.setCurrentSprite(firstSprite); projectManager.setCurrentScript(testScript); return brickList; } public static List<Brick> createTestProjectWithEveryBrick() { Project project = new Project(null, DEFAULT_TEST_PROJECT_NAME); Sprite firstSprite = new Sprite("cat"); Script testScript = new StartScript(); ArrayList<Brick> brickList = new ArrayList<Brick>(); brickList.add(new BroadcastBrick("broadcastMessage1")); brickList.add(new BroadcastWaitBrick("broadcastMessage2")); brickList.add(new ChangeBrightnessByNBrick(0)); brickList.add(new ChangeTransparencyByNBrick(0)); brickList.add(new ChangeSizeByNBrick(0)); brickList.add(new ChangeVolumeByNBrick(0)); brickList.add(new ChangeVariableBrick(0)); brickList.add(new ChangeXByNBrick(0)); brickList.add(new ChangeYByNBrick(0)); brickList.add(new ClearGraphicEffectBrick()); brickList.add(new ComeToFrontBrick()); brickList.add(new GlideToBrick(0, 0, 0)); brickList.add(new GoNStepsBackBrick(0)); brickList.add(new HideBrick()); brickList.add(new IfOnEdgeBounceBrick()); brickList.add(new MoveNStepsBrick(0)); brickList.add(new NextLookBrick()); brickList.add(new NoteBrick("")); brickList.add(new PlaceAtBrick(0, 0)); brickList.add(new PlaySoundBrick()); brickList.add(new PointInDirectionBrick(Direction.DOWN)); brickList.add(new PointToBrick(firstSprite)); brickList.add(new SetBrightnessBrick(0)); brickList.add(new SetTransparencyBrick(0)); brickList.add(new SetLookBrick()); brickList.add(new SetSizeToBrick(0)); brickList.add(new SetVariableBrick(0)); brickList.add(new SetVolumeToBrick(0)); brickList.add(new SetXBrick(0)); brickList.add(new SetYBrick(0)); brickList.add(new ShowBrick()); brickList.add(new SpeakBrick("")); brickList.add(new StopAllSoundsBrick()); brickList.add(new TurnLeftBrick(0)); brickList.add(new TurnRightBrick(0)); brickList.add(new WaitBrick(0)); for (Brick brick : brickList) { testScript.addBrick(brick); } firstSprite.addScript(testScript); project.addSprite(firstSprite); projectManager.setFileChecksumContainer(new FileChecksumContainer()); projectManager.setProject(project); projectManager.setCurrentSprite(firstSprite); projectManager.setCurrentScript(testScript); return brickList; } public static void createTestProjectForActionModeDelete() { Project project = new Project(null, DEFAULT_TEST_PROJECT_NAME); Sprite firstSprite = new Sprite("cat"); Script firstScript = new StartScript(); ArrayList<Brick> firstBrickList = new ArrayList<Brick>(); firstBrickList.add(new HideBrick()); firstBrickList.add(new ShowBrick()); for (Brick brick : firstBrickList) { firstScript.addBrick(brick); } Script secondScript = new WhenScript(); ArrayList<Brick> secondBrickList = new ArrayList<Brick>(); secondBrickList.add(new HideBrick()); secondBrickList.add(new ShowBrick()); for (Brick brick : secondBrickList) { secondScript.addBrick(brick); } firstSprite.addScript(firstScript); firstSprite.addScript(secondScript); project.addSprite(firstSprite); projectManager.setFileChecksumContainer(new FileChecksumContainer()); projectManager.setProject(project); projectManager.setCurrentSprite(firstSprite); projectManager.setCurrentScript(firstScript); } public static void createEmptyProject() { Project project = new Project(null, DEFAULT_TEST_PROJECT_NAME); Sprite firstSprite = new Sprite("cat"); Script testScript = new StartScript(); firstSprite.addScript(testScript); project.addSprite(firstSprite); projectManager.setFileChecksumContainer(new FileChecksumContainer()); projectManager.setProject(project); projectManager.setCurrentSprite(firstSprite); projectManager.setCurrentScript(testScript); } /** * saves a file into the project folder * if project == null or "" file will be saved into Catroid folder * * @param project Folder where the file will be saved, this folder should exist * @param name Name of the file * @param fileID the id of the file --> needs the right context * @param context * @param type type of the file: 0 = imagefile, 1 = soundfile * @return the file * @throws IOException */ public static File saveFileToProject(String project, String name, int fileID, Context context, FileTypes type) { boolean withChecksum = true; String filePath; if (project == null || project.equalsIgnoreCase("")) { filePath = Constants.DEFAULT_ROOT + "/"; } else { switch (type) { case IMAGE: filePath = Constants.DEFAULT_ROOT + "/" + project + "/" + Constants.IMAGE_DIRECTORY + "/"; break; case SOUND: filePath = Constants.DEFAULT_ROOT + "/" + project + "/" + Constants.SOUND_DIRECTORY + "/"; break; case ROOT: filePath = Constants.DEFAULT_ROOT + "/" + project + "/"; withChecksum = false; break; default: filePath = Constants.DEFAULT_ROOT + "/"; break; } } BufferedInputStream in = new BufferedInputStream(context.getResources().openRawResource(fileID), Constants.BUFFER_8K); try { File file = new File(filePath + name); file.getParentFile().mkdirs(); file.createNewFile(); BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file), Constants.BUFFER_8K); byte[] buffer = new byte[Constants.BUFFER_8K]; int length = 0; while ((length = in.read(buffer)) > 0) { out.write(buffer, 0, length); } in.close(); out.flush(); out.close(); String checksum; if (withChecksum) { checksum = Utils.md5Checksum(file) + "_"; } else { checksum = ""; } File tempFile = new File(filePath + checksum + name); file.renameTo(tempFile); return tempFile; } catch (IOException e) { Log.e(TAG, "File handling error", e); return null; } } public static boolean clearProject(String projectname) { File directory = new File(Constants.DEFAULT_ROOT + "/" + projectname); if (directory.exists()) { return UtilFile.deleteDirectory(directory); } return false; } public static Project createProject(String projectName, ArrayList<Sprite> spriteList, Context context) { Project project = new Project(context, projectName); StorageHandler.getInstance().saveProject(project); ProjectManager.getInstance().setProject(project); for (Sprite sprite : spriteList) { ProjectManager.getInstance().addSprite(sprite); } StorageHandler.getInstance().saveProject(project); return project; } public static void createProjectForCopySprite(String projectName, Context context) { StorageHandler storageHandler = StorageHandler.getInstance(); Project project = new Project(context, projectName); Sprite firstSprite = new Sprite(context.getString(R.string.default_project_sprites_mole_name)); Sprite secondSprite = new Sprite("second_sprite"); Script firstSpriteScript = new StartScript(); ArrayList<Brick> brickList = new ArrayList<Brick>(); brickList.add(new PlaceAtBrick(11, 12)); brickList.add(new SetXBrick(13)); brickList.add(new SetYBrick(14)); brickList.add(new ChangeXByNBrick(15)); brickList.add(new ChangeXByNBrick(16)); brickList.add(new IfOnEdgeBounceBrick()); brickList.add(new MoveNStepsBrick(17)); brickList.add(new TurnLeftBrick(18)); brickList.add(new TurnRightBrick(19)); brickList.add(new PointToBrick(secondSprite)); brickList.add(new GlideToBrick(21, 22, 23)); brickList.add(new GoNStepsBackBrick(24)); brickList.add(new ComeToFrontBrick()); brickList.add(new SetLookBrick()); brickList.add(new SetSizeToBrick(11)); brickList.add(new ChangeSizeByNBrick(12)); brickList.add(new HideBrick()); brickList.add(new ShowBrick()); brickList.add(new SetTransparencyBrick(13)); brickList.add(new ChangeTransparencyByNBrick(14)); brickList.add(new SetBrightnessBrick(15)); brickList.add(new ChangeTransparencyByNBrick(16)); brickList.add(new ClearGraphicEffectBrick()); brickList.add(new NextLookBrick()); brickList.add(new PlaySoundBrick()); brickList.add(new StopAllSoundsBrick()); brickList.add(new SetVolumeToBrick(17)); brickList.add(new ChangeVolumeByNBrick(18)); brickList.add(new SpeakBrick("Hallo")); brickList.add(new WaitBrick(19)); brickList.add(new BroadcastWaitBrick("firstMessage")); brickList.add(new NoteBrick()); ForeverBrick foreverBrick = new ForeverBrick(); LoopEndBrick endBrick = new LoopEndBrick(foreverBrick); brickList.add(foreverBrick); brickList.add(endBrick); RepeatBrick repeatBrick = new RepeatBrick(20); endBrick = new LoopEndBrick(repeatBrick); brickList.add(repeatBrick); brickList.add(endBrick); brickList.add(new WaitBrick(1)); // create formula to test copying // ( 1 + global ) * local - COMPASS_DIRECTION FormulaElement numberElement = new FormulaElement(FormulaElement.ElementType.NUMBER, "1", null); FormulaElement bracesElement = new FormulaElement(FormulaElement.ElementType.BRACKET, null, null, null, numberElement); FormulaElement operatorElementPlus = new FormulaElement(FormulaElement.ElementType.OPERATOR, "PLUS", null); FormulaElement operatorElementMult = new FormulaElement(FormulaElement.ElementType.OPERATOR, "MULT", null); FormulaElement operatorElementMinus = new FormulaElement(FormulaElement.ElementType.OPERATOR, "MINUS", null); DataContainer variableContainer = project.getDataContainer(); variableContainer.addProjectUserVariable("global"); FormulaElement variableElementGlobal = new FormulaElement(FormulaElement.ElementType.USER_VARIABLE, "global", null); variableContainer.addSpriteUserVariableToSprite(firstSprite, "local"); FormulaElement variableElemetLocal = new FormulaElement(FormulaElement.ElementType.USER_VARIABLE, "local", null); FormulaElement sensorElemet = new FormulaElement(FormulaElement.ElementType.SENSOR, "COMPASS_DIRECTION", null); operatorElementPlus.setLeftChild(numberElement); operatorElementPlus.setRightChild(variableElementGlobal); bracesElement.setRightChild(operatorElementPlus); operatorElementMult.setLeftChild(bracesElement); operatorElementMult.setRightChild(variableElemetLocal); operatorElementMinus.setLeftChild(operatorElementMult); operatorElementMinus.setRightChild(sensorElemet); if (internTokenList.isEmpty()) { internTokenList.addAll(operatorElementMinus.getInternTokenList()); } Formula formula = new Formula(operatorElementMinus); IfLogicBeginBrick ifBeginBrick = new IfLogicBeginBrick(formula); IfLogicElseBrick ifElseBrick = new IfLogicElseBrick(ifBeginBrick); IfLogicEndBrick ifEndBrick = new IfLogicEndBrick(ifElseBrick, ifBeginBrick); brickList.add(ifBeginBrick); brickList.add(new SpeakBrick("Hello, I'm true!")); brickList.add(ifElseBrick); brickList.add(new SpeakBrick("Hallo, I'm false!")); brickList.add(ifEndBrick); for (Brick brick : brickList) { firstSpriteScript.addBrick(brick); } firstSprite.addScript(firstSpriteScript); BroadcastScript broadcastScript = new BroadcastScript("Hallo"); BroadcastReceiverBrick brickBroad = new BroadcastReceiverBrick(broadcastScript); firstSprite.addScript(broadcastScript); brickList.add(brickBroad); project.addSprite(firstSprite); project.addSprite(secondSprite); ProjectManager.getInstance().setFileChecksumContainer(new FileChecksumContainer()); ProjectManager.getInstance().setCurrentSprite(firstSprite); ProjectManager.getInstance().setCurrentScript(firstSpriteScript); storageHandler.saveProject(project); } public static List<InternToken> getInternTokenList() { return internTokenList; } public static void clearAllUtilTestProjects() { Log.v(TAG, "clearAllUtilTestProjects"); projectManager.setFileChecksumContainer(new FileChecksumContainer()); File directory = new File(Constants.DEFAULT_ROOT + "/" + PROJECTNAME1); if (directory.exists()) { UtilFile.deleteDirectory(directory); } directory = new File(Constants.DEFAULT_ROOT + "/" + PROJECTNAME2); if (directory.exists()) { UtilFile.deleteDirectory(directory); } directory = new File(Constants.DEFAULT_ROOT + "/" + PROJECTNAME3); if (directory.exists()) { UtilFile.deleteDirectory(directory); } directory = new File(Constants.DEFAULT_ROOT + "/" + DEFAULT_TEST_PROJECT_NAME); if (directory.exists()) { UtilFile.deleteDirectory(directory); } directory = new File(Constants.DEFAULT_ROOT + "/" + "defaultProject"); if (directory.exists()) { UtilFile.deleteDirectory(directory); } directory = new File(Constants.DEFAULT_ROOT + "/" + "standardProjekt"); if (directory.exists()) { UtilFile.deleteDirectory(directory); } directory = new File(Constants.DEFAULT_ROOT + "/" + "My first project"); if (directory.exists()) { UtilFile.deleteDirectory(directory); } directory = new File(Constants.DEFAULT_ROOT + "/" + "Mein erstes Projekt"); if (directory.exists()) { UtilFile.deleteDirectory(directory); } directory = new File(Constants.DEFAULT_ROOT + "/" + "My first program"); if (directory.exists()) { UtilFile.deleteDirectory(directory); } directory = new File(Constants.DEFAULT_ROOT + "/" + "Mein erstes Programm"); if (directory.exists()) { UtilFile.deleteDirectory(directory); } directory = new File(Constants.DEFAULT_ROOT + "/" + "Project"); if (directory.exists()) { UtilFile.deleteDirectory(directory); } directory = new File(Constants.DEFAULT_ROOT + "/" + DEFAULT_TEST_PROJECT_NAME_MIXED_CASE); if (directory.exists()) { UtilFile.deleteDirectory(directory); } directory = new File(Constants.DEFAULT_ROOT + "/" + COPIED_PROJECT_NAME); if (directory.exists()) { UtilFile.deleteDirectory(directory); } directory = new File(Constants.DEFAULT_ROOT + "/" + JAPANESE_PROJECT_NAME); if (directory.exists()) { UtilFile.deleteDirectory(directory); } } public static void clickOnActionBar(Solo solo, int imageButtonId) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { solo.waitForView(LinearLayout.class); LinearLayout linearLayout = (LinearLayout) solo.getView(imageButtonId); solo.clickOnView(linearLayout); } else { solo.clickOnActionBarItem(imageButtonId); } } /** * This method can be used in 2 ways. Either to click on an action item * (icon), or to click on an item in the overflow menu. So either pass a * String + ID --OR-- a String + 0. * * @param solo Use Robotium functionality * @param overflowMenuItemName Name of the overflow menu item */ public static void openActionMode(Solo solo, String overflowMenuItemName, int menuItemId, Activity activity) { solo.sleep(1000); ArrayList<View> views = solo.getCurrentViews(); ArrayList<Integer> ids = new ArrayList<Integer>(); for (View view : views) { ids.add(view.getId()); } if (ids.contains(menuItemId)) { solo.waitForView(menuItemId, 0, 20000, false); UiTestUtils.clickOnActionBar(solo, menuItemId); } else if (overflowMenuItemName != null) { solo.waitForText(overflowMenuItemName, 0, 20000, false); solo.clickOnMenuItem(overflowMenuItemName, true); } else { fail("Cannot click on element with menuItemid " + menuItemId + " or overflowMenuItemName " + overflowMenuItemName); } solo.sleep(400); } public static void acceptAndCloseActionMode(Solo solo) { View doneButton; if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { doneButton = solo .getView(Resources.getSystem().getIdentifier("action_mode_close_button", "id", "android")); } else { doneButton = solo.getCurrentActivity().findViewById(R.id.abs__action_mode_close_button); } solo.clickOnView(doneButton); solo.sleep(200); } /** * Due to maintainability reasons you should use this method to open an options menu.The way to open an options menu * might differ in future. */ public static void openOptionsMenu(Solo solo) { solo.sendKey(Solo.MENU); solo.sleep(200); } public static void clickOnBottomBar(Solo solo, int buttonId) { solo.waitForView(ImageButton.class); ImageButton imageButton = (ImageButton) solo.getView(buttonId); solo.clickOnView(imageButton); } public static void clickOnPlayButton(Solo solo) { clickOnBottomBar(solo, R.id.button_play); } public static File createTestMediaFile(String filePath, int fileID, Context context) throws IOException { File testImage = new File(filePath); if (!testImage.exists()) { testImage.createNewFile(); } InputStream in = context.getResources().openRawResource(fileID); OutputStream out = new BufferedOutputStream(new FileOutputStream(testImage), Constants.BUFFER_8K); byte[] buffer = new byte[Constants.BUFFER_8K]; int length = 0; while ((length = in.read(buffer)) > 0) { out.write(buffer, 0, length); } in.close(); out.flush(); out.close(); return testImage; } public static void createValidUser(Context context) { try { String testUser = "testUser" + System.currentTimeMillis(); String testPassword = "pwspws"; String testEmail = testUser + "@gmail.com"; String token = Constants.NO_TOKEN; boolean userRegistered = ServerCalls.getInstance().registerOrCheckToken(testUser, testPassword, testEmail, "de", "at", token, context); assert userRegistered; } catch (WebconnectionException e) { Log.e(TAG, "Error creating test user.", e); fail("Error creating test user."); } } // Stage methods public static void compareByteArrays(byte[] firstArray, byte[] secondArray) { assertEquals("Length of byte arrays not equal", firstArray.length, secondArray.length); assertEquals("Arrays don't have same content.", firstArray[0] & 0xFF, secondArray[0] & 0xFF, 10); assertEquals("Arrays don't have same content.", firstArray[1] & 0xFF, secondArray[1] & 0xFF, 10); assertEquals("Arrays don't have same content.", firstArray[2] & 0xFF, secondArray[2] & 0xFF, 10); assertEquals("Arrays don't have same content.", firstArray[3] & 0xFF, secondArray[3] & 0xFF, 10); } public static boolean comparePixelRgbaArrays(byte[] firstArray, byte[] secondArray) { if (firstArray == null || secondArray == null || firstArray.length != secondArray.length) { return false; } for (int i = 0; i < 4; i++) { if (Math.abs((firstArray[0] & 0xFF) - (secondArray[0] & 0xFF)) > 10) { return false; } } return true; } /** * Returns the absolute pixel y coordinates of elements from a listview */ public static ArrayList<Integer> getListItemYPositions(final Solo solo) { return getListItemYPositions(solo, 0); } /** * Returns the absolute pixel y coordinates of elements from a listview * with a given index */ public static ArrayList<Integer> getListItemYPositions(final Solo solo, int listViewIndex) { ArrayList<Integer> yPositionList = new ArrayList<Integer>(); if (!solo.waitForView(ListView.class, 0, 10000, false)) { fail("ListView not shown in 10 secs!"); } ArrayList<ListView> listViews = solo.getCurrentViews(ListView.class); if (listViews.size() <= listViewIndex) { fail("Listview Index wrong"); } ListView listView = listViews.get(listViewIndex); for (int i = 0; i < listView.getChildCount(); ++i) { View currentViewInList = listView.getChildAt(i); Rect globalVisibleRectangle = new Rect(); currentViewInList.getGlobalVisibleRect(globalVisibleRectangle); int middleYPosition = globalVisibleRectangle.top + globalVisibleRectangle.height() / 2; yPositionList.add(middleYPosition); } return yPositionList; } public static int getAddedListItemYPosition(Solo solo) { ArrayList<Integer> yPositionsList = getListItemYPositions(solo, 0); int middleYPositionIndex = yPositionsList.size() / 2; return yPositionsList.get(middleYPositionIndex); } public static void longClickAndDrag(final Solo solo, final float xFrom, final float yFrom, final float xTo, final float yTo, final int steps) { final Activity activity = solo.getCurrentActivity(); Handler handler = new Handler(activity.getMainLooper()); handler.post(new Runnable() { public void run() { MotionEvent downEvent = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, xFrom, yFrom, 0); activity.dispatchTouchEvent(downEvent); downEvent.recycle(); } }); solo.sleep(ViewConfiguration.getLongPressTimeout() + 200); handler.post(new Runnable() { public void run() { double offsetX = xTo - xFrom; offsetX /= steps; double offsetY = yTo - yFrom; offsetY /= steps; for (int i = 0; i <= steps; i++) { float x = xFrom + (float) (offsetX * i); float y = yFrom + (float) (offsetY * i); MotionEvent moveEvent = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, x, y, 0); activity.dispatchTouchEvent(moveEvent); solo.sleep(20); moveEvent.recycle(); } } }); solo.sleep(steps * 20 + 200); handler.post(new Runnable() { public void run() { MotionEvent upEvent = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, xTo, yTo, 0); activity.dispatchTouchEvent(upEvent); upEvent.recycle(); Log.d(TAG, "longClickAndDrag finished: " + (int) yTo); } }); solo.sleep(1000); } private static class ProjectWithCatrobatLanguageVersion extends Project { static final long serialVersionUID = 1L; private final float catrobatLanguageVersion; public ProjectWithCatrobatLanguageVersion(String name, float catrobatLanguageVersion) { super(null, name); this.catrobatLanguageVersion = catrobatLanguageVersion; } @Override public float getCatrobatLanguageVersion() { return catrobatLanguageVersion; } } public static boolean createTestProjectOnLocalStorageWithCatrobatLanguageVersion( float catrobatLanguageVersion) { Project project = new ProjectWithCatrobatLanguageVersion(DEFAULT_TEST_PROJECT_NAME, catrobatLanguageVersion); Sprite firstSprite = new Sprite("cat"); Script testScript = new StartScript(); firstSprite.addScript(testScript); project.addSprite(firstSprite); ProjectManager.getInstance().setFileChecksumContainer(new FileChecksumContainer()); ProjectManager.getInstance().setProject(project); ProjectManager.getInstance().setCurrentSprite(firstSprite); ProjectManager.getInstance().setCurrentScript(testScript); return StorageHandler.getInstance().saveProject(project); } public static void goToHomeActivity(Activity activity) { Intent intent = new Intent(activity, MainMenuActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); activity.startActivity(intent); } @TargetApi(Build.VERSION_CODES.HONEYCOMB) public static void clickOnHomeActionBarButton(Solo solo) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { Activity activity = solo.getCurrentActivity(); ActionMenuItem logoNavItem = new ActionMenuItem(activity, 0, android.R.id.home, 0, 0, ""); ActionBarSherlockCompat actionBarSherlockCompat = (ActionBarSherlockCompat) Reflection .invokeMethod(SherlockFragmentActivity.class, activity, "getSherlock"); actionBarSherlockCompat.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, logoNavItem); } else { solo.clickOnActionBarHomeButton(); } } public static void getIntoSpritesFromMainMenu(Solo solo) { Log.d("UiTestUtils", "waitForMainMenuActivity: " + solo.waitForActivity(MainMenuActivity.class.getSimpleName())); solo.sleep(300); String continueString = solo.getString(R.string.main_menu_continue); solo.waitForText(continueString); solo.clickOnText(continueString); solo.waitForActivity(ProjectActivity.class.getSimpleName()); solo.waitForView(ListView.class); } public static void getIntoProgramMenuFromMainMenu(Solo solo, int spriteIndex) { getIntoSpritesFromMainMenu(solo); solo.sleep(200); solo.clickInList(spriteIndex); solo.waitForActivity(ProgramMenuActivity.class.getSimpleName()); } public static void getIntoSoundsFromMainMenu(Solo solo) { getIntoSoundsFromMainMenu(solo, 0); } public static void getIntoSoundsFromMainMenu(Solo solo, int spriteIndex) { getIntoProgramMenuFromMainMenu(solo, spriteIndex); solo.clickOnText(solo.getString(R.string.sounds)); solo.waitForActivity(ScriptActivity.class.getSimpleName()); solo.waitForView(ListView.class); solo.sleep(200); } public static void getIntoLooksFromMainMenu(Solo solo) { getIntoLooksFromMainMenu(solo, 0, false); } public static void getIntoLooksFromMainMenu(Solo solo, boolean isBackground) { getIntoLooksFromMainMenu(solo, 0, isBackground); } public static void getIntoLooksFromMainMenu(Solo solo, int spriteIndex, boolean isBackground) { getIntoProgramMenuFromMainMenu(solo, spriteIndex); String textToClickOn = ""; if (isBackground) { textToClickOn = solo.getString(R.string.backgrounds); } else { textToClickOn = solo.getString(R.string.looks); } solo.clickOnText(textToClickOn); solo.waitForActivity(ScriptActivity.class.getSimpleName()); solo.waitForView(ListView.class); solo.sleep(200); } public static void getIntoScriptActivityFromMainMenu(Solo solo) { getIntoScriptActivityFromMainMenu(solo, 0); } public static void getIntoScriptActivityFromMainMenu(Solo solo, int spriteIndex) { getIntoProgramMenuFromMainMenu(solo, spriteIndex); solo.clickOnText(solo.getString(R.string.scripts)); solo.waitForActivity(ScriptActivity.class.getSimpleName()); solo.waitForView(ListView.class); solo.sleep(200); } public static boolean clickOnTextInList(Solo solo, String text) { solo.sleep(300); ArrayList<TextView> textViews = solo.getCurrentViews(TextView.class, solo.getView(android.R.id.list)); for (int textView = 0; textView < textViews.size(); textView++) { TextView view = textViews.get(textView); if (view.getText().toString().equalsIgnoreCase(text)) { solo.clickOnView(view); return true; } } return false; } public static boolean longClickOnTextInList(Solo solo, String text) { solo.waitForView(solo.getView(android.R.id.list)); ArrayList<TextView> textViews = solo.getCurrentViews(TextView.class); for (int position = 0; position < textViews.size(); position++) { TextView view = textViews.get(position); if (view.getText().toString().equalsIgnoreCase(text)) { solo.clickLongOnView(view); return true; } } return false; } public static void clickOnStageCoordinates(Solo solo, int x, int y, int screenWidth, int screenHeight) { solo.clickOnScreen(screenWidth / 2 + x, screenHeight / 2 - y); } /** * Returns to the main screen. * This method should be called in tearDown() in tests which use Robotium. * See explanation here: * http://stackoverflow.com/questions/7851351/robotium-in-the-suite-of-tests-each-next-test-is- * affected-by-the-previous-test */ public static void goBackToHome(Instrumentation instrumentation) { boolean more = true; while (more) { try { instrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK); instrumentation.waitForIdleSync(); } catch (SecurityException e) { // Done, at Home. more = false; } } } public static void cropImage(String pathToImageFile, int sampleSize) throws FileNotFoundException { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = sampleSize; Bitmap imageBitmap = BitmapFactory.decodeFile(pathToImageFile, options); File imageFile = new File(pathToImageFile); StorageHandler.saveBitmapToImageFile(imageFile, imageBitmap); } public static ListView getScriptListView(Solo solo) { ArrayList<ListView> listOfListViews = solo.getCurrentViews(ListView.class); assertTrue("no ListView found!", listOfListViews.size() > 0); return listOfListViews.get(0); } public static void waitForFragment(Solo solo, int fragmentRootLayoutId) { waitForFragment(solo, fragmentRootLayoutId, 5000); } public static void waitForFragment(Solo solo, int fragmentRootLayoutId, int timeout) { boolean fragmentFoundInTime = solo.waitForView(solo.getView(fragmentRootLayoutId), timeout, true); if (!fragmentFoundInTime) { fail("Fragment was not loaded"); } } public static View getViewContainerByIds(Solo solo, int id, int containerId) { View parent = solo.getView(containerId); List<View> views = solo.getViews(parent); for (View view : views) { if (view.getId() == id) { return view; } } return null; } public static View getViewContainerByString(Solo solo, String text, int containerId) { View parent = solo.getView(containerId); List<TextView> views = solo.getCurrentViews(TextView.class, parent); for (TextView view : views) { if (view.getText().equals(text)) { return view; } } return null; } public static View getViewContainerByString(String text, List<TextView> views) { for (TextView view : views) { if (view.getText().equals(text)) { return view; } } return null; } public static List<TextView> getViewsByParentId(Solo solo, int parentId) { View parent = solo.getView(parentId); return solo.getCurrentViews(TextView.class, parent); } public static void prepareStageForTest() { Reflection.setPrivateField(StageListener.class, "DYNAMIC_SAMPLING_RATE_FOR_ACTIONS", false); } /* * This is a workaround from this robotium issue * http://code.google.com/p/robotium/issues/detail?id=296 * * This method should be removed, when the issue is fixed in robotium! */ public static void clickOnButton(Solo solo, ActivityInstrumentationTestCase2<?> testCase, String buttonText) { final Button buttonWithinTheDialog = solo.getButton(buttonText); try { testCase.runTestOnUiThread(new Runnable() { public void run() { buttonWithinTheDialog.performClick(); } }); } catch (Throwable throwable) { Log.e("CATROID", throwable.getMessage()); } solo.sleep(500); } public static void waitForText(Solo solo, String text) { assertEquals("Text not found!", true, solo.waitForText(text, 0, 3000)); } public static void switchToFragmentInScriptActivity(Solo solo, int fragmentIndex) { solo.goBack(); solo.waitForActivity(ProgramMenuActivity.class); solo.clickOnButton(fragmentIndex); solo.waitForActivity(ScriptActivity.class); int id = FRAGMENT_INDEX_LIST.get(fragmentIndex); solo.waitForFragmentById(id); } public static void cancelAllNotifications(Context context) { NotificationManager notificationManager = (NotificationManager) context .getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.cancelAll(); @SuppressWarnings("unchecked") SparseArray<NotificationData> notificationMap = (SparseArray<NotificationData>) Reflection.getPrivateField( StatusBarNotificationManager.class, StatusBarNotificationManager.getInstance(), "notificationDataMap"); notificationMap.clear(); } public static boolean getContextMenuAndGoBackToCheckIfSelected(Solo solo, Activity activity, int buttonId, String buttonText, String listElementName) { longClickOnTextInList(solo, listElementName); solo.waitForText(buttonText); solo.goBack(); openActionMode(solo, buttonText, buttonId, activity); ArrayList<CheckBox> checkBoxList = solo.getCurrentViews(CheckBox.class); for (CheckBox checkBox : checkBoxList) { if (checkBox.isChecked()) { return true; } } return false; } public static boolean menuButtonVisible(Solo solo, int menuItemId) { ArrayList<View> views = solo.getCurrentViews(); for (View view : views) { if (view.getId() == menuItemId) { return true; } } return false; } public static File setUpLookFile(Solo solo) throws IOException { File lookFile = UiTestUtils.createTestMediaFile(Constants.DEFAULT_ROOT + "/testFile.png", R.drawable.default_project_mole_whacked, solo.getCurrentActivity()); return lookFile; } public static void showAndFilloutNewSpriteDialogWithoutClickingOk(Solo solo, String spriteName, File file, ActionAfterFinished actionToPerform, SpinnerAdapterWrapper spinner) { showAndFilloutNewSpriteDialogWithoutClickingOk(solo, spriteName, Uri.fromFile(file), actionToPerform, spinner); } public static void showAndFilloutNewSpriteDialogWithoutClickingOk(Solo solo, String spriteName, Uri uri, ActionAfterFinished actionToPerform, SpinnerAdapterWrapper spinner) { if (!(solo.getCurrentActivity() instanceof FragmentActivity)) { fail("Current activity is not a FragmentActivity"); } FragmentManager fragmentManager = ((FragmentActivity) solo.getCurrentActivity()) .getSupportFragmentManager(); NewSpriteDialog dialog; // create dialog and skip step 1 (choosing an image) try { Constructor<NewSpriteDialog> constructor = NewSpriteDialog.class.getDeclaredConstructor( DialogWizardStep.class, Uri.class, String.class, ActionAfterFinished.class, SpinnerAdapterWrapper.class); constructor.setAccessible(true); dialog = constructor.newInstance(DialogWizardStep.STEP_2, uri, spriteName, actionToPerform, spinner); } catch (Exception e) { Log.e(TAG, "Reflection failure.", e); fail("Reflection failure"); return; } dialog.show(fragmentManager, NewSpriteDialog.DIALOG_FRAGMENT_TAG); EditText addNewSpriteEditText = solo.getEditText(0); //check if hint is set String hintString = addNewSpriteEditText.getHint().toString(); assertEquals("Not the proper hint set", true, hintString.startsWith(spriteName)); assertEquals("There should no text be set", "", addNewSpriteEditText.getText().toString()); solo.enterText(0, spriteName); } public static void addNewSprite(Solo solo, String spriteName, File file, ActionAfterFinished actionToPerform) { addNewSprite(solo, spriteName, Uri.fromFile(file), actionToPerform); } public static void addNewSprite(Solo solo, String spriteName, File file) { addNewSprite(solo, spriteName, Uri.fromFile(file), ActionAfterFinished.ACTION_FORWARD_TO_NEW_OBJECT); } public static void addNewSprite(Solo solo, String spriteName, Uri uri, ActionAfterFinished actionToPerform) { showAndFilloutNewSpriteDialogWithoutClickingOk(solo, spriteName, uri, actionToPerform, null); solo.clickOnButton(solo.getString(R.string.ok)); solo.waitForDialogToClose(); assertEquals("Not in expected object", true, solo.waitForText(spriteName, 0, 500)); assertEquals("Not in expected fragment", true, solo.waitForText(solo.getString(R.string.scripts), 0, 500)); solo.goBack(); solo.waitForActivity(ProgramMenuActivity.class); assertEquals("Not in expected fragment", true, solo.waitForText(solo.getString(R.string.scripts), 0, 500)); assertEquals("Not in expected fragment", true, solo.waitForText(solo.getString(R.string.looks), 0, 500)); assertEquals("Not in expected fragment", true, solo.waitForText(solo.getString(R.string.sounds), 0, 500)); solo.goBack(); hidePocketPaintDialog(solo); solo.waitForFragmentById(R.id.fragment_sprites_list); assertEquals("Not in expected fragment", true, solo.waitForText(ProjectManager.getInstance().getCurrentProject().getName(), 0, 500)); } public static void hidePocketPaintDialog(Solo solo) { while (solo.searchText(solo.getString(R.string.pocket_paint_not_installed_title))) { solo.clickOnButton(solo.getString(R.string.no)); } } public static void clickOnExactText(Solo solo, String text) { String regularExpressionForExactClick = "^" + java.util.regex.Pattern.quote(text) + "$"; solo.clickOnText(regularExpressionForExactClick); } public static boolean searchExactText(Solo solo, String text) { return searchExactText(solo, text, false); } public static boolean searchExactText(Solo solo, String text, boolean onlyVisible) { String regularExpressionForExactClick = "^" + java.util.regex.Pattern.quote(text) + "$"; return solo.searchText(regularExpressionForExactClick, onlyVisible); } public static void clickOnCheckBox(Solo solo, int checkBoxIndex) { solo.clickOnCheckBox(checkBoxIndex); solo.sleep(100); } public static void clickOnText(Solo solo, String text) { solo.waitForText(text); solo.clickOnText(text); solo.sleep(100); } // waits for a view to be in a specific state until a timeout occurs public static boolean waitForShownState(Solo solo, final View view, final boolean wantedState) { boolean result = solo.waitForCondition(new Condition() { public boolean isSatisfied() { return view.isShown() == wantedState; } }, 500); if (!result) { fail("Condition is not satisfied before timeout. wantedState: " + Boolean.valueOf(wantedState)); } return wantedState; } public static boolean checkTempFileFromMediaLibrary(String lookOrSound, String fileName) { File folder = new File(lookOrSound); File[] filesInFolder = folder.listFiles(); for (File file : filesInFolder) { if (file.isFile()) { String filename = file.getName(); return filename.contains(fileName); } } return false; } }