package com.thoughtworks.calabash.android.IT; import com.sun.deploy.util.StringUtils; import com.thoughtworks.calabash.android.*; import org.apache.commons.io.FileUtils; import org.joda.time.DateTime; import org.junit.*; import org.junit.rules.ExpectedException; import java.io.File; import java.util.Collections; import java.util.List; import java.util.Map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class AllActionsIT { public static final String EMULATOR = "emulator-5554"; public static final String MAIN_ACTIVITY = "MyActivity"; private static String packageName; private static File tempDir; private static File apkPath; private static AndroidApplication application; @Rule public ExpectedException expectedException = ExpectedException.none(); @BeforeClass public static void installApp() throws Exception { packageName = "com.example.AndroidTestApplication"; tempDir = TestUtils.createTempDir("TestAndroidApps"); apkPath = TestUtils.createTempDirWithProj("AndroidTestApplication.apk", tempDir); application = TestUtils.installAppOnEmulator(EMULATOR, packageName, apkPath); } @AfterClass public static void tearDown() throws Exception { FileUtils.deleteDirectory(tempDir); } @After public void goToMainActivity() throws CalabashException, OperationTimedoutException { if (!application.getCurrentActivity().equals(MAIN_ACTIVITY)) { application.hideKeyboard(); application.goBack(); try { application.waitForActivity(MAIN_ACTIVITY, 6); } catch (CalabashException e) { application.goBack(); application.waitForActivity(MAIN_ACTIVITY, 6); } } } @Test public void shouldQueryForElements() throws CalabashException, OperationTimedoutException { TestUtils.goToActivity(application, TestUtils.ACTIVITY_SIMPLE_ELEMENTS); UIElements elements = application.query("textview marked:'Hello world!'"); assertEquals(1, elements.size()); assertEquals("Hello world!", elements.first().getText()); } @Test public void shouldInspectApplicationElements() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_NESTED_VIEWS); String expectedElementCollection = "Element : com.android.internal.policy.impl.PhoneWindow$DecorView , Nesting : 0\n" + "Element : com.android.internal.widget.ActionBarOverlayLayout , Nesting : 1\n" + "Element : android.widget.FrameLayout , Nesting : 2\n" + "Element : android.widget.LinearLayout , Nesting : 3\n" + "Element : android.widget.TableLayout , Nesting : 4\n" + "Element : android.widget.TableRow , Nesting : 5\n" + "Element : android.widget.Button , Nesting : 6\n" + "Element : android.widget.Button , Nesting : 6\n" + "Element : android.widget.TableRow , Nesting : 5\n" + "Element : android.widget.TableRow , Nesting : 6\n" + "Element : android.widget.Button , Nesting : 7\n" + "Element : android.widget.RadioButton , Nesting : 7\n" + "Element : android.widget.LinearLayout , Nesting : 6\n" + "Element : android.widget.ToggleButton , Nesting : 7\n" + "Element : android.widget.CheckBox , Nesting : 7\n" + "Element : android.widget.TableRow , Nesting : 5\n" + "Element : android.widget.FrameLayout , Nesting : 6\n" + "Element : android.widget.ProgressBar , Nesting : 7\n" + "Element : android.widget.RelativeLayout , Nesting : 7\n" + "Element : android.widget.RelativeLayout , Nesting : 6\n" + "Element : android.widget.TextView , Nesting : 7\n" + "Element : android.widget.TextView , Nesting : 7\n" + "Element : com.android.internal.widget.ActionBarContainer , Nesting : 2\n" + "Element : com.android.internal.widget.ActionBarView , Nesting : 3\n" + "Element : android.widget.LinearLayout , Nesting : 4\n" + "Element : com.android.internal.widget.ActionBarView$HomeView , Nesting : 5\n" + "Element : android.widget.ImageView , Nesting : 6\n" + "Element : android.widget.LinearLayout , Nesting : 5\n" + "Element : android.widget.TextView , Nesting : 6\n"; final StringBuilder actualElementCollection = new StringBuilder(); application.inspect(new InspectCallback() { public void onEachElement(UIElement element, int nestingLevel) { actualElementCollection.append(String.format("Element : %s , Nesting : %d\n", element.getElementClass(), nestingLevel)); } }); assertEquals(expectedElementCollection, actualElementCollection.toString()); } @Test public void shouldInspectAllElementsBelowElement() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_NESTED_VIEWS); UIElement uiElement = application.query("tableRow index:1").first(); String expectedElementsCollection = "Element : android.widget.TableRow , Nesting : 0\n" + "Element : android.widget.TableRow , Nesting : 1\n" + "Element : android.widget.Button , Nesting : 2\n" + "Element : android.widget.RadioButton , Nesting : 2\n" + "Element : android.widget.LinearLayout , Nesting : 1\n" + "Element : android.widget.ToggleButton , Nesting : 2\n" + "Element : android.widget.CheckBox , Nesting : 2\n"; final StringBuilder actualElementsCollection = new StringBuilder(); uiElement.inspect(new InspectCallback() { public void onEachElement(UIElement element, int nestingLevel) { actualElementsCollection.append(String.format("Element : %s , Nesting : %d\n", element.getElementClass(), nestingLevel)); } }); assertEquals(expectedElementsCollection, actualElementsCollection.toString()); } @Test public void shouldTouchElements() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_SIMPLE_ELEMENTS); UIElement button = application.query("button marked:'Normal Button'").first(); UIElement radioButton = application.query("radioButton").first(); UIElement imageButton = application.query("imageButton").first(); button.touch(); UIElement textView = application.query("textView id:'textView'").first(); assertEquals("normal button was clicked", textView.getText()); radioButton.touch(); textView = application.query("textView id:'textView'").first(); assertEquals("radio button was clicked", textView.getText()); imageButton.touch(); textView = application.query("textView id:'textView'").first(); assertEquals("image button was clicked", textView.getText()); } @Test public void shouldSetText() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_SIMPLE_ELEMENTS); UIElement editText = application.query("editText").first(); editText.setText("foo bar"); UIElement textView = application.query("textView id:'textView'").first(); assertEquals("foo bar was entered", textView.getText()); } @Test public void shouldPerformCheckboxActions() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_NESTED_VIEWS); UIElement checkBox = application.query("checkBox").first(); String isChecked = checkBox.getProperty("checked").toString(); assertEquals(false, Boolean.parseBoolean(isChecked)); checkBox.setChecked(true); isChecked = checkBox.getProperty("checked").toString(); assertEquals(true, Boolean.parseBoolean(isChecked)); checkBox.setChecked(false); isChecked = checkBox.getProperty("checked").toString(); assertEquals(false, Boolean.parseBoolean(isChecked)); } @Test public void shouldTakeScreenshot() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_NESTED_VIEWS); File screenshotsDir = new File(tempDir, "screenshots"); screenshotsDir.mkdirs(); application.takeScreenshot(screenshotsDir, "first"); final File screenshot = new File(screenshotsDir, "first_0.png"); new ConditionalWaiter(new ICondition() { @Override public boolean test() throws CalabashException { return screenshot.exists(); } }).run(2000); assertTrue(screenshot.exists()); } @Test public void shouldSelectMenuOptions() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_SIMPLE_ELEMENTS); application.selectMenuItem("Third"); UIElement textView = application.query("textView id:'textView'").first(); assertEquals("Third menu item was selected", textView.getText()); application.selectMenuItem("Fourth"); textView = application.query("textView id:'textView'").first(); assertEquals("Fourth menu item was selected", textView.getText()); } @Test public void shouldPerformSwipeActions() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_SWIPE_PAGE); application.swipe(Direction.RIGHT); int index = Integer.parseInt((String) application.query("* id:'pager'").first().getProperty("currentItem")); assertEquals(1, index); application.swipe(Direction.LEFT); index = Integer.parseInt((String) application.query("* id:'pager'").first().getProperty("currentItem")); assertEquals(0, index); } @Test public void shouldPerformLongPress() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_SIMPLE_ELEMENTS); application.query("textView marked:'Long press text'").first().longPress(); UIElement resultTextView = application.query("textView id:'textView'").first(); assertEquals("long press text was long pressed", resultTextView.getText()); application.query("imageView id:'longPressImage'").first().longPress(); UIElement resultTextViewAfter = application.query("textView id:'textView'").first(); assertEquals("long press image was long pressed", resultTextViewAfter.getText()); } @Test public void shouldPerformScrollActions() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_SCROLL_LIST); String queryForSecondPageElement = "textView marked:'No Highway'"; assertEquals(0, application.query(queryForSecondPageElement).size()); application.scrollDown(); assertEquals(1, application.query(queryForSecondPageElement).size()); String queryForFirstPageElement = "textView marked:'A Time to Kill'"; assertEquals(0, application.query(queryForFirstPageElement).size()); application.scrollUp(); assertEquals(1, application.query(queryForFirstPageElement).size()); } @Ignore @Test public void shouldSetGPSCoordinates() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_CURRENT_LOCATION); application.setGPSCoordinates(12.928909, 77.628906); UIElement latitudeText = application.query("textView id:'latitude'").first(); UIElement longitudeText = application.query("textView id:'longitude'").first(); assertEquals(Double.parseDouble(latitudeText.getText()), 12.928909, .001); assertEquals(Double.parseDouble(longitudeText.getText()), 77.628906, .001); application.setGPSLocation("Thoughtworks inc, San Francisco"); latitudeText = application.query("textView id:'latitude'").first(); longitudeText = application.query("textView id:'longitude'").first(); assertEquals(Double.parseDouble(latitudeText.getText()), 37.792626, .05); assertEquals(Double.parseDouble(longitudeText.getText()), -122.402698, .05); } @Test public void shouldSetDateOnDatePicker() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_DATE_TIME_ELEMENTS); UIElement datePicker = application.query("datePicker").first(); datePicker.setDate(new DateTime(2011, 1, 25, 0, 0)); datePicker = application.query("datePicker").first(); DateTime actualDate = datePicker.getDate(); assertEquals(2011, actualDate.getYear()); assertEquals(1, actualDate.getMonthOfYear()); assertEquals(25, actualDate.getDayOfMonth()); } @Test public void shouldSetTimeOnTimePicker() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_DATE_TIME_ELEMENTS); UIElement timePicker = application.query("timePicker").first(); timePicker.setTime(13, 50); timePicker = application.query("timePicker").first(); String actualTime = timePicker.getTime(); assertEquals("13:50", actualTime); } @Test public void shouldGetSharedPreferences() throws Exception { Map<String, String> preferences = application.getSharedPreferences("my_preferences"); assertEquals("true", preferences.get("a boolean")); assertEquals("my string", preferences.get("a string")); assertEquals("1.5", preferences.get("a float")); assertEquals("123", preferences.get("an int")); } @Test public void shouldTestGoBack() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_NESTED_VIEWS); application.goBack(); application.waitForActivity(MAIN_ACTIVITY, 2); assertEquals(MAIN_ACTIVITY, application.getCurrentActivity()); } @Test public void shouldTestPerformCalabashAction() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_SWIPE_PAGE); application.performCalabashAction("drag", "99", "1", "50", "50", "5"); int index = Integer.parseInt((String) application.query("* id:'pager'").first().getProperty("currentItem")); assertEquals(1, index); } @Test public void shouldGetResultForPerformCalabashAction() throws Exception { String expectedActions = "backdoor\n" + "clear_preferences\n" + "click_on_screen\n" + "double_tap_coordinate\n" + "drag\n" + "drag_coordinates\n" + "dump_body_html\n" + "dump_html\n" + "enter_text_by_selector\n" + "execute_async_javascript\n" + "execute_javascript\n" + "finish_opened_activities\n" + "get_activity_name\n" + "get_load_progress\n" + "get_map_bounds\n" + "get_map_center\n" + "get_map_marker\n" + "get_map_markers\n" + "get_map_zoom\n" + "get_preferences\n" + "get_url\n" + "go_back\n" + "hide_soft_keyboard\n" + "is_current_activity_focused\n" + "keyboard_enter_text\n" + "list_actions\n" + "long_press_coordinate\n" + "nullAction\n" + "pan_map_to\n" + "press_key\n" + "press_l10n_element\n" + "press_menu\n" + "press_user_action_button\n" + "scroll_to\n" + "send_key_down\n" + "send_key_enter\n" + "send_key_left\n" + "send_key_right\n" + "send_key_up\n" + "set_activity_orientation\n" + "set_gps_coordinates\n" + "set_map_center\n" + "set_map_zoom\n" + "set_preferences\n" + "set_property_by_css_selector\n" + "swipe\n" + "tap_map_away_from_markers\n" + "tap_map_marker_by_title\n" + "touch_coordinate\n" + "version\n" + "wait_for_l10n_element"; TestUtils.goToActivity(application, TestUtils.ACTIVITY_SCROLL_LIST); ActionResult result = application.performCalabashAction("list_actions"); List<String> actions = result.getBonusInformation(); Collections.sort(actions); String actualActions = StringUtils.join(actions, "\n"); assertEquals(expectedActions, actualActions); assertEquals("Available actions", result.getMessage()); assertEquals(true, result.isSuccess()); } @Test public void shouldTakeScreenshotOnFailure() throws CalabashException { final StringBuffer screenshotPath = new StringBuffer(); AndroidConfiguration androidConfiguration = new AndroidConfiguration(); androidConfiguration.setSerial(EMULATOR); androidConfiguration.setScreenshotListener(new ScreenshotListener() { public void screenshotTaken(String path, String imageType, String fileName) { screenshotPath.append(path); } }); try { application.waitFor(new ICondition() { @Override public boolean test() throws CalabashException { return false; } }, 1); } catch (OperationTimedoutException e) { } assertTrue(new File(tempDir, screenshotPath.toString()).exists()); } @Test public void shouldWaitForAnElementWithId() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_SIMPLE_ELEMENTS); application.waitForElementWithId("button", 5); } @Test public void shouldFailForAnElementWithIdNotFound() throws Exception { expectedException.expect(OperationTimedoutException.class); expectedException.expectMessage("Timed out"); TestUtils.goToActivity(application, TestUtils.ACTIVITY_SIMPLE_ELEMENTS); application.waitForElementWithId("foobarid", 5); } @Test public void shouldWaitForAnWebElementWithId() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_WEB_VIEW); application.waitForElementWithId("second_input", 5); } @Test public void shouldFailForAWebViewElementWithIdNotFound() throws Exception { expectedException.expect(OperationTimedoutException.class); expectedException.expectMessage("Timed out"); TestUtils.goToActivity(application, TestUtils.ACTIVITY_WEB_VIEW); application.waitForElementWithId("foobarid", 5); } @Test public void shouldFailWaitingForActivity() throws Exception { expectedException.expect(OperationTimedoutException.class); expectedException.expectMessage("Activity 'foo' did not appear within 5 seconds"); application.waitForActivity("foo", 5); } @Test public void shouldGetPropertiesOfWebViewElement() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_WEB_VIEW); WebElements input = application.queryWebElements("webview css:'#first_input'"); input.setText("text"); WebElements resultingElement = application.queryWebElements("webview css:'#first_input'"); assertEquals("input_text", resultingElement.getElementClass()); assertEquals("first_input", resultingElement.getId()); assertEquals("text", resultingElement.getValue()); } @Test public void shouldGetWebElementByCssAndPropertyFilter() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_WEB_VIEW); WebElements button = application.queryWebElements("webview css:'button' id:'first_button'"); button.touch(); WebElements resultingElement = application.queryWebElements("webview css:'div' textContent:'button was pressed'"); assertEquals(1, resultingElement.size()); } @Test public void shouldTouchWebViewElement() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_WEB_VIEW); WebElements button = application.queryWebElements("webview css:'button'"); button.touch(); WebElements div = application.queryWebElements("webview css:'div'"); String result = div.getText(); assertEquals("button was pressed", result); } @Test public void shouldEnterTextForWebViewElement() throws Exception { String textToEnter = "random text"; TestUtils.goToActivity(application, TestUtils.ACTIVITY_WEB_VIEW); WebElements input = application.queryWebElements("webview css:'input'"); input.setText(textToEnter); WebElements result = application.queryWebElements("webview css:'input'"); assertEquals(textToEnter, result.getValue()); } @Test public void shouldExecuteCalabashCommand() throws Exception { TestUtils.goToActivity(application, TestUtils.ACTIVITY_SIMPLE_ELEMENTS); application.query("EditText").first().setText("sample text"); application.execute("clear_text(\"editText\")"); assertEquals("", application.query("EditText").first().getText()); } }